UPDATE: deprecated in favor of: cppduals
Under Construction!
Template header library for dual numbers in C++. Dual numbers are related to complex numbers, but ε is nilpotent (ε * ε = 0). Nesting provides hyperdual numbers, and hyperhyperdual numbers, etc...
Also compiles under CUDA.
Using dual numbers in place of basic types provides a simple way to compute the derivative of a function, because:
\f$ f(x + ε y) = f(x) + ε f'(x) y \f$
Thus, to calculate \f$ f'(3) \f$, set \f$ y = 1 \f$, \f$ z = (3 + ε 1) \f$ and take the \f$ ε\f$-part of \f$ f(z) \f$ => \f$ epart(f(z)) := f'(3) \f$
Shortcuts into the docs:
namespace cxxduals
cxxduals::dual
cxxduals::sin
A simple example calculating (xx) and the derivative of (xx):
#include <iostream>
#include <cxxduals/dual>
using namespace cxxduals;
int main(int argc, char *argv[])
{
dual<double> x;
x = {3,1};
std::cout << "x=" << x << "\n";
std::cout << "x*x=" << x*x << "\n";
std::cout << "epart(x*x) = d(x*x)/dx = " << epart(x*x) << "\n";
}
Produces:
x=(3 + e1*1)
x*x=(9 + e1*6)
epart(x*x) = d(x*x)/dx = 6
Before including the header, some "#defines" will modify what's done by the header:
#define CXXDUALS_NO_LIMITS // disable specialization of std::numeric_limits<>
#define CXXDUALS_NO_TYPEDEFS // disable typedefs for `dualf,duald,dualld,dualcf,dualcd,dualcld`
#define CXXDUALS_EIGEN // force inclusion of Eigen interface (normally auto-detected)
#include <cxxduals/dual>
See the examples in tests/* and examples/*
- lots more tests
- let the value_type be a std::vector
- add printer to show the number in linear form (as a matrix)
- define
dot(dual<complex<> >
,dual<complex<> >)
andnorm(dual<complex<> >)
- currently only tested on c++11, should make sure older c++ works as much as possible too
- support the other algebras, and their various nestings: (how easy
would this be???)
- (ε * ε) = -1 ("complex number")
- (ε * ε) = 1 ("double nunmber" / "split complex number")
- try to minimize subtractive cancellation within the library
- support & test multi-precision container types
Although it has diverged significantly, this started as a dual-number class implementation by Jeff A. Fike found here: http://adl.stanford.edu/hyperdual/.
It's been generalized for nesting, cleaned up for easier use in C++, and made suitable for use in Eigen matrices.
- https://en.wikipedia.org/wiki/Dual_number
- Fike's thesis
- Piponi, D. (2004). Automatic Differentiation, C++ Templates, and Photogrammetry. Journal of Graphics Tools, 9(4), 41–55. doi:10.1080/10867651.2004.10504901
- http://people.rit.edu/harkin/research/articles/generalized_complex_numbers.pdf
- https://www.ams.org/journals/tran/1960-094-03/S0002-9947-1960-0146681-0/S0002-9947-1960-0146681-0.pdf
- http://www.dtecta.com/files/GDC13_vandenBergen_Gino_Math_Tut.pdf
- https://hal.archives-ouvertes.fr/hal-01114178/document
- http://darioizzo.github.io/audi/gdual.html https://github.com/darioizzo/audi/blob/master/include/audi/gdual.hpp
- https://github.com/ceres-solver/ceres-solver/blob/master/include/ceres/jet.h
- https://github.com/dtecta/motion-toolkit/blob/master/moto/Dual.hpp
- https://github.com/JuliaDiff/DualNumbers.jl
- https://github.com/KyushuUniversityMathematics/iPad-ProbeDeformer/blob/master/iPad-ProbeDeformer/DCN.h
This work was partially supported by DFG/ANR grant (?) and the TUM School of Education.
MIT, same as the original Fike code.