LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_fluid_aoi.m
1function [QN, UN, RN, TN, xvec_it, QNt, UNt, TNt, xvec_t, t, iters, runtime, aoiResults] = solver_fluid_aoi(sn, options)
2%SOLVER_FLUID_AOI Age of Information analysis using Markovian Fluid Queues
3%
4% [QN, UN, RN, TN, xvec_it, QNt, UNt, TNt, xvec_t, t, iters, runtime, aoiResults] = SOLVER_FLUID_AOI(sn, options)
5%
6% Analyzes Age of Information for single-queue open systems using the
7% aoi-fluid MFQ solvers.
8%
9% Supported systems:
10% - Capacity 1 (bufferless): PH/PH/1/1 or PH/PH/1/1* (preemptive)
11% - Capacity 2 (single-buffer): M/PH/1/2 or M/PH/1/2* (replacement)
12%
13% Parameters:
14% sn (struct): Network structure from Network.getStruct()
15% options (struct): Solver options including:
16% - config.aoi_preemption: Override preemption/replacement probability (0-1)
17%
18% Returns:
19% QN, UN, RN, TN: Standard performance metrics
20% xvec_it, QNt, UNt, TNt, xvec_t, t: Transient outputs (for compatibility)
21% iters: Number of iterations (always 1)
22% runtime: Execution time in seconds
23% aoiResults (struct): Age of Information results:
24% .AoI_mean, .AoI_var: Mean and variance of AoI
25% .PAoI_mean, .PAoI_var: Mean and variance of Peak AoI
26% .AoI_g, .AoI_A, .AoI_h: Matrix exponential parameters for AoI CDF
27% .PAoI_g, .PAoI_A, .PAoI_h: Matrix exponential parameters for Peak AoI CDF
28% .systemType: 'bufferless' or 'singlebuffer'
29% .preemption: Preemption/replacement probability used
30%
31% References:
32% aoi-fluid toolbox by Ozancan Dogan, Nail Akar, Eray Unsal Atay
33% BSD 2-Clause License, 2020
34%
35% See also: aoi_is_aoi, aoi_extract_params, solveBufferless, solveSingleBuffer
36
37% Copyright (c) 2012-2026, Imperial College London
38% All rights reserved.
39
40runtime_start = tic;
41
42M = sn.nstations;
43K = sn.nclasses;
44
45% Initialize output arrays
46QN = zeros(M, K);
47UN = zeros(M, K);
48RN = zeros(M, K);
49TN = zeros(M, K);
50
51% Initialize transient outputs (AoI is steady-state only)
52t = [0; options.timespan(2)];
53QNt = cell(M, K);
54UNt = cell(M, K);
55TNt = cell(M, K);
56for ist = 1:M
57 for k = 1:K
58 QNt{ist, k} = zeros(2, 1);
59 UNt{ist, k} = zeros(2, 1);
60 TNt{ist, k} = zeros(2, 1);
61 end
62end
63
64xvec_t = [];
65xvec_it = {zeros(1, 1)};
66iters = 1;
67
68% Initialize AoI results
69aoiResults = struct();
70aoiResults.AoI_mean = NaN;
71aoiResults.AoI_var = NaN;
72aoiResults.PAoI_mean = NaN;
73aoiResults.PAoI_var = NaN;
74aoiResults.AoI_g = [];
75aoiResults.AoI_A = [];
76aoiResults.AoI_h = [];
77aoiResults.PAoI_g = [];
78aoiResults.PAoI_A = [];
79aoiResults.PAoI_h = [];
80aoiResults.systemType = '';
81aoiResults.preemption = NaN;
82
83% =========================================================================
84% TOPOLOGY VALIDATION
85% =========================================================================
86
87[isAoI, aoiInfo] = aoi_is_aoi(sn);
88
89if ~isAoI
90 line_error(mfilename, 'AoI analysis requires valid AoI topology: %s', aoiInfo.errorMsg);
91end
92
93% Get station indices
94sourceStation = aoiInfo.sourceStation;
95queueStation = aoiInfo.queueStation;
96
97line_debug('AoI: Source station=%d, Queue station=%d, capacity=%d', ...
98 sourceStation, queueStation, aoiInfo.capacity);
99
100% =========================================================================
101% EXTRACT PARAMETERS
102% =========================================================================
103
104[aoiParams, aoiInfo] = aoi_extract_params(sn, aoiInfo, options);
105
106aoiResults.systemType = aoiInfo.systemType;
107
108% =========================================================================
109% CALL AOI-FLUID SOLVER
110% =========================================================================
111
112if aoiInfo.capacity == 1
113 % BUFFERLESS: PH/PH/1/1 or PH/PH/1/1*
114 tau = aoiParams.tau;
115 T = aoiParams.T;
116 sigma = aoiParams.sigma;
117 S = aoiParams.S;
118 p = aoiParams.p;
119
120 aoiResults.preemption = p;
121
122 line_debug('AoI: Calling solveBufferless with p=%.2f', p);
123
124 try
125 [AoI_g, AoI_A, AoI_h, AoI_mean, AoI_var, ...
126 PAoI_g, PAoI_A, PAoI_h, PAoI_mean, PAoI_var] = solveBufferless(tau, T, sigma, S, p);
127 catch ME
128 line_error(mfilename, 'solveBufferless failed: %s', ME.message);
129 end
130
131else
132 % SINGLE-BUFFER: M/PH/1/2 or M/PH/1/2*
133 lambda = aoiParams.lambda;
134 sigma = aoiParams.sigma;
135 S = aoiParams.S;
136 r = aoiParams.r;
137
138 aoiResults.preemption = r;
139
140 line_debug('AoI: Calling solveSingleBuffer with r=%.2f', r);
141
142 try
143 [AoI_g, AoI_A, AoI_h, AoI_mean, AoI_var, ...
144 PAoI_g, PAoI_A, PAoI_h, PAoI_mean, PAoI_var] = solveSingleBuffer(lambda, sigma, S, r);
145 catch ME
146 line_error(mfilename, 'solveSingleBuffer failed: %s', ME.message);
147 end
148end
149
150% Store AoI results
151aoiResults.AoI_mean = AoI_mean;
152aoiResults.AoI_var = AoI_var;
153aoiResults.PAoI_mean = PAoI_mean;
154aoiResults.PAoI_var = PAoI_var;
155aoiResults.AoI_g = AoI_g;
156aoiResults.AoI_A = AoI_A;
157aoiResults.AoI_h = AoI_h;
158aoiResults.PAoI_g = PAoI_g;
159aoiResults.PAoI_A = PAoI_A;
160aoiResults.PAoI_h = PAoI_h;
161
162line_debug('AoI: Mean AoI=%.4f, Var AoI=%.4f', AoI_mean, AoI_var);
163line_debug('AoI: Mean PAoI=%.4f, Var PAoI=%.4f', PAoI_mean, PAoI_var);
164
165% =========================================================================
166% COMPUTE STANDARD PERFORMANCE METRICS
167% =========================================================================
168
169% Find the open class
170openClasses = find(isinf(sn.njobs));
171k = openClasses(1);
172
173% Get arrival rate
174lambda = sn.rates(sourceStation, k);
175
176% Get mean service rate
177if aoiInfo.capacity == 1
178 % For bufferless: compute from PH representation
179 % Mean service time = -sigma * S^{-1} * ones
180 sigma = aoiParams.sigma;
181 S = aoiParams.S;
182 meanServiceTime = -sigma / S * ones(size(S, 1), 1);
183 mu = 1 / meanServiceTime;
184else
185 % For single-buffer: compute similarly
186 sigma = aoiParams.sigma;
187 S = aoiParams.S;
188 meanServiceTime = -sigma / S * ones(size(S, 1), 1);
189 mu = 1 / meanServiceTime;
190end
191
192% Utilization
193rho = lambda / mu;
194UN(queueStation, k) = min(1, rho);
195
196% Throughput (for stable system, equals arrival rate)
197if rho < 1
198 TN(queueStation, k) = lambda;
199else
200 TN(queueStation, k) = mu; % Saturated throughput
201end
202TN(sourceStation, k) = TN(queueStation, k);
203
204% Queue length (using Little's Law approximation)
205% For AoI systems, we can use M/M/1 approximation for queue metrics
206if rho < 1
207 QN(queueStation, k) = rho / (1 - rho);
208 RN(queueStation, k) = 1 / (mu - lambda);
209else
210 QN(queueStation, k) = Inf;
211 RN(queueStation, k) = Inf;
212end
213
214% Transient outputs
215QNt{queueStation, k} = [0; QN(queueStation, k)];
216UNt{queueStation, k} = [0; UN(queueStation, k)];
217TNt{queueStation, k} = [0; TN(queueStation, k)];
218
219runtime = toc(runtime_start);
220
221line_debug('AoI completed in %.4f seconds', runtime);
222
223end