LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
getSymbolicSolution.m
1function [pi, num, den, stateSpace] = getSymbolicSolution(self)
2% [PI, NUM, DEN, STATESPACE] = GETSYMBOLICSOLUTION()
3%
4% Symbolic stationary distribution of the CTMC as a function of the event rate
5% symbols x1, ..., xE, i.e. the solution of pi*Q = 0 with sum(pi) = 1 over the
6% field of rational functions in those symbols.
7%
8% The generator is assembled by getSymbolicGenerator, which needs no computer
9% algebra because it is linear in the symbols. Solving with it does, and is
10% delegated to the backend named by options.config.symbolic: the Symbolic Math
11% Toolbox when it is licensed and the backend is 'auto' or 'matlab', otherwise
12% the line-sage-rest service (see SAGE.m). NUM and DEN give the same vector
13% over one common denominator.
14%
15% The expressions are not comparable with another codebase's by text: symbol
16% numbering follows event enumeration order and the printed normal form
17% depends on the engine. Substitute rates and compare numbers instead, as
18% SAGE.eval does.
19%
20% Copyright (c) 2012-2026, Imperial College London
21% All rights reserved.
22
23backend = SolverCTMC.symbolicBackend(self);
24timeout = 300;
25if isprop(self, 'options') && isfield(self.options, 'config') && ...
26 isfield(self.options.config, 'symbolic_timeout')
27 timeout = self.options.config.symbolic_timeout;
28end
29
30[infGen, ~, ~, stateSpace] = self.getSymbolicGenerator();
31
32useToolbox = SAGE.hasSymbolicToolbox() && ~strcmpi(backend, 'sage') && ...
33 ~strncmpi(backend, 'http', 4);
34if useToolbox
35 pi = ctmc_solve(infGen);
36 pi = simplify(pi(:).');
37 [num, den] = numden(pi);
38 num = simplify(num);
39 den = simplify(den);
40 if numel(symvar(den)) == 0 && isscalar(unique(den))
41 den = den(1);
42 end
43 return
44end
45
46% The service takes the generator as expression strings; a sym generator is
47% rendered on the way out, a cell one is already in that form.
48symbols = {};
49if isa(infGen, 'sym')
50 symbols = arrayfun(@char, symvar(infGen), 'UniformOutput', false);
51else
52 % Symbols are x1..xE by construction; collect the ones that occur.
53 joined = strjoin(reshape(infGen, 1, []), ' ');
54 tokens = unique(regexp(joined, 'x\d+', 'match'));
55 symbols = tokens;
56end
57url = SAGE.resolve(backend);
58if isempty(url)
59 url = SAGE.require();
60end
61[pi, num, den] = SAGE.solveCTMC(infGen, symbols, url, timeout);
62end