LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
getPerctRespT.m
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
4%
5% Parameters:
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
9%
10% Returns:
11% PercRT - Struct array with fields for each class:
12% .class - class name
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
18%
19% Reference:
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
23%
24% Copyright (c) 2012-2026, Imperial College London
25% All rights reserved.
26
27% Normalize percentiles to [0, 1] range
28if any(percentiles > 1)
29 percentiles = percentiles / 100;
30end
31
32sn = self.getStruct();
33
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;
38 useFJCodes = true;
39else
40 % Fall back to CDF-based percentile extraction
41 useFJCodes = false;
42end
43
44% Determine which classes to return
45if nargin < 3 || isempty(jobclass)
46 % Return all classes
47 classes = 1:sn.nclasses;
48else
49 % Find class index
50 if ischar(jobclass) || isstring(jobclass)
51 % Class name provided
52 classIdx = find(strcmp(sn.classnames, jobclass));
53 if isempty(classIdx)
54 line_error(mfilename, 'Job class "%s" not found in model.', jobclass);
55 end
56 classes = classIdx;
57 else
58 % Class index provided
60 end
61end
62
63% Build PercRT struct array
64PercRT = struct([]);
65
66if useFJCodes
67 % Use pre-computed FJ_codes results
68 for idx = 1:length(classes)
69 r = classes(idx);
70
71 if r > length(percResults.RT) || isempty(percResults.RT{r})
72 line_warning(mfilename, 'No percentile results for class %d.', r);
73 continue;
74 end
75
76 % Extract percentile data for this class
77 classPercResults = percResults.RT{r};
78
79 % Interpolate to get requested percentiles (if different from stored)
80 storedPercentiles = classPercResults.percentiles; % In percentage form from mainFJ
81 storedValues = classPercResults.RTp;
82
83 % Convert requested percentiles to percentage form for interpolation
84 % (percentiles are already normalized to [0,1] on line 28)
85 requestedPercentiles = percentiles * 100;
86
87 % Interpolate to requested percentiles
88 interpValues = interp1(storedPercentiles, storedValues, requestedPercentiles, 'linear', 'extrap');
89
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;
95 end
96else
97 % Extract percentiles from CDF
98 try
99 RD = self.getCdfRespT();
100 catch
101 line_error(mfilename, 'Unable to compute percentiles. getCdfRespT not available for this model.');
102 end
103
104 for idx = 1:length(classes)
105 r = classes(idx);
106
107 % Find CDF data for this class
108 % RD is a cell array with format RD{station, class} = [F, X]
109 % where F are CDF probabilities and X are time values
110 % Search through stations to find non-empty CDF data
111 cdfData = [];
112 for i = 1:size(RD, 1)
113 if r <= size(RD, 2) && ~isempty(RD{i, r})
114 cdfData = RD{i, r};
115 break;
116 end
117 end
118
119 if ~isempty(cdfData)
120 % CDF format is [F, X] where F = probabilities, X = times
121 probs = cdfData(:, 1);
122 times = cdfData(:, 2);
123
124 % Remove duplicate probability values for interpolation
125 [probs_unique, idx_unique] = unique(probs, 'last');
126 times_unique = times(idx_unique);
127
128 % Interpolate to find times at requested percentiles
129 percValues = interp1(probs_unique, times_unique, percentiles, 'linear', 'extrap');
130
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';
135 end
136 end
137end
138
139% Build PercTable for display
140if nargout > 1
141 JobClass = {};
142 Percentile = [];
143 ResponseTime = [];
144
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);
151 end
152 end
153
154 JobClass = label(JobClass);
155 PercTable = Table(JobClass, Percentile, ResponseTime);
156end
157
158end