SecondaryStructureResidue setup_coarse_secondary_structure_residue( const Particles &ssr_ps, Model *mdl, bool winner_takes_all_per_res) { Floats scores; scores.push_back(0.0); scores.push_back(0.0); scores.push_back(0.0); int count = 0; for (Particles::const_iterator p = ssr_ps.begin(); p != ssr_ps.end(); ++p) { IMP_USAGE_CHECK(SecondaryStructureResidue::get_is_setup(*p), "all particles must be SecondaryStructureResidues"); SecondaryStructureResidue ssr(*p); Floats tmp_scores; tmp_scores.push_back(ssr.get_prob_helix()); tmp_scores.push_back(ssr.get_prob_strand()); tmp_scores.push_back(ssr.get_prob_coil()); int max_i = 0; Float max = 0.0; for (int i = 0; i < 3; i++) { if (tmp_scores[i] > max) { max = tmp_scores[i]; max_i = i; } if (!winner_takes_all_per_res) scores[i] += tmp_scores[i]; } if (winner_takes_all_per_res) scores[max_i] += 1.0; count++; } IMP_NEW(Particle, coarse_p, (mdl)); SecondaryStructureResidue ssres = SecondaryStructureResidue::setup_particle( coarse_p, scores[0] / count, scores[1] / count, scores[2] / count); return ssres; }
core::MonteCarloMoverResult WeightMover::do_propose() { IMP_OBJECT_LOG; // store the old weights in case of reject oldweights_ = w_.get_weights(); // Draw weights from a uniform distribution of variables that sum to one // taken from http://stats.stackexchange.com/questions/14059/ // generate-uniformly-distributed-weights-that-sum-to-unity // get the old x Floats x; x.push_back(oldweights_[0]); for (unsigned i = 1; i < oldweights_.get_dimension() - 1; ++i) { x.push_back(oldweights_[i] + x[i - 1]); } // zero vector in D dimension algebra::VectorKD zero = algebra::get_zero_vector_kd(x.size()); // generate random perturbation of old components algebra::VectorKD dX = algebra::get_random_vector_in(algebra::SphereKD(zero, radius_)); // add perturbation to x and apply reflective boundaries for (unsigned i = 0; i < x.size(); ++i) { if (x[i] + dX[i] > 1.0) x[i] = 2.0 - x[i] - dX[i]; else if (x[i] + dX[i] < 0.0) x[i] = -x[i] - dX[i]; else x[i] += dX[i]; } // sort the new x here std::sort(x.begin(), x.end(), std::less<double>()); // get the new weights algebra::VectorKD newweights = algebra::get_zero_vector_kd(oldweights_.get_dimension()); newweights[0] = x[0]; for (unsigned i = 1; i < newweights.get_dimension() - 1; ++i) { newweights[i] = x[i] - x[i - 1]; } newweights[newweights.get_dimension() - 1] = 1.0 - x[x.size() - 1]; // set the new weights w_.set_weights(newweights); return core::MonteCarloMoverResult( ParticleIndexes(1, w_.get_particle()->get_index()), 1.0); }
Floats CrossLinkData::get_nonmarginal_elements(double sigmai, Floats dists) const { Floats probs; if (bias_) { for (unsigned n = 0; n < dists.size(); n++) { probs.push_back(get_biased_element(dists[n], sigmai)); } } if (!bias_) { for (unsigned n = 0; n < dists.size(); n++) { probs.push_back(get_unbiased_element(dists[n], sigmai)); } } return probs; }
Floats GaussianProcessInterpolation::get_posterior_covariance_derivative( Floats x, bool) const { IMP_Eigen::VectorXd mat(get_posterior_covariance_derivative(x)); Floats tmp; for (unsigned j = 0; j < mat.rows(); j++) tmp.push_back(mat(j)); return tmp; }
TEST(Neighbors,CoverTreeDistanceNeighbors) { typedef std::vector<float> Floats; const int N = 100; const int k = 10; Floats floats; for (int i=0;i<N;i++) floats.push_back(float(i)); float_distance_callback fdc; tapkee::tapkee_internal::Neighbors neighbors = tapkee::tapkee_internal::find_neighbors(tapkee::CoverTree, floats.begin(), floats.end(), tapkee::tapkee_internal::PlainDistance<Floats::iterator,float_distance_callback>(fdc), k, true); for (int i=0;i<N;i++) { // total number of found neighbors is k ASSERT_EQ(neighbors[i].size(),k); std::set<float> neighbors_set; for (int j=0;j<k;j++) neighbors_set.insert(neighbors[i][j]); // there are no repeated values ASSERT_EQ(neighbors_set.size(),k); // the vector is not a neighbor of itself ASSERT_EQ(neighbors_set.find(floats[i]),neighbors_set.end()); // check neighbors int k_left = std::min(i,k/2); int k_right = std::min(N-i-1,k/2); for (int j=0; j<k_left; j++) ASSERT_NE(neighbors_set.find(floats[i-j-1]),neighbors_set.end()); for (int j=0; j<k_right; j++) ASSERT_NE(neighbors_set.find(floats[i+j+1]),neighbors_set.end()); } }
Floats CysteineCrossLinkData::get_omegas(Floats fmods, double omega0) const { Floats omegas; for (unsigned n = 0; n < fmods.size(); ++n) { double cumul = 0; double cumul2 = 0; for (unsigned j = 1; j < omega_grid_.size(); ++j) { double omj = omega_grid_[j]; double omjm1 = omega_grid_[j - 1]; double dom = omj - omjm1; double priorj = get_omega_prior(omj, omega0); double priorjm1 = get_omega_prior(omjm1, omega0); double pj = get_element(fexp_, fmods[n], omj) * priorj; double pjm1 = get_element(fexp_, fmods[n], omjm1) * priorjm1; double pj2 = get_element(fexp_, fmods[n], omj) * priorj * omj; double pjm12 = get_element(fexp_, fmods[n], omjm1) * priorjm1 * omjm1; cumul += (pj + pjm1) / 2.0 * dom; cumul2 += (pj2 + pjm12) / 2.0 * dom; } omegas.push_back(cumul2 / cumul); } return omegas; }
Floats FStudentT::evaluate_derivative_FX(const Floats FXs) const { Floats dervs; double c = (N_ + nu_) / IMP::square(sigma_) / (nu_ + t2_); for (unsigned int i = 0; i < FXs.size(); i++) { dervs.push_back(c * (FXs[i] - FM_)); } return dervs; }
Floats ReplicaExchange::create_temperatures(double tmin,double tmax,int nrep) { Floats temp; double tfact=exp(log(tmax/tmin)/double(nrep-1)); for(int i=0;i<nrep;++i) { temp.push_back(tmin*pow(tfact,i)); } return temp; }
FloatsList GaussianProcessInterpolationRestraint::get_hessian(bool) const { IMP_Eigen::MatrixXd tmp(get_hessian()); FloatsList ret; for (unsigned i = 0; i < tmp.rows(); ++i) { Floats buf; for (unsigned j = 0; j < tmp.cols(); ++j) buf.push_back(tmp(i, j)); ret.push_back(buf); } return ret; }
Floats CrossLinkData::get_marginal_elements(double sigma, Floats dists) const { Floats probs; unsigned is = get_closest(sigma_grid_, sigma); for (unsigned n = 0; n < dists.size(); n++) { unsigned id = get_closest(dist_grid_, dists[n]); probs.push_back(grid_[is][id]); } return probs; }
FloatsList GaussianProcessInterpolation::get_data_variance() const { FloatsList ret; IMP_Eigen::MatrixXd S(get_S()); for (unsigned i = 0; i < M_; i++) { Floats val; for (unsigned j = 0; j < M_; j++) val.push_back(S(i, j)); ret.push_back(val); } return ret; }
Floats CysteineCrossLinkData::get_nonmarginal_elements(double fexp, Floats fmods, double omega) const { Floats probs; for (unsigned n = 0; n < fmods.size(); n++) { probs.push_back(get_element(fexp, fmods[n], omega)); } return probs; }
IMPISD_BEGIN_NAMESPACE CysteineCrossLinkData::CysteineCrossLinkData(double fexp, Floats fmod_grid, Floats omega_grid, Floats omega0_grid, int prior_type) : Object("Data Structure for CysteineCrossLinkRestraint %1%") { prior_type_ = prior_type; // fexp is the experimental frequency // fmod is the model frequency // omega0 is the typical value for omega, i.e., the experimental uncertainty // this constructor calculates the marginal likelihood using a // truncated gaussian function // to account for outliers // Store omega0 grid omega0_grid_ = omega0_grid; // Store the fmod grid fmod_grid_ = fmod_grid; // Store omega grid omega_grid_ = omega_grid; fexp_ = fexp; for (unsigned k = 0; k < omega0_grid_.size(); ++k) { double omega0 = omega0_grid_[k]; Floats grid; for (unsigned i = 0; i < fmod_grid_.size(); ++i) { double fmod = fmod_grid_[i]; double cumul = 0; for (unsigned j = 1; j < omega_grid_.size(); ++j) { double omj = omega_grid_[j]; double omjm1 = omega_grid_[j - 1]; double dom = omj - omjm1; double priorj = get_omega_prior(omj, omega0); double priorjm1 = get_omega_prior(omjm1, omega0); double pj = get_element(fexp_, fmod, omj) * priorj; double pjm1 = get_element(fexp_, fmod, omjm1) * priorjm1; cumul += (pj + pjm1) / 2.0 * dom; } grid.push_back(cumul); } grid_.push_back(grid); } }
FloatsList GaussianProcessInterpolation::get_posterior_covariance_hessian( Floats x, bool) const { IMP_Eigen::MatrixXd mat(get_posterior_covariance_hessian(x)); FloatsList ret; for (unsigned j = 0; j < mat.rows(); j++) { Floats tmp; for (unsigned i = 0; i < mat.cols(); i++) tmp.push_back(mat(i, j)); ret.push_back(tmp); } return ret; }
Floats CysteineCrossLinkData::get_marginal_elements(Floats fmods, double omega0) const { Floats probs; unsigned is = get_closest(omega0_grid_, omega0); for (unsigned n = 0; n < fmods.size(); n++) { unsigned id = get_closest(fmod_grid_, fmods[n]); probs.push_back(grid_[is][id]); } return probs; }
void ProbabilisticAnchorGraph::set_particle_probabilities_on_anchors( Particle *p, FittingSolutionRecords sols) { IMP_USAGE_CHECK(sols.size() > 0, "no solutions provided\n"); IMP_NEW(algebra::NearestNeighborD<3>, nn, (positions_)); Ints anchor_counters; anchor_counters.insert(anchor_counters.end(), positions_.size(), 0); for (unsigned int i = 0; i < sols.size(); i++) { algebra::Vector3D loc = sols[i].get_fit_transformation().get_transformed( core::XYZ(p).get_coordinates()); anchor_counters[nn->get_nearest_neighbor(loc)]++; } Floats probs; for (unsigned int i = 0; i < anchor_counters.size(); i++) { probs.push_back(1. * anchor_counters[i] / sols.size()); } particle_to_anchor_probabilities_[p] = probs; }
Floats CrossLinkData::get_omegas(double sigma, Floats dists) const { Floats omegas; for (unsigned n = 0; n < dists.size(); ++n) { double cumul = 0; double cumul2 = 0; if (!bias_) { for (unsigned j = 1; j < omega_grid_.size(); ++j) { double omj = omega_grid_[j]; double omjm1 = omega_grid_[j - 1]; double dom = omj - omjm1; double pj = get_unbiased_element(dists[n], omj * sigma) / omj; double pjm1 = get_unbiased_element(dists[n], omjm1 * sigma) / omjm1; double pj2 = get_unbiased_element(dists[n], omj * sigma); double pjm12 = get_unbiased_element(dists[n], omjm1 * sigma); cumul += (pj + pjm1) / 2.0 * dom; cumul2 += (pj2 + pjm12) / 2.0 * dom; } } if (bias_) { for (unsigned j = 1; j < omega_grid_.size(); ++j) { double omj = omega_grid_[j]; double omjm1 = omega_grid_[j - 1]; double dom = omj - omjm1; double pj = get_biased_element(dists[n], omj * sigma) / omj; double pjm1 = get_biased_element(dists[n], omjm1 * sigma) / omjm1; double pj2 = get_biased_element(dists[n], omj * sigma); double pjm12 = get_biased_element(dists[n], omjm1 * sigma); cumul += (pj + pjm1) / 2.0 * dom; cumul2 += (pj2 + pjm12) / 2.0 * dom; } } omegas.push_back(cumul2 / cumul); } return omegas; }
Floats ChainStatisticsOptimizerState::get_diffusion_coefficients() const { if (positions_.empty()) return Floats(); base::Vector<algebra::Vector3Ds > displacements(positions_[0].size(), algebra::Vector3Ds( positions_.size()-1)); for (unsigned int i=1; i< positions_.size(); ++i) { algebra::Transformation3D rel = algebra::get_transformation_aligning_first_to_second(positions_[i-1], positions_[i]); for (unsigned int j=0; j < positions_[i].size(); ++j) { displacements[j][i-1]= rel.get_transformed(positions_[i-1][j]) - positions_[i][j]; } } Floats ret; for (unsigned int i=0; i < displacements.size(); ++i) { ret.push_back(atom::get_diffusion_coefficient(displacements[i], get_period()*get_dt())); } return ret; }
/* Apply the restraint to two atoms, two Scales, one experimental value. */ double AmbiguousNOERestraint::unprotected_evaluate(DerivativeAccumulator *accum) const { IMP_OBJECT_LOG; IMP_USAGE_CHECK(get_model(), "You must at least register the restraint with the model" << " before calling evaluate."); /* compute Icalc = 1/(gamma*d^6) where d = (sum d_i^-6)^(-1/6) */ double vol = 0; Floats vols; IMP_CONTAINER_FOREACH(PairContainer, pc_, { core::XYZ d0(get_model(), _1[0]); core::XYZ d1(get_model(), _1[1]); algebra::Vector3D c0 = d0.get_coordinates(); algebra::Vector3D c1 = d1.get_coordinates(); //will raise an error if c0 == c1 double tmp = 1.0/(c0-c1).get_squared_magnitude(); vols.push_back(IMP::cube(tmp)); // store di^-6 vol += vols.back(); });
CrossLinkData::CrossLinkData(Floats dist_grid, Floats omega_grid, Floats sigma_grid, Floats pot_x_grid, Floats pot_value_grid, double don, double doff, int prior_type) : Object("Data Structure for CrossLinkMSRestraint %1%") { prior_type_ = prior_type; bias_ = true; // this constructor calculates the marginal likelihood using a biasing // potential // obtained from Free energy calculations. // Store dist grid dist_grid_ = dist_grid; // Store omega grid omega_grid_ = omega_grid; // Store sigma grid sigma_grid_ = sigma_grid; // Store the potential x coordinates pot_x_grid_ = pot_x_grid; // Store the normalized potential double cumul = 0; for (unsigned j = 1; j < pot_value_grid.size(); ++j) { double xj = pot_x_grid_[j]; double xjm1 = pot_x_grid_[j - 1]; double dx = xj - xjm1; double pj = pot_value_grid[j]; double pjm1 = pot_value_grid[j - 1]; cumul += (pj + pjm1) / 2.0 * dx; } for (unsigned i = 0; i < pot_value_grid.size(); ++i) { pot_value_grid_.push_back(pot_value_grid[i] / cumul); } for (unsigned k = 0; k < sigma_grid_.size(); ++k) { double sigma = sigma_grid_[k]; Floats grid; for (unsigned i = 0; i < dist_grid_.size(); ++i) { double dist = dist_grid_[i]; double cumul = 0; for (unsigned j = 1; j < omega_grid_.size(); ++j) { double omj = omega_grid_[j]; double omjm1 = omega_grid_[j - 1]; double dom = omj - omjm1; double pj; double pjm1; if (prior_type_ == 0) { pj = get_biased_element(dist, omj * sigma) / omj; pjm1 = get_biased_element(dist, omjm1 * sigma) / omjm1; } else { pj = get_biased_element(dist, omj) * get_omega_prior(omj, sigma); pjm1 = get_biased_element(dist, omjm1) * get_omega_prior(omjm1, sigma); } cumul += (pj + pjm1) / 2.0 * dom; } // switching cumul to zero between don and doff if (dist > doff) { cumul = 0.; } if (dist > don && dist <= doff) { cumul *= pow(doff * doff - dist * dist, 2) * (doff * doff + 2. * dist * dist - 3. * don * don) / pow(doff * doff - don * don, 3); } grid.push_back(cumul); } grid_.push_back(grid); } }
IMPISD_BEGIN_NAMESPACE CrossLinkData::CrossLinkData(Floats dist_grid, Floats omega_grid, Floats sigma_grid, double lexp, double don, double doff, int prior_type) : Object("Data Structure for CrossLinkMSRestraint %1%") { prior_type_ = prior_type; lexp_ = lexp; bias_ = false; // this constructor calculates the marginal likelihood using a theta function // to approximate the propensity of the linker // Store dist grid dist_grid_ = dist_grid; // Store omega grid omega_grid_ = omega_grid; // Store sigma grid sigma_grid_ = sigma_grid; for (unsigned k = 0; k < sigma_grid_.size(); ++k) { double sigma = sigma_grid_[k]; Floats grid; for (unsigned i = 0; i < dist_grid_.size(); ++i) { double dist = dist_grid_[i]; double cumul = 0; for (unsigned j = 1; j < omega_grid_.size(); ++j) { double omj = omega_grid_[j]; double omjm1 = omega_grid_[j - 1]; double dom = omj - omjm1; double pj; double pjm1; if (prior_type_ == 0) { pj = get_biased_element(dist, omj * sigma) / omj; pjm1 = get_biased_element(dist, omjm1 * sigma) / omjm1; } else { pj = get_biased_element(dist, omj) * get_omega_prior(omj, sigma); pjm1 = get_biased_element(dist, omjm1) * get_omega_prior(omjm1, sigma); } cumul += (pj + pjm1) / 2.0 * dom; } // switching cumul to zero between don and doff if (dist > doff) { cumul = 0.; } if (dist > don && dist <= doff) { cumul *= pow(doff * doff - dist * dist, 2) * (doff * doff + 2. * dist * dist - 3. * don * don) / pow(doff * doff - don * don, 3); } grid.push_back(cumul); } grid_.push_back(grid); } }
IMPCNMULTIFIT_BEGIN_NAMESPACE Floats get_rmsd_for_models(const std::string param_filename, const std::string trans_filename, const std::string ref_filename, int start_model, int end_model) { std::string protein_filename, surface_filename; int cn_symm_deg; std::cout << "============= parameters ============" << std::endl; std::cout << "params filename : " << param_filename << std::endl; std::cout << "trans filename : " << trans_filename << std::endl; std::cout << "ref filename : " << ref_filename << std::endl; std::cout << "start index to rmsd : " << start_model << std::endl; std::cout << "end index to rmsd : " << end_model << std::endl; std::cout << "=====================================" << std::endl; internal::Parameters params(param_filename.c_str()); protein_filename = params.get_unit_pdb_fn(); cn_symm_deg = params.get_cn_symm(); IMP_NEW(Model, mdl, ()); atom::Hierarchy asmb_ref; atom::Hierarchies mhs; // read the monomer core::XYZs model_xyzs; for (int i = 0; i < cn_symm_deg; i++) { atom::Hierarchy h = atom::read_pdb(protein_filename, mdl, new atom::CAlphaPDBSelector()); atom::Chain c = atom::get_chain( atom::Residue(atom::get_residue(atom::Atom(core::get_leaves(h)[0])))); c.set_id(std::string(1, char(65 + i))); atom::add_radii(h); atom::create_rigid_body(h); mhs.push_back(h); Particles leaves = core::get_leaves(h); for (Particles::iterator it = leaves.begin(); it != leaves.end(); it++) { model_xyzs.push_back(core::XYZ(*it)); } } // read the transformations multifit::FittingSolutionRecords recs = multifit::read_fitting_solutions(trans_filename.c_str()); // read the reference structure asmb_ref = atom::read_pdb(ref_filename, mdl, new atom::CAlphaPDBSelector()); atom::Hierarchies ref_chains = atom::Hierarchies(atom::get_by_type(asmb_ref, atom::CHAIN_TYPE)); std::cout << "number of records:" << recs.size() << std::endl; Floats rmsd; std::ofstream out; out.open("rmsd.output"); if (end_model < 0 || end_model >= static_cast<int>(recs.size())) { end_model = recs.size() - 1; } for (int i = start_model; i >= 0 && i <= end_model; ++i) { algebra::Transformation3D t1 = recs[i].get_dock_transformation(); algebra::Transformation3D t2 = recs[i].get_fit_transformation(); algebra::Transformation3D t2_inv = t1.get_inverse(); transform_cn_assembly(mhs, t1); for (unsigned int j = 0; j < model_xyzs.size(); j++) { model_xyzs[j] .set_coordinates(t2.get_transformed(model_xyzs[j].get_coordinates())); } std::cout << mhs.size() << "," << ref_chains.size() << std::endl; Float cn_rmsd = get_cn_rmsd(mhs, ref_chains); out << " trans:" << i << " rmsd: " << cn_rmsd << " cc: " << 1. - recs[i].get_fitting_score() << std::endl; rmsd.push_back(cn_rmsd); for (unsigned int j = 0; j < model_xyzs.size(); j++) { model_xyzs[j].set_coordinates( t2_inv.get_transformed(model_xyzs[j].get_coordinates())); } /* std::stringstream ss; ss<<"asmb_"<<i<<".pdb"; atom::write_pdb(mhs,ss.str());*/ transform_cn_assembly(mhs, t1.get_inverse()); } out.close(); return rmsd; }
Floats GaussianProcessInterpolation::get_data_mean() const { Floats ret; IMP_Eigen::VectorXd I(get_I()); for (unsigned i = 0; i < M_; i++) ret.push_back(I(i)); return ret; }
IMP_Eigen::MatrixXd GaussianProcessInterpolation::get_posterior_covariance_hessian(Floats x) const { const_cast<GaussianProcessInterpolation *>(this)->update_flags_covariance(); // get how many and which particles are optimized unsigned mnum = get_number_of_m_particles(); std::vector<bool> mopt; unsigned mnum_opt = 0; for (unsigned i = 0; i < mnum; i++) { mopt.push_back(get_m_particle_is_optimized(i)); if (mopt.back()) mnum_opt++; } unsigned Onum = get_number_of_Omega_particles(); std::vector<bool> Oopt; unsigned Onum_opt = 0; for (unsigned i = 0; i < Onum; i++) { Oopt.push_back(get_Omega_particle_is_optimized(i)); if (Oopt.back()) Onum_opt++; } // total number of optimized particles unsigned num_opt = mnum_opt + Onum_opt; // whether sigma is optimized unsigned sigma_opt = Oopt[0] ? 1 : 0; // cov_opt: number of optimized covariance particles without counting sigma unsigned cov_opt = Onum_opt - sigma_opt; // init matrix and fill with zeros at mean particle's indices // dprior_cov(q,q)/(dsigma d.) is also zero IMP_Eigen::MatrixXd ret(IMP_Eigen::MatrixXd::Zero(num_opt, num_opt)); // build vector of dcov(q,q)/dp1dp2 with p1 and p2 covariance particles FloatsList xv; xv.push_back(x); FloatsList tmplist; for (unsigned pa = 0; pa < Onum; ++pa) { if (!Oopt[pa]) continue; // skip not optimized particles if (pa == 0) continue; // skip sigma even when it is optimized Floats tmp; for (unsigned pb = pa; pb < Onum; ++pb) { if (!Oopt[pb]) continue; // skip not optimized particles // sigma has already been skipped tmp.push_back(covariance_function_->get_second_derivative_matrix( pa - 1, pb - 1, xv)(0, 0)); } tmplist.push_back(tmp); } for (unsigned pa_opt = 0; pa_opt < cov_opt; pa_opt++) for (unsigned pb_opt = pa_opt; pb_opt < cov_opt; pb_opt++) ret.bottomRightCorner(cov_opt, cov_opt)(pa_opt, pb_opt) = tmplist[pa_opt][pb_opt - pa_opt]; // compute and store w(q) derivatives (skip mean particles) IMP_Eigen::MatrixXd dwqdp(M_, Onum_opt); for (unsigned i = 0, j = 0; i < Onum; i++) if (Oopt[i]) dwqdp.col(j++) = get_wx_vector_derivative(x, i + mnum); // add d2cov/(dw(q)_k * dw(q)_l) * dw(q)^k/dp_i * dw(q)^l/dp_j ret.bottomRightCorner(cov_opt, cov_opt).noalias() += dwqdp.rightCols(cov_opt).transpose() * get_d2cov_dwq_dwq() * dwqdp.rightCols(cov_opt); // compute and store Omega derivatives (skip mean particles) std::vector<IMP_Eigen::MatrixXd> dOmdp; for (unsigned i = 0; i < Onum; i++) { if (Oopt[i]) dOmdp.push_back(get_Omega_derivative(i)); } // add d2cov/(dOm_kl * dOm_mn) * dOm^kl/dp_i * dOm^mn/dp_j std::vector<std::vector<IMP_Eigen::MatrixXd> > d2covdo; for (unsigned m = 0; m < M_; m++) { std::vector<IMP_Eigen::MatrixXd> tmp; for (unsigned n = 0; n < M_; n++) tmp.push_back(get_d2cov_dOm_dOm(x, m, n)); d2covdo.push_back(tmp); } for (unsigned i = 0; i < Onum_opt; i++) { IMP_Eigen::MatrixXd tmp(M_, M_); for (unsigned m = 0; m < M_; ++m) for (unsigned n = 0; n < M_; ++n) tmp(m, n) = (d2covdo[m][n].transpose() * dOmdp[i]).trace(); for (unsigned j = i; j < Onum_opt; j++) ret.bottomRightCorner(Onum_opt, Onum_opt)(i, j) += (dOmdp[j].transpose() * tmp).trace(); } for (unsigned i = 0; i < d2covdo.size(); i++) d2covdo[i].clear(); d2covdo.clear(); // compute cross-term std::vector<IMP_Eigen::MatrixXd> d2covdwdo; for (unsigned k = 0; k < M_; k++) d2covdwdo.push_back(get_d2cov_dwq_dOm(x, k)); // compute derivative contribution into temporary IMP_Eigen::MatrixXd tmpH(Onum_opt, Onum_opt); for (unsigned i = 0; i < Onum_opt; i++) { IMP_Eigen::VectorXd tmp(M_); for (unsigned k = 0; k < M_; k++) tmp(k) = (d2covdwdo[k].transpose() * dOmdp[i]).trace(); for (unsigned j = 0; j < Onum_opt; j++) tmpH(i, j) = dwqdp.col(j).transpose() * tmp; } ret.bottomRightCorner(Onum_opt, Onum_opt) += tmpH + tmpH.transpose(); // deallocate unused stuff // tmpH.resize(0,0); d2covdwdo.clear(); dOmdp.clear(); // dwqdp.resize(0,0); // dcov/dw_k * d2w^k/(dp_i dp_j) IMP_Eigen::VectorXd dcwq(get_dcov_dwq(x)); for (unsigned i = 0; i < cov_opt; i++) for (unsigned j = i; j < cov_opt; j++) ret.bottomRightCorner(cov_opt, cov_opt)(i, j) += dcwq.transpose() * get_wx_vector_second_derivative(x, mnum + 1 + i, mnum + 1 + j); // dcwq.resize(0,0); // dcov/dOm_kl * d2Om^kl/(dp_i dp_j), zero when p_i or p_j is sigma or mean IMP_Eigen::MatrixXd dcOm(get_dcov_dOm(x)); for (unsigned i = 0; i < cov_opt; i++) for (unsigned j = i; j < cov_opt; j++) ret.bottomRightCorner(cov_opt, cov_opt)(i, j) += (dcOm.transpose() * get_Omega_second_derivative(i + 1, j + 1)) .trace(); // dcOm.resize(0,0); // return as symmetric matrix for (unsigned i = mnum_opt; i < num_opt; ++i) for (unsigned j = mnum_opt + 1; j < num_opt; ++j) ret(j, i) = ret(i, j); return ret; }