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% Extract response time percentiles from CDF or solver-specific results
4%
5% Parameters:
6% self - NetworkSolver instance
7% percentiles - Array of percentile values (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 (as percentages)
14% .values - percentile values (response times)
15% .method - extraction method ('cdf' or solver-specific)
16% PercTable - Formatted table for display
17%
18% This method provides a generic interface for extracting response time
19% percentiles. Solvers that compute CDFs via getCdfRespT can use this
20% method to extract percentile values. Solvers may override this method
21% to provide more efficient or accurate percentile computation.
22%
23% Copyright (c) 2012-2026, Imperial College London
24% All rights reserved.
25
26% Normalize percentiles to [0, 1] range
27if any(percentiles > 1)
28 percentiles = percentiles / 100;
29end
30
31sn = self.getStruct();
32
33% Determine which classes to return
34if nargin < 3 || isempty(jobclass)
35 % Return all classes
36 classes = 1:sn.nclasses;
37else
38 % Find class index
39 if ischar(jobclass) || isstring(jobclass)
40 % Class name provided
41 classIdx = find(strcmp(sn.classnames, jobclass));
42 if isempty(classIdx)
43 line_error(mfilename, 'Job class "%s" not found in model.', jobclass);
44 end
45 classes = classIdx;
46 else
47 % Class index provided
49 end
50end
51
52% Try to get CDF for percentile extraction
53try
54 RD = self.getCdfRespT();
55catch ME
56 line_error(mfilename, ['Unable to compute percentiles. getCdfRespT not available for this solver.\n', ...
57 'Error: %s'], ME.message);
58end
59
60% Build PercRT struct array by extracting from CDF
61PercRT = struct([]);
62
63for idx = 1:length(classes)
64 r = classes(idx);
65
66 % CDF structure may vary by solver, try common patterns
67 cdfData = [];
68
69 % Pattern 1: RD is a struct with .C field (common in CTMC, Fluid, MAM)
70 if isfield(RD, 'C') && r <= length(RD.C)
71 cdfData = RD.C{r};
72 % Pattern 2: RD is a struct with .CDF field
73 elseif isfield(RD, 'CDF') && r <= length(RD.CDF)
74 cdfData = RD.CDF{r};
75 % Pattern 3: RD is a cell array
76 elseif iscell(RD) && r <= length(RD)
77 cdfData = RD{r};
78 end
79
80 if isempty(cdfData)
81 line_warning(mfilename, 'No CDF data available for class %d.', r);
82 continue;
83 end
84
85 % Extract time and probability arrays from CDF structure
86 if isstruct(cdfData)
87 if isfield(cdfData, 't') && isfield(cdfData, 'p')
88 times = cdfData.t(:);
89 probs = cdfData.p(:);
90 elseif isfield(cdfData, 'x') && isfield(cdfData, 'f')
91 times = cdfData.x(:);
92 probs = cumsum(cdfData.f(:)); % Convert PDF to CDF
93 else
94 line_warning(mfilename, 'Unrecognized CDF structure for class %d.', r);
95 continue;
96 end
97 elseif size(cdfData, 2) >= 2
98 % Matrix format: [time, prob]
99 times = cdfData(:, 1);
100 probs = cdfData(:, 2);
101 else
102 line_warning(mfilename, 'Unable to parse CDF data for class %d.', r);
103 continue;
104 end
105
106 % Ensure CDF is monotonic and normalized
107 [probs, sortIdx] = sort(probs);
108 times = times(sortIdx);
109
110 % Remove duplicates
111 [probs, uniqueIdx] = unique(probs);
112 times = times(uniqueIdx);
113
114 % Interpolate to find response times at requested percentiles
115 if length(times) > 1 && length(probs) > 1
116 percValues = interp1(probs, times, percentiles, 'linear', 'extrap');
117
118 % Ensure non-negative response times
119 percValues = max(percValues, 0);
120
121 PercRT(idx).class = sn.classnames{r};
122 PercRT(idx).percentiles = percentiles; % Keep in fractional form [0,1]
123 PercRT(idx).values = percValues;
124 PercRT(idx).method = 'cdf';
125 else
126 line_warning(mfilename, 'Insufficient CDF data points for class %d.', r);
127 end
128end
129
130% Build PercTable for display
131if nargout > 1
132 JobClass = {};
133 Percentile = [];
134 ResponseTime = [];
135
136 for idx = 1:length(PercRT)
137 nPercentiles = length(PercRT(idx).percentiles);
138 for p = 1:nPercentiles
139 JobClass{end+1,1} = PercRT(idx).class;
140 Percentile(end+1,1) = PercRT(idx).percentiles(p);
141 ResponseTime(end+1,1) = PercRT(idx).values(p);
142 end
143 end
144
145 JobClass = label(JobClass);
146 PercTable = Table(JobClass, Percentile, ResponseTime);
147end
148
149end