5#ifndef LINE_API_MAM_DMAP_OPTIM_DIST_H
6#define LINE_API_MAM_DMAP_OPTIM_DIST_H
52namespace dmapoptdetail {
61void build_constraints_d(
const Matrix<T>& B0,
const std::vector<T>& alB, Matrix<T>* Aeq,
62 std::vector<T>* beq) {
63 const std::size_t n = B0.rows();
64 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
66 Matrix<T> ImB0(n, n, zero);
67 for (std::size_t i = 0; i < n; ++i)
68 for (std::size_t j = 0; j < n; ++j) ImB0(i, j) = (i == j ? one : zero) - B0(i, j);
71 Matrix<T> tr(n, n, zero);
72 for (std::size_t i = 0; i < n; ++i)
73 for (std::size_t j = 0; j < n; ++j) tr(i, j) = ImB0(j, i);
74 const std::vector<T> row =
solve(tr, alB);
76 Matrix<T> rowM(1, n, zero);
77 for (std::size_t j = 0; j < n; ++j) rowM(0, j) = row[j];
78 Matrix<T> I(n, n, zero);
79 for (std::size_t i = 0; i < n; ++i) I(i, i) = one;
80 Matrix<T> ones1(1, n, one);
82 const Matrix<T> top = optdistdetail::mkron(I, rowM);
83 const Matrix<T> bot = optdistdetail::mkron(ones1, I);
85 for (std::size_t i = 0; i < n; ++i)
86 for (std::size_t j = 0; j < n * n; ++j) {
87 (*Aeq)(i, j) = top(i, j);
88 (*Aeq)(n + i, j) = bot(i, j);
90 beq->assign(2 * n, zero);
91 for (std::size_t i = 0; i < n; ++i) {
94 for (std::size_t j = 0; j < n; ++j) s += ImB0(i, j);
108 const std::vector<T>& alB,
unsigned L) {
110 const std::size_t n = B0.
rows();
111 if (n == 0 || B0.
cols() != n)
throw InputError(
"dmap_optim_dist: B0 must be square");
112 if (alB.size() != n)
throw InputError(
"dmap_optim_dist: alB has the wrong length");
113 if (alA.size() != a.
D0.rows())
throw InputError(
"dmap_optim_dist: alA has the wrong length");
114 if (L == 0)
throw InputError(
"dmap_optim_dist: at least one lag is required");
120 dmapoptdetail::build_constraints_d(B0, alB, &Aeq, &beq);
122 auto obj = [&a, &B0, &alA, &alB, L, n](
const std::vector<T>& x) {
125 b.
D1 = optdistdetail::unvec(x, n);
130 for (std::size_t i = 0; i < n; ++i) {
132 for (std::size_t j = 0; j < n; ++j) s += (i == j ? one : zero) - B0(i, j);
133 for (std::size_t j = 0; j < n; ++j)
138 const std::vector<T> sol =
139 optdistdetail::constrained_min(obj, Aeq, beq, optdistdetail::vec(seed), lo);
140 out.
B1 = optdistdetail::unvec(sol, n);
155 const Matrix<T>& B0,
const std::vector<T>& alB) {
157 "dmap_optim_dist_acf needs the D-MAP distances");
158 const std::size_t n = B0.
rows();
159 if (n == 0 || B0.
cols() != n)
throw InputError(
"dmap_optim_dist_acf: B0 must be square");
160 if (alB.size() != n)
throw InputError(
"dmap_optim_dist_acf: alB has the wrong length");
161 if (alA.size() != a.
D0.rows())
162 throw InputError(
"dmap_optim_dist_acf: alA has the wrong length");
168 dmapoptdetail::build_constraints_d(B0, alB, &Aeq, &beq);
170 auto obj = [&a, &B0, &alA, &alB, n](
const std::vector<T>& x) {
173 b.
D1 = optdistdetail::unvec(x, n);
177 for (std::size_t i = 0; i < n; ++i) {
179 for (std::size_t j = 0; j < n; ++j) s += (i == j ? one : zero) - B0(i, j);
180 for (std::size_t j = 0; j < n; ++j)
185 const std::vector<T> sol =
186 optdistdetail::constrained_min(obj, Aeq, beq, optdistdetail::vec(seed), lo);
187 out.
B1 = optdistdetail::unvec(sol, n);
Discrete-time Markovian arrival processes (D-MAPs).
The exception types the port throws.
LU factorization with partial pivoting, templated on the number type.
Fit the D1 of a MAP by MINIMIZING a distance to a reference MAP.
Dense matrix and non-owning view.
T dmap_dist_acf(const Dmap< T > &a, const Dmap< T > &b, const std::vector< T > &alA, const std::vector< T > &alB)
Squared distance between the autocorrelation structures of two D-MAPs.
T dmap_dist(const Dmap< T > &a, const Dmap< T > &b, unsigned L, const std::vector< T > &alA, const std::vector< T > &alB)
Squared L2 distance between the interarrival densities truncated at lag L.
MapOptimDist< T > dmap_optim_dist_acf(const Dmap< T > &a, const std::vector< T > &alA, const Matrix< T > &B0, const std::vector< T > &alB)
Fit B1 minimizing the AUTOCORRELATION distance, with B0 fixed.
MapOptimDist< T > dmap_optim_dist(const Dmap< T > &a, const std::vector< T > &alA, const Matrix< T > &B0, const std::vector< T > &alB, unsigned L)
Fit B1 minimizing the lag-L joint-PMF distance to a, with B0 fixed.
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.
A discrete-time MAP: substochastic D0 (no arrival) and D1 (one arrival).
What an optimizing distance fit returns.
Matrix< T > B1
the fitted D1
bool global
true only on the convex lag-1 path