LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
m3pp2m_fitc_approx.h File Reference

M3PP(2, m) fitted to counting-process characteristics with an optimized per-class split (matlab/lib/m3a/m3a/m3pp/m3pp2m_fitc_approx.m, matlab/lib/m3a/m3a/m3pp/m3pp2m_fitc_approx_ag.m, matlab/lib/m3a/m3a/m3pp/m3pp2m_fitc_approx_ag_multiclass.m). More...

#include <cstddef>
#include <vector>
#include "line/api/mam/map_fit_detail.h"
#include "line/api/mam/map_moment.h"
#include "line/api/mam/map_transform.h"
#include "line/api/mam/mmap_lambda.h"
#include "line/api/mam/mmpp2_fitc_approx.h"
#include "line/num/number.h"
#include "line/util/auglag.h"
#include "line/util/error.h"
#include "line/util/matrix.h"
Include dependency graph for m3pp2m_fitc_approx.h:

Go to the source code of this file.

Classes

struct  line::mam::M3pp2mFitcApproxResult< T >
 Result of the optimization-based M3PP(2, m) fits. More...

Namespaces

namespace  line
namespace  line::mam

Functions

template<class T>
Mmap< T > line::mam::m3pp2m_assemble (const Map< T > &base, const std::vector< T > &q1, const std::vector< T > &q2)
 Assemble the M3PP from an underlying MAP and the per-phase marking probabilities.
template<class T>
M3pp2mFitcApproxResult< T > line::mam::m3pp2m_fitc_approx (const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const std::vector< T > &ai, const std::vector< T > &dvt3, const T &t3, const std::vector< Bound< T > > &bounds, const AugLagOptions< T > &opt)
 m3pp2m_fitc_approx: fit the underlying MMPP(2) by optimization, then split the classes on their variance DIFFERENCES at t3.
template<class T>
M3pp2mFitcApproxResult< T > line::mam::m3pp2m_fitc_approx (const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const std::vector< T > &ai, const std::vector< T > &dvt3, const T &t3)
 m3pp2m_fitc_approx with no box on the free variables and the default tuning.
template<class T>
M3pp2mFitcApproxResult< T > line::mam::m3pp2m_fitc_approx_ag_multiclass (const Map< T > &mmpp, const std::vector< T > &ai, const std::vector< T > &gt3, const T &t3, const std::vector< Bound< T > > &bounds, const AugLagOptions< T > &opt)
 m3pp2m_fitc_approx_ag_multiclass: split a GIVEN MMPP(2) into m classes on their variance-plus-covariance at t3.
template<class T>
M3pp2mFitcApproxResult< T > line::mam::m3pp2m_fitc_approx_ag_multiclass (const Map< T > &mmpp, const std::vector< T > &ai, const std::vector< T > &gt3, const T &t3)
 m3pp2m_fitc_approx_ag_multiclass with no box and the default tuning.
template<class T>
M3pp2mFitcApproxResult< T > line::mam::m3pp2m_fitc_approx_ag (const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const std::vector< T > &ai, const std::vector< T > &gt3, const T &t3, const std::vector< Bound< T > > &bounds, const AugLagOptions< T > &opt)
 m3pp2m_fitc_approx_ag: fit the underlying MMPP(2) by optimization, then apply the 'ag' per-class split.
template<class T>
M3pp2mFitcApproxResult< T > line::mam::m3pp2m_fitc_approx_ag (const T &a, const T &bt1, const T &bt2, const T &binf, const T &m3t2, const T &t1, const T &t2, const std::vector< T > &ai, const std::vector< T > &gt3, const T &t3)
 m3pp2m_fitc_approx_ag with no box and the default tuning.

Detailed Description

M3PP(2, m) fitted to counting-process characteristics with an optimized per-class split (matlab/lib/m3a/m3a/m3pp/m3pp2m_fitc_approx.m, matlab/lib/m3a/m3a/m3pp/m3pp2m_fitc_approx_ag.m, matlab/lib/m3a/m3a/m3pp/m3pp2m_fitc_approx_ag_multiclass.m).

The underlying MMPP(2) comes from mmpp2_fitc_approx. The per-class split is then a pair of per-phase marking probabilities (q1i, q2i) per class, each an AFFINE function of the class rate ai (matched exactly) and of one free per-class quantity:

  • the non-'ag' variant frees dvi, the difference between the variance of class i and that of all other classes combined at resolution t3;
  • the 'ag' variant frees gi, the sum of the variance of class i and its covariance with all other classes combined at t3. Since m3pp2m_fitc.h can match only m - 1 of those exactly (the last class absorbs the remainder), the reference instead asks for the least-squares compromise over ALL m classes, subject to the marking probabilities being non-negative and summing to one in each phase. That is a quadratic program:

min sum_i (x_i / target_i - 1)^2 s.t. q1i(x_i) >= 0, q2i(x_i) >= 0 for every class i sum_i q1i(x_i) = 1, sum_i q2i(x_i) = 1

(the reference writes the objective as 1/2 x'Hx + f'x with H = diag(2/t_i^2) and f_i = -2/t_i, which is the expansion of the sum above minus the constant m; its reported fit_error = fx + m is therefore exactly the sum above, and that is what M3pp2mFitcApproxResult::class_objective holds).

Because the two coefficients q1i_dvi and q2i_dvi do not depend on i, both equality rows constrain only sum_i x_i; they have rank one and, as the algebra of the reference guarantees, a consistent right-hand side, so the program is a single equality plus 2m inequalities.

ACCEPTANCE CONTRACT (see line/util/auglag.h). MATLAB solves the QP with quadprog (interior-point-convex) or the bundled Goldfarb-Idnani QP; the JAR uses OSQP. This port uses the augmented Lagrangian with a Levenberg-Marquardt inner solver on the residual (x_i/target_i - 1). The iterates do not match any of them. What is guaranteed and tested is the specification:

  1. the returned MMAP is valid – sum_i Dc_i = D1 and every Dc_i non-negative to the toolbox feasibility tolerance 1e-8, and the underlying (D0, D1) passes map_isfeasible (see mmap_isfeasible_tol);
  2. the per-class rates are matched exactly, by construction;
  3. the achieved objective (the reference's fit_error) is returned so it can be compared against any other QP solver's on the same input;
  4. when the requested per-class targets are those of an actual M3PP(2, m), the objective reaches zero and the achieved targets, recomputed independently with mmap_count_var, reproduce the requested ones.

REFERENCE DEFECTS (matlab/lib/m3a/m3a/m3pp/m3pp2m_fitc_approx.m):

  1. the QP call reads [x,fx] = QP(H, h, A, b, Aeq, beq, lb, ub, options), but h is never defined in that function – the linear term is built as f. Every call therefore raises "Unrecognized function or variable 'h'" before the QP runs, so this MATLAB entry point cannot execute. The '_ag' path is unaffected: m3pp2m_fitc_approx_ag_multiclass.m calls quadprog(H, f, ...) correctly.
  2. the same dead call passes lb = 1e-6 * ones(m,1). The free variables are variance DIFFERENCES, which are routinely negative (a minority class has less variance than all others combined), and the equality row fixes their sum, which is negative on ordinary inputs. Reproduction: for the MMPP(2) l1 = 2, l2 = 0.5, r1 = 0.3, r2 = 0.7 at t3 = 1 the equality forces sum_i x_i = -1.8976, so with m = 3 and lb = 1e-6 the feasible set is empty. This port therefore leaves the box unconstrained by default – which is what the sibling _ag_multiclass does, its quadprog call passing [] for lb and ub – and exposes optional bounds for a caller that wants them. MATLAB was NOT edited.

DIVERGENCE FROM THE JAR: M3pp2m_fitc_approx.java and M3pp2m_fitc_approx_ag_multiclass.java add 2m further inequality rows (q1i <= 1, q2i <= 1) that neither MATLAB file has, and then project the solution post hoc with max(0, q) followed by a row renormalization. The extra rows can make a program infeasible that MATLAB solves, and the projection silently changes the fitted per-class rates. This port follows MATLAB: 2m rows, no post-hoc projection, and the infeasibility of the result reported through M3pp2mFitcApproxResult::feasible rather than repaired.

Gated on transcendental arithmetic.

Definition in file m3pp2m_fitc_approx.h.