Macro get_vderivative

Source
macro_rules! get_vderivative {
    ($f:ident, $func_name:ident) => { ... };
}
Expand description

Get a function that returns the derivative of the provided univariate, vector-valued function.

The derivative is computed using forward-mode automatic differentiation.

§Arguments

  • f - Univariate, vector-valued function, $\mathbb{f}:\mathbb{R}\to\mathbb{R}^{m}$.
  • func_name - Name of the function that will return the derivative of $\mathbf{f}(x)$ at any point $x\in\mathbb{R}$.

§Warning

f cannot be defined as closure. It must be defined as a function.

§Note

The function produced by this macro will perform 1 evaluation of $\mathbf{f}(x)$ to evaluate its derivative.

§Example

Compute the derivative of

$$f(t)=\begin{bmatrix}\sin{t}\\\cos{t}\end{bmatrix}$$

at $t=1$, and compare the result to the true result of

$$\frac{d\mathbf{f}}{dt}\bigg\rvert_{t=1}=\begin{bmatrix}\cos{(1)}\\-\sin{(1)}\end{bmatrix}$$

§Using standard vectors
use linalg_traits::{Scalar, Vector};
use numtest::*;

use numdiff::{get_vderivative, Dual};

// Define the function, f(t).
fn f<S: Scalar, V: Vector<S>>(t: S) -> V {
    V::from_slice(&[t.sin(), t.cos()])
}

// Autogenerate the function "df" that can be used to compute the derivative of f(t) at any
// point t.
get_vderivative!(f, df);

// Compute the derivative of f(t) at the evaluation point, t = 1.
let df_at_1 = df::<f64, Vec<f64>>(1.0);

// True derivative of f(t) at the evaluation point.
let df_at_1_true: Vec<f64> = vec![1.0_f64.cos(), -1.0_f64.sin()];

// Check the accuracy of the derivative.
assert_arrays_equal_to_decimal!(df_at_1, df_at_1_true, 16);
§Using other vector types

The function produced by get_vderivative! can accept any type for x0, as long as it implements the linalg_traits::Vector trait.

use faer::Mat;
use linalg_traits::{Scalar, Vector};
use nalgebra::{dvector, DVector, SVector};
use ndarray::{array, Array1};
use numtest::*;

 use numdiff::{get_vderivative, Dual};

// Define the function, f(t).
fn f<S: Scalar, V: Vector<S>>(t: S) -> V {
    V::from_slice(&[t.sin(), t.cos()])
}

// Autogenerate the function "df" that can be used to compute the derivative of f(t) at any
// point t.
get_vderivative!(f, df);

// True derivative of f(t) at the evaluation point.
let df_at_1_true: Vec<f64> = vec![1.0_f64.cos(), -1.0_f64.sin()];

// nalgebra::DVector
let df_at_1_dvector: DVector<f64> = df::<f64, DVector<f64>>(1.0);
assert_arrays_equal_to_decimal!(df_at_1_dvector, df_at_1_true, 16);

// nalgebra::SVector
let df_at_1_svector: SVector<f64, 2> = df::<f64, SVector<f64, 2>>(1.0);
assert_arrays_equal_to_decimal!(df_at_1_svector, df_at_1_true, 16);

// ndarray::Array1
let df_at_1_array1: Array1<f64> = df::<f64, Array1<f64>>(1.0);
assert_arrays_equal_to_decimal!(df_at_1_array1, df_at_1_true, 16);

// faer::Mat
let df_at_1_mat: Mat<f64> = df::<f64, Mat<f64>>(1.0);
assert_arrays_equal_to_decimal!(df_at_1_mat.as_slice(), df_at_1_true, 16);