LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
runTransientJson.m
1function res = runTransientJson(self, numEvents)
2% RES = RUNTRANSIENTJSON(NUMEVENTS)
3% Run a fully JSON-mediated transient LDES simulation over the horizon
4% [0, samples] (or [0, numEvents] when numEvents>0) with trajectory export,
5% and return the parsed trajectory. Mirrors the Python-native _run_transient.
6%
7% RES has fields:
8% .t - (nTimePoints x 1) time vector, or [] if none
9% .QNt - 1 x Nouter cell; RES.QNt{i} is a 1 x R cell whose {r} entry is the
10% (nTimePoints x 2) [value, time] trajectory of class r at the i-th
11% stateful node, or [] if absent. Nouter matches the engine's outer
12% transient dimension (stateful-node major, as consumed by sample()).
13
14options = self.getOptions;
15% The horizon is passed explicitly via --timespan; options.samples (the
16% steady-state event budget) is left untouched since the engine ignores it
17% in transient mode.
18S = options.samples;
19if nargin >= 2 && ~isempty(numEvents) && numEvents > 0
20 S = numEvents;
21end
22extraFlags = {'--timespan', sprintf('0,%.10g', S), '--trajectory'};
23
24% Ensemble transient: a single realization is not the transient mean E[N](t)
25% (no time-ergodicity at fixed t). When replications > 1 is requested, drive
26% the engine's parallel analyzer via --replications so the per-bucket QNt/UNt/
27% TNt are averaged across independent replications. Read from options.replications
28% or options.config.replications; default (absent/<=1) keeps the single-path run.
29reps = 0;
30if isfield(options, 'replications') && ~isempty(options.replications)
31 reps = options.replications;
32elseif isfield(options, 'config') && isfield(options.config, 'replications') ...
33 && ~isempty(options.config.replications)
34 reps = options.config.replications;
35end
36if reps > 1
37 extraFlags{end+1} = '--replications';
38 extraFlags{end+1} = sprintf('%d', round(reps));
39 if isfield(options, 'config') && isfield(options.config, 'numthreads') ...
40 && ~isempty(options.config.numthreads) && options.config.numthreads > 0
41 extraFlags{end+1} = '--numthreads';
42 extraFlags{end+1} = sprintf('%d', round(options.config.numthreads));
43 end
44end
45
46data = self.solveCli(options, extraFlags);
47
48res = struct('t', [], 'QNt', {{}});
49if ~isstruct(data) || ~isfield(data, 'transient') || isempty(data.transient)
50 return;
51end
52tran = data.transient;
53if isfield(tran, 't') && ~isempty(tran.t)
54 tvec = ldesJson2mat(tran.t, [], []);
55 res.t = tvec(:);
56end
57if isfield(tran, 'QNt') && ~isempty(tran.QNt)
58 sn = self.model.getStruct;
59 Nouter = sn.nstateful;
60 R = sn.nclasses;
61 % Normalize into an Nouter x R cell of [nRows x 2] matrices, then repackage
62 % as a 1 x Nouter cell of 1 x R class-cells (the layout sample() consumes).
63 grid = ldesTrajCell(tran.QNt, Nouter, R);
64 res.QNt = cell(1, Nouter);
65 for i = 1:Nouter
66 classCells = cell(1, R);
67 for r = 1:R
68 classCells{r} = grid{i, r};
69 end
70 res.QNt{i} = classCells;
71 end
72end
73end
Definition Station.m:245