|
bpp-phyl
2.1.0
|
00001 // 00002 // File: MarkovModulatedSubstitutionModel.cpp 00003 // Created by: Julien Dutheil 00004 // Created on: Sat Aug 05 08:21 2006 00005 // 00006 00007 /* 00008 Copyright or © or Copr. Bio++ Development Team, (November 16, 2004) 00009 00010 This software is a computer program whose purpose is to provide classes 00011 for phylogenetic data analysis. 00012 00013 This software is governed by the CeCILL license under French law and 00014 abiding by the rules of distribution of free software. You can use, 00015 modify and/ or redistribute the software under the terms of the CeCILL 00016 license as circulated by CEA, CNRS and INRIA at the following URL 00017 "http://www.cecill.info". 00018 00019 As a counterpart to the access to the source code and rights to copy, 00020 modify and redistribute granted by the license, users are provided only 00021 with a limited warranty and the software's author, the holder of the 00022 economic rights, and the successive licensors have only limited 00023 liability. 00024 00025 In this respect, the user's attention is drawn to the risks associated 00026 with loading, using, modifying and/or developing or reproducing the 00027 software by the user in light of its specific status of free software, 00028 that may mean that it is complicated to manipulate, and that also 00029 therefore means that it is reserved for developers and experienced 00030 professionals having in-depth computer knowledge. Users are therefore 00031 encouraged to load and test the software's suitability as regards their 00032 requirements in conditions enabling the security of their systems and/or 00033 data to be ensured and, more generally, to use and operate it in the 00034 same conditions as regards security. 00035 00036 The fact that you are presently reading this means that you have had 00037 knowledge of the CeCILL license and that you accept its terms. 00038 */ 00039 00040 #include "MarkovModulatedSubstitutionModel.h" 00041 00042 #include <Bpp/Numeric/VectorTools.h> 00043 #include <Bpp/Numeric/Matrix/MatrixTools.h> 00044 #include <Bpp/Numeric/Matrix/EigenValue.h> 00045 00046 using namespace bpp; 00047 using namespace std; 00048 00049 /******************************************************************************/ 00050 00051 MarkovModulatedSubstitutionModel::MarkovModulatedSubstitutionModel( 00052 const MarkovModulatedSubstitutionModel& model) : 00053 AbstractParameterAliasable(model), 00054 model_ (dynamic_cast<ReversibleSubstitutionModel*>(model.model_->clone())), 00055 nbStates_ (model.nbStates_), 00056 nbRates_ (model.nbRates_), 00057 rates_ (model.rates_), 00058 ratesExchangeability_(model.ratesExchangeability_), 00059 ratesFreq_ (model.ratesFreq_), 00060 ratesGenerator_ (model.ratesGenerator_), 00061 chars_ (model.chars_), 00062 generator_ (model.generator_), 00063 exchangeability_ (model.exchangeability_), 00064 leftEigenVectors_ (model.leftEigenVectors_), 00065 rightEigenVectors_ (model.rightEigenVectors_), 00066 eigenValues_ (model.eigenValues_), 00067 iEigenValues_ (model.iEigenValues_), 00068 eigenDecompose_ (model.eigenDecompose_), 00069 pijt_ (model.pijt_), 00070 dpijt_ (model.dpijt_), 00071 d2pijt_ (model.d2pijt_), 00072 freq_ (model.freq_), 00073 normalizeRateChanges_(model.normalizeRateChanges_), 00074 nestedPrefix_ (model.nestedPrefix_) 00075 {} 00076 00077 MarkovModulatedSubstitutionModel& MarkovModulatedSubstitutionModel::operator=( 00078 const MarkovModulatedSubstitutionModel& model) 00079 { 00080 AbstractParametrizable::operator=(model); 00081 model_ = dynamic_cast<ReversibleSubstitutionModel*>(model.model_->clone()); 00082 nbStates_ = model.nbStates_; 00083 nbRates_ = model.nbRates_; 00084 rates_ = model.rates_; 00085 ratesExchangeability_ = model.ratesExchangeability_; 00086 ratesFreq_ = model.ratesFreq_; 00087 ratesGenerator_ = model.ratesGenerator_; 00088 chars_ = model.chars_; 00089 generator_ = model.generator_; 00090 exchangeability_ = model.exchangeability_; 00091 leftEigenVectors_ = model.leftEigenVectors_; 00092 rightEigenVectors_ = model.rightEigenVectors_; 00093 eigenValues_ = model.eigenValues_; 00094 iEigenValues_ = model.iEigenValues_; 00095 eigenDecompose_ = model.eigenDecompose_; 00096 pijt_ = model.pijt_; 00097 dpijt_ = model.dpijt_; 00098 d2pijt_ = model.d2pijt_; 00099 freq_ = model.freq_; 00100 normalizeRateChanges_ = model.normalizeRateChanges_; 00101 nestedPrefix_ = model.nestedPrefix_; 00102 return *this; 00103 } 00104 00105 /******************************************************************************/ 00106 00107 void MarkovModulatedSubstitutionModel::updateMatrices() 00108 { 00109 // ratesGenerator_ and rates_ must be initialized! 00110 nbStates_ = model_->getNumberOfStates(); 00111 nbRates_ = rates_.getNumberOfColumns(); 00112 chars_ = VectorTools::rep(model_->getAlphabetChars(), nbRates_); 00113 RowMatrix<double> Tmp1, Tmp2; 00114 MatrixTools::diag(ratesFreq_, Tmp1); 00115 MatrixTools::mult(ratesExchangeability_, Tmp1, ratesGenerator_); 00116 MatrixTools::kroneckerMult(rates_, model_->getGenerator(), generator_); 00117 00118 MatrixTools::MatrixTools::getId< RowMatrix<double> >(nbStates_, Tmp1); 00119 MatrixTools::kroneckerMult(ratesGenerator_, Tmp1, Tmp2); 00120 MatrixTools::add(generator_, Tmp2); 00121 00122 MatrixTools::diag(1. / ratesFreq_, Tmp1); 00123 MatrixTools::mult(rates_, Tmp1, Tmp2); 00124 MatrixTools::kroneckerMult(Tmp2, model_->getExchangeabilityMatrix(), exchangeability_); 00125 00126 MatrixTools::diag(1 / model_->getFrequencies(), Tmp1); 00127 MatrixTools::kroneckerMult(ratesExchangeability_, Tmp1, Tmp2); 00128 MatrixTools::add(exchangeability_, Tmp2); 00129 freq_ = VectorTools::kroneckerMult(ratesFreq_, model_->getFrequencies()); 00130 if (normalizeRateChanges_) 00131 { 00132 // Normalization: 00133 Vdouble Tmp; 00134 MatrixTools::diag(generator_, Tmp); 00135 double scale = -VectorTools::scalar<double, double>(Tmp, freq_); 00136 MatrixTools::scale(generator_, 1. / scale); 00137 00138 // Normalize exchangeability matrix too: 00139 MatrixTools::scale(exchangeability_, 1. / scale); 00140 } 00141 00142 // Compute eigen values and vectors: 00143 eigenValues_.resize(nbRates_ * nbStates_); 00144 iEigenValues_.resize(nbRates_ * nbStates_); 00145 rightEigenVectors_.resize(nbStates_ * nbRates_, nbStates_ * nbRates_); 00146 pijt_.resize(nbStates_ * nbRates_, nbStates_ * nbRates_); 00147 dpijt_.resize(nbStates_ * nbRates_, nbStates_ * nbRates_); 00148 d2pijt_.resize(nbStates_ * nbRates_, nbStates_ * nbRates_); 00149 00150 vector<double> modelEigenValues = model_->getEigenValues(); 00151 RowMatrix<double> modelRightEigenVectors = model_->getColumnRightEigenVectors(); 00152 for (unsigned int i = 0; i < nbStates_; i++) 00153 { 00154 RowMatrix<double> tmp = rates_; 00155 MatrixTools::scale(tmp, modelEigenValues[i]); 00156 MatrixTools::add(tmp, ratesGenerator_); 00157 EigenValue<double> ev(tmp); 00158 vector<double> values = ev.getRealEigenValues(); 00159 RowMatrix<double> vectors = ev.getV(); 00160 for (size_t j = 0; j < nbRates_; j++) 00161 { 00162 size_t c = i * nbRates_ + j; // Current eigen value index. 00163 eigenValues_[c] = values[j]; 00164 // Compute the Kronecker product of the jth vector and the ith modelRightEigenVector. 00165 for (unsigned int ii = 0; ii < nbRates_; ii++) 00166 { 00167 double vii = vectors(ii, j); 00168 for (unsigned int jj = 0; jj < nbStates_; jj++) 00169 { 00170 rightEigenVectors_(ii * nbStates_ + jj, c) = vii * modelRightEigenVectors(jj, i); 00171 } 00172 } 00173 } 00174 } 00175 // Now compute left eigen vectors by inversion: 00176 MatrixTools::inv(rightEigenVectors_, leftEigenVectors_); 00177 } 00178 00179 /******************************************************************************/ 00180 00181 const Matrix<double>& MarkovModulatedSubstitutionModel::getPij_t(double t) const 00182 { 00183 if (t == 0) 00184 MatrixTools::getId< RowMatrix<double> >(nbStates_ * nbRates_, pijt_); 00185 else 00186 MatrixTools::mult(rightEigenVectors_, VectorTools::exp(eigenValues_ * t), leftEigenVectors_, pijt_); 00187 return pijt_; 00188 } 00189 00190 const Matrix<double>& MarkovModulatedSubstitutionModel::getdPij_dt(double t) const 00191 { 00192 MatrixTools::mult(rightEigenVectors_, eigenValues_ * VectorTools::exp(eigenValues_ * t), leftEigenVectors_, dpijt_); 00193 return dpijt_; 00194 } 00195 00196 const Matrix<double>& MarkovModulatedSubstitutionModel::getd2Pij_dt2(double t) const 00197 { 00198 MatrixTools::mult(rightEigenVectors_, NumTools::sqr(eigenValues_) * VectorTools::exp(eigenValues_ * t), leftEigenVectors_, d2pijt_); 00199 return d2pijt_; 00200 } 00201 00202 /******************************************************************************/ 00203 00204 double MarkovModulatedSubstitutionModel::getInitValue(size_t i, int state) const throw (IndexOutOfBoundsException, BadIntException) 00205 { 00206 if (i >= (nbStates_ * nbRates_)) 00207 throw IndexOutOfBoundsException("MarkovModulatedSubstitutionModel::getInitValue", i, 0, nbStates_ * nbRates_ - 1); 00208 if (state < 0 || !model_->getAlphabet()->isIntInAlphabet(state)) 00209 throw BadIntException(state, "MarkovModulatedSubstitutionModel::getInitValue. Character " + model_->getAlphabet()->intToChar(state) + " is not allowed in model."); 00210 vector<int> states = model_->getAlphabet()->getAlias(state); 00211 for (size_t j = 0; j < states.size(); j++) 00212 { 00213 if (getAlphabetChar(i) == states[j]) 00214 return 1.; 00215 } 00216 return 0.; 00217 } 00218 00219 /******************************************************************************/ 00220 00221 void MarkovModulatedSubstitutionModel::setNamespace(const string& prefix) 00222 { 00223 AbstractParameterAliasable::setNamespace(prefix); 00224 // We also need to update the namespace of the nested model: 00225 model_->setNamespace(prefix + nestedPrefix_); 00226 } 00227 00228 /******************************************************************************/ 00229