Boost logo

Boost :

Subject: [boost] Automatic differentiation (and complex numbers) with lazy component evaluation
From: Hal Finkel (half_at_[hidden])
Date: 2010-04-26 12:27:37


Hello,

I've uploaded to a subversion repository on SourceForge my Lazy Types
library. This library provides template classes for dual numbers (used
for automatic differentiation) and complex numbers. Expression templates
are used in order to evaluate only those components which are actually
needed. All of the standard-library math functions (and arithmetic
operators) are supported.

http://lazytypes.sourceforge.net/
http://sourceforge.net/projects/lazytypes

The dual-number formalism is especially useful because it enables the
compiler to generate analytic expressions for the derivative of "any"
function (where "any" is restricted to those functions which compute
using operators and functions the library knows about, which include all
of the standard ones). These are *not* finite-difference approximations,
but exact answers (to machine precision). Functions which use
conditional statements, loops, etc. are fine, although the derivative
might not have a meaning if evaluated at a point of discontinuity.

This code has been released under the BSL 1.0. Although some Boost
headers are used (enable_if, type_traits, etc.), Boost.Proto is not
used. Is there any interest in having these libraries in Boost:

1. As-is (plus more documentation, tests, namespace change, etc.)
2. Only if rewritten to use Boost.Proto (which I am willing to do, so
long as the performance of the current implementation can be matched).

The project Wiki page (to which http://lazytypes.sourceforge.net/
redirects) has some documentation and usage examples. Here is a quick
example of taking the derivative (and the second derivative) of a
multivariate function:

#include <lazy_types.hpp>
namespace lt = lazy_types;

...

template <typename X>
X f(X &v1, X &v2) {
        using namespace lt;
        return pow(v1, 3) + pow<3>(v1) + pow<2>(v2 + v1) + v2*v1/5.0 +
3.0;
}
// A pow<> template is provided which works with the expression-template
types.

...

lt::dual<double, 2> fv1(2.0, 0), fv2(4.0, 1);
lt::dual<double, 2> fv = f(fv1, fv2);
std::cout << fv << " " << fv.eps(0) << " " << fv.eps(1) << std::endl;
// This computes the derivative of the function f with respect to both
of its arguments evaluated at the point where the function itself has
been evaluated.

// An example of computing the second derivative:
template <typename X>
X df(X &v1, X &v2, size_t ei) {
        lt::dual<X, 2> d1(v1, 0);
        lt::dual<X, 2> d2(v2, 1);
        return f(d1, d2).eps(ei);
}

lt::dual<double, 2> df0 = df(fv1, fv2, 0);
lt::dual<double, 2> df1 = df(fv1, fv2, 1);
std::cout << df0.eps(0) << " " << df0.eps(1) << std::endl;
std::cout << df1.eps(0) << " " << df1.eps(1) << std::endl;

If there is interest in adding these types (or some rewritten version of
them) to Boost, please let me know, and I'll work on getting the library
ready for review.

Sincerely,
Hal Finkel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk