MultiDual

Struct MultiDual 

Source
pub struct MultiDual<T, const N: usize> {
    pub value: T,
    pub derivs: [T; N],
}
Expand description

A multi-component dual number representing a value and N partial derivatives.

MultiDual<T, N> represents a value along with its gradient [∂f/∂x₁, …, ∂f/∂xₙ] for forward-mode automatic differentiation of multivariable functions.

§Type Parameters

  • T: The numeric type (typically f64 or f32)
  • N: The number of input variables (compile-time constant)

§Examples

§Creating Variables

use autodiff::MultiDual;

// Create the first variable x with value 3.0 (∂/∂x = 1, ∂/∂y = 0)
let x = MultiDual::<f64, 2>::variable(3.0, 0);
assert_eq!(x.value, 3.0);
assert_eq!(x.derivs, [1.0, 0.0]);

// Create the second variable y with value 4.0 (∂/∂x = 0, ∂/∂y = 1)
let y = MultiDual::<f64, 2>::variable(4.0, 1);
assert_eq!(y.value, 4.0);
assert_eq!(y.derivs, [0.0, 1.0]);

// Create a constant (∂/∂x = 0, ∂/∂y = 0)
let c = MultiDual::<f64, 2>::constant(2.0);
assert_eq!(c.value, 2.0);
assert_eq!(c.derivs, [0.0, 0.0]);

§Computing Gradients

use autodiff::MultiDual;

// f(x, y) = x² + y²
let x = MultiDual::<f64, 2>::variable(3.0, 0);
let y = MultiDual::<f64, 2>::variable(4.0, 1);

let f = x * x + y * y;

assert_eq!(f.value, 25.0);      // 3² + 4² = 25
assert_eq!(f.derivs[0], 6.0);   // ∂f/∂x = 2x = 6
assert_eq!(f.derivs[1], 8.0);   // ∂f/∂y = 2y = 8

Fields§

§value: T

The primal value (function output)

§derivs: [T; N]

The partial derivatives [∂f/∂x₁, ∂f/∂x₂, …, ∂f/∂xₙ]

Implementations§

Source§

impl<T, const N: usize> MultiDual<T, N>
where T: Copy,

Source

pub fn new(value: T, derivs: [T; N]) -> Self

Create a dual number with explicit value and derivatives.

§Examples
use autodiff::MultiDual;

let d = MultiDual::new(5.0, [1.0, 2.0, 3.0]);
assert_eq!(d.value, 5.0);
assert_eq!(d.derivs, [1.0, 2.0, 3.0]);
Source

pub fn constant(value: T) -> Self
where T: Zero,

Create a constant (all partial derivatives are zero).

§Examples
use autodiff::MultiDual;

let c = MultiDual::<f64, 3>::constant(42.0);
assert_eq!(c.value, 42.0);
assert_eq!(c.derivs, [0.0, 0.0, 0.0]);
Source

pub fn variable(value: T, index: usize) -> Self
where T: Zero + One,

Create the i-th input variable.

Sets derivs[index] = 1 and all other derivatives to zero, representing ∂xᵢ/∂xⱼ = δᵢⱼ (Kronecker delta).

§Panics

Panics if index >= N.

§Examples
use autodiff::MultiDual;

// Create x (first variable)
let x = MultiDual::<f64, 2>::variable(3.0, 0);
assert_eq!(x.value, 3.0);
assert_eq!(x.derivs, [1.0, 0.0]);

// Create y (second variable)
let y = MultiDual::<f64, 2>::variable(4.0, 1);
assert_eq!(y.value, 4.0);
assert_eq!(y.derivs, [0.0, 1.0]);
Source§

impl<T, const N: usize> MultiDual<T, N>
where T: Float,

Source

pub fn recip(self) -> Self

Reciprocal: 1/(b + ∇b) = (1/b) + (-∇b/b²)

Implements the rule: (1/g)′ = -g′/g² (note: g ≠ 0)

§Examples
use autodiff::MultiDual;

// f(x, y) = 1/x at (2, 3)
let x = MultiDual::<f64, 2>::variable(2.0, 0);
let recip_x = x.recip();

assert_eq!(recip_x.value, 0.5);        // 1/2
assert!((recip_x.derivs[0] + 0.25).abs() < 1e-10);  // -1/4
assert_eq!(recip_x.derivs[1], 0.0);    // ∂(1/x)/∂y = 0
Source

pub fn exp(self) -> Self

Exponential function: exp(a + ∇a) = exp(a) + (exp(a) · ∇a)

Implements the chain rule: ∂/∂xᵢ(exp(f)) = exp(f) · ∂f/∂xᵢ

§Examples
use autodiff::MultiDual;

// f(x, y) = exp(x) at (0, 1)
let x = MultiDual::<f64, 2>::variable(0.0, 0);
let f = x.exp();

assert_eq!(f.value, 1.0);       // exp(0) = 1
assert_eq!(f.derivs[0], 1.0);   // ∂exp(x)/∂x at x=0 is exp(0) = 1
assert_eq!(f.derivs[1], 0.0);   // ∂exp(x)/∂y = 0
Source

pub fn ln(self) -> Self

Natural logarithm: ln(a + ∇a) = ln(a) + (∇a / a)

Implements the chain rule: ∂/∂xᵢ(ln(f)) = (∂f/∂xᵢ) / f

§Examples
use autodiff::MultiDual;

// f(x, y) = ln(x) at (1, 2)
let x = MultiDual::<f64, 2>::variable(1.0, 0);
let f = x.ln();

assert!((f.value - 0.0_f64).abs() < 1e-12);    // ln(1) = 0
assert!((f.derivs[0] - 1.0_f64).abs() < 1e-12); // ∂ln(x)/∂x at x=1 is 1/1 = 1
assert_eq!(f.derivs[1], 0.0);               // ∂ln(x)/∂y = 0
Source

pub fn sin(self) -> Self

Sine function: sin(a + ∇a) = sin(a) + (cos(a) · ∇a)

Implements the chain rule: ∂/∂xᵢ(sin(f)) = cos(f) · ∂f/∂xᵢ

§Examples
use autodiff::MultiDual;

// f(x, y) = sin(x) at (0, 1)
let x = MultiDual::<f64, 2>::variable(0.0, 0);
let f = x.sin();

assert!((f.value - 0.0_f64).abs() < 1e-12);    // sin(0) = 0
assert!((f.derivs[0] - 1.0_f64).abs() < 1e-12); // ∂sin(x)/∂x at x=0 is cos(0) = 1
assert_eq!(f.derivs[1], 0.0);               // ∂sin(x)/∂y = 0
Source

pub fn cos(self) -> Self

Cosine function: cos(a + ∇a) = cos(a) + (-sin(a) · ∇a)

Implements the chain rule: ∂/∂xᵢ(cos(f)) = -sin(f) · ∂f/∂xᵢ

§Examples
use autodiff::MultiDual;

// f(x, y) = cos(x) at (0, 1)
let x = MultiDual::<f64, 2>::variable(0.0, 0);
let f = x.cos();

assert!((f.value - 1.0_f64).abs() < 1e-12);    // cos(0) = 1
assert!((f.derivs[0] - 0.0_f64).abs() < 1e-12); // ∂cos(x)/∂x at x=0 is -sin(0) = 0
assert_eq!(f.derivs[1], 0.0);               // ∂cos(x)/∂y = 0
Source

pub fn sqrt(self) -> Self

Square root: sqrt(a + ∇a) = sqrt(a) + (∇a / (2·sqrt(a)))

Implements the chain rule: ∂/∂xᵢ(√f) = (∂f/∂xᵢ) / (2√f)

§Examples
use autodiff::MultiDual;

// f(x, y) = √x at (4, 1)
let x = MultiDual::<f64, 2>::variable(4.0, 0);
let f = x.sqrt();

assert_eq!(f.value, 2.0);       // √4 = 2
assert_eq!(f.derivs[0], 0.25);  // ∂√x/∂x at x=4 is 1/(2·2) = 0.25
assert_eq!(f.derivs[1], 0.0);   // ∂√x/∂y = 0

Trait Implementations§

Source§

impl<T, const N: usize> Add for MultiDual<T, N>
where T: Add<Output = T> + Copy,

Addition: (a + ∇a) + (b + ∇b) = (a+b) + (∇a+∇b)

§Examples

use autodiff::MultiDual;

let x = MultiDual::new(3.0, [1.0, 0.0]);
let y = MultiDual::new(4.0, [0.0, 1.0]);
let sum = x + y;

assert_eq!(sum.value, 7.0);
assert_eq!(sum.derivs, [1.0, 1.0]);
Source§

type Output = MultiDual<T, N>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Self) -> Self

Performs the + operation. Read more
Source§

impl<T: Clone, const N: usize> Clone for MultiDual<T, N>

Source§

fn clone(&self) -> MultiDual<T, N>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug, const N: usize> Debug for MultiDual<T, N>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T, const N: usize> Div for MultiDual<T, N>
where T: Float,

Division: (a + ∇a) / (b + ∇b) = (a + ∇a) * (1/(b + ∇b))

Implements division via reciprocal (composition of operations).

§Examples

use autodiff::MultiDual;

// f(x, y) = x / y at (6, 2)
let x = MultiDual::<f64, 2>::variable(6.0, 0);
let y = MultiDual::<f64, 2>::variable(2.0, 1);
let quotient = x / y;

assert_eq!(quotient.value, 3.0);         // 6/2
assert_eq!(quotient.derivs[0], 0.5);     // ∂(x/y)/∂x = 1/y = 0.5
assert_eq!(quotient.derivs[1], -1.5);    // ∂(x/y)/∂y = -x/y² = -1.5
Source§

type Output = MultiDual<T, N>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: Self) -> Self

Performs the / operation. Read more
Source§

impl<T, const N: usize> Mul for MultiDual<T, N>
where T: Mul<Output = T> + Add<Output = T> + Copy,

Multiplication: (a + ∇a) * (b + ∇b) = ab + (b∇a + a∇b)

This implements the product rule automatically.

§Examples

use autodiff::MultiDual;

// f(x, y) = x * y at (3, 4)
let x = MultiDual::<f64, 2>::variable(3.0, 0);
let y = MultiDual::<f64, 2>::variable(4.0, 1);
let product = x * y;

assert_eq!(product.value, 12.0);      // 3 * 4
assert_eq!(product.derivs[0], 4.0);   // ∂(xy)/∂x = y = 4
assert_eq!(product.derivs[1], 3.0);   // ∂(xy)/∂y = x = 3
Source§

type Output = MultiDual<T, N>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Self) -> Self

Performs the * operation. Read more
Source§

impl<T, const N: usize> Neg for MultiDual<T, N>
where T: Neg<Output = T> + Copy,

Negation: -(a + ∇a) = -a + (-∇a)

§Examples

use autodiff::MultiDual;

let x = MultiDual::new(3.0, [1.0, 2.0]);
let neg_x = -x;

assert_eq!(neg_x.value, -3.0);
assert_eq!(neg_x.derivs, [-1.0, -2.0]);
Source§

type Output = MultiDual<T, N>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Self

Performs the unary - operation. Read more
Source§

impl<T: PartialEq, const N: usize> PartialEq for MultiDual<T, N>

Source§

fn eq(&self, other: &MultiDual<T, N>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T, const N: usize> Sub for MultiDual<T, N>
where T: Sub<Output = T> + Copy,

Subtraction: (a + ∇a) - (b + ∇b) = (a-b) + (∇a-∇b)

§Examples

use autodiff::MultiDual;

let x = MultiDual::new(7.0, [2.0, 3.0]);
let y = MultiDual::new(4.0, [1.0, 2.0]);
let diff = x - y;

assert_eq!(diff.value, 3.0);
assert_eq!(diff.derivs, [1.0, 1.0]);
Source§

type Output = MultiDual<T, N>

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Self) -> Self

Performs the - operation. Read more
Source§

impl<T: Copy, const N: usize> Copy for MultiDual<T, N>

Source§

impl<T, const N: usize> StructuralPartialEq for MultiDual<T, N>

Auto Trait Implementations§

§

impl<T, const N: usize> Freeze for MultiDual<T, N>
where T: Freeze,

§

impl<T, const N: usize> RefUnwindSafe for MultiDual<T, N>
where T: RefUnwindSafe,

§

impl<T, const N: usize> Send for MultiDual<T, N>
where T: Send,

§

impl<T, const N: usize> Sync for MultiDual<T, N>
where T: Sync,

§

impl<T, const N: usize> Unpin for MultiDual<T, N>
where T: Unpin,

§

impl<T, const N: usize> UnwindSafe for MultiDual<T, N>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.