5#ifndef LINE_API_INFER_INFER_LQN_H
6#define LINE_API_INFER_INFER_LQN_H
114 const std::vector<LqnObsSpec>& obs,
const Matrix<T>& Z,
118 "infer_lqn requires transcendental arithmetic: its filter corrects on a "
119 "finite-difference sensitivity matrix and reports root mean square errors");
121 const std::size_t no = obs.size();
122 if (Z.
rows() != no)
throw InputError(
"infer_lqn: row count of Z must equal numel(obsSpec)");
123 if (spec.empty())
throw InputError(
"infer_lqn: no parameters to identify");
124 if (!
solve)
throw InputError(
"infer_lqn: an observation model is required");
127 std::vector<T> a0 =
opt.a0;
129 if (a0.size() != spec.size())
130 throw InputError(
"infer_lqn: a0 has the wrong length");
131 const std::size_t np = a0.size();
139 else if (
opt.has_T &&
opt.has_Tstar)
140 gammaT =
opt.T_interval /
opt.Tstar;
145 if (
opt.Q.rows() != 0) {
150 for (std::size_t i = 0; i < np; ++i) {
151 const T qi = qf *
num_abs(a0[i]);
153 out.
Q(i, i) = v > eps ? v : eps;
157 if (
opt.R.rows() != 0) {
164 for (std::size_t i = 0; i < no; ++i) {
166 for (std::size_t k = 0; k < Z.
cols(); ++k) zbar += Z(i, k);
167 zbar = zbar / nsteps;
168 const T ri = rf *
num_abs(zbar);
169 const T v = ri * ri / gt;
170 out.
R(i, i) = v > eps ? v : eps;
174 if (
opt.P0.rows() != 0) {
179 for (std::size_t i = 0; i < np; ++i) {
180 const T pi_ = half *
num_abs(a0[i]);
181 const T v = pi_ * pi_;
182 out.
P0(i, i) = v > eps ? v : eps;
188 const std::vector<LqnParamSpec>* sp = &spec;
189 const std::vector<LqnObsSpec>* ob = &obs;
190 std::function<std::vector<T>(
const std::vector<T>&)> hfun =
191 [model, sp, ob, &
solve](
const std::vector<T>& a) {
205 std::vector<T> afinal(np, zero);
206 const std::size_t last = out.
ekf.ahat.cols() - 1;
207 for (std::size_t i = 0; i < np; ++i) afinal[i] = out.
ekf.ahat(i, last);
The exception types the port throws.
Extended Kalman Filter for LQN parameter identification.
Observation vector of a solved LQN, z = h(a).
Apply a parameter vector to a LayeredNetworkStruct, and read it back.
LayeredNetworkStruct, the flattened description of a layered queueing network.
Dense matrix and non-owning view.
InferLqnResult< T > infer_lqn(lqn::LqnStruct< T > &lsn, const std::vector< LqnParamSpec > &spec, const std::vector< LqnObsSpec > &obs, const Matrix< T > &Z, const std::function< LqnMetrics< T >(const lqn::LqnStruct< T > &)> &solve, const InferLqnOptions< T > &opt=InferLqnOptions< T >())
Identify hidden LQN parameters from measured performance data.
void infer_lqn_setparams(lqn::LqnStruct< T > &lsn, const std::vector< LqnParamSpec > &spec, const std::vector< T > &a)
Set the parameters named in spec to the values in a, in place.
std::vector< T > infer_lqn_getparams(const lqn::LqnStruct< T > &lsn, const std::vector< LqnParamSpec > &spec)
Read the current values of the parameters named in spec.
std::vector< T > infer_lqn_getobs(const std::vector< std::string > &names, const LqnMetrics< T > &metrics, const std::vector< LqnObsSpec > &spec)
Observation vector of a solved LQN, z = h(a).
EkfResult< T > infer_lqn_ekf(const std::function< std::vector< T >(const std::vector< T > &)> &hfun, const std::vector< T > &a0, const Matrix< T > &P0, const Matrix< T > &Z, const Matrix< T > &Q, const Matrix< T > &R, const EkfOptions< T > &opts=EkfOptions< T >())
Extended Kalman Filter for LQN parameter identification.
std::vector< T > solve(const Matrix< T > &A, const std::vector< T > &b)
Convenience: solve Ax = b, leaving A and b untouched.
Number-type abstraction for the templated API port.
MATLAB's OPTIONS struct, with the same defaults infer_lqn_optget supplies.
double fd_floor
minimum absolute perturbation scale
bool clamp_positive
clamp each estimate to at least fd_floor
std::vector< T > a_true
ground truth for Ea, empty for none
double fd_step
relative finite-difference step
MATLAB's [ahat, info] return list.
MATLAB's OPTIONS struct for infer_lqn, with the same defaults the infer_lqn_optget calls supply.
double gammaT
T/Tstar ratio used in R.
std::vector< T > a0
initial estimate, empty to read it off the model
double fdStep
relative finite-difference step
bool clampPositive
clamp each estimate to at least fdFloor
double fdFloor
minimum absolute perturbation scale
double QFac
drift-noise factor
std::vector< T > a_true
ground truth, enables the Ea metric
Matrix< T > R
explicit measurement covariance, empty for the default
bool has_gammaT
true when gammaT is given outright
double RFac
measurement-noise factor
bool has_Tstar
true when the system constant is given
Matrix< T > P0
explicit initial covariance, empty for the default
bool has_T
true when the measurement interval is given
double Tstar
system constant
double cvA
parameter drift coefficient of variation
double T_interval
measurement interval
Matrix< T > Q
explicit drift covariance, empty for the default
MATLAB's INFO struct: the EKF result plus what the driver constructed.
Matrix< T > Q
drift covariance actually used
std::vector< T > a0
initial estimate actually used
Matrix< T > R
measurement covariance actually used
EkfResult< T > ekf
the filter output, ahat included
Matrix< T > P0
initial covariance actually used
Per-element metric vectors, each aligned with the element name list.
std::vector< std::string > names
(nidx+1) declared name