bpp-phyl  2.2.0
MutationProcess.cpp
Go to the documentation of this file.
1 //
2 // File: MutationProcess.cpp
3 // Created by: Julien Dutheil
4 // Created on: Wed Mar 12 16:11:44 2003
5 //
6 
7 /*
8  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
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 "MutationProcess.h"
41 
42 #include <Bpp/Text/TextTools.h>
43 #include <Bpp/Numeric/Random/RandomTools.h>
44 
45 using namespace bpp;
46 
47 /******************************************************************************/
48 
49 size_t AbstractMutationProcess::mutate(size_t state) const
50 {
51  double alea = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0);
52  for (size_t j = 0; j < size_; j++)
53  {
54  if (alea < repartition_[state][j]) return j;
55  }
56  throw Exception("AbstractMutationProcess::mutate. Repartition function is incomplete for state " + TextTools::toString(state));
57 }
58 
59 /******************************************************************************/
60 
61 size_t AbstractMutationProcess::mutate(size_t state, unsigned int n) const
62 {
63  size_t s = state;
64  for (unsigned int k = 0; k < n; k++)
65  {
66  double alea = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0);
67  for (size_t j = 1; j < size_ + 1; j++)
68  {
69  if (alea < repartition_[s][j])
70  {
71  s = j;
72  break;
73  }
74  }
75  }
76  return s;
77 }
78 
79 /******************************************************************************/
80 
82 {
83  return RandomTools::randExponential(-1. / model_->Qij(state, state));
84 }
85 
86 /******************************************************************************/
87 
88 size_t AbstractMutationProcess::evolve(size_t initialState, double time) const
89 {
90  double t = 0;
91  size_t currentState = initialState;
92  t += getTimeBeforeNextMutationEvent(currentState);
93  while (t < time)
94  {
95  currentState = mutate(currentState);
96  t += getTimeBeforeNextMutationEvent(currentState);
97  }
98  return currentState;
99 }
100 
101 /******************************************************************************/
102 
103 MutationPath AbstractMutationProcess::detailedEvolve(size_t initialState, double time) const
104 {
105  MutationPath mp(model_->getAlphabet(), initialState, time);
106  double t = 0;
107  size_t currentState = initialState;
108  t += getTimeBeforeNextMutationEvent(currentState);
109  while (t < time)
110  {
111  currentState = mutate(currentState);
112  mp.addEvent(currentState, t);
113  t += getTimeBeforeNextMutationEvent(currentState);
114  }
115  return mp;
116 }
117 
118 /******************************************************************************/
119 
122 {
123  size_ = model->getNumberOfStates();
124  repartition_ = VVdouble(size_);
125  // Each element contains the probabilities concerning each character in the alphabet.
126 
127  // We will now initiate each of these probability vector.
128  RowMatrix<double> Q = model->getGenerator();
129  for (size_t i = 0; i < size_; i++)
130  {
131  repartition_[i] = Vdouble(size_);
132  double cum = 0;
133  double sum_Q = 0;
134  for (size_t j = 0; j < size_; j++)
135  {
136  if (j != i) sum_Q += Q(i, j);
137  }
138  for (size_t j = 0; j < size_; j++)
139  {
140  if (j != i)
141  {
142  cum += model->Qij(i, j) / sum_Q;
143  repartition_[i][j] = cum;
144  }
145  else repartition_[i][j] = -1;
146  // Forbiden value: does not correspond to a change.
147  }
148  }
149  // Note that I use cumulative probabilities in repartition_ (hence the name).
150  // These cumulative probabilities are useful for the 'mutate(...)' function.
151 }
152 
154 
155 /******************************************************************************/
156 
157 size_t SimpleMutationProcess::evolve(size_t initialState, double time) const
158 {
159  // Compute all cumulative pijt:
160  Vdouble pijt(size_);
161  pijt[0] = model_->Pij_t(initialState, 0, time);
162  for (size_t i = 1; i < size_; i++)
163  {
164  pijt[i] = pijt[i - 1] + model_->Pij_t(initialState, i, time);
165  }
166  double rand = RandomTools::giveRandomNumberBetweenZeroAndEntry(1);
167  for (size_t i = 0; i < size_; i++)
168  {
169  if (rand < pijt[i]) return i;
170  }
171  throw Exception("SimpleSimulationProcess::evolve(intialState, time): error all pijt do not sum to one (total sum = " + TextTools::toString(pijt[size_ - 1]) + ").");
172 }
173 
174 /******************************************************************************/
175 
178 {
179  size_ = alphabetSize;
180  repartition_ = VVdouble(size_);
181  // Each element contains the probabilities concerning each character in the alphabet.
182 
183  // We will now initiate each of these probability vector.
184  for (size_t i = 0; i < size_; i++)
185  {
186  repartition_[i] = Vdouble(size_);
187  for (size_t j = 0; j < size_; j++)
188  {
189  repartition_[i][j] = static_cast<double>(j + 1) / static_cast<double>(size_);
190  }
191  }
192  // Note that I use cumulative probabilities in repartition_ (hence the name).
193  // These cumulative probabilities are useful for the 'mutate(...)' function.
194 }
195 
197 
198 /******************************************************************************/
199 
Interface for all substitution models.
VVdouble repartition_
The repartition function for states probabilities.
MutationPath detailedEvolve(size_t initialState, double time) const
Simulation a character evolution during a specified time according to the given substitution model an...
This class is used by MutationProcess to store detailed results of simulations.
virtual const Alphabet * getAlphabet() const =0
size_t mutate(size_t state) const
Mutate a character in state i.
SelfMutationProcess(size_t alphabetSize)
size_t size_
The number of states allowed for the character to mutate.
Partial implmentation of the MutationProcess interface.
SimpleMutationProcess(const SubstitutionModel *model)
Build a new SimpleMutationProcess object.
virtual double Pij_t(size_t i, size_t j, double t) const =0
virtual double Qij(size_t i, size_t j) const =0
virtual const Matrix< double > & getGenerator() const =0
double getTimeBeforeNextMutationEvent(size_t state) const
Get the time before next mutation event.
size_t evolve(size_t initialState, double time) const
Simulation a character evolution during a specified time according to the given substitution model an...
virtual size_t getNumberOfStates() const =0
Get the number of states.
size_t evolve(size_t initialState, double time) const
Method redefinition for better performance.
const SubstitutionModel * model_
The substitution model to use: