Skip to content
This repository has been archived by the owner on Apr 28, 2019. It is now read-only.
/ cxxduals Public archive

Template library for dual numbers in c++ [deprecated]

License

Notifications You must be signed in to change notification settings

tesch1/cxxduals

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UPDATE: deprecated in favor of: cppduals

cxxduals

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.

Build Status Coverage Status

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

Usage

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/*

TODO

  • 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<> >) and norm(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???)
  • try to minimize subtractive cancellation within the library
  • support & test multi-precision container types

History

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.

References

Other implementations

Acknowledgements

This work was partially supported by DFG/ANR grant (?) and the TUM School of Education.

License

MIT, same as the original Fike code.

Please report (and/or fix) any problems you find!

About

Template library for dual numbers in c++ [deprecated]

Resources

License

Stars

Watchers

Forks

Packages