LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
ctmc_transient_sens.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_MC_CTMC_TRANSIENT_SENS_H
6#define LINE_API_MC_CTMC_TRANSIENT_SENS_H
7
8/**
9 * @file
10 * @ingroup api_mc
11 * Sensitivity of the transient distribution of a CTMC to a scalar parameter.
12 *
13 * Templated port of matlab/src/api/mc/ctmc_transient_sens.m. Differentiating
14 * the forward equations with respect to theta, with an initial vector that does
15 * not depend on theta, gives Trivedi and Bobbio (2017), Eq. (9.82),
16 *
17 * d/dt (dpi/dtheta) = (dpi/dtheta) Q + pi (dQ/dtheta), dpi(0)/dtheta = 0.
18 *
19 * The sensitivity equation is driven by pi(t), so the two cannot be advanced
20 * separately: state and sensitivity are integrated as ONE augmented system of
21 * size 2n on a single adaptive grid, which is also what keeps the two
22 * consistent at every returned time point.
23 *
24 * GATED ON TRANSCENDENTAL ARITHMETIC, for the same reason as ctmc_transient:
25 * it is the same ode23 controller on a larger system.
26 */
27
28#include <cstddef>
29#include <vector>
30
32#include "line/num/number.h"
33#include "line/util/error.h"
34#include "line/util/matrix.h"
35
36namespace line {
37namespace mc {
38
39template <class T>
41 std::vector<T> t; ///< accepted time points, the first being t0
42 Matrix<T> pi; ///< distribution at each time point
43 Matrix<T> dpi; ///< sensitivity at each time point
44};
45
46/**
47 * @brief Sensitivity of the transient distribution of a CTMC to a scalar
48 * parameter.
49 *
50 * @param Q generator
51 * @param dQ derivative of the generator with respect to theta, same size
52 * @param pi0 initial distribution (row vector)
53 * @param t0 initial time
54 * @param t1 final time
55 * @param rtol relative tolerance of the ODE integrator
56 * @param atol absolute tolerance of the ODE integrator
57 */
58template <class T>
60 const std::vector<T>& pi0, const T& t0, const T& t1,
61 double rtol = 1e-3, double atol = 1e-6) {
63 "ctmc_transient_sens requires transcendental arithmetic: it is the ode23 "
64 "controller of ctmc_transient applied to the augmented 2n system");
65 const std::size_t n = Q.rows();
66 if (Q.cols() != n) throw InputError("ctmc_transient_sens: generator is not square");
67 if (dQ.rows() != n || dQ.cols() != n)
68 throw InputError("ctmc_transient_sens: dQ must have the same size as Q");
69 if (pi0.size() != n) throw InputError("ctmc_transient_sens: pi0 has the wrong length");
70 const T zero = num_traits<T>::from_int(0);
71
72 std::vector<T> v0(2 * n, zero);
73 for (std::size_t i = 0; i < n; ++i) v0[i] = pi0[i];
74
75 std::vector<T> tv;
76 std::vector<std::vector<T>> yv;
77 detail::ode23<T>(
78 [&Q, &dQ, n, &zero](const std::vector<T>& v, std::vector<T>& dv) {
79 for (std::size_t j = 0; j < n; ++j) {
80 T a = zero, b = zero;
81 for (std::size_t i = 0; i < n; ++i) {
82 a += v[i] * Q(i, j);
83 b += v[n + i] * Q(i, j) + v[i] * dQ(i, j);
84 }
85 dv[j] = a;
86 dv[n + j] = b;
87 }
88 },
89 t0, t1, v0, rtol, atol, tv, yv);
90
92 r.t = tv;
93 r.pi = Matrix<T>(yv.size(), n);
94 r.dpi = Matrix<T>(yv.size(), n);
95 for (std::size_t k = 0; k < yv.size(); ++k)
96 for (std::size_t j = 0; j < n; ++j) {
97 r.pi(k, j) = yv[k][j];
98 r.dpi(k, j) = yv[k][n + j];
99 }
100 return r;
101}
102
103/** Overload starting from the uniform distribution, as MATLAB's short forms do. */
104template <class T>
106 const T& t1, double rtol = 1e-3, double atol = 1e-6) {
107 const std::size_t n = Q.rows();
108 if (n == 0) throw InputError("ctmc_transient_sens: empty generator");
109 const std::vector<T> pi0(n, num_traits<T>::from_int(1) / num_traits<T>::from_int(static_cast<long>(n)));
110 return ctmc_transient_sens(Q, dQ, pi0, t0, t1, rtol, atol);
111}
112
113} // namespace mc
114} // namespace line
115
116#endif // LINE_API_MC_CTMC_TRANSIENT_SENS_H
InputError(const std::string &what)
Definition error.h:39
std::size_t cols() const
Definition matrix.h:90
std::size_t rows() const
Definition matrix.h:89
Transient distribution of a CTMC over a time interval, by integrating the forward equations d pi/dt =...
The exception types the port throws.
Dense matrix and non-owning view.
TransientSensResult< T > ctmc_transient_sens(const Matrix< T > &Q, const Matrix< T > &dQ, const std::vector< T > &pi0, const T &t0, const T &t1, double rtol=1e-3, double atol=1e-6)
Sensitivity of the transient distribution of a CTMC to a scalar parameter.
Number-type abstraction for the templated API port.
Matrix< T > pi
distribution at each time point
std::vector< T > t
accepted time points, the first being t0
Matrix< T > dpi
sensitivity at each time point