LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
estimator_mcmc.m
1function estVal = estimator_mcmc(self, nodes)
2 % Gibbs Sampling MCMC-based optimization
3 % Supports closed, open, and mixed queueing networks.
4 % For open classes, uses the open-to-closed equivalence Z_r = N_r / lambda_r.
5 %
6 % Copyright (c) 2012-2026, Imperial College London
7 % All rights reserved.
8 % This code is released under the 3-Clause BSD License.
9
10 sn = self.model.getStruct;
11
12 % Get effective population for open classes
13 if isfield(self.options, 'openPopulation') && ~isempty(self.options.openPopulation)
14 Nopen = self.options.openPopulation;
15 else
16 Nopen = 100;
17 end
18
19 % Determine population per class
20 P = zeros(1, sn.nclasses);
21 for r = 1:sn.nclasses
22 if sn.njobs(r) < Inf
23 P(r) = sn.njobs(r);
24 else
25 P(r) = Nopen;
26 end
27 end
28
29 % Extract think times
30 Z = zeros(1, sn.nclasses);
31 allNodes = self.model.getNodes;
32 for n = 1:length(allNodes)
33 if isa(allNodes{n}, 'Delay')
34 svcProc = allNodes{n}.getService;
35 for r = 1:sn.nclasses
36 if sn.njobs(r) < Inf
37 Z(r) = Z(r) + svcProc{r}.getMean();
38 end
39 end
40 elseif isa(allNodes{n}, 'Source')
41 svcProc = allNodes{n}.getService;
42 for r = 1:sn.nclasses
43 if sn.njobs(r) == Inf
44 lambda_r = 1 / svcProc{r}.getMean();
45 Z(r) = P(r) / lambda_r;
46 end
47 end
48 end
49 end
50
51 % obtain per class metrics
52 for n=1:size(nodes,2)
53 node = nodes{n};
54
55 for r=1:sn.nclasses
56 avgAQLen{n,r} = self.getAggrQLen(node); % aggregate queue-length
57 if isempty(avgAQLen{n,r})
58 error('Transient queue-length data for node %d in class %d is missing.', self.model.getNodeIndex(node), r);
59 else
60 avgAQLen{n,r} = avgAQLen{n,r}.data;
61 end
62 end
63 end
64
65 try
66 avgQL = cell2mat(avgAQLen);
67 experiments = size(avgQL,1);
68 avgQL = reshape(avgQL, size(avgQL,1)/size(avgAQLen, 1), size(avgAQLen, 1), sn.nclasses);
69 avgQL = squeeze(mean(avgQL,1))';
70 catch me
71 switch me.identifier
72 case 'MATLAB:catenate:dimensionMismatch'
73 error('Sampled metrics have different number of samples, use interpolate() before starting this estimation algorithm.');
74 end
75 end
76
77 estVal = mcmc_data(avgQL, self.model.getStruct.visits, experiments, self.options.iter_max, P, Z);
78end
79
80% mcmc procedure based on the comon data format
81function demEst = mcmc_data(avgQL, visits, experiments, ITERMAX, P, Z)
82
83 %% number of resources
84 M = size(avgQL,1);
85 %% number of classes
86 R = size(avgQL,2);
87
88 %% Number of experiments
89 N = experiments;
90
91 %% Number of Gibbs samples
92 S = 100;
93
94 mciVariant = 'imci';
95 integralRange = [0, max(avgQL(:))];
96 thetaStep = integralRange(2) / 400;
97
98
99 %% assuming uniform prior distribution - TODO add as option
100 function p = prior(integralRange, delta)
101 p = delta / (integralRange(2) - integralRange(1));
102 end
103
104 theta = zeros(S, M, R);
105 steps = integralRange(1):thetaStep:integralRange(2);
106
107 for s=1:S
108 sampleTheta = theta(s,:,:);
109 for i=1:M
110 for c=1:R
111 logPosteriors = zeros(size(steps));
112 for st=1:length(steps)
113 stepTheta = steps(st);
114 logPrior = log(prior(integralRange, thetaStep));
115 gNormalizingConstant = pfqn_mci(squeeze(sampleTheta)', P, Z, N, mciVariant);
116
117 logPosteriors(st) = N*avgQL(i, c)*log(stepTheta)-N*log(gNormalizingConstant)+logPrior;
118 end
119
120 probs = exp(logPosteriors-max(logPosteriors));
121 probs = probs / sum(probs);
122
123 cumulativeProb = cumsum(probs);
124 u = rand(1);
125 index = find(u<cumulativeProb, 1, 'first');
126 sampleTheta(i, c) = steps(index);
127 end
128 end
129 theta(s+1,:,:) = sampleTheta;
130 end
131
132 visitPerClass = zeros(R, M);
133 for i = 1 : R
134 visitPerClass(i, :) = visits{i}(2:M+1, i); %TODO investigate
135 end
136
137 theta = arrayfun(@(x) x ./ visitPerClass', theta, 'UniformOutput', false);
138
139 cutoff = round(S / 2);
140 theta = theta(cutoff:end);
141
142 thetaAvg = mean(cat(3,theta{:}),3);
143
144 demEst = thetaAvg;
145end
Definition mmt.m:124