1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use crateCBRT_EPS;
use Vector;
/// Second derivative of a univariate, vector-valued function using the forward difference
/// approximation.
///
/// # Arguments
///
/// * `f` - Univariate, vector-valued function, $\mathbf{f}:\mathbb{R}\to\mathbb{R}^{m}$.
/// * `x0` - Evaluation point, $x_{0}\in\mathbb{R}$.
/// * `h` - Relative step size, $h\in\mathbb{R}$. Defaults to [`CBRT_EPS`].
///
/// # Returns
///
/// Second derivative of $\mathbf{f}$ with respect to $x$, evaluated at $x=x_{0}$.
///
/// $$\frac{d^{2}\mathbf{f}}{dx^{2}}\bigg\rvert_{x=x_{0}}\in\mathbb{R}^{m}$$
///
/// # Note
///
/// This function performs 3 evaluations of $f(x)$.
///
/// # Examples
///
/// ## Basic Example
///
/// Approximate the second 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^{2}\mathbf{f}}{dt^{2}}\bigg\rvert_{t=1}=\begin{bmatrix}-\sin{(1)}\\\\-\cos{(1)}\end{bmatrix}$$
///
/// ```
/// use numtest::*;
///
/// use numdiff::forward_difference::vderivative2;
///
/// // Define the function, f(t).
/// let f = |t: f64| vec![t.sin(), t.cos()];
///
/// // Approximate the second derivative of f(t) at the evaluation point.
/// let d2f: Vec<f64> = vderivative2(&f, 1.0, None);
///
/// // True second derivative of f(t) at the evaluation point.
/// let d2f_true: Vec<f64> = vec![-1.0_f64.sin(), -1.0_f64.cos()];
///
/// // Check the accuracy of the second derivative approximation.
/// assert_arrays_equal_to_decimal!(d2f, d2f_true, 3);
/// ```
///
/// ## Example Passing Runtime Parameters
///
/// Approximate the second derivative of a parameterized vector function
///
/// $$f(t)=\begin{bmatrix}at^{2}+b\\\\ce^{t}+d\end{bmatrix}$$
///
/// where $a$, $b$, $c$, and $d$ are runtime parameters. Compare the result against the true second
/// derivative of
///
/// $$f''(t)=\begin{bmatrix}2a\\\\ce^{t}\end{bmatrix}$$
///
/// ```
/// use numtest::*;
///
/// use numdiff::forward_difference::vderivative2;
///
/// // Runtime parameters.
/// let a = 1.5;
/// let b = -2.0;
/// let c = 0.8;
/// let d = 3.0;
///
/// // Define the parameterized function.
/// fn f_param(t: f64, a: f64, b: f64, c: f64, d: f64) -> Vec<f64> {
/// vec![a * t.powi(2) + b, c * t.exp() + d]
/// }
///
/// // Wrap the parameterized function with a closure that captures the parameters.
/// let f = |t: f64| f_param(t, a, b, c, d);
///
/// // True second derivative function.
/// let d2f_true = |t: f64| vec![2.0 * a, c * t.exp()];
///
/// // Approximate the second derivative at t = 1.0 and compare with true second derivative.
/// let d2f_at_1: Vec<f64> = vderivative2(&f, 1.0, None);
/// let d2f_at_1_true: Vec<f64> = d2f_true(1.0);
/// assert_arrays_equal_to_decimal!(d2f_at_1, d2f_at_1_true, 3);
/// ```