Approximating Trig Functions (Python)

vegaseat 3 Tallied Votes 549 Views Share

Continued fraction expansion is a simple way to approximate common trigonometry functions to a relatively high precision. In this example we only look at sin and cosine. The results compare well with the results of high precision packages like SymPy. The Python module decimal is used to achieve the high precision.

TrustyTony commented: You catched the hint +13
sneekula commented: good use of modules +12
# approximate sin and cos using continued fraction expansion
# and module decimal to set higher precision
# convergence cutoff = 5 gives module math precision
# tested with Python27  by  vegaseat

import decimal as dc
# for comparison
import math
try:
    from sympy.mpmath import *
    # set precision
    mp.dps = 60
    print(type(sin(0.5)))
    print(sin(0.5))
    print(cos(0.5))
    print('-'*62)
except:
    print("Install module SymPy from http://code.google.com/p/sympy")

def cont_fraction(r, cutoff=5):
    """
    continued fraction expansion
    higher convergence cutoff gives higher precision
    but of course makes the approximation slower
    """
    t = dc.Decimal(4)*cutoff + 2
    for k in range(cutoff, 0, -1):
        t = 4*k - 2 + dc.Decimal(r)/t
    return t

def get_sin(x, cutoff=5):
    """returns an approximation of math.sin(x)"""
    r = dc.Decimal(-x)*dc.Decimal(x)
    s = cont_fraction(r, cutoff)
    return 2*dc.Decimal(x)*s/(s*s - r)

def get_cos(x, cutoff=5):
    """returns an approximation of math.cos(x)"""
    r = dc.Decimal(-x)*dc.Decimal(x)
    s = cont_fraction(r, cutoff)
    return (s*s + r)/(s*s - r)

# set decimal precision
dc.getcontext().prec = 60

# x is angle in radians
x = 0.5

print(type(get_sin(x)))
print(get_sin(x, 20))
print(math.sin(x))
# and some cosine approximations different cutoff values
print('-'*62)
print(get_cos(x, 15))
print(get_cos(x, 20))
print(get_cos(x, 25))
print(math.cos(x))

'''
<class 'sympy.mpmath.ctx_mp_python.mpf'>
0.479425538604203000273287935215571388081803367940600675188617
0.877582561890372716116281582603829651991645197109744052997611
--------------------------------------------------------------
<class 'decimal.Decimal'>
0.479425538604203000273287935215571388081803367940600675188618
0.479425538604
--------------------------------------------------------------
0.877582561890372716116281582603829651991645197109744053008284
0.877582561890372716116281582603829651991645197109744052997610
0.877582561890372716116281582603829651991645197109744052997610
0.87758256189
'''
TrustyTony 888 pyMod Team Colleague Featured Poster

Your code is OK, but still I am impressed with this mpmath module included in Sympy, which you use for comparison.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.