Nice simplifcation and substitution of expressions in a large script

40 views
Skip to first unread message

Alexander Tille

unread,
Nov 15, 2016, 7:50:24 AM11/15/16
to sympy
Hi guys,

I'm working on a larger project, solving non-linear differential equation systems by calculating the steady states.
I want to create a very flexible script were I enter a n-dimensional equation system (mostly n=3).
The script calculates the  steady states and does a stabilty analysis and will have a latex file output.

The main part of the script is working. (see test.py or test.sh for compiling the latex code)

But I face two problems I can't solve.

My first problem is also discussed here: https://groups.google.com/forum/#!topic/sympy/ebGJLKeMODQ

All Variables of the System (here X,Y,Z) should be >= 0.
If you look at the last steady state in the latex file, the expressions for Y,Z are quite uncomfortable because of the negative sign.

(1, -(\RXZ*\RZY + \RZY + 1)/(\RYZ*\RZY - 1), -(\RXZ + \RYZ + 1)/(\RYZ*\RZY - 1))

So I would like to replace these expression by
(1, (\RXZ*\RZY + \RZY + 1)/(1 - \RYZ*\RZY ), (\RXZ + \RYZ + 1)/(1 - \RYZ*\RZY ))


If you also have a look at the diagonal elements J_2,2 and J_3,3 of the jacobian matrix.
These elements could be replaced by a much shorter term like -\RY*\Y for J_2,2 and -\RZ*\Z for J_3,3.

But the function sympy.subs() doesn't work in this case because of the negative sign of the solutions of Y and Z

I think I could solve this problem if I can transform
(1, -(\RXZ*\RZY + \RZY + 1)/(\RYZ*\RZY - 1), -(\RXZ + \RYZ + 1)/(\RYZ*\RZY - 1))
to
(1, (\RXZ*\RZY + \RZY + 1)/(1 - \RYZ*\RZY ), (\RXZ + \RYZ + 1)/(1 - \RYZ*\RZY ))

as written above.

Do you know how to transform these lines ?


My second problem is the analysis of the calculated eigenvalues of the jacobian matrix. If all eigenvalues are negative, there is a stable steady state.

The problem is that the eigenvalues can be a number or an expression. For numbers I can easily ask with an if statement, if they are negative.
For the expressions I found the function
solve_univariate_inequality()
but it doesn't seem very robust if I have a longer expressions with a lot of unknown positive constants.

Is there any function which solves ineualities with a flexible amount of input data?

Sorry for this long text and thank you in advance for your answers!

Alex



test.py
test.sh

Björn Dahlgren

unread,
Nov 16, 2016, 4:48:41 AM11/16/16
to sympy


On Tuesday, 15 November 2016 13:50:24 UTC+1, Alexander Tille wrote:
Hi guys,


Hi,
 

My first problem is also discussed here: https://groups.google.com/forum/#!topic/sympy/ebGJLKeMODQ

All Variables of the System (here X,Y,Z) should be >= 0.
If you look at the last steady state in the latex file, the expressions for Y,Z are quite uncomfortable because of the negative sign.

In this thread you will find a work-around for printing with positive terms first:
https://groups.google.com/d/topic/sympy/I0dE0-Xjshk
ideally we should enable the `order` kwarg to accept a callback (and provide some default callback which does "the right thing" most of the time).

Alexander Tille

unread,
Nov 16, 2016, 5:51:23 AM11/16/16
to sympy
Hi Björn,

Thank you for your answer. I like your work-around because it improves the latex output of my original formulas.

But I'm afraid it doesn't work for my problem (the terms calculated by solve). It is not  just a problem of printing in the right order. If you look at the variable test (see code below), the term has to be manipulated, by moving the *-1 from the numerator to the denominator.

test = -(Rzy + 1)/(Ryz*Rzy - 1)

In [22]: test
Out[22]: (-\RZY - 1)/(\RYZ*\RZY - 1)

In [23]: latex(test)
Out[23]: '\\frac{- \\RZY - 1}{\\RYZ \\RZY - 1}'

In [24]: print(MyLatexPrinter().doprint(test))
\frac{-1 - \RZY}{\RYZ \RZY - 1}

In my opinion, a manipulated output function won't solve this problem.

I also need the manipulated term for further calculation, so I don't see a need for a pure output function.

Unfortunately I don't have the skills to write such a function. I even don't  understand your example.

Alex

Alexander Tille

unread,
Nov 16, 2016, 5:56:59 AM11/16/16
to sympy
Hi Björn,
Here is the complete example with the shifted *-1 from the numerator to the denominator.

In the second part of the example your code works quite well again. But I don't know how to shift the -1* automatically when there is a need for.

In [21]: test = -(Rzy + 1)/(Ryz*Rzy - 1)


In [22]: test
Out[22]: (-\RZY - 1)/(\RYZ*\RZY - 1)

In [23]: latex(test)
Out[23]: '\\frac{- \\RZY - 1}{\\RYZ \\RZY - 1}'

In [24]: print(MyLatexPrinter().doprint(test))
\frac{-1 - \RZY}{\RYZ \RZY - 1}

In [25]: test = (Rzy + 1)/(-1*(Ryz*Rzy - 1))

In [26]: test
Out[26]: (\RZY + 1)/(-\RYZ*\RZY + 1)

In [27]: latex(test)
Out[27]: '\\frac{\\RZY + 1}{- \\RYZ \\RZY + 1}'

In [28]: print(MyLatexPrinter().doprint(test))
\frac{1 + \RZY}{1 - \RYZ \RZY}



Reply all
Reply to author
Forward
0 new messages