bpp-phyl  2.2.0
DecompositionReward.cpp
Go to the documentation of this file.
1 //
2 // File: DecompositionReward.h
3 // Created by: Laurent Guéguen
4 // Created on: mercredi 27 mars 2013, à 12h 36
5 //
6 
7 /*
8 Copyright or © or Copr. Bio++ Development Team, (November 16, 2004, 2005, 2006)
9 
10 This software is a computer program whose purpose is to provide classes
11 for phylogenetic data analysis.
12 
13 This software is governed by the CeCILL license under French law and
14 abiding by the rules of distribution of free software. You can use,
15 modify and/ or redistribute the software under the terms of the CeCILL
16 license as circulated by CEA, CNRS and INRIA at the following URL
17 "http://www.cecill.info".
18 
19 As a counterpart to the access to the source code and rights to copy,
20 modify and redistribute granted by the license, users are provided only
21 with a limited warranty and the software's author, the holder of the
22 economic rights, and the successive licensors have only limited
23 liability.
24 
25 In this respect, the user's attention is drawn to the risks associated
26 with loading, using, modifying and/or developing or reproducing the
27 software by the user in light of its specific status of free software,
28 that may mean that it is complicated to manipulate, and that also
29 therefore means that it is reserved for developers and experienced
30 professionals having in-depth computer knowledge. Users are therefore
31 encouraged to load and test the software's suitability as regards their
32 requirements in conditions enabling the security of their systems and/or
33 data to be ensured and, more generally, to use and operate it in the
34 same conditions as regards security.
35 
36 The fact that you are presently reading this means that you have had
37 knowledge of the CeCILL license and that you accept its terms.
38 */
39 
40 #include "DecompositionReward.h"
41 
42 #include "Bpp/Numeric/Matrix/MatrixTools.h"
43 #include <vector>
44 
45 using namespace bpp;
46 using namespace std;
47 
48 /******************************************************************************/
49 
50 DecompositionReward::DecompositionReward(const SubstitutionModel* model, AlphabetIndex1* alphIndex) :
51  AbstractReward(alphIndex),
52  model_(dynamic_cast<const ReversibleSubstitutionModel*>(model)),
53  nbStates_(model->getNumberOfStates()),
54  jMat_(nbStates_, nbStates_),
55  v_(nbStates_, nbStates_),
56  vInv_(nbStates_, nbStates_),
57  lambda_(nbStates_, nbStates_),
58  bMatrice_(nbStates_, nbStates_),
59  insideProduct_(nbStates_, nbStates_),
60  rewards_(nbStates_, nbStates_),
61  currentLength_(-1.)
62 {
63  //Check compatiblity between model and alphabet Index:
64  if (model->getAlphabet()->getAlphabetType() != alphIndex_->getAlphabet()->getAlphabetType())
65  throw Exception("DecompositionReward (constructor): alphabets do not match between alphabet index and model.");
66  if (!dynamic_cast<const ReversibleSubstitutionModel*>(model))
67  throw Exception("DecompositionReward::DecompositionReward. Only works with declared reversible models for now.");
68 
69  //Initialize the B matrice. This is done once for all,
70  //unless the number of states changes:
72  computeEigen_();
74 }
75 
76 /******************************************************************************/
77 
79 {
80  vector<int> supportedStates = model_->getAlphabetStates();
81  for (size_t j = 0; j < nbStates_; ++j)
82  bMatrice_(j, j) = getAlphabetIndex()->getIndex(supportedStates[j]);
83 }
84 
86 {
90 }
91 
93 {
94  RowMatrix<double> tmp(nbStates_, nbStates_);
95  MatrixTools::mult(vInv_, bMatrice_, tmp);
96  MatrixTools::mult(tmp, v_, insideProduct_);
97 }
98 
100 {
101  jMat_.resize(nbStates_, nbStates_);
102  v_.resize(nbStates_, nbStates_);
103  vInv_.resize(nbStates_, nbStates_);
104  lambda_.resize(nbStates_);
105  bMatrice_.resize(nbStates_, nbStates_);
107  rewards_.resize(nbStates_, nbStates_);
108 }
109 
110 void DecompositionReward::jFunction_(const std::vector<double>& lambda, double t, RowMatrix<double>& result) const
111 {
112  vector<double> expLam = VectorTools::exp(lambda * t);
113  for (unsigned int i = 0; i < nbStates_; ++i) {
114  for (unsigned int j = 0; j < nbStates_; ++j) {
115  double dd = lambda[i] - lambda[j];
116  if (dd == 0) {
117  result(i, j) = t * expLam[i];
118  } else {
119  result(i, j) = (expLam[i] - expLam[j]) / dd;
120  }
121  }
122  }
123 }
124 
125 /******************************************************************************/
126 
127 void DecompositionReward::computeRewards_(double length) const
128 {
129  jFunction_(lambda_, length, jMat_);
130  RowMatrix<double> tmp1(nbStates_, nbStates_), tmp2(nbStates_, nbStates_);
131  MatrixTools::hadamardMult(jMat_, insideProduct_, tmp1);
132  MatrixTools::mult(v_, tmp1, tmp2);
133  MatrixTools::mult(tmp2, vInv_, rewards_);
134 
135  // Now we must divide by pijt:
136  RowMatrix<double> P = model_->getPij_t(length);
137  for (size_t j = 0; j < nbStates_; j++) {
138  for (size_t k = 0; k < nbStates_; k++) {
139  rewards_(j, k) /= P(j, k);
140  if (isnan(rewards_(j, k)))
141  rewards_(j, k) = 0.;
142  }
143  }
144 }
145 
146 /******************************************************************************/
147 
148 Matrix<double>* DecompositionReward::getAllRewards(double length) const
149 {
150  if (length < 0)
151  throw Exception("DecompositionReward::getAllRewards. Negative branch length: " + TextTools::toString(length) + ".");
152  if (length != currentLength_)
153  {
154  computeRewards_(length);
155  currentLength_ = length;
156  }
157  return new RowMatrix<double>(rewards_);
158 }
159 
160 /******************************************************************************/
161 
162 double DecompositionReward::getReward(size_t initialState, size_t finalState, double length) const
163 {
164  if (length < 0)
165  throw Exception("DecompositionReward::getRewards. Negative branch length: " + TextTools::toString(length) + ".");
166  if (length != currentLength_)
167  {
168  computeRewards_(length);
169  currentLength_ = length;
170  }
171  return rewards_(initialState, finalState);
172 }
173 
174 /******************************************************************************/
175 
177 {
178  const ReversibleSubstitutionModel* rModel = dynamic_cast<const ReversibleSubstitutionModel*>(model);
179  if (!rModel)
180  throw Exception("DecompositionReward::setSubstitutionModel. Only works with reversible models for now.");
181 
182  //Check compatiblity between model and substitution register:
183  if (model->getAlphabet()->getAlphabetType() != alphIndex_->getAlphabet()->getAlphabetType())
184  throw Exception("DecompositionReward::setSubstitutionModel: alphabets do not match between alphabet index and model.");
185  model_ = rModel;
186  unsigned int n = model->getAlphabet()->getSize();
187  if (n != nbStates_) {
188  nbStates_ = n;
189  resetStates_();
190  }
191  computeEigen_();
193 
194  //Recompute rewards:
196 }
197 
198 /******************************************************************************/
199 
201 {
202  //Check compatiblity between model and substitution register:
203  if (model_->getAlphabet()->getAlphabetType() != alphIndex_->getAlphabet()->getAlphabetType())
204  throw Exception("DecompositionReward::AlphabetIndexHasChanged: alphabets do not match between alphbaet index and model.");
205 
208 
209  //Recompute rewards:
210  if (currentLength_ > 0)
212 }
213 
214 
RowMatrix< double > bMatrice_
RowMatrix< double > jMat_
Interface for all substitution models.
AlphabetIndex1 * alphIndex_
Definition: Reward.h:155
RowMatrix< double > rewards_
virtual const std::vector< int > & getAlphabetStates() const =0
virtual const Alphabet * getAlphabet() const =0
STL namespace.
Basic implementation of the the Reward interface.
Definition: Reward.h:151
const AlphabetIndex1 * getAlphabetIndex() const
Definition: Reward.h:194
DecompositionReward(const SubstitutionModel *model, AlphabetIndex1 *alphIndex)
virtual const Vdouble & getEigenValues() const =0
virtual const Matrix< double > & getPij_t(double t) const =0
Interface for reversible substitution models.
double getReward(size_t initialState, size_t finalState, double length) const
Get the reward of susbstitutions on a branch, given the initial and final states, and the branch leng...
const ReversibleSubstitutionModel * model_
void computeRewards_(double length) const
RowMatrix< double > insideProduct_
void jFunction_(const std::vector< double > &lambda, double t, RowMatrix< double > &result) const
std::vector< double > lambda_
virtual const Matrix< double > & getRowLeftEigenVectors() const =0
virtual const Matrix< double > & getColumnRightEigenVectors() const =0
Matrix< double > * getAllRewards(double length) const
Get the rewards on a branch, for each initial and final states, and given the branch length...
void setSubstitutionModel(const SubstitutionModel *model)
Set the substitution model.
RowMatrix< double > vInv_