From 9eaab4f9e0c50bf8bfa8d8b79b809d3d564ccbf3 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Tue, 10 Jan 2017 10:57:08 +0100 Subject: Refactoring: move all symbolic stuff into its own namespace --- Eigen/src/Core/ArithmeticSequence.h | 171 +++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 73 deletions(-) (limited to 'Eigen/src/Core/ArithmeticSequence.h') diff --git a/Eigen/src/Core/ArithmeticSequence.h b/Eigen/src/Core/ArithmeticSequence.h index 88954b4a6..72ca639db 100644 --- a/Eigen/src/Core/ArithmeticSequence.h +++ b/Eigen/src/Core/ArithmeticSequence.h @@ -19,93 +19,103 @@ namespace Eigen { struct all_t { all_t() {} }; static const all_t all; +//-------------------------------------------------------------------------------- +// minimalistic symbolic scalar type +//-------------------------------------------------------------------------------- + +namespace Symbolic { + +template class Symbol; +template class NegateExpr; +template class AddExpr; +template class ProductExpr; +template class QuotientExpr; + // A simple wrapper around an Index to provide the eval method. // We could also use a free-function symbolic_eval... -class symbolic_value_wrapper { +class ValueExpr { public: - symbolic_value_wrapper(Index val) : m_value(val) {} + ValueExpr(Index val) : m_value(val) {} template Index eval(const T&) const { return m_value; } protected: Index m_value; }; -//-------------------------------------------------------------------------------- -// minimalistic symbolic scalar type -//-------------------------------------------------------------------------------- - -template class symbolic_symbol; -template class symbolic_negate; -template class symbolic_add; -template class symbolic_product; -template class symbolic_quotient; - template -class symbolic_index_base +class BaseExpr { public: const Derived& derived() const { return *static_cast(this); } - symbolic_negate operator-() const { return symbolic_negate(derived()); } + NegateExpr operator-() const { return NegateExpr(derived()); } - symbolic_add operator+(Index b) const - { return symbolic_add(derived(), b); } - symbolic_add operator-(Index a) const - { return symbolic_add(derived(), -a); } - symbolic_quotient operator/(Index a) const - { return symbolic_quotient(derived(),a); } + AddExpr operator+(Index b) const + { return AddExpr(derived(), b); } + AddExpr operator-(Index a) const + { return AddExpr(derived(), -a); } + QuotientExpr operator/(Index a) const + { return QuotientExpr(derived(),a); } - friend symbolic_add operator+(Index a, const symbolic_index_base& b) - { return symbolic_add(b.derived(), a); } - friend symbolic_add,symbolic_value_wrapper> operator-(Index a, const symbolic_index_base& b) - { return symbolic_add,symbolic_value_wrapper>(-b.derived(), a); } - friend symbolic_add operator/(Index a, const symbolic_index_base& b) - { return symbolic_add(a,b.derived()); } + friend AddExpr operator+(Index a, const BaseExpr& b) + { return AddExpr(b.derived(), a); } + friend AddExpr,ValueExpr> operator-(Index a, const BaseExpr& b) + { return AddExpr,ValueExpr>(-b.derived(), a); } + friend AddExpr operator/(Index a, const BaseExpr& b) + { return AddExpr(a,b.derived()); } template - symbolic_add operator+(const symbolic_index_base &b) const - { return symbolic_add(derived(), b.derived()); } + AddExpr operator+(const BaseExpr &b) const + { return AddExpr(derived(), b.derived()); } template - symbolic_add > operator-(const symbolic_index_base &b) const - { return symbolic_add >(derived(), -b.derived()); } + AddExpr > operator-(const BaseExpr &b) const + { return AddExpr >(derived(), -b.derived()); } template - symbolic_add operator/(const symbolic_index_base &b) const - { return symbolic_quotient(derived(), b.derived()); } + AddExpr operator/(const BaseExpr &b) const + { return QuotientExpr(derived(), b.derived()); } }; template struct is_symbolic { - enum { value = internal::is_convertible >::value }; + // BaseExpr has no conversion ctor, so we only to check whether T can be staticaly cast to its base class BaseExpr. + enum { value = internal::is_convertible >::value }; }; template -class symbolic_value_pair +class SymbolValue { public: - symbolic_value_pair(Index val) : m_value(val) {} + SymbolValue(Index val) : m_value(val) {} Index value() const { return m_value; } protected: Index m_value; }; -template -class symbolic_value : public symbolic_index_base > +template +class SymbolExpr : public BaseExpr > { public: - symbolic_value() {} + typedef TagT Tag; + SymbolExpr() {} + + Index eval(const SymbolValue &values) const { return values.value(); } - Index eval(const symbolic_value_pair &values) const { return values.value(); } - // TODO add a c++14 eval taking a tuple of symbolic_value_pair and getting the value with std::get >... + // TODO add a c++14 eval taking a tuple of SymbolValue and getting the value with std::get >... }; +template +SymbolValue defineValue(SymbolExpr,Index val) { + return SymbolValue(val); +} + template -class symbolic_negate : public symbolic_index_base > +class NegateExpr : public BaseExpr > { public: - symbolic_negate(const Arg0& arg0) : m_arg0(arg0) {} + NegateExpr(const Arg0& arg0) : m_arg0(arg0) {} template Index eval(const T& values) const { return -m_arg0.eval(values); } @@ -114,10 +124,10 @@ protected: }; template -class symbolic_add : public symbolic_index_base > +class AddExpr : public BaseExpr > { public: - symbolic_add(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} + AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} template Index eval(const T& values) const { return m_arg0.eval(values) + m_arg1.eval(values); } @@ -127,10 +137,10 @@ protected: }; template -class symbolic_product : public symbolic_index_base > +class ProductExpr : public BaseExpr > { public: - symbolic_product(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} + ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} template Index eval(const T& values) const { return m_arg0.eval(values) * m_arg1.eval(values); } @@ -140,10 +150,10 @@ protected: }; template -class symbolic_quotient : public symbolic_index_base > +class QuotientExpr : public BaseExpr > { public: - symbolic_quotient(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} + QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} template Index eval(const T& values) const { return m_arg0.eval(values) / m_arg1.eval(values); } @@ -152,12 +162,16 @@ protected: Arg1 m_arg1; }; -struct symb_last_tag {}; +} // end namespace Symbolic namespace placeholders { -static const symbolic_value last; -static const symbolic_add,symbolic_value_wrapper> end(last+1); +namespace internal { +struct symbolic_last_tag {}; +} + +static const Symbolic::SymbolExpr last; +static const Symbolic::AddExpr,Symbolic::ValueExpr> end(last+1); } // end namespace placeholders @@ -256,7 +270,7 @@ auto seq(FirstType f, LastType l, IncrType incr) } #else template -typename internal::enable_if::value || is_symbolic::value), +typename internal::enable_if::value || Symbolic::is_symbolic::value), ArithemeticSequence::type,Index> >::type seq(FirstType f, LastType l) { @@ -264,31 +278,34 @@ seq(FirstType f, LastType l) } template -typename internal::enable_if::value, - ArithemeticSequence,symbolic_value_wrapper>,symbolic_value_wrapper> > >::type -seq(const symbolic_index_base &f, LastType l) +typename internal::enable_if::value, + ArithemeticSequence,Symbolic::ValueExpr>, + Symbolic::ValueExpr> > >::type +seq(const Symbolic::BaseExpr &f, LastType l) { return seqN(f.derived(),(l-f.derived()+1)); } template -typename internal::enable_if::value, - ArithemeticSequence::type,symbolic_add,symbolic_value_wrapper> > >::type -seq(FirstType f, const symbolic_index_base &l) +typename internal::enable_if::value, + ArithemeticSequence::type, + Symbolic::AddExpr,Symbolic::ValueExpr> > >::type +seq(FirstType f, const Symbolic::BaseExpr &l) { return seqN(f,(l.derived()-f+1)); } template -ArithemeticSequence >,symbolic_value_wrapper> > -seq(const symbolic_index_base &f, const symbolic_index_base &l) +ArithemeticSequence >,Symbolic::ValueExpr> > +seq(const Symbolic::BaseExpr &f, const Symbolic::BaseExpr &l) { return seqN(f.derived(),(l.derived()-f.derived()+1)); } template -typename internal::enable_if::value || is_symbolic::value), +typename internal::enable_if::value || Symbolic::is_symbolic::value), ArithemeticSequence::type,Index,typename cleanup_seq_type::type> >::type seq(FirstType f, LastType l, IncrType incr) { @@ -297,22 +314,27 @@ seq(FirstType f, LastType l, IncrType incr) } template -typename internal::enable_if::value, +typename internal::enable_if::value, ArithemeticSequence,symbolic_value_wrapper>,symbolic_value_wrapper>,symbolic_value_wrapper>, - typename cleanup_seq_type::type> >::type -seq(const symbolic_index_base &f, LastType l, IncrType incr) + Symbolic::QuotientExpr, + Symbolic::ValueExpr>, + Symbolic::ValueExpr>, + Symbolic::ValueExpr>, + typename cleanup_seq_type::type> >::type +seq(const Symbolic::BaseExpr &f, LastType l, IncrType incr) { typedef typename cleanup_seq_type::type CleanedIncrType; return seqN(f.derived(),(l-f.derived()+CleanedIncrType(incr))/CleanedIncrType(incr), incr); } template -typename internal::enable_if::value, +typename internal::enable_if::value, ArithemeticSequence::type, - symbolic_quotient,symbolic_value_wrapper>,symbolic_value_wrapper>, + Symbolic::QuotientExpr, + Symbolic::ValueExpr>, + Symbolic::ValueExpr>, typename cleanup_seq_type::type> >::type -seq(FirstType f, const symbolic_index_base &l, IncrType incr) +seq(FirstType f, const Symbolic::BaseExpr &l, IncrType incr) { typedef typename cleanup_seq_type::type CleanedIncrType; return seqN(f,(l.derived()-f+CleanedIncrType(incr))/CleanedIncrType(incr), incr); @@ -320,9 +342,12 @@ seq(FirstType f, const symbolic_index_base &l, IncrType incr) template ArithemeticSequence >,symbolic_value_wrapper>,symbolic_value_wrapper>, + Symbolic::QuotientExpr >, + Symbolic::ValueExpr>, + Symbolic::ValueExpr>, typename cleanup_seq_type::type> -seq(const symbolic_index_base &f, const symbolic_index_base &l, IncrType incr) +seq(const Symbolic::BaseExpr &f, const Symbolic::BaseExpr &l, IncrType incr) { typedef typename cleanup_seq_type::type CleanedIncrType; return seqN(f.derived(),(l.derived()-f.derived()+CleanedIncrType(incr))/CleanedIncrType(incr), incr); @@ -404,15 +429,15 @@ template fix_t symbolic2value(fix_t x, Index /*size*/) { return x; } template -Index symbolic2value(const symbolic_index_base &x, Index size) +Index symbolic2value(const Symbolic::BaseExpr &x, Index size) { - return x.derived().eval(symbolic_value_pair(size-1)); + return x.derived().eval(Symbolic::defineValue(placeholders::last,size-1)); } // Convert a symbolic span into a usable one (i.e., remove last/end "keywords") template struct make_size_type { - typedef typename internal::conditional::value, Index, T>::type type; + typedef typename internal::conditional::value, Index, T>::type type; }; template -- cgit v1.2.3