jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def evaluate_logprob(model, split, use_image_space=False, return_avg=True, batch=2000):
    """
    Evaluate a trained model only in terms of log probability.
    :param model: the model to evaluate. Can be any made, maf, or real nvp
    :param split: string, the data split to evaluate on. Must be 'trn', 'val' or 'tst'
    :param use_image_space: bool, whether to report log probability in [0, 1] image space (only for cifar and mnist)
    :param return_avg: bool, whether to return average log prob with std error, or all log probs
    :param batch: batch size to use for computing log probability
    :return: average log probability & standard error, or all log probs
    """

    assert is_data_loaded(), 'Dataset hasn\'t been loaded'

    # choose which data split to evaluate on
    data_split = getattr(data, split, None)
    if data_split is None:
        raise ValueError('Invalid data split')

    if is_conditional(model):

        logprobs = np.empty([data_split.N, data.n_labels])

        for i in range(data.n_labels):

            # create labels
            y = np.zeros([data_split.N, data.n_labels])
            y[:, i] = 1

            # process data in batches to make sure they fit in memory
            r, l = 0, batch
            while r < data_split.N:
                logprobs[r:l, i] = model.eval([y[r:l], data_split.x[r:l]])
                l += batch
                r += batch

        logprobs = scipy.special.logsumexp(logprobs, axis=1) - np.log(logprobs.shape[1])

    else:

        logprobs = np.empty(data_split.N)

        # process data in batches to make sure they fit in memory
        r, l = 0, batch
        while r < data_split.N:
            logprobs[r:l] = model.eval(data_split.x[r:l])
            l += batch
            r += batch

    if use_image_space:
        assert data_name in ['mnist', 'cifar10']
        z = util.logistic(data_split.x)
        logprobs += data.n_dims * np.log(1-2*data.alpha) - np.sum(np.log(z) + np.log(1-z), axis=1)

    if return_avg:
        avg_logprob = logprobs.mean()
        std_err = logprobs.std() / np.sqrt(data_split.N)
        return avg_logprob, std_err

    else:
        return logprobs
//  [python]
def turner_hyperparameter_optimization(self, step_size):
        """Called by HyperparameterOpimizer at each iteration of the 
        optimization routine.
        
        NOTE: Should be checked w.r.t. step-size computation, probably one can
        do better here!"""
        
        """STEP 1: Get the new gradient value"""
        sign, gradient = scipy.misc.logsumexp(
                a=(self.model_specific_joint_log_probabilities_derivative),
                b=self.model_specific_joint_log_probabilities_derivative_sign,
                return_sign=True, axis=1)
        gradient = np.exp(gradient)*sign
        
        """STEP 2: Get the difference a_{t-1} - a_{t-2}, b_{t-1} - b_{t-2}"""
        #Debug: Initialize self.a_old as self.a!, gradient_old = 0
        dif_old_a = self.a - self.a_old
        dif_old_b = self.b - self.b_old
        dif_old_val = np.array([dif_old_a, dif_old_b])
        dif_old_grad = gradient - self.gradient_old
        
        """STEP 3: Compute step size via BB method"""
        if True:
            D1_sign = np.dot(np.sign(dif_old_val), np.sign(dif_old_grad))
            D1 = min(max(np.abs(np.dot(dif_old_val, dif_old_grad)), pow(10,5)),
                     pow(10, -5))*D1_sign
            D2 = min(max(np.dot(dif_old_grad, dif_old_grad), pow(10,5)),
                     pow(10,-5))
            #D3 = min(max(np.dot(dif_old_val, dif_old_val), pow(10,5)),
            #         pow(10,-5))
            alpha_1 = D1/D2
            #alpha_2 = D3/D1
            step_size = alpha_1 
        
        """STEP 2: Calculate the new a-value, and return the difference to
        old a-value, (a_{it+1} - a_it)"""
        self.a_old, self.b_old = self.a, self.b
        self.gradient_old = gradient
        self.a = min(max(self.a + gradient[0]*step_size, pow(10,-20)), pow(10,15))
        self.b = min(max(self.b + gradient[1]*step_size, pow(10,-20)), pow(10,15))
        a_dif, b_dif = self.a - self.a_old, self.b - self.b_old
        return [a_dif, b_dif]
//  [python]
def turner_hyperparameter_optimization(self, step_size):
        """Called by HyperparameterOpimizer at each iteration of the 
        optimization routine.
        
        NOTE: Should be checked w.r.t. step-size computation, probably one can
        do better here!"""
        
        """STEP 1: Get the new gradient value"""
        sign, gradient = scipy.special.logsumexp(
                a=(self.model_specific_joint_log_probabilities_derivative),
                b=self.model_specific_joint_log_probabilities_derivative_sign,
                return_sign=True, axis=1)
        gradient = np.exp(gradient)*sign
        
        """STEP 2: Get the difference a_{t-1} - a_{t-2}, b_{t-1} - b_{t-2}"""
        #Debug: Initialize self.a_old as self.a!, gradient_old = 0
        dif_old_a = self.a - self.a_old
        dif_old_b = self.b - self.b_old
        dif_old_val = np.array([dif_old_a, dif_old_b])
        dif_old_grad = gradient - self.gradient_old
        
        """STEP 3: Compute step size via BB method"""
        if True:
            D1_sign = np.dot(np.sign(dif_old_val), np.sign(dif_old_grad))
            D1 = min(max(np.abs(np.dot(dif_old_val, dif_old_grad)), pow(10,5)),
                     pow(10, -5))*D1_sign
            D2 = min(max(np.dot(dif_old_grad, dif_old_grad), pow(10,5)),
                     pow(10,-5))
            #D3 = min(max(np.dot(dif_old_val, dif_old_val), pow(10,5)),
            #         pow(10,-5))
            alpha_1 = D1/D2
            #alpha_2 = D3/D1
            step_size = alpha_1 
        
        """STEP 2: Calculate the new a-value, and return the difference to
        old a-value, (a_{it+1} - a_it)"""
        self.a_old, self.b_old = self.a, self.b
        self.gradient_old = gradient
        self.a = min(max(self.a + gradient[0]*step_size, pow(10,-20)), pow(10,15))
        self.b = min(max(self.b + gradient[1]*step_size, pow(10,-20)), pow(10,15))
        a_dif, b_dif = self.a - self.a_old, self.b - self.b_old
        return [a_dif, b_dif]
//  [python]
def compute_log_posteriors(points, model):
    """
    Returns responsibilities for each
    point in each cluster
    
    Parameters
    ----------
    points : an array (n_points,dim)
    model : GMM model, formatted like the output from load_model
    
    Returns
    -------
    log_resp: an array (n_points,n_components)
        an array containing the logarithm of the responsibilities.            
    """
    log_normal_matrix = _log_normal_matrix(points,
                                           model['means'],
                                           model['cov'])
    log_product = log_normal_matrix + model['log_weights'][:,np.newaxis].T
    log_prob_norm = scipy.misc.logsumexp(log_product,axis=1)
    log_resp = log_product - log_prob_norm[:,np.newaxis]       
    return log_resp
//  [python]
def compute_log_posteriors(points, model):
    """
    Returns responsibilities for each
    point in each cluster
    
    Parameters
    ----------
    points : an array (n_points,dim)
    model : GMM model, formatted like the output from load_model
    
    Returns
    -------
    log_resp: an array (n_points,n_components)
        an array containing the logarithm of the responsibilities.            
    """
    log_normal_matrix = _log_normal_matrix(points,
                                           model['means'],
                                           model['cov'])
    log_product = log_normal_matrix + model['log_weights'][:,np.newaxis].T
    log_prob_norm = scipy.special.logsumexp(log_product,axis=1)
    log_resp = log_product - log_prob_norm[:,np.newaxis]       
    return log_resp
//  [python]
def n_effective(self):
        """
        Estimate the effective number of posterior samples using the Kish
        Effective Sample Size (ESS) where `ESS = sum(wts)^2 / sum(wts^2)`.
        Note that this is `len(wts)` when `wts` are uniform and
        `1` if there is only one non-zero element in `wts`.

        """

        if len(self.saved_logwt) == 0:
            # If there are no saved weights, return 0.
            return 0
        else:
            # Otherwise, compute Kish ESS.
            logwts = np.array(self.saved_logwt)
            logneff = logsumexp(logwts) * 2 - logsumexp(logwts * 2)
            return np.exp(logneff)
//  [python]
def n_effective(self):
        """
        Estimate the effective number of posterior samples using the Kish
        Effective Sample Size (ESS) where `ESS = sum(wts)^2 / sum(wts^2)`.
        Note that this is `len(wts)` when `wts` are uniform and
        `1` if there is only one non-zero element in `wts`.

        """

        if len(self.saved_logwt) == 0:
            # If there are no saved weights, return 0.
            return 0
        else:
            # Otherwise, compute Kish ESS.
            logwts = np.array(self.saved_logwt)
            logneff = scipy.special.logsumexp(logwts) * 2 - scipy.special.logsumexp(logwts * 2)
            return np.exp(logneff)
//  [python]
def log_carlson_r_positive_a(a,b,z):

    log_prefac=scipy.special.gammaln(a+1)+scipy.special.gammaln(sum(b))-scipy.special.gammaln(a+sum(b))
    new_zs=z
        
    new_zs_log=numpy.log(new_zs)
    new_bs=b
   
    cs=[0.0]
    
    if(a>0):
        
        lambdas=[]
        
        new_bs_log=numpy.log(new_bs)
        running_lambda_vec=new_bs_log
        
        for cur_ind in range(a):
            running_lambda_vec+=new_zs_log
            lambdas.append(scipy.misc.logsumexp(running_lambda_vec).sum())
            
            new_cs=scipy.misc.logsumexp( numpy.array(lambdas[::-1])+numpy.array(cs))-numpy.log(cur_ind+1)
            cs.append(new_cs)

    return log_prefac+cs[-1]
//  [python]
def log_carlson_r_positive_a(a,b,z):

    log_prefac=scipy.special.gammaln(a+1)+scipy.special.gammaln(sum(b))-scipy.special.gammaln(a+sum(b))
    new_zs=z
        
    new_zs_log=numpy.log(new_zs)
    new_bs=b
   
    cs=[0.0]
    
    if(a>0):
        
        lambdas=[]
        
        new_bs_log=numpy.log(new_bs)
        running_lambda_vec=new_bs_log
        
        for cur_ind in range(a):
            running_lambda_vec+=new_zs_log
            lambdas.append(scipy.special.logsumexp(running_lambda_vec).sum())
            
            new_cs=scipy.special.logsumexp( numpy.array(lambdas[::-1])+numpy.array(cs))-numpy.log(cur_ind+1)
            cs.append(new_cs)

    return log_prefac+cs[-1]
//  [python]
def aggregate_prediction_from_probabilities(probabilities,
                                            aggregation_method=METHOD_AVERAGE):
    """Determine the whole-image class prediction from patch probabilities.

  Args:
    probabilities: Numpy array of marginal probabilities, shape
     (batch_size, num_classes).
    aggregation_method: String, the method of aggregating the patch
      probabilities.

  Returns:
    A WholeImagePrediction object.

  Raises:
    ValueError: If the aggregation method is not valid.
  """
    certainties = certainties_from_probabilities(probabilities)

    certainty_dict = {
        'mean': numpy.round(numpy.mean(certainties), 3),
        'max': numpy.round(numpy.max(certainties), 3)
    }

    weights = certainties
    weights = None if numpy.sum(weights) == 0 else weights

    if aggregation_method == METHOD_AVERAGE:
        probabilities_aggregated = numpy.average(probabilities, 0, weights=weights)
    elif aggregation_method == METHOD_PRODUCT:
        # For i denoting index within batch and c the class:
        #   Q_c = product_over_i(p_c(i))
        # probabilities_aggregated = Q_c / sum_over_c(Q_c)
        # The following computes this using logs for numerical stability.
        sum_log_probabilities = numpy.sum(numpy.log(probabilities), 0)
        probabilities_aggregated = numpy.exp(
            sum_log_probabilities - scipy.misc.logsumexp(sum_log_probabilities))
    else:
        raise ValueError('Invalid aggregation method %s.' % aggregation_method)
    predicted_class = numpy.argmax(probabilities_aggregated)
    certainty_dict['aggregate'] = numpy.round(
        get_certainty(probabilities_aggregated), 3)
    certainty_dict['weighted'] = numpy.round(
        numpy.average(
            certainties, 0, weights=weights), 3)

    assert sorted(CERTAINTY_TYPES.values()) == sorted(certainty_dict.keys())

    return WholeImagePrediction(predicted_class, certainty_dict,
                                probabilities_aggregated)
//  [python]
def aggregate_prediction_from_probabilities(probabilities,
                                            aggregation_method=METHOD_AVERAGE):
    """Determine the whole-image class prediction from patch probabilities.

  Args:
    probabilities: Numpy array of marginal probabilities, shape
     (batch_size, num_classes).
    aggregation_method: String, the method of aggregating the patch
      probabilities.

  Returns:
    A WholeImagePrediction object.

  Raises:
    ValueError: If the aggregation method is not valid.
  """
    certainties = certainties_from_probabilities(probabilities)

    certainty_dict = {
        'mean': numpy.round(numpy.mean(certainties), 3),
        'max': numpy.round(numpy.max(certainties), 3)
    }

    weights = certainties
    weights = None if numpy.sum(weights) == 0 else weights

    if aggregation_method == METHOD_AVERAGE:
        probabilities_aggregated = numpy.average(probabilities, 0, weights=weights)
    elif aggregation_method == METHOD_PRODUCT:
        # For i denoting index within batch and c the class:
        #   Q_c = product_over_i(p_c(i))
        # probabilities_aggregated = Q_c / sum_over_c(Q_c)
        # The following computes this using logs for numerical stability.
        sum_log_probabilities = numpy.sum(numpy.log(probabilities), 0)
        probabilities_aggregated = numpy.exp(
            sum_log_probabilities - scipy.special.logsumexp(sum_log_probabilities))
    else:
        raise ValueError('Invalid aggregation method %s.' % aggregation_method)
    predicted_class = numpy.argmax(probabilities_aggregated)
    certainty_dict['aggregate'] = numpy.round(
        get_certainty(probabilities_aggregated), 3)
    certainty_dict['weighted'] = numpy.round(
        numpy.average(
            certainties, 0, weights=weights), 3)

    assert sorted(CERTAINTY_TYPES.values()) == sorted(certainty_dict.keys())

    return WholeImagePrediction(predicted_class, certainty_dict,
                                probabilities_aggregated)
//  [python]
def explorationHelper(self, query_id):
        numAllowedDocs = self.dataset.docsPerQuery[query_id]
        uniformDistribution = numpy.ones(numAllowedDocs, dtype = numpy.float32) / numAllowedDocs
        probDistribution = numpy.zeros(numAllowedDocs, dtype = numpy.float32)
        if self.detPolicy is None:
            probDistribution = numpy.random.dirichlet(uniformDistribution)
            probDistribution += self.temperature
            probDistribution /= probDistribution.sum(dtype = numpy.float32)
        else:
            if self.temperature <= 0:
                probDistribution = uniformDistribution
            else:
                numFeatures = numpy.shape(self.dataset.features)[2]
                allDocFeatures = numpy.zeros((numAllowedDocs, numFeatures), dtype = numpy.float32)
                currentFeatures = self.dataset.features[query_id, 0:numAllowedDocs,:]
                allDocFeatures[:, self.detPolicy.featureList] = currentFeatures[:, self.detPolicy.featureList]
                allDocScores = None
                if self.detPolicy.modelType != 'tree':
                    allDocScores = numpy.dot(allDocFeatures, self.detPolicy.policyParams)
                else:
                    allDocScores = self.detPolicy.tree.predict(allDocFeatures)
                
                allDocScores *= self.temperature
                
                partitionFunction = scipy.misc.logsumexp(allDocScores)
                logProb = allDocScores - partitionFunction
                probDistribution = numpy.exp(logProb).astype(numpy.float32)
        
        return probDistribution
//  [python]
def explorationHelper(self, query_id):
        numAllowedDocs = self.dataset.docsPerQuery[query_id]
        uniformDistribution = numpy.ones(numAllowedDocs, dtype = numpy.float32) / numAllowedDocs
        probDistribution = numpy.zeros(numAllowedDocs, dtype = numpy.float32)
        if self.detPolicy is None:
            probDistribution = numpy.random.dirichlet(uniformDistribution)
            probDistribution += self.temperature
            probDistribution /= probDistribution.sum(dtype = numpy.float32)
        else:
            if self.temperature <= 0:
                probDistribution = uniformDistribution
            else:
                numFeatures = numpy.shape(self.dataset.features)[2]
                allDocFeatures = numpy.zeros((numAllowedDocs, numFeatures), dtype = numpy.float32)
                currentFeatures = self.dataset.features[query_id, 0:numAllowedDocs,:]
                allDocFeatures[:, self.detPolicy.featureList] = currentFeatures[:, self.detPolicy.featureList]
                allDocScores = None
                if self.detPolicy.modelType != 'tree':
                    allDocScores = numpy.dot(allDocFeatures, self.detPolicy.policyParams)
                else:
                    allDocScores = self.detPolicy.tree.predict(allDocFeatures)
                
                allDocScores *= self.temperature
                
                partitionFunction = scipy.special.logsumexp(allDocScores)
                logProb = allDocScores - partitionFunction
                probDistribution = numpy.exp(logProb).astype(numpy.float32)
        
        return probDistribution
//  [python]
def rescale_DPD_run_length_distribution(self, log_scale_new, 
                                        rescaler_for_old_obs, t):
        """Rescales joint log probs"""
        if rescaler_for_old_obs is None:
            self.joint_log_probabilities = (self.joint_log_probabilities 
                                            - log_scale_new)
        else:
            self.joint_log_probabilities[0] = (self.joint_log_probabilities[0] 
                    - log_scale_new)
            self.joint_log_probabilities[1:] = (
                    self.joint_log_probabilities[1:] + rescaler_for_old_obs)
        self.model_log_evidence = scipy.misc.logsumexp(
                self.joint_log_probabilities)
//  [python]
def rescale_DPD_run_length_distribution(self, log_scale_new, 
                                        rescaler_for_old_obs, t):
        """Rescales joint log probs"""
        if rescaler_for_old_obs is None:
            self.joint_log_probabilities = (self.joint_log_probabilities 
                                            - log_scale_new)
        else:
            self.joint_log_probabilities[0] = (self.joint_log_probabilities[0] 
                    - log_scale_new)
            self.joint_log_probabilities[1:] = (
                    self.joint_log_probabilities[1:] + rescaler_for_old_obs)
        self.model_log_evidence = scipy.special.logsumexp(
                self.joint_log_probabilities)
//  [python]
def _multivec(
    filepath,
    output_file,
    assembly,
    tile_size,
    chromsizes_filename,
    starting_resolution,
    method,
    row_infos_filename=None,
):
    """
    Aggregate a multivec file.

    This is a file containing nxn data that is aggregated along only one axis.
    This data should be in an HDF5 file where each dataset is named for a
    chromosome and contains a 'resolutions' group containing values for the
    base level resolution.

    Example: f['chr1']['reslutions']['1000'] = [[1,2,3],[4,5,6]]

    The resulting data will be organized by resolution and chromosome.

    Example: f_out['chr1']['resolutions']['5000']=[[1000,2000,3000],[4000,5000,6000]]

    Aggregation is currently done by summing adjacent values.
    """
    f_in = h5py.File(filepath, "r")

    if output_file is None:
        output_file = op.splitext(filepath)[0] + ".multires.mv5"

    (chrom_info, chrom_names, chrom_sizes) = cch.load_chromsizes(
        chromsizes_filename, assembly
    )

    # TODO: "method" is not defined, so this would not work?
    if method == "maxtotal":  # noqa: F821
        pass
    if method == "logsumexp":  # noqa: F821

        def agg(x):
            a = x.T.reshape((x.shape[1], -1, 2))
            return sm.logsumexp(a, axis=2).T

    else:

        def agg(x):
            return x.T.reshape((x.shape[1], -1, 2)).sum(axis=2).T

    print("agg:", agg)
    if row_infos_filename is not None:
        with open(row_infos_filename, "r") as f:
            row_infos = [line.strip().encode("utf8") for line in f]
    else:
        row_infos = None
    print("row_infos:", row_infos)

    cmv.create_multivec_multires(
        f_in,
        chromsizes=zip(chrom_names, chrom_sizes),
        agg=lambda x: np.nansum(x.T.reshape((x.shape[1], -1, 2)), axis=2).T,
        starting_resolution=starting_resolution,
        tile_size=tile_size,
        output_file=output_file,
        row_infos=row_infos,
    )
//  [python]
def _multivec(
    filepath,
    output_file,
    assembly,
    tile_size,
    chromsizes_filename,
    starting_resolution,
    method,
    row_infos_filename=None,
):
    """
    Aggregate a multivec file.

    This is a file containing nxn data that is aggregated along only one axis.
    This data should be in an HDF5 file where each dataset is named for a
    chromosome and contains a 'resolutions' group containing values for the
    base level resolution.

    Example: f['chr1']['reslutions']['1000'] = [[1,2,3],[4,5,6]]

    The resulting data will be organized by resolution and chromosome.

    Example: f_out['chr1']['resolutions']['5000']=[[1000,2000,3000],[4000,5000,6000]]

    Aggregation is currently done by summing adjacent values.
    """
    f_in = h5py.File(filepath, "r")

    if output_file is None:
        output_file = op.splitext(filepath)[0] + ".multires.mv5"

    (chrom_info, chrom_names, chrom_sizes) = cch.load_chromsizes(
        chromsizes_filename, assembly
    )

    # TODO: "method" is not defined, so this would not work?
    if method == "maxtotal":  # noqa: F821
        pass
    if method == "logsumexp":  # noqa: F821

        def agg(x):
            a = x.T.reshape((x.shape[1], -1, 2))
            return sp.special.logsumexp(a, axis=2).T

    else:

        def agg(x):
            return x.T.reshape((x.shape[1], -1, 2)).sum(axis=2).T

    print("agg:", agg)
    if row_infos_filename is not None:
        with open(row_infos_filename, "r") as f:
            row_infos = [line.strip().encode("utf8") for line in f]
    else:
        row_infos = None
    print("row_infos:", row_infos)

    cmv.create_multivec_multires(
        f_in,
        chromsizes=zip(chrom_names, chrom_sizes),
        agg=lambda x: np.nansum(x.T.reshape((x.shape[1], -1, 2)), axis=2).T,
        starting_resolution=starting_resolution,
        tile_size=tile_size,
        output_file=output_file,
        row_infos=row_infos,
    )
//  [python]
def speaker(self,state,world,depth):
		# print("rationality",world.rationality)
		# print("world prior shape",state.world_priors[0].shape)
		# print("SPEAKER\n\n",depth)


		if depth==0:
			# print("S0")
			# print("TIMESTEP:",state.timestep,"INITIAL SPEAKER CALL")



			return self.initial_speakers[world.speaker].forward(state=state,world=world)
			
		else: 

			prior = self.speaker(state,world,depth=0)
			# self.initial_speakers[world.speaker].forward(state=state,world=world)
			# prior = self.speaker_prior.forward(state=state,world=world)

		# self.speaker(state=state,world=world,depth=0)
		if depth==1:

			scores = []
			for k in range(prior.shape[0]):
				# print(world.target,world.rationality,"FIRST")
				out = self.listener(state=state,utterance=k,depth=depth-1)

				
				scores.append(out[world.target,world.rationality,world.speaker])

			scores = np.asarray(scores)
			# print("SCORES",scores)
			# rationality in traditional RSA sense
			scores = scores*(self.initial_speakers[world.speaker].rationality_support[world.rationality])
			# update prior to posterior
			# print(scores.shape,prior.shape)
			posterior = (scores + prior) - scipy.misc.logsumexp(scores + prior)
			# print("POSTERIOR",posterior)

			return posterior

		elif depth==2:

			scores = []
			for k in range(prior.shape[0]):

				# print(world.rationality,"rat")
				out = self.listener(state=state,utterance=k,depth=depth-1)
				scores.append(out[world.target,world.rationality,world.speaker])

			scores = np.asarray(scores)
			# rationality not present at s2
			# update prior to posterior
			posterior = (scores + prior) - scipy.misc.logsumexp(scores + prior)

			return posterior
//  [python]
def speaker(self,state,world,depth):
		# print("rationality",world.rationality)
		# print("world prior shape",state.world_priors[0].shape)
		# print("SPEAKER\n\n",depth)


		if depth==0:
			# print("S0")
			# print("TIMESTEP:",state.timestep,"INITIAL SPEAKER CALL")



			return self.initial_speakers[world.speaker].forward(state=state,world=world)
			
		else: 

			prior = self.speaker(state,world,depth=0)
			# self.initial_speakers[world.speaker].forward(state=state,world=world)
			# prior = self.speaker_prior.forward(state=state,world=world)

		# self.speaker(state=state,world=world,depth=0)
		if depth==1:

			scores = []
			for k in range(prior.shape[0]):
				# print(world.target,world.rationality,"FIRST")
				out = self.listener(state=state,utterance=k,depth=depth-1)

				
				scores.append(out[world.target,world.rationality,world.speaker])

			scores = np.asarray(scores)
			# print("SCORES",scores)
			# rationality in traditional RSA sense
			scores = scores*(self.initial_speakers[world.speaker].rationality_support[world.rationality])
			# update prior to posterior
			# print(scores.shape,prior.shape)
			posterior = (scores + prior) - scipy.special.logsumexp(scores + prior)
			# print("POSTERIOR",posterior)

			return posterior

		elif depth==2:

			scores = []
			for k in range(prior.shape[0]):

				# print(world.rationality,"rat")
				out = self.listener(state=state,utterance=k,depth=depth-1)
				scores.append(out[world.target,world.rationality,world.speaker])

			scores = np.asarray(scores)
			# rationality not present at s2
			# update prior to posterior
			posterior = (scores + prior) - scipy.special.logsumexp(scores + prior)

			return posterior
//  [python]
def trimmer(self, kept_run_lengths):
        """Trim the relevant quantities for the PG model"""
        self.joint_log_probabilities = self.joint_log_probabilities[kept_run_lengths]
        self.sums = self.sums[kept_run_lengths,:,:]
        self.retained_run_lengths = self.retained_run_lengths[kept_run_lengths]
        self.model_log_evidence = scipy.misc.logsumexp(self.joint_log_probabilities)
//  [python]
def trimmer(self, kept_run_lengths):
        """Trim the relevant quantities for the PG model"""
        self.joint_log_probabilities = self.joint_log_probabilities[kept_run_lengths]
        self.sums = self.sums[kept_run_lengths,:,:]
        self.retained_run_lengths = self.retained_run_lengths[kept_run_lengths]
        self.model_log_evidence = scipy.special.logsumexp(self.joint_log_probabilities)
//  [python]
def normalize_logits(logits):
  """Logit normalization"""
  return logits - scipy.misc.logsumexp(logits, axis=1, keepdims=True)
//  [python]
def normalize_logits(logits):
  """Logit normalization"""
  return logits - scipy.special.logsumexp(logits, axis=1, keepdims=True)
//  [python]
def _log_posterior(self, X, normalize = True):
		# https://github.com/probml/pmtk3/blob/5fefd068a2e84ae508684d3e4750bd72a4164ba0/toolbox/SupervisedModels/discrimAnalysis/discrimAnalysisPredict.m
		# Apply Bayes rule with Gaussian class-conditional densities.
		# post[i,c] = P(y=c|x(i,:), params)
		# yhat[i] = arg max_c post[i,c]
		N = X.shape[0]
		Nclasses = len(self.priors_)
		loglik = numpy.zeros((N, Nclasses))
		for c in range(Nclasses):
			try: 
				mvnorm = scipy.stats.multivariate_normal(self.means_[c], self.covariances_[c], allow_singular=True)
			except: 
				mvnorm = scipy.stats.multivariate_normal(self.means_[c], self.covariances_[c])
			loglik[:, c] = mvnorm.logpdf(X)
		logjoint = numpy.log(self.priors_) + loglik

		if normalize:
			normalization = scipy.misc.logsumexp(logjoint, axis=1)
			return logjoint - numpy.reshape(normalization, (len(normalization), 1))
		else:
			return logjoint
//  [python]
def _log_posterior(self, X, normalize = True):
		# https://github.com/probml/pmtk3/blob/5fefd068a2e84ae508684d3e4750bd72a4164ba0/toolbox/SupervisedModels/discrimAnalysis/discrimAnalysisPredict.m
		# Apply Bayes rule with Gaussian class-conditional densities.
		# post[i,c] = P(y=c|x(i,:), params)
		# yhat[i] = arg max_c post[i,c]
		N = X.shape[0]
		Nclasses = len(self.priors_)
		loglik = numpy.zeros((N, Nclasses))
		for c in range(Nclasses):
			try: 
				mvnorm = scipy.stats.multivariate_normal(self.means_[c], self.covariances_[c], allow_singular=True)
			except: 
				mvnorm = scipy.stats.multivariate_normal(self.means_[c], self.covariances_[c])
			loglik[:, c] = mvnorm.logpdf(X)
		logjoint = numpy.log(self.priors_) + loglik

		if normalize:
			normalization = scipy.special.logsumexp(logjoint, axis=1)
			return logjoint - numpy.reshape(normalization, (len(normalization), 1))
		else:
			return logjoint
//  [python]
def reward_func(self, obses, acts, next_obses, eps=1e-6):
    act_labels = np.array(
        [self.expert_policy(obses[i, :]) for i in range(obses.shape[0])])
    act_labels -= scipy.misc.logsumexp(act_labels, axis=1, keepdims=True)
    acts -= scipy.misc.logsumexp(acts, axis=1, keepdims=True)
    xent = -(acts * np.exp(act_labels)).sum(axis=1)
    return -xent
//  [python]
def reward_func(self, obses, acts, next_obses, eps=1e-6):
    act_labels = np.array(
        [self.expert_policy(obses[i, :]) for i in range(obses.shape[0])])
    act_labels -= scipy.special.logsumexp(act_labels, axis=1, keepdims=True)
    acts -= scipy.special.logsumexp(acts, axis=1, keepdims=True)
    xent = -(acts * np.exp(act_labels)).sum(axis=1)
    return -xent
//  [python]
def log_softmax(xs):
    assert len(xs.shape) == 2
    import scipy.misc
    return xs - scipy.misc.logsumexp(xs, 1)[:, None]
//  [python]
def log_softmax(xs):
    assert len(xs.shape) == 2
    import scipy.special
    return xs - scipy.special.logsumexp(xs, 1)[:, None]
//  [python]
def shapeChainPlots(shapeSuffix, inputFile, outputFile = None, plotWeights = False):
	"""
	Plot Lhood obtained from chains files either for theoretical
	or empirical samples. For former, plots 1-d graphs of raw samples (i.e. letting all parameters)
	and also 1-d marginalised graphs. In latter case, the two are equivalent assuming no binning
	in the marginalisation
	if plotWeights, plots the weights L omega / Z instead of Lhood for empirical samples
	n.b. for mn samples, 2nd column doesn't appear to be LLhood, in fact I have no idea what it is,
	hence plotting it is pretty pointless

	Args:

	shapeSuffix : string shape suffix string of name
	inputFile : string input file location 
	outputFile : string output file location 
	plotWeights : boolean see body of docstring
	"""
	if 'tg' in inputFile or plotWeights:
		Lhood, _, params = input.getFromTxt(inputFile)
	else:
		_, LLhood, params = input.getFromTxt(inputFile)
		Lhood = np.exp(LLhood - scipy.misc.logsumexp(LLhood))
	if shapeSuffix == '_Sc':
		plt.figure('Sc')
		plt.scatter(params, Lhood)
		plt.xlabel('phi')
		if outputFile:
			plt.savefig(outputFile + '_phi.png')
		else:
			plt.show()
		plt.close()
	elif shapeSuffix == '_St':
		#unmarginalised plots
		plt.figure('St phi')
		plt.scatter(params[:,0], Lhood)
		plt.xlabel('phi')
		if outputFile:
			plt.savefig(outputFile + '_phi.png')
		else:
			plt.show()
		plt.close()
		plt.figure('St theta')
		plt.scatter(params[:,1], Lhood)
		plt.xlabel('theta')
		if outputFile:
			plt.savefig(outputFile + '_theta.png')
		else:
			plt.show()
		plt.close()
		if 'tg' in inputFile:
			#marginalised plots  
			oneDn = 100 #this has to be same as in plotTheoreticalSamples() or plots will be completely wrong!!
			phi, LPhi, theta, LTheta = plotting.get2DMarg(params, Lhood, oneDn) 
			plt.figure('St phi marg')
			plt.scatter(phi, LPhi)
			plt.xlabel('phi marg')
			if outputFile:
				plt.savefig(outputFile + '_phimarg.png')
			else:
				plt.show()
			plt.close()
			plt.figure('St theta marg')
			plt.scatter(theta, LTheta)
			plt.xlabel('theta marg')
			if outputFile:
				plt.savefig(outputFile + '_thetamarg.png')
			else:
				plt.show()
			plt.close()
	elif shapeSuffix == '_Ss':
		#unmarginalised plots
		plt.figure('Ss phi')
		plt.scatter(params[:,0], Lhood)
		plt.xlabel('phi')
		if outputFile:
			plt.savefig(outputFile + '_phi.png')
		else:
			plt.show()
		plt.close()
		plt.figure('Ss theta')
		plt.scatter(params[:,1], Lhood)
		plt.xlabel('theta')
		if outputFile:
			plt.savefig(outputFile + '_theta.png')
		else:
			plt.show()
		plt.close()
		if 'tg' in inputFile:
			#marginalised plots
			oneDn = 100 #this has to be same as in plotTheoreticalSamples() or plots will be completely wrong!!
			phi, LPhi, theta, LTheta = plotting.get2DMarg(params, Lhood, oneDn)
			plt.figure('Ss phi marg')
			plt.scatter(phi, LPhi)
			plt.xlabel('phi marg')
			if outputFile:
				plt.savefig(outputFile + '_phimarg.png')
			else:
				plt.show()
			plt.close()
			plt.figure('Ss theta marg')
			plt.scatter(theta, LTheta)
			plt.xlabel('theta marg')
			if outputFile:
				plt.savefig(outputFile + '_thetamarg.png')
			else:
				plt.show()
			plt.close()
//  [python]
def shapeChainPlots(shapeSuffix, inputFile, outputFile = None, plotWeights = False):
	"""
	Plot Lhood obtained from chains files either for theoretical
	or empirical samples. For former, plots 1-d graphs of raw samples (i.e. letting all parameters)
	and also 1-d marginalised graphs. In latter case, the two are equivalent assuming no binning
	in the marginalisation
	if plotWeights, plots the weights L omega / Z instead of Lhood for empirical samples
	n.b. for mn samples, 2nd column doesn't appear to be LLhood, in fact I have no idea what it is,
	hence plotting it is pretty pointless

	Args:

	shapeSuffix : string shape suffix string of name
	inputFile : string input file location 
	outputFile : string output file location 
	plotWeights : boolean see body of docstring
	"""
	if 'tg' in inputFile or plotWeights:
		Lhood, _, params = input.getFromTxt(inputFile)
	else:
		_, LLhood, params = input.getFromTxt(inputFile)
		Lhood = np.exp(LLhood - scipy.special.logsumexp(LLhood))
	if shapeSuffix == '_Sc':
		plt.figure('Sc')
		plt.scatter(params, Lhood)
		plt.xlabel('phi')
		if outputFile:
			plt.savefig(outputFile + '_phi.png')
		else:
			plt.show()
		plt.close()
	elif shapeSuffix == '_St':
		#unmarginalised plots
		plt.figure('St phi')
		plt.scatter(params[:,0], Lhood)
		plt.xlabel('phi')
		if outputFile:
			plt.savefig(outputFile + '_phi.png')
		else:
			plt.show()
		plt.close()
		plt.figure('St theta')
		plt.scatter(params[:,1], Lhood)
		plt.xlabel('theta')
		if outputFile:
			plt.savefig(outputFile + '_theta.png')
		else:
			plt.show()
		plt.close()
		if 'tg' in inputFile:
			#marginalised plots  
			oneDn = 100 #this has to be same as in plotTheoreticalSamples() or plots will be completely wrong!!
			phi, LPhi, theta, LTheta = plotting.get2DMarg(params, Lhood, oneDn) 
			plt.figure('St phi marg')
			plt.scatter(phi, LPhi)
			plt.xlabel('phi marg')
			if outputFile:
				plt.savefig(outputFile + '_phimarg.png')
			else:
				plt.show()
			plt.close()
			plt.figure('St theta marg')
			plt.scatter(theta, LTheta)
			plt.xlabel('theta marg')
			if outputFile:
				plt.savefig(outputFile + '_thetamarg.png')
			else:
				plt.show()
			plt.close()
	elif shapeSuffix == '_Ss':
		#unmarginalised plots
		plt.figure('Ss phi')
		plt.scatter(params[:,0], Lhood)
		plt.xlabel('phi')
		if outputFile:
			plt.savefig(outputFile + '_phi.png')
		else:
			plt.show()
		plt.close()
		plt.figure('Ss theta')
		plt.scatter(params[:,1], Lhood)
		plt.xlabel('theta')
		if outputFile:
			plt.savefig(outputFile + '_theta.png')
		else:
			plt.show()
		plt.close()
		if 'tg' in inputFile:
			#marginalised plots
			oneDn = 100 #this has to be same as in plotTheoreticalSamples() or plots will be completely wrong!!
			phi, LPhi, theta, LTheta = plotting.get2DMarg(params, Lhood, oneDn)
			plt.figure('Ss phi marg')
			plt.scatter(phi, LPhi)
			plt.xlabel('phi marg')
			if outputFile:
				plt.savefig(outputFile + '_phimarg.png')
			else:
				plt.show()
			plt.close()
			plt.figure('Ss theta marg')
			plt.scatter(theta, LTheta)
			plt.xlabel('theta marg')
			if outputFile:
				plt.savefig(outputFile + '_thetamarg.png')
			else:
				plt.show()
			plt.close()
//  [python]
def match_pts(self, x, z):
        # blurred = gaussian_filter(self._log_m, 0.2/self.resolution)

        scan_pts = x[:2, None] + z[0:1,:]*np.array([np.cos(z[1,:] + x[2]), np.sin(z[1,:] + x[2])]) + self.map_offset[:, None]

        idx = np.array(scan_pts/self.resolution, dtype=np.int)

        p = 0.0001
        try:
            p = scipy.misc.logsumexp(self._blurred[idx[0,:], idx[1,:]])
        except IndexError:
            pass
        # print("log_odds: {}".format(log_odds))

        # m = 1.0 - 1.0/(1.0 + np.exp(self._log_m))
        # m = 1.0 - 1.0/(1.0 + np.exp(self._blurred))
        # m = self._blurred
        # m = np.array(1. - m, dtype=np.float32)
        # m = cv2.cvtColor(m,cv2.COLOR_GRAY2BGR)
        # m = cv2.resize(m, (0,0), fx=4, fy=4)
        # cv2.imshow("blurred", m)
        # cv2.waitKey(1)
        # return 1.0 - 1.0/(1.0 + np.exp(log_odds))
        return p
//  [python]
def match_pts(self, x, z):
        # blurred = gaussian_filter(self._log_m, 0.2/self.resolution)

        scan_pts = x[:2, None] + z[0:1,:]*np.array([np.cos(z[1,:] + x[2]), np.sin(z[1,:] + x[2])]) + self.map_offset[:, None]

        idx = np.array(scan_pts/self.resolution, dtype=np.int)

        p = 0.0001
        try:
            p = scipy.special.logsumexp(self._blurred[idx[0,:], idx[1,:]])
        except IndexError:
            pass
        # print("log_odds: {}".format(log_odds))

        # m = 1.0 - 1.0/(1.0 + np.exp(self._log_m))
        # m = 1.0 - 1.0/(1.0 + np.exp(self._blurred))
        # m = self._blurred
        # m = np.array(1. - m, dtype=np.float32)
        # m = cv2.cvtColor(m,cv2.COLOR_GRAY2BGR)
        # m = cv2.resize(m, (0,0), fx=4, fy=4)
        # cv2.imshow("blurred", m)
        # cv2.waitKey(1)
        # return 1.0 - 1.0/(1.0 + np.exp(log_odds))
        return p
//  [python]
def logsumexp( *args, **kwargs ):
    '''Log-sum-exp, \log \sum_c \exp(logit_c), from scipy.'''
    if hasattr(scipy.misc, 'logsumexp'):
        return scipy.misc.logsumexp( *args, **kwargs )
    else:
        return scipy.special.logsumexp( *args, **kwargs )
//  [python]
def logsumexp( *args, **kwargs ):
    '''Log-sum-exp, \log \sum_c \exp(logit_c), from scipy.'''
    return scipy.special.logsumexp( *args, **kwargs )
//  [python]
def create_problem_shell(**config):
	ndim = config.get('ndim', 2)
	nmodes = config.get('nmodes', 2)
	width = numpy.array(config.get('width', [0.1/12]*nmodes))
	radius = numpy.array(config.get('radius', [2./12]*nmodes))
	tilt = config.get('tilt', 0)
	centers = numpy.array(config.get('centers', numpy.array([[0.3]*ndim, [0.7]*ndim])))
	
	def loglikelihood(u):
		#x = 12 * numpy.asarray(u) - 6
		l = []
		for sw, sr, sc in zip(width, radius, centers):
			dist = (((sc - u)**2).sum()**0.5 - sr)**2 
			lmode = - dist / (2 * sw**2) - log(2*pi*(sw)**2) / 2
			l.append(lmode)
		l = scipy.misc.logsumexp(l) + (u[0] - 0.5) * tilt
		return l
	def loglikelihood(u):
		x = numpy.asarray(u)
		dist = (((centers - x)**2).sum(axis=1)**0.5 - radius)**2
		lmode = -dist / (2. * width**2) - log(2 * pi * (width)**2) / 2
		l = scipy.misc.logsumexp(lmode) + (x - 0.5).sum() * tilt
		return l

	config['loglikelihood'] = loglikelihood
	
	# analytic solution:
	def shell_vol(r, w):
		# integral along the radius
		mom = scipy.stats.norm.moment(ndim - 1, loc=r, scale=w)
		# integral along the angles is surface of hyper-ball
		# which is volume of one higher dimension x (ndim + 1)
		vol = pi**((ndim)/2.) / scipy.special.gamma((ndim)/2. + 1)
		surf = vol * ndim
		return mom * surf
	Z_analytic = log(sum([shell_vol(sr, sw) for sr, sw in zip(radius, width)]))
	#Z_analytic = log(shell_vol(radius[0], width[0]) * 2)
	# values in arxiv:0809.3437 are off by log(12) in all dimensions
	
	config['Z_analytic'] = Z_analytic
	config['description'] = """A gaussian shell, in %d dimensions.
	Width of shells: %s, radius: %s, centers: %s
	
	<p>From <a href="http://arxiv.org/abs/0704.3704">MultiNest</a> 
	<a href="http://arxiv.org/abs/0809.3437">papers</a></p>
	""" % (ndim, width[0] if (width[0] == width).all() else width, 
		radius[0] if (radius[0] == radius).all() else radius, 
		centers[:,0] if (centers[:,0] == centers.transpose()).all() else centers, 
		)
	return config
//  [python]
def create_problem_shell(**config):
	ndim = config.get('ndim', 2)
	nmodes = config.get('nmodes', 2)
	width = numpy.array(config.get('width', [0.1/12]*nmodes))
	radius = numpy.array(config.get('radius', [2./12]*nmodes))
	tilt = config.get('tilt', 0)
	centers = numpy.array(config.get('centers', numpy.array([[0.3]*ndim, [0.7]*ndim])))
	
	def loglikelihood(u):
		#x = 12 * numpy.asarray(u) - 6
		l = []
		for sw, sr, sc in zip(width, radius, centers):
			dist = (((sc - u)**2).sum()**0.5 - sr)**2 
			lmode = - dist / (2 * sw**2) - log(2*pi*(sw)**2) / 2
			l.append(lmode)
		l = scipy.special.logsumexp(l) + (u[0] - 0.5) * tilt
		return l
	def loglikelihood(u):
		x = numpy.asarray(u)
		dist = (((centers - x)**2).sum(axis=1)**0.5 - radius)**2
		lmode = -dist / (2. * width**2) - log(2 * pi * (width)**2) / 2
		l = scipy.special.logsumexp(lmode) + (x - 0.5).sum() * tilt
		return l

	config['loglikelihood'] = loglikelihood
	
	# analytic solution:
	def shell_vol(r, w):
		# integral along the radius
		mom = scipy.stats.norm.moment(ndim - 1, loc=r, scale=w)
		# integral along the angles is surface of hyper-ball
		# which is volume of one higher dimension x (ndim + 1)
		vol = pi**((ndim)/2.) / scipy.special.gamma((ndim)/2. + 1)
		surf = vol * ndim
		return mom * surf
	Z_analytic = log(sum([shell_vol(sr, sw) for sr, sw in zip(radius, width)]))
	#Z_analytic = log(shell_vol(radius[0], width[0]) * 2)
	# values in arxiv:0809.3437 are off by log(12) in all dimensions
	
	config['Z_analytic'] = Z_analytic
	config['description'] = """A gaussian shell, in %d dimensions.
	Width of shells: %s, radius: %s, centers: %s
	
	<p>From <a href="http://arxiv.org/abs/0704.3704">MultiNest</a> 
	<a href="http://arxiv.org/abs/0809.3437">papers</a></p>
	""" % (ndim, width[0] if (width[0] == width).all() else width, 
		radius[0] if (radius[0] == radius).all() else radius, 
		centers[:,0] if (centers[:,0] == centers.transpose()).all() else centers, 
		)
	return config
//  [python]
def test_logsumexp_b():
    a = np.random.normal(size=(200, 500, 5))
    b = np.random.normal(size=(200, 500, 5)) ** 2.

    for axis in range(a.ndim):
        ans_ne = pymbar.utils.logsumexp(a, b=b, axis=axis)
        ans_no_ne = pymbar.utils.logsumexp(a, b=b, axis=axis, use_numexpr=False)
        ans_scipy = scipy.misc.logsumexp(a, b=b, axis=axis)
        eq(ans_ne, ans_no_ne)
        eq(ans_ne, ans_scipy)
//  [python]
def test_logsumexp_b():
    a = np.random.normal(size=(200, 500, 5))
    b = np.random.normal(size=(200, 500, 5)) ** 2.

    for axis in range(a.ndim):
        ans_ne = pymbar.utils.logsumexp(a, b=b, axis=axis)
        ans_no_ne = pymbar.utils.logsumexp(a, b=b, axis=axis, use_numexpr=False)
        ans_scipy = scipy.special.logsumexp(a, b=b, axis=axis)
        eq(ans_ne, ans_no_ne)
        eq(ans_ne, ans_scipy)
//  [python]
def map_assign_i(self, i):
        """
        Assign data vector `i` to the component giving the maximum posterior.

        This function is very similar to `gibbs_sample_inside_loop_i`, but
        instead of sampling the assignment, the MAP estimate is used.
        """

        # Compute log probability of `X[i]` belonging to each component
        # (24.26) in Murphy, p. 843
        log_prob_z = (
            np.ones(self.components.K_max)*np.log(
                float(self.alpha)/self.components.K_max + self.components.counts
                )
            )
        # (24.23) in Murphy, p. 842
        log_prob_z[:self.components.K] += self.components.log_post_pred(i)
        # Empty (unactive) components
        log_prob_z[self.components.K:] += self.components.log_prior(i)
        prob_z = np.exp(log_prob_z - logsumexp(log_prob_z))

        # Take the MAP assignment for `X[i]`
        k = np.argmax(prob_z)

        # There could be several empty, unactive components at the end
        if k > self.components.K:
            k = self.components.K

        logger.debug("Adding item " + str(i) + " to acoustic model component " + str(k))
        self.components.add_item(i, k)
//  [python]
def map_assign_i(self, i):
        """
        Assign data vector `i` to the component giving the maximum posterior.

        This function is very similar to `gibbs_sample_inside_loop_i`, but
        instead of sampling the assignment, the MAP estimate is used.
        """

        # Compute log probability of `X[i]` belonging to each component
        # (24.26) in Murphy, p. 843
        log_prob_z = (
            np.ones(self.components.K_max)*np.log(
                float(self.alpha)/self.components.K_max + self.components.counts
                )
            )
        # (24.23) in Murphy, p. 842
        log_prob_z[:self.components.K] += self.components.log_post_pred(i)
        # Empty (unactive) components
        log_prob_z[self.components.K:] += self.components.log_prior(i)
        prob_z = np.exp(log_prob_z - scipy.special.logsumexp(log_prob_z))

        # Take the MAP assignment for `X[i]`
        k = np.argmax(prob_z)

        # There could be several empty, unactive components at the end
        if k > self.components.K:
            k = self.components.K

        logger.debug("Adding item " + str(i) + " to acoustic model component " + str(k))
        self.components.add_item(i, k)
//  [python]
def save_negative_log_likelihood(self,t):
        """Get the negative log likelihood if you want to store it"""
        #DEBUG: Unclear why model and run length log distr has different length
        #       Maybe because of trimming?
        all_one_step_ahead_lklhoods_weighted = [
            (self.model_universe[m].one_step_ahead_predictive_log_probs +
             self.model_and_run_length_log_distr[m,
                        self.model_and_run_length_log_distr[m,:]> -np.inf])
             #self.model_universe[m].retained_run_lengths])
             #np.where(self.model_and_run_length_log_distr[m,:]> -np.inf)])
             for m in range(0, self.Q)]
        summed_up = -misc.logsumexp([item for entry in
            all_one_step_ahead_lklhoods_weighted for item in entry])
        self.negative_log_likelihood.append(summed_up)
//  [python]
def save_negative_log_likelihood(self,t):
        """Get the negative log likelihood if you want to store it"""
        #DEBUG: Unclear why model and run length log distr has different length
        #       Maybe because of trimming?
        all_one_step_ahead_lklhoods_weighted = [
            (self.model_universe[m].one_step_ahead_predictive_log_probs +
             self.model_and_run_length_log_distr[m,
                        self.model_and_run_length_log_distr[m,:]> -np.inf])
             #self.model_universe[m].retained_run_lengths])
             #np.where(self.model_and_run_length_log_distr[m,:]> -np.inf)])
             for m in range(0, self.Q)]
        summed_up = -scipy.special.logsumexp([item for entry in
            all_one_step_ahead_lklhoods_weighted for item in entry])
        self.negative_log_likelihood.append(summed_up)