1function [PercRT, PercTable] = getPerctRespT(self, percentiles,
jobclass)
2% [PERCRT, PERCTABLE] = GETPERCTRESPT(SELF, PERCENTILES, JOBCLASS)
3% Retrieve response time percentile results from FJ_codes analysis or CDF
6% self - SolverMAM instance
7% percentiles - Array of percentile values to compute (e.g., [0.90, 0.95, 0.99] or [90, 95, 99])
8%
jobclass - (optional) specific job
class to retrieve percentiles
for
11% PercRT - Struct array with fields for each class:
13% .percentiles - percentile levels (e.g., [90, 95, 99])
14% .values - percentile values (response times)
15% .K - number of parallel queues in Fork-Join
16% PercTable - Formatted table for display with columns:
17% JobClass, Percentile, ResponseTime
20% Z. Qiu, J.F. Pérez, and
P. Harrison,
"Beyond the Mean in Fork-Join Queues:
21% Efficient Approximation for Response-Time Tails", IFIP Performance 2015.
22% Copyright 2015 Imperial College London
24% Copyright (c) 2012-2026, Imperial College London
27% Normalize percentiles to [0, 1] range
28if any(percentiles > 1)
29 percentiles = percentiles / 100;
34% Check
if FJ_codes percentile results are available
35if isfield(self.result,
'Percentile') && ~isempty(self.result.Percentile)
36 % Use FJ_codes results (pre-computed)
37 percResults = self.result.Percentile;
40 % Fall back to CDF-based percentile extraction
44% Determine which
classes to
return
52 classIdx = find(strcmp(sn.classnames,
jobclass));
54 line_error(mfilename,
'Job class "%s" not found in model.',
jobclass);
58 % Class index provided
63% Build PercRT
struct array
67 % Use pre-computed FJ_codes results
71 if r > length(percResults.RT) || isempty(percResults.RT{r})
72 line_warning(mfilename, 'No percentile results for class %d.', r);
76 % Extract percentile data for this class
77 classPercResults = percResults.
RT{r};
79 % Interpolate to get requested percentiles (
if different from stored)
80 storedPercentiles = classPercResults.percentiles; % In percentage form from mainFJ
81 storedValues = classPercResults.RTp;
83 % Convert requested percentiles to percentage form
for interpolation
84 % (percentiles are already normalized to [0,1] on line 28)
85 requestedPercentiles = percentiles * 100;
87 % Interpolate to requested percentiles
88 interpValues = interp1(storedPercentiles, storedValues, requestedPercentiles,
'linear',
'extrap');
90 PercRT(idx).class = sn.classnames{r};
91 PercRT(idx).percentiles = percentiles; % Keep in fractional form [0,1]
92 PercRT(idx).values = interpValues;
93 PercRT(idx).K = percResults.K;
94 PercRT(idx).method = percResults.method;
97 % Extract percentiles from CDF
99 RD = self.getCdfRespT();
101 line_error(mfilename,
'Unable to compute percentiles. getCdfRespT not available for this model.');
107 % Find CDF data
for this class
109 % where F are CDF probabilities and X are time values
110 % Search through stations to find non-empty CDF data
112 for i = 1:size(
RD, 1)
113 if r <= size(
RD, 2) && ~isempty(
RD{i, r})
120 % CDF format
is [F, X] where F = probabilities, X = times
121 probs = cdfData(:, 1);
122 times = cdfData(:, 2);
124 % Remove duplicate probability values
for interpolation
125 [probs_unique, idx_unique] = unique(probs,
'last');
126 times_unique = times(idx_unique);
128 % Interpolate to find times at requested percentiles
129 percValues = interp1(probs_unique, times_unique, percentiles,
'linear',
'extrap');
131 PercRT(idx).class = sn.classnames{r};
132 PercRT(idx).percentiles = percentiles; % Keep in fractional form [0,1]
133 PercRT(idx).values = percValues;
134 PercRT(idx).method =
'cdf';
139% Build PercTable
for display
145 for idx = 1:length(PercRT)
146 nPercentiles = length(PercRT(idx).percentiles);
147 for p = 1:nPercentiles
148 JobClass{end+1,1} = PercRT(idx).class;
149 Percentile(end+1,1) = PercRT(idx).percentiles(p);
150 ResponseTime(end+1,1) = PercRT(idx).values(p);
154 JobClass = label(JobClass);
155 PercTable = Table(JobClass, Percentile, ResponseTime);