hyperdual/
differentials.rs1use crate::OHyperdual;
2
3use super::Float;
4use na::{allocator::Allocator, DefaultAllocator};
5use na::{Dim, DimName, OMatrix, OVector, SMatrix, SVector};
6use {Dual, DualN, One, Scalar, Zero};
7
8#[inline]
10pub fn differentiate<T: Copy + Scalar + One, F>(x: T, f: F) -> T
11where
12 F: Fn(Dual<T>) -> Dual<T>,
13{
14 f(Dual::new(x, T::one())).dual()
15}
16
17#[inline]
19pub fn extract_jacobian_and_result<T: Scalar + Zero + Float, const DIM_IN: usize, const DIM_OUT: usize, const DIM_HYPER: usize>(
20 fx_dual: &SVector<DualN<T, DIM_HYPER>, DIM_OUT>,
21) -> (SVector<T, DIM_OUT>, SMatrix<T, DIM_OUT, DIM_IN>) {
22 let fx = super::vector_from_hyperspace(fx_dual);
23 let mut grad = SMatrix::<T, DIM_OUT, DIM_IN>::zeros();
24
25 for i in 0..DIM_OUT {
26 for j in 0..DIM_IN {
27 grad[(i, j)] = fx_dual[i][j + 1];
28 }
29 }
30 (fx, grad)
31}
32
33#[inline]
35pub fn extract_jacobian_and_result_owned<T: Scalar + Zero + Float, DimIn: Dim + DimName, DimOut: Dim + DimName, DimHyper: Dim + DimName>(
36 fx_dual: &OVector<OHyperdual<T, DimHyper>, DimOut>,
37) -> (OVector<T, DimOut>, OMatrix<T, DimOut, DimIn>)
38where
39 DefaultAllocator: Allocator<DimIn> + Allocator<DimOut> + Allocator<DimOut, DimIn> + Allocator<DimOut> + Allocator<DimHyper>,
40 <DefaultAllocator as Allocator<DimHyper>>::Buffer<T>: Copy,
41{
42 let fx = super::ovector_from_hyperspace(fx_dual);
43 let mut grad = OMatrix::<T, DimOut, DimIn>::zeros();
44
45 for i in 0..DimOut::dim() {
46 for j in 0..DimIn::dim() {
47 grad[(i, j)] = fx_dual[i][j + 1];
48 }
49 }
50 (fx, grad)
51}