Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/eigen3/Eigen/src/Core/util/SymbolicIndex.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0009 
0010 #ifndef EIGEN_SYMBOLIC_INDEX_H
0011 #define EIGEN_SYMBOLIC_INDEX_H
0012 
0013 namespace Eigen {
0014 
0015 /** \namespace Eigen::symbolic
0016   * \ingroup Core_Module
0017   *
0018   * This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type Index.
0019   * Here is a simple example:
0020   *
0021   * \code
0022   * // First step, defines symbols:
0023   * struct x_tag {};  static const symbolic::SymbolExpr<x_tag> x;
0024   * struct y_tag {};  static const symbolic::SymbolExpr<y_tag> y;
0025   * struct z_tag {};  static const symbolic::SymbolExpr<z_tag> z;
0026   *
0027   * // Defines an expression:
0028   * auto expr = (x+3)/y+z;
0029   *
0030   * // And evaluate it: (c++14)
0031   * std::cout << expr.eval(x=6,y=3,z=-13) << "\n";
0032   *
0033   * // In c++98/11, only one symbol per expression is supported for now:
0034   * auto expr98 = (3-x)/2;
0035   * std::cout << expr98.eval(x=6) << "\n";
0036   * \endcode
0037   *
0038   * It is currently only used internally to define and manipulate the Eigen::last and Eigen::lastp1 symbols in Eigen::seq and Eigen::seqN.
0039   *
0040   */
0041 namespace symbolic {
0042 
0043 template<typename Tag> class Symbol;
0044 template<typename Arg0> class NegateExpr;
0045 template<typename Arg1,typename Arg2> class AddExpr;
0046 template<typename Arg1,typename Arg2> class ProductExpr;
0047 template<typename Arg1,typename Arg2> class QuotientExpr;
0048 
0049 // A simple wrapper around an integral value to provide the eval method.
0050 // We could also use a free-function symbolic_eval...
0051 template<typename IndexType=Index>
0052 class ValueExpr {
0053 public:
0054   ValueExpr(IndexType val) : m_value(val) {}
0055   template<typename T>
0056   IndexType eval_impl(const T&) const { return m_value; }
0057 protected:
0058   IndexType m_value;
0059 };
0060 
0061 // Specialization for compile-time value,
0062 // It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
0063 template<int N>
0064 class ValueExpr<internal::FixedInt<N> > {
0065 public:
0066   ValueExpr() {}
0067   template<typename T>
0068   EIGEN_CONSTEXPR Index eval_impl(const T&) const { return N; }
0069 };
0070 
0071 
0072 /** \class BaseExpr
0073   * \ingroup Core_Module
0074   * Common base class of any symbolic expressions
0075   */
0076 template<typename Derived>
0077 class BaseExpr
0078 {
0079 public:
0080   const Derived& derived() const { return *static_cast<const Derived*>(this); }
0081 
0082   /** Evaluate the expression given the \a values of the symbols.
0083     *
0084     * \param values defines the values of the symbols, it can either be a SymbolValue or a std::tuple of SymbolValue
0085     *               as constructed by SymbolExpr::operator= operator.
0086     *
0087     */
0088   template<typename T>
0089   Index eval(const T& values) const { return derived().eval_impl(values); }
0090 
0091 #if EIGEN_HAS_CXX14
0092   template<typename... Types>
0093   Index eval(Types&&... values) const { return derived().eval_impl(std::make_tuple(values...)); }
0094 #endif
0095 
0096   NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }
0097 
0098   AddExpr<Derived,ValueExpr<> > operator+(Index b) const
0099   { return AddExpr<Derived,ValueExpr<> >(derived(),  b); }
0100   AddExpr<Derived,ValueExpr<> > operator-(Index a) const
0101   { return AddExpr<Derived,ValueExpr<> >(derived(), -a); }
0102   ProductExpr<Derived,ValueExpr<> > operator*(Index a) const
0103   { return ProductExpr<Derived,ValueExpr<> >(derived(),a); }
0104   QuotientExpr<Derived,ValueExpr<> > operator/(Index a) const
0105   { return QuotientExpr<Derived,ValueExpr<> >(derived(),a); }
0106 
0107   friend AddExpr<Derived,ValueExpr<> > operator+(Index a, const BaseExpr& b)
0108   { return AddExpr<Derived,ValueExpr<> >(b.derived(), a); }
0109   friend AddExpr<NegateExpr<Derived>,ValueExpr<> > operator-(Index a, const BaseExpr& b)
0110   { return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); }
0111   friend ProductExpr<ValueExpr<>,Derived> operator*(Index a, const BaseExpr& b)
0112   { return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); }
0113   friend QuotientExpr<ValueExpr<>,Derived> operator/(Index a, const BaseExpr& b)
0114   { return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); }
0115 
0116   template<int N>
0117   AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>) const
0118   { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); }
0119   template<int N>
0120   AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N>) const
0121   { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
0122   template<int N>
0123   ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N>) const
0124   { return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
0125   template<int N>
0126   QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N>) const
0127   { return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
0128 
0129   template<int N>
0130   friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>, const BaseExpr& b)
0131   { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
0132   template<int N>
0133   friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N>, const BaseExpr& b)
0134   { return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
0135   template<int N>
0136   friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N>, const BaseExpr& b)
0137   { return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
0138   template<int N>
0139   friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N>, const BaseExpr& b)
0140   { return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
0141 
0142 #if (!EIGEN_HAS_CXX14)
0143   template<int N>
0144   AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N> (*)()) const
0145   { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); }
0146   template<int N>
0147   AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N> (*)()) const
0148   { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
0149   template<int N>
0150   ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N> (*)()) const
0151   { return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
0152   template<int N>
0153   QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N> (*)()) const
0154   { return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
0155 
0156   template<int N>
0157   friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N> (*)(), const BaseExpr& b)
0158   { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
0159   template<int N>
0160   friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N> (*)(), const BaseExpr& b)
0161   { return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
0162   template<int N>
0163   friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N> (*)(), const BaseExpr& b)
0164   { return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
0165   template<int N>
0166   friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N> (*)(), const BaseExpr& b)
0167   { return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
0168 #endif
0169 
0170 
0171   template<typename OtherDerived>
0172   AddExpr<Derived,OtherDerived> operator+(const BaseExpr<OtherDerived> &b) const
0173   { return AddExpr<Derived,OtherDerived>(derived(),  b.derived()); }
0174 
0175   template<typename OtherDerived>
0176   AddExpr<Derived,NegateExpr<OtherDerived> > operator-(const BaseExpr<OtherDerived> &b) const
0177   { return AddExpr<Derived,NegateExpr<OtherDerived> >(derived(), -b.derived()); }
0178 
0179   template<typename OtherDerived>
0180   ProductExpr<Derived,OtherDerived> operator*(const BaseExpr<OtherDerived> &b) const
0181   { return ProductExpr<Derived,OtherDerived>(derived(), b.derived()); }
0182 
0183   template<typename OtherDerived>
0184   QuotientExpr<Derived,OtherDerived> operator/(const BaseExpr<OtherDerived> &b) const
0185   { return QuotientExpr<Derived,OtherDerived>(derived(), b.derived()); }
0186 };
0187 
0188 template<typename T>
0189 struct is_symbolic {
0190   // BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class BaseExpr<T>.
0191   enum { value = internal::is_convertible<T,BaseExpr<T> >::value };
0192 };
0193 
0194 /** Represents the actual value of a symbol identified by its tag
0195   *
0196   * It is the return type of SymbolValue::operator=, and most of the time this is only way it is used.
0197   */
0198 template<typename Tag>
0199 class SymbolValue
0200 {
0201 public:
0202   /** Default constructor from the value \a val */
0203   SymbolValue(Index val) : m_value(val) {}
0204 
0205   /** \returns the stored value of the symbol */
0206   Index value() const { return m_value; }
0207 protected:
0208   Index m_value;
0209 };
0210 
0211 /** Expression of a symbol uniquely identified by the template parameter type \c tag */
0212 template<typename tag>
0213 class SymbolExpr : public BaseExpr<SymbolExpr<tag> >
0214 {
0215 public:
0216   /** Alias to the template parameter \c tag */
0217   typedef tag Tag;
0218 
0219   SymbolExpr() {}
0220 
0221   /** Associate the value \a val to the given symbol \c *this, uniquely identified by its \c Tag.
0222     *
0223     * The returned object should be passed to ExprBase::eval() to evaluate a given expression with this specified runtime-time value.
0224     */
0225   SymbolValue<Tag> operator=(Index val) const {
0226     return SymbolValue<Tag>(val);
0227   }
0228 
0229   Index eval_impl(const SymbolValue<Tag> &values) const { return values.value(); }
0230 
0231 #if EIGEN_HAS_CXX14
0232   // C++14 versions suitable for multiple symbols
0233   template<typename... Types>
0234   Index eval_impl(const std::tuple<Types...>& values) const { return std::get<SymbolValue<Tag> >(values).value(); }
0235 #endif
0236 };
0237 
0238 template<typename Arg0>
0239 class NegateExpr : public BaseExpr<NegateExpr<Arg0> >
0240 {
0241 public:
0242   NegateExpr(const Arg0& arg0) : m_arg0(arg0) {}
0243 
0244   template<typename T>
0245   Index eval_impl(const T& values) const { return -m_arg0.eval_impl(values); }
0246 protected:
0247   Arg0 m_arg0;
0248 };
0249 
0250 template<typename Arg0, typename Arg1>
0251 class AddExpr : public BaseExpr<AddExpr<Arg0,Arg1> >
0252 {
0253 public:
0254   AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
0255 
0256   template<typename T>
0257   Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) + m_arg1.eval_impl(values); }
0258 protected:
0259   Arg0 m_arg0;
0260   Arg1 m_arg1;
0261 };
0262 
0263 template<typename Arg0, typename Arg1>
0264 class ProductExpr : public BaseExpr<ProductExpr<Arg0,Arg1> >
0265 {
0266 public:
0267   ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
0268 
0269   template<typename T>
0270   Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) * m_arg1.eval_impl(values); }
0271 protected:
0272   Arg0 m_arg0;
0273   Arg1 m_arg1;
0274 };
0275 
0276 template<typename Arg0, typename Arg1>
0277 class QuotientExpr : public BaseExpr<QuotientExpr<Arg0,Arg1> >
0278 {
0279 public:
0280   QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
0281 
0282   template<typename T>
0283   Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) / m_arg1.eval_impl(values); }
0284 protected:
0285   Arg0 m_arg0;
0286   Arg1 m_arg1;
0287 };
0288 
0289 } // end namespace symbolic
0290 
0291 } // end namespace Eigen
0292 
0293 #endif // EIGEN_SYMBOLIC_INDEX_H