LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
openSensitivities.m
1function sens = openSensitivities(model)
2% openSensitivities Analytic d(metric)/d(rate) for open product-form networks
3% (single-server queueing and infinite-server delay stations, which decouple),
4% mirroring native-Python _open_sensitivities. Returns [] for closed, mixed, or
5% multiserver networks (finite-difference fallback).
6%
7% Reference: Z. Liu and P. Nain, INRIA RR-1144 (1989), Thm 3.2 (open BCMP).
8
9sens = [];
10sn = model.getStruct();
11R = sn.nclasses;
12njobs = sn.njobs(:);
13if isempty(njobs) || ~all(isinf(njobs))
14 return; % open only
15end
16
17nstations = sn.nstations;
18rates = sn.rates;
19nservers = sn.nservers(:);
20
21% visits per (station,class): sum over chains (sn.visits is a cell per chain)
22visits = zeros(nstations, R);
23gotVisits = false;
24if iscell(sn.visits) && ~isempty(sn.visits)
25 for c = 1:numel(sn.visits)
26 vm = sn.visits{c};
27 if ~isempty(vm) && size(vm, 1) == nstations && size(vm, 2) == R
28 visits = visits + full(vm);
29 gotVisits = true;
30 end
31 end
32end
33if ~gotVisits || all(visits(:) == 0), visits(:) = 1.0; end
34
35extId = SchedStrategy.toId(SchedStrategy.EXT);
36infId = SchedStrategy.toId(SchedStrategy.INF);
37
38lam = zeros(1, R);
39for i = 1:nstations
40 if sn.sched(i) == extId
41 for r = 1:R
42 if isfinite(rates(i, r)), lam(r) = lam(r) + rates(i, r); end
43 end
44 end
45end
46
47sens = opt.SensitivityData();
48for i = 1:nstations
49 sc = sn.sched(i);
50 if sc == extId, continue; end
51 isDelay = (sc == infId);
52 if ~isDelay && nservers(i) > 1
53 sens = []; return; % multiserver M/M/c not handled here
54 end
55 stName = sn.nodenames{sn.stationToNode(i)};
56
57 D = zeros(1, R); rho = zeros(1, R);
58 for r = 1:R
59 mu = rates(i, r);
60 if isfinite(mu) && mu > 0 && visits(i, r) > 0
61 D(r) = visits(i, r) / mu;
62 rho(r) = lam(r) * D(r);
63 end
64 end
65 U = 0.0; if ~isDelay, U = sum(rho); end
66 denom = 1.0 - U;
67 if ~isDelay && denom <= 0, sens = []; return; end
68
69 for s = 1:R
70 muS = rates(i, s);
71 if isfinite(muS) && muS > 0 && visits(i, s) > 0
72 sens.add('Util', stName, opt.SensitivityData.paramKey(stName, sn.classnames{s}), -rho(s) / muS);
73 end
74 end
75
76 for r = 1:R
77 mu = rates(i, r);
78 if visits(i, r) <= 0 || ~(isfinite(mu) && mu > 0), continue; end
79 cl = sn.classnames{r};
80 mkey = opt.SensitivityData.metricKey(stName, cl);
81 for s = 1:R
82 muS = rates(i, s);
83 if ~(isfinite(muS) && muS > 0 && visits(i, s) > 0), continue; end
84 pkey = opt.SensitivityData.paramKey(stName, sn.classnames{s});
85 dU = 0.0; if ~isDelay, dU = -rho(s) / muS; end
86 if s == r, dDr = -D(r) / muS; dRhoR = -rho(r) / muS; else, dDr = 0.0; dRhoR = 0.0; end
87 if isDelay
88 dResp = dDr; dQ = dRhoR;
89 else
90 dResp = (dDr * denom + D(r) * dU) / (denom * denom);
91 dQ = (dRhoR * denom + rho(r) * dU) / (denom * denom);
92 end
93 sens.add('RespT', mkey, pkey, dResp);
94 sens.add('QLen', mkey, pkey, dQ);
95 end
96 sens.add('Tput', mkey, opt.SensitivityData.paramKey(stName, cl), 0.0);
97 end
98end
99end