5#ifndef LINE_API_MAM_MAPH2M_FIT_H
6#define LINE_API_MAM_MAPH2M_FIT_H
90 const std::vector<T>& B,
91 const std::vector<T>& classWeights = std::vector<T>()) {
93 "maph2m_fit_multiclass solves a quadratic program");
95 if (aph.
D0.rows() != 2)
throw InputError(
"maph2m_fit_multiclass: the APH must be second order");
97 throw InputError(
"maph2m_fit_multiclass: the APH must be acyclic");
99 throw InputError(
"maph2m_fit_multiclass: the APH must be in canonical acyclic form");
101 const std::size_t k = p.size();
102 if (k == 0)
throw InputError(
"maph2m_fit_multiclass: no classes given");
104 throw InputError(
"maph2m_fit_multiclass: one backward moment per class is required");
105 std::vector<T> w = classWeights;
106 if (w.empty()) w.assign(k, one);
107 if (w.size() != k)
throw InputError(
"maph2m_fit_multiclass: one weight per class is required");
109 const T h1 = T(-one / aph.
D0(0, 0));
110 const T h2 = T(-one / aph.
D0(1, 1));
111 const T r1 = T(aph.
D0(0, 1) * h1);
118 std::vector<std::vector<T>> q(2, std::vector<T>(k, zero));
121 const double degentol = 1e-6, feastol = 1e-8;
124 for (std::size_t c = 0; c < k; ++c) {
129 std::vector<std::vector<T>> qb(2, std::vector<T>(k, zero));
130 std::vector<std::vector<T>> q0(2, std::vector<T>(k, zero));
131 for (std::size_t c = 0; c < k; ++c) {
132 qb[0][c] = T(p[c] * (one / (h2 * (r1 - one))));
133 q0[0][c] = T(p[c] * (-(h1 + h2) / (h2 * (r1 - one))));
134 qb[1][c] = T(p[c] * (one / (h2 * r1)));
135 q0[1][c] = T(p[c] * (-h1 / (h2 * r1)));
140 auto fobj = [&](
const std::vector<T>& x) {
142 for (std::size_t c = 0; c < k; ++c) {
143 const T r = T(x[c] / B[c] - one);
148 auto heq = [&](
const std::vector<T>& x) {
149 std::vector<T> v(2, zero);
150 for (std::size_t j = 0; j < 2; ++j) {
152 for (std::size_t c = 0; c < k; ++c) s += qb[j][c] * x[c] + q0[j][c];
157 auto gineq = [&](
const std::vector<T>& x) {
160 for (std::size_t c = 0; c < k; ++c)
161 for (std::size_t j = 0; j < 2; ++j) {
162 const T qq = T(qb[j][c] * x[c] + q0[j][c]);
163 v.push_back(T(qq - one));
169 std::vector<T> x0 = B;
170 std::vector<Bound<T>> bounds(k);
171 for (std::size_t c = 0; c < k; ++c) {
174 if (x0[c] < bounds[c].lo) x0[c] = bounds[c].lo;
175 if (x0[c] > bounds[c].hi) x0[c] = bounds[c].hi;
180 for (std::size_t c = 0; c < k; ++c)
181 for (std::size_t j = 0; j < 2; ++j) q[j][c] = T(r.
x[c] * qb[j][c] + q0[j][c]);
185 for (std::size_t j = 0; j < 2; ++j) {
186 T lo = q[j][0], s = zero;
187 for (std::size_t c = 0; c < k; ++c) {
188 if (q[j][c] < lo) lo = q[j][c];
194 "maph2m_fit_multiclass: feasibility could not be restored; the requested class "
195 "probabilities and backward moments admit no valid split of the APH(2) exit flows");
197 for (std::size_t j = 0; j < 2; ++j) {
199 for (std::size_t c = 0; c < k; ++c) {
200 if (q[j][c] < zero) q[j][c] = zero;
204 throw NumericError(
"maph2m_fit_multiclass: a split lost all its mass");
205 for (std::size_t c = 0; c < k; ++c) q[j][c] = T(q[j][c] / s);
210 for (std::size_t c = 0; c < k; ++c) {
211 out.
maph.Dc[c](0, 0) = T(out.
maph.D1(0, 0) * q[0][c]);
212 out.
maph.Dc[c](1, 0) = T(out.
maph.D1(1, 0) * q[1][c]);
215 const std::vector<std::vector<T>> bm =
217 out.
fB.assign(k, zero);
218 for (std::size_t c = 0; c < k; ++c) out.
fB[c] = bm[c][0];
229 const std::vector<T>& B) {
231 if (a.
aphs.empty())
throw NumericError(
"maph2m_fit: no APH(2) fits the given moments");
233 double bestErr = 0.0;
235 for (std::size_t j = 0; j < a.
aphs.size(); ++j) {
239 }
catch (
const Error&) {
243 for (std::size_t c = 0; c < p.size(); ++c) {
247 if (!have || err < bestErr) {
255 "maph2m_fit: no APH(2) form admits a valid class split for the requested class "
256 "probabilities and backward moments");
263 const std::vector<T> p =
mmap_pc(m);
264 const std::vector<std::vector<T>> bm =
267 for (std::size_t c = 0; c < p.size(); ++c) B[c] = bm[c][0];
279 if (Tv.empty() || Tv.size() != A.size())
280 throw InputError(
"maph2m_fit_trace: the trace and its labels must agree in length");
282 T m1 = zero, m2 = zero, m3 = zero;
283 for (std::size_t i = 0; i < Tv.size(); ++i) {
292 std::vector<T> B(p.size(), zero);
293 for (std::size_t c = 0; c < p.size(); ++c) B[c] = bm(c, 0);
294 return maph2m_fit(T(m1 / n), T(m2 / n), T(m3 / n), p, B);
APH(2) fit of three moments, with a fallback to adjusted moments (matlab/lib/m3a/m3a/aph2/aph2_fit....
Augmented Lagrangian method for equality- and inequality-constrained minimization,...
Base error for the multiprecision C++ port.
NumericError(const std::string &what)
The exception types the port throws.
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Dense matrix and non-owning view.
Compression of a marked MAP into a smaller representation, and the two M3A primitives it is built fro...
Marked MAP (MMAP) algebra: per-class rates, class probabilities, superposition, normalization and sca...
Backward moments of a marked trace: the moments of the inter-arrival time that PRECEDES an event of e...
Class probabilities of a marked trace, p_c = count_c / N.
Mmap< T > maph2m_fit(const T &M1, const T &M2, const T &M3, const std::vector< T > &p, const std::vector< T > &B)
Fit a MAPH(2,m) to three moments, the class probabilities and the per-class backward moments,...
Aph2FitResult< T > aph2_fit(const T &M1, const T &M2, const T &M3)
Fit an APH(2) to (M1, M2, M3), relaxing the moments if necessary.
Mmap< T > maph2m_fit_mmap(const Mmap< T > &m)
Fit a MAPH(2,m) to the descriptors measured on a marked MAP.
Mmap< T > maph2m_fit_trace(const std::vector< T > &Tv, const std::vector< int > &A)
Fit a MAPH(2,m) to the descriptors measured on a marked trace.
std::vector< std::vector< T > > mmap_backward_moment(const Mmap< T > &m, const std::vector< unsigned > &orders, bool normalized)
Class-conditional backward moments of an MMAP (mmap_backward_moment.m).
std::vector< T > mmap_pc(const Mmap< T > &m)
Class probabilities seen by an arriving job, pc = pie (-D0)^-1 D1^(c) e.
T map_moment(const Map< T > &m, unsigned k)
Raw moment of order k of the inter-arrival time: k!
Maph2mFitResult< T > maph2m_fit_multiclass(const Map< T > &aph, const std::vector< T > &p, const std::vector< T > &B, const std::vector< T > &classWeights=std::vector< T >())
Mark a canonical acyclic APH(2) with m classes.
Matrix< T > mtrace_backward_moment(const std::vector< T > &Tv, const std::vector< int > &A, const std::vector< unsigned > &orders, bool norm=true)
Backward moments of a marked trace: the moments of the inter-arrival time that PRECEDES an event of e...
std::vector< T > mtrace_pc(const std::vector< int > &A)
Class probabilities of a marked trace, p_c = count_c / N.
AugLagResult< T > auglag(F f, H h, G g, const std::vector< T > &x0, const std::vector< Bound< T > > &bounds, const AugLagOptions< T > &opt)
Augmented Lagrangian with a scalar objective and a simplex inner solver.
Number-type abstraction for the templated API port.
Outcome of a constrained solve.
std::vector< T > x
best point found
std::vector< Map< T > > aphs
every feasible form found
A MAP as the pair of matrices (D0, D1).
The fitted MAPH and the backward moments it actually achieved.
std::vector< T > fB
achieved per-class backward moments
An MMAP: the underlying MAP plus the per-class arrival matrices.