Eigen  3.4.90 (git rev 67eeba6e720c5745abc77ae6c92ce0a44aa7b7ae)
SymbolicIndex.h
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 
95  NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }
96 
97  AddExpr<Derived,ValueExpr<> > operator+(Index b) const
98  { return AddExpr<Derived,ValueExpr<> >(derived(), b); }
99  AddExpr<Derived,ValueExpr<> > operator-(Index a) const
100  { return AddExpr<Derived,ValueExpr<> >(derived(), -a); }
101  ProductExpr<Derived,ValueExpr<> > operator*(Index a) const
102  { return ProductExpr<Derived,ValueExpr<> >(derived(),a); }
103  QuotientExpr<Derived,ValueExpr<> > operator/(Index a) const
104  { return QuotientExpr<Derived,ValueExpr<> >(derived(),a); }
105 
106  friend AddExpr<Derived,ValueExpr<> > operator+(Index a, const BaseExpr& b)
107  { return AddExpr<Derived,ValueExpr<> >(b.derived(), a); }
108  friend AddExpr<NegateExpr<Derived>,ValueExpr<> > operator-(Index a, const BaseExpr& b)
109  { return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); }
110  friend ProductExpr<ValueExpr<>,Derived> operator*(Index a, const BaseExpr& b)
111  { return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); }
112  friend QuotientExpr<ValueExpr<>,Derived> operator/(Index a, const BaseExpr& b)
113  { return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); }
114 
115  template<int N>
116  AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>) const
117  { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<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>
122  ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N>) const
123  { return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
124  template<int N>
125  QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N>) const
126  { return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
127 
128  template<int N>
129  friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>, const BaseExpr& b)
130  { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
131  template<int N>
132  friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N>, const BaseExpr& b)
133  { return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
134  template<int N>
135  friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N>, const BaseExpr& b)
136  { return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
137  template<int N>
138  friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N>, const BaseExpr& b)
139  { return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
140 
141 
142  template<typename OtherDerived>
143  AddExpr<Derived,OtherDerived> operator+(const BaseExpr<OtherDerived> &b) const
144  { return AddExpr<Derived,OtherDerived>(derived(), b.derived()); }
145 
146  template<typename OtherDerived>
147  AddExpr<Derived,NegateExpr<OtherDerived> > operator-(const BaseExpr<OtherDerived> &b) const
148  { return AddExpr<Derived,NegateExpr<OtherDerived> >(derived(), -b.derived()); }
149 
150  template<typename OtherDerived>
151  ProductExpr<Derived,OtherDerived> operator*(const BaseExpr<OtherDerived> &b) const
152  { return ProductExpr<Derived,OtherDerived>(derived(), b.derived()); }
153 
154  template<typename OtherDerived>
155  QuotientExpr<Derived,OtherDerived> operator/(const BaseExpr<OtherDerived> &b) const
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:
179  Index m_value;
180 };
181 
183 template<typename tag>
184 class SymbolExpr : public BaseExpr<SymbolExpr<tag> >
185 {
186 public:
188  typedef tag Tag;
189 
190  SymbolExpr() {}
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
Definition: SymbolicIndex.h:79
Index eval(const T &values) const
Definition: SymbolicIndex.h:90
Definition: SymbolicIndex.h:185
SymbolValue< Tag > operator=(Index val) const
Definition: SymbolicIndex.h:196
tag Tag
Definition: SymbolicIndex.h:188
Definition: SymbolicIndex.h:171
SymbolValue(Index val)
Definition: SymbolicIndex.h:174
Index value() const
Definition: SymbolicIndex.h:177
Namespace containing all symbols from the Eigen library.
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:59