Theoretica
Mathematical Library
Loading...
Searching...
No Matches
multidual.h
Go to the documentation of this file.
1#ifndef THEORETICA_MULTIDUAL_H
2#define THEORETICA_MULTIDUAL_H
3
4
8
9#ifndef THEORETICA_NO_PRINT
10#include <sstream>
11#include <ostream>
12#endif
13
14#include "../algebra/vec.h"
15#include "../algebra/mat.h"
16
17
18namespace theoretica {
19
25 template<unsigned int N = 0>
26 class multidual {
27
28 public:
29
32
35 vec<real, N> v;
36
37 // The template argument of the vector type used
38 static constexpr size_t vector_argument = N;
39
40
43 multidual() : a(0) {}
44
45
48 multidual(real r, vec<real, N> u) : a(r), v(u) {}
49
50
53 multidual(real r) : a(r), v(vec<real, N>()) {}
54
55 ~multidual() = default;
56
57
60 a = x;
61 v = vec<real, N>();
62 return *this;
63 }
64
65
67 inline real Re() const {
68 return a;
69 }
70
71
73 inline real& Re() {
74 return a;
75 }
76
77
79 inline vec<real, N> Dual() const {
80 return v;
81 }
82
83
85 inline vec<real, N>& Dual() {
86 return v;
87 }
88
89
93 inline real Dual(unsigned int i) const {
94 return v[i];
95 }
96
97
101 inline real& Dual(unsigned int i) {
102 return v[i];
103 }
104
105
107 inline multidual conjugate() const {
108 return multidual(a, -v);
109 }
110
111
113 inline multidual inverse() const {
114
115 if(a == 0) {
116 TH_MATH_ERROR("multidual::inverse", 0, DIV_BY_ZERO);
117 return multidual(nan(), vec<real, N>(N, nan()));
118 }
119
120 return multidual(1.0 / a, v * (-1 / (a * a)));
121 }
122
123
125 inline multidual operator+() const {
126 return multidual(a, v);
127 }
128
129
131 inline multidual operator+(const multidual& other) const {
132 return multidual(a + other.a, v + other.v);
133 }
134
135
137 inline multidual operator+(real r) const {
138 return multidual(a + r, v);
139 }
140
141
143 inline multidual operator-() const {
144 return multidual(-a, -v);
145 }
146
147
149 inline multidual operator-(const multidual& other) const {
150 return multidual(a - other.a, v - other.v);
151 }
152
153
155 inline multidual operator-(real r) const {
156 return multidual(a - r, v);
157 }
158
159
161 inline multidual operator*(const multidual& other) const {
162 return multidual(a * other.a, other.v * a + v * other.a);
163 }
164
165
167 inline multidual operator*(real r) const {
168 return multidual(a * r, v * r);
169 }
170
171
173 inline multidual operator/(const multidual& other) const {
174
175 if(a == 0) {
176 TH_MATH_ERROR("multidual::operator/", 0, DIV_BY_ZERO);
177 return multidual(nan(), vec<real, N>(N, nan()));
178 }
179
180 return multidual(a / other.a,
181 (v * other.a - other.v * a) / (other.a * other.a));
182 }
183
185 inline multidual operator/(real r) const {
186 return multidual(a / r, v / r);
187 }
188
189
191 inline multidual& operator+=(const multidual& other) {
192
193 a += other.a;
194 v += other.v;
195 return *this;
196 }
197
198
201
202 a += r;
203 return *this;
204 }
205
207 inline multidual& operator-=(const multidual& other) {
208
209 a -= other.a;
210 v -= other.v;
211 return *this;
212 }
213
216
217 a -= r;
218 return *this;
219 }
220
222 inline multidual& operator*=(const multidual& other) {
223
224 a = (a * other.a);
225 v = (other.v * a) + (v * other.a);
226 return *this;
227 }
228
231
232 a *= r;
233 v *= r;
234 return *this;
235 }
236
238 inline multidual& operator/=(const multidual& other) {
239
240 a = (a / other.a);
241 v = (v * other.a - other.v * a) / (other.a * other.a);
242 return *this;
243 }
244
247
248 if(r == 0) {
249 TH_MATH_ERROR("multidual::operator/=", 0, DIV_BY_ZERO);
250 a = nan();
251 v = vec<real, N>(N, nan());
252 return *this;
253 }
254
255 a /= r;
256 v /= r;
257
258 return *this;
259 }
260
261
264 inline bool operator==(const multidual& other) {
265 return (a == other.a) && (v == other.v);
266 }
267
268
272 inline static vec<multidual<N>, N> make_argument(
273 const vec<real, N>& x) {
274
275 vec<multidual<N>, N> arg;
276 arg.resize(x.size());
277
278 for (unsigned int i = 0; i < x.size(); ++i)
279 arg[i] = multidual<N>(
281 );
282
283 return arg;
284 }
285
286
289 inline static vec<real, N> extract_real(
290 const vec<multidual<N>, N>& v) {
291
292 vec<real, N> x;
293 x.resize(v.size());
294
295 for (unsigned int i = 0; i < N; ++i)
296 x[i] = v[i].Re();
297
298 return x;
299 }
300
301
305 inline static mat<real, N, N> extract_dual(
306 const vec<multidual<N>, N>& v) {
307
308 mat<real, N, N> J;
309 J.resize(v.size(), v.size());
310
311 for (unsigned int i = 0; i < N; ++i)
312 for (unsigned int j = 0; j < N; ++j)
313 J(j, i) = v[j].Dual(i);
314
315 return J;
316 }
317
318
322 inline static void extract(
323 const vec<multidual<N>, N>& v,
324 vec<real, N>& x,
325 mat<real, N, N>& J) {
326
327 for (unsigned int i = 0; i < N; ++i) {
328
329 for (unsigned int j = 0; j < N; ++j)
330 J(j, i) = v[j].Dual(i);
331
332 x[i] = v[i].Re();
333 }
334 }
335
336
339 unsigned int size() const {
340 return v.size();
341 }
342
343
346 inline void resize(unsigned int size) {
347 v.resize(size);
348 }
349
350
351 // Friend operators to enable equations of the form
352 // (real) op. (multidual)
353
354 inline friend multidual operator+(real a, const multidual& d) {
355 return d + a;
356 }
357
358 inline friend multidual operator-(real a, const multidual& d) {
359 return -d + a;
360 }
361
362 inline friend multidual operator*(real a, const multidual& d) {
363 return d * a;
364 }
365
366 inline friend multidual operator/(real a, const multidual& d) {
367 return a * d.inverse();
368 }
369
370
371#ifndef THEORETICA_NO_PRINT
372
375 inline std::string to_string(const std::string& epsilon = "e") const {
376
377 std::stringstream res;
378 res << a << " + " << v << epsilon;
379
380 return res.str();
381 }
382
383
385 inline operator std::string() {
386 return to_string();
387 }
388
389
392 inline friend std::ostream& operator<<(std::ostream& out, const multidual& obj) {
393 return out << obj.to_string();
394 }
395
396#endif
397
398 };
399
400}
401
402#endif
Multidual number algebra for functions of the form .
Definition multidual.h:26
multidual operator+(const multidual &other) const
Sum two multidual numbers.
Definition multidual.h:131
real & Dual(unsigned int i)
Access the i-th element of the multidual part, corresponding to the i-th independent variable in auto...
Definition multidual.h:101
multidual operator+() const
Identity (for consistency)
Definition multidual.h:125
multidual operator/(const multidual &other) const
Dual division.
Definition multidual.h:173
bool operator==(const multidual &other)
Check whether two multidual numbers have the same real and multidual parts.
Definition multidual.h:264
multidual & operator*=(real r)
Multiply this multidual number by a real number.
Definition multidual.h:230
multidual & operator-=(real r)
Subtract a real number from this multidual number.
Definition multidual.h:215
multidual & operator*=(const multidual &other)
Multiply this multidual number by another one.
Definition multidual.h:222
multidual & operator/=(const multidual &other)
Divide this multidual number by another one.
Definition multidual.h:238
multidual & operator+=(const multidual &other)
Sum a real number to this one.
Definition multidual.h:191
real Dual(unsigned int i) const
Get the i-th element of the multidual part, corresponding to the i-th independent variable in automat...
Definition multidual.h:93
vec< real, N > v
The dual part of the multidimensional dual number as a real vector.
Definition multidual.h:35
multidual & operator-=(const multidual &other)
Subtract a real number from this one.
Definition multidual.h:207
friend std::ostream & operator<<(std::ostream &out, const multidual &obj)
Stream the multidual number in string representation to an output stream (std::ostream)
Definition multidual.h:392
unsigned int size() const
Get the number of independent variables associated with the multidual number.
Definition multidual.h:339
multidual operator-(real r) const
Subtract a real number from a multidual number.
Definition multidual.h:155
multidual operator*(const multidual &other) const
Multiply two multidual numbers.
Definition multidual.h:161
multidual & operator+=(real r)
Sum a real number to this multidual number.
Definition multidual.h:200
multidual operator*(real r) const
Multiply a multidual number by a real number.
Definition multidual.h:167
multidual(real r, vec< real, N > u)
Construct a multidual number from a real number and an N dimensional vector.
Definition multidual.h:48
real a
The real part of the multidimensional dual number.
Definition multidual.h:31
multidual operator/(real r) const
Divide a multidual number by a real number.
Definition multidual.h:185
multidual & operator/=(real r)
Divide a multidual number by a real number.
Definition multidual.h:246
vec< real, N > & Dual()
Access the multidual part.
Definition multidual.h:85
static vec< real, N > extract_real(const vec< multidual< N >, N > &v)
Extract the real vector from a vector of multidual numbers as a vec<real, N>
Definition multidual.h:289
static vec< multidual< N >, N > make_argument(const vec< real, N > &x)
Construct an N-dimensional vector of multidual numbers to be passed as argument to a multidual functi...
Definition multidual.h:272
vec< real, N > Dual() const
Get the multidual part.
Definition multidual.h:79
multidual(real r)
Construct a multidual number from a real number.
Definition multidual.h:53
real Re() const
Get the real part.
Definition multidual.h:67
std::string to_string(const std::string &epsilon="e") const
Convert the multidual number to string representation.
Definition multidual.h:375
static mat< real, N, N > extract_dual(const vec< multidual< N >, N > &v)
Extract the dual matrix (Jacobian) from a vector of multidual numbers as a mat<N, N>
Definition multidual.h:305
multidual inverse() const
Get the inverse of a multidual number.
Definition multidual.h:113
multidual operator+(real r) const
Sum a real number to a multidual number.
Definition multidual.h:137
multidual operator-() const
Get the opposite of a multidual number.
Definition multidual.h:143
static void extract(const vec< multidual< N >, N > &v, vec< real, N > &x, mat< real, N, N > &J)
Extract the real vector and dual matrix from a vector of multidual numbers as a vec<real,...
Definition multidual.h:322
void resize(unsigned int size)
Change the size of the dual part of the number (only for dynamically allocated vectors)
Definition multidual.h:346
multidual conjugate() const
Get the multidual conjugate.
Definition multidual.h:107
real & Re()
Access the real part.
Definition multidual.h:73
multidual()
Construct a multidual number as .
Definition multidual.h:43
multidual & operator=(real x)
Initialize a multidual number from a real number.
Definition multidual.h:59
multidual operator-(const multidual &other) const
Subtract two multidual numbers.
Definition multidual.h:149
A statically allocated N-dimensional vector with elements of the given type.
Definition vec.h:92
void resize(size_t n) const
Compatibility function to allow for allocation or resizing of dynamic vectors.
Definition vec.h:422
TH_CONSTEXPR unsigned int size() const
Returns the size of the vector (N)
Definition vec.h:412
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition error.h:225
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
double real
A real number, defined as a floating point type.
Definition constants.h:198
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:54