LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
infer_lqn_jacobian.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_INFER_INFER_LQN_JACOBIAN_H
6#define LINE_API_INFER_INFER_LQN_JACOBIAN_H
7
8/**
9 * @file
10 * @ingroup api_infer
11 * Forward finite-difference sensitivity matrix of an observation map.
12 *
13 * Templated port of matlab/src/api/infer/infer_lqn_jacobian.m. The JAR carries
14 * the same computation inline inside jline/api/infer/InferLqn.java rather than
15 * as a separate entry point.
16 *
17 * H = dh/da at the parameter vector a, column by column,
18 * H(:,i) = (h(a + d_i e_i) - h(a)) / d_i, d_i = fd_step max(|a_i|, fd_floor)
19 * which is the approximate sensitivity matrix H_k of the EKF update of Zheng,
20 * Yang, Woodside, Litoiu, Iszlai, "Tracking Time-Varying Parameters in
21 * Software Systems with Extended Kalman Filters", CASCON 2005. h is evaluated
22 * numel(a)+1 times, and h0 = h(a) is returned alongside because the caller
23 * (the EKF innovation) always needs it too.
24 *
25 * The observation map is a std::function, so the rest of infer_lqn -- which
26 * needs the LayeredNetwork model layer to evaluate h -- stays out of this
27 * header: any caller that can evaluate h can use this.
28 *
29 * ARITHMETIC: additions, one division per column and a comparison, so a finite
30 * field computation and no transcendental gate. Note what that does and does
31 * not buy: in the exact instantiation the returned matrix is the exact
32 * DIFFERENCE QUOTIENT of h, not the derivative -- the truncation error of the
33 * forward difference is a property of the formula, not of the arithmetic.
34 */
35
36#include <cstddef>
37#include <functional>
38#include <vector>
39
40#include "line/num/number.h"
41#include "line/util/error.h"
42#include "line/util/matrix.h"
43
44namespace line {
45namespace infer {
46
47/** Mirrors the [H, h0] return list of the MATLAB function. */
48template <class T>
50 Matrix<T> H; ///< (no x np) sensitivity matrix
51 std::vector<T> h0; ///< (no) observation at the base point
52};
53
54/**
55 * @brief Forward finite-difference sensitivity matrix of an observation map.
56 *
57 * @param hfun observation map, a parameter vector to an observation vector
58 * @param a (np) point at which the sensitivity is taken
59 * @param fd_step relative perturbation, MATLAB's default 1e-3
60 * @param fd_floor minimum absolute perturbation scale, MATLAB's default 1e-6
61 */
62template <class T>
64 const std::function<std::vector<T>(const std::vector<T>&)>& hfun, const std::vector<T>& a,
65 double fd_step = 1e-3, double fd_floor = 1e-6) {
66 const std::size_t np = a.size();
67 if (np == 0) throw InputError("infer_lqn_jacobian: empty parameter vector");
68 if (!(fd_step > 0.0)) throw InputError("infer_lqn_jacobian: the step must be positive");
69
71 out.h0 = hfun(a);
72 const std::size_t no = out.h0.size();
73 out.H = Matrix<T>(no, np, num_traits<T>::from_int(0));
74
75 const T step = num_traits<T>::from_double(fd_step);
76 const T floor = num_traits<T>::from_double(fd_floor);
77 for (std::size_t i = 0; i < np; ++i) {
78 const T mag = num_abs(T(a[i]));
79 const T d = step * (mag > floor ? mag : floor);
80 std::vector<T> ap = a;
81 ap[i] = ap[i] + d;
82 const std::vector<T> hi = hfun(ap);
83 if (hi.size() != no)
84 throw InputError("infer_lqn_jacobian: the observation map changed its output length");
85 for (std::size_t k = 0; k < no; ++k) out.H(k, i) = (hi[k] - out.h0[k]) / d;
86 }
87 return out;
88}
89
90} // namespace infer
91} // namespace line
92
93#endif // LINE_API_INFER_INFER_LQN_JACOBIAN_H
InputError(const std::string &what)
Definition error.h:39
The exception types the port throws.
Dense matrix and non-owning view.
JacobianResult< T > infer_lqn_jacobian(const std::function< std::vector< T >(const std::vector< T > &)> &hfun, const std::vector< T > &a, double fd_step=1e-3, double fd_floor=1e-6)
Forward finite-difference sensitivity matrix of an observation map.
T num_abs(const T &v)
Definition number.h:172
Number-type abstraction for the templated API port.
Mirrors the [H, h0] return list of the MATLAB function.
std::vector< T > h0
(no) observation at the base point
Matrix< T > H
(no x np) sensitivity matrix