Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.
mir.ediff
Expression differentiation
The module provides API for rapid evaluation of a user-requested set of partial derivatives of any order.
The implementation operates with double precision numbers.
| Name | Description |
|---|
| Name | Description |
|---|
| Name | Description |
|---|
| Name | Description |
|---|
| Name | Description |
|---|
Optimization note
During function differentiation, the resulting set of expressions likely contains a lot of identical calls of elementary functions. LLVM efficiently eliminates equivalent calls of intrinsic functions such as powi, log, exp, and sqrt. On the other hand, it can't eliminate identical calls of complex functions. It is highly recommended to evaluate a set of partial derivatives immediately after constructing a complex expression such as normalDistribution.Authors:
Ilia Ki
Examples:
/// static struct D { @Derivative() double _; @Derivative("a") double a; @Derivative("b") double b; @Minus @Derivative("a", "b") double mab; } auto d = D(3, 4, 5, -6); assert(d.powi!2.setDerivatives!D == D(9, 24, 30, -76));
Examples:
/// static struct Greeks { @Derivative("spot") double delta; @Derivative("spot", "spot") double gamma; @Minus @Derivative("time", "spot") double charm; } auto greeks = Greeks(2, 3, 4); auto dspot = derivativeOf!"spot"(&greeks); assert(greeks.delta is dspot.getFunctionValue); assert(greeks.gamma is dspot.getDerivative!(["spot"])); assert(greeks.charm is -dspot.getDerivative!(["time"]));
Examples:
import mir.test; import mir.math; // Test Const static assert(Dependencies!Const == [].DependsOn); auto c = 5.Const; static assert(c.getDerivative!(["any"]) == 0); assert(c.getFunctionValue == 5); // Test Var auto spot = 7.Var!"spot"; static assert(Dependencies!(Var!"spot") == ["spot"].DependsOn); static assert(spot.getDerivative!(["spot"]) == 1); static assert(spot.getDerivative!(["other"]) == 0); assert(spot.getFunctionValue == 7); // Test integer power and exponent auto f1 = exp(3.Const * spot.powi!(-2)); static assert(Dependencies!(typeof(f1)) == ["spot"].DependsOn); assert(f1.getFunctionValue == mir.math.exp(3 * 7.0 ^^ -2)); assert(f1.getDerivative!(["spot"]).approxEqual(3 * -2 * 7.0 ^^ -3 * mir.math.exp(3 * 7.0 ^^ -2))); // Test DerivativeOf assert(f1.derivativeOf!"spot".getFunctionValue == f1.getDerivative!(["spot"])); // Test product and sum assert(f1.derivativeOf!"spot".derivativeOf!"spot".getFunctionValue.approxEqual((3 * (-2 * 7.0 ^^ -3)) ^^ 2 * mir.math.exp(3 * 7.0 ^^ -2) + 3 * (6 * 7.0 ^^ -4)* mir.math.exp(3 * 7.0 ^^ -2))); auto strike = 9.Var!"strike"; auto f2 = strike * f1 + strike; assert(f2.getDerivative!(["strike"]).approxEqual(1 + f1.getFunctionValue)); // Test log assert(f2.log.getFunctionValue == mir.math.log(f2.getFunctionValue)); assert(f2.log.getDerivative!(["strike"]) == getFunctionValue(f2.powi!(-1) * (1.Const + f1))); assert(f2.sqrt.getFunctionValue == mir.math.sqrt(f2.getFunctionValue)); assert(f2.sqrt.getDerivative!(["strike"]) == getFunctionValue(f2.sqrt.powi!(-1) * 0.5.Const * (1.Const + f1))); // Compose auto barrier = 13.Var!"barrier"; auto fc = barrier.powi!2 / strike; auto f3 = f2.composeAt!"strike"(fc); assert(f3.getFunctionValue == f2.getFunctionValue); assert(f3.getDerivative!(["vol"]) == f2.getDerivative!(["vol"])); assert(f3.getDerivative!(["strike"]) == f2.getDerivative!(["strike"]) * fc.getDerivative!(["strike"])); f3.getDerivative!(["barrier"]).shouldApprox == f2.getDerivative!(["strike"]) * fc.getDerivative!(["barrier"]); getDerivative!(["barrier"])(f3 + barrier).shouldApprox == f2.getDerivative!(["strike"]) * fc.getDerivative!(["barrier"]) + 1; f3.getDerivative!(["strike", "barrier"]).shouldApprox == f2.getDerivative!(["strike", "strike"]) * fc.getDerivative!(["strike"]) * fc.getDerivative!(["barrier"]) + f2.getDerivative!(["strike"]) * fc.getDerivative!(["strike", "barrier"]); /// normalDistribution import mir.math.func.normal: constantNormalCDF = normalCDF, normalPDF; barrier.powi!2.normalCDF.getFunctionValue.shouldApprox == constantNormalCDF(13.0 ^^ 2); barrier.powi!2.normalCDF.getDerivative!(["barrier"]).shouldApprox == normalPDF(13.0 ^^ 2) * (2 * 13);
- template
ediffOperators() - struct
DependsOn; - User defined attribute that should applied on struct definition of a user-defined expression function.
- string[]
variables; - const pure nothrow @nogc @safe auto
contains(stringvariable); - const pure nothrow @nogc @safe auto
containsAll(string[]variables); - const pure nothrow @nogc @safe auto
containsAny(string[]variables); - DependsOn
opBinary(string op : "~")(DependsOnrhs); - Set union
- template
Dependencies(T) - Fetchs a set of variables the expression is depends on. First, it checks if the expression has DependsOn UDA ; otherwise, iterates over members with Derivative UDA and collects variable names.
- struct
Derivative; - User defined attribute that should applied on a struct member definition of a user-defined set of derivatives. The attribute holds an unordered set with duplicates of variables names to reflect which partial derivative this member contains.
- string[]
variables; - pure nothrow @nogc @trusted this(string[]
variables...);
- enum
Minus; - User-defined attribute that can be applied on struct member definition along with Derivative to denote that the member holds a negative value of the partial derivative. This attribute is useful for financial code where verbal definitions may denote negative partial derivatives.
- template
getFunctionValue(bool strict = true) - Evaluates function value. It is shortcut for getDerivative of zero order.Parameters:
strict The parameter is used when the expression can't evaluate the function. If true, prints error at compile-time; otherwise, getFunctionValues returns NaN. - template
getDerivative(string[] variables, bool strict = true) - Evaluates partial derivative for user-defined compiletime set of variables. First, it checks if the expression has .
getDerivativemethods and uses it, otherwise iterates over members with Derivative UDA and tries to find a member that holds the required partial derivative.Parameters:variables array that denotes partial derivative strict The parameter is used when the expression can't evaluate the derivative. If true, prints error at compile-time; otherwise, getDerivativereturns NaN. - void
setDerivatives(bool strict = true, D, E)(ref scope Dderivatives, Eexpression);
templatesetDerivatives(D, bool strict = true) - Evaluates partial derivatives and function value, if any, for a user-provided set of partial derivatives. The derivative set can be defined with Derivative and Minus UDAs.Parameters:
D type of the requested set of partial derivatives strict The parameter is used when the expression can't evaluate the derivative. If true, prints error at compile-time; otherwise, the corresponding member is set to NaN. D derivativesa structure that holds set of partial derivatives (optional) E expressionexpression - template
composeAt(string position) - Given a compiletime variable name v and two expressions F(v, U) and G(Y), constructs a composition F ∘ G (U, Y) as v = G.Parameters:
position name of the variable to compose functions at. - auto
composeAt(F, G)(const Ff, const Gg); - Parameters:
F fF expression G gG expression
- template
derivativeOf(string variable) - Constructs a partial derivative of one order. The function can be applied in any stage any number of times. The function does NOT evaluate the expression.
- @property auto
derivativeOf(T)(const Tvalue); - Parameters:
T valueexpression
- struct
Const; - A double precision constant with an immidiate value
- double
value; - Immidiate value
- struct
Var(string name); - A double precision named variable with an immidiate value
- double
value; - Immidiate value
- auto
powi(int power, T)(const Tvalue)
if (is(T == struct)); - Constructs of the expression raised to the specified (positive or negative) compile-time integral power.Parameters:
power integral power (compile-time) T valueexpression - auto
exp(T)(const Tpower)
if (is(T == struct)); - Constructs the natural exponent of the expression.Parameters:
T powerexpression - auto
log(T)(const Tvalue)
if (is(T == struct)); - Constructs the natural logarithm of the expression.Parameters:
T valueexpression - auto
sqrt(T)(const Tvalue)
if (is(T == struct)); - Constructs the square root of the expression.Parameters:
T valueexpression - auto
normalCDF(T)(const Tvalue)
if (is(T == struct)); - Constructs the cumulative normal distribution function of the expressionParameters:
T valueexpression
Copyright © 2016-2026 by Ilya Yaroshenko | Page generated by
Ddoc on Wed Apr 8 13:47:03 2026