LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
fes_validate.m
1%{ @file fes_validate.m
2 % @brief Validates inputs for Flow-Equivalent Server (FES) aggregation
3 %
4 % @author LINE Development Team
5%}
6
7%{
8 % @brief Validates inputs for Flow-Equivalent Server (FES) aggregation
9 %
10 % @details
11 % Checks that the network structure and station subset are valid for FES aggregation:
12 % - Model is a closed product-form queueing network
13 % - Station subset is non-empty and not the entire network
14 % - Subset contains only Queue or Delay stations
15 % - All station indices are valid
16 %
17 % @par Syntax:
18 % @code
19 % [isValid, errorMsg] = fes_validate(sn, subsetIndices)
20 % @endcode
21 %
22 % @par Parameters:
23 % <table>
24 % <tr><th>Name<th>Description
25 % <tr><td>sn<td>Network structure (from model.getStruct())
26 % <tr><td>subsetIndices<td>Array of station indices to aggregate (1-based)
27 % </table>
28 %
29 % @par Returns:
30 % <table>
31 % <tr><th>Name<th>Description
32 % <tr><td>isValid<td>True if inputs are valid for FES aggregation
33 % <tr><td>errorMsg<td>Error message if validation fails, empty otherwise
34 % </table>
35%}
36function [isValid, errorMsg] = fes_validate(sn, subsetIndices)
37
38isValid = false;
39errorMsg = '';
40
41% Check sn is a struct
42if ~isstruct(sn)
43 errorMsg = 'First argument must be a network structure (sn).';
44 return;
45end
46
47% Check required fields exist in sn
48requiredFields = {'nstations', 'nclasses', 'njobs', 'nodetype', 'stationToNode'};
49for i = 1:length(requiredFields)
50 if ~isfield(sn, requiredFields{i})
51 errorMsg = sprintf('Network structure missing required field: %s', requiredFields{i});
52 return;
53 end
54end
55
56% Check subsetIndices is a numeric array
57if ~isnumeric(subsetIndices)
58 errorMsg = 'Station subset must be a numeric array of station indices.';
59 return;
60end
61
62% Check subset is non-empty
63if isempty(subsetIndices)
64 errorMsg = 'Station subset cannot be empty.';
65 return;
66end
67
68% Check model has only closed classes (FES applies to closed networks)
69if sn_is_open_model(sn)
70 errorMsg = 'FES aggregation only applies to closed queueing networks. Model contains open classes.';
71 return;
72end
73
74M = sn.nstations;
75
76% Check subset is not the entire network
77if length(subsetIndices) >= M
78 errorMsg = 'Cannot aggregate all stations. The subset must be a proper subset of the network.';
79 return;
80end
81
82% Validate each station index in the subset
83for i = 1:length(subsetIndices)
84 stationIdx = subsetIndices(i);
85
86 % Check station index is valid
87 if stationIdx < 1 || stationIdx > M || stationIdx ~= floor(stationIdx)
88 errorMsg = sprintf('Station index %d is invalid. Must be an integer between 1 and %d.', stationIdx, M);
89 return;
90 end
91
92 % Check station is a Queue or Delay (not Fork, Join, Source, Sink, Cache, etc.)
93 nodeIdx = sn.stationToNode(stationIdx);
94 nodeType = sn.nodetype(nodeIdx);
95
96 if nodeType ~= NodeType.Queue && nodeType ~= NodeType.Delay
97 errorMsg = sprintf('Station %d has type %s. FES aggregation only supports Queue and Delay stations.', ...
98 stationIdx, NodeType.toText(nodeType));
99 return;
100 end
101end
102
103% Check for duplicate stations in subset
104if length(unique(subsetIndices)) ~= length(subsetIndices)
105 errorMsg = 'Station subset contains duplicate stations.';
106 return;
107end
108
109% All validations passed
110isValid = true;
111
112end