5#ifndef LINE_API_MAM_MMPP2_FITC_APPROX_H
6#define LINE_API_MAM_MMPP2_FITC_APPROX_H
106T mmpp2_idc_at(
const T& l1,
const T& l2,
const T& r1,
const T& r2,
const T& tt) {
110 const T E = num_exp(T(-(r1 + r2) * tt));
111 const T inner = r1 * (two * l1 * l1 * r2 * r2 * tt - two * l2 * l2 * r2 - two * l1 * l1 * r2 +
112 two * l2 * l2 * r2 * r2 * tt + four * l1 * l2 * r2 +
113 two * l1 * l1 * r2 * E + two * l2 * l2 * r2 * E -
114 four * l1 * l2 * r2 * r2 * tt - four * l1 * l2 * r2 * E) +
115 r1 * r1 * (two * r2 * tt * l1 * l1 - four * r2 * tt * l1 * l2 +
116 two * r2 * tt * l2 * l2);
117 return inner / (tt * pw(T(r1 + r2), 3) * (l1 * r2 + l2 * r1)) + one;
121Mmpp2Chars<T> mmpp2_chars(
const T& l1,
const T& l2,
const T& r1,
const T& r2,
const T& a,
122 const T& t1,
const T& t2,
bool same_scale) {
123 const T one = num_traits<T>::from_int(1);
124 const T two = num_traits<T>::from_int(2);
125 const T three = num_traits<T>::from_int(3);
126 const T four = num_traits<T>::from_int(4);
127 const T six = num_traits<T>::from_int(6);
130 c.xa = (l1 * r2 + l2 * r1) / (r1 + r2);
131 const T factor = a / c.xa;
133 c.xbt1 = mmpp2_idc_at(l1, l2, r1, r2, T(t1 * factor));
134 c.xbt2 = same_scale ? c.xbt1 : mmpp2_idc_at(l1, l2, r1, r2, T(t2 * factor));
136 c.xbinf = ((two * r2 * l1 * l1 - four * r2 * l1 * l2 + two * r2 * l2 * l2) * r1 * r1 +
137 (two * l1 * l1 * r2 * r2 - four * l1 * l2 * r2 * r2 + two * l2 * l2 * r2 * r2) * r1) /
138 (pw(T(r1 + r2), 3) * (l1 * r2 + l2 * r1)) +
141 const T t = t2 * factor;
143 const T p = (l1 - l2) * (r1 - r2);
144 const T Etd = num_exp(T(-t * d));
145 const T bm1 = c.xbinf - one;
146 const T xg3t = pw(c.xa, 3) * pw(t, 3) + three * c.xa * c.xa * bm1 * t * t +
147 three * c.xa * bm1 / d * (p / d - c.xa) * t +
148 three * c.xa / (d * d) * bm1 * (p + c.xa * d) * t * Etd -
149 six * c.xa / pw(d, 3) * bm1 * p * (one - Etd);
150 c.xm3t2 = xg3t - three * c.xa * t * (c.xa * t - one) * c.xbt2 -
151 c.xa * t * (c.xa * t - one) * (c.xa * t - two);
170 const T& m3t2,
const T& t1,
const T& t2,
173 "mmpp2_fitc_approx requires transcendental arithmetic");
176 if (a <= zero)
throw InputError(
"mmpp2_fitc_approx: non-positive arrival rate");
177 if (t1 <= zero || t2 <= zero)
throw InputError(
"mmpp2_fitc_approx: non-positive time scale");
178 if (bt1 == zero || bt2 == zero || binf == zero || m3t2 == zero)
179 throw InputError(
"mmpp2_fitc_approx: a target characteristic is zero, so the relative "
180 "objective of the reference is undefined");
182 const bool same_scale = t1 == t2;
183 const std::size_t nres = same_scale ? 4 : 5;
185 auto resid = [a, bt1, bt2, binf, m3t2, t1, t2, same_scale, one](
const std::vector<T>& x) {
186 const fitdetail::Mmpp2Chars<T> c =
187 fitdetail::mmpp2_chars(x[0], x[1], x[2], x[3], a, t1, t2, same_scale);
189 r.push_back(T(c.xa / a - one));
190 r.push_back(T(c.xbt1 / bt1 - one));
191 if (!same_scale) r.push_back(T(c.xbt2 / bt2 - one));
192 r.push_back(T(c.xbinf / binf - one));
193 r.push_back(T(c.xm3t2 / m3t2 - one));
199 auto g = [lmin, zero](
const std::vector<T>& x) {
200 std::vector<T> gv(4);
208 std::vector<T> x0(4);
216 const T l1 = sol.
x[0];
217 const T l2 = sol.
x[1];
218 const T r1 = sol.
x[2];
219 const T r2 = sol.
x[3];
224 m.
D0(0, 0) = -(l1 + r1);
227 m.
D0(1, 1) = -(l2 + r2);
242 const T& m3t2,
const T& t1,
const T& t2) {
Augmented Lagrangian method for equality- and inequality-constrained minimization,...
The exception types the port throws.
Scalar helpers shared by the MAP/PH moment-matching headers.
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Dense matrix and non-owning view.
Mmpp2FitcApproxResult< T > mmpp2_fitc_approx(const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const AugLagOptions< T > &opt)
Fit an MMPP(2) to counting characteristics.
Map< T > map_scale(const Map< T > &in, const T &new_mean)
Rescale time so that the mean inter-arrival time becomes new_mean.
AugLagOptions< T > auglag_defaults()
Defaults: rho0 = 10, growth 10, feasibility 1e-10, 50 outer iterations.
AugLagResult< T > auglag_ls(R r, std::size_t m, H h, G g, const std::vector< T > &x0, const AugLagOptions< T > &opt)
Augmented Lagrangian with a least-squares objective and levmar as the inner solver.
Number-type abstraction for the templated API port.
Tuning of the outer multiplier iteration.
Outcome of a constrained solve.
std::vector< T > x
best point found
T violation
max(|h_i|, max(0, g_j)) at x
T fval
the ORIGINAL objective f(x), not the augmented one
A constraint map that returns no constraints; the default for h or g.
A MAP as the pair of matrices (D0, D1).
Result of mmpp2_fitc_approx.
Map< T > map
the fitted MMPP(2), rescaled to rate a
T objective
sum of squared relative errors at the optimum
T violation
worst bound violation at the optimum
bool converged
the constrained solve reached feasibility within its caps