<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def estimate(self, observations, weights):
 """ Maximum likelihood estimation of output model given the observations and weights Parameters observations : [ ndarray(T_k) ] with K elements A list of K observation trajectories, each having length T_k weights : [ ndarray(T_k, N) ] with K elements A list of K weight matrices, each having length T_k and containing the probability of any of the states in the given time step Examples -------- Generate an observation model and samples from each state. Update the observation model parameters my a maximum-likelihood fit. """

        # sizes
        N, M = self._output_probabilities.shape
        K = len(observations)
        # initialize output probability matrix
        self._output_probabilities = np.zeros((N, M))
        # update output probability matrix (numerator)
        if self.__impl__ == self.__IMPL_C__:
            for k in range(K):
                dc.update_pout(observations[k], weights[k], self._output_probabilities, dtype=config.dtype)
        elif self.__impl__ == self.__IMPL_PYTHON__:
            for k in range(K):
                for o in range(M):
                    times = np.where(observations[k] == o)[0]
                    self._output_probabilities[:, o] += np.sum(weights[k][times, :], axis=0)
        else:
            raise RuntimeError('Implementation '+str(self.__impl__)+' not available')
        # normalize
        self._output_probabilities /= np.sum(self._output_probabilities, axis=1)[:, None]