Theoretica
A C++ numerical and automatic mathematical library
Loading...
Searching...
No Matches
autodiff.h
Go to the documentation of this file.
1
5
6#ifndef THEORETICA_AUTODIFF_H
7#define THEORETICA_AUTODIFF_H
8
9#include "dual.h"
10#include "dual2.h"
11#include "multidual.h"
12#include "../algebra/vec.h"
13#include "../algebra/mat.h"
14#include "../core/error.h"
15#include "../core/core_traits.h"
16#include "./autodiff_types.h"
17
18#include <functional>
19
20
21namespace theoretica {
22
24 namespace autodiff {
25
26
27 // Univariate automatic differentiation
28
29
37 template <
38 typename DualFunction = std::function<dual(dual)>,
40 >
41 inline real deriv(DualFunction f, real x) {
42 return f(dual(x, 1.0)).Dual();
43 }
44
45
54 template <
55 typename DualFunction = std::function<dual(dual)>,
57 >
58 inline auto deriv(DualFunction f) {
59
60 return [f](real x) -> real {
61 return autodiff::deriv(f, x);
62 };
63 }
64
65
73 template <
74 typename Dual2Function = std::function<dual2(dual2)>,
76 >
78 return f(dual2(x, 1.0, 0.0)).Dual2();
79 }
80
81
90 template <
91 typename Dual2Function = std::function<dual2(dual2)>,
93 >
94 inline auto deriv2(Dual2Function f) {
95
96 return [f](real x) -> real {
97 return autodiff::deriv2(f, x);
98 };
99 }
100
101
102 // Differential operators
103
104
109 template <
110 typename MultidualType,
111 typename Vector = vec<real>
112 >
113 inline auto make_autodiff_arg(const Vector& x) {
114
115 constexpr size_t N = MultidualType::vector_argument;
117 arg.resize(x.size());
118
119 // Iterate over each element, setting the dual part to
120 // the i-th element of the canonical base
121 for (unsigned int i = 0; i < x.size(); ++i) {
122 arg[i] = MultidualType(
123 x[i], vec<real, N>::euclidean_base(i, x.size())
124 );
125 }
126
127 return arg;
128 }
129
130
143 template <
144 typename Function, typename Vector = vec<real>,
147 >
148 inline auto gradient(Function f, const Vector& x) {
149
150 // Extract the return type of the function
152
153 return f(make_autodiff_arg<R>(x)).Dual();
154 }
155
156
168 template <
169 typename Function,
171 >
172 inline auto gradient(Function f) {
173
174 constexpr size_t N = return_type_t<Function>::vector_argument;
175
176 return [f](vec<real, N> x) {
177 return gradient(f, x);
178 };
179 }
180
181
193 template <
194 typename Function, typename Vector = vec<real>,
197 >
198 inline real divergence(Function f, const Vector& x) {
199
201 MultidualT d = f(MultidualT::make_argument(x));
202
203 real div = 0;
204 for (unsigned int i = 0; i < d.v.size(); ++i)
205 div += d.v[i];
206
207 return div;
208 }
209
210
221 template <
222 typename Function,
224 >
225 inline auto divergence(Function f) {
226
227 constexpr size_t N = return_type_t<Function>::vector_argument;
228
229 return [f](vec<real, N> x) {
230 return divergence(f, x);
231 };
232 }
233
234
242 template<unsigned int N = 0, unsigned int M = 0>
244 vec<multidual<N>, M>(*f)(vec<multidual<N>, N>), const vec<real, N>& x) {
245
247
248 // Construct the jacobian matrix
250 J.resize(res.size(), x.size());
251
252 for (unsigned int j = 0; j < J.rows(); ++j)
253 for (unsigned int i = 0; i < res[j].v.size(); ++i)
254 J(j, i) = res[j].v[i];
255
256 return J;
257 }
258
259
267 template<unsigned int N = 0, unsigned int M = 0>
268 inline auto jacobian(
269 vec<multidual<N>, M>(*f)(vec<multidual<N>, N>)) {
270
271 return [f](vec<real, N> x) {
272 return jacobian(f, x);
273 };
274 }
275
276
285 template<unsigned int N = 0>
287 vec<multidual<N>, N>(*f)(vec<multidual<N>, N>), const vec<real, N>& x) {
288
289 if(x.size() != 3) {
290 TH_MATH_ERROR("th::curl", x.size(), INVALID_ARGUMENT);
291 return vec<real, N>(nan(), x.size());
292 }
293
295 J.resize(3, 3);
296
298 res.resize(3);
299
300 res[0] = J(2, 1) - J(1, 2);
301 res[1] = J(0, 2) - J(2, 0);
302 res[2] = J(1, 0) - J(0, 1);
303
304 return res;
305 }
306
307
316 template<unsigned int N = 0>
317 inline auto curl(vec<multidual<N>, N>(*f)(vec<multidual<N>, N>)) {
318
319 return [f](vec<real, N> x) {
320 return curl(f, x);
321 };
322 }
323
324
340 template<unsigned int N = 0>
342 const vec<real, N>& x, const vec<real, N>& v) {
343
344 return v * dot(v, gradient(f, x));
345 }
346
347
364 template<unsigned int N = 0>
366 multidual<N>(*f)(vec<multidual<N>, N>), const vec<real, N>& v) {
367
368 return [f, v](vec<real, N> x) {
369 return directional_derivative(f, x, v);
370 };
371 }
372
373
382 template<unsigned int N = 0>
384
385 real res = 0;
387 d.resize(x.size());
388
389 for (unsigned int i = 0; i < x.size(); ++i)
390 d[i].a = x[i];
391
392 for (unsigned int i = 0; i < x.size(); ++i) {
393 d[i].b = 1;
394 res += f(d).Dual2();
395 d[i].b = 0;
396 }
397
398 return res;
399 }
400
401
410 template<unsigned int N = 0>
411 inline auto laplacian(dual2(*f)(vec<dual2, N>)) {
412
413 return [f](vec<real, N> x) {
414 return laplacian(f, x);
415 };
416 }
417
418
433 template<unsigned int N = 0>
438
439 return gradient(f, eta)
440 * mat<real, N, N>::symplectic(eta.size(), eta.size())
441 * gradient(H, eta);
442 }
443
444 }
445}
446
447#endif
Types and traits for automatic differentiation.
Second order dual number class.
Definition dual2.h:29
real Dual2() const
Return second order dual part.
Definition dual2.h:95
Dual number class.
Definition dual.h:28
A generic matrix with a fixed number of rows and columns.
Definition mat.h:136
Multidual number algebra for functions of the form .
Definition multidual.h:26
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:416
TH_CONSTEXPR unsigned int size() const
Returns the size of the vector (N)
Definition vec.h:406
Second order dual number class.
Dual number class.
#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
Multidual numbers.
vec< real, N > curl(vec< multidual< N >, N >(*f)(vec< multidual< N >, N >), const vec< real, N > &x)
Compute the curl for a given of a vector field defined by using automatic differentiation.
Definition autodiff.h:286
real sturm_liouville(multidual< N >(*f)(vec< multidual< N >, N >), multidual< N >(*H)(vec< multidual< N >, N >), vec< real, N > eta)
Compute the Sturm-Liouville operator on a generic function of the form with respect to a given Hamil...
Definition autodiff.h:434
real deriv(DualFunction f, real x)
Compute the derivative of a function at the given point using univariate automatic differentiation.
Definition autodiff.h:41
vec< real, N > directional_derivative(multidual< N >(*f)(vec< multidual< N >, N >), const vec< real, N > &x, const vec< real, N > &v)
Compute the directional derivative of a generic function of the form .
Definition autodiff.h:341
real laplacian(dual2(*f)(vec< dual2, N >), const vec< real, N > &x)
Compute the Laplacian differential operator for a generic function of the form at a given $\vec x$.
Definition autodiff.h:383
real deriv2(Dual2Function f, real x)
Compute the second derivative of a function at the given point using univariate automatic differentia...
Definition autodiff.h:77
auto gradient(Function f, const Vector &x)
Compute the gradient for a given of a scalar field of the form using automatic differentiation.
Definition autodiff.h:148
auto make_autodiff_arg(const Vector &x)
Prepare a vector of multidual numbers in "canonical" form, where the i-th element of the vector has a...
Definition autodiff.h:113
mat< real, M, N > jacobian(vec< multidual< N >, M >(*f)(vec< multidual< N >, N >), const vec< real, N > &x)
Compute the jacobian of a vector field of the form .
Definition autodiff.h:243
real divergence(Function f, const Vector &x)
Compute the divergence for a given of a scalar field of the form using automatic differentiation.
Definition autodiff.h:198
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
typename _internal::func_helper< Function >::return_type return_type_t
Extract the return type of a Callable object, such as a function pointer or lambda function.
Definition core_traits.h:255
std::remove_reference_t< decltype(std::declval< Structure >()[0])> vector_element_t
Extract the type of a vector (or any indexable container) from its operator[].
Definition core_traits.h:134
real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:54