bpp-phyl3  3.0.0
MultinomialFromTransitionModel.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #ifndef BPP_PHYL_MODEL_MULTINOMIALFROMTRANSITIONMODEL_H
6 #define BPP_PHYL_MODEL_MULTINOMIALFROMTRANSITIONMODEL_H
7 
8 #include <unsupported/Eigen/SpecialFunctions>
9 
10 #include "AbstractWrappedModel.h"
11 
12 // namespace std
13 // {
14 // // template<class U = Eigen::VectorXd>
15 // template<>
16 
17 
18 // }
19 
20 namespace bpp
21 {
32 {
33  typedef bool lessEigenType(Eigen::VectorXd const&, Eigen::VectorXd const&);
34 
35 private:
39  std::shared_ptr<TransitionModelInterface> subModel_; // -> shared?
40 
41  /*
42  * The number of states
43  *
44  */
45 
46  size_t size_;
47 
54  mutable double tref_;
55 
63  mutable const Matrix<double>* Pij_t, * dPij_dt, * d2Pij_dt2;
64 
68  mutable Eigen::VectorXd Pi_, dPi_, d2Pi_;
69 
73  mutable std::map<Eigen::VectorXd, double, bool (*)(const Eigen::VectorXd&, const Eigen::VectorXd&)> mapFact_;
74 
75  static bool lessEigen(Eigen::VectorXd const& a, Eigen::VectorXd const& b)
76  {
77  assert(a.size() == b.size());
78  for (auto i = 0; i < a.size(); ++i)
79  {
80  if (a[i] < b[i]) return true;
81  if (a[i] > b[i]) return false;
82  }
83  return false;
84  }
85 
86 protected:
88  {
89  return *subModel_;
90  }
91 
93  {
94  return *subModel_;
95  }
96 
97 public:
98  MultinomialFromTransitionModel(std::shared_ptr<TransitionModelInterface> originalModel) :
99  AbstractParameterAliasable("MultinomialFrom." + originalModel->getNamespace()),
100  AbstractWrappedModel("MultinomialFrom." + originalModel->getNamespace()),
101  subModel_(originalModel),
102  size_(originalModel->getNumberOfStates()),
104  {
105  subModel_->setNamespace(getNamespace());
106  addParameters_(subModel_->getParameters());
107  }
108 
111  AbstractWrappedModel(fmsm),
112  subModel_(fmsm.subModel_->clone()),
113  size_(fmsm.size_),
115  {}
116 
118  {
120 
121  subModel_ = std::shared_ptr<TransitionModelInterface>(fmsm.subModel_->clone());
122  size_ = fmsm.size_;
123  Pi_.resize(Eigen::Index(size_));
124  dPi_.resize(Eigen::Index(size_));
125  d2Pi_.resize(Eigen::Index(size_));
126 
128  mapFact_.clear();
129 
130  return *this;
131  }
132 
134 
135  MultinomialFromTransitionModel* clone() const override { return new MultinomialFromTransitionModel(*this); }
136 
137 public:
138  void fireParameterChanged(const ParameterList& parameters) override
139  {
141  if (model().matchParametersValues(parameters))
143  }
144 
145  const BranchModelInterface& model() const override
146  {
147  return *subModel_;
148  }
149 
151  {
152  return *subModel_;
153  }
154 
155  const Eigen::VectorXd& Lik_t (const Eigen::VectorXd& from, double t) const override;
156  const Eigen::VectorXd& dLik_dt (const Eigen::VectorXd& from, double t) const override;
157  const Eigen::VectorXd& d2Lik_dt2(const Eigen::VectorXd& from, double t) const override;
158 
159  void setFreqFromData(const SequenceDataInterface& data, double pseudoCount = 0)
160  {
161  transitionModel().setFreqFromData(data, pseudoCount);
162  }
163 
164  virtual void setFreq(std::map<int, double>& m)
165  {
167  }
168 
169  double getRate() const override { return transitionModel().getRate(); }
170 
171  void setRate(double rate) override { return transitionModel().setRate(rate); }
172 
173  double getInitValue(size_t i, int state) const override { return transitionModel().getInitValue(i, state); }
174 
175  std::string getName() const override
176  {
177  return "MultinomialFrom";
178  }
179 
180  void addRateParameter() override
181  {
184  }
185 
186 private:
191  void compute_Multinomial_(const Eigen::VectorXd& counts) const;
192  void compute_dMultinomial_dt_(const Eigen::VectorXd& counts) const;
193  void compute_d2Multinomial_dt2_(const Eigen::VectorXd& counts) const;
194 
195  static uint factorial(uint n)
196  {
197  return (n == 0 || n == 1) ? 1 : factorial(n - 1) * n;
198  }
199 
206  double getFact_(const Eigen::VectorXd& counts) const
207  {
208  auto it = mapFact_.find(counts);
209  if (it == mapFact_.end())
210  {
211  auto lsto(std::lgamma(counts.sum() + 1));
212  auto lr((counts.array() + 1.).lgamma().sum());
213  auto fact = lsto - lr;
214 
215  mapFact_[counts] = fact;
216  return fact;
217  }
218  else
219  return it->second;
220  }
221 };
222 } // end of namespace bpp.
223 #endif // BPP_PHYL_MODEL_MULTINOMIALFROMTRANSITIONMODEL_H
void addParameters_(const ParameterList &parameters)
void addParameter_(Parameter *parameter)
AbstractParameterAliasable & operator=(const AbstractParameterAliasable &ap)
virtual void fireParameterChanged(const ParameterList &parameters)
bool matchParametersValues(const ParameterList &parameters) override
std::string getNamespace() const override
Abstract class of Wrapping model class, where all methods are redirected from model().
size_t getNumberOfStates() const override
Get the number of states.
Interface for all Branch models.
virtual void setRate(double rate)=0
Set the rate of the model (must be positive).
virtual double getRate() const =0
Get the rate.
virtual double getInitValue(size_t i, int state) const =0
virtual void addRateParameter()=0
From a model, compute the likelihood of counts given an ancestral state.
const TransitionModelInterface & transitionModel() const
MultinomialFromTransitionModel & operator=(const MultinomialFromTransitionModel &fmsm)
MultinomialFromTransitionModel(std::shared_ptr< TransitionModelInterface > originalModel)
std::string getName() const override
Get the name of the model.
double getRate() const override
Get the rate.
Eigen::VectorXd Pi_
Used return vectors.
const Eigen::VectorXd & d2Lik_dt2(const Eigen::VectorXd &from, double t) const override
void setRate(double rate) override
Set the rate of the model (must be positive).
std::map< Eigen::VectorXd, double, bool(*)(const Eigen::VectorXd &, const Eigen::VectorXd &)> mapFact_
map to store constant values of multinomial
static bool lessEigen(Eigen::VectorXd const &a, Eigen::VectorXd const &b)
MultinomialFromTransitionModel(const MultinomialFromTransitionModel &fmsm)
MultinomialFromTransitionModel * clone() const override
double getFact_(const Eigen::VectorXd &counts) const
Compute the log of the normalization term for the multinomial for any count, and keeps it in a map to...
std::shared_ptr< TransitionModelInterface > subModel_
The related model.
void fireParameterChanged(const ParameterList &parameters) override
const Eigen::VectorXd & Lik_t(const Eigen::VectorXd &from, double t) const override
const BranchModelInterface & model() const override
void compute_Multinomial_(const Eigen::VectorXd &counts) const
Fills the res vector of the likelihoods of the counts given ancestral states & transition matrix.
double getInitValue(size_t i, int state) const override
const Matrix< double > * Pij_t
Transition Matrices owned by the submodel.
double tref_
Reference time to avoid recomuputation of transition matrix when time has not changed....
void setFreqFromData(const SequenceDataInterface &data, double pseudoCount=0)
const Eigen::VectorXd & dLik_dt(const Eigen::VectorXd &from, double t) const override
void compute_d2Multinomial_dt2_(const Eigen::VectorXd &counts) const
virtual void setFreq(std::map< int, double > &m)
void compute_dMultinomial_dt_(const Eigen::VectorXd &counts) const
bool lessEigenType(Eigen::VectorXd const &, Eigen::VectorXd const &)
static double MINF()
static const std::shared_ptr< IntervalConstraint > R_PLUS_STAR
Interface for all transition models.
virtual void setFreq(std::map< int, double > &frequencies)=0
Set equilibrium frequencies.
virtual void setFreqFromData(const SequenceDataInterface &data, double pseudoCount=0)=0
Set equilibrium frequencies equal to the frequencies estimated from the data.
Defines the basic types of data flow nodes.