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).
7% Reference: Z. Liu and
P. Nain, INRIA RR-1144 (1989), Thm 3.2 (open BCMP).
10sn = model.getStruct();
13if isempty(njobs) || ~all(isinf(njobs))
17nstations = sn.nstations;
19nservers = sn.nservers(:);
21%
visits per (station,
class): sum over chains (sn.
visits is a cell per chain)
22visits = zeros(nstations, R);
24if iscell(sn.visits) && ~isempty(sn.visits)
27 if ~isempty(vm) && size(vm, 1) == nstations && size(vm, 2) == R
33if ~gotVisits || all(
visits(:) == 0),
visits(:) = 1.0; end
35extId = SchedStrategy.toId(SchedStrategy.EXT);
36infId = SchedStrategy.toId(SchedStrategy.INF);
40 if sn.sched(i) == extId
42 if isfinite(rates(i, r)), lam(r) = lam(r) + rates(i, r); end
47sens = opt.SensitivityData();
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
55 stName = sn.nodenames{sn.stationToNode(i)};
57 D = zeros(1, R); rho = zeros(1, R);
60 if isfinite(mu) && mu > 0 &&
visits(i, r) > 0
62 rho(r) = lam(r) * D(r);
65 U = 0.0;
if ~isDelay, U = sum(rho); end
67 if ~isDelay && denom <= 0, sens = [];
return; end
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);
78 if visits(i, r) <= 0 || ~(isfinite(mu) && mu > 0),
continue; end
79 cl = sn.classnames{r};
80 mkey = opt.SensitivityData.metricKey(stName, cl);
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
88 dResp = dDr; dQ = dRhoR;
90 dResp = (dDr * denom + D(r) * dU) / (denom * denom);
91 dQ = (dRhoR * denom + rho(r) * dU) / (denom * denom);
93 sens.add(
'RespT', mkey, pkey, dResp);
94 sens.add(
'QLen', mkey, pkey, dQ);
96 sens.add(
'Tput', mkey, opt.SensitivityData.paramKey(stName, cl), 0.0);