1function [pi, num, den, stateSpace] = getSymbolicSolution(self)
2% [PI, NUM, DEN, STATESPACE] = GETSYMBOLICSOLUTION()
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.
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.
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
20% Copyright (c) 2012-2026, Imperial College London
23backend = SolverCTMC.symbolicBackend(self);
25if isprop(self, 'options
') && isfield(self.options, 'config
') && ...
26 isfield(self.options.config, 'symbolic_timeout
')
27 timeout = self.options.config.symbolic_timeout;
30[infGen, ~, ~, stateSpace] = self.getSymbolicGenerator();
32useToolbox = SAGE.hasSymbolicToolbox() && ~strcmpi(backend, 'sage
') && ...
33 ~strncmpi(backend, 'http
', 4);
35 pi = ctmc_solve(infGen);
36 pi = simplify(pi(:).');
37 [num, den] = numden(pi);
40 if numel(symvar(den)) == 0 && isscalar(unique(den))
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.
50 symbols = arrayfun(@
char, symvar(infGen), 'UniformOutput', false);
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'));
57url = SAGE.resolve(backend);
61[pi, num, den] = SAGE.solveCTMC(infGen, symbols, url, timeout);