bpp-phyl3 3.0.0
DataFlowNumeric.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_LIKELIHOOD_DATAFLOW_DATAFLOWNUMERIC_H
6#define BPP_PHYL_LIKELIHOOD_DATAFLOW_DATAFLOWNUMERIC_H
7
13#include <Eigen/Core>
14#include <algorithm>
15#include <cassert>
16#include <string>
17#include <tuple>
18#include <type_traits>
19
20#include "DataFlow.h"
21#include "Definitions.h"
22
23/* For now copy matrix cell by cell.
24 * TODO use eigen internally in SubstitutionModel ! (not perf critical for now though)
25 * FIXME if multithreading, internal model state must be removed !
26 */
27
28namespace bpp
29{
30/******************/
31
32template<typename eVector, typename bVector>
33using ForConvert = typename std::enable_if< ((std::is_same<bVector, Vdouble>::value
34 || std::is_same<bVector, std::vector<ExtendedFloat>>::value)
35 &&
36 (std::is_same<eVector, Eigen::RowVectorXd>::value
37 || std::is_same<eVector, Eigen::VectorXd>::value)), bool>::type;
38
39template<typename eVector,
40 typename bVector, ForConvert<eVector, bVector> = true>
41void copyBppToEigen (const bVector& bppVector, eVector& eigenVector)
42{
43 const auto eigenRows = static_cast<Eigen::Index>(bppVector.size());
44 eigenVector.resize (eigenRows);
45 for (Eigen::Index i = 0; i < eigenRows; ++i)
46 {
47 eigenVector (i) = convert(bppVector[size_t(i)]);
48 }
49}
50
51extern template void copyBppToEigen (const std::vector<ExtendedFloat>& bppVector, Eigen::VectorXd& eigenVector);
52extern template void copyBppToEigen (const std::vector<ExtendedFloat>& bppVector, Eigen::RowVectorXd& eigenVector);
53extern template void copyBppToEigen (const bpp::Vdouble& bppVector, Eigen::RowVectorXd& eigenVector);
54extern template void copyBppToEigen (const bpp::Vdouble& bppVector, Eigen::VectorXd& eigenVector);
55
56
57/*****************/
58
59template<typename eVector>
60using EFVector = typename std::enable_if<(std::is_same<eVector, ExtendedFloatRowVectorXd>::value
61 || std::is_same<eVector, ExtendedFloatVectorXd>::value), bool>::type;
62
63template<typename eVector, EFVector<eVector> = true>
64void copyBppToEigen (const std::vector<ExtendedFloat>& bppVector, eVector& eigenVector)
65{
66 // Look for largest extendedfloat
67 ExtendedFloat::ExtType maxE = std::max_element(bppVector.begin(), bppVector.end(), [](const ExtendedFloat& lhs, const ExtendedFloat& rhs){
68 return lhs.exponent_part() < rhs.exponent_part();
69 })->exponent_part();
70
71 eigenVector.exponent_part() = maxE;
72 eigenVector.float_part() = Eigen::RowVectorXd::NullaryExpr(static_cast<Eigen::Index>(bppVector.size()),
73 [&maxE, &bppVector](int i){
74 return bppVector[(size_t)i].float_part() * bpp::constexpr_power<double>(bpp::ExtendedFloat::radix, bppVector[(size_t)i].exponent_part () - maxE);
75 });
76}
77
78
79extern template void copyBppToEigen (const std::vector<ExtendedFloat>& bppVector, ExtendedFloatRowVectorXd& eigenVector);
80extern template void copyBppToEigen (const std::vector<ExtendedFloat>& bppVector, ExtendedFloatVectorXd& eigenVector);
81
82
83/****************/
84
85template<typename eVector>
86using EFoutput = typename std::enable_if<(std::is_same<eVector, ExtendedFloatRowVectorXd>::value
87 || std::is_same<eVector, ExtendedFloatVectorXd>::value), bool>::type;
88
89template<typename eVector,
90 EFoutput<eVector> = true>
91void copyBppToEigen (const Vdouble& bppVector, eVector& eigenVector)
92{
93 // Look for largest extendedfloat
94 eigenVector.exponent_part() = 0;
95 copyBppToEigen(bppVector, eigenVector.float_part());
96 eigenVector.normalize();
97}
98
99
100extern template void copyBppToEigen (const bpp::Vdouble& bppVector, ExtendedFloatRowVectorXd& eigenVector);
101extern template void copyBppToEigen (const bpp::Vdouble& bppVector, ExtendedFloatVectorXd& eigenVector);
102
103
104/********************************/
105
106extern void copyBppToEigen (const bpp::Matrix<double>& bppMatrix, Eigen::MatrixXd& eigenMatrix);
107extern void copyBppToEigen (const bpp::Matrix<double>& bppMatrix, ExtendedFloatMatrixXd& eigenMatrix);
108
109extern void copyBppToEigen (const std::vector<Eigen::VectorXd>& bppVector, Eigen::MatrixXd& eigenMatrix);
110extern void copyBppToEigen (const std::vector<ExtendedFloatVectorXd>& bppVector, ExtendedFloatMatrixXd& eigenMatrix);
111
112
113/****************/
114/* copyEigenToBpp */
115
116
117template<typename eType,
118 typename = typename std::enable_if<(std::is_same<eType, double>::value
119 || std::is_same<eType, ExtendedFloat>::value)>::type>
120void copyEigenToBpp (const ExtendedFloatMatrixXd& eigenMatrix, std::vector<std::vector<eType>>& bppMatrix)
121{
122 const auto eigenRows = static_cast<std::size_t>(eigenMatrix.rows());
123 const auto eigenCols = static_cast<std::size_t>(eigenMatrix.cols());
124
125 bppMatrix.resize (eigenRows);
126 for (size_t i = 0; i < eigenRows; ++i)
127 {
128 bppMatrix[i].resize (eigenCols);
129 auto bMi = &bppMatrix[i];
130 for (size_t j = 0; j < eigenCols; ++j)
131 {
132 (*bMi)[j] = convert(eigenMatrix (static_cast<Eigen::Index>(i), static_cast<Eigen::Index>(j)));
133 }
134 }
135}
136
137
138extern template void copyEigenToBpp(const ExtendedFloatMatrixXd& eigenMatrix, std::vector<std::vector<double>>& bppMatrix);
139extern template void copyEigenToBpp(const ExtendedFloatMatrixXd& eigenMatrix, std::vector<std::vector<bpp::ExtendedFloat>>& bppMatrix);
140
141template<typename eType,
142 typename = typename std::enable_if<(std::is_same<eType, double>::value
143 || std::is_same<eType, ExtendedFloat>::value)>::type>
144void copyEigenToBpp (const Eigen::MatrixXd& eigenMatrix, std::vector<std::vector<eType>>& bppMatrix)
145{
146 const auto eigenRows = static_cast<std::size_t>(eigenMatrix.rows());
147 const auto eigenCols = static_cast<std::size_t>(eigenMatrix.cols());
148
149 bppMatrix.resize (eigenRows);
150 for (size_t i = 0; i < eigenRows; ++i)
151 {
152 bppMatrix[i].resize (eigenCols);
153 auto bMi = &bppMatrix[i];
154 for (size_t j = 0; j < eigenCols; ++j)
155 {
156 (*bMi)[j] = eigenMatrix (static_cast<Eigen::Index>(i), static_cast<Eigen::Index>(j));
157 }
158 }
159}
160
161
162extern template void copyEigenToBpp(const Eigen::MatrixXd& eigenMatrix, std::vector<std::vector<double>>& bppMatrix);
163extern template void copyEigenToBpp(const Eigen::MatrixXd& eigenMatrix, std::vector<std::vector<bpp::ExtendedFloat>>& bppMatrix);
164
165
166extern void copyEigenToBpp(const MatrixLik& eigenMatrix, Matrix<double>& bppMatrix);
167
168
169template<typename eVector, typename bVector>
170using ForConvert2 = typename std::enable_if< ((std::is_same<bVector, Vdouble>::value
171 || std::is_same<bVector, std::vector<ExtendedFloat>>::value)
172 &&
173 (std::is_same<eVector, Eigen::RowVectorXd>::value
174 || std::is_same<eVector, Eigen::VectorXd>::value
175 || std::is_same<eVector, ExtendedFloatVectorXd>::value
176 || std::is_same<eVector, ExtendedFloatRowVectorXd>::value)), bool>::type;
177
178
179template<typename eVector,
180 typename bVector, ForConvert2<bVector, eVector> = true>
181void copyEigenToBpp (const bVector& eigenVector, eVector& bppVector)
182{
183 bppVector.resize(size_t(eigenVector.size()));
184 for (auto i = 0; i < eigenVector.size(); i++)
185 {
186 bppVector[(size_t)i] = convert(eigenVector(i));
187 }
188}
189
190extern template void copyEigenToBpp (const RowLik& eigenVector, Vdouble& bppVector);
191extern template void copyEigenToBpp (const VectorLik& eigenVector, Vdouble& bppVector);
192extern template void copyEigenToBpp (const RowLik& eigenVector, std::vector<ExtendedFloat>& bppVector);
193extern template void copyEigenToBpp (const VectorLik& eigenVector, std::vector<ExtendedFloat>& bppVector);
194
195/*******************************************/
196/*** Definition of function from (const Eigen::Vector&) -> const Eigen::Vector& ***/
197
198using TransitionFunction = std::function<VectorLik (const VectorLik&)>;
199
200/*
201 * The same but with constant result
202 *
203 */
204
206 public TransitionFunction
207{
208private:
210
211public:
212 ConstantTransitionFunction(double val, int row) :
213 result_(row)
214 {
215 result_.fill(val);
216 }
217
219 result_(res){}
220
222 {
223 return result_;
224 }
225};
226
227/******************************************************************************
228 * Dimension
229 */
230
232struct NoDimension {};
233
234std::string to_string (const NoDimension&);
235inline std::size_t hash (const NoDimension&) { return 0; }
236inline bool operator==(const NoDimension&, const NoDimension&) { return true; }
237inline bool operator!=(const NoDimension&, const NoDimension&) { return false; }
238
241{
242 Eigen::Index rows{};
243 Eigen::Index cols{};
244
245 MatrixDimension () = default;
246 MatrixDimension (Eigen::Index rows_, Eigen::Index cols_) : rows (rows_),
247 cols (cols_)
248 {}
249 MatrixDimension (int rows_, int cols_) : rows (Eigen::Index(rows_)),
250 cols (Eigen::Index(cols_))
251 {}
252 MatrixDimension (size_t rows_, size_t cols_) : rows (Eigen::Index(rows_)),
253 cols (Eigen::Index(cols_))
254 {}
255
256 // Get dimensions of any matrix-like eigen object.
257 template<typename Derived>
258 MatrixDimension (const Eigen::MatrixBase<Derived>& m) : MatrixDimension (m.rows (), m.cols ())
259 {}
260
261 template<typename Derived>
262 MatrixDimension (const ExtendedFloatEigenBase<Derived>& m) : MatrixDimension (m.derived().float_part().rows (), m.derived().float_part().cols ())
263 {}
264};
265
267 public MatrixDimension
268{
270 VectorDimension(Eigen::Index rows_) : MatrixDimension(rows_, Eigen::Index(1))
271 {}
272 VectorDimension(int rows_) : MatrixDimension(rows_, 1)
273 {}
274 VectorDimension(size_t rows_) : MatrixDimension(rows_, (size_t)1)
275 {}
276};
277
279 public MatrixDimension
280{
282 RowVectorDimension(Eigen::Index cols_) : MatrixDimension(Eigen::Index(1), cols_)
283 {}
284 RowVectorDimension(int cols_) : MatrixDimension(1, cols_)
285 {}
286 RowVectorDimension(size_t cols_) : MatrixDimension((size_t)1, cols_)
287 {}
288};
289
290std::string to_string (const MatrixDimension& dim);
291
292std::size_t hash (const MatrixDimension& dim);
293
294inline bool operator==(const MatrixDimension& lhs, const MatrixDimension& rhs)
295{
296 return lhs.rows == rhs.rows && lhs.cols == rhs.cols;
297}
298inline bool operator!=(const MatrixDimension& lhs, const MatrixDimension& rhs) { return !(lhs == rhs); }
299
307template<typename T> struct Dimension;
308
310template<> struct Dimension<double> : NoDimension
311{
312 Dimension () = default;
313 Dimension (const double&)
314 {}
315};
316
317template<> struct Dimension<uint> : NoDimension
318{
319 Dimension () = default;
320 Dimension (const uint&)
321 {}
322};
323
324template<> struct Dimension<char> : NoDimension
325{
326 Dimension () = default;
327 Dimension (const char&)
328 {}
329};
330
331template<> struct Dimension<std::string> : NoDimension
332{
333 Dimension () = default;
334 Dimension (const std::string&)
335 {}
336};
337
338template<> struct Dimension<size_t> : NoDimension
339{
340 Dimension () = default;
341 Dimension (const size_t&)
342 {}
343};
344template<> struct Dimension<float> : NoDimension
345{
346 Dimension () = default;
347 Dimension (const float&)
348 {}
349};
350
352{
353 Dimension () = default;
355 {}
356};
357
358template<> struct Dimension<Parameter> : NoDimension
359{
360 Dimension () = default;
362 {}
363};
364
371template<typename T, int Rows, int Cols> struct Dimension<Eigen::Matrix<T, Rows, Cols>> : MatrixDimension
372{
373 using MatrixDimension::MatrixDimension; // Have the same constructors as MatrixDimension
375 {} // From MatrixDimension
376};
377
378
379template< int R, int C, template< int R2 = R, int C2 = C> class EigenType > struct Dimension<ExtendedFloatEigen<R, C, EigenType>> : MatrixDimension
380{
383 {} // From MatrixDimension
384};
385
386
387template<> struct Dimension<TransitionFunction> : Dimension<VectorLik>
388{
389public:
390 Dimension () = default;
391 Dimension (Eigen::Index rows_) : Dimension<VectorLik>(rows_, (Eigen::Index)1)
392 {}
393};
394
395
396/******************************************************************************
397 * Collection of overloaded numerical functions.
398 * Not documented with doxygen, as this is only intended for use in dataflow nodes.
399 */
400namespace numeric
401{
402// Error util
403void checkDimensionIsSquare (const MatrixDimension& dim);
404
405// Create a zero value of the given dimension
406template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
408{
409 return T (0);
410}
411
412template<typename T = void>
414{
415 return '0';
416}
417
418template<typename T = void>
419std::string zero (const Dimension<std::string>&)
420{
421 return "zero";
422}
423
424template<typename T = void>
426{
427 return *std::make_shared<Parameter>("Zero", 0);
428}
429
430template<typename T = void>
432{
433 return ExtendedFloat(0);
434}
435
436template<typename T, int Rows, int Cols>
437auto zero (const Dimension<Eigen::Matrix<T, Rows, Cols>>& dim)
438-> decltype (Eigen::Matrix<T, Rows, Cols>::Zero (dim.rows, dim.cols))
439{
440 return Eigen::Matrix<T, Rows, Cols>::Zero (dim.rows, dim.cols);
441}
442
443template< int R, int C, template< int R2 = R, int C2 = C> class MatType >
445-> decltype (ExtendedFloatEigen<R, C, MatType>::Zero (dim.rows, dim.cols))
446{
447 return ExtendedFloatEigen<R, C, MatType>::Zero (dim.rows, dim.cols);
448}
449
450template<typename T = void>
452{
453 return TransitionFunction([dim](const VectorLik& x){
454 return VectorLik::Zero(dim.cols);
455 });
456}
457
458
459// Create a one value of the given dimension
460template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
462{
463 return T (1);
464}
465
466template<typename T = void>
467char one (const Dimension<char>&)
468{
469 return '1';
470}
471
472template<typename T = void>
473std::string one (const Dimension<std::string>&)
474{
475 return "one";
476}
477
478template<typename T = void>
480{
481 return *std::make_shared<Parameter>("One", 1);
482}
483
484template<typename T = void>
486{
487 return ExtendedFloat(1);
488}
489
490template<typename T, int Rows, int Cols>
491auto one (const Dimension<Eigen::Matrix<T, Rows, Cols>>& dim)
492-> decltype (Eigen::Matrix<T, Rows, Cols>::Ones (dim.rows, dim.cols))
493{
494 return Eigen::Matrix<T, Rows, Cols>::Ones (dim.rows, dim.cols);
495}
496
497template< int R, int C, template< int R2 = 2, int C2 = C> class MatType>
499-> decltype (ExtendedFloatEigen<R, C, MatType>::Ones (dim.rows, dim.cols))
500{
501 return ExtendedFloatEigen<R, C, MatType>::Ones (dim.rows, dim.cols);
502}
503
504template<typename T = void>
506{
507 return TransitionFunction([dim](const VectorLik& x){
508 return VectorLik::Ones(dim.cols);
509 });
510}
511
512// Create an identity value of the given dimension (fails if not a square matrix)
513template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
515{
516 return T (1); // Equivalent to matrix of size 1x1
517}
518
519template<typename T, typename = typename std::enable_if<std::is_same<T, ExtendedFloat>::value>::type>
521{
522 return T (1); // Equivalent to matrix of size 1x1
523}
524
525template<typename T, int Rows, int Cols>
526auto identity (const Dimension<Eigen::Matrix<T, Rows, Cols>>& dim)
527-> decltype (Eigen::Matrix<T, Rows, Cols>::Identity (dim.rows, dim.cols))
528{
530 return Eigen::Matrix<T, Rows, Cols>::Identity (dim.rows, dim.cols);
531}
532
533template< int R, int C, template< int R2 = R, int C2 = C> class MatType>
535-> decltype (ExtendedFloatEigen<R, C, MatType>::Identity (dim.rows))
536{
539}
540
541
542// Check if value is Infinity
543inline bool isinf(const double& d)
544{
545 return std::isinf(d);
546}
547
548inline bool isinf(const ExtendedFloat& d)
549{
550 return std::isinf(d.float_part()) || std::isinf(d.exponent_part());
551}
552
553// Check if value is identity itself
554template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value || std::is_same<T, ExtendedFloat>::value>::type>
555bool isIdentity (const T& t)
556{
557 return t == T (1);
558}
559
560template<typename T = void>
561bool isIdentity (const std::string& t)
562{
563 return t == "Id";
564}
565
566template<typename Derived>
567bool isIdentity (const Eigen::MatrixBase<Derived>& m)
568{
569 auto dim = Dimension<Derived>(m.derived ());
570 return dim.rows == dim.cols && m == identity (dim);
571}
572
573template< int R, int C, template< int R2 = R, int C2 = C> class MatType>
575{
576 return isIdentity(efm.float_part()) && efm.exponent_part() == 0;
577}
578
579
580/********************************************************/
581/*** CONVERSI0N ***/
582
583/* Convert from F to R (with specific dimension).
584 * scalar -> scalar: simple cast.
585 * scalar -> matrix: fill the matrix with scalar value.
586 * matrix -> matrix: copy values, size must match (conversion between eigen dynamic/fixed)
587 *
588 * Two APIs:
589 * r = convert(f, dim); -> convert returns a "converted" result
590 * convert (r, f, dim); -> convert does the assignment directly
591 */
592
593/*************************/
594/*** From arithmetic ***/
595
596template<typename R, typename F, typename = typename std::enable_if<std::is_arithmetic<R>::value || std::is_same<R, ExtendedFloat>::value>::type>
597R convert (const F& from, const Dimension<R>&)
598{
599 return R (from); // scalar -> scalar
600}
601
602template<typename T, int Rows, int Cols, typename F,
603 typename = typename std::enable_if<std::is_arithmetic<F>::value>::type>
604auto convert (const F& from, const Dimension<Eigen::Matrix<T, Rows, Cols>>& dim)
605-> decltype (Eigen::Matrix<T, Rows, Cols>::Constant (dim.rows, dim.cols, from))
606{
607 // scalar -> matrix
608 return Eigen::Matrix<T, Rows, Cols>::Constant (dim.rows, dim.cols, from);
609}
610
611template< int R, int C, template< int R2 = R, int C2 = C> class MatType, typename F,
612 typename = typename std::enable_if<std::is_same<F, ExtendedFloat>::value || std::is_arithmetic<F>::value>::type>
613auto convert (const F& from, const Dimension<ExtendedFloatEigen<R, C, MatType>>& dim)
614-> decltype (ExtendedFloatEigen<R, C, MatType>::Constant (dim.rows, dim.cols, from))
615{
616 // scalar -> efmatrix
617 return ExtendedFloatEigen<R, C, MatType>::Constant (dim.rows, dim.cols, from);
618}
619
621{
622 return ConstantTransitionFunction(from, (int)dim.cols);
623}
624
625/**************************************/
627/**************************************/
628
629template<typename T, int R, int C, typename DerivedF>
630const Eigen::Matrix<T, R, C> convert (const Eigen::MatrixBase<DerivedF>& from,
631 const Dimension<Eigen::Matrix<T, R, C>>& dim,
632 typename std::enable_if<std::is_same<DerivedF, Eigen::RowVectorXi>::value || std::is_same<DerivedF, Eigen::VectorXi>::value>::type* = 0)
633{
634 return from.derived().template cast<T>(); // matrixXi -> matrix
635}
636
637
638template< int R, int C, typename DerivedF>
639const ExtendedFloatMatrix<R, C> convert (const Eigen::MatrixBase<DerivedF>& from,
641 typename std::enable_if<std::is_same<DerivedF, Eigen::RowVectorXi>::value || std::is_same<DerivedF, Eigen::VectorXi>::value>::type* = 0)
642
643{
644 return ExtendedFloatMatrix<R, C>(from.derived().template cast<double>(), 0); // matrixXi -> efmatrix
645}
646
647
648/**************************************/
650/**************************************/
651
652template<typename T, int Rows, int Cols, typename DerivedF>
653const DerivedF& convert (const Eigen::MatrixBase<DerivedF>& from,
654 const Dimension<Eigen::Matrix<T, Rows, Cols>>& dim,
655 typename std::enable_if<!(std::is_same<DerivedF, Eigen::RowVectorXi>::value || std::is_same<DerivedF, Eigen::VectorXi>::value)>::type* = 0)
656{
657 return from.derived (); // matrix -> matrix, conversion will be done in the assignment
658}
659
660template< int R, int C, typename DerivedF>
661const ExtendedFloatMatrix<R, C> convert (const Eigen::MatrixBase<DerivedF>& from,
663 typename std::enable_if<!(std::is_same<DerivedF, Eigen::RowVectorXi>::value || std::is_same<DerivedF, Eigen::VectorXi>::value)>::type* = 0)
664{
665 return ExtendedFloatMatrix<R, C>(from.derived (), 0); // matrix -> matrix, conversion will be done in the assignment
666}
667
668/**************************************/
670/**************************************/
671
672template< int R, int C, typename DerivedF>
673const DerivedF& convert (const ExtendedFloatEigenBase<DerivedF>& from,
675{
676 return from.derived(); // efmatrix -> efmatrix
677}
678
679template< int R, int C>
680const Eigen::Matrix<double, R, C> convert (const ExtendedFloatMatrix<R, C>& from,
681 const Dimension<Eigen::Matrix<double, R, C>>& dim)
682{
683 return from.float_part() * constexpr_power<double>(ExtendedFloat::radix, from.exponent_part()); // efmatrix -> matrix
684}
685
686
687/***********************/
690template<typename R, typename F>
691void convert (R& r, const F& from, const Dimension<R>& dim)
692{
693 r = convert (from, dim);
694}
695
696template<typename R>
697void convert (R& r, const R& from, const Dimension<R>& dim)
698{
699 r = R(from);
700}
701
702// template<typename R, typename F>
703// typename std::enable_if<!((std::is_base_of<R, Eigen::MatrixXd>::value) && (std::is_base_of<F, ExtendedFloatMatrixXd>::value)), const R>::type
704// convert (const F& from, const Dimension<R>& dim)
705// {
706// const R result = convert (from, dim);
707// return result;
708// }
709
710/*******************************************/
711/*** Simple operators ***/
712
713
714// 1/x
715template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
716T inverse (T t)
717{
718 return T (1) / t;
719}
720
722{
723 return ExtendedFloat{1 / t.float_part(), -t.exponent_part()};
724}
725
726using Eigen::inverse;
727
728template<typename Derived>
730{
731 return Derived(base.derived().float_part().inverse(), -base.derived().exponent_part());
732}
733
734// x^y
735using Eigen::pow;
736using std::pow;
737
738// log
739template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
740T log (T t)
741{
742 return T(std::log(t));
743}
744
745// exp
746template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
747T exp (T t)
748{
749 return T(std::exp(t));
750}
751
752// template <typename Derived>
753// Derived exp (const Eigen::DenseBase<Derived>& T) {
754// return T.derived().exp();
755// }
756using Eigen::exp;
757
758/*******************************************/
759/*** Debug/Output ***/
760/*******************************************/
761
762// Numerical information as text
763template<typename T>
764std::string debug (const T& t, typename std::enable_if<std::is_arithmetic<T>::value>::type* = 0)
765{
766 // For basic arithmetic scalar types, just print the value itself
767 using std::to_string;
768 return "value=" + to_string_with_precision<T>(t, 20);
769}
770
771template<typename T>
772std::string debug (const Parameter& t)
773{
774 // For basic arithmetic scalar types, just print the value itself
775 using std::to_string;
776 return "value=" + to_string_with_precision<double>(t.getValue(), 20);
777}
778
779template<typename T = std::string>
780std::string debug (const std::string& t)
781{
782 // For basic arithmetic scalar types, just print the value itself
783 return "value=" + t;
784}
785
786template<typename T = ExtendedFloat>
787std::string debug (const ExtendedFloat& t)
788{
789 // For basic arithmetic scalar types, just print the value itself
790 return "value=" + to_string(t);
791}
792
793template<typename Derived>
794std::string debug (const Eigen::MatrixBase<Derived>& m) // , typename std::enable_if<!std::is_same<Derived, Parameter const&>::value>::type* = 0) {
795// With matrices, check some numeric properties and encode results as text
796{
797 using std::to_string;
798 const auto dim = Dimension<Derived>(m.derived ());
799 std::string props = "dim=" + to_string (dim) + " props={";
800 const auto zero_value = zero (dim);
801 // Properties on all elements
802 if (m == zero_value)
803 props += "[0]";
804 if (m == one (dim))
805 props += "[1]";
806 if (isIdentity (m))
807 props += "[I]";
808 // Properties on any element
809 if (m.array ().isNaN ().any ())
810 props += "N";
811 if (m.array ().isInf ().any ())
812 props += "i";
813 if ((m.array () == zero_value.array ()).any ())
814 props += "0";
815 if ((m.array () > zero_value.array ()).any ())
816 props += "+";
817 if ((m.array () < zero_value.array ()).any ())
818 props += "-";
819 props += "}";
820 return props;
821}
822
823template<typename Derived>
825{
826 // For basic arithmetic scalar types, just print the value itself
827 using std::to_string;
828 return debug(m.derived().float_part()) + " 2^ " + debug(m.derived().exponent_part());
829}
830
831template<typename T = TransitionFunction>
832std::string debug (const TransitionFunction& f) // , typename std::enable_if<!std::is_same<Derived, Parameter const&>::value>::type* = 0) {
833// With matrices, check some numeric properties and encode results as text
834{
835 return "TransitionFunction";
836}
837
838/**************************************************/
839/* HASH */
840
841// Hash of numerical value
842template<typename T>
843std::size_t hash (T t, typename std::enable_if<std::is_floating_point<T>::value || std::is_integral<T>::value>::type* = 0)
844{
845 return std::hash<T>{}(t);
846}
847
848inline std::size_t hash (const ExtendedFloat& ef)
849{
850 std::size_t seed = hash(ef.float_part());
851 combineHash(seed, ef.exponent_part());
852 return seed;
853}
854
855template<typename T = std::string>
856std::size_t hash (const std::string& t)
857{
858 return std::hash<std::string>{}(t);
859}
860
861template<typename Derived> std::size_t hash (const Eigen::MatrixBase<Derived>& m)
862{
863 std::size_t seed = 0;
864 for (Eigen::Index j = 0; j < m.cols (); ++j)
865 {
866 for (Eigen::Index i = 0; i < m.rows (); ++i)
867 {
868 combineHash (seed, m (i, j));
869 }
870 }
871 return seed;
872}
873
874template<typename Derived>
875std::size_t hash (const ExtendedFloatEigenBase<Derived>& efm)
876{
877 std::size_t seed = hash(efm.derived().float_part());
878 combineHash(seed, efm.derived().exponent_part());
879 return seed;
880}
881} // namespace numeric
882
883
884/******************************************************************************
885 * Data flow nodes for those numerical functions.
886 *
887 * TODO numerical simplification:
888 * add(x,x) -> 2*x ? (and similar for mul, ...)
889 * all deps constant => return constant ?
890 */
891
892// Error utils
893[[noreturn]] void failureDeltaNotDerivable (const std::type_info& contextNodeType);
894[[noreturn]] void failureNumericalDerivationNotConfigured ();
895void checkRecreateWithoutDependencies (const std::type_info& contextNodeType, const NodeRefVec& deps);
896
897// Type tag to indicate a reduction operation (for +,*,...).
898template<typename T> struct ReductionOf;
899
900// Declaration of all defined nodes, in order of implementation.
901template<typename T> class ConstantZero;
902template<typename T> class ConstantOne;
903template<typename T> class NumericConstant;
904template<typename T> class NumericMutable;
905template<typename Result, typename From> class Convert;
906
907// Utilities
908template<typename Predicate> void removeDependenciesIf (NodeRefVec& deps, Predicate p)
909{
910 auto new_end = std::remove_if (deps.begin (), deps.end (), std::move (p));
911 deps.erase (new_end, deps.end ()); // Truncate vector storage
912}
913
942template<typename T> struct NumericalDependencyTransform
943{
945 using DepType = T;
947 static const DepType& transform (const DepType& d) { return d; }
948};
949
951template<typename T> struct Transposed;
953template<typename T> struct NumericalDependencyTransform<Transposed<T>>
954{
955 // Get DepType by recursion
957
958 // Perform inner transformation for T, then transpose. Only for Eigen types.
959 static auto transform (const DepType& d)
960 -> decltype (NumericalDependencyTransform<T>::transform (d).transpose ())
961 {
962 return NumericalDependencyTransform<T>::transform (d).transpose ();
963 }
964};
965
972template<typename T> class ConstantZero : public Value<T>
973{
974public:
976
978 static std::shared_ptr<Self> create (Context& c, const Dimension<T>& dim)
979 {
980 return cachedAs<Self>(c, std::make_shared<Self>(dim));
981 }
982
983 explicit ConstantZero (const Dimension<T>& dim) : Value<T>(NodeRefVec{}), targetDimension_ (dim)
984 {}
985
986 std::string debugInfo () const override { return "targetDim=" + to_string (targetDimension_); }
987
989 {
990 switch (prop)
991 {
993 return true;
995 return true;
996 default:
997 return false;
998 }
999 }
1000
1001 // ConstantZero<T> additional arguments = (targetDimension_).
1002 bool compareAdditionalArguments (const Node_DF& other) const final
1003 {
1004 const auto* derived = dynamic_cast<const Self*>(&other);
1005 return derived != nullptr && targetDimension_ == derived->targetDimension_;
1006 }
1007 std::size_t hashAdditionalArguments () const final { return hash (targetDimension_); }
1008
1009 NodeRef derive (Context& c, const Node_DF& node) final
1010 {
1011 if (&node == this)
1012 {
1014 }
1015 return this->shared_from_this (); // Return handle to self, as d(0)/dx = 0
1016 }
1017
1019 {
1020 checkRecreateWithoutDependencies (typeid (Self), deps);
1021 return this->shared_from_this ();
1022 }
1023
1024private:
1025 void compute () final
1026 {
1027 using namespace numeric;
1029 }
1030
1032};
1033
1040template<typename T> class ConstantOne : public Value<T>
1041{
1042public:
1044
1046 static std::shared_ptr<Self> create (Context& c, const Dimension<T>& dim)
1047 {
1048 return cachedAs<Self>(c, std::make_shared<Self>(dim));
1049 }
1050
1051 explicit ConstantOne (const Dimension<T>& dim) : Value<T>(NodeRefVec{}), targetDimension_ (dim) {}
1052
1053 std::string debugInfo () const override { return "targetDim=" + to_string (targetDimension_); }
1054
1056 {
1057 switch (prop)
1058 {
1060 return true;
1062 return true;
1063 default:
1064 return false;
1065 }
1066 }
1067
1068 // ConstantOne<T> additional arguments = (targetDimension_).
1069 bool compareAdditionalArguments (const Node_DF& other) const final
1070 {
1071 const auto* derived = dynamic_cast<const Self*>(&other);
1072 return derived != nullptr && targetDimension_ == derived->targetDimension_;
1073 }
1074 std::size_t hashAdditionalArguments () const final { return hash (targetDimension_); }
1075
1076 NodeRef derive (Context& c, const Node_DF& node) final
1077 {
1078 if (&node == this)
1079 {
1081 }
1083 }
1084
1086 {
1087 checkRecreateWithoutDependencies (typeid (Self), deps);
1088 return this->shared_from_this ();
1089 }
1090
1091private:
1092 void compute () final
1093 {
1094 using namespace numeric;
1096 }
1097
1099};
1100
1108template<typename T> class NumericConstant : public Value<T>
1109{
1110public:
1112
1114 template<typename ... Args> static std::shared_ptr<Self> create (Context& c, Args&&... args)
1115 {
1116 return cachedAs<Self>(c, std::make_shared<Self>(std::forward<Args>(args)...));
1117 }
1118
1119 template<typename ... Args>
1120 explicit NumericConstant (Args&&... args) : Value<T>(NodeRefVec{}, std::forward<Args>(args)...)
1121 {
1122 this->makeValid (); // Always valid
1123 }
1124
1125 std::string debugInfo () const override
1126 {
1127 using namespace numeric;
1128 return debug (this->accessValueConst ());
1129 }
1130
1131 std::string description() const override
1132 {
1133 using namespace numeric;
1134 return Node_DF::description() + "\n" + debug (this->accessValueConst ());
1135 }
1136
1137 std::string color () const override
1138 {
1139 return "grey";
1140 }
1141
1143 {
1144 using namespace numeric;
1145 const auto& value = this->accessValueConst ();
1146 switch (prop)
1147 {
1149 return true;
1151 return value == zero (Dimension<T>(value));
1153 return value == one (Dimension<T>(value));
1155 return isIdentity (value);
1156 default:
1157 return false;
1158 }
1159 }
1160
1161 // NumericConstant<T> additional arguments = (value).
1162 bool compareAdditionalArguments (const Node_DF& other) const override
1163 {
1164 const auto* derived = dynamic_cast<const Self*>(&other);
1165 return derived != nullptr && this->accessValueConst () == derived->accessValueConst ();
1166 }
1167
1168 std::size_t hashAdditionalArguments () const override
1169 {
1170 using namespace numeric;
1171 return hash (this->accessValueConst ());
1172 }
1173
1174 NodeRef derive (Context& c, const Node_DF& node) final
1175 {
1176 const auto dim = Dimension<T>(this->accessValueConst ());
1177 if (&node == this)
1178 {
1179 return ConstantOne<T>::create (c, dim);
1180 }
1181 return ConstantZero<T>::create (c, dim);
1182 }
1183
1185 {
1186 checkRecreateWithoutDependencies (typeid (Self), deps);
1187 return this->shared_from_this ();
1188 }
1189
1190private:
1191 void compute () final
1192 {
1193 // Constant is valid from construction
1194 failureComputeWasCalled (typeid (*this));
1195 }
1196};
1197
1206template<typename T> class NumericMutable : public Value<T>
1207{
1208public:
1210
1212 template<typename ... Args> static std::shared_ptr<Self> create (Context&, Args&&... args)
1213 {
1214 return std::make_shared<Self>(std::forward<Args>(args)...);
1215 }
1216
1217 template<typename ... Args>
1218 explicit NumericMutable (Args&&... args) : Value<T>(NodeRefVec{}, std::forward<Args>(args)...)
1219 {
1220 this->makeValid (); // Initial value is valid
1221 }
1222
1224 void setValue (const T& t)
1225 {
1226 this->modify ([&t](T& v) { v = t; }, true);
1227 }
1228
1230 void setValue (T&& t)
1231 {
1232 this->modify ([&t](T& v) { v = std::move (t); }, true);
1233 }
1234
1235 std::string debugInfo () const override
1236 {
1237 using namespace numeric;
1238 return debug (this->accessValueConst ());
1239 }
1240
1241 std::string description() const override
1242 {
1243 using namespace numeric;
1244 return Node_DF::description() + "\n" + debug (this->accessValueConst ());
1245 }
1246
1247 NodeRef derive (Context& c, const Node_DF& node) final
1248 {
1249 const auto dim = Dimension<T>(this->accessValueConst ());
1250 if (&node == this)
1251 {
1252 return ConstantOne<T>::create (c, dim);
1253 }
1254 return ConstantZero<T>::create (c, dim);
1255 }
1256
1258 {
1259 checkRecreateWithoutDependencies (typeid (Self), deps);
1260 return this->shared_from_this ();
1261 }
1262
1263private:
1264 void compute () final
1265 {
1266 // Mutable is always valid
1267 failureComputeWasCalled (typeid (*this));
1268 }
1269};
1270
1278template<typename R, typename F> class Convert : public Value<R>
1279{
1280public:
1281 using Self = Convert;
1283
1285 static ValueRef<R> create (Context& c, NodeRefVec&& deps, const Dimension<R>& dim)
1286 {
1287 // Check dependencies
1288 checkDependenciesNotNull (typeid (Self), deps);
1289 checkDependencyVectorSize (typeid (Self), deps, 1);
1290 checkNthDependencyIsValue<DepF>(typeid (Self), deps, 0);
1291 // Select node
1292 if (std::is_same<R, F>::value)
1293 {
1294 return convertRef<Value<R>>(deps[0]);
1295 }
1297 {
1298 return ConstantZero<R>::create (c, dim);
1299 }
1301 {
1302 return ConstantOne<R>::create (c, dim);
1303 }
1304 else
1305 {
1306 return cachedAs<Value<R>>(c, std::make_shared<Self>(std::move (deps), dim));
1307 }
1308 }
1309
1310 Convert (NodeRefVec&& deps, const Dimension<R>& dim)
1311 : Value<R>(std::move (deps)), targetDimension_ (dim) {}
1312
1313 std::string debugInfo () const override
1314 {
1315 using namespace numeric;
1316 return debug (this->accessValueConst ()) + " targetDim=" + to_string (targetDimension_);
1317 }
1318
1319 // Convert<T> additional arguments = ().
1320 bool compareAdditionalArguments (const Node_DF& other) const final
1321 {
1322 return dynamic_cast<const Self*>(&other) != nullptr;
1323 }
1324
1325 NodeRef derive (Context& c, const Node_DF& node) final
1326 {
1327 if (&node == this)
1328 {
1330 }
1331 return Self::create (c, {this->dependency (0)->derive (c, node)}, targetDimension_);
1332 }
1333
1335 {
1336 return Self::create (c, std::move (deps), targetDimension_);
1337 }
1338
1339private:
1340 void compute () final
1341 {
1342 using namespace numeric;
1343 auto& result = this->accessValueMutable ();
1344 const auto& arg = accessValueConstCast<DepF>(*this->dependency (0));
1346 }
1347
1349};
1350
1360template<typename R> class Identity : public Value<R>
1361{
1362public:
1364
1366 static ValueRef<R> create (Context& c, NodeRefVec&& deps, const Dimension<R>& dim, size_t id = 0)
1367 {
1368 // Check dependencies
1369 checkDependenciesNotNull (typeid (Self), deps);
1370 checkDependencyVectorSize (typeid (Self), deps, 1);
1371 checkNthDependencyIsValue<R>(typeid (Self), deps, 0);
1372
1373 return cachedAs<Value<R>>(c, std::make_shared<Self>(std::move (deps), dim, id));
1374 }
1375
1376 Identity (NodeRefVec&& deps, const Dimension<R>& dim, size_t id)
1377 : Value<R>(std::move (deps)), targetDimension_ (dim), id_(id) {}
1378
1379 std::string debugInfo () const override
1380 {
1381 using namespace numeric;
1382 return debug (this->accessValueConst ()) + " id_=" + std::to_string (id_) + " targetDim=" + to_string (targetDimension_);
1383 }
1384
1385 // Convert<T> additional arguments = ().
1386 bool compareAdditionalArguments (const Node_DF& other) const final
1387 {
1388 auto oself = dynamic_cast<const Self*>(&other);
1389 if (oself == nullptr)
1390 return false;
1391
1392 return id_ == oself->id_;
1393 }
1394
1395 NodeRef derive (Context& c, const Node_DF& node) final
1396 {
1397 if (&node == this)
1398 {
1400 }
1401 return Self::create (c, {this->dependency (0)->derive (c, node)}, targetDimension_, id_);
1402 }
1403
1405 {
1406 return Self::create (c, std::move (deps), targetDimension_, id_);
1407 }
1408
1409private:
1410 void compute () final
1411 {
1412 using namespace numeric;
1413 auto& result = this->accessValueMutable ();
1414 result = accessValueConstCast<R>(*this->dependency (0));
1415 }
1416
1418
1419 size_t id_;
1420};
1421
1422// Precompiled instantiations
1423extern template class ConstantZero<uint>;
1424extern template class ConstantZero<double>;
1425extern template class ConstantZero<char>;
1426extern template class ConstantZero<std::string>;
1427
1428extern template class ConstantZero<Parameter>;
1429extern template class ConstantZero<TransitionFunction>;
1430
1431extern template class ConstantZero<Eigen::VectorXd>;
1432extern template class ConstantZero<Eigen::RowVectorXd>;
1433extern template class ConstantZero<Eigen::MatrixXd>;
1434
1435extern template class ConstantZero<ExtendedFloatVectorXd>;
1436extern template class ConstantZero<ExtendedFloatRowVectorXd>;
1437extern template class ConstantZero<ExtendedFloatMatrixXd>;
1438
1439
1440extern template class ConstantOne<uint>;
1441extern template class ConstantOne<double>;
1442extern template class ConstantOne<char>;
1443extern template class ConstantOne<std::string>;
1444
1445extern template class ConstantOne<Parameter>;
1446extern template class ConstantOne<TransitionFunction>;
1447
1448extern template class ConstantOne<Eigen::VectorXd>;
1449extern template class ConstantOne<Eigen::RowVectorXd>;
1450extern template class ConstantOne<Eigen::MatrixXd>;
1451
1452extern template class ConstantOne<ExtendedFloatVectorXd>;
1453extern template class ConstantOne<ExtendedFloatRowVectorXd>;
1454extern template class ConstantOne<ExtendedFloatMatrixXd>;
1455
1456
1457extern template class Identity<double>;
1458extern template class Identity<ExtendedFloatMatrixXd>;
1459extern template class Identity<Eigen::MatrixXd>;
1460
1461
1462extern template class NumericConstant<uint>;
1463extern template class NumericConstant<double>;
1464extern template class NumericConstant<size_t>;
1465extern template class NumericConstant<std::string>;
1466
1467extern template class NumericConstant<ExtendedFloatVectorXd>;
1468extern template class NumericConstant<ExtendedFloatRowVectorXd>;
1469extern template class NumericConstant<ExtendedFloatMatrixXd>;
1470
1471extern template class NumericConstant<Eigen::VectorXd>;
1472extern template class NumericConstant<Eigen::RowVectorXd>;
1473extern template class NumericConstant<Eigen::MatrixXd>;
1474
1476
1477extern template class NumericMutable<uint>;
1478extern template class NumericMutable<double>;
1479
1480extern template class NumericMutable<ExtendedFloatVectorXd>;
1481extern template class NumericMutable<ExtendedFloatRowVectorXd>;
1482extern template class NumericMutable<ExtendedFloatMatrixXd>;
1483
1484extern template class NumericMutable<Eigen::VectorXd>;
1485extern template class NumericMutable<Eigen::RowVectorXd>;
1486extern template class NumericMutable<Eigen::MatrixXd>;
1487
1488extern template class Convert<double, double>;
1489
1490extern template class Convert<ExtendedFloatVectorXd, double>;
1496
1497extern template class Convert<ExtendedFloatRowVectorXd, double>;
1503
1504extern template class Convert<ExtendedFloatMatrixXd, double>;
1509
1510extern template class Convert<Eigen::VectorXd, double>;
1511extern template class Convert<Eigen::VectorXd, Eigen::VectorXd>;
1512extern template class Convert<Eigen::VectorXd, Eigen::VectorXi>;
1514
1515extern template class Convert<Eigen::RowVectorXd, double>;
1519
1520extern template class Convert<Eigen::MatrixXd, double>;
1521extern template class Convert<Eigen::MatrixXd, Eigen::MatrixXd>;
1523} // namespace bpp
1524#endif // BPP_PHYL_LIKELIHOOD_DATAFLOW_DATAFLOWNUMERIC_H
r = 1 for each component.
ConstantOne(const Dimension< T > &dim)
Dimension< T > targetDimension_
bool hasNumericalProperty(NumericalProperty prop) const final
Test if the node has the given numerical property.
std::size_t hashAdditionalArguments() const final
Return the hash of node-specific configuration.
NodeRef recreate(Context &, NodeRefVec &&deps) final
Recreate the node with different dependencies.
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.
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
static std::shared_ptr< Self > create(Context &c, const Dimension< T > &dim)
Build a new ConstantOne node of the given dimension.
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
const VectorLik & operator()(const VectorLik &)
ConstantTransitionFunction(const VectorLik &res)
ConstantTransitionFunction(double val, int row)
r = 0 for each component.
std::size_t hashAdditionalArguments() const final
Return the hash of node-specific configuration.
static std::shared_ptr< Self > create(Context &c, const Dimension< T > &dim)
Build a new ConstantZero node of the given dimension.
NodeRef derive(Context &c, const Node_DF &node) final
Returns a node computing d(this_node_expression)/d(node_expression).
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
bool hasNumericalProperty(NumericalProperty prop) const final
Test if the node has the given numerical property.
NodeRef recreate(Context &, NodeRefVec &&deps) final
Recreate the node with different dependencies.
void compute() final
Computation implementation.
Dimension< T > targetDimension_
ConstantZero(const Dimension< T > &dim)
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
Context for dataflow node construction.
Definition: DataFlow.h:527
r = convert(f).
typename NumericalDependencyTransform< F >::DepType DepF
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).
NodeRef recreate(Context &c, NodeRefVec &&deps) final
Recreate the node with different dependencies.
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new Convert node with the given output dimensions.
Dimension< R > targetDimension_
Convert(NodeRefVec &&deps, const Dimension< R > &dim)
void compute() final
Computation implementation.
static Self Constant(Eigen::Index rows, Eigen::Index cols, double value)
static Self Zero(Eigen::Index rows, Eigen::Index cols)
virtual const MatType & float_part() const
Eigen::Index cols() const
Eigen::Index rows() const
virtual const ExtType & exponent_part() const
static Self Identity(Eigen::Index rows)
static Self Ones(Eigen::Index rows, Eigen::Index cols)
const ExtType & exponent_part() const noexcept
Definition: ExtendedFloat.h:89
const FloatType & float_part() const noexcept
Definition: ExtendedFloat.h:88
static constexpr int radix
Definition: ExtendedFloat.h:49
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim, size_t id=0)
Build a new Convert node with the given output dimensions.
NodeRef recreate(Context &c, NodeRefVec &&deps) final
Recreate the node with different dependencies.
NodeRef derive(Context &c, const Node_DF &node) final
Returns a node computing d(this_node_expression)/d(node_expression).
Identity(NodeRefVec &&deps, const Dimension< R > &dim, size_t id)
Dimension< R > targetDimension_
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
void compute() final
Computation implementation.
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
Base dataflow Node class.
Definition: DataFlow.h:152
virtual std::string description() const
Node pretty name (default = type name).
Definition: DataFlow.cpp:151
const NodeRef & dependency(std::size_t i) const noexcept
Definition: DataFlow.h:185
virtual bool hasNumericalProperty(NumericalProperty prop) const
Test if the node has the given numerical property.
Definition: DataFlow.cpp:168
void makeValid() noexcept
Definition: DataFlow.h:271
r = constant_value.
bool compareAdditionalArguments(const Node_DF &other) const override
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).
NodeRef recreate(Context &, NodeRefVec &&deps) override
Recreate the node with different dependencies.
bool hasNumericalProperty(NumericalProperty prop) const final
Test if the node has the given numerical property.
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
static std::shared_ptr< Self > create(Context &c, Args &&... args)
Build a new NumericConstant node with T(args...) value.
std::size_t hashAdditionalArguments() const override
Return the hash of node-specific configuration.
std::string color() const override
void compute() final
Computation implementation.
NumericConstant(Args &&... args)
std::string description() const override
Node pretty name (default = type name).
r = variable_value.
NodeRef recreate(Context &, NodeRefVec &&deps) final
Recreate the node with different dependencies.
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
static std::shared_ptr< Self > create(Context &, Args &&... args)
Build a new NumericMutable node with T(args...) value.
void setValue(T &&t)
Setter with invalidation (movable value version).
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.
std::string description() const override
Node pretty name (default = type name).
NumericMutable(Args &&... args)
void setValue(const T &t)
Setter with invalidation.
virtual double getValue() const
Abstract Node storing a value of type T.
Definition: DataFlow.h:352
void modify(Callable &&modifier, bool makeValid)
General case for modification of the T object.
Definition: DataFlow.h:405
T & accessValueMutable() noexcept
Definition: DataFlow.h:416
const T & accessValueConst() const noexcept
Raw value access (const).
Definition: DataFlow.h:385
bool isinf(const ExtendedFloat &d)
T identity(const Dimension< T > &)
std::size_t hash(T t, typename std::enable_if< std::is_floating_point< T >::value||std::is_integral< T >::value >::type *=0)
bool isinf(const double &d)
T one(const Dimension< T > &)
TransitionFunction one(const Dimension< TransitionFunction > &dim)
std::string debug(const TransitionFunction &f)
bool isIdentity(const T &t)
TransitionFunction zero(const Dimension< TransitionFunction > &dim)
bool isIdentity(const ExtendedFloatEigen< R, C, MatType > &efm)
void checkDimensionIsSquare(const MatrixDimension &dim)
std::string debug(const T &t, typename std::enable_if< std::is_arithmetic< T >::value >::type *=0)
R convert(const F &from, const Dimension< R > &)
T zero(const Dimension< T > &)
Derived inverse(ExtendedFloatEigenBase< Derived > base)
Defines the basic types of data flow nodes.
void removeDependenciesIf(NodeRefVec &deps, Predicate p)
std::size_t hash(const MatrixDimension &dim)
std::vector< double > Vdouble
NumericConstant< char > NodeX('X')
std::shared_ptr< Value< T > > ValueRef
Shared pointer alias for Value<T>.
Definition: DataFlow.h:84
void checkDependenciesNotNull(const std::type_info &contextNodeType, const NodeRefVec &deps)
Checks that all dependencies are not null, throws if not.
Definition: DataFlow.cpp:103
bool operator!=(const NoDimension &, const NoDimension &)
typename std::enable_if<(std::is_same< eVector, ExtendedFloatRowVectorXd >::value||std::is_same< eVector, ExtendedFloatVectorXd >::value), bool >::type EFoutput
bool operator==(const Matrix< Scalar > &m1, const Matrix< Scalar > &m2)
ExtendedFloatVectorXd VectorLik
Definition: Definitions.h:15
ExtendedFloatRowVectorXd RowLik
Definition: Definitions.h:14
std::string to_string(const NoDimension &)
ExtendedFloatMatrixXd MatrixLik
Definition: Definitions.h:13
ExtendedFloat pow(const ExtendedFloat &ef, double exp)
template void copyEigenToBpp(const ExtendedFloatMatrixXd &eigenMatrix, std::vector< std::vector< double > > &bppMatrix)
void checkRecreateWithoutDependencies(const std::type_info &contextNodeType, const NodeRefVec &deps)
typename std::enable_if<(std::is_same< eVector, ExtendedFloatRowVectorXd >::value||std::is_same< eVector, ExtendedFloatVectorXd >::value), bool >::type EFVector
ExtendedFloatRowVector< Eigen::Dynamic > ExtendedFloatRowVectorXd
void failureDeltaNotDerivable(const std::type_info &contextNodeType)
typename std::enable_if<((std::is_same< bVector, Vdouble >::value||std::is_same< bVector, std::vector< ExtendedFloat > >::value) &&(std::is_same< eVector, Eigen::RowVectorXd >::value||std::is_same< eVector, Eigen::VectorXd >::value)), bool >::type ForConvert
std::vector< NodeRef > NodeRefVec
Alias for a dependency vector (of NodeRef).
Definition: DataFlow.h:81
template void copyBppToEigen(const std::vector< ExtendedFloat > &bppVector, Eigen::RowVectorXd &eigenVector)
NumericalProperty
Numerical properties for DF Node.
Definition: DataFlow.h:88
double convert(const bpp::ExtendedFloat &ef)
void checkDependencyVectorSize(const std::type_info &contextNodeType, const NodeRefVec &deps, std::size_t expectedSize)
Definition: DataFlow.cpp:83
void combineHash(std::size_t &seed, const T &t)
Combine hashable value to a hash, from Boost library.
Definition: DataFlow.h:33
void failureNumericalDerivationNotConfigured()
void failureComputeWasCalled(const std::type_info &nodeType)
Definition: DataFlow.cpp:51
std::shared_ptr< Node_DF > NodeRef
Definition: DataFlow.h:78
std::function< VectorLik(const VectorLik &)> TransitionFunction
ExtendedFloatMatrix< Eigen::Dynamic, Eigen::Dynamic > ExtendedFloatMatrixXd
ExtendedFloatVector< Eigen::Dynamic > ExtendedFloatVectorXd
typename std::enable_if<((std::is_same< bVector, Vdouble >::value||std::is_same< bVector, std::vector< ExtendedFloat > >::value) &&(std::is_same< eVector, Eigen::RowVectorXd >::value||std::is_same< eVector, Eigen::VectorXd >::value||std::is_same< eVector, ExtendedFloatVectorXd >::value||std::is_same< eVector, ExtendedFloatRowVectorXd >::value)), bool >::type ForConvert2
Dimension(const ExtendedFloat &)
Dimension(const Parameter &)
Dimension(const std::string &)
Store a dimension for type T.
Basic matrix dimension type.
MatrixDimension(const ExtendedFloatEigenBase< Derived > &m)
MatrixDimension(Eigen::Index rows_, Eigen::Index cols_)
MatrixDimension(int rows_, int cols_)
MatrixDimension(size_t rows_, size_t cols_)
MatrixDimension()=default
MatrixDimension(const Eigen::MatrixBase< Derived > &m)
Empty type representing no dimensions.
typename NumericalDependencyTransform< T >::DepType DepType
static auto transform(const DepType &d) -> decltype(NumericalDependencyTransform< T >::transform(d).transpose())
Template struct used to describe a dependency transformation before compute().
static const DepType & transform(const DepType &d)
Transform the DepType value: do nothing in the default case.
T DepType
Real type of the dependency: T in the default case.
RowVectorDimension(Eigen::Index cols_)
RowVectorDimension(size_t cols_)
The T dependency should be transposed before computation.
VectorDimension(Eigen::Index rows_)
VectorDimension(size_t rows_)