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
//! `LabeledJacobian` + `compute_labeled_jacobian` — string-keyed Jacobian
//! helper, gated on the `labeled-ndarray` feature.
//!
//! This module is a thin wrapper around [`crate::jacobian::compute_jacobian_rev`]
//! that flattens the row-major `Vec<Vec<f64>>` output into an
//! `ndarray::Array2<f64>` and decorates it with row + column labels.
//!
//! # Example
//!
//! ```
//! # #[cfg(feature = "labeled-ndarray")]
//! # {
//! use xad_rs::areal::AReal;
//! use xad_rs::labeled::jacobian::compute_labeled_jacobian;
//!
//! // f(x, y) = [x · y, x + y]
//! let inputs = vec![("x".to_string(), 3.0), ("y".to_string(), 5.0)];
//! let outputs = vec!["prod".to_string(), "sum".to_string()];
//! let j = compute_labeled_jacobian(&inputs, &outputs, |v: &[AReal<f64>]| {
//! vec![&v[0] * &v[1], &v[0] + &v[1]]
//! });
//! assert_eq!(j.matrix[[0, 0]], 5.0);
//! assert_eq!(j.matrix[[0, 1]], 3.0);
//! assert_eq!(j.matrix[[1, 0]], 1.0);
//! assert_eq!(j.matrix[[1, 1]], 1.0);
//! # }
//! ```
use Arc;
use Array2;
use crateAReal;
use cratecompute_jacobian_rev;
use crateVarRegistry;
/// Row-labeled, column-labeled Jacobian matrix.
///
/// `matrix[[i, j]] = ∂outputs[i] / ∂inputs[j]`. Row order matches the
/// `outputs` slice passed to [`compute_labeled_jacobian`]; column order
/// matches the `inputs` slice (which becomes the inner [`VarRegistry`]).
/// Compute a labeled Jacobian via reverse-mode AD.
///
/// Delegates the heavy lifting to [`compute_jacobian_rev`]; this wrapper
/// only attaches row + column labels and reshapes the output into an
/// `ndarray::Array2<f64>`.
///
/// # Arguments
///
/// * `inputs` — input `(name, value)` pairs in the order they should appear
/// as columns of the Jacobian.
/// * `outputs` — output labels in the order they should appear as rows.
/// * `f` — forward closure operating on positional `&[AReal<f64>]`,
/// returning `Vec<AReal<f64>>` (matches `compute_jacobian_rev`).
///
/// # Panics
///
/// Panics if `f(&inputs)` returns a vector whose length differs from
/// `outputs.len()`.