SymbolicIndex.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_SYMBOLIC_INDEX_H
11 #define EIGEN_SYMBOLIC_INDEX_H
12 
13 #include "../InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
42 namespace symbolic {
43 
44 template<typename Tag> class Symbol;
45 template<typename Arg0> class NegateExpr;
46 template<typename Arg1,typename Arg2> class AddExpr;
47 template<typename Arg1,typename Arg2> class ProductExpr;
48 template<typename Arg1,typename Arg2> class QuotientExpr;
49 
50 // A simple wrapper around an integral value to provide the eval method.
51 // We could also use a free-function symbolic_eval...
52 template<typename IndexType=Index>
53 class ValueExpr {
54 public:
55  ValueExpr(IndexType val) : m_value(val) {}
56  template<typename T>
57  IndexType eval_impl(const T&) const { return m_value; }
58 protected:
59  IndexType m_value;
60 };
61 
62 // Specialization for compile-time value,
63 // It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
64 template<int N>
65 class ValueExpr<internal::FixedInt<N> > {
66 public:
67  ValueExpr() {}
68  template<typename T>
69  EIGEN_CONSTEXPR Index eval_impl(const T&) const { return N; }
70 };
71 
72 
77 template<typename Derived>
78 class BaseExpr
79 {
80 public:
81  const Derived& derived() const { return *static_cast<const Derived*>(this); }
82 
89  template<typename T>
90  Index eval(const T& values) const { return derived().eval_impl(values); }
91 
92  template<typename... Types>
93  Index eval(Types&&... values) const { return derived().eval_impl(std::make_tuple(values...)); }
94 
96 
98  { return AddExpr<Derived,ValueExpr<> >(derived(), b); }
100  { return AddExpr<Derived,ValueExpr<> >(derived(), -a); }
102  { return ProductExpr<Derived,ValueExpr<> >(derived(),a); }
105 
107  { return AddExpr<Derived,ValueExpr<> >(b.derived(), a); }
109  { return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); }
111  { return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); }
113  { return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); }
114 
115  template<int N>
118  template<int N>
119  AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N>) const
120  { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
121  template<int N>
124  template<int N>
127 
128  template<int N>
129  friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>, const BaseExpr& b)
131  template<int N>
134  template<int N>
135  friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N>, const BaseExpr& b)
137  template<int N>
138  friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N>, const BaseExpr& b)
140 
141 
142  template<typename OtherDerived>
144  { return AddExpr<Derived,OtherDerived>(derived(), b.derived()); }
145 
146  template<typename OtherDerived>
148  { return AddExpr<Derived,NegateExpr<OtherDerived> >(derived(), -b.derived()); }
149 
150  template<typename OtherDerived>
152  { return ProductExpr<Derived,OtherDerived>(derived(), b.derived()); }
153 
154  template<typename OtherDerived>
156  { return QuotientExpr<Derived,OtherDerived>(derived(), b.derived()); }
157 };
158 
159 template<typename T>
160 struct is_symbolic {
161  // BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class BaseExpr<T>.
162  enum { value = internal::is_convertible<T,BaseExpr<T> >::value };
163 };
164 
169 template<typename Tag>
171 {
172 public:
174  SymbolValue(Index val) : m_value(val) {}
175 
177  Index value() const { return m_value; }
178 protected:
180 };
181 
183 template<typename tag>
184 class SymbolExpr : public BaseExpr<SymbolExpr<tag> >
185 {
186 public:
188  typedef tag Tag;
189 
191 
197  return SymbolValue<Tag>(val);
198  }
199 
200  Index eval_impl(const SymbolValue<Tag> &values) const { return values.value(); }
201 
202  // C++14 versions suitable for multiple symbols
203  template<typename... Types>
204  Index eval_impl(const std::tuple<Types...>& values) const { return std::get<SymbolValue<Tag> >(values).value(); }
205 };
206 
207 template<typename Arg0>
208 class NegateExpr : public BaseExpr<NegateExpr<Arg0> >
209 {
210 public:
211  NegateExpr(const Arg0& arg0) : m_arg0(arg0) {}
212 
213  template<typename T>
214  Index eval_impl(const T& values) const { return -m_arg0.eval_impl(values); }
215 protected:
216  Arg0 m_arg0;
217 };
218 
219 template<typename Arg0, typename Arg1>
220 class AddExpr : public BaseExpr<AddExpr<Arg0,Arg1> >
221 {
222 public:
223  AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
224 
225  template<typename T>
226  Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) + m_arg1.eval_impl(values); }
227 protected:
228  Arg0 m_arg0;
229  Arg1 m_arg1;
230 };
231 
232 template<typename Arg0, typename Arg1>
233 class ProductExpr : public BaseExpr<ProductExpr<Arg0,Arg1> >
234 {
235 public:
236  ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
237 
238  template<typename T>
239  Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) * m_arg1.eval_impl(values); }
240 protected:
241  Arg0 m_arg0;
242  Arg1 m_arg1;
243 };
244 
245 template<typename Arg0, typename Arg1>
246 class QuotientExpr : public BaseExpr<QuotientExpr<Arg0,Arg1> >
247 {
248 public:
249  QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
250 
251  template<typename T>
252  Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) / m_arg1.eval_impl(values); }
253 protected:
254  Arg0 m_arg0;
255  Arg1 m_arg1;
256 };
257 
258 } // end namespace symbolic
259 
260 } // end namespace Eigen
261 
262 #endif // EIGEN_SYMBOLIC_INDEX_H
Array< int, 3, 1 > b
#define EIGEN_CONSTEXPR
Definition: Macros.h:747
AddExpr(const Arg0 &arg0, const Arg1 &arg1)
Index eval_impl(const T &values) const
ProductExpr< Derived, OtherDerived > operator*(const BaseExpr< OtherDerived > &b) const
friend AddExpr< Derived, ValueExpr<> > operator+(Index a, const BaseExpr &b)
ProductExpr< Derived, ValueExpr<> > operator*(Index a) const
friend QuotientExpr< ValueExpr< internal::FixedInt< N > >, Derived > operator/(internal::FixedInt< N >, const BaseExpr &b)
friend AddExpr< NegateExpr< Derived >, ValueExpr<> > operator-(Index a, const BaseExpr &b)
AddExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator+(internal::FixedInt< N >) const
NegateExpr< Derived > operator-() const
Definition: SymbolicIndex.h:95
Index eval(const T &values) const
Definition: SymbolicIndex.h:90
friend ProductExpr< ValueExpr<>, Derived > operator*(Index a, const BaseExpr &b)
QuotientExpr< Derived, OtherDerived > operator/(const BaseExpr< OtherDerived > &b) const
ProductExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator*(internal::FixedInt< N >) const
friend AddExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator+(internal::FixedInt< N >, const BaseExpr &b)
friend QuotientExpr< ValueExpr<>, Derived > operator/(Index a, const BaseExpr &b)
Index eval(Types &&... values) const
Definition: SymbolicIndex.h:93
friend ProductExpr< ValueExpr< internal::FixedInt< N > >, Derived > operator*(internal::FixedInt< N >, const BaseExpr &b)
QuotientExpr< Derived, ValueExpr<> > operator/(Index a) const
AddExpr< Derived, OtherDerived > operator+(const BaseExpr< OtherDerived > &b) const
const Derived & derived() const
Definition: SymbolicIndex.h:81
AddExpr< Derived, ValueExpr< internal::FixedInt<-N > > > operator-(internal::FixedInt< N >) const
AddExpr< Derived, NegateExpr< OtherDerived > > operator-(const BaseExpr< OtherDerived > &b) const
QuotientExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator/(internal::FixedInt< N >) const
AddExpr< Derived, ValueExpr<> > operator-(Index a) const
Definition: SymbolicIndex.h:99
friend AddExpr< NegateExpr< Derived >, ValueExpr< internal::FixedInt< N > > > operator-(internal::FixedInt< N >, const BaseExpr &b)
AddExpr< Derived, ValueExpr<> > operator+(Index b) const
Definition: SymbolicIndex.h:97
NegateExpr(const Arg0 &arg0)
Index eval_impl(const T &values) const
ProductExpr(const Arg0 &arg0, const Arg1 &arg1)
Index eval_impl(const T &values) const
Index eval_impl(const T &values) const
QuotientExpr(const Arg0 &arg0, const Arg1 &arg1)
SymbolValue< Tag > operator=(Index val) const
Index eval_impl(const SymbolValue< Tag > &values) const
Index eval_impl(const std::tuple< Types... > &values) const
IndexType eval_impl(const T &) const
Definition: SymbolicIndex.h:57
: InteropHeaders
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82