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

Replace every non-Markovian service and firing law by a Markovian surrogate. More...

#include <cmath>
#include <cstddef>
#include <functional>
#include <map>
#include <vector>
#include "line/api/mam/cme.h"
#include "line/api/mam/hyperexp_fit_longtail.h"
#include "line/api/mam/map_bernstein.h"
#include "line/api/mam/map_moment.h"
#include "line/api/mam/map_transform.h"
#include "line/api/sn/sn_is_phasetype.h"
#include "line/lang/distribution.h"
#include "line/lang/lang_types.h"
#include "line/lang/qn/network_struct.h"
#include "line/num/number.h"
#include "line/util/error.h"
Include dependency graph for sn_nonmarkov_toph.h:

Go to the source code of this file.

Classes

struct  line::api::NonmarkovOptions
 options.config.nonmkv and friends. More...

Namespaces

namespace  line
namespace  line::api

Enumerations

enum class  line::api::PhFit { line::api::Cme , line::api::Ph , line::api::Hyperexp }
 Which Markovian surrogate to fit; options.config.phfit. More...

Functions

template<class T>
bool line::api::sn_has_nonmarkov (const qn::NetworkStruct< T > &sn, bool preserve_det=false)
 Whether any law in the struct would be replaced, so a caller can skip copying the struct when there is nothing to convert.
template<class T>
void line::api::sn_nonmarkov_toph (qn::NetworkStruct< T > &sn, const NonmarkovOptions &opts=NonmarkovOptions())
 Replace every non-Markovian service and firing law by a Markovian surrogate.

Detailed Description

Replace every non-Markovian service and firing law by a Markovian surrogate.

Templated port of matlab/src/api/sn/sn_nonmarkov_toph.m, mirrored by jline.api.sn.SnNonmarkovToPh and the native Python sn_nonmarkov_toph. The MAM, CTMC, Fluid and SSA analyzers all run it on their own copy of the struct before any state space is built, so a Gamma, Weibull, Lognormal, Pareto, Uniform or Det service law reaches an algorithm that only understands generators.

IT IS NOT convertToMAP. The struct refresh already lowers those families to an Erlang of ceil(1/scv) phases (dist_to_map in lang/distribution.h); that fit matches the mean and, above SCV 1, nothing else. This is the SOLVER-side conversion, with an explicit phase budget (20 by default) and a choice of fit:

  • phfit = Cme, the default: a concentrated matrix exponential convolved with an exponential (dist_fit_me), which matches the first TWO moments exactly whenever the SCV is in (0,1). It is what makes an M/G/1 mean come out right: on M/Gamma/1 at rho 0.5 the two-moment fit lands on the exact mean queue length where the density fit lands 2.7e-2 away.
  • phfit = Ph: the Bernstein density fit (map_bernstein), kept because it carries SHAPE information a two-moment fit cannot, and because SSA, Fluid and JMT cannot consume a matrix exponential at all.

DET IS ERLANG, WHATEVER phfit ASKS FOR. A concentrated ME matches a Det's moments far better (SCV 5.7e-3 against Erlang-20's 0.05) but is not a generator: its off-diagonal entries are not rates, so a CTMC built from it does not describe the model. Measured on the reference's test_OQN_DM1 (Det(1) arrivals, Exp(2) service, rho = 0.5), the ME surrogate reported U = 0.993 and a departure rate of 2.0 against a mean interarrival of 1.0, where JMT gives 0.497, LDES 0.502 and the golden 0.500.

WHAT IS NOT TOUCHED. The Markovian families, DISABLED, IMMEDIATE, and the three time-inhomogeneous families NHPP / MAPt / PHt, whose whole content is the schedule – collapsing one to a single homogeneous surrogate would erase the time dependence that is the reason it was declared.

NO STATE SURGERY IS NEEDED HERE. The MATLAB reference rewrites sn.phases, phasessz, phaseshift, mu, phi, pie and then splices extra columns into any pre-initialized sn.state and sn.space, because those are stored arrays that would otherwise disagree with the new phase count. In this port every one of them is DERIVED from sn.service[i][r] on demand (phases_of, dist_pie, dist_to_map), so replacing the distribution updates all of them at once and there is nothing left to splice. Callers run this before generating states, exactly as the reference's analyzers do.

ARITHMETIC: transcendental. The fits evaluate densities and take square roots, so this does not instantiate under Rational.

Definition in file sn_nonmarkov_toph.h.