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 
10 using namespace std;
11 
12 namespace bpp
13 {
14 ConfiguredDistribution::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 
27 std::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 
68  NodeRefVec&& deps, const Dimension<Eigen::RowVectorXd>& dim)
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 
112 std::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 
143 std::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 
197 std::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.
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 NodeRef & dependency(std::size_t i) const noexcept
Definition: DataFlow.h:185
const NodeRefVec & dependencies() const noexcept
Definition: DataFlow.h:183
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
const Eigen::RowVectorXd & accessValueConst() const noexcept
Raw value access (const).
Definition: DataFlow.h:385
Eigen::RowVectorXd & accessValueMutable() noexcept
Definition: DataFlow.h:416
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.