5#ifndef LINE_SOLVERS_ENV_ENV_DISPATCH_H
6#define LINE_SOLVERS_ENV_ENV_DISPATCH_H
126namespace dispatch_detail {
132 for (std::size_t i = 0; i < A.
rows(); ++i)
148 for (std::size_t i = 0; i < c.
caches.size(); ++i) {
156 for (std::size_t k = 0; k < m.
hitprob.size(); ++k)
158 for (std::size_t k = 0; k < m.
missprob.size(); ++k)
160 for (std::size_t k = 0; k < m.
delayedprob.size(); ++k)
162 for (std::size_t k = 0; k < m.
latency.size(); ++k)
164 for (std::size_t k = 0; k < m.
listcost.size(); ++k)
193EnvStatevecOptions<T> env_statevec_options(
const EnvOptions& o) {
194 EnvStatevecOptions<T> s;
195 s.iter_max = o.iter_max;
196 s.iter_tol = o.iter_tol;
197 s.stage_solver = o.stage_solver;
198 s.sojourn = o.sojourn;
199 s.timespan_end = o.timespan_end;
204 if (o.stage_cutoff > 0) s.mam_cutoff =
static_cast<std::size_t
>(o.stage_cutoff);
210void env_take_statevec(EnvAnalyzerSolution<T>& out) {
211 out.method =
"statevec";
212 out.QN = out.statevec.QN;
213 out.UN = out.statevec.UN;
214 out.TN = out.statevec.TN;
215 out.iterations = out.statevec.iterations;
216 out.converged = out.statevec.converged;
217 out.cache = out.statevec.cache;
229void env_take_meanfield(EnvAnalyzerSolution<T>& out,
const std::string& asked =
"meanfield") {
230 out.method = asked.
empty() ?
"meanfield" : asked;
231 out.QN = env_widen<T>(out.meanfield.avg.QN);
232 out.UN = env_widen<T>(out.meanfield.avg.UN);
233 out.TN = env_widen<T>(out.meanfield.avg.TN);
234 out.iterations = out.meanfield.avg.iterations;
235 out.converged = out.meanfield.avg.converged;
236 out.cache = out.meanfield.cache;
241void env_take_limit(EnvAnalyzerSolution<T>& out) {
242 out.method = out.limit.method;
243 out.QN = env_widen<T>(out.limit.QN);
244 out.UN = env_widen<T>(out.limit.UN);
245 out.TN = env_widen<T>(out.limit.TN);
247 out.converged =
true;
248 out.cache = env_widen_cache<T>(out.limit.cache);
252inline bool env_is_statevec(
const std::string& m) {
return m ==
"statevec"; }
255inline bool env_is_limit(
const std::string& m) {
return m ==
"avg" || m ==
"dec"; }
285 return {
"default",
"meanfield",
"mean",
"meancov",
"blend",
286 "blending",
"smp",
"statedep",
"statevec",
"avg",
"dec"};
292 if (std::find(valid.begin(), valid.end(), method) != valid.end())
return;
293 throw UnsupportedError(
"SolverENV: the '" + method +
"' method is unsupported by this solver");
307 if (dispatch_detail::env_is_limit(o.
method)) {
309 dispatch_detail::env_take_limit(out);
312 if (dispatch_detail::env_is_statevec(o.
method)) {
314 dispatch_detail::env_take_statevec(out);
318 dispatch_detail::env_take_meanfield(out, o.
method);
348 if (!dispatch_detail::env_is_limit(o.
method))
350 "SolverENV: the '" + o.
method +
351 "' coupling cannot run an injected stage solver; it carries a per-stage object across "
352 "an environment switch that only its own backend produces (the mean-field coupling "
353 "the RMF transient and the marginal means, the state-vector one a generator and the "
354 "joint law over it). The closed-form limits 'avg' and 'dec' take one");
358 dispatch_detail::env_take_limit(out);
384 if (dispatch_detail::env_is_limit(o.
method)) {
389 dispatch_detail::env_take_limit(out);
392 if (dispatch_detail::env_is_statevec(o.
method)) {
397 dispatch_detail::env_take_statevec(out);
402 dispatch_detail::env_take_meanfield(out, o.
method);
UnsupportedError(const std::string &what)
The state-vector environment solver.
EnvStatevecSolution< T > solve()
A random environment: a port of matlab/src/lang/Environment.m, restricted to what SolverENV reads out...
Dense matrix and non-owning view.
EnvStatevecSolution< T > solver_env_statevec(Environment< T > &e, const EnvStatevecOptions< T > &o)
Solve in one call, for a caller with no use for the solver object.
EnvLimitSolution solver_env_limit(Environment< T > &e, const EnvOptions &o)
solveEnvLimit on the original stages.
std::function< EnvStageAvg< T >(const qn::NetworkStruct< T > &)> EnvStageAvgFn
The stage solver, as a callable: the C++ spelling of the MATLAB function handle SolverENV(renv,...
void env_check_method(const std::string &method)
Port of runAnalyzerChecks' method gate: an unlisted method is refused.
EnvMeanfieldSolution< T > solver_env_meanfield(Environment< T > &e, const EnvOptions &o)
The mean-field solve on the original stages, with no compression.
EnvCompression< T > env_compress(const Environment< T > &e0, const EnvCompressOptions &opt)
Port of applyCompression: pick a partition, decompose, and build the macro-state environment.
std::vector< std::string > env_list_valid_methods()
Port of SolverENV.listValidMethods.
void env_apply_macro_probabilities(Environment< T > &e, const EnvCompression< T > &c)
probEnv = pMacro and probOrig = newEmbweight, the two quantities applyCompression overwrites on the e...
EnvAnalyzerSolution< T > solver_env(Environment< T > &e, const EnvOptions &o)
SolverENV.init's analyzer selection: solve the environment with the coupling o.method names.
Conservation laws of a layered queueing network, enumerated from its structure.
Number-type abstraction for the templated API port.
SolverENV: a queueing network in a random environment.
The two CLOSED-FORM environment limits: SolverENV.solveEnvLimit, reached by options....
SolverENV, the default mean-field path: ENVIRONMENT COMPRESSION.
SolverENV, method = "statevec": a port of matlab/src/solvers/ENV/solver_env_statevec_analyzer....
What the ENV entry reports: the environment-blended metrics, and the whole result of whichever coupli...
EnvMeanfieldSolution< T > meanfield
Populated on the mean-field path.
std::string method
What ran: meanfield, statevec, or the limit avg / dec.
EnvLimitSolution limit
Populated on the closed-form limit path (avg, dec).
EnvStatevecSolution< T > statevec
Populated on the state-vector path.
bool converged
True on the limit path: a closed form has converged by construction.
Matrix< T > QN
Environment-averaged metrics, (nstations x nclasses).
EnvCompression< T > compression
The aggregation, when there was one; its eps against epsMAX says whether it was meaningful.
bool compressed
True when the environment was aggregated before the coupling ran.
solvers::CacheMetrics< T > cache
The environment-blended cache surface, whichever coupling produced it.
int iterations
ZERO ON THE LIMIT PATH, and that is the answer rather than a gap: a limit reads the environment once ...
The knobs applyCompression reads out of options.config.
Everything applyCompression computes, plus the compressed environment.
What a limit solve reports.
A mean-field solve, with the compression that produced it.
std::string method
The inter-stage coupling: meanfield is the reference's default.
What the state-vector coupling reports.
Every Cache node of the model, in node order; empty on a model with none.
std::vector< CacheNodeMetrics< T > > caches
One Cache node's measured behaviour.
std::vector< double > itemcap
(h) capacity of each list
std::vector< double > itemsize
(n) storage cost per item, EMPTY without setItemSizes
std::vector< T > hitprob
(K) TRUE hit fraction, EMPTY = not computed
std::vector< T > delayedprob
(K) delayed-hit fraction, EMPTY off a retrieval system
Matrix< T > hitproblist
(K x h) per-list hit fraction, EMPTY = not computed
std::size_t node
1-based node index of the Cache
std::vector< T > latency
(K) expected retrieval latency, EMPTY = not computed
std::vector< T > missprob
(K)
std::vector< T > listcost
(h) mean storage cost held by each list
Matrix< T > itemprob
(n x h+1), column 0 = miss; EMPTY = not computed
std::string name
The Cache node's NAME, which is what a cross-language payload must key on.