5#ifndef BPP_PHYL_LIKELIHOOD_DATAFLOW_DATAFLOWCWISE_H
6#define BPP_PHYL_LIKELIHOOD_DATAFLOW_DATAFLOWCWISE_H
28template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
44template<
typename Derived>
auto cwise (
const Eigen::MatrixBase<Derived>& m) ->
decltype (m.array ())
49template<
typename Derived>
auto cwise (Eigen::MatrixBase<Derived>& m) ->
decltype (m.array ())
54inline auto cwise (
const Eigen::RowVectorXi& m) ->
decltype (m.template cast<double>().array ())
56 return m.template cast<double>().array ();
78template<
typename Result,
typename From>
class CWiseFill;
100 checkNthDependencyIsValue<T>(
typeid (
Self), deps, 0);
102 return cachedAs<Value<R>>(c, std::make_shared<Self>(std::move (deps), dim));
113 using namespace numeric;
120 return dynamic_cast<const Self*
>(&other) !=
nullptr;
140 template<
class U = T>
141 typename std::enable_if<std::is_arithmetic<U>::value,
void>::type
144 using namespace numeric;
146 const auto& x0 = accessValueConstCast<T>(*this->
dependency (0));
150 template<
class U = T>
151 typename std::enable_if<std::is_same<U, RowLik>::value>::type
154 using namespace numeric;
156 const auto& x0 = accessValueConstCast<T>(*this->
dependency (0));
157 result.colwise() = x0.transpose();
160 template<
class U = T>
161 typename std::enable_if<std::is_same<U, VectorLik>::value>::type
164 using namespace numeric;
166 const auto& x0 = accessValueConstCast<T>(*this->
dependency (0));
167 result.colwise() = x0;
195 const typename R::Scalar&
operator()(Eigen::Index row, Eigen::Index col)
const
206 template<
typename R2 = R>
209 return m_arg_.exponent_part();
222 checkNthDependencyIsValue<R>(
typeid (
Self), deps, 0);
223 checkNthDependencyIsValue<PatternType>(
typeid(
Self), deps, 1);
226 return convertRef<Value<R>>(deps[0]);
228 return cachedAs<Value<R>>(c, std::make_shared<Self>(std::move (deps), dim));
237 using namespace numeric;
244 return dynamic_cast<const Self*
>(&other) !=
nullptr;
264 const auto& arg = accessValueConstCast<R>(*this->
dependency(0));
265 const auto& pattern = accessValueConstCast<PatternType>(*this->
dependency(1));
294 class matching_functor
301 m_arg_(arg), matching_(matching) {}
303 const typename R::Scalar&
operator()(Eigen::Index row, Eigen::Index col)
const
305 return compute<T>(row, col);
308 template<
typename T2 = T>
309 const typename R::Scalar&
compute(Eigen::Index row, Eigen::Index col,
310 typename std::enable_if< !std::is_same<T2, typename R::Scalar>::value, T*>::type* = 0)
const
312 return (*m_arg_[matching_(col, 0)])(row, Eigen::Index(matching_(col, 1)));
317 template<
typename T2 = T>
318 const typename R::Scalar&
compute(Eigen::Index row, Eigen::Index col,
319 typename std::enable_if< std::is_same<T2, typename R::Scalar>::value, T*>::type* = 0)
const
321 return *m_arg_[matching_(col, 0)];
325 template<
typename R2 = R>
328 std::vector<ExtendedFloat::ExtType> vexp(m_arg_.size());
329 std::transform(m_arg_.begin(), m_arg_.end(), vexp.begin(), [](
const T* t){return t->exponent_part();});
331 if (!std::equal(vexp.begin() + 1, vexp.end(), vexp.begin()) )
332 throw Exception(
"DataFlowCwise::CWiseMatching not possible on ExtendedFloatEigen data with different exponents. Ask developers.");
346 checkDependencyRangeIsValue<T>(
typeid (
Self), deps, 0, deps.size () - 1);
347 checkNthDependencyIsValue<MatchingType>(
typeid(
Self), deps, deps.size() - 1);
351 return cachedAs<Value<R>>(c, std::make_shared<Self>(std::move (deps), dim));
355 :
Value<R>(std::move(deps)), targetDimension_ (dim)
360 using namespace numeric;
361 return debug (this->accessValueConst ()) +
" targetDim=" +
to_string (targetDimension_);
367 return dynamic_cast<const Self*
>(&other) !=
nullptr;
376 const auto n = this->nbDependencies ();
378 for (std::size_t i = 0; i < n - 1; ++i)
380 derivedDeps[i] = this->dependency (i)->derive (c, node);
382 derivedDeps[n - 1] = this->dependency(n - 1);
384 return Self::create (c, std::move (derivedDeps), targetDimension_);
389 return Self::create (c, std::move (deps), targetDimension_);
395 const auto n = this->nbDependencies ();
396 std::vector<const T*> vR(n - 1);
397 for (std::size_t i = 0; i < n - 1; ++i)
399 vR[i] = &accessValueConstCast<T>(*this->dependency(i));
402 const auto& matching = accessValueConstCast<MatchingType>(*this->dependency(n - 1));
404 this->accessValueMutable() = R::NullaryExpr(targetDimension_.rows, targetDimension_.cols, matching_functor(vR, matching));
419 class compound_functor
427 const typename R::Scalar&
operator()(Eigen::Index row, Eigen::Index col)
const
429 return compute<T>(row, col);
432 template<
typename T2 = T>
433 const typename R::Scalar&
compute(Eigen::Index row, Eigen::Index col,
434 typename std::enable_if< std::is_same<T2, RowLik>::value, T*>::type* = 0)
const
436 return (*m_arg_[
size_t(row)])(col);
439 template<
typename T2 = T>
440 const typename R::Scalar&
compute(Eigen::Index row, Eigen::Index col,
441 typename std::enable_if< std::is_same<T2, VectorLik>::value, T*>::type* = 0)
const
443 return (*m_arg_[
size_t(col)])(row);
447 template<
typename R2 = R>
450 std::vector<ExtendedFloat::ExtType> vexp(m_arg_.size());
451 std::transform(m_arg_.begin(), m_arg_.end(), vexp.begin(), [](
const T* t){return t->exponent_part();});
453 if (!std::equal(vexp.begin() + 1, vexp.end(), vexp.begin()) )
454 throw Exception(
"DataFlowCwise::CWiseCompound not possible on ExtendedFloatEigen data with different exponents. Ask developers.");
468 checkDependencyRangeIsValue<T>(
typeid (
Self), deps, 0, deps.size ());
470 return cachedAs<Value<R>>(c, std::make_shared<Self>(std::move (deps), dim));
474 :
Value<R>(std::move(deps)), targetDimension_ (dim)
479 using namespace numeric;
480 return debug (this->accessValueConst ()) +
" targetDim=" +
to_string (targetDimension_);
486 return dynamic_cast<const Self*
>(&other) !=
nullptr;
495 const auto n = this->nbDependencies ();
497 for (std::size_t i = 0; i < n; ++i)
499 derivedDeps[i] = this->dependency (i)->derive (c, node);
502 return Self::create (c, std::move (derivedDeps), targetDimension_);
507 return Self::create (c, std::move (deps), targetDimension_);
513 const auto n = this->nbDependencies ();
514 std::vector<const T*> vR(n);
515 for (std::size_t i = 0; i < n; ++i)
517 vR[i] = &accessValueConstCast<T>(*this->dependency(i));
520 this->accessValueMutable() = R::NullaryExpr(targetDimension_.rows, targetDimension_.cols, compound_functor(vR));
const R::Scalar & compute(Eigen::Index row, Eigen::Index col, typename std::enable_if< std::is_same< T2, VectorLik >::value, T * >::type *=0) const
const R::Scalar & compute(Eigen::Index row, Eigen::Index col, typename std::enable_if< std::is_same< T2, RowLik >::value, T * >::type *=0) const
const std::vector< const T * > & m_arg_
const R::Scalar & operator()(Eigen::Index row, Eigen::Index col) const
compound_functor(const std::vector< const T * > &arg)
ExtendedFloat::ExtType exponent_part(typename std::enable_if< std::is_base_of< ExtendedFloatEigenBase< R2 >, R2 >::value >::type *=0) const
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new CWiseCompound node.
std::string debugInfo() const override
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.
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
Dimension< R > targetDimension_
void compute() override
Computation implementation.
CWiseCompound(NodeRefVec &&deps, const Dimension< R > &dim)
NodeRef derive(Context &c, const Node_DF &node) final
Returns a node computing d(this_node_expression)/d(node_expression).
Dimension< R > targetDimension_
void compute() override
Computation implementation.
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
std::enable_if< std::is_same< U, RowLik >::value >::type compute()
Computation implementation.
std::enable_if< std::is_same< U, VectorLik >::value >::type compute()
Computation implementation.
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new CWiseFill node.
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.
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
CWiseFill(NodeRefVec &&deps, const Dimension< R > &dim)
std::enable_if< std::is_arithmetic< U >::value, void >::type compute()
Computation implementation.
const R::Scalar & compute(Eigen::Index row, Eigen::Index col, typename std::enable_if< !std::is_same< T2, typename R::Scalar >::value, T * >::type *=0) const
matching_functor(const std::vector< const T * > &arg, const MatchingType &matching)
const R::Scalar & operator()(Eigen::Index row, Eigen::Index col) const
const R::Scalar & compute(Eigen::Index row, Eigen::Index col, typename std::enable_if< std::is_same< T2, typename R::Scalar >::value, T * >::type *=0) const
ExtendedFloat::ExtType exponent_part(typename std::enable_if< std::is_base_of< ExtendedFloatEigenBase< R2 >, R2 >::value >::type *=0) const
const MatchingType & matching_
const std::vector< const T * > & m_arg_
NodeRef derive(Context &c, const Node_DF &node) final
Returns a node computing d(this_node_expression)/d(node_expression).
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new CWiseMatching node.
NodeRef recreate(Context &c, NodeRefVec &&deps) final
Recreate the node with different dependencies.
CWiseMatching(NodeRefVec &&deps, const Dimension< R > &dim)
bool compareAdditionalArguments(const Node_DF &other) const final
Compare node-specific configuration to another.
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
void compute() override
Computation implementation.
Dimension< R > targetDimension_
const R::Scalar & operator()(Eigen::Index col) const
const PatternType & pattern_
ExtendedFloat::ExtType exponent_part(typename std::enable_if< std::is_base_of< ExtendedFloatEigenBase< R2 >, R2 >::value >::type *=0) const
const R::Scalar & operator()(Eigen::Index row, Eigen::Index col) const
pattern_functor(const R &arg, const PatternType &pattern)
CWisePattern(NodeRefVec &&deps, const Dimension< R > &dim)
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.
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() override
Computation implementation.
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new CWisePattern node.
Dimension< R > targetDimension_
static std::shared_ptr< Self > create(Context &c, const Dimension< T > &dim)
Build a new ConstantOne node of the given dimension.
Context for dataflow node construction.
virtual const MatType & float_part() const
virtual const ExtType & exponent_part() const
Base dataflow Node class.
const NodeRef & dependency(std::size_t i) const noexcept
virtual bool hasNumericalProperty(NumericalProperty prop) const
Test if the node has the given numerical property.
Abstract Node storing a value of type T.
R & accessValueMutable() noexcept
const R & accessValueConst() const noexcept
Raw value access (const).
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.
std::shared_ptr< Value< T > > ValueRef
Shared pointer alias for Value<T>.
void checkDependenciesNotNull(const std::type_info &contextNodeType, const NodeRefVec &deps)
Checks that all dependencies are not null, throws if not.
std::string to_string(const NoDimension &)
std::vector< NodeRef > NodeRefVec
Alias for a dependency vector (of NodeRef).
double convert(const bpp::ExtendedFloat &ef)
void checkDependencyVectorSize(const std::type_info &contextNodeType, const NodeRefVec &deps, std::size_t expectedSize)
Eigen::Matrix< size_t, -1, 1 > PatternType
Eigen::Matrix< size_t, -1, 2 > MatchingType
std::shared_ptr< Node_DF > NodeRef