bpp-phyl3 3.0.0
DiscreteDistribution.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
5#include <Bpp/Exceptions.h>
8
9
10using namespace std;
11
12namespace bpp
13{
14ConfiguredDistribution::ConfiguredDistribution (Context& context, NodeRefVec&& deps, std::unique_ptr<DiscreteDistributionInterface>&& distrib)
15 : Value<const DiscreteDistributionInterface*>(std::move(deps), distrib.get()), AbstractParametrizable(distrib->getNamespace()) // , context_(context)
16 , distrib_(std::move(distrib))
17{
18 for (const auto& dep:dependencies())
19 {
20 const auto& param = std::dynamic_pointer_cast<ConfiguredParameter>(dep);
21 shareParameter_(param);
22 }
23}
24
26
27std::string ConfiguredDistribution::description () const { return "Distribution(" + distrib_->getName () + ")"; }
28
30{
31 return "nbClass=" + std::to_string (distrib_->getNumberOfCategories ());
32}
33
34// Model node additional arguments = (type of bpp::BranchModel).
35// Everything else is determined by the node dependencies.
37{
38 const auto* derived = dynamic_cast<const Self*>(&other);
39 if (derived == nullptr)
40 {
41 return false;
42 }
43 else
44 {
45 const auto& thisDistrib = *distrib_;
46 const auto& otherDistrib = *derived->distrib_;
47 return typeid (thisDistrib) == typeid (otherDistrib);
48 }
49}
50
52{
53 const auto& bppDistrib = *distrib_;
54 return typeid (bppDistrib).hash_code ();
55}
56
58{
59 auto m = ConfiguredParametrizable::createConfigured<Target, Self>(c, std::move (deps), std::unique_ptr<DiscreteDistributionInterface>{dynamic_cast<DiscreteDistributionInterface*>(distrib_->clone ())});
60 m->config = this->config; // Duplicate derivation config
61 return m;
62}
63
65// ProbabilitiesFromDiscreteDistribution
66
69 : Value<Eigen::RowVectorXd>(std::move (deps)), nbClass_ (dim) {}
70
71
73{
74 using namespace numeric;
75 return debug (this->accessValueConst ()) + " nbClass=" + to_string (nbClass_);
76}
77
78// ProbabilitiesFromDiscreteDistribution additional arguments = ().
80{
81 return dynamic_cast<const Self*>(&other) != nullptr;
82}
83
85{
86 // d(Prob)/dn = sum_i d(Prob)/dx_i * dx_i/dn (x_i = distrib parameters)
87 auto distribDep = this->dependency (0);
88 auto& distrib = static_cast<Dep&>(*distribDep);
89 auto buildPWithNewDistrib = [this, &c](NodeRef&& newDistrib) {
90 return ConfiguredParametrizable::createRowVector<Dep, Self>(c, {std::move(newDistrib)}, nbClass_);
91 };
92
93 NodeRefVec derivativeSumDeps = ConfiguredParametrizable::generateDerivativeSumDepsForComputations<ConfiguredDistribution, T >(
94 c, distrib, node, nbClass_, buildPWithNewDistrib);
95 return CWiseAdd<T, ReductionOf<T>>::create (c, std::move (derivativeSumDeps), nbClass_);
96}
97
99{
100 return ConfiguredParametrizable::createRowVector<Dep, Self>(c, std::move (deps), nbClass_);
101}
102
104{
105 const auto* distrib = accessValueConstCast<const DiscreteDistributionInterface*>(*this->dependency (0));
106 const auto& probasFromDistrib = distrib->getProbabilities();
107 auto& r = this->accessValueMutable ();
108 r = Eigen::Map<const T>(probasFromDistrib.data(), static_cast<Eigen::Index>(probasFromDistrib.size ()));
109}
110
111
112std::shared_ptr<ProbabilitiesFromDiscreteDistribution> ProbabilitiesFromDiscreteDistribution::create(Context& c, NodeRefVec&& deps)
113{
114 checkDependenciesNotNull (typeid (Self), deps);
115 checkDependencyVectorSize (typeid (Self), deps, 1);
116 checkNthDependencyIs<ConfiguredDistribution>(typeid (Self), deps, 0);
117 size_t nbCat = accessValueConstCast<DiscreteDistributionInterface*>(*deps[0])->getNumberOfCategories();
118 return cachedAs<ProbabilitiesFromDiscreteDistribution>(c, std::make_shared<ProbabilitiesFromDiscreteDistribution>(std::move(deps), RowVectorDimension(Eigen::Index(nbCat))));
119}
120
121
123// ProbabilityFromDiscreteDistribution
124
126 NodeRefVec&& deps, uint nCat)
127 : Value<double>(std::move (deps)), nCat_ (nCat) {}
128
129
131{
132 using namespace numeric;
133 return "proba=" + TextTools::toString(accessValueConst()) + ":nCat=" + TextTools::toString(nCat_);
134}
135
136// ProbabilityFromDiscreteDistribution additional arguments = ().
138{
139 const auto* derived = dynamic_cast<const Self*>(&other);
140 return derived != nullptr && nCat_ == derived->nCat_;
141}
142
143std::shared_ptr<ProbabilityFromDiscreteDistribution> ProbabilityFromDiscreteDistribution::create (Context& c, NodeRefVec&& deps, uint nCat)
144{
145 checkDependenciesNotNull (typeid (Self), deps);
146 checkDependencyVectorSize (typeid (Self), deps, 1);
147 checkNthDependencyIs<ConfiguredDistribution>(typeid (Self), deps, 0);
148 return cachedAs<ProbabilityFromDiscreteDistribution>(c, std::make_shared<ProbabilityFromDiscreteDistribution>(std::move (deps), nCat));
149}
150
152{
153 // d(Prob)/dn = sum_i d(Prob)/dx_i * dx_i/dn (x_i = distrib parameters)
154 auto distribDep = this->dependency (0);
155 auto& distrib = static_cast<Dep&>(*distribDep);
156 auto buildPWithNewDistrib = [this, &c](NodeRef&& newDistrib) {
157 return this->create (c, {std::move (newDistrib)}, nCat_);
158 };
159
160 NodeRefVec derivativeSumDeps = ConfiguredParametrizable::generateDerivativeSumDepsForComputations<Dep, T >(
161 c, distrib, node, 1, buildPWithNewDistrib);
162 return CWiseAdd<T, ReductionOf<T>>::create (c, std::move (derivativeSumDeps), 1);
163}
164
166{
167 return ProbabilityFromDiscreteDistribution::create (c, {std::move (deps)}, nCat_);
168}
169
171{
172 const auto* distrib = accessValueConstCast<const DiscreteDistributionInterface*>(*this->dependency (0));
173 this->accessValueMutable () = distrib->getProbability((size_t)nCat_);
174}
175
177// CategoryFromDiscreteDistribution
178
180 NodeRefVec&& deps, uint nCat)
181 : Value<double>(std::move (deps)), nCat_ (nCat) {}
182
183
185{
186 using namespace numeric;
187 return "rate=" + TextTools::toString(accessValueConst()) + ":nCat=" + TextTools::toString(nCat_);
188}
189
190// CategoryFromDiscreteDistribution additional arguments = ().
192{
193 const auto* derived = dynamic_cast<const Self*>(&other);
194 return derived != nullptr && nCat_ == derived->nCat_;
195}
196
197std::shared_ptr<CategoryFromDiscreteDistribution> CategoryFromDiscreteDistribution::create (Context& c, NodeRefVec&& deps, uint nCat)
198{
199 checkDependenciesNotNull (typeid (Self), deps);
200 checkDependencyVectorSize (typeid (Self), deps, 1);
201 checkNthDependencyIs<ConfiguredDistribution>(typeid (Self), deps, 0);
202 return cachedAs<CategoryFromDiscreteDistribution>(c, std::make_shared<CategoryFromDiscreteDistribution>(std::move (deps), nCat));
203}
204
206{
207 // d(Prob)/dn = sum_i d(Prob)/dx_i * dx_i/dn (x_i = distrib parameters)
208 auto distribDep = this->dependency (0);
209 auto& distrib = static_cast<Dep&>(*distribDep);
210 auto buildPWithNewDistrib = [this, &c](NodeRef&& newDistrib) {
211 return this->create (c, {std::move (newDistrib)}, nCat_);
212 };
213
214 NodeRefVec derivativeSumDeps = ConfiguredParametrizable::generateDerivativeSumDepsForComputations<Dep, T >(
215 c, distrib, node, 1, buildPWithNewDistrib);
216 return CWiseAdd<T, ReductionOf<T>>::create (c, std::move (derivativeSumDeps), 1);
217}
218
220{
221 return CategoryFromDiscreteDistribution::create (c, {std::move (deps)}, nCat_);
222}
223
225{
226 const auto* distrib = accessValueConstCast<const DiscreteDistributionInterface*>(*this->dependency (0));
227 double categoryFromDistrib = distrib->getCategory(nCat_);
228 this->accessValueMutable () = categoryFromDistrib;
229}
230} // namespace bpp
virtual void shareParameter_(const std::shared_ptr< Parameter > &parameter)
std::string debugInfo() const final
Node debug info (default = ""): user defined detailed info for DF graph debug.
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
NodeRef derive(Context &c, const Node_DF &node) final
Returns a node computing d(this_node_expression)/d(node_expression).
void compute() final
Computation implementation.
NodeRef recreate(Context &c, NodeRefVec &&deps) final
Recreate the node with different dependencies.
CategoryFromDiscreteDistribution(NodeRefVec &&deps, uint nCat_)
static std::shared_ptr< Self > create(Context &c, NodeRefVec &&deps, uint nCat)
Data flow node representing a DiscreteDistribution configured with parameter values.
NumericalDerivativeConfiguration config
Configuration for numerical derivation of computation nodes using this Model.
std::unique_ptr< DiscreteDistributionInterface > distrib_
bool compareAdditionalArguments(const Node_DF &other) const
Compare node-specific configuration to another.
std::string debugInfo() const final
Node debug info (default = ""): user defined detailed info for DF graph debug.
NodeRef recreate(Context &c, NodeRefVec &&deps) final
Recreate the node with different dependencies.
ConfiguredDistribution(Context &context, NodeRefVec &&deps, std::unique_ptr< DiscreteDistributionInterface > &&distrib)
std::string description() const final
Node pretty name (default = type name).
std::size_t hashAdditionalArguments() const
Return the hash of node-specific configuration.
Context for dataflow node construction.
Definition: DataFlow.h:527
Base dataflow Node class.
Definition: DataFlow.h:152
const NodeRefVec & dependencies() const noexcept
Definition: DataFlow.h:183
const NodeRef & dependency(std::size_t i) const noexcept
Definition: DataFlow.h:185
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
NodeRef recreate(Context &c, NodeRefVec &&deps) final
Recreate the node with different dependencies.
static std::shared_ptr< Self > create(Context &c, NodeRefVec &&deps)
std::string debugInfo() const final
Node debug info (default = ""): user defined detailed info for DF graph debug.
ProbabilitiesFromDiscreteDistribution(NodeRefVec &&deps, const Dimension< T > &dim)
NodeRef derive(Context &c, const Node_DF &node) final
Returns a node computing d(this_node_expression)/d(node_expression).
void compute() final
Computation implementation.
void compute() final
Computation implementation.
static std::shared_ptr< Self > create(Context &c, NodeRefVec &&deps, uint nCat)
NodeRef derive(Context &c, const Node_DF &node) final
Returns a node computing d(this_node_expression)/d(node_expression).
ProbabilityFromDiscreteDistribution(NodeRefVec &&deps, uint nCat_)
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
NodeRef recreate(Context &c, NodeRefVec &&deps) final
Recreate the node with different dependencies.
std::string debugInfo() const final
Node debug info (default = ""): user defined detailed info for DF graph debug.
Abstract Node storing a value of type T.
Definition: DataFlow.h:352
Eigen::RowVectorXd & accessValueMutable() noexcept
Definition: DataFlow.h:416
const Eigen::RowVectorXd & accessValueConst() const noexcept
Raw value access (const).
Definition: DataFlow.h:385
std::string toString(T t)
std::string debug(const T &t, typename std::enable_if< std::is_arithmetic< T >::value >::type *=0)
Defines the basic types of data flow nodes.
void checkDependenciesNotNull(const std::type_info &contextNodeType, const NodeRefVec &deps)
Checks that all dependencies are not null, throws if not.
Definition: DataFlow.cpp:103
std::string to_string(const NoDimension &)
std::vector< NodeRef > NodeRefVec
Alias for a dependency vector (of NodeRef).
Definition: DataFlow.h:81
void checkDependencyVectorSize(const std::type_info &contextNodeType, const NodeRefVec &deps, std::size_t expectedSize)
Definition: DataFlow.cpp:83
std::shared_ptr< Node_DF > NodeRef
Definition: DataFlow.h:78
Store a dimension for type T.