![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
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"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. | |
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:
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.