Eigen  3.4.90 (git rev 9589cc4e7fd8e4538bedef80dd36c7738977a8be)
 
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Loading...
Searching...
No Matches
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// IWYU pragma: private
14#include "../InternalHeaderCheck.h"
15
16namespace Eigen {
17
43namespace symbolic {
44
45template <typename Tag>
46class Symbol;
47template <typename Tag, typename Type>
48class SymbolValue;
49template <typename Arg0>
50class NegateExpr;
51template <typename Arg1, typename Arg2>
52class AddExpr;
53template <typename Arg1, typename Arg2>
54class ProductExpr;
55template <typename Arg1, typename Arg2>
56class QuotientExpr;
57template <typename IndexType = Index>
58class ValueExpr;
59
64template <typename Derived_>
65class 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>
87 return Derived::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
88 }
89
90 constexpr NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }
91
92 constexpr AddExpr<Derived, ValueExpr<>> operator+(Index b) const {
93 return AddExpr<Derived, ValueExpr<>>(derived(), b);
94 }
95 constexpr AddExpr<Derived, ValueExpr<>> operator-(Index a) const {
96 return AddExpr<Derived, ValueExpr<>>(derived(), -a);
97 }
98 constexpr ProductExpr<Derived, ValueExpr<>> operator*(Index a) const {
99 return ProductExpr<Derived, ValueExpr<>>(derived(), a);
100 }
101 constexpr QuotientExpr<Derived, ValueExpr<>> operator/(Index a) const {
102 return QuotientExpr<Derived, ValueExpr<>>(derived(), a);
103 }
104
105 friend constexpr AddExpr<Derived, ValueExpr<>> operator+(Index a, const BaseExpr& b) {
106 return AddExpr<Derived, ValueExpr<>>(b.derived(), a);
107 }
108 friend constexpr AddExpr<NegateExpr<Derived>, ValueExpr<>> operator-(Index a, const BaseExpr& b) {
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 }
114 friend constexpr QuotientExpr<ValueExpr<>, Derived> operator/(Index a, const BaseExpr& b) {
115 return QuotientExpr<ValueExpr<>, Derived>(a, b.derived());
116 }
117
118 template <int N>
119 constexpr 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 }
122 template <int N>
123 constexpr AddExpr<Derived, ValueExpr<internal::FixedInt<-N>>> operator-(internal::FixedInt<N>) const {
124 return AddExpr<Derived, ValueExpr<internal::FixedInt<-N>>>(derived(), ValueExpr<internal::FixedInt<-N>>());
125 }
126 template <int N>
127 constexpr ProductExpr<Derived, ValueExpr<internal::FixedInt<N>>> operator*(internal::FixedInt<N>) const {
128 return ProductExpr<Derived, ValueExpr<internal::FixedInt<N>>>(derived(), ValueExpr<internal::FixedInt<N>>());
129 }
130 template <int N>
131 constexpr QuotientExpr<Derived, ValueExpr<internal::FixedInt<N>>> operator/(internal::FixedInt<N>) const {
132 return QuotientExpr<Derived, ValueExpr<internal::FixedInt<N>>>(derived(), ValueExpr<internal::FixedInt<N>>());
133 }
134
135 template <int N>
136 friend constexpr AddExpr<Derived, ValueExpr<internal::FixedInt<N>>> operator+(internal::FixedInt<N>,
137 const BaseExpr& b) {
138 return AddExpr<Derived, ValueExpr<internal::FixedInt<N>>>(b.derived(), ValueExpr<internal::FixedInt<N>>());
139 }
140 template <int N>
141 friend constexpr AddExpr<NegateExpr<Derived>, ValueExpr<internal::FixedInt<N>>> operator-(internal::FixedInt<N>,
142 const BaseExpr& b) {
143 return AddExpr<NegateExpr<Derived>, ValueExpr<internal::FixedInt<N>>>(-b.derived(),
144 ValueExpr<internal::FixedInt<N>>());
145 }
146 template <int N>
147 friend constexpr ProductExpr<ValueExpr<internal::FixedInt<N>>, Derived> operator*(internal::FixedInt<N>,
148 const BaseExpr& b) {
149 return ProductExpr<ValueExpr<internal::FixedInt<N>>, Derived>(ValueExpr<internal::FixedInt<N>>(), b.derived());
150 }
151 template <int N>
152 friend constexpr QuotientExpr<ValueExpr<internal::FixedInt<N>>, Derived> operator/(internal::FixedInt<N>,
153 const BaseExpr& b) {
154 return QuotientExpr<ValueExpr<internal::FixedInt<N>>, Derived>(ValueExpr<internal::FixedInt<N>>(), b.derived());
155 }
156
157 template <typename OtherDerived>
158 constexpr AddExpr<Derived, OtherDerived> operator+(const BaseExpr<OtherDerived>& b) const {
159 return AddExpr<Derived, OtherDerived>(derived(), b.derived());
160 }
161
162 template <typename OtherDerived>
163 constexpr AddExpr<Derived, NegateExpr<OtherDerived>> operator-(const BaseExpr<OtherDerived>& b) const {
164 return AddExpr<Derived, NegateExpr<OtherDerived>>(derived(), -b.derived());
165 }
166
167 template <typename OtherDerived>
168 constexpr ProductExpr<Derived, OtherDerived> operator*(const BaseExpr<OtherDerived>& b) const {
169 return ProductExpr<Derived, OtherDerived>(derived(), b.derived());
170 }
171
172 template <typename OtherDerived>
173 constexpr QuotientExpr<Derived, OtherDerived> operator/(const BaseExpr<OtherDerived>& b) const {
174 return QuotientExpr<Derived, OtherDerived>(derived(), b.derived());
175 }
176};
177
178template <typename T>
179struct 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...
187template <typename IndexType>
188class 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.
207template <int N>
208class ValueExpr<internal::FixedInt<N>> : public BaseExpr<ValueExpr<internal::FixedInt<N>>> {
209 public:
210 constexpr ValueExpr() = default;
211 constexpr ValueExpr(internal::FixedInt<N>) {}
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>
217 static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tags, Types>&...) {
218 return Index(N);
219 }
220};
221
226template <typename Tag, typename Type>
227class SymbolValue : public BaseExpr<SymbolValue<Tag, Type>> {};
228
229template <typename Tag>
230class 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>
249 static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tags, Types>&...) {
250 return value_at_compile_time();
251 }
252
253 protected:
254 Index value_;
255};
256
257template <typename Tag, int N>
258class SymbolValue<Tag, internal::FixedInt<N>> : public BaseExpr<SymbolValue<Tag, internal::FixedInt<N>>> {
259 public:
260 constexpr SymbolValue() = default;
261
263 constexpr SymbolValue(internal::FixedInt<N>) {}
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>
277 static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tags, Types>&...) {
278 return value_at_compile_time();
279 }
280};
281
282// Find and return a symbol value based on the tag.
283template <typename Tag, typename... Types>
284struct EvalSymbolValueHelper;
285
286// Empty base case, symbol not found.
287template <typename Tag>
288struct EvalSymbolValueHelper<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!
297template <typename Tag, typename Type, typename... OtherTypes>
298struct 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.
308template <typename Tag, typename T1, typename... OtherTypes>
309struct EvalSymbolValueHelper<Tag, T1, OtherTypes...> {
310 static constexpr Index eval_impl(const T1&, const OtherTypes&... values) {
311 return EvalSymbolValueHelper<Tag, OtherTypes...>::eval_impl(values...);
312 }
313 static constexpr Index eval_at_compile_time_impl(const T1&, const OtherTypes&...) {
314 return EvalSymbolValueHelper<Tag, OtherTypes...>::eval_at_compile_time_impl(OtherTypes{}...);
315 }
316};
317
319template <typename tag>
320class SymbolExpr : public BaseExpr<SymbolExpr<tag>> {
321 public:
323 typedef tag Tag;
324
325 constexpr SymbolExpr() = default;
326
333
334 template <int N>
335 constexpr SymbolValue<Tag, internal::FixedInt<N>> operator=(internal::FixedInt<N>) const {
336 return SymbolValue<Tag, internal::FixedInt<N>>{internal::FixedInt<N>{}};
337 }
338
339 template <typename... Tags, typename... Types>
340 constexpr Index eval_impl(const SymbolValue<Tags, Types>&... values) const {
341 return EvalSymbolValueHelper<Tag, SymbolValue<Tags, Types>...>::eval_impl(values...);
342 }
343
344 template <typename... Tags, typename... Types>
345 static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tags, Types>&...) {
346 return EvalSymbolValueHelper<Tag, SymbolValue<Tags, Types>...>::eval_at_compile_time_impl(
347 SymbolValue<Tags, Types>{}...);
348 }
349};
350
351template <typename Arg0>
352class 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>
363 static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tags, 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
372template <typename Arg0, typename Arg1>
373class 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>
384 static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tags, 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
395template <typename Arg0, typename Arg1>
396class 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>
407 static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tags, 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
418template <typename Arg0, typename Arg1>
419class 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>
430 static constexpr Index eval_at_compile_time_impl(const SymbolValue<Tags, 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
Definition SymbolicIndex.h:65
constexpr Index eval(const SymbolValue< Tags, Types > &... values) const
Definition SymbolicIndex.h:76
static constexpr Index eval_at_compile_time(const SymbolValue< Tags, Types > &...)
Definition SymbolicIndex.h:86
constexpr SymbolValue< Tag, Index > operator=(Index val) const
Definition SymbolicIndex.h:332
internal::symbolic_last_tag Tag
Definition SymbolicIndex.h:323
Definition SymbolicIndex.h:227
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
const int Undefined
Definition Constants.h:34
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82