6

This is not directly a math question but rather a question on computing error.

I am looking for ways to perform calculation involving 100s of decimal places (especially for, but not limited to, this problem statement)

One well known library for high precision calculation in Python is mpmath which is used for floating-point arithmetic with arbitrary precision. So to test its accuracy I calculated the value of $\zeta(2)$ to 200 decimal places using mpmath and compared the result with that from wolframalpha.com as shown in the code below. They agreed only to 16 decimal places. Comparing against the known value of $\pi$ to 200 decimal places, I found that wolframalpha.com was accurate to 200 decimal places whereas mpmath stops being accurate after the 16th decimal place. So clearly the arbitrary precision of mpmath is not at reliable. So mpmath is not as accurate as it is said to be.

Question: How do we calculate decimals to 100s decimal places accurately in pure Python (not SageMath?

Python Code:

%%time 
import mpmath

mp.dps = 200; mp.pretty = True

Value from mpmath

z1 = zeta(2)

Value from wolframalpha.com

z2 = 1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896233719067962872468700500778793510294633086627683173330936776260509525100687214005479681155879489036082327776191984075645587696323563670971009694890

Error

z1 - z2

  • 4
    I suspect this is programming rather than mathematics. In particular I would be suspicious of your line saying z1 = zeta(2) possibly forcing to a double. What do you get with just zeta(2)? https://mpmath.org/doc/current/functions/zeta.html suggests it would start 1.6449340668482264364724151666460251892189499012067 like your Wolfram Alpha value – Henry Mar 27 '23 at 08:59
  • 1
    You say you want to use 100s of decimal places, but you are talking about using a floating-point library. Regardless of the number of floating-point places you have, you cannot create a floating-point value that is exactly equal to 0.1, for example. Have you looked into decimal? "the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for a given problem" – JimmyJames supports Canada Mar 27 '23 at 17:41
  • 1
    @JimmyJames How is base 10 any better for the OP than base 2? Regardless of the number of decimal places you have, you cannot create a decimal value that is exactly equal to 1/7, for example. – Rosie F Mar 27 '23 at 17:51
  • 1
    @RosieF All binary fractions can be represented as decimal fractions but not all decimal values can be represented in binary. 1/7 can't be represented in either so it's not really relevant here. – JimmyJames supports Canada Mar 27 '23 at 18:04
  • 1
    Sorry, I wasn't familiar with this library and mp.dps = 200 sets the decimal precision to 200 places. The problem is how z2 defined. See Matthew Tower's answer. – JimmyJames supports Canada Mar 27 '23 at 18:59
  • @Henry That kind of conversion is common in other languages but in python variables don't have a type, only values have types. – JimmyJames supports Canada Mar 27 '23 at 19:55

2 Answers2

13

Your z2 looks very precise, but it's actually just a Python float and so is truncated after around 16 dps. You need to do

z2 = mpf('1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896233719067962872468700500778793510294633086627683173330936776260509525100687214005479681155879489036082327776191984075645587696323563670971009694890')

to create an mpf object you can compare to zeta(2). (Also, like Sage, mpmath isn't "pure Python", in the sense that it is not part of the standard library).

4

Verifying a few of the responses you got:

from mpmath import mp

mp.dps = 200 mp.pretty = True

Value from mpmath

z1 = mp.zeta(2) print(f"z1 has type {type(z1)}") print(f"zeta(2) from mpmath {z1}")

Value from wolframalpha.com

z2 = 1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896233719067962872468700500778793510294633086627683173330936776260509525100687214005479681155879489036082327776191984075645587696323563670971009694890 print(f"z2 has type {type(z2)}") print(f"z2 from copy-paste {z2}")

Output is:

z1 has type <class 'mpmath.ctx_mp_python.mpf'>
zeta(2) from mpmath 1.6449340668482264364724151666460251892189499012067984377355582293700074704032008738336289006197587053040043189623371906796287246870050077879351029463308662768317333093677626050952510068721400547968116
z2 has type <class 'float'>
z2 from copy-paste 1.6449340668482264
  • 2
    @NilotpalSinha -Note that the actual value for zeta(2) reported still does not match the known value to 200 decimal places. The reason for this is most likely because you only allot 200 decimal places for the calculation. This means that not just the result, but every step of the calculation will be off by some amount $\sim 10^{-200}$. These errors propagate as the calculation goes on, resulting in increasing overall error as it continues. Just how bad it gets depends on exactly how the calculation is performed. You need more than 200 digits to calculate accurately to 200 digits. – Paul Sinclair Mar 27 '23 at 18:44
  • 2
    @PaulSinclair According to the docs "When the precision has been set, all mpf operations are carried out at that precision" which I take to mean it will maintain the precision that is set. The error is actually in the assignment of z2. That's a python float with limited precision. – JimmyJames supports Canada Mar 27 '23 at 19:04
  • 1
    @JimmyJames - please note that A rural reader has posted the actual output of zeta(2) when you do not convert it to a float. The official value from Wolfram Alpha gives several more digits than the zeta(2) output. They agree to the last digit of "6" of zeta(2) here, but the Wolfram Alpha value has "5" instead, then goes on with "5879489036082327776191984075645587696323563670971009694890" – Paul Sinclair Mar 27 '23 at 19:23
  • 2
    Though, after checking the string length, zeta(2) is shown to 200 places (including the leading 1). So apparently they have calculated it to 200 decimal places accurately. – Paul Sinclair Mar 27 '23 at 19:32
  • 2
    @PaulSinclair Right. If you line them up, they agree until the 199th decimal place so mpmath appears to be working as the OP intended. – JimmyJames supports Canada Mar 27 '23 at 19:52