LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
sym_engine.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_SYM_SYM_ENGINE_H
6#define LINE_API_SYM_SYM_ENGINE_H
7
8/**
9 * @file
10 * @ingroup api_sym
11 * Computer algebra operations LINE needs, as seen by this port.
12 *
13 * Port of jline.api.sym.SymEngine. C++ has no computer algebra system any more
14 * than Java does, so every operation here is delegated to an external engine;
15 * SageRestEngine is the SageMath implementation and is resolved by
16 * sym_engines.h. Expressions cross the interface as plain ASCII infix strings,
17 * e.g. "2*x1 - 3*x2".
18 *
19 * EXPRESSION STRINGS ARE NOT COMPARABLE ACROSS CODEBASES, and not even across
20 * engine versions: the symbol numbering x1..xE follows event enumeration order
21 * and printed normal forms depend on the engine. Compare by substituting values
22 * with eval() and comparing numbers; a string diff against the JAR's output is
23 * a false failure waiting to happen.
24 *
25 * ABSENT VALUES. Java returns null for a field the request did not ask for.
26 * Here an absent scalar is the empty string and an absent list or matrix is
27 * empty, with an explicit `has*` flag where emptiness would otherwise be
28 * ambiguous.
29 */
30
31#include <map>
32#include <string>
33#include <vector>
34
35#include "line/util/error.h"
36
37namespace line {
38namespace sym {
39
40/** The symbolic backend is unreachable, or rejected the request. */
41class SymEngineError : public Error {
42public:
43 explicit SymEngineError(const std::string& what) : Error(what) {}
44};
45
46/** Symbolic stationary distribution of a CTMC. */
48 std::vector<std::string> pi; ///< Stationary probability of each state, as an expression
49 std::vector<std::string> num; ///< Numerator of each entry over the common denominator
50 std::string den = "1"; ///< Common denominator of the whole vector
51 int nConnComp = 1; ///< Weakly connected components of the generator
52 std::vector<int> connComp; ///< Component index of each state, one based
53};
54
55/**
56 * Exact parametric sensitivity, following Trivedi and Bobbio (2017), Sec. 9.7.
57 *
58 * As in `@SolverCTMC/getSensitivity.m`, dr/dtheta is taken to be zero: a reward
59 * whose rates themselves depend on theta needs the second term of Eq. (9.83)
60 * and is not covered here.
61 */
63 std::vector<std::string> pi; ///< Stationary distribution
64 std::vector<std::string> dpi; ///< Derivative of the distribution with respect to theta
65 std::string Er; ///< Mean reward, empty if no reward was given
66 std::string S; ///< Unscaled sensitivity d(E[r])/dtheta, Eq. (9.79)
67 std::string SS; ///< Scaled sensitivity (theta/E[r]) d(E[r])/dtheta, Eq. (9.80)
68 bool hasReward = false; ///< Whether Er, S and SS were computed
69};
70
71/** Symbolic analysis of a fluid vector field. */
72struct FluidODEs {
73 std::vector<std::vector<std::string>> jacobian; ///< d f_i / d x_j
74 std::vector<std::string> latex; ///< LaTeX form of each right hand side
75 std::vector<std::map<std::string, std::string>> equilibria; ///< variable -> expression
76 bool hasJacobian = false;
77 bool hasLatex = false;
78 bool hasEquilibria = false;
79};
80
81/** A computer algebra backend. */
82class SymEngine {
83public:
84 virtual ~SymEngine() {}
85
86 /** Name of the backing engine, e.g. "sage". */
87 virtual std::string name() const = 0;
88
89 /** True if the engine answers a health probe. */
90 virtual bool isAvailable() const = 0;
91
92 /**
93 * Symbolic stationary distribution of a CTMC, pi Q = 0 with sum(pi) = 1.
94 *
95 * @param Q generator entries as expression strings, row major and square
96 * @param symbols the symbols appearing in Q, e.g. x1..xE
97 * @return the solution, with pi also split over a common denominator
98 */
99 virtual CtmcSolution solveCTMC(const std::vector<std::vector<std::string>>& Q,
100 const std::vector<std::string>& symbols) = 0;
101
102 /**
103 * Exact parametric sensitivity of a steady-state reward.
104 *
105 * @param Q generator entries as expression strings, row major
106 * @param symbols the symbols appearing in Q
107 * @param theta the symbol to differentiate with respect to
108 * @param reward reward rate per state, empty for the distribution alone
109 * @return the sensitivity of the distribution and, if a reward is given, of its mean
110 */
111 virtual SymSensitivity ctmcSensitivity(const std::vector<std::vector<std::string>>& Q,
112 const std::vector<std::string>& symbols,
113 const std::string& theta,
114 const std::vector<std::string>& reward) = 0;
115
116 /**
117 * Rewrites expressions into a normal form.
118 *
119 * @param exprs the expressions
120 * @param form one of simplify, factor, together, cancel, expand, latex
121 * @return the rewritten expressions, in the input order
122 */
123 virtual std::vector<std::string> simplify(const std::vector<std::string>& exprs,
124 const std::string& form) = 0;
125
126 /**
127 * Differentiates expressions.
128 *
129 * @param exprs the expressions
130 * @param variable the differentiation variable
131 * @param order the order of the derivative, at least 1
132 * @return the derivatives, in the input order
133 */
134 virtual std::vector<std::string> diff(const std::vector<std::string>& exprs,
135 const std::string& variable, int order) = 0;
136
137 /**
138 * Substitutes values for symbols and evaluates.
139 *
140 * @param exprs the expressions
141 * @param assignment value of each symbol
142 * @return the numeric values, NaN where a free symbol remains
143 */
144 virtual std::vector<double> eval(const std::vector<std::string>& exprs,
145 const std::map<std::string, double>& assignment) = 0;
146
147 /**
148 * Jacobian, LaTeX form and equilibria of a fluid vector field.
149 *
150 * @param rhs the right hand side of dx/dt, one expression per state variable
151 * @param vars the state variable names
152 * @param want any of jacobian, latex, equilibria
153 * @return the requested items
154 */
155 virtual FluidODEs fluidODEs(const std::vector<std::string>& rhs,
156 const std::vector<std::string>& vars,
157 const std::vector<std::string>& want) = 0;
158};
159
160} // namespace sym
161} // namespace line
162
163#endif // LINE_API_SYM_SYM_ENGINE_H
Error(const std::string &what)
Definition error.h:33
SymEngineError(const std::string &what)
Definition sym_engine.h:43
A computer algebra backend.
Definition sym_engine.h:82
virtual bool isAvailable() const =0
True if the engine answers a health probe.
virtual std::string name() const =0
Name of the backing engine, e.g.
virtual CtmcSolution solveCTMC(const std::vector< std::vector< std::string > > &Q, const std::vector< std::string > &symbols)=0
Symbolic stationary distribution of a CTMC, pi Q = 0 with sum(pi) = 1.
virtual std::vector< std::string > diff(const std::vector< std::string > &exprs, const std::string &variable, int order)=0
Differentiates expressions.
virtual SymSensitivity ctmcSensitivity(const std::vector< std::vector< std::string > > &Q, const std::vector< std::string > &symbols, const std::string &theta, const std::vector< std::string > &reward)=0
Exact parametric sensitivity of a steady-state reward.
virtual std::vector< std::string > simplify(const std::vector< std::string > &exprs, const std::string &form)=0
Rewrites expressions into a normal form.
virtual std::vector< double > eval(const std::vector< std::string > &exprs, const std::map< std::string, double > &assignment)=0
Substitutes values for symbols and evaluates.
virtual FluidODEs fluidODEs(const std::vector< std::string > &rhs, const std::vector< std::string > &vars, const std::vector< std::string > &want)=0
Jacobian, LaTeX form and equilibria of a fluid vector field.
The exception types the port throws.
Symbolic stationary distribution of a CTMC.
Definition sym_engine.h:47
std::vector< std::string > pi
Stationary probability of each state, as an expression.
Definition sym_engine.h:48
std::vector< int > connComp
Component index of each state, one based.
Definition sym_engine.h:52
std::vector< std::string > num
Numerator of each entry over the common denominator.
Definition sym_engine.h:49
int nConnComp
Weakly connected components of the generator.
Definition sym_engine.h:51
std::string den
Common denominator of the whole vector.
Definition sym_engine.h:50
Symbolic analysis of a fluid vector field.
Definition sym_engine.h:72
std::vector< std::string > latex
LaTeX form of each right hand side.
Definition sym_engine.h:74
std::vector< std::map< std::string, std::string > > equilibria
variable -> expression
Definition sym_engine.h:75
std::vector< std::vector< std::string > > jacobian
d f_i / d x_j
Definition sym_engine.h:73
Exact parametric sensitivity, following Trivedi and Bobbio (2017), Sec.
Definition sym_engine.h:62
bool hasReward
Whether Er, S and SS were computed.
Definition sym_engine.h:68
std::vector< std::string > dpi
Derivative of the distribution with respect to theta.
Definition sym_engine.h:64
std::vector< std::string > pi
Stationary distribution.
Definition sym_engine.h:63
std::string SS
Scaled sensitivity (theta/E[r]) d(E[r])/dtheta, Eq. (9.80).
Definition sym_engine.h:67
std::string Er
Mean reward, empty if no reward was given.
Definition sym_engine.h:65
std::string S
Unscaled sensitivity d(E[r])/dtheta, Eq. (9.79).
Definition sym_engine.h:66