#!/usr/bin/env python

import numpy as np

def poly_eval(x, a):
    return sum([an*x**n for n,an in enumerate(a)])

def sqrt_1px(x):
    a = [1.0, 
         0.49959804148061, 
         -0.12047308243453, 
         0.04585425015501, 
         -0.01076564682800 ]
    return poly_eval(x, a)

def log2_1px(x):
    a = [0.0,
         1.44254494359510,
         -0.7181452567504,
         0.45754919692582,
         -0.27790534462866,
         0.121797910687826,
         -0.02584144982967 ]
    return poly_eval(x, a)

def pow2x(x):
    a = [ 1.0,
        0.69303212081966 ,
        0.24137976293709,
        0.05203236900844,
        0.01355574723481 ]
    return poly_eval(x,a)
    
def sin_pi2x(x):
    a = [ 0.0,
         1.57079632679490,
         0.0,
         -0.64596406188166,
         0.0,
         0.07969158490912,
         0.0,
         -0.00467687997706,
         0.0,
         0.00015303015470 ]
    return poly_eval(x, a)
    
def cos_pix(x):
    return 1 - 2*sin_pi2x(x)**2
    
if __name__ == '__main__':
    xp = np.linspace(0, 1, 1001)
    xn = np.linspace(-1, 0, 1001)
    x  = np.linspace(-1, 1, 2001)
    
    # sqrt(1+x)
    mae = np.max(np.abs(sqrt_1px(xp)-np.sqrt(1+xp)))
    print "sqrt(1+x)\nMaximum Absolute Error: %e\n" % mae
    
    # log2(1+x)
    mae = np.max(np.abs(log2_1px(xp) - np.log2(1+xp)))
    print "log2(1+x)\nMaximum Absolute Error: %e\n" % mae
    
    # 2^x
    mae = np.max(np.abs(pow2x(xp) - 2**xp))
    print "2^x\nMaximum Absolute Error: %e\n" % mae
    
    # sin(pi/2*x)
    mae = np.max(np.abs(sin_pi2x(x) - np.sin(np.pi/2*x)))
    print "sin(pi/2*x)\nMaximum Absolute Error: %e\n" % mae    
    
    # cos(pi*x)
    mae = np.max(np.abs(cos_pix(x) - np.cos(np.pi*x)))
    print "cos(pi*x)\nMaximum Absolute Error: %e\n" % mae
