SymPy uses mpmath under the hood to get arbitrary precision. With
SymPy, you should either create a symbolic expression and evaluate it
with evalf and a precision, or start with something like
Float("1.4142", 100) (for 100 digits of precision) and manipulate it.

I'm actually seeing a lot of issues around this.

It seems there is a SymPy issue with creating this expression
symbolically https://github.com/sympy/sympy/issues/10963.

I should also point out that if you are taking a large power and the a
modulus, it's better to use pow(x, a, b) instead of x**a % b, since
the former is computed more efficiently using modular arithmetic.

With NumPy, I get wildly different answers, both of which are likely
wrong due to precision issues:

In [19]: (np.longdouble(1.4142)** 6000 )%400
Out[19]: 32.0

In [20]: pow(np.longdouble(1.4142), 6000, 400)
Out[20]: 1.1614417884357119756e+903

With SymPy's Float, pow() doesn't work
(https://github.com/sympy/sympy/issues/5715), but I get

In [21]: x = Float("1.4142", 100)

In [22]: x**6000 % 400
Out[22]: 
272.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

mpmath unsurprisingly gives the same thing (by the way, sympy.mpmath
no longer works with SymPy 1.0, just use "import mpmath").

In [28]: x = mpmath.mpf("1.4142")

In [29]: x**6000 % 400
Out[29]: mpf('272.0')

(also it seems pow() doesn't work with mpf)

But, you can also use SymPy to convert 1.4142 to a rational number:

In [30]: nsimplify("1.4142")
Out[30]:
7071
────
5000

In [31]: 7071/5000
Out[31]: 1.4142

In [32]: x = nsimplify("1.4142")

In [33]: a = x**6000 % 400

In [34]: a.evalf()
Out[34]: 271.048181008631

I didn't print the value of a because it's a very large rational
number. Unless there's a bug somewhere in the rational number
calculations, or in the conversion of large rational numbers to
floats, I would wager this is the correct answer (at any rate, a would
have evaluated to 272 exactly if the answer were an exact integer).

Aaron Meurer

On Mon, Apr 4, 2016 at 8:56 PM, Amy Valhausen <[email protected]> wrote:
> Sympy vs Numpy, better accuracy in precision?
>
> I've been trying to solve a problem with numpy and other code routines
> to raise a base to a large power and then take the modulus.
>
> Precision accuracy is very important, speed isnt as much - although it would
> be convenient if I didnt have to wait a long long time for processing.
>
> Constraints Im under is that Im working on a winxp system, Im using
> python 3.4 and numpy version 1.1.
>
> When using numpy Ive been using the code lines;
>
> import numpy
> (np.longdouble(1.4142)** 6000 )%400
>
> I am not sure how accurate the result is, and I have tried using other
> methods too
> but recently I found a post comparing sympy to numpy and it seems someone
> is claiming that sympy can return superior precision results, can anyone
> confirm
> that this is true and do you know if this would be a good solution to run on
> my system?
>
> Link with info comparing the below is shown ;
>
> http://stackoverflow.com/questions/25181642/how-set-numpy-floating-point-accuracy
>
> In normal numpy use, the numbers are double. Which means that the accuracy
> will be less than 16 digits. Here is a solved subject that contains the same
> problematic ...
>
> If you need to increase the accuracy, you can use symbolic computation ....
> The library mpmath ... is a quiet good one. The advantage is that you can
> use limitless precision. However, calculations are slower than what numpy
> can do.
>
> Here is an example:
>
> # The library mpmath is a good solution
>>>> import sympy as smp
>>>> mp = smp.mpmath
>
>>>> mp.mp.dps = 50  # Computation precision is 50 digits
> # Notice that the difference between x and y is in the digit before last
> (47th)
>>>> x = smp.mpmath.mpf("0.910221324013388510820732335560023784637451171875")
>>>> y = smp.mpmath.mpf("0.910221324013388510820732335560023784637451171865")
>>>> x - y  # Must be equal to 1e-47 as the difference is on the 47th digit
> mpf('1.000014916280995001003481719184726944958705912691304e-47')
>
> You can't do better with numpy. You can calculate exponentials with a better
> accuracy.
>
> smp.exp(x).evalf(20) = 2.4848724344693696167
>
> http://stackoverflow.com/questions/25181642/how-set-numpy-floating-point-accuracy
>
> https://github.com/sympy/sympy/releases
> http://docs.sympy.org/latest/index.html
>
> --
> 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 [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/e54f1042-193a-44db-88ec-8a4e13a8e44b%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/CAKgW%3D6KoboHGvkGpXDHdt%3DMuO2_0e_skhZMTvWfJ3dX9gH4L3g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to