LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
afterEventInit.m
1function ctx = afterEventInit(sn)
2% CTX = AFTEREVENTINIT(SN)
3% Precomputes the loop-invariant setup of State.afterEvent so that hot
4% callers (e.g., the solver_ssa Gillespie loop, which re-evaluates every
5% synchronization at every step) avoid re-deriving it on each call.
6%
7% IMPORTANT: ctx caches sn.nservers, sn.cap and sn.classcap. It must be
8% built AFTER any caller-side rewrite of these fields (solver_ssa rewrites
9% them in its preamble: Inf servers at delay nodes and open-class cutoffs)
10% and AFTER sn_nonmarkov_toph, and the SAME sn must be passed to afterEvent
11% alongside ctx. Building ctx from a stale sn silently drops blocking and
12% server-count semantics.
13
14% Copyright (c) 2012-2026, Imperial College London
15% All rights reserved.
16
17M = sn.nstations;
18R = sn.nclasses;
19
20ctx.M = M;
21ctx.R = R;
22ctx.S = sn.nservers;
23ctx.phasessz = sn.phasessz;
24ctx.phaseshift = sn.phaseshift;
25ctx.pie = sn.pie;
26ctx.mu = sn.mu;
27ctx.phi = sn.phi;
28ctx.proc = sn.proc;
29ctx.capacity = sn.cap;
30ctx.classcap = sn.classcap;
31
32lldscaling = sn.lldscaling;
33if isempty(lldscaling)
34 lldlimit = max(sum(sn.nclosedjobs),1);
35 lldscaling = ones(M,lldlimit);
36else
37 lldlimit = size(lldscaling,2);
38end
39ctx.lldscaling = lldscaling;
40ctx.lldlimit = lldlimit;
41
42% sn.cdscaling holds a class-dependence handle only for the stations that
43% declare one; the others are left empty (see getLimitedClassDependence), since
44% a constant 1 is not a valid class-dependent RATE. The state machinery indexes
45% every station unconditionally, so fill the gaps with the neutral scaling here.
46cdscaling = sn.cdscaling;
47if isempty(cdscaling)
48 cdscaling = cell(M,1);
49end
50neutral = @(ni) 1;
51for i = 1:M
52 if i > numel(cdscaling) || isempty(cdscaling{i})
53 cdscaling{i} = neutral;
54 end
55end
56% Joint-dependence handles (sn.jdscaling, non-product-form eta_i) are applied
57% by the same state machinery. cd and jd are evaluated identically, so fold
58% them into a single effective per-station handle eta_i(n)*beta_i(n) (scalar
59% .* vector broadcasts). For stations with only one of the two, the other is
60% the neutral 1, so the product reproduces the single-mechanism case exactly.
61jdscaling = sn.jdscaling;
62if ~isempty(jdscaling)
63 for i = 1:M
64 if i <= numel(jdscaling) && ~isempty(jdscaling{i})
65 cdh = cdscaling{i};
66 jdh = jdscaling{i};
67 cdscaling{i} = @(ni) cdh(ni) .* jdh(ni);
68 end
69 end
70end
71ctx.cdscaling = cdscaling;
72
73ctx.ismkvmod = false(sn.nnodes,1);
74ctx.ismkvmodclass = cell(sn.nnodes,1);
75for ind=1:sn.nnodes
76 if sn.isstation(ind)
77 ist = sn.nodeToStation(ind);
78 ctx.ismkvmod(ind) = any(sn.procid(ist,:)==ProcessType.MAP | sn.procid(ist,:)==ProcessType.MMPP2);
79 ismkvmodclass = zeros(R,1);
80 for r=1:R
81 ismkvmodclass(r) = any(sn.procid(ist,r)==ProcessType.MAP | sn.procid(ist,r)==ProcessType.MMPP2);
82 end
83 ctx.ismkvmodclass{ind} = ismkvmodclass;
84 end
85end
86end
Definition fjtag.m:161