Problems with numerical evaluation in sympy after init_session()

33 views
Skip to first unread message

Marek Kaluba

unread,
Oct 20, 2014, 1:18:40 PM10/20/14
to sy...@googlegroups.com
Hi all,

recently I started using sympy (and immediately fall for it), so this mail may be simply my lack of understanding how sympy internally works.
However I found a _strange_ (to me) issue with numerical evaluation:

(ipython console)
from sympy import *
N(1/3)
0 //integer division, ok
N(Rational(1)/Rational(3),20)
0.33333333333333333333 //numerical approximation of 1/3, ok

init_session() //for nice latex printing and default variables -- I guess this is what init_session() does??
[...] //standard output

pprint(N(1/3))
0.333333333333333 // why not 0?

pprint(N(1/3,100))
0.3333333333333333148296162562473909929394721984863281250000000000000000000000
000000000000000000000000
// what is happening here??

I'd be grateful if anyone can explain this to me...

Cheers,
Mark

Mateusz Paprocki

unread,
Oct 20, 2014, 1:30:13 PM10/20/14
to sympy
Hi,

On 20 October 2014 19:18, Marek Kaluba <abu...@gmail.com> wrote:
> Hi all,
>
> recently I started using sympy (and immediately fall for it), so this mail
> may be simply my lack of understanding how sympy internally works.
> However I found a _strange_ (to me) issue with numerical evaluation:
>
> (ipython console)
> from sympy import *
> N(1/3)
> 0 //integer division, ok
> N(Rational(1)/Rational(3),20)
> 0.33333333333333333333 //numerical approximation of 1/3, ok
>
> init_session() //for nice latex printing and default variables -- I guess
> this is what init_session() does??
> [...] //standard output
>
> pprint(N(1/3))
> 0.333333333333333 // why not 0?

This is because init_session() issues `from __future__ import
division`, so now 1/3 is equivalent to float(1)/3.

> pprint(N(1/3,100))
> 0.3333333333333333148296162562473909929394721984863281250000000000000000000000
> 000000000000000000000000
> // what is happening here??

As 1/3 is a float in this case, thus SymPy can't compute it's
numerical value to the expected precision. You can use
init_session(auto_int_to_Integer=True) get the desired behavior, where
1/3 is understood as Integer(1)/3. In general, handling rationals in
SymPy can be tricky, so if unsure, use type(1/3) to get feedback what
you are dealing with.

Mateusz

> I'd be grateful if anyone can explain this to me...
>
> Cheers,
> Mark
>
> --
> 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 post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/c3a412a0-7e30-4b34-8f9d-b521991bd40e%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Marek Kaluba

unread,
Oct 20, 2014, 2:11:38 PM10/20/14
to sy...@googlegroups.com
Well I tried auto_int_to_Integer=True, with no effect:

from sympy import init_session

init_session(auto_int_to_Integer=True)
IPython console for SymPy 0.7.4.1 (Python 2.7.7-64-bit) (ground types: gmpy)

These commands were executed:
>>> from __future__ import division
>>> from sympy import *
>>> x, y, z, t = symbols('x y z t')
>>> k, m, n = symbols('k m n', integer=True)
>>> f, g, h = symbols('f g h', cls=Function)

Documentation can be found at http://www.sympy.org
WARNING: Hook shutdown_hook is deprecated. Use the atexit module instead.

type(1/3)
Out[3]: float

pprint(1/3)
0.333333333333

Aaron Meurer

unread,
Oct 20, 2014, 4:56:26 PM10/20/14
to sy...@googlegroups.com
On Mon, Oct 20, 2014 at 1:11 PM, Marek Kaluba <abu...@gmail.com> wrote:
> Well I tried auto_int_to_Integer=True, with no effect:

This is a known issue https://github.com/sympy/sympy/issues/2839.

I recommend just using S(1)/3. This will work even if you write a
Python script with your code (int_to_Integer is only for interactive
use). If you do want the interactive use, you'll need to use isympy -i
for now.

And by the way, if you want integer division, I recommend always using
//, like 1//3. This will work even in Python 3 or Python 2 with from
__future__ import division.

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 post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/203eb3ef-b8dd-49f8-8a94-4d1b3418d23d%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages