bpp-phyl  2.1.0
Bpp/Phyl/Model/Nucleotide/gBGC.cpp
Go to the documentation of this file.
00001 //
00002 // File: gBGC.cpp
00003 // Created by: Laurent Gueguen
00004 // Created on: lundi 13 février 2012, à 09h 42
00005 //
00006 
00007 /*
00008    Copyright or © or Copr. CNRS, (November 16, 2004)
00009    This software is a computer program whose purpose is to provide
00010    classes for phylogenetic data analysis.
00011 
00012    This software is governed by the CeCILL license under French law and
00013    abiding by the rules of distribution of free software. You can use,
00014    modify and/ or redistribute the software under the terms of the CeCILL
00015    license as circulated by CEA, CNRS and INRIA at the following URL
00016    "http://www.cecill.info".
00017 
00018    As a counterpart to the access to the source code and rights to copy,
00019    modify and redistribute granted by the license, users are provided
00020    only with a limited warranty and the software's author, the holder of
00021    the economic rights, and the successive licensors have only limited
00022    liability.
00023 
00024    In this respect, the user's attention is drawn to the risks associated
00025    with loading, using, modifying and/or developing or reproducing the
00026    software by the user in light of its specific status of free software,
00027    that may mean that it is complicated to manipulate, and that also
00028    therefore means that it is reserved for developers and experienced
00029    professionals having in-depth computer knowledge. Users are therefore
00030    encouraged to load and test the software's suitability as regards
00031    their requirements in conditions enabling the security of their
00032    systems and/or data to be ensured and, more generally, to use and
00033    operate it in the same conditions as regards security.
00034 
00035    The fact that you are presently reading this means that you have had
00036    knowledge of the CeCILL license and that you accept its terms.
00037  */
00038 
00039 #include "gBGC.h"
00040 
00041 // From the STL:
00042 #include <cmath>
00043 
00044 using namespace bpp;
00045 
00046 #include <Bpp/Numeric/Matrix/MatrixTools.h>
00047 #include <Bpp/Numeric/VectorTools.h>
00048 #include <Bpp/Numeric/Matrix/EigenValue.h>
00049 
00050 /******************************************************************************/
00051 
00052 gBGC::gBGC(const NucleicAlphabet* alph, NucleotideSubstitutionModel* const pm, double gamma) :
00053   AbstractParameterAliasable("gBGC."),
00054   AbstractSubstitutionModel(alph,"gBGC."),
00055   pmodel_(pm->clone()),
00056   nestedPrefix_(pm->getNamespace()),
00057   gamma_(gamma)
00058 {
00059   pmodel_->setNamespace("gBGC."+nestedPrefix_);
00060   pmodel_->enableEigenDecomposition(0);
00061   addParameters_(pmodel_->getParameters());
00062   addParameter_(new Parameter("gBGC.gamma", gamma_,new IntervalConstraint(-999, 10, true, true), true));
00063 
00064   updateMatrices();
00065 }
00066 
00067 gBGC::gBGC(const gBGC& gbgc) :
00068   AbstractParameterAliasable(gbgc),
00069   AbstractSubstitutionModel(gbgc),
00070   pmodel_(gbgc.pmodel_->clone()),
00071   nestedPrefix_(gbgc.nestedPrefix_),
00072   gamma_(gbgc.gamma_)
00073 {
00074 }
00075 
00076 gBGC& gBGC::operator=(const gBGC& gbgc)
00077 {
00078   AbstractParameterAliasable::operator=(gbgc);
00079   AbstractSubstitutionModel::operator=(gbgc);
00080   pmodel_ = gbgc.pmodel_->clone();
00081   nestedPrefix_ = gbgc.nestedPrefix_;
00082   gamma_=gbgc.gamma_;
00083   return *this;
00084 }
00085 
00086 void gBGC::fireParameterChanged(const ParameterList& parameters)
00087 {
00088   pmodel_->matchParametersValues(parameters);
00089   AbstractSubstitutionModel::matchParametersValues(parameters);
00090   updateMatrices();
00091 }
00092 
00093 void gBGC::updateMatrices()
00094 {
00095   gamma_=getParameterValue("gamma");
00096   unsigned int i,j;
00097   // Generator:
00098   double eg=exp(gamma_);
00099   for ( i = 0; i < 4; i++)
00100     for ( j = 0; j < 4; j++)
00101       generator_(i,j)=pmodel_->Qij(i,j);
00102 
00103   generator_(0,1) *= eg;
00104   generator_(0,2) *= eg;
00105   generator_(3,1) *= eg;
00106   generator_(3,2) *= eg;
00107 
00108   generator_(0,0) -= (generator_(0,1)+generator_(0,2))*(1-1/eg);
00109   generator_(3,3) -= (generator_(3,1)+generator_(3,2))*(1-1/eg);
00110 
00111   // calcul spectral
00112 
00113   EigenValue<double> ev(generator_);
00114   eigenValues_ = ev.getRealEigenValues();
00115   
00116   rightEigenVectors_ = ev.getV();
00117   MatrixTools::inv(rightEigenVectors_,leftEigenVectors_);
00118 
00119   iEigenValues_ = ev.getImagEigenValues();
00120 
00121   // frequence stationnaire
00122   double x = 0;
00123   j = 0;
00124   while (j < 4){
00125     if (abs(eigenValues_[j]) < 0.000001 && abs(iEigenValues_[j]) < 0.000001) {
00126       eigenValues_[j]=0; //to avoid approximation problems in the future
00127       iEigenValues_[j]=0; //to avoid approximation problems in the future
00128       for (i = 0; i < 4; i++)
00129         {
00130           freq_[i] = leftEigenVectors_(j,i);
00131           x += freq_[i];
00132         }
00133       break;
00134     }
00135     j++;
00136   }
00137 
00138   for (i = 0; i < 4; i++)
00139     freq_[i] /= x;
00140 
00141   // mise a l'echelle
00142 
00143   x = 0;
00144   for (i = 0; i < 4; i++)
00145     x += freq_[i] * generator_(i,i);
00146 
00147   MatrixTools::scale(generator_,-1 / x);
00148 
00149   for (i = 0; i < 4; i++)
00150     eigenValues_[i] /= -x;
00151   
00152   isDiagonalizable_=true;
00153   for (i = 0; i < size_ && isDiagonalizable_; i++)
00154     if (abs(iEigenValues_[i])> NumConstants::SMALL()){
00155       isDiagonalizable_=false;
00156       break;
00157     }
00158 
00159   // and the exchangeability_
00160   for ( i = 0; i < size_; i++)
00161     for ( j = 0; j < size_; j++)
00162       exchangeability_(i,j) = generator_(i,j) / freq_[j];
00163 
00164 }
00165 
00166 void gBGC::setNamespace(const std::string& prefix)
00167 {
00168   AbstractSubstitutionModel::setNamespace(prefix);
00169   // We also need to update the namespace of the nested model:
00170   pmodel_->setNamespace(prefix + nestedPrefix_);
00171 }
00172 
00173 
00174 std::string gBGC::getName() const
00175 {
00176   return "gBGC(model=" + pmodel_->getName()+")";
00177 }
00178 
 All Classes Namespaces Files Functions Variables Typedefs Friends