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 // IWYU pragma: private
14 #include "../InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
43 namespace symbolic {
44 
45 template <typename Tag>
46 class Symbol;
47 template <typename Tag, typename Type>
48 class SymbolValue;
49 template <typename Arg0>
50 class NegateExpr;
51 template <typename Arg1, typename Arg2>
52 class AddExpr;
53 template <typename Arg1, typename Arg2>
54 class ProductExpr;
55 template <typename Arg1, typename Arg2>
56 class QuotientExpr;
57 template <typename IndexType = Index>
58 class ValueExpr;
59 
64 template <typename Derived_>
65 class BaseExpr {
66  public:
67  using Derived = Derived_;
68  constexpr const Derived& derived() const { return *static_cast<const Derived*>(this); }
69 
75  template <typename... Tags, typename... Types>
76  constexpr Index eval(const SymbolValue<Tags, Types>&... values) const {
77  return derived().eval_impl(values...);
78  }
79 
85  template <typename... Tags, typename... Types>
86  static constexpr Index eval_at_compile_time(const SymbolValue<Tags, Types>&...) {
87  return Derived::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
88  }
89 
90  constexpr NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }
91 
94  }
97  }
100  }
103  }
104 
106  return AddExpr<Derived, ValueExpr<>>(b.derived(), a);
107  }
109  return AddExpr<NegateExpr<Derived>, ValueExpr<>>(-b.derived(), a);
110  }
111  friend constexpr ProductExpr<ValueExpr<>, Derived> operator*(Index a, const BaseExpr& b) {
112  return ProductExpr<ValueExpr<>, Derived>(a, b.derived());
113  }
115  return QuotientExpr<ValueExpr<>, Derived>(a, b.derived());
116  }
117 
118  template <int N>
121  }
122  template <int N>
125  }
126  template <int N>
129  }
130  template <int N>
133  }
134 
135  template <int N>
137  const BaseExpr& b) {
139  }
140  template <int N>
142  const BaseExpr& b) {
145  }
146  template <int N>
148  const BaseExpr& b) {
150  }
151  template <int N>
153  const BaseExpr& b) {
155  }
156 
157  template <typename OtherDerived>
159  return AddExpr<Derived, OtherDerived>(derived(), b.derived());
160  }
161 
162  template <typename OtherDerived>
164  return AddExpr<Derived, NegateExpr<OtherDerived>>(derived(), -b.derived());
165  }
166 
167  template <typename OtherDerived>
169  return ProductExpr<Derived, OtherDerived>(derived(), b.derived());
170  }
171 
172  template <typename OtherDerived>
174  return QuotientExpr<Derived, OtherDerived>(derived(), b.derived());
175  }
176 };
177 
178 template <typename T>
179 struct is_symbolic {
180  // BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class
181  // BaseExpr<T>.
182  enum { value = internal::is_convertible<T, BaseExpr<T>>::value };
183 };
184 
185 // A simple wrapper around an integral value to provide the eval method.
186 // We could also use a free-function symbolic_eval...
187 template <typename IndexType>
188 class ValueExpr : BaseExpr<ValueExpr<IndexType>> {
189  public:
190  constexpr ValueExpr() = default;
191  constexpr ValueExpr(IndexType val) : value_(val) {}
192  template <typename... Tags, typename... Types>
193  constexpr IndexType eval_impl(const SymbolValue<Tags, Types>&...) const {
194  return value_;
195  }
196  template <typename... Tags, typename... Types>
197  static constexpr IndexType eval_at_compile_time_impl(const SymbolValue<Tags, Types>&...) {
198  return IndexType(Undefined);
199  }
200 
201  protected:
202  IndexType value_;
203 };
204 
205 // Specialization for compile-time value,
206 // It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
207 template <int N>
208 class ValueExpr<internal::FixedInt<N>> : public BaseExpr<ValueExpr<internal::FixedInt<N>>> {
209  public:
210  constexpr ValueExpr() = default;
212  template <typename... Tags, typename... Types>
213  constexpr Index eval_impl(const SymbolValue<Tags, Types>&...) const {
214  return Index(N);
215  }
216  template <typename... Tags, typename... Types>
218  return Index(N);
219  }
220 };
221 
226 template <typename Tag, typename Type>
227 class SymbolValue : public BaseExpr<SymbolValue<Tag, Type>> {};
228 
229 template <typename Tag>
230 class SymbolValue<Tag, Index> : public BaseExpr<SymbolValue<Tag, Index>> {
231  public:
232  constexpr SymbolValue() = default;
233 
235  constexpr SymbolValue(Index val) : value_(val) {}
236 
238  constexpr Index value() const { return value_; }
239 
241  static constexpr Index value_at_compile_time() { return Index(Undefined); }
242 
243  template <typename... Tags, typename... Types>
244  constexpr Index eval_impl(const SymbolValue<Tags, Types>&...) const {
245  return value();
246  }
247 
248  template <typename... Tags, typename... Types>
250  return value_at_compile_time();
251  }
252 
253  protected:
255 };
256 
257 template <typename Tag, int N>
258 class SymbolValue<Tag, internal::FixedInt<N>> : public BaseExpr<SymbolValue<Tag, internal::FixedInt<N>>> {
259  public:
260  constexpr SymbolValue() = default;
261 
264 
266  constexpr Index value() const { return static_cast<Index>(N); }
267 
269  static constexpr Index value_at_compile_time() { return static_cast<Index>(N); }
270 
271  template <typename... Tags, typename... Types>
272  constexpr Index eval_impl(const SymbolValue<Tags, Types>&...) const {
273  return value();
274  }
275 
276  template <typename... Tags, typename... Types>
278  return value_at_compile_time();
279  }
280 };
281 
282 // Find and return a symbol value based on the tag.
283 template <typename Tag, typename... Types>
285 
286 // Empty base case, symbol not found.
287 template <typename Tag>
289  static constexpr Index eval_impl() {
290  eigen_assert(false && "Symbol not found.");
291  return Index(Undefined);
292  }
293  static constexpr Index eval_at_compile_time_impl() { return Index(Undefined); }
294 };
295 
296 // We found a symbol value matching the provided Tag!
297 template <typename Tag, typename Type, typename... OtherTypes>
298 struct EvalSymbolValueHelper<Tag, SymbolValue<Tag, Type>, OtherTypes...> {
299  static constexpr Index eval_impl(const SymbolValue<Tag, Type>& symbol, const OtherTypes&...) {
300  return symbol.value();
301  }
302  static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tag, Type>& symbol, const OtherTypes&...) {
303  return symbol.value_at_compile_time();
304  }
305 };
306 
307 // No symbol value in first value, recursive search starting with next.
308 template <typename Tag, typename T1, typename... OtherTypes>
309 struct EvalSymbolValueHelper<Tag, T1, OtherTypes...> {
310  static constexpr Index eval_impl(const T1&, const OtherTypes&... values) {
312  }
313  static constexpr Index eval_at_compile_time_impl(const T1&, const OtherTypes&...) {
315  }
316 };
317 
319 template <typename tag>
320 class SymbolExpr : public BaseExpr<SymbolExpr<tag>> {
321  public:
323  typedef tag Tag;
324 
325  constexpr SymbolExpr() = default;
326 
333 
334  template <int N>
337  }
338 
339  template <typename... Tags, typename... Types>
340  constexpr Index eval_impl(const SymbolValue<Tags, Types>&... values) const {
342  }
343 
344  template <typename... Tags, typename... Types>
348  }
349 };
350 
351 template <typename Arg0>
352 class NegateExpr : public BaseExpr<NegateExpr<Arg0>> {
353  public:
354  constexpr NegateExpr() = default;
355  constexpr NegateExpr(const Arg0& arg0) : m_arg0(arg0) {}
356 
357  template <typename... Tags, typename... Types>
358  constexpr Index eval_impl(const SymbolValue<Tags, Types>&... values) const {
359  return -m_arg0.eval_impl(values...);
360  }
361 
362  template <typename... Tags, typename... Types>
364  constexpr Index v = Arg0::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
365  return (v == Undefined) ? Undefined : -v;
366  }
367 
368  protected:
369  Arg0 m_arg0;
370 };
371 
372 template <typename Arg0, typename Arg1>
373 class AddExpr : public BaseExpr<AddExpr<Arg0, Arg1>> {
374  public:
375  constexpr AddExpr() = default;
376  constexpr AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
377 
378  template <typename... Tags, typename... Types>
379  constexpr Index eval_impl(const SymbolValue<Tags, Types>&... values) const {
380  return m_arg0.eval_impl(values...) + m_arg1.eval_impl(values...);
381  }
382 
383  template <typename... Tags, typename... Types>
385  constexpr Index v0 = Arg0::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
386  constexpr Index v1 = Arg1::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
387  return (v0 == Undefined || v1 == Undefined) ? Undefined : v0 + v1;
388  }
389 
390  protected:
391  Arg0 m_arg0;
392  Arg1 m_arg1;
393 };
394 
395 template <typename Arg0, typename Arg1>
396 class ProductExpr : public BaseExpr<ProductExpr<Arg0, Arg1>> {
397  public:
398  constexpr ProductExpr() = default;
399  constexpr ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
400 
401  template <typename... Tags, typename... Types>
402  constexpr Index eval_impl(const SymbolValue<Tags, Types>&... values) const {
403  return m_arg0.eval_impl(values...) * m_arg1.eval_impl(values...);
404  }
405 
406  template <typename... Tags, typename... Types>
408  constexpr Index v0 = Arg0::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
409  constexpr Index v1 = Arg1::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
410  return (v0 == Undefined || v1 == Undefined) ? Undefined : v0 * v1;
411  }
412 
413  protected:
414  Arg0 m_arg0;
415  Arg1 m_arg1;
416 };
417 
418 template <typename Arg0, typename Arg1>
419 class QuotientExpr : public BaseExpr<QuotientExpr<Arg0, Arg1>> {
420  public:
421  constexpr QuotientExpr() = default;
422  constexpr QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
423 
424  template <typename... Tags, typename... Types>
425  constexpr Index eval_impl(const SymbolValue<Tags, Types>&... values) const {
426  return m_arg0.eval_impl(values...) / m_arg1.eval_impl(values...);
427  }
428 
429  template <typename... Tags, typename... Types>
431  constexpr Index v0 = Arg0::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
432  constexpr Index v1 = Arg1::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
433  return (v0 == Undefined || v1 == Undefined) ? Undefined : v0 / v1;
434  }
435 
436  protected:
437  Arg0 m_arg0;
438  Arg1 m_arg1;
439 };
440 
441 } // end namespace symbolic
442 
443 } // end namespace Eigen
444 
445 #endif // EIGEN_SYMBOLIC_INDEX_H
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
#define eigen_assert(x)
Definition: Macros.h:910
M1<< 1, 2, 3, 4, 5, 6, 7, 8, 9;Map< RowVectorXf > v1(M1.data(), M1.size())
Scalar * b
Definition: benchVecAdd.cpp:17
Definition: IntegralConstant.h:23
Definition: SymbolicIndex.h:373
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:384
constexpr Index eval_impl(const SymbolValue< Tags, Types > &... values) const
Definition: SymbolicIndex.h:379
constexpr AddExpr(const Arg0 &arg0, const Arg1 &arg1)
Definition: SymbolicIndex.h:376
Arg0 m_arg0
Definition: SymbolicIndex.h:391
constexpr AddExpr()=default
Arg1 m_arg1
Definition: SymbolicIndex.h:392
Definition: SymbolicIndex.h:65
Derived_ Derived
Definition: SymbolicIndex.h:67
constexpr AddExpr< Derived, ValueExpr<> > operator-(Index a) const
Definition: SymbolicIndex.h:95
constexpr QuotientExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator/(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:131
constexpr friend AddExpr< NegateExpr< Derived >, ValueExpr<> > operator-(Index a, const BaseExpr &b)
Definition: SymbolicIndex.h:108
constexpr ProductExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator*(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:127
constexpr AddExpr< Derived, NegateExpr< OtherDerived > > operator-(const BaseExpr< OtherDerived > &b) const
Definition: SymbolicIndex.h:163
constexpr friend AddExpr< NegateExpr< Derived >, ValueExpr< internal::FixedInt< N > > > operator-(internal::FixedInt< N >, const BaseExpr &b)
Definition: SymbolicIndex.h:141
constexpr QuotientExpr< Derived, ValueExpr<> > operator/(Index a) const
Definition: SymbolicIndex.h:101
constexpr QuotientExpr< Derived, OtherDerived > operator/(const BaseExpr< OtherDerived > &b) const
Definition: SymbolicIndex.h:173
constexpr ProductExpr< Derived, ValueExpr<> > operator*(Index a) const
Definition: SymbolicIndex.h:98
constexpr Index eval(const SymbolValue< Tags, Types > &... values) const
Definition: SymbolicIndex.h:76
constexpr friend ProductExpr< ValueExpr< internal::FixedInt< N > >, Derived > operator*(internal::FixedInt< N >, const BaseExpr &b)
Definition: SymbolicIndex.h:147
constexpr const Derived & derived() const
Definition: SymbolicIndex.h:68
constexpr friend AddExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator+(internal::FixedInt< N >, const BaseExpr &b)
Definition: SymbolicIndex.h:136
constexpr AddExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator+(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:119
constexpr AddExpr< Derived, ValueExpr< internal::FixedInt<-N > > > operator-(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:123
constexpr AddExpr< Derived, OtherDerived > operator+(const BaseExpr< OtherDerived > &b) const
Definition: SymbolicIndex.h:158
constexpr friend AddExpr< Derived, ValueExpr<> > operator+(Index a, const BaseExpr &b)
Definition: SymbolicIndex.h:105
constexpr friend QuotientExpr< ValueExpr<>, Derived > operator/(Index a, const BaseExpr &b)
Definition: SymbolicIndex.h:114
constexpr AddExpr< Derived, ValueExpr<> > operator+(Index b) const
Definition: SymbolicIndex.h:92
constexpr ProductExpr< Derived, OtherDerived > operator*(const BaseExpr< OtherDerived > &b) const
Definition: SymbolicIndex.h:168
constexpr friend ProductExpr< ValueExpr<>, Derived > operator*(Index a, const BaseExpr &b)
Definition: SymbolicIndex.h:111
static constexpr Index eval_at_compile_time(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:86
constexpr NegateExpr< Derived > operator-() const
Definition: SymbolicIndex.h:90
constexpr friend QuotientExpr< ValueExpr< internal::FixedInt< N > >, Derived > operator/(internal::FixedInt< N >, const BaseExpr &b)
Definition: SymbolicIndex.h:152
Definition: SymbolicIndex.h:352
constexpr Index eval_impl(const SymbolValue< Tags, Types > &... values) const
Definition: SymbolicIndex.h:358
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:363
constexpr NegateExpr()=default
constexpr NegateExpr(const Arg0 &arg0)
Definition: SymbolicIndex.h:355
Arg0 m_arg0
Definition: SymbolicIndex.h:369
Definition: SymbolicIndex.h:396
Arg1 m_arg1
Definition: SymbolicIndex.h:415
constexpr ProductExpr(const Arg0 &arg0, const Arg1 &arg1)
Definition: SymbolicIndex.h:399
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:407
Arg0 m_arg0
Definition: SymbolicIndex.h:414
constexpr Index eval_impl(const SymbolValue< Tags, Types > &... values) const
Definition: SymbolicIndex.h:402
constexpr ProductExpr()=default
Definition: SymbolicIndex.h:419
constexpr QuotientExpr()=default
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:430
Arg1 m_arg1
Definition: SymbolicIndex.h:438
Arg0 m_arg0
Definition: SymbolicIndex.h:437
constexpr Index eval_impl(const SymbolValue< Tags, Types > &... values) const
Definition: SymbolicIndex.h:425
constexpr QuotientExpr(const Arg0 &arg0, const Arg1 &arg1)
Definition: SymbolicIndex.h:422
Definition: SymbolicIndex.h:320
constexpr SymbolValue< Tag, internal::FixedInt< N > > operator=(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:335
constexpr SymbolExpr()=default
constexpr SymbolValue< Tag, Index > operator=(Index val) const
Definition: SymbolicIndex.h:332
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:345
tag Tag
Definition: SymbolicIndex.h:323
constexpr Index eval_impl(const SymbolValue< Tags, Types > &... values) const
Definition: SymbolicIndex.h:340
Definition: SymbolicIndex.h:230
Index value_
Definition: SymbolicIndex.h:254
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:249
constexpr SymbolValue(Index val)
Definition: SymbolicIndex.h:235
constexpr Index value() const
Definition: SymbolicIndex.h:238
constexpr Index eval_impl(const SymbolValue< Tags, Types > &...) const
Definition: SymbolicIndex.h:244
static constexpr Index value_at_compile_time()
Definition: SymbolicIndex.h:241
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:277
constexpr Index value() const
Definition: SymbolicIndex.h:266
constexpr Index eval_impl(const SymbolValue< Tags, Types > &...) const
Definition: SymbolicIndex.h:272
constexpr SymbolValue(internal::FixedInt< N >)
Definition: SymbolicIndex.h:263
static constexpr Index value_at_compile_time()
Definition: SymbolicIndex.h:269
Definition: SymbolicIndex.h:227
Definition: SymbolicIndex.h:46
constexpr Index eval_impl(const SymbolValue< Tags, Types > &...) const
Definition: SymbolicIndex.h:213
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:217
constexpr ValueExpr(internal::FixedInt< N >)
Definition: SymbolicIndex.h:211
Definition: SymbolicIndex.h:188
constexpr ValueExpr(IndexType val)
Definition: SymbolicIndex.h:191
constexpr ValueExpr()=default
static constexpr IndexType eval_at_compile_time_impl(const SymbolValue< Tags, Types > &...)
Definition: SymbolicIndex.h:197
constexpr IndexType eval_impl(const SymbolValue< Tags, Types > &...) const
Definition: SymbolicIndex.h:193
IndexType value_
Definition: SymbolicIndex.h:202
@ N
Definition: constructor.cpp:22
const Scalar * a
Definition: level2_cplx_impl.h:32
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
const int Undefined
Definition: Constants.h:34
squared absolute value
Definition: GlobalFunctions.h:87
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
val
Definition: calibrate.py:119
Definition: Eigen_Colamd.h:49
Type
Type of JSON value.
Definition: rapidjson.h:513
static constexpr Index eval_at_compile_time_impl(const SymbolValue< Tag, Type > &symbol, const OtherTypes &...)
Definition: SymbolicIndex.h:302
static constexpr Index eval_impl(const SymbolValue< Tag, Type > &symbol, const OtherTypes &...)
Definition: SymbolicIndex.h:299
static constexpr Index eval_at_compile_time_impl(const T1 &, const OtherTypes &...)
Definition: SymbolicIndex.h:313
static constexpr Index eval_impl(const T1 &, const OtherTypes &... values)
Definition: SymbolicIndex.h:310
static constexpr Index eval_at_compile_time_impl()
Definition: SymbolicIndex.h:293
static constexpr Index eval_impl()
Definition: SymbolicIndex.h:289
Definition: SymbolicIndex.h:284
Definition: SymbolicIndex.h:179