Problem with subs and Simpify

59 views
Skip to first unread message

Thomas Ligon

unread,
Feb 27, 2020, 10:44:53 AM2/27/20
to sympy

It looks to me like I haven’t fully understood how to use symbols.

I define b sub minus 1 and b sub minus 2 as

bm1, bm2 = symbols('b_{-1} b_{-2}')

Then I define expression 129 as

ex129 = 2*F1*b1*bm1 + F1 + G1*bm1**2 + G1*bm2 - b1

This reflects my expectation that I should use bm2 in the code, but the output via latex() will contain b_{-2}. However, when I look at ex129 in the debugger, it looks like this:

2*F_1*b_1*b_{-1} + F_1 + G_1*b_{-1}**2 + G_1*b_{-2} - b_1

This is presumably why my subs() statement fails:

ex129a = ex129.subs(bm2, ex132a)

I expect bm2 to be gone from ex129a, but it isn’t.

 

What is the correct way to do this?

 

The other problem is, even though

print(latex(ex129b))

works fine,

print(latex(Eq(b1, ex129b)))

produces the following error:

 

  Message=SympifyError: [-(F_1 + G_1*b_{-1}**2 + G_1*b_{-2})/(2*F_1*b_{-1} - 1)]

  Source=C:\data\Tom\Research\Hill\python\Ansatz3\solveTest1.py

  StackTrace:

  File "C:\data\Tom\Research\Hill\python\Ansatz3\solveTest1.py", line 48, in <module>

    print(latex(Eq(b1, ex129b)))

 

solveTest1.py
solveTest1.pdf

Kalevi Suominen

unread,
Feb 27, 2020, 11:40:44 AM2/27/20
to sympy
Hi,

It looks like solve returns a list containing the solution:

129 after solving for b1

[-(F_1 + G_1*b_{-1}**2 + G_1*b_{-2})/(2*F_1*b_{-1} - 1)]

SymPy's Eq expects something that can be converted to an expression. In this case, this should work:

Eq(b1, ex129b[0])

Kalevi Suominen

Thomas Ligon

unread,
Feb 27, 2020, 12:08:24 PM2/27/20
to sympy
Hi Kalevi,
thanks! That solves the Simpify problem. My test code now looks like this:
sol = solve(ex129a, b1)
ex129b
= sol[0]
print('129 after solving for b1')
print(ex129b)
print(latex(ex129b))
print(latex(Eq(b1, ex129b)))
Now I just need to solve the subs() problem

Thomas Ligon

unread,
Feb 28, 2020, 4:29:45 AM2/28/20
to sympy
The problem is solved. The subs() problem was also caused by overlooking the list returned by solve().
I admit that I was misguided by the fact that I previously worked a lot with the MATLAB symbolic math toolbox. In it, solve() for multiple variables returns a struct, and for a single variable does not return a struct with a single element, but the element itself. Because of that, I needed to write code that treated the single value as a special case. Now, I prefer the way that Sympy does it, because the code would be simpler, just a loop over a variable number of elements that might be one.
This means:
ex129a = ex129.subs(bm2, ex132a)
may have problems when given a list instead of an expression.

David Bailey

unread,
Feb 28, 2020, 5:15:17 AM2/28/20
to sy...@googlegroups.com

Dear Group,

I have been exploring some of the SymPy source files, and came across a parser. This puzzled me because I have always thought that SymPy didn't need its own parser because its syntax is consistent with Python, but then all the operators are overloaded as required.

I also discovered implicit multiplication in the code - so that xyz is parsed as x*y*z, but (presumably) sin is not parsed as s*i*n. Is this accessible somehow, or is it a relic of earlier ideas that have now been abandoned?

David

Aaron Meurer

unread,
Feb 28, 2020, 3:30:17 PM2/28/20
to sympy
SymPy indeed reuses Python's built in parser, but it has some
extensions to the tokenizer to allow things like implicit
multiplication (in sympy.parsing.sympy_parser). These things are not
abandoned. You can use them via the parse_expr() function. See
https://docs.sympy.org/latest/modules/parsing.html#sympy.parsing.sympy_parser.parse_expr

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/5a462c5c-3f9c-e4d2-c819-e5d9ef3899ef%40dbailey.co.uk.

Aaron Meurer

unread,
Feb 28, 2020, 4:12:40 PM2/28/20
to sympy
There are flags you can pass to solve() to make it always return a
consistent type. For instance, dict=True. This is recommended if you
are processing the solutions programmatically.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/e0d84f45-363e-45cc-86bf-261164d75eee%40googlegroups.com.

David Bailey

unread,
Feb 29, 2020, 11:34:04 AM2/29/20
to sy...@googlegroups.com
On 28/02/2020 20:29, Aaron Meurer wrote:
SymPy indeed reuses Python's built in parser, but it has some
extensions to the tokenizer to allow things like implicit
multiplication (in sympy.parsing.sympy_parser). These things are not
abandoned. You can use them via the parse_expr() function. See
https://docs.sympy.org/latest/modules/parsing.html#sympy.parsing.sympy_parser.parse_expr

Thanks Aaron - that is an interesting feature that I knew nothing about.

David

Reply all
Reply to author
Forward
0 new messages