![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
The diffusion method: a port of solver_fluid_diffusion.m. More...
#include <algorithm>#include <cmath>#include <cstddef>#include <random>#include <vector>#include "line/api/mc/dtmc_stochcomp.h"#include "line/lang/lang_types.h"#include "line/lang/qn/network_struct.h"#include "line/util/error.h"#include "line/util/matrix.h"Go to the source code of this file.
Classes | |
| struct | line::fluid::DiffusionOptions |
| Controls of the Euler-Maruyama trajectory. More... | |
| struct | line::fluid::DiffusionResult |
| Steady-state averages of the diffusion trajectory. More... | |
Namespaces | |
| namespace | line |
| Conservation laws of a layered queueing network, enumerated from its structure. | |
| namespace | line::fluid |
Functions | |
| template<class T> | |
| DiffusionResult | line::fluid::fluid_diffusion (const qn::NetworkStruct< T > &sn, const DiffusionOptions &opt) |
| Run the diffusion approximation of sn. | |
The diffusion method: a port of solver_fluid_diffusion.m.
WHAT IT COMPUTES. The fluid limit follows the MEAN drift and says nothing about fluctuation. The diffusion approximation simulates the diffusion limit by Euler-Maruyama. Every routing arc a -> b carries the flux phi_a(x) P(a,b), with phi = mu*x at an INF station and mu*x/max(1,n_i) at a single server (n_i the station total), plus its own Brownian noise sqrt(phi_a P(a,b) dt) Z moved from a to b, so each step conserves the chain populations exactly. A transfer that would drive a coordinate below zero is scaled down until it lands there, which keeps the population exact without re-projecting.
QN is the time average over the SECOND HALF of the trajectory (the first is warm-up). TN is X_c * V(i,r) per chain, with X_c the mean departure rate E[phi]/V at the chain's bottleneck (largest V/mu, single servers before INF stations), so the throughputs are flow-balanced by construction; UN is TN/mu at a single server and QN at an INF station.
THE HORIZON IS NOT iter_max. timestep is the step and a finite timespan_end sets the horizon, ceil(tend/dt) steps; otherwise 100000 steps are taken. iter_max is the closing-iteration count every FLD run carries a default for, and sizing the SDE with it once capped the run at ~200 steps. That, together with a drift that served the whole queue at a single server and unit noise per coordinate, made the method several-fold wrong.
PARITY IS STATISTICAL, NOT EXACT. The trajectory is driven by pseudorandom normals, and MATLAB's randn and this port's Mersenne Twister produce different streams from the same seed. Two runs therefore agree in distribution and not digit for digit – the same situation the SSA solvers are in across codebases. Tests must assert on averages and invariants (population conservation, ordering), never on a specific trajectory.
Definition in file fluid_diffusion.h.