Theoretica
A C++ numerical and automatic mathematical library
dual.h
Go to the documentation of this file.
1 
5 
6 #ifndef THEORETICA_DUAL_H
7 #define THEORETICA_DUAL_H
8 
9 #ifndef THEORETICA_NO_PRINT
10 #include <sstream>
11 #include <ostream>
12 #endif
13 
14 #include "../core/error.h"
15 #include "../core/constants.h"
16 #include "../algebra/algebra_types.h"
17 
18 
19 namespace theoretica {
20 
21 
28  class dual {
29  public:
30 
31  real a; // Real part
32  real b; // "Dual" part
33 
35  dual() : a(0), b(0) {}
36 
38  dual(real real_part, real dual_part)
39  : a(real_part), b(dual_part) {}
40 
42  dual(real real_part)
43  : a(real_part), b(0) {}
44 
45  ~dual() = default;
46 
48  dual(const vec2& v) {
49  a = v[0];
50  b = v[1];
51  }
52 
54  inline dual& operator=(const vec2& v) {
55  a = v[0];
56  b = v[1];
57  return *this;
58  }
59 
61  inline dual& operator=(real x) {
62  a = x;
63  b = 0;
64  return *this;
65  }
66 
68  inline dual& operator=(const std::array<real, 2>& v) {
69  a = v[0];
70  b = v[1];
71  return *this;
72  }
73 
75  inline const real& Re() const {
76  return a;
77  }
78 
80  inline real& Re() {
81  return a;
82  }
83 
85  inline friend real Re(const dual& d) {
86  return d.a;
87  }
88 
89 
91  inline friend real& Re(dual& d) {
92  return d.a;
93  }
94 
96  inline const real& Dual() const {
97  return b;
98  }
99 
101  inline real& Dual() {
102  return b;
103  }
104 
106  inline friend real Dual(const dual& d) {
107  return d.b;
108  }
109 
110 
112  inline friend real& Dual(dual& d) {
113  return d.b;
114  }
115 
117  inline dual conjugate() const {
118  return dual(a, -b);
119  }
120 
122  inline dual inverse() const {
123 
124  if(a == 0) {
125  TH_MATH_ERROR("dual::inverse", 0, DIV_BY_ZERO);
126  return dual(nan(), nan());
127  }
128 
129  return dual(1.0 / a, -b / square(a));
130  }
131 
133  inline dual operator+() const {
134  return dual(a, b);
135  }
136 
138  inline dual operator+(const dual& other) const {
139  return dual(a + other.a, b + other.b);
140  }
141 
143  inline dual operator+(real r) const {
144  return dual(a + r, b);
145  }
146 
148  inline dual operator-() const {
149  return dual(-a, -b);
150  }
151 
153  inline dual operator-(const dual& other) const {
154  return dual(a - other.a, b - other.b);
155  }
156 
158  inline dual operator-(real r) const {
159  return dual(a - r, b);
160  }
161 
163  inline dual operator*(const dual& other) const {
164  return dual(a * other.a, a * other.b + b * other.a);
165  }
166 
168  inline dual operator*(real r) const {
169  return dual(a * r, b * r);
170  }
171 
173  inline dual operator/(const dual& other) const {
174  return dual(a / other.a,
175  (b * other.a - a * other.b) / square(other.a));
176  }
177 
179  inline dual operator/(real r) const {
180  return dual(a / r, b / r);
181  }
182 
183 
185  inline dual& operator+=(const dual& other) {
186 
187  a += other.a;
188  b += other.b;
189  return *this;
190  }
191 
192 
194  inline dual& operator+=(real r) {
195 
196  a += r;
197  return *this;
198  }
199 
201  inline dual& operator-=(const dual& other) {
202 
203  a -= other.a;
204  b -= other.b;
205  return *this;
206  }
207 
209  inline dual& operator-=(real r) {
210 
211  a -= r;
212  return *this;
213  }
214 
216  inline dual& operator*=(const dual& other) {
217 
218  a = (a * other.a);
219  b = (a * other.b) + (b * other.a);
220  return *this;
221  }
222 
224  inline dual& operator*=(real r) {
225 
226  a *= r;
227  b *= r;
228  return *this;
229  }
230 
232  inline dual& operator/=(const dual& other) {
233 
234  a = (a / other.a);
235  b = (b * other.a - a * other.b) / square(other.a);
236  return *this;
237  }
238 
240  inline dual& operator/=(real r) {
241 
242  if(r == 0) {
243  TH_MATH_ERROR("dual::operator/=", 0, DIV_BY_ZERO);
244  a = nan();
245  b = nan();
246  return *this;
247  }
248 
249  a /= r;
250  b /= r;
251 
252  return *this;
253  }
254 
255 
258  inline bool operator==(const dual& other) {
259  return (a == other.a) && (b == other.b);
260  }
261 
262 
264  inline vec2 to_vec() const {
265  vec2 res;
266  res[0] = a;
267  res[1] = b;
268  return res;
269  }
270 
272  inline void from_vec(const vec2& v) {
273  a = v[0];
274  b = v[1];
275  }
276 
277 
279  inline mat2 to_mat() const {
280 
281  mat2 m;
282  m.at(0, 0) = a;
283  m.at(1, 0) = 0;
284  m.at(0, 1) = b;
285  m.at(1, 1) = a;
286  return m;
287  }
288 
289 
290  // Friend operators to enable equations of the form
291  // (real) op. (dual)
292 
293  inline friend dual operator+(real a, const dual& d) {
294  return d + a;
295  }
296 
297  inline friend dual operator-(real a, const dual& d) {
298  return -d + a;
299  }
300 
301  inline friend dual operator*(real a, const dual& d) {
302  return d * a;
303  }
304 
305  inline friend dual operator/(real a, const dual& d) {
306  return dual(a, 0) / d;
307  }
308 
309 
310 #ifndef THEORETICA_NO_PRINT
311 
314  inline std::string to_string(const std::string& epsilon = "e") const {
315 
316  std::stringstream res;
317 
318  res << a;
319  res << (b >= 0 ? " + " : " - ");
320  res << abs(b) << epsilon;
321 
322  return res.str();
323  }
324 
325 
327  inline operator std::string() {
328  return to_string();
329  }
330 
331 
334  inline friend std::ostream& operator<<(std::ostream& out, const dual& obj) {
335  return out << obj.to_string();
336  }
337 
338 #endif
339 
340  };
341 
342 }
343 
344 
345 #endif
Dual number class.
Definition: dual.h:28
vec2 to_vec() const
Convert a dual number to a vector.
Definition: dual.h:264
dual operator/(const dual &other) const
Dual division.
Definition: dual.h:173
dual & operator=(real x)
Initialize a dual number from a real number.
Definition: dual.h:61
dual(const vec2 &v)
Initialize from a vec2.
Definition: dual.h:48
dual & operator*=(real r)
Multiply this dual number by a real number.
Definition: dual.h:224
dual conjugate() const
Get the dual conjugate.
Definition: dual.h:117
dual & operator-=(real r)
Subtract a real number from this dual number.
Definition: dual.h:209
dual operator*(real r) const
Multiply a dual number by a real number.
Definition: dual.h:168
friend std::ostream & operator<<(std::ostream &out, const dual &obj)
Stream the dual number in string representation to an output stream (std::ostream)
Definition: dual.h:334
dual & operator-=(const dual &other)
Subtract a real number from this one.
Definition: dual.h:201
dual operator-(const dual &other) const
Subtract two dual numbers.
Definition: dual.h:153
std::string to_string(const std::string &epsilon="e") const
Convert the dual number to string representation.
Definition: dual.h:314
real & Dual()
Return dual part.
Definition: dual.h:101
mat2 to_mat() const
Convert a dual number to matrix form.
Definition: dual.h:279
friend real & Dual(dual &d)
Extract the real part of the dual number.
Definition: dual.h:112
dual operator+(const dual &other) const
Sum two dual numbers.
Definition: dual.h:138
dual & operator*=(const dual &other)
Multiply this dual number by another one.
Definition: dual.h:216
friend real & Re(dual &d)
Extract the real part of the dual number.
Definition: dual.h:91
dual inverse() const
Get the inverse of a dual number.
Definition: dual.h:122
friend real Re(const dual &d)
Extract the real part of the dual number.
Definition: dual.h:85
void from_vec(const vec2 &v)
Initialize from a vector.
Definition: dual.h:272
real & Re()
Return real part.
Definition: dual.h:80
dual operator/(real r) const
Divide a dual number by a real number.
Definition: dual.h:179
dual & operator/=(const dual &other)
Divide this dual number by another one.
Definition: dual.h:232
dual operator-() const
Get the opposite of a dual number.
Definition: dual.h:148
const real & Re() const
Return real part.
Definition: dual.h:75
dual operator-(real r) const
Subtract a real number from a dual number.
Definition: dual.h:158
bool operator==(const dual &other)
Check whether two dual numbers have the same real and dual parts.
Definition: dual.h:258
dual(real real_part, real dual_part)
Initialize from two real numbers.
Definition: dual.h:38
dual(real real_part)
Initialize from a real number.
Definition: dual.h:42
dual operator*(const dual &other) const
Multiply two dual numbers.
Definition: dual.h:163
dual operator+() const
Identity (for consistency)
Definition: dual.h:133
dual operator+(real r) const
Sum a real number to a dual number.
Definition: dual.h:143
dual & operator=(const std::array< real, 2 > &v)
Initialize a dual number from a std::array.
Definition: dual.h:68
dual & operator+=(const dual &other)
Add a dual number to this one.
Definition: dual.h:185
dual()
Default constructor, initialize with null values.
Definition: dual.h:35
friend real Dual(const dual &d)
Extract the real part of the dual number.
Definition: dual.h:106
dual & operator+=(real r)
Sum a real number to this dual number.
Definition: dual.h:194
const real & Dual() const
Return dual part.
Definition: dual.h:96
dual & operator=(const vec2 &v)
Initialize a dual number from a vec2.
Definition: dual.h:54
dual & operator/=(real r)
Divide a dual number by a real number.
Definition: dual.h:240
Type & at(unsigned int i, unsigned int j)
Accesses the element at the given row and column.
Definition: mat.h:487
A statically allocated N-dimensional vector with elements of the given type.
Definition: vec.h:92
#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:219
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
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition: dual2_functions.h:198
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition: dual2_functions.h:23
real nan()
Return a quiet NaN number in floating point representation.
Definition: error.h:54