|  | // This file is part of Eigen, a lightweight C++ template library | 
|  | // for linear algebra. | 
|  | // | 
|  | // Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr> | 
|  | // | 
|  | // This Source Code Form is subject to the terms of the Mozilla | 
|  | // Public License v. 2.0. If a copy of the MPL was not distributed | 
|  | // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | 
|  |  | 
|  | #ifndef EIGEN_SYMBOLIC_INDEX_H | 
|  | #define EIGEN_SYMBOLIC_INDEX_H | 
|  |  | 
|  | #include "../InternalHeaderCheck.h" | 
|  |  | 
|  | namespace Eigen { | 
|  |  | 
|  | /** \namespace Eigen::symbolic | 
|  | * \ingroup Core_Module | 
|  | * | 
|  | * This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type Index. | 
|  | * Here is a simple example: | 
|  | * | 
|  | * \code | 
|  | * // First step, defines symbols: | 
|  | * struct x_tag {};  static const symbolic::SymbolExpr<x_tag> x; | 
|  | * struct y_tag {};  static const symbolic::SymbolExpr<y_tag> y; | 
|  | * struct z_tag {};  static const symbolic::SymbolExpr<z_tag> z; | 
|  | * | 
|  | * // Defines an expression: | 
|  | * auto expr = (x+3)/y+z; | 
|  | * | 
|  | * // And evaluate it: (c++14) | 
|  | * std::cout << expr.eval(x=6,y=3,z=-13) << "\n"; | 
|  | * | 
|  | * // In c++98/11, only one symbol per expression is supported for now: | 
|  | * auto expr98 = (3-x)/2; | 
|  | * std::cout << expr98.eval(x=6) << "\n"; | 
|  | * \endcode | 
|  | * | 
|  | * It is currently only used internally to define and manipulate the | 
|  | * Eigen::placeholders::last and Eigen::placeholders::lastp1 symbols in | 
|  | * Eigen::seq and Eigen::seqN. | 
|  | * | 
|  | */ | 
|  | namespace symbolic { | 
|  |  | 
|  | template<typename Tag> class Symbol; | 
|  | template<typename Arg0> class NegateExpr; | 
|  | template<typename Arg1,typename Arg2> class AddExpr; | 
|  | template<typename Arg1,typename Arg2> class ProductExpr; | 
|  | template<typename Arg1,typename Arg2> class QuotientExpr; | 
|  |  | 
|  | // A simple wrapper around an integral value to provide the eval method. | 
|  | // We could also use a free-function symbolic_eval... | 
|  | template<typename IndexType=Index> | 
|  | class ValueExpr { | 
|  | public: | 
|  | ValueExpr(IndexType val) : m_value(val) {} | 
|  | template<typename T> | 
|  | IndexType eval_impl(const T&) const { return m_value; } | 
|  | protected: | 
|  | IndexType m_value; | 
|  | }; | 
|  |  | 
|  | // Specialization for compile-time value, | 
|  | // It is similar to ValueExpr(N) but this version helps the compiler to generate better code. | 
|  | template<int N> | 
|  | class ValueExpr<internal::FixedInt<N> > { | 
|  | public: | 
|  | ValueExpr() {} | 
|  | template<typename T> | 
|  | EIGEN_CONSTEXPR Index eval_impl(const T&) const { return N; } | 
|  | }; | 
|  |  | 
|  |  | 
|  | /** \class BaseExpr | 
|  | * \ingroup Core_Module | 
|  | * Common base class of any symbolic expressions | 
|  | */ | 
|  | template<typename Derived> | 
|  | class BaseExpr | 
|  | { | 
|  | public: | 
|  | const Derived& derived() const { return *static_cast<const Derived*>(this); } | 
|  |  | 
|  | /** Evaluate the expression given the \a values of the symbols. | 
|  | * | 
|  | * \param values defines the values of the symbols, it can either be a SymbolValue or a std::tuple of SymbolValue | 
|  | *               as constructed by SymbolExpr::operator= operator. | 
|  | * | 
|  | */ | 
|  | template<typename T> | 
|  | Index eval(const T& values) const { return derived().eval_impl(values); } | 
|  |  | 
|  | template<typename... Types> | 
|  | Index eval(Types&&... values) const { return derived().eval_impl(std::make_tuple(values...)); } | 
|  |  | 
|  | NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); } | 
|  |  | 
|  | AddExpr<Derived,ValueExpr<> > operator+(Index b) const | 
|  | { return AddExpr<Derived,ValueExpr<> >(derived(),  b); } | 
|  | AddExpr<Derived,ValueExpr<> > operator-(Index a) const | 
|  | { return AddExpr<Derived,ValueExpr<> >(derived(), -a); } | 
|  | ProductExpr<Derived,ValueExpr<> > operator*(Index a) const | 
|  | { return ProductExpr<Derived,ValueExpr<> >(derived(),a); } | 
|  | QuotientExpr<Derived,ValueExpr<> > operator/(Index a) const | 
|  | { return QuotientExpr<Derived,ValueExpr<> >(derived(),a); } | 
|  |  | 
|  | friend AddExpr<Derived,ValueExpr<> > operator+(Index a, const BaseExpr& b) | 
|  | { return AddExpr<Derived,ValueExpr<> >(b.derived(), a); } | 
|  | friend AddExpr<NegateExpr<Derived>,ValueExpr<> > operator-(Index a, const BaseExpr& b) | 
|  | { return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); } | 
|  | friend ProductExpr<ValueExpr<>,Derived> operator*(Index a, const BaseExpr& b) | 
|  | { return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); } | 
|  | friend QuotientExpr<ValueExpr<>,Derived> operator/(Index a, const BaseExpr& b) | 
|  | { return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); } | 
|  |  | 
|  | template<int N> | 
|  | AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>) const | 
|  | { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); } | 
|  | template<int N> | 
|  | AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N>) const | 
|  | { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); } | 
|  | template<int N> | 
|  | ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N>) const | 
|  | { return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); } | 
|  | template<int N> | 
|  | QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N>) const | 
|  | { return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); } | 
|  |  | 
|  | template<int N> | 
|  | friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>, const BaseExpr& b) | 
|  | { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); } | 
|  | template<int N> | 
|  | friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N>, const BaseExpr& b) | 
|  | { return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); } | 
|  | template<int N> | 
|  | friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N>, const BaseExpr& b) | 
|  | { return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); } | 
|  | template<int N> | 
|  | friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N>, const BaseExpr& b) | 
|  | { return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); } | 
|  |  | 
|  |  | 
|  | template<typename OtherDerived> | 
|  | AddExpr<Derived,OtherDerived> operator+(const BaseExpr<OtherDerived> &b) const | 
|  | { return AddExpr<Derived,OtherDerived>(derived(),  b.derived()); } | 
|  |  | 
|  | template<typename OtherDerived> | 
|  | AddExpr<Derived,NegateExpr<OtherDerived> > operator-(const BaseExpr<OtherDerived> &b) const | 
|  | { return AddExpr<Derived,NegateExpr<OtherDerived> >(derived(), -b.derived()); } | 
|  |  | 
|  | template<typename OtherDerived> | 
|  | ProductExpr<Derived,OtherDerived> operator*(const BaseExpr<OtherDerived> &b) const | 
|  | { return ProductExpr<Derived,OtherDerived>(derived(), b.derived()); } | 
|  |  | 
|  | template<typename OtherDerived> | 
|  | QuotientExpr<Derived,OtherDerived> operator/(const BaseExpr<OtherDerived> &b) const | 
|  | { return QuotientExpr<Derived,OtherDerived>(derived(), b.derived()); } | 
|  | }; | 
|  |  | 
|  | template<typename T> | 
|  | struct is_symbolic { | 
|  | // BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class BaseExpr<T>. | 
|  | enum { value = internal::is_convertible<T,BaseExpr<T> >::value }; | 
|  | }; | 
|  |  | 
|  | /** Represents the actual value of a symbol identified by its tag | 
|  | * | 
|  | * It is the return type of SymbolValue::operator=, and most of the time this is only way it is used. | 
|  | */ | 
|  | template<typename Tag> | 
|  | class SymbolValue | 
|  | { | 
|  | public: | 
|  | /** Default constructor from the value \a val */ | 
|  | SymbolValue(Index val) : m_value(val) {} | 
|  |  | 
|  | /** \returns the stored value of the symbol */ | 
|  | Index value() const { return m_value; } | 
|  | protected: | 
|  | Index m_value; | 
|  | }; | 
|  |  | 
|  | /** Expression of a symbol uniquely identified by the template parameter type \c tag */ | 
|  | template<typename tag> | 
|  | class SymbolExpr : public BaseExpr<SymbolExpr<tag> > | 
|  | { | 
|  | public: | 
|  | /** Alias to the template parameter \c tag */ | 
|  | typedef tag Tag; | 
|  |  | 
|  | SymbolExpr() {} | 
|  |  | 
|  | /** Associate the value \a val to the given symbol \c *this, uniquely identified by its \c Tag. | 
|  | * | 
|  | * The returned object should be passed to ExprBase::eval() to evaluate a given expression with this specified runtime-time value. | 
|  | */ | 
|  | SymbolValue<Tag> operator=(Index val) const { | 
|  | return SymbolValue<Tag>(val); | 
|  | } | 
|  |  | 
|  | Index eval_impl(const SymbolValue<Tag> &values) const { return values.value(); } | 
|  |  | 
|  | // C++14 versions suitable for multiple symbols | 
|  | template<typename... Types> | 
|  | Index eval_impl(const std::tuple<Types...>& values) const { return std::get<SymbolValue<Tag> >(values).value(); } | 
|  | }; | 
|  |  | 
|  | template<typename Arg0> | 
|  | class NegateExpr : public BaseExpr<NegateExpr<Arg0> > | 
|  | { | 
|  | public: | 
|  | NegateExpr(const Arg0& arg0) : m_arg0(arg0) {} | 
|  |  | 
|  | template<typename T> | 
|  | Index eval_impl(const T& values) const { return -m_arg0.eval_impl(values); } | 
|  | protected: | 
|  | Arg0 m_arg0; | 
|  | }; | 
|  |  | 
|  | template<typename Arg0, typename Arg1> | 
|  | class AddExpr : public BaseExpr<AddExpr<Arg0,Arg1> > | 
|  | { | 
|  | public: | 
|  | AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} | 
|  |  | 
|  | template<typename T> | 
|  | Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) + m_arg1.eval_impl(values); } | 
|  | protected: | 
|  | Arg0 m_arg0; | 
|  | Arg1 m_arg1; | 
|  | }; | 
|  |  | 
|  | template<typename Arg0, typename Arg1> | 
|  | class ProductExpr : public BaseExpr<ProductExpr<Arg0,Arg1> > | 
|  | { | 
|  | public: | 
|  | ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} | 
|  |  | 
|  | template<typename T> | 
|  | Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) * m_arg1.eval_impl(values); } | 
|  | protected: | 
|  | Arg0 m_arg0; | 
|  | Arg1 m_arg1; | 
|  | }; | 
|  |  | 
|  | template<typename Arg0, typename Arg1> | 
|  | class QuotientExpr : public BaseExpr<QuotientExpr<Arg0,Arg1> > | 
|  | { | 
|  | public: | 
|  | QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {} | 
|  |  | 
|  | template<typename T> | 
|  | Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) / m_arg1.eval_impl(values); } | 
|  | protected: | 
|  | Arg0 m_arg0; | 
|  | Arg1 m_arg1; | 
|  | }; | 
|  |  | 
|  | } // end namespace symbolic | 
|  |  | 
|  | } // end namespace Eigen | 
|  |  | 
|  | #endif // EIGEN_SYMBOLIC_INDEX_H |