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

The two CLOSED-FORM environment limits: SolverENV.solveEnvLimit, reached by options.method in {avg, dec}. More...

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <functional>
#include <limits>
#include <string>
#include <type_traits>
#include <vector>
#include "line/api/sn/sn_node_metrics.h"
#include "line/lang/qn/environment.h"
#include "line/lang/qn/network_struct.h"
#include "line/num/number.h"
#include "line/solvers/cache_metrics.h"
#include "line/solvers/env/solver_env.h"
#include "line/solvers/fluid/fluid_runner.h"
#include "line/solvers/fluid/solver_fluid.h"
#include "line/util/error.h"
#include "line/util/matrix.h"
Include dependency graph for solver_env_limit.h:

Go to the source code of this file.

Classes

struct  line::env::EnvStageAvg< T >
 What one stage solve reports back to the limits. More...
struct  line::env::EnvLimitSolution
 What a limit solve reports. More...
class  line::env::SolverEnvLimit< T >
 The limit solver. More...

Namespaces

namespace  line
 Conservation laws of a layered queueing network, enumerated from its structure.
namespace  line::env

Typedefs

template<class T>
using line::env::EnvStageAvgFn = std::function<EnvStageAvg<T>(const qn::NetworkStruct<T>&)>
 The stage solver, as a callable: the C++ spelling of the MATLAB function handle SolverENV(renv, @(m) SolverX(m, opts)) passes.

Functions

template<class T>
EnvLimitSolution line::env::solver_env_limit (Environment< T > &e, const EnvOptions &o)
 solveEnvLimit on the original stages.
template<class T>
EnvLimitSolution line::env::solver_env_limit (Environment< T > &e, const EnvOptions &o, EnvStageAvgFn< T > stage_fn)
 solveEnvLimit with the CALLING solver running every stage.

Detailed Description

The two CLOSED-FORM environment limits: SolverENV.solveEnvLimit, reached by options.method in {avg, dec}.

Both replace the fixed point with a single reading, and each is exact at one end of the time-scale separation between the environment and the network:

avg, the FAST-environment limit. The environment switches so much faster than the network responds that the network only ever sees the AVERAGE of the modulated rates. One rate-averaged model is built – every station-class rate that varies across stages replaced by its probEnv-weighted mean, as an exponential – and solved once, in steady state. Exact as the stage-switch rate goes to infinity.

dec, the SLOW-environment limit, i.e. quasi-stationary decomposition. The environment stays in a stage long enough for the network to reach that stage's own steady state, so each stage is solved independently and the metrics are averaged with weights probEnv. Exact as the stage-switch rate goes to zero.

NEITHER CARRIES ANYTHING ACROSS A SWITCH, which is what makes them closed form and also what they give up: no entry state, no reset policy, no transient. A reset policy declared on an arc is therefore inert here, exactly as it is in the reference, whose solveEnvLimit never reads resetFun.

WHAT IS AVERAGED, AND WHAT IS LEFT ALONE (buildRateAveragedModel). Only a Source, a Queue or a Delay carries a rate to average. A station-class pair that is disabled in any stage, or whose rate does not actually vary across them, keeps its ORIGINAL distribution rather than being rewritten as an exponential of its own mean – so a non-modulated Erlang stays an Erlang, and the base model is preserved exactly outside the modulated rates.

A STAGE HOLDING A CACHE is solved, not refused. The hit, miss and delayed fractions each stage reports are blended the way the reference's accumCacheMetric does after 2026-09-13: as RATES weighted by that stage's per-class arrival INTO THE CACHE, normalised once at the end. Rates and not ratios, because a stage's hit ratio is conditional on arriving in that stage, so a probEnv-weighted mean of ratios disagrees with the Sink-row hit throughput – sum_e p_e*lambda_e*h_e – in the SAME node table. It is also the convention aggregate_cache_meanfield and the statevec cache_blend already hold, each with a comment saying so.

WHICH SOLVER RUNS A STAGE. The reference hands SolverENV a FACTORY and calls it for every stage, so "the stage solver is the calling solver" is literally true there. The second constructor here takes an EnvStageAvgFn, the same thing as a callable, and the no-factory path keeps the fluid analyzer. Without a factory an MVA or NC caller would silently be answered by a fluid solve, and even an FLD caller would lose its own FluidOptions (method, timespan, tolerances) on the way in.

Definition in file solver_env_limit.h.