Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Calculate sine/cosine with a precision of up to 1 million digits

Question is pretty self-explanatory. I've seen a couple of examples for pi but not for trigo functions. Maybe one could use a Taylor series as done here but I'm not entirely sure how to implement that in python. Especially how to store so many digits. I should mention: this ideally would run on vanilla python i.e. no numpy etc.

Thanks!

Edit: as said, I know the question has been asked before but it's in java and I was looking for a python implementation :)

Edit 2: wow I wasn't aware people here can be so self-absorbed. I did try several approaches but none would work. I thought this a place you can ask for advice, guess I was wrong

last edit: For anyone who might find this useful: many angles can be calculated as a multiple of sqrt(2), sqrt(3) and Phi (1.61803..) Since those numbers are widely available with a precision up to 10mio digits, it's useful to have them in a file and read them in your program directly

like image 824
S. L. Avatar asked Jul 18 '17 14:07

S. L.


3 Answers

mpmath is the way:

from mpmath import mp
precision = 1000000
mp.dps = precision
mp.cos(0.1)

If unable to install mpmath or any other module you could try polynomial approximation as suggested.

enter image description here

where Rn is the Lagrange Remainder

enter image description here

Note that Rn grows fast as soon as x moves away from the center x0, so be careful using Maclaurin series (Taylor series centered in 0) when trying to calculate sin(x) or cos(x) of arbitrary x.

Bad idea: infinity does not exist in computers

Bad idea: infinity does not exist in computers

like image 151
Marco Avatar answered Oct 18 '22 20:10

Marco


Try this

import math
from decimal import *


def sin_taylor(x, decimals):
    p = 0
    getcontext().prec = decimals
    for n in range(decimals):
        p += Decimal(((-1)**n)*(x**(2*n+1)))/(Decimal(math.factorial(2*n+1)))
    return p


def cos_taylor(x, decimals):
    p = 0
    getcontext().prec = decimals
    for n in range(decimals):
        p += Decimal(((-1)**n)*(x**(2*n)))/(Decimal(math.factorial(2*n)))
    return p

if __name__ == "__main__":
    ang = 0.1
    decimals = 1000000
    print 'sin:', sin_taylor(ang, decimals)
    print 'cos:', cos_taylor(ang, decimals)
like image 3
efirvida Avatar answered Oct 18 '22 22:10

efirvida


import math
x = .5
def sin(x):
    sum = 0
    for a in range(0,50): #this number (50) to be changed for more accurate results
        sum+=(math.pow(-1,a))/(math.factorial(2*a+1))*(math.pow(x,2*a+1))
    return sum

ans = sin(x)
print(str.format('{0:.15f}', ans)) #change the 15 for more decimal places

Here is an example of implementing the Taylor series using python as you suggested above. Changing to cos wouldn't be too hard after that.

EDIT:

Added in the formatting of the last line in order to actual print out more decimal places.

like image 1
Ryan Avatar answered Oct 18 '22 22:10

Ryan