3 % @file dist_scale_rate.m
4 % @brief Rate-scaled copy of a distribution, preserving its shape.
8function scaled = dist_scale_rate(distrib,
factor)
11 % @brief Returns a
new distribution whose rate
is FACTOR times
the rate of
12 % DISTRIB, i.e.
the time-scaled variable X/FACTOR. The scaling
is
13 % exact: every moment of order n
is divided by FACTOR^n, so
the mean
14 %
is divided by FACTOR
while the SCV,
the skewness and
the whole
15 % shape of
the distribution are preserved.
17 % The scaled
object is rebuilt from
the parameters of
the original,
18 % rather than by rescaling its Markovian representation, so that
the
19 % parameter list stays coherent with
the distribution family. Solvers
20 % that serialize
the model (JMT, LDES) read
the parameters, and would
21 % otherwise
export the unscaled process.
23 % This
is the perturbation primitive of
the finite-difference branch
24 % of getSensitivityTable: scaling
the rate at a station-
class by
25 % (1+h)
is exactly
the perturbation
the derivative d(.)/d(rate)
is
28 % @fn dist_scale_rate(distrib,
factor)
29 % @param distrib A Distribution
object.
31 % @
return scaled A
new Distribution of
the same family with rate*FACTOR.
35if ~isa(distrib,
'Distribution')
36 line_error(mfilename, 'dist_scale_rate expects a Distribution
object.');
39 line_error(mfilename, 'The scaling
factor must be a positive finite scalar.');
44 scaled = Exp(distrib.getParam(1).paramValue *
factor);
46 scaled = Erlang(distrib.getParam(1).paramValue *
factor, ...
47 distrib.getParam(2).paramValue);
49 p = distrib.getParam(1).paramValue;
50 lambda1 = distrib.getParam(2).paramValue;
51 lambda2 = distrib.getParam(3).paramValue;
53 % n-phase form: param2 holds
the whole rate vector.
54 scaled = HyperExp(p, lambda1 *
factor);
56 scaled = HyperExp(p, lambda1 *
factor, lambda2 *
factor);
58 case {
'Coxian',
'Cox2'}
59 % Completion probabilities are dimensionless and are left untouched;
60 % only
the phase rates carry
the time scale. A Cox2
is a two-phase
61 % Coxian and
is rebuilt as one, its own constructor being a fit.
62 if length(distrib.params) == 3
63 scaled = Coxian(distrib.getParam(1).paramValue *
factor, ...
64 distrib.getParam(2).paramValue *
factor, ...
65 distrib.getParam(3).paramValue);
67 scaled = Coxian(distrib.getParam(1).paramValue *
factor, ...
68 distrib.getParam(2).paramValue);
71 scaled = APH(distrib.getParam(1).paramValue, ...
72 distrib.getParam(2).paramValue *
factor);
74 scaled = PH(distrib.getParam(1).paramValue, ...
75 distrib.getParam(2).paramValue *
factor);
77 scaled = MAP(distrib.getParam(1).paramValue *
factor, ...
78 distrib.getParam(2).paramValue *
factor);
80 % Every rate of
the modulating chain and of
the arrival process
is
81 % scaled, which time-scales
the whole process.
82 scaled = MMPP2(distrib.getParam(1).paramValue *
factor, ...
83 distrib.getParam(2).paramValue *
factor, ...
84 distrib.getParam(3).paramValue *
factor, ...
85 distrib.getParam(4).paramValue *
factor);
87 scaled = Det(distrib.getParam(1).paramValue /
factor);
89 scaled = Uniform(distrib.getParam(1).paramValue /
factor, ...
90 distrib.getParam(2).paramValue /
factor);
92 % Gamma(shape, scale):
the shape
is dimensionless.
93 scaled = Gamma(distrib.getParam(1).paramValue, ...
94 distrib.getParam(2).paramValue /
factor);
96 % Pareto(shape, scale):
the scale
is the minimum of
the support.
97 scaled = Pareto(distrib.getParam(1).paramValue, ...
98 distrib.getParam(2).paramValue /
factor);
100 % Weibull params are (1)
the scale alpha and (2)
the shape r, while
101 %
the constructor takes (shape, scale).
102 scaled = Weibull(distrib.getParam(2).paramValue, ...
103 distrib.getParam(1).paramValue /
factor);
106 scaled = Lognormal(distrib.getParam(1).paramValue - log(
factor), ...
107 distrib.getParam(2).paramValue);
109 % A piecewise-constant intensity
is time-scaled by lambda(t) ->
111 % up and its breakpoints compressed. The time-average rate, which
is
112 % what sn.rates carries for an NHPP,
is then scaled by
factor.
113 scaled = NHPP(distrib.getBreakpoints() /
factor, ...
114 distrib.getRates() *
factor, distrib.isCyclic());
116 % A trace
is scaled sample by sample. A file-backed Replayer
is left
117 % alone: rescaling it means writing a new trace file, which a
118 % sensitivity sweep must not do behind
the caller's back.
119 if isempty(distrib.data)
120 line_error(mfilename, ['Rate scaling
is not defined for a ', ...
121 'file-backed Replayer:
the trace
is the parameter. Pass
the ', ...
122 'samples as an array, Replayer(data), to differentiate it.']);
124 scaled = Replayer(distrib.data /
factor);
126 scaled = Immediate();
128 line_error(mfilename, sprintf(['Rate scaling
is not defined for a %s ', ...
129 'process. Supported: Exp, Erlang, HyperExp, Coxian, Cox2, APH, PH, ', ...
130 'MAP, MMPP2, Det, Uniform, Gamma, Pareto, Weibull, Lognormal, NHPP, ', ...
131 'Replayer, Immediate.'], class(distrib)));