LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
tut12_posterior_analysis.m
1% Example 12: Posterior analysis with uncertain parameters
2%
3% This tutorial demonstrates how to analyze queueing models with parameter
4% uncertainty using the Posterior solver. The Posterior solver works with
5% Prior distributions that represent uncertainty about model parameters,
6% computing posterior distributions of performance metrics.
7%
8% Scenario: An M/M/1 queue where the service rate is uncertain. We model
9% this uncertainty using a Prior distribution with 30 alternatives,
10% creating a Gaussian-like distribution of possible service rates.
11
12%% Block 1: Create model with uncertain service rate
13model = Network('UncertainServiceModel');
14
15% Create nodes
16source = Source(model, 'Source');
17queue = Queue(model, 'Queue', SchedStrategy.FCFS);
18sink = Sink(model, 'Sink');
19
20% Create job class
21jobClass = OpenClass(model, 'Jobs');
22
23% Set arrival rate (lambda = 0.5)
24lambda = 0.5;
25source.setArrival(jobClass, Exp(lambda));
26
27%% Block 2: Define Prior distribution for uncertain service rate
28% Use many alternatives to create a smooth, continuous-looking PDF
29% Service rates range from 0.7 to 2.5 with a Gaussian-like prior
30numAlternatives = 30;
31serviceRates = linspace(0.7, 2.5, numAlternatives);
32
33% Create Gaussian-like prior probabilities centered at mu=1.3
34priorMean = 1.3;
35priorStd = 0.4;
36priorProbs = exp(-0.5 * ((serviceRates - priorMean) / priorStd).^2);
37priorProbs = priorProbs / sum(priorProbs); % Normalize to sum to 1
38
39alternatives = cell(1, numAlternatives);
40for i = 1:numAlternatives
41 alternatives{i} = Exp(serviceRates(i));
42end
43
44prior = Prior(alternatives, priorProbs);
45queue.setService(jobClass, prior);
46
47%% Block 3: Complete model topology
48model.link(model.serialRouting(source, queue, sink));
49
50fprintf('Model: M/M/1 with uncertain service rate\n');
51fprintf('Arrival rate: lambda = %.1f\n', lambda);
52fprintf('Number of service rate alternatives: %d\n', numAlternatives);
53fprintf('Service rate range: mu in [%.2f, %.2f]\n', min(serviceRates), max(serviceRates));
54fprintf('Prior: Gaussian-like centered at mu=%.1f with std=%.1f\n\n', priorMean, priorStd);
55
56%% Block 4: Solve with Posterior wrapper using MVA
57post = Posterior(model, @SolverMVA);
58post.runAnalyzer();
59
60%% Block 5: Get prior-weighted average results
61avgTable = post.getAvgTable()
62
63%% Block 6: Get posterior table with per-alternative results
64postTable = post.getPosteriorTable()
65
66%% Block 7: Extract posterior distributions for different metrics
67% Get posterior distribution of response time at the queue
68respDist = post.getPosteriorDist('R', queue, jobClass);
69
70% Get posterior distribution of queue length at the queue
71qlenDist = post.getPosteriorDist('Q', queue, jobClass);
72
73% Get posterior distribution of utilization at the queue
74utilDist = post.getPosteriorDist('U', queue, jobClass);
75
76%% Block 8: Extract values and probabilities from the EmpiricalCDF objects
77% For response time
78respCdfData = respDist.data; % [CDF, Value]
79respValues = respCdfData(:, 2);
80respCdf = respCdfData(:, 1);
81respProbs = [respCdf(1); diff(respCdf)]; % Convert CDF to PMF
82
83% For queue length
84qlenCdfData = qlenDist.data;
85qlenValues = qlenCdfData(:, 2);
86qlenCdf = qlenCdfData(:, 1);
87qlenProbs = [qlenCdf(1); diff(qlenCdf)];
88
89% For utilization
90utilCdfData = utilDist.data;
91utilValues = utilCdfData(:, 2);
92utilCdf = utilCdfData(:, 1);
93utilProbs = [utilCdf(1); diff(utilCdf)];
94
95%% Block 9: Print posterior distribution statistics
96% Response time statistics
97expectedR = sum(respValues .* respProbs);
98[~, modeIdxR] = max(respProbs);
99fprintf('Response Time (R) at Queue:\n');
100fprintf(' Expected Value E[R]: %.4f\n', expectedR);
101fprintf(' Mode (most likely): %.4f\n\n', respValues(modeIdxR));
102
103% Queue length statistics
104expectedQ = sum(qlenValues .* qlenProbs);
105[~, modeIdxQ] = max(qlenProbs);
106fprintf('Queue Length (Q) at Queue:\n');
107fprintf(' Expected Value E[Q]: %.4f\n', expectedQ);
108fprintf(' Mode (most likely): %.4f\n\n', qlenValues(modeIdxQ));
109
110% Utilization statistics
111expectedU = sum(utilValues .* utilProbs);
112[~, modeIdxU] = max(utilProbs);
113fprintf('Utilization (U) at Queue:\n');
114fprintf(' Expected Value E[U]: %.4f\n', expectedU);
115fprintf(' Mode (most likely): %.4f\n\n', utilValues(modeIdxU));
116
117% Optional: Find median from CDF
118medianIdx = find(respCdf >= 0.5, 1, 'first');
119if ~isempty(medianIdx)
120 medianR = respValues(medianIdx);
121 fprintf('Response Time Median: %.4f\n', medianR);
122end
123
124%% Block 10: Create PDF plots
125figure('Name', 'Posterior Distribution PDFs', 'Position', [100, 100, 1200, 400]);
126
127% Plot 1: Response Time PDF
128subplot(1, 3, 1);
129bar(respValues, respProbs, 1.0, 'FaceColor', [0.2, 0.6, 0.8], 'EdgeColor', [0.1, 0.4, 0.6]);
130hold on;
131xline(expectedR, 'r-', 'LineWidth', 2.5);
132hold off;
133xlabel('Response Time (R)');
134ylabel('Probability');
135title('Posterior PDF: Response Time');
136legend({'P(R)', sprintf('E[R] = %.3f', expectedR)}, 'Location', 'best');
137grid on;
138
139% Plot 2: Queue Length PDF
140subplot(1, 3, 2);
141bar(qlenValues, qlenProbs, 1.0, 'FaceColor', [0.4, 0.8, 0.4], 'EdgeColor', [0.2, 0.6, 0.2]);
142hold on;
143xline(expectedQ, 'r-', 'LineWidth', 2.5);
144hold off;
145xlabel('Queue Length (Q)');
146ylabel('Probability');
147title('Posterior PDF: Queue Length');
148legend({'P(Q)', sprintf('E[Q] = %.3f', expectedQ)}, 'Location', 'best');
149grid on;
150
151% Plot 3: Utilization PDF
152subplot(1, 3, 3);
153bar(utilValues, utilProbs, 1.0, 'FaceColor', [0.8, 0.4, 0.4], 'EdgeColor', [0.6, 0.2, 0.2]);
154hold on;
155xline(expectedU, 'r-', 'LineWidth', 2.5);
156hold off;
157xlabel('Utilization (U)');
158ylabel('Probability');
159title('Posterior PDF: Utilization');
160legend({'P(U)', sprintf('E[U] = %.3f', expectedU)}, 'Location', 'best');
161grid on;
162
163sgtitle('Posterior Distribution PDFs for M/M/1 with Uncertain Service Rate');
164
165%% Block 11: Create PDF and CDF plot for response time
166figure('Name', 'Response Time: PDF and CDF', 'Position', [150, 150, 1000, 400]);
167
168% Left: Area plot for continuous-looking PDF
169subplot(1, 2, 1);
170area(respValues, respProbs, 'FaceColor', [0.2, 0.6, 0.8], 'FaceAlpha', 0.7, 'EdgeColor', [0.1, 0.4, 0.6], 'LineWidth', 1.5);
171hold on;
172xline(expectedR, 'r-', 'LineWidth', 2.5);
173[~, modeIdx] = max(respProbs);
174plot(respValues(modeIdx), respProbs(modeIdx), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', 'k');
175hold off;
176xlabel('Response Time (R)');
177ylabel('Probability Density');
178title('Posterior PDF');
179legend({'f(R)', sprintf('E[R] = %.3f', expectedR), sprintf('Mode = %.3f', respValues(modeIdx))}, 'Location', 'best');
180grid on;
181
182% Right: CDF
183subplot(1, 2, 2);
184plot(respValues, respCdf, 'LineWidth', 2.5, 'Color', [0.2, 0.6, 0.8]);
185hold on;
186medianIdx = find(respCdf >= 0.5, 1, 'first');
187if ~isempty(medianIdx)
188 medianR = respValues(medianIdx);
189 plot(medianR, 0.5, 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');
190 xline(medianR, 'r:', 'LineWidth', 1.5);
191end
192xline(expectedR, 'g--', 'LineWidth', 2);
193yline(0.5, 'k:', 'LineWidth', 1);
194hold off;
195xlabel('Response Time (R)');
196ylabel('Cumulative Probability');
197title('Posterior CDF');
198if ~isempty(medianIdx)
199 legend({'F(R)', sprintf('Median = %.3f', medianR), '', sprintf('E[R] = %.3f', expectedR)}, 'Location', 'best');
200else
201 legend({'F(R)', sprintf('E[R] = %.3f', expectedR)}, 'Location', 'best');
202end
203grid on;
204xlim([min(respValues)*0.9, max(respValues)*1.1]);
205ylim([0, 1.05]);
206
207sgtitle('Response Time Posterior Distribution');
Definition mmt.m:92