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
11
12// namespace std
13// {
14// // template<class U = Eigen::VectorXd>
15// template<>
16
17
18// }
19
20namespace bpp
21{
32{
33 typedef bool lessEigenType(Eigen::VectorXd const&, Eigen::VectorXd const&);
34
35private:
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
86protected:
88 {
89 return *subModel_;
90 }
91
93 {
94 return *subModel_;
95 }
96
97public:
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
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
136
137public:
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
186private:
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 BranchModelInterface & model() const override
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
const TransitionModelInterface & transitionModel() const
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...
MultinomialFromTransitionModel & operator=(const MultinomialFromTransitionModel &fmsm)
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
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.