5 #ifndef BPP_PHYL_LIKELIHOOD_DATAFLOW_DATAFLOWCWISE_H
6 #define BPP_PHYL_LIKELIHOOD_DATAFLOW_DATAFLOWCWISE_H
18 #include <type_traits>
28 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
44 template<
typename Derived>
auto cwise (
const Eigen::MatrixBase<Derived>& m) -> decltype (m.array ())
49 template<
typename Derived>
auto cwise (Eigen::MatrixBase<Derived>& m) -> decltype (m.array ())
54 inline auto cwise (
const Eigen::RowVectorXi& m) -> decltype (m.template cast<double>().array ())
56 return m.template cast<double>().array ();
59 template<
int R,
int C>
66 template<
int R,
int C>
78 template<
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;
192 m_arg_(arg), pattern_(pattern) {}
195 const typename R::Scalar&
operator()(Eigen::Index row, Eigen::Index col)
const
197 return m_arg_(row, Eigen::Index(pattern_[col]));
202 return m_arg_(Eigen::Index(pattern_[col]));
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));
360 using namespace numeric;
367 return dynamic_cast<const Self*
>(&other) !=
nullptr;
378 for (std::size_t i = 0; i < n - 1; ++i)
380 derivedDeps[i] = this->
dependency (i)->derive (c, node);
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));
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));
479 using namespace numeric;
486 return dynamic_cast<const Self*
>(&other) !=
nullptr;
497 for (std::size_t i = 0; i < n; ++i)
499 derivedDeps[i] = this->
dependency (i)->derive (c, node);
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));
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 std::vector< const T * > & m_arg_
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, RowLik >::value, T * >::type *=0) 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
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.
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new CWiseCompound node.
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).
std::enable_if< std::is_same< U, VectorLik >::value >::type compute()
Computation implementation.
Dimension< R > targetDimension_
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new CWiseFill node.
void compute() override
Computation implementation.
std::enable_if< std::is_same< U, RowLik >::value >::type compute()
Computation implementation.
std::string debugInfo() const override
Node debug info (default = ""): user defined detailed info for DF graph debug.
std::enable_if< std::is_arithmetic< U >::value, void >::type compute()
Computation implementation.
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)
matching_functor(const std::vector< const T * > &arg, const MatchingType &matching)
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 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
const MatchingType & matching_
const std::vector< const T * > & m_arg_
const R::Scalar & operator()(Eigen::Index row, Eigen::Index col) const
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.
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.
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new CWiseMatching node.
void compute() override
Computation implementation.
Dimension< R > targetDimension_
const R::Scalar & operator()(Eigen::Index row, 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
pattern_functor(const R &arg, const PatternType &pattern)
const R::Scalar & operator()(Eigen::Index col) const
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.
static ValueRef< R > create(Context &c, NodeRefVec &&deps, const Dimension< R > &dim)
Build a new CWisePattern node.
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.
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 ExtType & exponent_part() const
virtual const MatType & float_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.
std::size_t nbDependencies() const noexcept
Number of dependencies (ie nodes we depend on)
Abstract Node storing a value of type T.
const R & accessValueConst() const noexcept
Raw value access (const).
R & accessValueMutable() noexcept
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