This is an automatic differentiation library written in D supporting one-dimensional, real-valued derivatives of arbitrary order. It is not a high performance library. It could become one; I'm not against that by any means! It's just that I originally built this library after learning about automatic differentiation. The elegance of the concept struct me. I had to implement it.
- supports all of D's arithmetic operators
- supports the same set of functions as
core.math - supports the same set of functions as
std.math - supports the same set of functions as
std.mathspecial - supports arbitrary order differentiation, must be fixed at compile time
This library consists of a handful of modules. ad provides the generalized dual number type GDN and its basic arithmetic operations that are available to the floating point type real. The remaining modules provide implementations for GDN objects of all of the mathematical operations defined for real values in the phobos modules core.math, std.math, and std.mathspecial. They are organized similarly to the modules in the std.math package. Here is the mapping.
ad.core.math→core.mathad.math→std.mathad.math.algebraic→std.math.algebraicad.math.constants→std.math.constantsad.math.exponential→std.math.exponentialad.math.operations→std.math.operationsad.math.remainder→std.math.remainderad.math.rounding→std.math.roundingad.math.traits→std.math.traitsad.math.trigonometry→std.math.trigonometryad.mathspecial→std.mathspecial
The module ad.math aggregates and exposes all of the functions defined in its submodules in the same way the Phobos package std.math does.
Here are some examples of using this library.
To differentiate a function, create a GDN variable with the desired derivative degree and evaluate your function:
import ad;
voidmain()
do {
// Create a variable x = 3 that can track up to first order// derivativesconst x = GDN!1(3);
// Evaluate a function: f(x) = 2x + 1const f = 2* x +1;
// The value and first derivativeassert(f ==7); // f(3)assert(f.d ==2); // f'(3), f'(x) = 2
}Specify a higher degree to compute multiple orders of derivatives:
import ad;
voidmain()
do {
// Create a variable x = 2 that tracks up to third order// derivativesconst x = GDN!3(2);
// Evaluate a function: f(x) = x³const f = x ^^3;
// Access derivatives of different ordersassert(f ==8); // f(2)assert(f.d ==12); // f'(2), f'(x) = 3x²assert(f.d!2==12); // f''(2), f''(x) = 6xassert(f.d!3==6); // f'''(2), f'''(x) = 6
}The library supports standard math functions from core.math, std.math, and std.mathspecial:
importstd.math : E;
importstd.mathspecial : digamma;
import ad;
import ad.math;
import ad.mathspecial;
voidmain()
do {
// Differentiate trigonometric functionsconst x = GDN!1(0);
const y = sin(x);
assert(y ==0); // sin(0) = 0assert(y.d ==1); // sin'(x) = cos(x)// Differentiate exponential functionsconst u = exp(GDN!1(1));
assert(u == E);
assert(u.d == E); // (d/dx)eˣ = eˣ// Differentiate the Gamma functionconst q = gamma(GDN!1(2));
assert(q ==1); // Γ(2) = 1assert(q.d == digamma(2)); // Γ'(x) = Γ(x)Ψ(x)
}GDN objects can be freely mixed with arithmetic operations and math functions:
importstd.math : E, cos;
import ad;
import ad.math;
voidmain()
do {
// x is the result of evaluating a function whose value is 1// and derivative is 2.const x = GDN!1(1, 2);
// Evaluate f(x) = eˣsin(x)const f = exp(x) * sin(x);
assert(f == E * sin(1.0L));
// f'(x) = eˣx'sin(x) + eˣcos(x)x'// = x'eˣ[cos(x) + sin(x)]assert(f.d ==2*E*(cos(1.0L) + sin(1.0L)));
}This library is built with DUB.
To build the library, run:
dub buildTo build the API documentation from the DDoc configuration, run:
dub build --config=docsThis command will generate a docs/ folder with HTML reference pages.
Add ad github repository as a dependency in your application's dub.json or dub.sdl.
Example dub.json dependency:
"dependencies": {
"ad": {
"repository": "git+https://github.com/tedgin/ad.git"
}
}The implementations of the regularized lower incomplete gamma function
For the regularized lower incomplete gamma function
For the regularized incomplete beta function