WPILibC++ 2023.4.3-108-ge5452e3
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
13namespace Eigen {
14
15/** \namespace Eigen::symbolic
16 * \ingroup Core_Module
17 *
18 * This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type Index.
19 * Here is a simple example:
20 *
21 * \code
22 * // First step, defines symbols:
23 * struct x_tag {}; static const symbolic::SymbolExpr<x_tag> x;
24 * struct y_tag {}; static const symbolic::SymbolExpr<y_tag> y;
25 * struct z_tag {}; static const symbolic::SymbolExpr<z_tag> z;
26 *
27 * // Defines an expression:
28 * auto expr = (x+3)/y+z;
29 *
30 * // And evaluate it: (c++14)
31 * std::cout << expr.eval(x=6,y=3,z=-13) << "\n";
32 *
33 * // In c++98/11, only one symbol per expression is supported for now:
34 * auto expr98 = (3-x)/2;
35 * std::cout << expr98.eval(x=6) << "\n";
36 * \endcode
37 *
38 * It is currently only used internally to define and manipulate the Eigen::last and Eigen::lastp1 symbols in Eigen::seq and Eigen::seqN.
39 *
40 */
41namespace symbolic {
42
43template<typename Tag> class Symbol;
44template<typename Arg0> class NegateExpr;
45template<typename Arg1,typename Arg2> class AddExpr;
46template<typename Arg1,typename Arg2> class ProductExpr;
47template<typename Arg1,typename Arg2> class QuotientExpr;
48
49// A simple wrapper around an integral value to provide the eval method.
50// We could also use a free-function symbolic_eval...
51template<typename IndexType=Index>
52class ValueExpr {
53public:
54 ValueExpr(IndexType val) : m_value(val) {}
55 template<typename T>
56 IndexType eval_impl(const T&) const { return m_value; }
57protected:
58 IndexType m_value;
59};
60
61// Specialization for compile-time value,
62// It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
63template<int N>
64class ValueExpr<internal::FixedInt<N> > {
65public:
67 template<typename T>
68 EIGEN_CONSTEXPR Index eval_impl(const T&) const { return N; }
69};
70
71
72/** \class BaseExpr
73 * \ingroup Core_Module
74 * Common base class of any symbolic expressions
75 */
76template<typename Derived>
78{
79public:
80 const Derived& derived() const { return *static_cast<const Derived*>(this); }
81
82 /** Evaluate the expression given the \a values of the symbols.
83 *
84 * \param values defines the values of the symbols, it can either be a SymbolValue or a std::tuple of SymbolValue
85 * as constructed by SymbolExpr::operator= operator.
86 *
87 */
88 template<typename T>
89 Index eval(const T& values) const { return derived().eval_impl(values); }
90
91#if EIGEN_HAS_CXX14
92 template<typename... Types>
93 Index eval(Types&&... values) const { return derived().eval_impl(std::make_tuple(values...)); }
94#endif
95
97
99 { return AddExpr<Derived,ValueExpr<> >(derived(), b); }
101 { return AddExpr<Derived,ValueExpr<> >(derived(), -a); }
106
108 { return AddExpr<Derived,ValueExpr<> >(b.derived(), a); }
110 { return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); }
112 { return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); }
114 { return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); }
115
116 template<int N>
119 template<int N>
121 { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
122 template<int N>
125 template<int N>
128
129 template<int N>
132 template<int N>
135 template<int N>
138 template<int N>
141
142#if (!EIGEN_HAS_CXX14)
143 template<int N>
146 template<int N>
148 { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
149 template<int N>
152 template<int N>
155
156 template<int N>
159 template<int N>
162 template<int N>
165 template<int N>
168#endif
169
170
171 template<typename OtherDerived>
173 { return AddExpr<Derived,OtherDerived>(derived(), b.derived()); }
174
175 template<typename OtherDerived>
177 { return AddExpr<Derived,NegateExpr<OtherDerived> >(derived(), -b.derived()); }
178
179 template<typename OtherDerived>
181 { return ProductExpr<Derived,OtherDerived>(derived(), b.derived()); }
182
183 template<typename OtherDerived>
185 { return QuotientExpr<Derived,OtherDerived>(derived(), b.derived()); }
186};
187
188template<typename T>
190 // BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class BaseExpr<T>.
192};
193
194/** Represents the actual value of a symbol identified by its tag
195 *
196 * It is the return type of SymbolValue::operator=, and most of the time this is only way it is used.
197 */
198template<typename Tag>
200{
201public:
202 /** Default constructor from the value \a val */
203 SymbolValue(Index val) : m_value(val) {}
204
205 /** \returns the stored value of the symbol */
206 Index value() const { return m_value; }
207protected:
209};
210
211/** Expression of a symbol uniquely identified by the template parameter type \c tag */
212template<typename tag>
213class SymbolExpr : public BaseExpr<SymbolExpr<tag> >
214{
215public:
216 /** Alias to the template parameter \c tag */
217 typedef tag Tag;
218
220
221 /** Associate the value \a val to the given symbol \c *this, uniquely identified by its \c Tag.
222 *
223 * The returned object should be passed to ExprBase::eval() to evaluate a given expression with this specified runtime-time value.
224 */
226 return SymbolValue<Tag>(val);
227 }
228
229 Index eval_impl(const SymbolValue<Tag> &values) const { return values.value(); }
230
231#if EIGEN_HAS_CXX14
232 // C++14 versions suitable for multiple symbols
233 template<typename... Types>
234 Index eval_impl(const std::tuple<Types...>& values) const { return std::get<SymbolValue<Tag> >(values).value(); }
235#endif
236};
237
238template<typename Arg0>
239class NegateExpr : public BaseExpr<NegateExpr<Arg0> >
240{
241public:
242 NegateExpr(const Arg0& arg0) : m_arg0(arg0) {}
243
244 template<typename T>
245 Index eval_impl(const T& values) const { return -m_arg0.eval_impl(values); }
246protected:
247 Arg0 m_arg0;
248};
249
250template<typename Arg0, typename Arg1>
251class AddExpr : public BaseExpr<AddExpr<Arg0,Arg1> >
252{
253public:
254 AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
255
256 template<typename T>
257 Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) + m_arg1.eval_impl(values); }
258protected:
259 Arg0 m_arg0;
260 Arg1 m_arg1;
261};
262
263template<typename Arg0, typename Arg1>
264class ProductExpr : public BaseExpr<ProductExpr<Arg0,Arg1> >
265{
266public:
267 ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
268
269 template<typename T>
270 Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) * m_arg1.eval_impl(values); }
271protected:
272 Arg0 m_arg0;
273 Arg1 m_arg1;
274};
275
276template<typename Arg0, typename Arg1>
277class QuotientExpr : public BaseExpr<QuotientExpr<Arg0,Arg1> >
278{
279public:
280 QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
281
282 template<typename T>
283 Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) / m_arg1.eval_impl(values); }
284protected:
285 Arg0 m_arg0;
286 Arg1 m_arg1;
287};
288
289} // end namespace symbolic
290
291} // end namespace Eigen
292
293#endif // EIGEN_SYMBOLIC_INDEX_H
#define EIGEN_CONSTEXPR
Definition: Macros.h:797
Definition: IntegralConstant.h:52
Definition: SymbolicIndex.h:252
AddExpr(const Arg0 &arg0, const Arg1 &arg1)
Definition: SymbolicIndex.h:254
Arg0 m_arg0
Definition: SymbolicIndex.h:259
Index eval_impl(const T &values) const
Definition: SymbolicIndex.h:257
Arg1 m_arg1
Definition: SymbolicIndex.h:260
Common base class of any symbolic expressions.
Definition: SymbolicIndex.h:78
AddExpr< Derived, NegateExpr< OtherDerived > > operator-(const BaseExpr< OtherDerived > &b) const
Definition: SymbolicIndex.h:176
NegateExpr< Derived > operator-() const
Definition: SymbolicIndex.h:96
QuotientExpr< Derived, OtherDerived > operator/(const BaseExpr< OtherDerived > &b) const
Definition: SymbolicIndex.h:184
AddExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator+(internal::FixedInt< N >(*)()) const
Definition: SymbolicIndex.h:144
Index eval(const T &values) const
Evaluate the expression given the values of the symbols.
Definition: SymbolicIndex.h:89
QuotientExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator/(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:126
AddExpr< Derived, ValueExpr< internal::FixedInt<-N > > > operator-(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:120
QuotientExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator/(internal::FixedInt< N >(*)()) const
Definition: SymbolicIndex.h:153
AddExpr< Derived, ValueExpr< internal::FixedInt<-N > > > operator-(internal::FixedInt< N >(*)()) const
Definition: SymbolicIndex.h:147
friend AddExpr< NegateExpr< Derived >, ValueExpr< internal::FixedInt< N > > > operator-(internal::FixedInt< N >, const BaseExpr &b)
Definition: SymbolicIndex.h:133
ProductExpr< Derived, ValueExpr<> > operator*(Index a) const
Definition: SymbolicIndex.h:102
friend AddExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator+(internal::FixedInt< N >, const BaseExpr &b)
Definition: SymbolicIndex.h:130
friend ProductExpr< ValueExpr< internal::FixedInt< N > >, Derived > operator*(internal::FixedInt< N >, const BaseExpr &b)
Definition: SymbolicIndex.h:136
friend AddExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator+(internal::FixedInt< N >(*)(), const BaseExpr &b)
Definition: SymbolicIndex.h:157
const Derived & derived() const
Definition: SymbolicIndex.h:80
AddExpr< Derived, OtherDerived > operator+(const BaseExpr< OtherDerived > &b) const
Definition: SymbolicIndex.h:172
friend AddExpr< NegateExpr< Derived >, ValueExpr<> > operator-(Index a, const BaseExpr &b)
Definition: SymbolicIndex.h:109
friend QuotientExpr< ValueExpr<>, Derived > operator/(Index a, const BaseExpr &b)
Definition: SymbolicIndex.h:113
friend AddExpr< Derived, ValueExpr<> > operator+(Index a, const BaseExpr &b)
Definition: SymbolicIndex.h:107
ProductExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator*(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:123
ProductExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator*(internal::FixedInt< N >(*)()) const
Definition: SymbolicIndex.h:150
QuotientExpr< Derived, ValueExpr<> > operator/(Index a) const
Definition: SymbolicIndex.h:104
friend AddExpr< NegateExpr< Derived >, ValueExpr< internal::FixedInt< N > > > operator-(internal::FixedInt< N >(*)(), const BaseExpr &b)
Definition: SymbolicIndex.h:160
ProductExpr< Derived, OtherDerived > operator*(const BaseExpr< OtherDerived > &b) const
Definition: SymbolicIndex.h:180
friend ProductExpr< ValueExpr< internal::FixedInt< N > >, Derived > operator*(internal::FixedInt< N >(*)(), const BaseExpr &b)
Definition: SymbolicIndex.h:163
AddExpr< Derived, ValueExpr<> > operator+(Index b) const
Definition: SymbolicIndex.h:98
friend QuotientExpr< ValueExpr< internal::FixedInt< N > >, Derived > operator/(internal::FixedInt< N >(*)(), const BaseExpr &b)
Definition: SymbolicIndex.h:166
AddExpr< Derived, ValueExpr< internal::FixedInt< N > > > operator+(internal::FixedInt< N >) const
Definition: SymbolicIndex.h:117
friend QuotientExpr< ValueExpr< internal::FixedInt< N > >, Derived > operator/(internal::FixedInt< N >, const BaseExpr &b)
Definition: SymbolicIndex.h:139
friend ProductExpr< ValueExpr<>, Derived > operator*(Index a, const BaseExpr &b)
Definition: SymbolicIndex.h:111
AddExpr< Derived, ValueExpr<> > operator-(Index a) const
Definition: SymbolicIndex.h:100
Definition: SymbolicIndex.h:240
NegateExpr(const Arg0 &arg0)
Definition: SymbolicIndex.h:242
Index eval_impl(const T &values) const
Definition: SymbolicIndex.h:245
Arg0 m_arg0
Definition: SymbolicIndex.h:247
Definition: SymbolicIndex.h:265
ProductExpr(const Arg0 &arg0, const Arg1 &arg1)
Definition: SymbolicIndex.h:267
Arg1 m_arg1
Definition: SymbolicIndex.h:273
Index eval_impl(const T &values) const
Definition: SymbolicIndex.h:270
Arg0 m_arg0
Definition: SymbolicIndex.h:272
Definition: SymbolicIndex.h:278
Index eval_impl(const T &values) const
Definition: SymbolicIndex.h:283
Arg1 m_arg1
Definition: SymbolicIndex.h:286
QuotientExpr(const Arg0 &arg0, const Arg1 &arg1)
Definition: SymbolicIndex.h:280
Arg0 m_arg0
Definition: SymbolicIndex.h:285
Expression of a symbol uniquely identified by the template parameter type tag.
Definition: SymbolicIndex.h:214
Index eval_impl(const SymbolValue< Tag > &values) const
Definition: SymbolicIndex.h:229
SymbolValue< Tag > operator=(Index val) const
Associate the value val to the given symbol *this, uniquely identified by its Tag.
Definition: SymbolicIndex.h:225
SymbolExpr()
Definition: SymbolicIndex.h:219
tag Tag
Alias to the template parameter tag.
Definition: SymbolicIndex.h:217
Definition: SymbolicIndex.h:43
Represents the actual value of a symbol identified by its tag.
Definition: SymbolicIndex.h:200
SymbolValue(Index val)
Default constructor from the value val.
Definition: SymbolicIndex.h:203
Index value() const
Definition: SymbolicIndex.h:206
Index m_value
Definition: SymbolicIndex.h:208
EIGEN_CONSTEXPR Index eval_impl(const T &) const
Definition: SymbolicIndex.h:68
Definition: SymbolicIndex.h:52
IndexType m_value
Definition: SymbolicIndex.h:58
IndexType eval_impl(const T &) const
Definition: SymbolicIndex.h:56
ValueExpr(IndexType val)
Definition: SymbolicIndex.h:54
Definition: core.h:1240
Namespace containing all symbols from the Eigen library.
Definition: Core:141
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
Definition: Eigen_Colamd.h:50
b
Definition: data.h:44
Definition: Meta.h:258
Definition: SymbolicIndex.h:189