solvers.wrappers.LDES
- ldes_require_finite_pas_buffers(model)
LDES_REQUIRE_FINITE_PAS_BUFFERS(MODEL) Refuse an OI/PAS station with no finite buffer before it reaches LDES.
mu(c) cannot cross JSON as a function, so linemodel_save materializes it as a macrostate table, and LDES needs a finite buffer to bound the state whether or not the rate saturates: saturation only keeps the table compact, it cannot bound the queue length. Without this gate an uncapped station was written over the 10-per-open-class box and served clamped at the box edge without a word. The saturation search is the shared pas_saturation_cutoffs (matlab/src/io).
The reference refusal is Python save_model’s (linemodel_io.py); C++ raises the same two messages in io::require_finite_pas_buffers, called by ldes::solver_ldes. The JAR needs no twin: its NetworkSolver constructor builds the struct WITH the initial state, so FromMarginal already refuses an uncapped PAS station for every solver. The messages are the reference’s word for word, naming the station. The gate is at SOLVE time, NOT in linemodel_save, which must still save such a model. model.getStruct() with the initial state refuses the same model generically (State.fromMarginalAndStarted, ‘PAS stations require finite capacity …’, not naming the station), so the gate has to run before it to be heard: NetworkSolver.getAvg (getAvg is Sealed, hence a SolverLDES branch there), SolverLDES.getStruct (getAvgTable), SolverLDES.runAnalyzer (getTranAvg) and SolverLDES.solveCli (every engine run, including the entry points that build the struct without the initial state). getProb*, sample*, getAvgReward, getTranReward and initFromSolver take their struct from SolverLDES.getStruct, never from model.getStruct, so that one gate covers them; a new SolverLDES method must do the same. A buffer is finite when sn.cap is, so a closed station bounded by its chain population passes. see _kb/09-ldes-and-cache.md
Copyright (c) 2012-2026, Imperial College London All rights reserved.
- ldes_ln_refusal(model)
[OK, REASON] = LDES_LN_REFUSAL(MODEL) Whether the LDES layered engine serves this LayeredNetwork, as a predicate.
The engine is the JVM backend (jline.solvers.ldes), which validates the LQN against its SolverLDES.getLNFeatureSet at run time; the MATLAB SolverLDES.getLNFeatureSet is the mirror of that declaration. supports() used to answer true for every LayeredNetwork and leave the refusal to Java, so model.help offered ‘ldes’ on an LQN with a DPS processor or a Zipf demand and the run then died in the backend. Two callers: SolverLDES.supports (hence supportsModelMethod, model.help and SolverAUTO) and runAnalyzer before the Java run, so both speak the same sentence.
WHAT IS COMPARED. The LayeredNetwork has no feature recorder of its own (its getUsedLangFeatures returns the per-layer Networks SolverLN builds, which carry no LQN-level name), so the two dimensions that vary across LQNs are marked here: the discipline of every processor and task (SchedStrategy_*) and the law of every host demand and think time (the distribution’s feature name, the one the Network recorder marks). A PS task is refused by the engine rather than served FCFS, so it is refused here by name too. Element kinds, calls and precedences are declared for every model and are not marked.
Copyright (c) 2012-2026, Imperial College London All rights reserved.
- ldesHistogram(solver)
[SPACE, TIME] = LDESHISTOGRAM(SOLVER) Exact joint-state residence-time histogram of one LDES run.
Runs the fully JSON-mediated solve with –export-histogram and returns the (nstates x nstations*nclasses) joint-state matrix and the (nstates x 1) residence time of each row, so P(state) = t(state)/sum(t) is exact on the sampled path.
WHY THIS AND NOT THE TRAJECTORY. The transient QNt series the engine returns under –trajectory holds INTERVAL TIME-AVERAGES of the queue length, not the integer states the path visits, so it cannot be compared against a state to estimate a probability. Every probability the LDES wrapper reports goes through this histogram, as getAvgReward already does.
Copyright (c) 2012-2026, Imperial College London All rights reserved.
- ldesHistProb(space, time, R, stations, targets)
PROB = LDESHISTPROB(SPACE, TIME, R, STATIONS, TARGETS) Residence-time probability of an aggregate joint state in an LDES histogram.
SPACE is the (nstates x nstations*R) joint-state matrix and TIME the (nstates x 1) residence time of each row, as ldesHistogram returns them; R is sn.nclasses, which fixes the column stride. STATIONS is a vector of 1-based station indices to constrain and TARGETS a cell array of matching per-class job-count vectors; a target shorter than R constrains only the classes it names. Returns 0 when the state is never visited, which is a measurement.
The layout is the station-major, class-minor one ctmc_state_space_aggr builds: column (i-1)*R+k is the number of class-k jobs at station i.
Copyright (c) 2012-2026, Imperial College London All rights reserved.
- ldesTrajCell(raw, M, R)
C = LDESTRAJCELL(RAW, M, R) Normalize a jsondecode’d transient trajectory (logical nesting [station][class][row][2]) into an M x R cell array C where C{i,r} is the (nRows x 2) [value, time] matrix for class r at the i-th stateful node, or [] if absent/empty.
- jsondecode collapses this nesting inconsistently depending on raggedness:
fully rectangular -> numeric 4-D [M x R x nRows x 2]
- ragged outer -> cell{M}, each element numeric 3-D [R x nRows x 2]
(or [] for an empty station, or a nested cell)
R == 1 collapses -> a station element may be a plain [nRows x 2] matrix
This helper resolves all of these to a uniform M x R cell of 2-D matrices.
- ldesJson2mat(x, nr, nc)
M = LDESJSON2MAT(X, NR, NC) Convert a jsondecode’d matrix into a numeric NR x NC matrix. Handles numeric 2-D arrays, cell arrays (ragged / containing JSON null, which jsondecode maps to []), and empties (returns []). JSON null entries become NaN. When NR,NC are supplied the result is oriented to NR x NC. Shared by the LDES wrapper methods that parse the fully JSON-mediated result of the LDES engine.
- ldesGetField(s, f, dflt)
V = LDESGETFIELD(S, F, DFLT) Value of field F in struct S, or DFLT if S is not a struct or lacks F. Shared helper for the fully JSON-mediated LDES wrapper methods.