0

Sympy changes the order of display of coefficients in equations. In epidemiological models it is common practice to put parameters first followed by state variables. Sympy changes the order when it displays the system of equations (including when using sympy.printlatex()). Note, parameters are usually lower case and from the Greek, occasionally Latin, alphabets, whereas state variables are upper case and from the Latin alphabet.

Here is a code example:

import sympy 

# Setup Symbols for Sympy
N, S, I, R, mu, beta,  gamma = sympy.symbols('N S I R mu beta gamma')

# The system written to epidimiological mode format
ODE_S = mu*N-beta*S*I-mu*S
ODE_I = beta*S*I-(mu+gamma)*I
ODE_R = gamma*I-mu*R

ODEs = sympy.Matrix([ODE_S,ODE_I,ODE_R])

Yet the order changes when using:

ODEs

or

sympy.print_latex(ODEs)

So for instance, in the output the recovery term becomes $I \gamma $, not what was input, $\gamma I$. I would like this term to to remain $\gamma I$, and a similar format for all other multiples.

I ask as this question as part of an issue with an epidimiological modelling package that uses sympy (see https://github.com/publichealthengland/pygom/issues/59). It would be handy if the order of input terms was preserved despite changes that might occur later to the equations.

  • You can use `evaluate(False)` to prevent the terms being reordered in the internal data structures. The problem then is that the printing code also changes the order so you'd need to make a custom printer and override how it prints Add and Mul. – Oscar Benjamin Nov 29 '21 at 16:51

1 Answers1

0

This is discussed here and it works for your case:

>>> e = ODEs.replace(
...     lambda x: x.is_Mul and I in x.args,
...     lambda x: Mul(x/I, I, evaluate=False))  # put I last
>>> from sympy.printing.latex import LatexPrinter
>>> nprint = LatexPrinter(dict(order='none'))
>>> nprint.doprint(e)
\left[\begin{matrix}N \mu + - S \beta I - S \mu\\S \beta I + \left(-
\gamma - \mu\right) I\\\gamma I - R \mu\end{matrix}\right]

From texrendr.com I get:

(There should really be a simpler way to do this; maybe there is but I don't use custom printing much.)

smichr
  • 16,948
  • 2
  • 27
  • 34