1classdef LINE < SolverAuto
5 % @brief Main entry point
for the LINE solver.
6 % @details Provides a unified
interface to access various
solvers (CTMC, MVA, SSA, JMT, Fluid, NC, MAM).
7 % Can also be used to load models from files.
10 % Alias
for SolverAuto
12 % Copyright (c) 2012-2026, Imperial College London
13 % All rights reserved.
17 function self = LINE(model, varargin)
20 % @brief Constructor
for the LINE solver wrapper.
21 % @param model The network model (Network or LayeredNetwork).
22 % @param varargin Optional arguments passed to SolverAuto.
23 % @
return self Instance of
the LINE solver.
26 % SELF = LINE(MODEL, VARARGIN)
27 self@SolverAuto(model, varargin{:});
32 function result = load(varargin)
35 % @brief Factory method to load models or instantiate
solvers.
37 % Usage 1: Load a model from file.
38 % model = LINE.load(filename)
39 % model = LINE.load(filename, verbose)
40 % Supported formats: .jsim, .jsimg, .jsimw (JMT), .jmva (JMVA), .xml/lqn/lqnx (LQN), .mat (MATLAB).
42 % Usage 2: Instantiate a solver with a specific method.
43 % solver = LINE.load(method, model, options...)
45 % @param varargin Arguments
for loading a model or creating a solver.
46 % @
return result Loaded model
object or Solver instance.
50 % Flexible loading method that handles both solver and model loading
52 % Usage 1: Load a model from file
53 % model = LINE.load(filename)
54 % model = LINE.load(filename, verbose)
56 % Usage 2: Load a solver with chosen method (legacy)
57 % solver = LINE.load(method, model, options...)
59 % Check
if this is model loading (1-2 args with first arg as
string filename)
60 if nargin >= 1 && nargin <= 2 && ischar(varargin{1}) && contains(varargin{1},
'.')
61 % Check
if this is actually a filename with a supported extension
62 [~, ~, ext] = fileparts(varargin{1});
63 supported_extensions = {
'.jsim',
'.jsimg',
'.jsimw',
'.jmva',
'.xml',
'.lqn',
'.lqnx',
'.mat'};
65 if ismember(lower(ext), supported_extensions)
66 filename = varargin{1};
69 verbose = varargin{2};
72 % Determine file format and load accordingly
74 case {
'.jsim',
'.jsimg',
'.jsimw'}
76 result = JSIM2LINE(filename);
79 result = JMVA2LINE(filename);
80 case {
'.xml',
'.lqn',
'.lqnx'}
81 % Try to load as LQN model
83 result = LQN2MATLAB(filename);
85 % If LQN fails,
try as
generic XML
86 error(
'LINE:load',
'Unsupported XML format. Only LQN XML files are supported.');
89 % Load MATLAB saved model
90 data = load(filename);
91 if isfield(data,
'model')
93 elseif isfield(data, 'network')
94 result = data.network;
96 % Find first Network
object in
the file
97 fields = fieldnames(data);
99 for i = 1:length(fields)
100 if isa(data.(fields{i}),
'Network')
101 result = data.(fields{i});
107 error(
'LINE:load',
'No Network model found in MAT file.');
112 fprintf(
'Loaded model "%s" from %s\n', result.name, filename);
115 error(
'LINE:load',
'Unsupported file format: %s', ext);
120 % If we get here,
the string contains a dot but
is not a supported file format
121 % Continue to solver loading logic below
124 % Otherwise,
this is solver loading (legacy behavior)
126 error(
'LINE:load',
'Solver loading requires at least method and model arguments.');
129 chosenmethod = varargin{1};
131 options_args = varargin(3:end);
133 options = Solver.parseOptions(options_args, Solver.defaultOptions);
134 options.method = chosenmethod;
135 switch options.method
136 case {
'default',
'auto'}
137 if strcmp(options.method,
'auto'), options.method=
'default'; end
138 result = LINE(model, options);
139 case {
'ctmc',
'ctmc.gpu',
'gpu'}
140 if strcmp(options.method,
'ctmc'), options.method=
'default'; end
141 options.method = erase(options.method,
'ctmc.');
142 result = SolverCTMC(model, options);
143 case {
'mva',
'mva.exact',
'amva',
'mva.amva',
'qna',
'mva.qna',
'sqrt',
'mva.sqrt' ...
144 'amva.qd',
'mva.amva.qd', ...
145 'amva.bs',
'mva.amva.bs', ...
146 'amva.qli',
'mva.amva.qli', ...
147 'amva.fli',
'mva.amva.fli', ...
148 'amva.lin',
'mva.amva.lin', ...
149 'mm1',
'mmk',
'mg1',
'gm1',
'gig1',
'gim1',
'gig1.kingman', ...
150 'gigk',
'gigk.kingman_approx', ...
151 'gig1.gelenbe',
'gig1.heyman',
'gig1.kimura',
'gig1.allen',
'gig1.kobayashi',
'gig1.klb',
'gig1.marchal'}
152 %
'amva.aql',
'mva.amva.aql', ...
153 %
'amva.qdaql',
'mva.amva.qdaql', ...
154 if strcmp(options.method,
'mva'), options.method=
'default'; end
155 options.method = erase(options.method,
'mva.');
156 result = SolverMVA(model, options);
157 case {
'aba.upper',
'aba.lower',
'bjb.upper',
'bjb.lower',
'gb.upper',
'gb.lower', ...
158 'pb.upper',
'pb.lower',
'sb.upper',
'sb.lower',
'mwba.upper',
'mwba.lower', ...
159 'pbh.upper',
'pbh.lower', ...
160 'pbk.upper',
'pbk.lower',
'bjbk.upper',
'bjbk.lower', ...
161 'cbh.upper',
'cbh.lower',
'ssd.upper',
'ssd.lower', ...
162 'cub.upper',
'mbjb.lower',
'sib.upper',
'sib.lower',
'ldbcmp.lower', ...
164 'qrf.mmi',
'qrf.mem',
'qrf.mmi.ld',
'qrf.mmi.linear', ...
165 'qrf.bas.mmi',
'qrf.bas.mem',
'qrf.bas',
'qrf.rsrd', ...
167 % Bound analysis (incl. QRF LP-based reduction bounds)
168 % lives in SolverBA (moved out of SolverMVA and SolverCTMC)
169 options.method = erase(options.method,
'ba.');
170 result = SolverBA(model, options);
171 case {
'nrm',
'ssa',
'ssa.serial',
'ssa.parallel',
'serial',
'parallel'}
172 if strcmp(options.method,
'ssa'), options.method=
'default'; end
173 options.method = erase(options.method,
'ssa.');
174 result = SolverSSA(model, options);
175 case {
'jmt',
'jsim',
'jmva',
'jmva.mva',
'jmva.recal',
'jmva.comom',
'jmva.chow',
'jmva.bs',
'jmva.aql',
'jmva.lin',
'jmva.dmlin',... %,
'jmva.ls',
'jmt.jmva.ls'
176 'jmt.jsim',
'jmt.jmva',
'jmt.jmva.mva',
'jmt.jmva.amva',
'jmva.amva',
'jmt.jmva.recal',
'jmt.jmva.comom',
'jmt.jmva.chow',
'jmt.jmva.bs',
'jmt.jmva.aql',
'jmt.jmva.lin',
'jmt.jmva.dmlin'}
177 if strcmp(options.method,
'jmt'), options.method=
'default'; end
178 options.method = erase(options.method,
'jmt.');
179 result = SolverJMT(model, options);
180 case {
'fluid',
'fluid.softmin',
'fluid.statedep',
'fluid.closing'}
181 if strcmp(options.method,
'fluid'), options.method=
'default'; end
182 options.method = erase(options.method,
'fluid.');
183 result = SolverFluid(model, options);
184 case {
'nc',
'nc.exact',
'nc.imci',
'nc.ls',
'comom',
'comomld',
'cub',
'ls',
'nc.le',
'le',
'mmint2',
'nc.panacea',
'nc.pana',
'nc.mmint2',
'nc.kt',
'nc.deterministic',
'nc.sampling',
'nc.propfair',
'nc.comom',
'nc.comomld',
'nc.mom',
'nc.cub',
'nc.brute',
'nc.rd',
'nc.nr.probit',
'nc.nr.logit',
'nc.gm'}
185 if strcmp(options.method,
'nc'), options.method=
'default'; end
186 options.method = erase(options.method,
'nc.');
187 result = SolverNC(model, options);
188 case {
'mam',
'mam.dec.source',
'mam.dec.mmap',
'mam.dec.poisson'}
189 if strcmp(options.method,
'mam'), options.method=
'default'; end
190 options.method = erase(options.method,
'mam.');
191 result = SolverMAM(model, options);
193 if strcmp(options.method,
'auto'), options.method=
'default'; end
194 result = LINE(model, options);