pub struct Dual<T> {
pub value: T,
pub deriv: T,
}Expand description
A dual number representing a value and its derivative.
Dual(value, deriv) represents value + deriv·ε where ε² = 0.
Arithmetic operations follow the algebraic rules of dual numbers;
derivatives propagate automatically.
§Type Parameter
T: The numeric type (typicallyf64orf32)
§Examples
§Basic Usage
use autodiff::Dual;
let x = Dual::variable(5.0);
let y = x * x; // y = x²
assert_eq!(y.value, 25.0); // 5² = 25
assert_eq!(y.deriv, 10.0); // d/dx(x²) at x=5 is 2*5 = 10§Chain Rule
use autodiff::Dual;
// f(x) = (x + 1) * (x + 2)
let x = Dual::variable(3.0);
let f = (x + Dual::constant(1.0)) * (x + Dual::constant(2.0));
assert_eq!(f.value, 20.0); // (3+1)*(3+2) = 4*5 = 20
assert_eq!(f.deriv, 9.0); // f'(x) = 2x+3, f'(3) = 9§Multiple Operations
use autodiff::Dual;
// f(x) = x³ - 2x + 1
let x = Dual::variable(2.0);
let x2 = x * x;
let x3 = x2 * x;
let f = x3 - Dual::constant(2.0) * x + Dual::constant(1.0);
assert_eq!(f.value, 5.0); // 8 - 4 + 1 = 5
assert_eq!(f.deriv, 10.0); // f'(x) = 3x² - 2, f'(2) = 12 - 2 = 10Fields§
§value: TThe primal value
deriv: TThe derivative (tangent)
Implementations§
Source§impl<T> Dual<T>
impl<T> Dual<T>
Sourcepub fn new(value: T, deriv: T) -> Self
pub fn new(value: T, deriv: T) -> Self
Create a new dual number with explicit value and derivative.
§Example
use autodiff::Dual;
let d = Dual::new(3.0, 1.0);
assert_eq!(d.value, 3.0);
assert_eq!(d.deriv, 1.0);Sourcepub fn constant(value: T) -> Selfwhere
T: Zero,
pub fn constant(value: T) -> Selfwhere
T: Zero,
Create a constant (derivative = 0).
Use this for literal values in your computation.
§Example
use autodiff::Dual;
let c = Dual::constant(5.0);
assert_eq!(c.value, 5.0);
assert_eq!(c.deriv, 0.0);Sourcepub fn variable(value: T) -> Selfwhere
T: One,
pub fn variable(value: T) -> Selfwhere
T: One,
Create a variable (derivative = 1).
Use this for the input variable you’re differentiating with respect to.
§Example
use autodiff::Dual;
let x = Dual::variable(3.0);
assert_eq!(x.value, 3.0);
assert_eq!(x.deriv, 1.0); // dx/dx = 1Sourcepub fn recip(self) -> Self
pub fn recip(self) -> Self
Reciprocal (multiplicative inverse).
For g = b + b′·ε with b ≠ 0, computes:
g⁻¹ = (1/b) + (-b′/b²)·ε
This encodes the derivative rule: (1/g)′ = -g′/g².
§Example
use autodiff::Dual;
// f(x) = 1/x at x=2
let x = Dual::variable(2.0);
let f = x.recip();
assert_eq!(f.value, 0.5); // 1/2 = 0.5
assert_eq!(f.deriv, -0.25); // d/dx(1/x) at x=2 is -1/4Sourcepub fn exp(self) -> Selfwhere
T: Float,
pub fn exp(self) -> Selfwhere
T: Float,
Exponential function.
For f = a + a′·ε, computes e^f = e^a + (a′·e^a)·ε.
This encodes the derivative: d/dx(e^f) = f′·e^f.
§Example
use autodiff::Dual;
// f(x) = e^x at x=0
let x = Dual::variable(0.0);
let f = x.exp();
assert_eq!(f.value, 1.0); // e^0 = 1
assert_eq!(f.deriv, 1.0); // d/dx(e^x) at x=0 is e^0 = 1Sourcepub fn ln(self) -> Selfwhere
T: Float,
pub fn ln(self) -> Selfwhere
T: Float,
Natural logarithm.
For f = a + a′·ε, computes ln(f) = ln(a) + (a′/a)·ε.
This encodes the derivative: d/dx(ln f) = f′/f.
§Example
use autodiff::Dual;
// f(x) = ln(x) at x=1
let x = Dual::variable(1.0);
let f = x.ln();
assert!((f.value - 0.0_f64).abs() < 1e-12); // ln(1) = 0
assert!((f.deriv - 1.0_f64).abs() < 1e-12); // d/dx(ln x) at x=1 is 1/1 = 1Sourcepub fn sin(self) -> Selfwhere
T: Float,
pub fn sin(self) -> Selfwhere
T: Float,
Sine function.
For f = a + a′·ε, computes sin(f) = sin(a) + (a′·cos(a))·ε.
This encodes the derivative: d/dx(sin f) = f′·cos f.
§Example
use autodiff::Dual;
// f(x) = sin(x) at x=0
let x = Dual::variable(0.0);
let f = x.sin();
assert!((f.value - 0.0_f64).abs() < 1e-12); // sin(0) = 0
assert!((f.deriv - 1.0_f64).abs() < 1e-12); // d/dx(sin x) at x=0 is cos(0) = 1Sourcepub fn cos(self) -> Selfwhere
T: Float,
pub fn cos(self) -> Selfwhere
T: Float,
Cosine function.
For f = a + a′·ε, computes cos(f) = cos(a) + (-a′·sin(a))·ε.
This encodes the derivative: d/dx(cos f) = -f′·sin f.
§Example
use autodiff::Dual;
// f(x) = cos(x) at x=0
let x = Dual::variable(0.0);
let f = x.cos();
assert!((f.value - 1.0_f64).abs() < 1e-12); // cos(0) = 1
assert!((f.deriv - 0.0_f64).abs() < 1e-12); // d/dx(cos x) at x=0 is -sin(0) = 0Sourcepub fn sqrt(self) -> Selfwhere
T: Float,
pub fn sqrt(self) -> Selfwhere
T: Float,
Square root.
For f = a + a′·ε, computes √f = √a + (a′/(2√a))·ε.
This encodes the derivative: d/dx(√f) = f′/(2√f).
§Example
use autodiff::Dual;
// f(x) = √x at x=4
let x = Dual::variable(4.0);
let f = x.sqrt();
assert_eq!(f.value, 2.0); // √4 = 2
assert_eq!(f.deriv, 0.25); // d/dx(√x) at x=4 is 1/(2*2) = 0.25Trait Implementations§
Source§impl<T: Add<Output = T>> Add for Dual<T>
Addition: (a + a′·ε) + (b + b′·ε) = (a+b) + (a′+b′)·ε
impl<T: Add<Output = T>> Add for Dual<T>
Addition: (a + a′·ε) + (b + b′·ε) = (a+b) + (a′+b′)·ε
Source§impl<T> Div for Dual<T>
Division: f / g = f * (1/g).
impl<T> Div for Dual<T>
Division: f / g = f * (1/g).
The quotient rule emerges automatically from the product rule
(in Mul) composed with the reciprocal rule (in recip).
Source§impl<T: Mul<Output = T> + Add<Output = T> + Clone> Mul for Dual<T>
Multiplication: (a + a′·ε) * (b + b′·ε) = ab + (a′b + ab′)·ε
impl<T: Mul<Output = T> + Add<Output = T> + Clone> Mul for Dual<T>
Multiplication: (a + a′·ε) * (b + b′·ε) = ab + (a′b + ab′)·ε
This implements the product rule: d/dx(f·g) = f′·g + f·g′
Source§impl<T: Sub<Output = T>> Sub for Dual<T>
Subtraction: (a + a′·ε) - (b + b′·ε) = (a-b) + (a′-b′)·ε
impl<T: Sub<Output = T>> Sub for Dual<T>
Subtraction: (a + a′·ε) - (b + b′·ε) = (a-b) + (a′-b′)·ε