Simplification Not Removing Multiplication by 1.0

63 views
Skip to first unread message

Rafael Turner

unread,
Jun 1, 2020, 1:12:11 AM6/1/20
to sympy
Hello,

I am trying to simplify the following expression:


E = '(-2*d11*d23*d32 + 4*d11 - 4*d12*d21 + 2*d12*d23*d31 + 1.0*d12*d31 + 2*d13*d21*d32 - 2*d13*d22*d31 - 2*d13*d31 + d22*d31 + d22*(4*d11 + 4) - 2*d23*d32 - d31*(d22 + 1) + d31 - 1.0*d32*(d11 + 1) + 2*d33*(d11*d22 + d11 - d12*d21 + d22 + 1) + 4)/(2.0*d11*(d22*d33 + d22 - d23*d32 + d33 + 1) - 2.0*d12*(d21*d33 + d21 - d23*d31) + 2.0*d13*d21*d32 - 2.0*d13*d31*(d22 + 1) + 2.0*d22*d33 + 2.0*d22 - 2.0*d23*d32 + 2.0*d33 + 2.0)' 

When I run

 ``` 
from sympy import * 
from sympy.parsing.sympy_parser import parse_expr 
 
str(simplify(parse_expr(E))) 
```

I get this result back: 

'0.5*(-2*d11*d23*d32 + 4*d11 - 4*d12*d21 + 2*d12*d23*d31 + 1.0*d12*d31 + 2*d13*d21*d32 - 2*d13*d22*d31 - 2*d13*d31 + d22*d31 + 4*d22*(d11 + 1) - 2*d23*d32 - d31*(d22 + 1) + d31 - 1.0*d32*(d11 + 1) + 2*d33*(d11*d22 + d11 - d12*d21 + d22 + 1) + 4)/(d11*(d22*d33 + d22 - d23*d32 + d33 + 1) - d12*(d21*d33 + d21 - d23*d31) + d13*d21*d32 - d13*d31*(d22 + 1) + d22*d33 + d22 - d23*d32 + d33 + 1)' 

Which didn't remove 1.0 and fully simplify the expression. Currently running Sympy version '1.5.1'.

I tried expanding and simplify again as well as multiply and dividing by 1. But these operations didn't work and I can't fully reduce the expression. Is there a way to simplify the equation further in 
Sympy? Am I doing something wrong? 

 Best wishes!

Garth Snyder

unread,
Jun 1, 2020, 5:36:47 AM6/1/20
to sympy
I believe 1.0 is a floating-point value that's distinct from 1 and presumed to be inexact. If you change the 1.0s and 2.0s to 1 and 2, they will be dropped or cancelled appropriately. It doesn't look like that will buy you much more simplification, unfortunately.

Oscar Benjamin

unread,
Jun 1, 2020, 8:10:42 AM6/1/20
to sympy
On Mon, 1 Jun 2020 at 10:36, Garth Snyder <ga...@garthsnyder.com> wrote:
>
> I believe 1.0 is a floating-point value that's distinct from 1 and presumed to be inexact. If you change the 1.0s and 2.0s to 1 and 2, they will be dropped or cancelled appropriately.

There is a function nsimplify which can do this for you.
https://docs.sympy.org/latest/modules/simplify/simplify.html#nsimplify

David Bailey

unread,
Jun 1, 2020, 7:16:00 PM6/1/20
to sy...@googlegroups.com

Dear Group,

It seems unfortunate that Python evaluates fractions such as 1/2 to 0.5, whereas SymPy recognises that in algebraic expressions fractions should rarely be evaluated to a decimal number. This means that if, for example, you input 3*x**2/2, you get a nice algebraic expression, but if you enter

 (3/2)*x**2

you get

1.5*x^2

This problem is particularly unfortunate if you cut and paste expressions a lot, as I tend to do.

I wonder if any thought has been given to this - I know you can always input Rational(3/2), but that seems very clumsy.

David


Aaron Meurer

unread,
Jun 1, 2020, 7:19:46 PM6/1/20
to sympy
There is some discussion about this behavior here and in linked issues
https://github.com/sympy/sympy/issues/16378 (possibly other places as
well, it's hard to search the issue tracker for this).

Even so, it does seem reasonable to me that simplify(1.0*x) should
return x, even if 1.0*x stays as it is without simplification.

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/CAHVvXxSLWndHrwOgZ-eGH%3DVq3b8-7Ug6gtUZpnuvpdG-o%3DexRA%40mail.gmail.com.

Aaron Meurer

unread,
Jun 1, 2020, 7:45:02 PM6/1/20
to sympy
If you are using the Jupyter notebook you can run

from sympy import init_session
init_session(auto_int_to_Integer=True)

This also works in IPython in the terminal, or you can use isympy -i.
This will automatically wrap integer literals with Integer() so that
1/2 produces Integer(1)/Integer(2). Just be aware that this could
break non-SymPy things if they don't work properly with Integer, for
example, numpy will create arrays with dtype=object when passed
Integer. You can wrap integers in int() to fix this, like
np.array([int(1)]).

If the issue is only for copy-pasting, I would just use sympify() to
convert the input as a string.

> I know you can always input Rational(3/2), but that seems very clumsy.

You should use Rational(3, 2) with the comma. Rational(3/2) will
convert 3/2 to a float first and then convert it to a rational. That
works fine for 3/2 because 3/2 is exactly representable as a floating
point number, but for others it isn't

>>> Rational(1/3)
6004799503160661/18014398509481984
>>> Rational(1, 3)
1/3

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/79efcea3-13ec-d997-5461-8be0536b6431%40dbailey.co.uk.

David Bailey

unread,
Jun 2, 2020, 10:21:36 AM6/2/20
to sy...@googlegroups.com
Thanks Aaron,

On 02/06/2020 00:44, Aaron Meurer wrote:
If you are using the Jupyter notebook you can run

from sympy import init_session
init_session(auto_int_to_Integer=True)

This also works in IPython in the terminal, or you can use isympy -i.
This will automatically wrap integer literals with Integer() so that
1/2 produces Integer(1)/Integer(2).  
Just be aware that this could
break non-SymPy things if they don't work properly with Integer, for
example, numpy will create arrays with dtype=object when passed
Integer. 



Couldn't that be made a lot more specific and therefore less risky? Looking for <integer>/<integer> and replacing it with what you describe - or indeed with Rational(<integer>,<integer>) would be a lot less likely to disturb Python code.


If the issue is only for copy-pasting, I would just use sympify() to
convert the input as a string.
Sorry, that was a typo - I mean to write Rational(3,2)!


David

Chris Smith

unread,
Jun 3, 2020, 11:30:39 PM6/3/20
to sympy
>  it does seem reasonable to me that simplify(1.0*x) 

Isn't this what `nsimplfy` (especially with rational=True) is for?


On Monday, June 1, 2020 at 6:19:46 PM UTC-5, Aaron Meurer wrote:
There is some discussion about this behavior here and in linked issues
https://github.com/sympy/sympy/issues/16378 (possibly other places as
well, it's hard to search the issue tracker for this).

Even so, it does seem reasonable to me that simplify(1.0*x) should
return x, even if 1.0*x stays as it is without simplification.

Aaron Meurer

On Mon, Jun 1, 2020 at 6:10 AM Oscar Benjamin
<oscar.j...@gmail.com> wrote:
>
> On Mon, 1 Jun 2020 at 10:36, Garth Snyder <ga...@garthsnyder.com> wrote:
> >
> > I believe 1.0 is a floating-point value that's distinct from 1 and presumed to be inexact. If you change the 1.0s and 2.0s to 1 and 2, they will be dropped or cancelled appropriately.
>
> There is a function nsimplify which can do this for you.
> https://docs.sympy.org/latest/modules/simplify/simplify.html#nsimplify
>
> --
> 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 sy...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages