bpp-phyl  2.1.0
Bpp/Phyl/Model/Nucleotide/T92.cpp
Go to the documentation of this file.
00001 //
00002 // File: T92.cpp
00003 // Created by:  Julien Dutheil
00004 // Created on: Mon May 26 14:41:24 2003
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 "T92.h"
00041 #include "../FrequenciesSet/NucleotideFrequenciesSet.h"
00042 
00043 #include <Bpp/Numeric/Matrix/MatrixTools.h>
00044 
00045 // From SeqLib:
00046 #include <Bpp/Seq/Container/SequenceContainerTools.h>
00047 
00048 using namespace bpp;
00049 
00050 // From the STL:
00051 #include <cmath>
00052 
00053 using namespace std;
00054 
00055 /******************************************************************************/
00056 
00057 T92::T92(const NucleicAlphabet* alpha, double kappa, double theta) :
00058   AbstractParameterAliasable("T92."),
00059   AbstractSubstitutionModel(alpha, "T92."),
00060   AbstractReversibleSubstitutionModel(alpha, "T92."),
00061   kappa_(kappa),
00062   theta_(theta),
00063   k_(),
00064   r_(),
00065   piA_((1. - theta_) / 2.),
00066   piC_(theta_ / 2.),
00067   piG_(theta_ / 2.),
00068   piT_((1. - theta_) / 2.),
00069   exp1_(),
00070   exp2_(),
00071   l_(),
00072   p_(size_, size_)
00073 {
00074   addParameter_(new Parameter("T92.kappa", kappa, &Parameter::R_PLUS_STAR));
00075   addParameter_(new Parameter("T92.theta", theta, &FrequenciesSet::FREQUENCE_CONSTRAINT_SMALL));
00076   p_.resize(size_, size_);
00077   updateMatrices();
00078 }
00079 
00080 /******************************************************************************/
00081 
00082 void T92::updateMatrices()
00083 {
00084   kappa_ = getParameterValue("kappa");
00085   theta_ = getParameterValue("theta");
00086   piA_ = (1 - theta_) / 2;
00087   piC_ = theta_ / 2;
00088   piG_ = theta_ / 2;
00089   piT_ = (1 - theta_) / 2;
00090   k_ = (kappa_ + 1.) / 2.;
00091   r_ = 2. / (1. + 2. * theta_ * kappa_ - 2. * theta_ * theta_ * kappa_);
00092 
00093   freq_[0] = piA_;
00094   freq_[1] = piC_;
00095   freq_[2] = piG_;
00096   freq_[3] = piT_;
00097 
00098   generator_(0, 0) = -(1. +        theta_ * kappa_) / 2;
00099   generator_(1, 1) = -(1. + (1. - theta_) * kappa_) / 2;
00100   generator_(2, 2) = -(1. + (1. - theta_) * kappa_) / 2;
00101   generator_(3, 3) = -(1. +        theta_ * kappa_) / 2;
00102 
00103   generator_(1, 0) = (1. - theta_) / 2;
00104   generator_(3, 0) = (1. - theta_) / 2;
00105   generator_(0, 1) = theta_ / 2;
00106   generator_(2, 1) = theta_ / 2;
00107   generator_(1, 2) = theta_ / 2;
00108   generator_(3, 2) = theta_ / 2;
00109   generator_(0, 3) = (1. - theta_) / 2;
00110   generator_(2, 3) = (1. - theta_) / 2;
00111 
00112   generator_(2, 0) = kappa_ * (1. - theta_) / 2;
00113   generator_(3, 1) = kappa_ * theta_ / 2;
00114   generator_(0, 2) = kappa_ * theta_ / 2;
00115   generator_(1, 3) = kappa_ * (1. - theta_) / 2;
00116 
00117   // Normalization:
00118   MatrixTools::scale(generator_, r_);
00119 
00120   // Exchangeability:
00121   exchangeability_(0, 0) = generator_(0, 0) * 2. / (1. - theta_);
00122   exchangeability_(0, 1) = generator_(0, 1) * 2. / theta_;
00123   exchangeability_(0, 2) = generator_(0, 2) * 2. / theta_;
00124   exchangeability_(0, 3) = generator_(0, 3) * 2. / (1. - theta_);
00125 
00126   exchangeability_(1, 0) = generator_(1, 0) * 2. / (1. - theta_);
00127   exchangeability_(1, 1) = generator_(1, 1) * 2 / theta_;
00128   exchangeability_(1, 2) = generator_(1, 2) * 2 / theta_;
00129   exchangeability_(1, 3) = generator_(1, 3) * 2 / (1. - theta_);
00130 
00131   exchangeability_(2, 0) = generator_(2, 0) * 2. / (1. - theta_);
00132   exchangeability_(2, 1) = generator_(2, 1) * 2 / theta_;
00133   exchangeability_(2, 2) = generator_(2, 2) * 2 / theta_;
00134   exchangeability_(2, 3) = generator_(2, 3) * 2 / (1. - theta_);
00135 
00136   exchangeability_(3, 0) = generator_(3, 0) * 2. / (1. - theta_);
00137   exchangeability_(3, 1) = generator_(3, 1) * 2. / theta_;
00138   exchangeability_(3, 2) = generator_(3, 2) * 2. / theta_;
00139   exchangeability_(3, 3) = generator_(3, 3) * 2. / (1. - theta_);
00140 
00141   // Eigen values:
00142   eigenValues_[0] = 0;
00143   eigenValues_[1] = eigenValues_[2] = -r_ * (1. + kappa_) / 2;
00144   eigenValues_[3] = -r_;
00145 
00146   // Eigen vectors:
00147   leftEigenVectors_(0, 0) = -(theta_ - 1.) / 2.;
00148   leftEigenVectors_(0, 1) = theta_ / 2.;
00149   leftEigenVectors_(0, 2) = theta_ / 2.;
00150   leftEigenVectors_(0, 3) = -(theta_ - 1.) / 2.;
00151 
00152   leftEigenVectors_(1, 0) = 0.;
00153   leftEigenVectors_(1, 1) = -(theta_ - 1.);
00154   leftEigenVectors_(1, 2) = 0.;
00155   leftEigenVectors_(1, 3) = theta_ - 1.;
00156 
00157   leftEigenVectors_(2, 0) = theta_;
00158   leftEigenVectors_(2, 1) = 0.;
00159   leftEigenVectors_(2, 2) = -theta_;
00160   leftEigenVectors_(2, 3) = 0.;
00161 
00162   leftEigenVectors_(3, 0) = -(theta_ - 1.) / 2.;
00163   leftEigenVectors_(3, 1) = -theta_ / 2.;
00164   leftEigenVectors_(3, 2) = theta_ / 2.;
00165   leftEigenVectors_(3, 3) = (theta_ - 1.) / 2.;
00166 
00167 
00168   rightEigenVectors_(0, 0) = 1.;
00169   rightEigenVectors_(0, 1) = 0.;
00170   rightEigenVectors_(0, 2) = 1.;
00171   rightEigenVectors_(0, 3) = 1.;
00172 
00173   rightEigenVectors_(1, 0) = 1.;
00174   rightEigenVectors_(1, 1) = 1.;
00175   rightEigenVectors_(1, 2) = 0.;
00176   rightEigenVectors_(1, 3) = -1.;
00177 
00178   rightEigenVectors_(2, 0) = 1.;
00179   rightEigenVectors_(2, 1) = 0.;
00180   rightEigenVectors_(2, 2) = (theta_ - 1.) / theta_;
00181   rightEigenVectors_(2, 3) = 1.;
00182 
00183   rightEigenVectors_(3, 0) = 1.;
00184   rightEigenVectors_(3, 1) = theta_ / (theta_ - 1.);
00185   rightEigenVectors_(3, 2) = 0;
00186   rightEigenVectors_(3, 3) = -1.;
00187 }
00188 
00189 /******************************************************************************/
00190 
00191 double T92::Pij_t(int i, int j, double d) const
00192 {
00193   l_ = rate_ * r_ * d;
00194   exp1_ = exp(-l_);
00195   exp2_ = exp(-k_ * l_);
00196 
00197   switch (i)
00198   {
00199   // A
00200   case 0: {
00201     switch (j)
00202     {
00203     case 0: return piA_ * (1. + exp1_) + theta_ * exp2_; // A
00204     case 1: return piC_ * (1. - exp1_);                 // C
00205     case 2: return piG_ * (1. + exp1_) - theta_ * exp2_; // G
00206     case 3: return piT_ * (1. - exp1_);                 // T, U
00207     }
00208   }
00209   // C
00210   case 1: {
00211     switch (j)
00212     {
00213     case 0: return piA_ * (1. - exp1_);                        // A
00214     case 1: return piC_ * (1. + exp1_) + (1. - theta_) * exp2_; // C
00215     case 2: return piG_ * (1. - exp1_);                        // G
00216     case 3: return piT_ * (1. + exp1_) - (1. - theta_) * exp2_; // T, U
00217     }
00218   }
00219   // G
00220   case 2: {
00221     switch (j)
00222     {
00223     case 0: return piA_ * (1. + exp1_) - (1. - theta_) * exp2_; // A
00224     case 1: return piC_ * (1. - exp1_);                        // C
00225     case 2: return piG_ * (1. + exp1_) + (1. - theta_) * exp2_; // G
00226     case 3: return piT_ * (1. - exp1_);                        // T, U
00227     }
00228   }
00229   // T, U
00230   case 3: {
00231     switch (j)
00232     {
00233     case 0: return piA_ * (1. - exp1_);                 // A
00234     case 1: return piC_ * (1. + exp1_) - theta_ * exp2_; // C
00235     case 2: return piG_ * (1. - exp1_);                 // G
00236     case 3: return piT_ * (1. + exp1_) + theta_ * exp2_; // T, U
00237     }
00238   }
00239   }
00240   return 0;
00241 }
00242 
00243 /******************************************************************************/
00244 
00245 double T92::dPij_dt(int i, int j, double d) const
00246 {
00247   l_ = rate_ * r_ * d;
00248   exp1_ = exp(-l_);
00249   exp2_ = exp(-k_ * l_);
00250 
00251   switch (i)
00252   {
00253   // A
00254   case 0: {
00255     switch (j)
00256     {
00257     case 0: return rate_ * r_ * (piA_ * -exp1_ + theta_ * -k_ * exp2_); // A
00258     case 1: return rate_ * r_ * (piC_ *   exp1_);                       // C
00259     case 2: return rate_ * r_ * (piG_ * -exp1_ - theta_ * -k_ * exp2_); // G
00260     case 3: return rate_ * r_ * (piT_ *   exp1_);                       // T, U
00261     }
00262   }
00263   // C
00264   case 1: {
00265     switch (j)
00266     {
00267     case 0: return rate_ * r_ * (piA_ *   exp1_);                              // A
00268     case 1: return rate_ * r_ * (piC_ * -exp1_ + (1. - theta_) * -k_ * exp2_); // C
00269     case 2: return rate_ * r_ * (piG_ *   exp1_);                              // G
00270     case 3: return rate_ * r_ * (piT_ * -exp1_ - (1. - theta_) * -k_ * exp2_); // T, U
00271     }
00272   }
00273   // G
00274   case 2: {
00275     switch (j)
00276     {
00277     case 0: return rate_ * r_ * (piA_ * -exp1_ - (1. - theta_) * -k_ * exp2_); // A
00278     case 1: return rate_ * r_ * (piC_ *   exp1_);                              // C
00279     case 2: return rate_ * r_ * (piG_ * -exp1_ + (1. - theta_) * -k_ * exp2_); // G
00280     case 3: return rate_ * r_ * (piT_ *   exp1_);                              // T, U
00281     }
00282   }
00283   // T, U
00284   case 3: {
00285     switch (j)
00286     {
00287     case 0: return rate_ * r_ * (piA_ *   exp1_);                       // A
00288     case 1: return rate_ * r_ * (piC_ * -exp1_ - theta_ * -k_ * exp2_); // C
00289     case 2: return rate_ * r_ * (piG_ *   exp1_);                       // G
00290     case 3: return rate_ * r_ * (piT_ * -exp1_ + theta_ * -k_ * exp2_); // T, U
00291     }
00292   }
00293   }
00294   return 0;
00295 }
00296 
00297 /******************************************************************************/
00298 
00299 double T92::d2Pij_dt2(int i, int j, double d) const
00300 {
00301   double k2_ = k_ * k_;
00302   l_ = rate_ * r_ * d;
00303   double r2 = rate_ * rate_ * r_ * r_;
00304   exp1_ = exp(-l_);
00305   exp2_ = exp(-k_ * l_);
00306 
00307   switch (i)
00308   {
00309   // A
00310   case 0: {
00311     switch (j)
00312     {
00313     case 0: return r2 * (piA_ *   exp1_ + theta_ * k2_ * exp2_); // A
00314     case 1: return r2 * (piC_ * -exp1_);                       // C
00315     case 2: return r2 * (piG_ *   exp1_ - theta_ * k2_ * exp2_); // G
00316     case 3: return r2 * (piT_ * -exp1_);                       // T, U
00317     }
00318   }
00319   // C
00320   case 1: {
00321     switch (j)
00322     {
00323     case 0: return r2 * (piA_ * -exp1_);                              // A
00324     case 1: return r2 * (piC_ *   exp1_ + (1. - theta_) * k2_ * exp2_); // C
00325     case 2: return r2 * (piG_ * -exp1_);                              // G
00326     case 3: return r2 * (piT_ *   exp1_ - (1. - theta_) * k2_ * exp2_); // T, U
00327     }
00328   }
00329   // G
00330   case 2: {
00331     switch (j)
00332     {
00333     case 0: return r2 * (piA_ *   exp1_ - (1. - theta_) * k2_ * exp2_); // A
00334     case 1: return r2 * (piC_ * -exp1_);                              // C
00335     case 2: return r2 * (piG_ *   exp1_ + (1. - theta_) * k2_ * exp2_); // G
00336     case 3: return r2 * (piT_ * -exp1_);                              // T, U
00337     }
00338   }
00339   // T, U
00340   case 3: {
00341     switch (j)
00342     {
00343     case 0: return r2 * (piA_ * -exp1_);                       // A
00344     case 1: return r2 * (piC_ *   exp1_ - theta_ * k2_ * exp2_); // C
00345     case 2: return r2 * (piG_ * -exp1_);                       // G
00346     case 3: return r2 * (piT_ *   exp1_ + theta_ * k2_ * exp2_); // T, U
00347     }
00348   }
00349   }
00350   return 0;
00351 }
00352 
00353 /******************************************************************************/
00354 
00355 const Matrix<double>& T92::getPij_t(double d) const
00356 {
00357   l_ = rate_ * r_ * d;
00358   exp1_ = exp(-l_);
00359   exp2_ = exp(-k_ * l_);
00360 
00361   // A
00362   p_(0, 0) = piA_ * (1. + exp1_) + theta_ * exp2_; // A
00363   p_(0, 1) = piC_ * (1. - exp1_);                  // C
00364   p_(0, 2) = piG_ * (1. + exp1_) - theta_ * exp2_; // G
00365   p_(0, 3) = piT_ * (1. - exp1_);                  // T, U
00366 
00367   // C
00368   p_(1, 0) = piA_ * (1. - exp1_);                         // A
00369   p_(1, 1) = piC_ * (1. + exp1_) + (1. - theta_) * exp2_; // C
00370   p_(1, 2) = piG_ * (1. - exp1_);                         // G
00371   p_(1, 3) = piT_ * (1. + exp1_) - (1. - theta_) * exp2_; // T, U
00372 
00373   // G
00374   p_(2, 0) = piA_ * (1. + exp1_) - (1. - theta_) * exp2_; // A
00375   p_(2, 1) = piC_ * (1. - exp1_);                         // C
00376   p_(2, 2) = piG_ * (1. + exp1_) + (1. - theta_) * exp2_; // G
00377   p_(2, 3) = piT_ * (1. - exp1_);                         // T, U
00378 
00379   // T, U
00380   p_(3, 0) = piA_ * (1. - exp1_);                  // A
00381   p_(3, 1) = piC_ * (1. + exp1_) - theta_ * exp2_; // C
00382   p_(3, 2) = piG_ * (1. - exp1_);                  // G
00383   p_(3, 3) = piT_ * (1. + exp1_) + theta_ * exp2_; // T, U
00384 
00385   return p_;
00386 }
00387 
00388 const Matrix<double>& T92::getdPij_dt(double d) const
00389 {
00390   l_ = rate_ * r_ * d;
00391   exp1_ = exp(-l_);
00392   exp2_ = exp(-k_ * l_);
00393 
00394   // A
00395   p_(0, 0) = rate_ * r_ * (piA_ * -exp1_ + theta_ * -k_ * exp2_); // A
00396   p_(0, 1) = rate_ * r_ * (piC_ *   exp1_);                        // C
00397   p_(0, 2) = rate_ * r_ * (piG_ * -exp1_ - theta_ * -k_ * exp2_); // G
00398   p_(0, 3) = rate_ * r_ * (piT_ *   exp1_);                        // T, U
00399 
00400   // C
00401   p_(1, 0) = rate_ * r_ * (piA_ *   exp1_);                               // A
00402   p_(1, 1) = rate_ * r_ * (piC_ * -exp1_ + (1. - theta_) * -k_ * exp2_); // C
00403   p_(1, 2) = rate_ * r_ * (piG_ *   exp1_);                               // G
00404   p_(1, 3) = rate_ * r_ * (piT_ * -exp1_ - (1. - theta_) * -k_ * exp2_); // T, U
00405 
00406   // G
00407   p_(2, 0) = rate_ * r_ * (piA_ * -exp1_ - (1. - theta_) * -k_ * exp2_); // A
00408   p_(2, 1) = rate_ * r_ * (piC_ *   exp1_);                               // C
00409   p_(2, 2) = rate_ * r_ * (piG_ * -exp1_ + (1. - theta_) * -k_ * exp2_); // G
00410   p_(2, 3) = rate_ * r_ * (piT_ *   exp1_);                               // T, U
00411 
00412   // T, U
00413   p_(3, 0) = rate_ * r_ * (piA_ *   exp1_);                        // A
00414   p_(3, 1) = rate_ * r_ * (piC_ * -exp1_ - theta_ * -k_ * exp2_); // C
00415   p_(3, 2) = rate_ * r_ * (piG_ *   exp1_);                        // G
00416   p_(3, 3) = rate_ * r_ * (piT_ * -exp1_ + theta_ * -k_ * exp2_); // T, U
00417 
00418   return p_;
00419 }
00420 
00421 const Matrix<double>& T92::getd2Pij_dt2(double d) const
00422 {
00423   double k2 = k_ * k_;
00424   l_ = rate_ * r_ * d;
00425   double r2 = rate_ * rate_ * r_ * r_;
00426   exp1_ = exp(-l_);
00427   exp2_ = exp(-k_ * l_);
00428 
00429   // A
00430   p_(0, 0) = r2 * (piA_ *   exp1_ + theta_ * k2 * exp2_); // A
00431   p_(0, 1) = r2 * (piC_ * -exp1_);                      // C
00432   p_(0, 2) = r2 * (piG_ *   exp1_ - theta_ * k2 * exp2_); // G
00433   p_(0, 3) = r2 * (piT_ * -exp1_);                      // T, U
00434 
00435   // C
00436   p_(1, 0) = r2 * (piA_ * -exp1_);                             // A
00437   p_(1, 1) = r2 * (piC_ *   exp1_ + (1. - theta_) * k2 * exp2_); // C
00438   p_(1, 2) = r2 * (piG_ * -exp1_);                             // G
00439   p_(1, 3) = r2 * (piT_ *   exp1_ - (1. - theta_) * k2 * exp2_); // T, U
00440 
00441   // G
00442   p_(2, 0) = r2 * (piA_ *   exp1_ - (1. - theta_) * k2 * exp2_); // A
00443   p_(2, 1) = r2 * (piC_ * -exp1_);                             // C
00444   p_(2, 2) = r2 * (piG_ *   exp1_ + (1. - theta_) * k2 * exp2_); // G
00445   p_(2, 3) = r2 * (piT_ * -exp1_);                             // T, U
00446 
00447   // T, U
00448   p_(3, 0) = r2 * (piA_ * -exp1_);                      // A
00449   p_(3, 1) = r2 * (piC_ *   exp1_ - theta_ * k2 * exp2_); // C
00450   p_(3, 2) = r2 * (piG_ * -exp1_);                      // G
00451   p_(3, 3) = r2 * (piT_ *   exp1_ + theta_ * k2 * exp2_); // T, U
00452 
00453   return p_;
00454 }
00455 
00456 /******************************************************************************/
00457 
00458 void T92::setFreq(std::map<int, double>& freqs)
00459 {
00460   double f = (freqs[1] + freqs[2]) / (freqs[0] + freqs[1] + freqs[2] + freqs[3]);
00461   setParameterValue("theta", f);
00462   updateMatrices();
00463 }
00464 
00465 /******************************************************************************/
00466 
 All Classes Namespaces Files Functions Variables Typedefs Friends