1classdef Solver < handle
2 % Abstract base
class for all LINE model solution algorithms
4 % Provides common
interface and infrastructure for queueing network analysis.
6 % Copyright (c) 2012-2026, Imperial College London
15 properties (Hidden, Access =
public)
19 properties (Access = public)
20 options; % Data structure with solver options
22 model; % Model to be solved
29 function self = Solver(model, name, options)
30 % SELF = SOLVER(MODEL, NAME, OPTIONS)
31 if nargin<3 %~exist('options','var')
32 options = self.defaultOptions;
34 self.model = model; % passed by reference for cache update
36 self.options = options;
37 self.enableChecks = true;
41 methods (Abstract) % implemented with errors for Octave compatibility
43 runtime = runAnalyzer(self, options)% generic method to run the solver
44 bool = supports(self,model);
49 function model = getModel(self)
53 function self = setChecks(self,
bool)
54 self.enableChecks =
bool;
56 function out = getName(self)
61 function results = getResults(self)
62 % RESULTS = GETRESULTS()
63 % Return results data structure
64 results = self.result;
67 function
bool = hasResults(self)
69 % Check if the model has been solved
70 bool = ~isempty(self.result);
73 function options = getOptions(self)
74 % OPTIONS = GETOPTIONS()
75 % Return options data structure
76 options = self.options;
81 % Dispose previously stored results
83 Solver.resetRandomGeneratorSeed(self.options.seed);
86 function self = setOptions(self, options)
87 % SELF = SETOPTIONS(OPTIONS)
88 % Set a new options data structure
89 self.options = options;
96 function resetRandomGeneratorSeed(seed)
97 % RESETRANDOMGENERATORSEED(SEED)
98 % Assign a new seed to the random number generator
99 warning('off','MATLAB:RandStream:ActivatingLegacyGenerators');
100 warning('off','MATLAB:RandStream:ReadingInactiveLegacyGeneratorState');
104 function
bool = isJavaAvailable()
105 % BOOL = ISJAVAAVAILABLE()
106 % Check if Java dependencies are available for the solver
109 [~,ret] = dos('java -version');
110 if strfind(ret,'not recognized') %
#ok<STRIFCND>
114 [~,ret] = unix(
'java -version');
115 if strfind(ret,
'command not found') %#ok<STRIFCND>
121 function [optList, allOpt] = listValidOptions()
122 % OPTLIST = LISTVALIDOPTIONS()
123 % List valid fields
for options data structure
124 optList = {
'cache',
'cutoff',
'force',
'init_sol',
'iter_max',
'iter_tol',
'lang',
'tol', ...
125 'keep',
'method',
'odesolvers',
'samples',
'seed',
'stiff',
'timespan',
'timestep',
'verbose',
'config.multiserver',
'confint'};
126 %,
'amva.aql',
'aql',
'amva.qdaql',
'qdaql',
'mom',
'brute',
'jmva.ls',
'jmt.jmva.ls'
127 allOpt = {
'cache',
'cutoff',
'force',
'init_sol',
'iter_max',
'iter_tol',
'lang',
'tol', ...
128 'keep',
'method',
'odesolvers',
'samples',
'seed',
'stiff',
'timespan',
'timestep',
'verbose',
'config.multiserver',
'confint', ...
129 'default',
'exact',
'auto',
'ctmc',
'ctmc.gpu',
'gpu',
'mva',
'mva.exact',
'mva.amva',
'mva.qna',
'sqni',
'mva.sqni',...
130 'amva',
'amva.bs',
'amva.qd',
'bs',
'qd',
'amva.qli',
'qli',
'amva.fli',
'fli',
'amva.lin',
'lin',
'amva.qdlin',
'qdlin',...
131 'ssa',
'ssa.parallel',
'serial',
'parallel',
'nrm',...
132 'jmt',
'jsim',
'replication',
'jmva',
'jmva.amva',
'jmva.mva',
'jmva.recal',
'jmva.mom',
'jmva.comom',
'jmva.chow',
'jmva.bs',
'jmva.aql',
'jmva.lin',
'jmva.dmlin',
'jmt.jsim',...
133 'jmt.jmva',
'jmt.jmva.mva',
'jmt.jmva.amva',
'jmt.jmva.recal',
'jmt.jmva.comom',
'jmt.jmva.chow',
'jmt.jmva.bs',
'jmt.jmva.aql',
'jmt.jmva.lin',
'jmt.jmva.dmlin',...
134 'ca',
'comom',
'comomld',
'gm',
'propfair',
'recal',
'kt',
'rd',
'nrp',
'nrl', ...
135 'nc.brute',
'nc.ca',
'nc.comom',
'nc.comomld',
'nc.gm',
'nc.mom',
'nc.propfair',
'nc.recal',
'nc.kt',
'nc.rd',
'nc.nr.probit',
'nc.nr.logit', ...
136 'fluid',
'matrix',
'softmin',
'statedep',
'closing',
'diffusion',
'fluid.softmin',
'fluid.statedep',
'fluid.closing',
'fluid.matrix',
'fluid.diffusion',...
137 'nc',
'nc.exact',
'nc.imci',
'ls',
'nc.ls',
'nc.cub',
'cub',
'le',
'nc.le',
'nc.panacea',
'panacea',
'nc.mmint2',
'mmint2',
'nc.gleint',
'gleint',
'mam',
'dec.source',
'dec.mmap',...
138 'mmk',
'gigk',
'gigk.kingman_approx', ...
139 'mm1',
'mg1',
'gm1',
'gig1',
'gim1',
'gig1.kingman',
'gig1.gelenbe',
'gig1.heyman',
'gig1.kimura',
'gig1.allen',
'gig1.kobayashi',
'gig1.klb',
'gig1.marchal',...
140 'aba.upper',
'aba.lower',
'gb.upper',
'gb.lower',
'sb.upper',
'sb.lower',
'bjb.upper',
'bjb.lower',
'pb.upper',
'pb.lower'};
143 function
bool = isValidOption(optName)
144 % BOOL = ISVALIDOPTION(OPTNAME)
145 % Check
if the given option exists
for the solver
146 [~,allOpts] = Solver.listValidOptions();
147 bool = any(cell2mat(findstring(optName, allOpts))==1);
150 function options = defaultOptions()
151 % OPTIONS = DEFAULTOPTIONS()
152 % Return
default options
153 options = lineDefaults;
156 function [enabled, level] = parseConfInt(confint)
157 % [ENABLED, LEVEL] = PARSECONFINT(CONFINT)
158 % Parse confidence interval option value
159 % Returns enabled (
true/
false) and confidence level (0.0-1.0)
160 if islogical(confint)
162 level = 0.95; % default 95% confidence
163 elseif isnumeric(confint) && confint > 0 && confint < 1
166 elseif isnumeric(confint) && confint == 0
175 function options = parseOptions(varargin, defaultOptions)
176 % OPTIONS = PARSEOPTIONS(VARARGIN, DEFAULTOPTIONS)
177 % Parse option parameters into options data structure
179 options = defaultOptions;
180 elseif isstruct(varargin{1})
181 options = varargin{1};
182 elseif ischar(varargin{1})
183 if length(varargin)>1 && isstruct(varargin{2}) % options
struct after method field
184 options = varargin{2};
186 elseif isscalar(varargin)
187 options = defaultOptions;
188 options.method = varargin{1};
190 options = defaultOptions;
192 [optList, allOpt] = Solver.listValidOptions();
193 allMethodsList = setdiff(allOpt, optList);
194 while ~isempty(varargin)
195 if Solver.isValidOption(varargin{1}) || startsWith(varargin{1},
'config.')
198 options.method = varargin{1};
202 case 'config.eventcache'
203 options.config.eventcache = varargin{2};
204 case 'config.highvar'
205 options.config.highvar = varargin{2};
206 case 'config.multiserver'
207 options.config.multiserver = varargin{2};
208 case 'config.np_priority'
209 options.config.np_priority = varargin{2};
210 case 'config.fork_join'
211 options.config.fork_join = varargin{2};
213 % Convert
string verbose level to VerboseLevel constant
214 if ischar(varargin{2}) || isstring(varargin{2})
215 switch upper(
char(varargin{2}))
217 options.verbose = VerboseLevel.SILENT;
219 options.verbose = VerboseLevel.STD;
221 options.verbose = VerboseLevel.DEBUG;
223 options.verbose = varargin{2};
226 options.verbose = varargin{2};
229 options.(varargin{1}) = varargin{2};
235 %line_warning(mfilename,sprintf(
'Option "%s" does not exist. Ignoring.',varargin{1}));
240 line_error(mfilename,
'Invalid parameter.');