LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
solver.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_SOLVERS_SOLVER_H
6#define LINE_SOLVERS_SOLVER_H
7
8/**
9 * @file
10 * @ingroup line_solvers
11 * @ingroup line_public
12 * The solver API a user writes, spelled as its Python twin.
13 *
14 * SolverMVA s(model, "lin");
15 * AvgTable t = s.avg_table();
16 *
17 * against Python's
18 *
19 * s = MVA(model, method='lin')
20 * t = s.avg_table()
21 *
22 * NAMING. A multi-word getter drops the `get_` prefix (`avg_table`,
23 * `tran_avg`, `cdf_respt`), because `line_solver/_aliasing.py` resolves exactly
24 * that spelling onto Python's own `getAvgTable`/`getTranAvg`/`getCdfRespT`; a
25 * SINGLE-word getter keeps it (`get_name`), because that same module
26 * deliberately refuses to expand a bare lowercase word and Python has no
27 * `name()`. So every name here is a name that also resolves in Python.
28 *
29 * IT IS A FACADE, NOT A SOLVER. Every method forwards to the runner the CLI
30 * calls, so a program written against this header and `line-cli` on the same
31 * model answer with the same numbers.
32 *
33 * THESE CLASSES ARE `double`-ONLY AND NOT TEMPLATES, deliberately. The solver
34 * templates are a heavy instantiation and the multiprecision arithmetic has no
35 * Python counterpart, so the bodies are compiled ONCE into `line_mp_api` and a
36 * translation unit including this header pays for none of it. Reach for
37 * `line::mva::solver_mva_run_analyzer` and its siblings directly when you want
38 * another arithmetic.
39 */
40
41#include <cstddef>
42#include <string>
43#include <vector>
44
48#include "line/util/matrix.h"
49
50namespace line {
51
52/** `Network` as a user names it: the `double` model, Python's `Network`. */
54/** `model.init_routing_matrix()`'s type, Python's `RoutingMatrix`. */
56
57/**
58 * The shared surface of every solver, Python's `NetworkSolver`.
59 *
60 * The solve is performed on first demand and cached, which is what
61 * `hasResults`/`is_solved` reports; `reset()` discards it.
62 */
64 public:
65 virtual ~NetworkSolver() {}
66
67 /** `getName()`: the solver's own name, e.g. "MVA". */
68 const std::string& get_name() const { return name_; }
69 /** The options this solver was built with. */
70 const SolverOptions& options() const { return opts_; }
71 /** The model this solver was built on. */
72 Network& model() const { return *model_; }
73
74 /** `getAvgTable()`: the average table, solving on first demand. */
75 const AvgTable& avg_table();
76 /** `getAvgSysTable()`: the per-class system columns of the same solve. */
77 const AvgTable& avg_sys_table() { return avg_table(); }
78 /** `runAnalyzer()`: force the solve, returning the table it produced. */
79 const AvgTable& run_analyzer() { return avg_table(); }
80 /** `listValidMethods()`: the methods this solver advertises on this model. */
81 std::vector<std::string> list_valid_methods() const;
82 /** `isSolved()` / `hasResults()`: whether a solve has been performed. */
83 bool is_solved() const { return solved_; }
84 /** `reset()`: discard the cached solve. */
85 void reset() { solved_ = false; table_ = AvgTable(); }
86 /** `getMethodUsed()`: the method the solve actually resolved to. */
87 std::string method_used();
88
89 protected:
90 NetworkSolver(Network& m, const std::string& name, const SolverOptions& o)
91 : model_(&m), name_(name), opts_(o) {}
92
94 std::string name_;
97 bool solved_ = false;
98};
99
100/**
101 * Every solver takes the model and either a method name or a full option set,
102 * mirroring Python's `SolverX(model, method_or_options=None, **kwargs)`.
103 */
104#define LINE_DECLARE_SOLVER(Cls, tag) \
105 class Cls : public NetworkSolver { \
106 public: \
107 explicit Cls(Network& m, const SolverOptions& o = SolverOptions()) \
108 : NetworkSolver(m, tag, o) {} \
109 Cls(Network& m, const std::string& method) \
110 : NetworkSolver(m, tag, SolverOptions().set_method(method)) {} \
111 }
112
113LINE_DECLARE_SOLVER(SolverMVA, "MVA");
114LINE_DECLARE_SOLVER(SolverNC, "NC");
115LINE_DECLARE_SOLVER(SolverMAM, "MAM");
116LINE_DECLARE_SOLVER(SolverSSA, "SSA");
117LINE_DECLARE_SOLVER(SolverJMT, "JMT");
118LINE_DECLARE_SOLVER(SolverLDES, "LDES");
119LINE_DECLARE_SOLVER(SolverAUTO, "AUTO");
120
121#undef LINE_DECLARE_SOLVER
122
123/** `SolverCTMC`: the average table plus the chain it was computed from. */
124class SolverCTMC : public NetworkSolver {
125 public:
127 : NetworkSolver(m, "CTMC", o) {}
128 SolverCTMC(Network& m, const std::string& method)
129 : NetworkSolver(m, "CTMC", SolverOptions().set_method(method)) {}
130
131 /** `getStateSpace()`: the aggregate state space, one row per state. */
133 /** `getGenerator()`: the infinitesimal generator over that space. */
135 /** `getProbAggr(node, state)`: the aggregate marginal of one state. */
136 double prob_aggr(std::size_t node, const std::vector<double>& state);
137 /** `getProbStateAggr(node)`: the marginal over every state of one station. */
138 std::vector<double> marg_aggr(std::size_t node);
139 /** `getCdfRespT()`: the response-time CDF per (station, class). */
140 std::vector<std::vector<CdfCurve> > cdf_respt();
141
142 /** `CTMC.printInfGen(Q, SS)`: the generator beside the state it belongs to. */
143 static void print_inf_gen(const Matrix<double>& Q, const Matrix<double>& space);
144};
145
146/** `SolverFLD`: the fluid solver, which also answers a transient. */
147class SolverFLD : public NetworkSolver {
148 public:
149 explicit SolverFLD(Network& m, const SolverOptions& o = SolverOptions())
150 : NetworkSolver(m, "FLD", o) {}
151 SolverFLD(Network& m, const std::string& method)
152 : NetworkSolver(m, "FLD", SolverOptions().set_method(method)) {}
153
154 /** `getTranAvg()`: the transient mean queue length per station. */
156 /** `getCdfRespT()`: the response-time CDF per (station, class). */
157 std::vector<std::vector<CdfCurve> > cdf_respt();
158};
159
160/** `SolverBA`: the bounding solver, whose result is a bounds table. */
161class SolverBA : public NetworkSolver {
162 public:
163 explicit SolverBA(Network& m, const SolverOptions& o = SolverOptions())
164 : NetworkSolver(m, "BA", o) {}
165 SolverBA(Network& m, const std::string& method)
166 : NetworkSolver(m, "BA", SolverOptions().set_method(method)) {}
167
168 /** `getBoundsTable()`: the per-class queue-length and throughput bounds. */
170};
171
172// Python's short aliases: `MVA(model)` is `SolverMVA(model)`.
173typedef SolverMVA MVA;
174typedef SolverNC NC;
176typedef SolverSSA SSA;
179typedef SolverMAM MAM;
180typedef SolverJMT JMT;
181typedef SolverLDES LDES;
182typedef SolverAUTO AUTO;
183typedef SolverBA BA;
184
185} // namespace line
186
187#endif // LINE_SOLVERS_SOLVER_H
The result tables a solver returns.
const AvgTable & avg_sys_table()
getAvgSysTable(): the per-class system columns of the same solve.
Definition solver.h:77
AvgTable table_
Definition solver.h:96
const SolverOptions & options() const
The options this solver was built with.
Definition solver.h:70
const std::string & get_name() const
getName(): the solver's own name, e.g.
Definition solver.h:68
SolverOptions opts_
Definition solver.h:95
std::string method_used()
getMethodUsed(): the method the solve actually resolved to.
const AvgTable & run_analyzer()
runAnalyzer(): force the solve, returning the table it produced.
Definition solver.h:79
Network * model_
Definition solver.h:93
std::vector< std::string > list_valid_methods() const
listValidMethods(): the methods this solver advertises on this model.
const AvgTable & avg_table()
getAvgTable(): the average table, solving on first demand.
virtual ~NetworkSolver()
Definition solver.h:65
bool is_solved() const
isSolved() / hasResults(): whether a solve has been performed.
Definition solver.h:83
Network & model() const
The model this solver was built on.
Definition solver.h:72
void reset()
reset(): discard the cached solve.
Definition solver.h:85
NetworkSolver(Network &m, const std::string &name, const SolverOptions &o)
Definition solver.h:90
std::string name_
Definition solver.h:94
SolverBA: the bounding solver, whose result is a bounds table.
Definition solver.h:161
BoundsTable bounds_table()
getBoundsTable(): the per-class queue-length and throughput bounds.
SolverBA(Network &m, const std::string &method)
Definition solver.h:165
SolverBA(Network &m, const SolverOptions &o=SolverOptions())
Definition solver.h:163
SolverCTMC: the average table plus the chain it was computed from.
Definition solver.h:124
static void print_inf_gen(const Matrix< double > &Q, const Matrix< double > &space)
CTMC.printInfGen(Q, SS): the generator beside the state it belongs to.
Matrix< double > generator()
getGenerator(): the infinitesimal generator over that space.
double prob_aggr(std::size_t node, const std::vector< double > &state)
getProbAggr(node, state): the aggregate marginal of one state.
Matrix< double > state_space()
getStateSpace(): the aggregate state space, one row per state.
SolverCTMC(Network &m, const SolverOptions &o=SolverOptions())
Definition solver.h:126
std::vector< double > marg_aggr(std::size_t node)
getProbStateAggr(node): the marginal over every state of one station.
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the response-time CDF per (station, class).
SolverCTMC(Network &m, const std::string &method)
Definition solver.h:128
SolverFLD: the fluid solver, which also answers a transient.
Definition solver.h:147
SolverFLD(Network &m, const std::string &method)
Definition solver.h:151
std::vector< std::vector< CdfCurve > > cdf_respt()
getCdfRespT(): the response-time CDF per (station, class).
TranAvg tran_avg()
getTranAvg(): the transient mean queue length per station.
SolverFLD(Network &m, const SolverOptions &o=SolverOptions())
Definition solver.h:149
A queueing network under construction.
The routing matrix a model script fills in, MATLAB's P cell array.
Dense matrix and non-owning view.
SolverSSA SSA
Definition solver.h:176
SolverAUTO AUTO
Definition solver.h:182
SolverBA BA
Definition solver.h:183
qn::RoutingMatrix< double > RoutingMatrix
model.init_routing_matrix()'s type, Python's RoutingMatrix.
Definition solver.h:55
SolverMAM MAM
Definition solver.h:179
qn::Network< double > Network
Network as a user names it: the double model, Python's Network.
Definition solver.h:53
SolverFLD FLD
Definition solver.h:177
SolverLDES LDES
Definition solver.h:181
SolverNC NC
Definition solver.h:174
SolverFLD SolverFluid
Definition solver.h:178
SolverCTMC CTMC
Definition solver.h:175
SolverJMT JMT
Definition solver.h:180
SolverMVA MVA
Definition solver.h:173
LINE_DECLARE_SOLVER(SolverMVA, "MVA")
The Network constructor API: Queue, Delay, Source, Sink, Router, ClassSwitch, Cache,...
The keyword arguments a solver takes, as one struct.
getAvgTable, one row per (station, class) that carries a metric.
Definition avg_table.h:34
SolverBA(model, method).getBoundsTable().
Definition avg_table.h:60
The knobs a solver reads; a negative or empty field keeps the engine default.
getTranAvg: the transient mean queue length per (station, class).
Definition avg_table.h:72