Ejemplo n.º 1
0
      void _optimize_likelihood() {
        par::init();
        typedef std::pair<Eigen::VectorXd, double> pair_t;
        auto body = [ = ](int i) {
          // we need a copy because each thread should touch a copy of the GP!
          auto gp = *this;
          Eigen::VectorXd v = rprop::optimize([&](const Eigen::VectorXd & v) {
            return gp.log_likelihood(v);
          },
          [&](const Eigen::VectorXd & v) {
            return gp.log_likelihood_grad(v, false);
          },
          this->kernel_function().h_params_size(), Params::gp_auto::n_rprop());
          double lik = gp.log_likelihood(v);
          return std::make_pair(v, lik);
        };
        auto comp = [](const pair_t& v1, const pair_t& v2) {
          return v1.second > v2.second;
        };
        pair_t init(Eigen::VectorXd::Zero(1), -std::numeric_limits<float>::max());
        auto m = par::max(init, Params::gp_auto::rprop_restart(), body, comp);
        std::cout << "likelihood:" << m.second << std::endl;
        this->_kernel_function.set_h_params(m.first);

      }
Ejemplo n.º 2
0
inline double pmcmc_do (vsmc::Sampler<T> &sampler, std::size_t model_num)
{
    const std::size_t nchain = static_cast<std::size_t>(sampler.size());
    std::vector<double> log_likelihood(nchain);

    sampler.particle().value().comp_num(model_num);
    sampler.initialize();
    sampler.iterate(BurninNum);
    for (std::size_t k = 0; k != nchain; ++k)
        log_likelihood[k] = 0;
    for (std::size_t j = 0; j != IterNum; ++j) {
        sampler.iterate();
        for (std::size_t k = 0; k != nchain; ++k) {
            log_likelihood[k] += sampler.particle().value().
                state(k, 0).log_likelihood();
        }
    }
    for (std::size_t k = 0; k != nchain; ++k)
        log_likelihood[k] /= IterNum;
    double ps = sampler.particle().value().log_likelihood_const();
    for (std::size_t k = 1; k != nchain; ++k) {
        ps += sampler.particle().value().state(k, 0).alpha_inc() *
            0.5 * (log_likelihood[k -1] + log_likelihood[k]);
    }

    return ps;
}
Ejemplo n.º 3
0
/*
 * Sample the parameter space uniformly. Very slow!
 */ 
void explore_prior_space(live_point* livpnt,double llstar,unsigned num_dim,
unsigned num_par,ellipsis_mt19937_rng* rng,
void (*log_likelihood)(double *cube, unsigned ndim, unsigned npar, double *lnew))
{
	/*Evolve the object within the likelihood constraint*/
	
	unsigned i;
	double llik;
	
	live_point* trial_lvpnt=(live_point*)malloc(sizeof(live_point));
	init_live_point(trial_lvpnt,num_dim);
	
	for(;;)
	{
	
		for(i=0;i<num_dim;++i)
		{
			trial_lvpnt->x[i]=genrand_uniform(rng);
		}
			
		log_likelihood(trial_lvpnt->x,num_dim,num_par,&llik);
		trial_lvpnt->log_lik=llik;
		
		/*accpet if and only if within l > lstar */
		if(trial_lvpnt->log_lik > llstar)
		{
			copy_live_point(livpnt,trial_lvpnt);
			break;
		}
	}
	
	free(trial_lvpnt);
	
}
Ejemplo n.º 4
0
void CGppe::Approx_CGppe_Laplace(const VectorXd & theta_x, const VectorXd& theta_t, const double& sigma, const MatrixXd& t, const MatrixXd &x, const TypePair & all_pairs,
                               const VectorXd & idx_global, const VectorXd& idx_global_1, const VectorXd& idx_global_2,
                               const VectorXd& ind_t, const VectorXd& ind_x, int M, int N)
{
    //Parameters function initialization
    double eps = 1E-6, psi_new, psi_old;
    M = all_pairs.rows();
    int n = M * N;
    f = VectorXd::Zero(n);
    VectorXd fvis = VectorXd::Zero(idx_global.rows());
    VectorXd deriv;
    double loglike = 0;

    covfunc_t->SetTheta(theta_t);
    covfunc_x->SetTheta(theta_x);

    MatrixXd Kt = covfunc_t->ComputeGrandMatrix(t);
    Kx = covfunc_x->ComputeGrandMatrix(x);

    MatrixXd K = GetMat(Kt, ind_t, ind_t).array() * GetMat(Kx, ind_x, ind_x).array();

    loglike = log_likelihood( sigma, all_pairs, idx_global_1, idx_global_2, M, N);
    Kinv = K.inverse();
    psi_new = loglike - 0.5 * fvis.transpose() * Kinv * fvis;
    psi_old = INT_MIN;
    while ((psi_new - psi_old) > eps)
    {
        psi_old = psi_new;
        deriv = deriv_log_likelihood_CGppe_fast( sigma, all_pairs, idx_global_1, idx_global_2, M, N);
        W = -deriv2_log_likelihood_CGppe_fast(sigma, all_pairs, idx_global_1, idx_global_2, M, N);
        W = GetMat(W, idx_global, idx_global);
        llt.compute(W + Kinv);
        L = llt.matrixL(); //no need to extract the triangular matrix here
        fvis = llt.solve(GetVec(deriv, idx_global) + W * fvis);
        for (int w = 0;w < idx_global.rows();w++)
        {
            f(idx_global(w)) = fvis(w);
        }
        loglike = log_likelihood( sigma, all_pairs, idx_global_1, idx_global_2, M, N);
        psi_new = loglike - 0.5 * fvis.transpose() * Kinv * fvis;
    }





}
Ejemplo n.º 5
0
    void calc_theta_loglik()
    {
        loglik_theta = 0.0;

        for (int i=0; i!=m->nparams; ++i)
        {
            loglik_theta += log_likelihood(m->param_dists[i], theta[i], m->param_hyper[i]);
            loglik_theta += jacobian_adj(m->param_trans[i], theta[i], m->param_hyper[i]);
        }
    }
Ejemplo n.º 6
0
float score_gmm (int gmm_index, float *input) { 
	gmm *g = &gmms[gmm_index];	
	const float *mixtures = g->mixture_weights;
	float score = 0.0f;
	int k=0;
	for(k = 0; k < g->count; k++) {
		float likelihood = log_likelihood( &g->gaussians[k], input) + mixtures[k];
		score = logsum(score, likelihood);			
	}
	return score;	
}
Ejemplo n.º 7
0
 double LRM::Loglike(Vec &g, Mat &h, uint nd)const{
   if(nd>=2) return log_likelihood(Beta(), &g, &h);
   if(nd==1) return log_likelihood(Beta(), &g, 0);
   return log_likelihood(Beta(), 0, 0);
 }
Ejemplo n.º 8
0
 double log_likelihood() const
 {
   return log_likelihood(discount, strength);
 }
Ejemplo n.º 9
0
void run(std::string tree_filename, std::string fasta_filename, std::string model_name) {
  Model Mod;                 // The model
  Counts data;               // the counts
  Parameters Par;            // the parameters
  std::vector<double> br;    // branch lengths
  double eps = 1e-8;         // The threshold for the EM algorithm.

  Parameters Parsim;         // used for simulating data.
  std::vector<double> brsim; // branch lengths of simulated data.

  std::vector<std::vector<double> > Cov;  // Covariance matrix
  std::vector<double> variances;          // The variances


  bool simulate;
  bool nonident;
  std::string parameters_filename;
  std::string covariances_filename;

  // initialize random number generator with time(0).
  random_initialize();

  parameters_filename = strip_extension(fasta_filename) + ".dat";
  covariances_filename = strip_extension(fasta_filename) + ".cov";

  // Creates the pointers to the model-specific functions.
  Mod = create_model(model_name);
  std::cout << "Model: " << Mod.name << std::endl;

  // Reads the tree.
  Tree T = read_tree(tree_filename);

  // Prints the Tree
  std::cout << "Tree:" << std::endl;
  print_tree(T);

  // Check for possible nonidentifiability issues.
  nonident = nonident_warning(T);

  // Initialize the parameters for simulation of K81 data for testing
  Parsim = create_parameters(T);

  if (fasta_filename == ":test") {      // if fasta file is :test generate random data.
    simulate = true;

    // Warn
    std::cout << "WARNING: Using simulated data " << std::endl << std::endl;

    // Generate random parameters
    random_parameters_length(T, Mod, Parsim);

    // Simulate the data
    data = random_fake_counts(T, 1000, Parsim);

    // Prints branch-lengths for future check.
    branch_lengths(Parsim, brsim);
    std::cout << "Simulated branch lengths:" << std::endl;
    print_vector(brsim);

  } else {                                  // otherwise read the data
    simulate = false;

    // Read the counts.
    std::cout << "Reading fasta file:" << std::endl;
    read_counts(T, data, fasta_filename);
    add_pseudocounts(0.01, data);
    std::cout << std::endl;
  }

  // Check whether the data and the tree match.
  if (T.nalpha != data.nalpha || T.nleaves != data.nspecies) {
    throw std::invalid_argument("The order of the sequences or their number and the phylogenetic tree do not match.");
  }

  //Par = create_parameters(T);
  //print_parameters(Par);
  //print_vector(Par.r);

  //clock_t
  long start_time, end_time;

  // Runs the EM algorithm. Par is used as initial parameters.
  // After execution, Par contains the MLE computed by the algorithm.

 // for local max over multiple iterations
  Parameters Parmax = Par;
  Model Modmax = Mod;

  float likelL = 0.0;
  float likelMax = -1000000.0;
  float timerec;
  float timemax;

  int outfiles; //whether to save output
  std::cout << "Starting the EM algorithm: " << std::endl;

  int s;
  int S = 0; //count of cases with neg branches

  int iter;
  int iterMax;

  for (int it_runs = 0; it_runs < 10; it_runs++) {
      Par = create_parameters(T);
      Mod = create_model(model_name);
      std::cout << it_runs << ", " ;

      start_time = clock();

      std::tie(likelL, iter) = EMalgorithm(T, Mod, Par, data, eps);

      end_time = clock();
      //print_parameters(Par);

      // Choses the best permutation.
      guess_permutation(T, Mod, Par);

      branch_lengths(Par, br);

      //print_vector(br);
      s = find_negative(br);
      S +=s;
      timerec = ((float)end_time - start_time) / CLOCKS_PER_SEC;

      //assign the 1st iter time value, inc ase it's the best
      if (it_runs == 0){
        timemax = timerec;
        iterMax = iter;
      }

      if (likelL > likelMax){
        Parmax = Par;
        Modmax = Mod;
        timemax = timerec;
        likelMax = likelL;
        iterMax = iter;
      }

  }


  // If parameters are not identifiable, the computation of the covariance matrix will
  // fail as the Fisher info matrix will not be invertible.
  if (!nonident) {
    // Compute the covariance matrix using observed Fisher.
    full_MLE_observed_covariance_matrix(T, Modmax, Parmax, data, Cov);
    variances.resize(Cov.size());
    for(unsigned int i=0; i < Cov.size(); i++) {
      variances[i] = Cov[i][i];
    }

    // OUTPUT Save the sigmas into a file
    //save_sigmas_to(covariances_filename, Cov);
  }

  std::cout << std::endl;
  std::cout << "Finished." << std::endl;
  std::cout << "Likelihood: " << log_likelihood(T, Parmax, data) << std::endl ;
  std::cout << "Time: " << timemax << std::endl << std::endl;
  std::cout << "negative branches: "  << S << std::endl;
  std::cout << "Iter: "  << iterMax << std::endl;

  //std::cout << "Branch lengths: " << std::endl;
  //print_vector(br);
  outfiles = 0;
  if (!nonident && outfiles) {
    std::cout << "Parameter variances: " << std::endl;
    print_vector(variances);
  }

  std::cout << "Newick Tree:" << std::endl;
  print_newick_tree(T, br);

  // if is a simulation, print the L2 distance !
  if (simulate) {
    std::cout << "L2 distance:   " << parameters_distance(Par, Parsim) << std::endl;
    std::cout << "KL divergence: " << KL_divergence(T, Par, Parsim) << std::endl;
    std::cout << std::endl;
  }

  // if it is not a simulation, store the parameters in a file !
  if (!simulate && outfiles) {
    std::fstream st;
    st.precision(15);
    st.setf(std::ios::fixed,std::ios::floatfield);
    st.open(parameters_filename.c_str(), std::ios::out);
    print_parameters(Par, st);
  }
}
Ejemplo n.º 10
0
/*
 * Explore the parameter space with MCMC.
 * See Sivia & Skilling 2006, page 193 for more details
 */
void explore_prior_space_with_mcmc(live_point* livpnt,double llstar,unsigned num_dim,
	unsigned num_par,ellipsis_mt19937_rng* rng,
	void (*log_likelihood)(double *cube, unsigned ndim, unsigned npar, double *lnew))
{
	/*Evolve the object within the likelihood constraint*/
	
	unsigned num_samples=20;
	double step=0.1;
	unsigned accept=0;
	unsigned reject=0;
	unsigned i;
	double llik;
	unsigned samps=0;
	double* uvals;
	double* uvals_new;
	double* xvals;
	double* xvals_new;
	double llik_new;
	
	uvals=(double*)malloc(num_dim*sizeof(double));
	uvals_new=(double*)malloc(num_dim*sizeof(double));
	xvals=(double*)malloc(num_dim*sizeof(double));
	xvals_new=(double*)malloc(num_dim*sizeof(double));

	
	for(i=0;i<num_dim;++i)
	{
		uvals[i]=livpnt->u[i];
		xvals[i]=livpnt->x[i];
		llik_new=livpnt->log_lik;
	}
	
	
	for(;;)
	{
	
		for(i=0;i<num_dim;++i)
		{
			uvals_new[i]=uvals[i]+step*(2.*genrand_uniform(rng)-1.);
			uvals_new[i]-=floor(uvals_new[i]);
			xvals_new[i]=uvals_new[i];
		}
			
		log_likelihood(xvals_new,num_dim,num_par,&llik);
		
		/*accpet if and only if within l > lstar */
		if(llik > llstar)
		{
			for(i=0;i<num_dim;++i)
			{
				uvals[i]=uvals_new[i];
				xvals[i]=xvals_new[i];
			}
			llik_new=llik;
			++accept;
		}
		else
		{
			++reject;
		}
		
		/*refine step size to let acceptance ratio converge around 50% */
		if(accept>reject)
		{
			step*=exp(1./(double)accept);
		}
		if(accept<reject)
		{
			step/=exp(1./(double)reject);
		}
		
		
		if(accept>0 && samps>=num_samples)
		{
			for(i=0;i<num_dim;++i)
			{
				livpnt->u[i]=uvals[i];
				livpnt->x[i]=xvals[i];
			}
			livpnt->log_lik=llik_new;
			break;
		}
		++samps;
	}
	
	free(uvals);
	free(uvals_new);
	free(xvals);
	free(xvals_new);
}
Ejemplo n.º 11
0
/*
 *This function implements an approximation to Mukherjee's Ellipsoidal methods.
 * EXPERIMENTAL -> DO NOT USE
 */
void explore_prior_space_with_mcmc_var_tuned(live_point* livpnt,double llstar,
	live_point* phys_live_points,unsigned num_phys_live,unsigned num_dim,unsigned num_par,	ellipsis_mt19937_rng* rng,
	void (*log_likelihood)(double *cube, unsigned ndim, unsigned npar, double *lnew))
{
	/*Evolve the object within the likelihood constraint*/
	
	unsigned num_samples=20;
	unsigned i,j;
	double llik;
	unsigned samps=0;
	unsigned accept=0;
	unsigned reject=0;
	double step=2.;
	double* sigma;
	double* mean;
	double sum;
	double sum2;
	double enlarge_fact=2.;
	double* uvals;
	double* uvals_new;
	double* xvals;
	double* xvals_new;
	double llik_new;
	unsigned best=0;
	
	/*From the available live points, estimate the variance in each dimension*/
	sigma=(double*)malloc(num_dim*sizeof(double));
	mean=(double*)malloc(num_dim*sizeof(double));
	
	for(i=0;i<num_phys_live;++i)
	{
		if(phys_live_points[i].log_lik>phys_live_points[best].log_lik)
		{
			best=i;
		}
	}
	
	/*printf("\nbest= %d\tval=%f\n",best,phys_live_points[best].log_lik);*/
	
	for(i=0;i<num_dim;++i)
	{
		sum=0;
		sum2=0;
		for(j=0;j<num_phys_live;++j)
		{
			sum+=phys_live_points[j].u[i];
			sum2+=phys_live_points[j].u[i]*phys_live_points[j].u[i];
		}
		sigma[i]=sqrt( (sum2-sum*sum/(double)num_phys_live)/(double)num_phys_live );
		/*mean[i]=sum/(double)num_phys_live;*/
		mean[i]=(phys_live_points[best].u[i]+sum/(double)num_phys_live)*0.5;
		/*printf("%f\t",mean[i]);*/
	}
	/*printf("\n");*/
	
	uvals=(double*)malloc(num_dim*sizeof(double));
	uvals_new=(double*)malloc(num_dim*sizeof(double));
	xvals=(double*)malloc(num_dim*sizeof(double));
	xvals_new=(double*)malloc(num_dim*sizeof(double));
	
	/*printf("\nllstar= %f\n",llstar);*/
	

	for(i=0;i<num_dim;++i)
	{
		uvals[i]=livpnt->u[i];
		xvals[i]=livpnt->x[i];
		llik_new=livpnt->log_lik;
	}
	
	
	for(;;)
	{
	
		for(i=0;i<num_dim;++i)
		{
			uvals_new[i]=(uvals[i]+mean[i])*0.5+sigma[i]*genrand_uniform(rng);
			xvals_new[i]=uvals_new[i];
		}
			
		log_likelihood(xvals_new,num_dim,num_par,&llik);
		
		/*trial_lvpnt->log_lik=llik*/
		
		/*accpet if and only if within l > lstar */
		if(llik > llstar)
		{
			for(i=0;i<num_dim;++i)
			{
				uvals[i]=uvals_new[i];
				xvals[i]=xvals_new[i];
			}
			llik_new=llik;
			++accept;
		}
		else
		{
			++reject;
		}
		
		/*refine step size to let acceptance ratio converge around 50% */
		if(accept>reject)
		{
			step*=exp(1./(double)accept);
		}
		if(accept<reject)
		{
			step/=exp(1./(double)reject);
		}
		
		if(accept>0 && samps>=num_samples)
		{
			/*copy_live_point(livpnt,trial_lvpnt);*/
			for(i=0;i<num_dim;++i)
			{
				livpnt->u[i]=uvals[i];
				livpnt->x[i]=xvals[i];
			}
			livpnt->log_lik=llik_new;
			break;
		}
		++samps;
		
		/*printf("accept=%d\tsamps= %d\n",accept,samps);*/
	}
	
	free(uvals);
	free(uvals_new);
	free(xvals);
	free(xvals_new);
	
	free(sigma);
	free(mean);
	
}
/*
 * Compute the following entities:
 *      - responsibilities r(k|ij)
 *      - mu_ij_k
 *      - Lambda_ij_k
 *      - log determinante Lamda_ij_k
 *
 *  And then use these to compute likelihood and gradients
 */
void Likelihood_Protein::compute_f_df(int hessian_pseudocount)
{


	//initialize parameters for second gaussian
    mu_ij_k.zeros(400, this->nr_components);
    lambda_ij_k.zeros(400, 400, this->nr_components);
    lambda_ij_k_inv.zeros(400, 400, this->nr_components);
    log_det_lambda_ij_k.zeros(this->nr_components);
	responsibilities.zeros(this->nr_components);

    //initialize likelihood vector
    log_likelihood.zeros(this->number_of_pairs);

    //intialize gradients to zero
	grad_weight.zeros(this->nr_components, 2);
	grad_mu.zeros(400,this-> nr_components);
	grad_precMat.zeros(400, this->nr_components);

    for(int pair = 0; pair < this->number_of_pairs; pair++){

		int i 				= this->i_indices(pair);
		int j 				= this->j_indices(pair);
		int lin_index       = i*(L - (i+1)/2.0 - 1) + j - 1; //i*L - i*(i+1)/2 + j-(i+1);
		int contact         = this->protein_contacts(pair);

        //for computation of likelihood
		arma::vec log_density(this->nr_components, arma::fill::zeros);

        arma::vec vqij = mq_ij.col(lin_index);
        double N_ij = mN_ij(i,j);
		arma::vec w_ij = w_ij3d.tube(i,j);
		//diagonal matrix Qij = diag(q'ji)
		//q'ijab = q(x_i=a, x_j=b) - (lambda_w * wijab / N_ij) --> has been precomputed
		arma::mat Qij 		= arma::diagmat(vqij);

		//outer product
		arma::mat qij_prod = vqij * vqij.t();

		//determine negative Hessian = Hij
		arma::mat diff = Qij - qij_prod;
		arma::mat H_ij = N_ij * diff + regularizer_w; //eq 37

        // remove after debugging ---------------------------------------------------------------------------------
		//debugging artefacts in learning
		//add counts to Hessian to see if we have problems with non-informative data
		H_ij.diag() += hessian_pseudocount;
		//H_ij = arma::diagmat(H_ij);
		// remove after debugging ---------------------------------------------------------------------------------

		//precompute product H_ij * wij
		arma::vec Hij_wij_prod = H_ij * w_ij;

		for(int k = 0; k < this->nr_components; k++){

            //gaussian parameters of coupling prior
            double weight_k 		        = this->parameters.get_weight(k, contact);
			arma::vec mu_k 				    = this->parameters.get_mean(k);
			arma::mat lambda_k 			    = this->parameters.get_precMat(k);


            //---------------- simplify computation in case that lambda_k is diagonal matrix
            // A, A_inv, lambda_k, Qij are diagonal matrices
            arma::vec A = N_ij * vqij + lambda_k.diag();     //represents diagonal matrix
            arma::vec A_inv = 1.0 / A;                    //represents diagonal matrix
            double log_det_A	= arma::sum(arma::log(A));
            arma::vec Ainv_qij_product  = A_inv % vqij;   ////column vector
            double triple_product 	    = arma::sum(vqij % Ainv_qij_product);
            //---------------- matrix computations in case lambda_k is NOT diagonal matrix
			//A is a diagonal matrix, as Qij and lambda_k are diagonal matrices
			//arma::mat A 		= N_ij * Qij + lambda_k;                    //diagonal
			//arma::mat A_inv 	= arma::diagmat(1.0 / A.diag());            //diagonal
			//double log_det_A	= arma::sum(arma::log(A.diag()));
			//arma::vec Ainv_qij_product  = arma::vec(A_inv * vqij);          //400x1 dim matrix
			//double triple_product 	    = arma::as_scalar(vqij.t() * Ainv_qij_product);


			//compute lambda_ij_k_mat
			arma::mat lambda_ij_k_mat  	= H_ij - regularizer_w + lambda_k;
			lambda_ij_k.slice(k) 	    = lambda_ij_k_mat;






            //debugging: we assume diagonal Hessian ================================================================
//            arma::mat lambda_ij_k_mat_inv(400,400,arma::fill::zeros);
//            lambda_ij_k_mat_inv.diag() = 1.0 / lambda_ij_k_mat.diag();
            //debugging=======================================================================================
			//compute inverse of lambda_ij_k_mat
			//---------------- simplify computation in case that lambda_k is diagonal matrix
			arma::mat lambda_ij_k_mat_inv = arma::diagmat(A_inv) + (Ainv_qij_product * Ainv_qij_product.t()) / (1.0/N_ij - triple_product);
			//---------------- matrix computations in case lambda_k is NOT diagonal matrix
			//arma::mat  lambda_ij_k_mat_inv  = A_inv + (Ainv_qij_product * Ainv_qij_product.t()) / (1.0/N_ij - triple_product);
			lambda_ij_k_inv.slice(k) 	    = lambda_ij_k_mat_inv;


		    //compute mu_ij_k from precomputed entities
			arma::vec mu_ij_k_vec      = lambda_ij_k_mat_inv * ( Hij_wij_prod + lambda_k * mu_k);
			mu_ij_k.col(k)             = mu_ij_k_vec;


            //debugging: we assume diagonal Hessian ================================================================
//            log_det_lambda_ij_k(k) = arma::sum(arma::log(lambda_ij_k_mat.diag()));
            //debugging=======================================================================================
			//save log determinant of lambda_ij_k, see page 16 Saikats theory
			log_det_lambda_ij_k(k) = log(1 - N_ij * triple_product) + log_det_A;

			//ratio of two gaussians in log space
			//     N(0 | mu_k, lambda_k)
            //------------------------------
            //  N(0 | mu_ij_k, lambda_ij,k)
			double gaussian_ratio_logdensity = log_density_gaussian_ratio(	mu_k,
																			mu_ij_k_vec,
																			lambda_k,
																			lambda_ij_k_mat,
																			this->parameters.get_log_det_inv_covMat(k),
																			log_det_lambda_ij_k(k) );


            if(this->debug > 0 and gaussian_ratio_logdensity>1000){
                std::cout  << protein_id << " " << i << " " << j << " " << pair << " " << contact << " " << k << std::endl;
                std::cout  << "Gaussian log density > 1: " << gaussian_ratio_logdensity << std::endl;
                std::cout  << "A_inv.max() : " << A_inv.max()  << std::endl;
                arma::uword max_ind = index_max(A_inv);
                std::cout  << "A(max_ind) : " << A(max_ind)  << std::endl;
                std::cout  << "vqij(max_ind): " << vqij(max_ind) << std::endl;
                std::cout  << "N_ij: " << N_ij << std::endl;
                std::cout  << "mu_ij_k_vec(max_ind) : " << mu_ij_k_vec(max_ind)  << std::endl;
                std::cout  << "mu_k(max_ind) : " << mu_k(max_ind)  << std::endl;
                std::cout  << "lambda_ij_k_mat(max_ind, max_ind) : " << lambda_ij_k_mat(max_ind, max_ind)  << std::endl;
                std::cout  << "lambda_ij_k_mat_inv(max_ind, max_ind) : " << lambda_ij_k_mat_inv(max_ind, max_ind)  << std::endl;
                std::cout  << "lambda_k(max_ind, max_ind) : " << lambda_k(max_ind, max_ind)  << std::endl;
                std::cout  << "parameters.get_log_det_inv_covMat(k) : " << this->parameters.get_log_det_inv_covMat(k)  << std::endl;
                std::cout  << "log_det_lambda_ij_k(k) : " << log_det_lambda_ij_k(k)  << std::endl;
            }


            log_density(k) = log(weight_k) + gaussian_ratio_logdensity;

		}//end loop over components k

		//Johannes suggestion how to precisely compute the responsibilities
		double a_max = arma::max(log_density);
		this->responsibilities = arma::exp(log_density - a_max);//r_nk = exp( a_nk - a_max)
		double sum_resp = arma::sum(this->responsibilities);    //sum += r_nk
		this->responsibilities /= sum_resp; //normalization of responsibilities, NOT in log space  => r_nk /= sum;



		//save neg likelihood of current pair
		double f = log(sum_resp) + a_max;
		if(! std::isnormal(f)) {
				std::cout  << "ERROR: likelihood cannot be computed for protein " << protein_id << ", i " << i << ", j " << j << " ("<< contact <<"): " << f << std::endl;
                std::cout  << "Nij: " << N_ij << ", sum_resp: " << sum_resp << ", a_max: " << a_max << std::endl;
                for(int k = 0; k < this->nr_components; k++){
                    std::cout  << "component: " << k << ", sum_precMat(k)diag: "<< arma::sum(this->parameters.get_precMat(k).diag()) << ", responsibilty:" << this->responsibilities(k) << ", log_density: " << log_density(k) << ", log_det_lambda_ij_k: " << log_det_lambda_ij_k(k) << std::endl;
                }

				continue;
		} else log_likelihood(pair) = f;


        // Compute ALL gradients for ALL components
        for(int k = 0; k < this->nr_components; k++){

            //weights (either for contact or non_contact)
            grad_weight(k, contact) += gradient_weight_comp(k, contact);

            //mu
            grad_mu.col(k) += gradient_mu_comp(k);

            //precMat - diagonal
            arma::mat grad_precMat_protein = gradient_precisionMatrix_comp(k);
            grad_precMat.col(k) += grad_precMat_protein.diag();

        }//end components


	}//end loop over ij pairs


}
/*
 * This function calculates the Hessian and mu_ij_k and Lambda_ij_k
 * for all pairs (i,j) in the batch
 * and for all components k
 *
*/
void Likelihood_Protein::compute_negLL(int nr_threads_prot)
{
    //initialize likelihood vector
    log_likelihood.zeros(this->number_of_pairs);

	#pragma omp parallel for num_threads(nr_threads_prot)
    for(int pair = 0; pair < this->number_of_pairs; pair++){

		int i 				= this->i_indices(pair);
		int j 				= this->j_indices(pair);
		int lin_index       = i*(L - (i+1)/2.0 - 1) + j - 1; //i*L - i*(i+1)/2 + j-(i+1);
		int contact         = this->protein_contacts(pair);

        //for computation of likelihood
		arma::vec log_density(this->nr_components, arma::fill::zeros);

        arma::vec vqij = mq_ij.col(lin_index);
        double N_ij = mN_ij(i,j);
		arma::vec w_ij = w_ij3d.tube(i,j);
		//arma::vec vqij = q_ij3d.tube(i,j);

		//diagonal matrix Qij = diag(q'ji)
		//q'ijab = q(x_i=a, x_j=b) - (lambda_w * wijab / N_ij) --> has been precomputed
		arma::mat Qij 		= arma::diagmat(vqij);

		//outer product
		arma::mat qij_prod = vqij * vqij.t();

		//determine negative Hessian = Hij
		arma::mat diff = Qij - qij_prod;
		arma::mat H_ij = N_ij * diff + regularizer_w; //eq 37

		//precompute product H_ij * wij
		arma::vec Hij_wij_prod = H_ij * w_ij;


		for(int k = 0; k < this->nr_components; k++){


            //gaussian parameters of coupling prior
            double weight_k 		        = this->parameters.get_weight(k, contact);
			arma::vec mu_k 				    = this->parameters.get_mean(k);
			arma::mat lambda_k 			    = this->parameters.get_precMat(k);


            //---------------- simplify computation in case that lambda_k is diagonal matrix
            // A, A_inv, lambda_k, Qij are diagonal matrices
            arma::vec A = N_ij * vqij + lambda_k.diag();     //represents diagonal matrix
            arma::vec A_inv = 1.0 / A;                    //represents diagonal matrix
            double log_det_A	= arma::sum(arma::log(A));
            arma::vec Ainv_qij_product  = A_inv % vqij;   ////column vector
            double triple_product 	    = arma::sum(vqij % Ainv_qij_product);
            //---------------- matrix computations in case lambda_k is NOT diagonal matrix
			//A is a diagonal matrix, as Qij and lambda_k are diagonal matrices
			//arma::mat A 		= N_ij * Qij + lambda_k;                    //diagonal
			//arma::mat A_inv 	= arma::diagmat(1.0 / A.diag());            //diagonal
			//double log_det_A	= arma::sum(arma::log(A.diag()));
			//arma::vec Ainv_qij_product  = arma::vec(A_inv * vqij);          //400x1 dim matrix
			//double triple_product 	    = arma::as_scalar(vqij.t() * Ainv_qij_product);


			//compute lambda_ij_k_mat
			arma::mat lambda_ij_k_mat  	= H_ij - regularizer_w + lambda_k;


            //debugging: we assume diagonal Hessian ================================================================
//            arma::mat lambda_ij_k_mat_inv(400,400,arma::fill::zeros);
//            lambda_ij_k_mat_inv.diag() = 1.0 / lambda_ij_k_mat.diag();
            //debugging=======================================================================================
			//compute inverse of lambda_ij_k_mat
			//---------------- simplify computation in case that lambda_k is diagonal matrix
			arma::mat lambda_ij_k_mat_inv = arma::diagmat(A_inv) + (Ainv_qij_product * Ainv_qij_product.t()) / (1.0/N_ij - triple_product);
			//---------------- matrix computations in case lambda_k is NOT diagonal matrix
			//arma::mat  lambda_ij_k_mat_inv  = A_inv + (Ainv_qij_product * Ainv_qij_product.t()) / (1.0/N_ij - triple_product);



		    //compute mu_ij_k from precomputed entities
			arma::vec mu_ij_k_vec      = lambda_ij_k_mat_inv * ( Hij_wij_prod + lambda_k * mu_k);



            //debugging: we assume diagonal Hessian ================================================================
//            log_det_lambda_ij_k(k) = arma::sum(arma::log(lambda_ij_k_mat.diag()));
            //debugging=======================================================================================
			//save log determinant of lambda_ij_k, see page 16 Saikats theory
			double log_det_lambda_ij = log(1 - N_ij * triple_product) + log_det_A;

			//ratio of two gaussians in log space
			//     N(0 | mu_k, lambda_k)
            //------------------------------
            //  N(0 | mu_ij_k, lambda_ij,k)
			double gaussian_ratio_logdensity = log_density_gaussian_ratio(	mu_k,
																			mu_ij_k_vec,
																			lambda_k,
																			lambda_ij_k_mat,
																			this->parameters.get_log_det_inv_covMat(k),
																			log_det_lambda_ij);


            log_density(k) = log(weight_k) + gaussian_ratio_logdensity;


//            if ((i == 0) && (j == 12)){
//                std::cout  << " " << std::endl;
//                std::cout  << protein_id << " i: " << i << " j: " << j << " contact=" << contact << " component: " << k << std::endl;
//                std::cout  << "triple_product : " << triple_product  << std::endl;
//                std::cout  << "log_det_A : " << log_det_A  << std::endl;
//                std::cout  << "lambda_ij_k_mat(0,1) : " << lambda_ij_k_mat(0,1) << "lambda_ij_k_mat(0,2) : " << lambda_ij_k_mat(0,2) << "lambda_ij_k_mat(2,0) : " << lambda_ij_k_mat(2,0)  << std::endl;
//                std::cout  << "mu_ij_k_vec(0) : " << mu_ij_k_vec(0) << "mu_ij_k_vec(1) : " << mu_ij_k_vec(1) << "mu_ij_k_vec(2) : " << mu_ij_k_vec(2)  << std::endl;
//                std::cout  << "Gaussian log density: " << gaussian_ratio_logdensity << std::endl;
//                std::cout  << "log_density(k): " << log_density(k)<< std::endl;
//                std::cout  << "log(weight_k): " << log(weight_k) << " weight_k: " << weight_k << std::endl ;
//            }



		}//end loop over components k



		//Johannes suggestion how to precisely compute the responsibilities
		double a_max = arma::max(log_density);
		arma::vec resps = arma::exp(log_density - a_max);//r_nk = exp( a_nk - a_max)
		double sum_resp = arma::sum(resps);    //sum += r_nk


		//save neg likelihood of current pair
		double f = log(sum_resp) + a_max;

//        if ((i == 0) && (j == 12)){
//            std::cout  << "a_max : " << a_max  << std::endl;
//            std::cout  << "sum_resp : " << sum_resp  << std::endl;
//            std::cout  << "f : " << f  << std::endl;
//        }


		if(! std::isnormal(f)) {
				std::cout  << "ERROR: likelihood cannot be computed for protein " << protein_id << ", i " << i << ", j " << j << " ("<< contact <<"): " << f << std::endl;
                std::cout  << "Nij " << N_ij << ", sum_resp: " << sum_resp << ", a_max: " << a_max << std::endl;
                for(int k = 0; k < this->nr_components; k++){
                    std::cout  << "component: " << k << ", sum_precMat(k)diag: "<< arma::sum(this->parameters.get_precMat(k).diag()) << ", responsibilty:" << resps(k)/sum_resp << ", log_density: " << log_density(k) << std::endl;
                }

				continue;
		} else log_likelihood(pair) = f;

	}//end of parallelized for loop over ij pairs

}
Ejemplo n.º 14
0
int main(int argc, char *argv[]) {

	int nobs, sizex, nsample = 0;
	char *location = NULL;
	int ret = 0;

	//////////////////////////////////////
	/////////////// PARSERS //////////////
	//////////////////////////////////////
	// Parse the command line
	ret = parse_command_line(argc,argv,&nobs,&sizex,&nsample,&location);
	if( ret != PARSER_SUCCESS ) {
		printf("Parsing failed ! Exiting...\n");
		return EXIT_FAILURE;
	}

	// Parse the data on master
	double *buffer_X = (double*)malloc(nobs*sizex*sizeof(double));	
	double *isigma = (double*)malloc(sizex*sizex*sizeof(double));
	double *mu = (double*)malloc(sizex*sizeof(double));
	double det_sigma = 0.0; 

	ret = read_data(buffer_X, isigma, &det_sigma, mu, &nobs, &sizex, location);
	if( ret != PARSER_SUCCESS ) {
		printf("Parsing failed ! Exiting...\n");
		return EXIT_FAILURE;
	}	

	////////////////////////////////////////
	/////////////// Variables //////////////
	////////////////////////////////////////
	// Thread variables
	int nthreads = 1;
	int th_num = 0;
	int th_nobs = nobs;

	nthreads = get_num_threads();


	// Timing variables
	double tic, toc, tot_time = 0.0; 

	//// Arrays for all threads 
	// The pool is allocated inside the shared memory
	double *pool_LV = (double*)malloc(nobs*sizex*sizeof(double)); // Left hand side vector (X-mu)
	double *pool_tmp = (double*)malloc(nobs*sizex*sizeof(double)); // Temporary holder for (X-mu)*SIG 
	double *pool_ones = (double*)malloc(nobs*sizeof(double)); // Temporary holder to create LV
	double *pool_res = (double*)malloc(nthreads*sizeof(double)); // Each thread puts its result in pool_res
	
	// Use pointers to get the correct location in the array 
	double *LV = NULL;
	double *tmp = NULL;
	double *ones = NULL;
	double *X = NULL;

	// Holder for final sum
	double final_sum = 0.0;

	////////////////////////////////////////
	/////////////// Algorithm //////////////
	////////////////////////////////////////
	//// Start time sampling
	for(int k = 0; k < nsample; k++) {
		tic = omp_get_wtime();
		final_sum = 0.0;

		// Main driver
		#pragma omp parallel private(th_num,th_nobs,LV,tmp,ones,X) default(shared)
		{
			// Get thread number
			th_num = omp_get_thread_num();
			// Total number of observations for that thread
			th_nobs = nobs/nthreads;

			// Use the address to point to the correct location in the vector
			X = &buffer_X[th_num*nobs*sizex/nthreads];
			LV = &pool_LV[th_num*th_nobs*sizex];
			tmp = &pool_tmp[th_num*th_nobs*sizex];
			ones = &pool_ones[th_num*th_nobs];
			
			// Each process can now calculate the term in the
			// exponent for a subset of random vectors

			// Naive approach: for loop on each vector X 
			// pool_res[th_num] += exp_term();		

			// Guru approach: BLAS
			log_likelihood(X,isigma,mu,det_sigma,th_nobs,sizex,&pool_res[th_num],LV,tmp,ones);

			#pragma omp barrier

			// Reduction: sum all the intermediary results
			#pragma omp for reduction(+:final_sum)
			for(int i = 0; i < nthreads; i++)
				final_sum = final_sum + pool_res[i];
		}
		toc = omp_get_wtime();
		tot_time += toc-tic;
	}	

	printf("Result: %f\n",final_sum);
	printf("Total time: %f\n",tot_time/(double)nsample);

	////////////////////////////////////////
	/////////////// Clean up ///////////////
	////////////////////////////////////////
	free(pool_res);
	free(pool_ones);
	free(pool_tmp);
	free(pool_LV);

	free(buffer_X);
	free(isigma);
	free(mu);
	free(location);

	return EXIT_SUCCESS;
}
Ejemplo n.º 15
0
 double LRM::Loglike(const Vector &beta, Vector &g, Matrix &h, uint nd)const{
   if(nd>=2) return log_likelihood(beta, &g, &h);
   if(nd==1) return log_likelihood(beta, &g, 0);
   return log_likelihood(beta, 0, 0);
 }