使用 Machine Epsilon 通过泰勒级数逼近 sin(x)

Using Machine Epsilon to approximate sin(x) using Taylor's Series

提问人:Colton Hancock 提问时间:2/2/2022 最后编辑:Colton Hancock 更新时间:2/2/2022 访问量:322

问:

我很难使用机器 Epsilon,它是 2.220446049250313e-16,然后我需要使用 abs 错误来确定我的正弦项的 abs 值是否小于机器 Epsilon。

使用泰勒级数编写一个正弦函数来计算 sin(x) 的值,其中是弧度中的角度。角度必须介于 -(pi/2) 和 pi/2 之间。使用机器 Epsilon 确定计算正弦值所需的项数。

我需要输出角度、正弦计算、绝对误差和使用的项数。这是我已经拥有的:

def machineEpsilon(e):
    e = 1.0
    while(1.0 + e/2.0) > 1.0:
        e = e/2.0
    return e

def sine(x, n):
    sign = 1
    sine  = 0.0
    half_pi = math.pi/2
    #converts anything greater than pi/2 to something in between -pi/2 and pi/2
    while x > half_pi:
        x -= half_pi
    #converts anything less than -pi/2 to something in between -pi/2 and pi/2
    while x < -(half_pi):
        x += half_pi

    if x > math.pi:
        x -= math.pi
        sign = -1

    swap_sign = 1
    #loops through taylor series for sine

    for i in range(1, n * 2, 2):
        sine += swap_sign * (x ** i) / math.factorial(i)
        swap_sign *= -1

    return sign * sine

def main():
    numTerms = 0
    pie = math.pi
    angle1 = round(sine(-20, 50), 9)
    abbsErr1 = (abs(angle1 - math.sin(-20)))
    angle2 = round(sine((-pie), 10), 9)
    abbsErr2 = abs(angle2 - math.sin(-pie))
    angle3 = round(sine((-pie/2), 10), 9)
    abbsErr3 = abs(angle3 - math.sin((-pie/2)))
    angle4 = round(sine(-0.5, 10), 9)
    abbsErr4 = abs(angle4 - math.sin(-0.05))
    angle5 = round(sine(0.0000, 10), 9)
    abbsErr5 = abs(angle5 - math.sin(0))
    angle6 = round(sine(0.05, 10), 9)
    abbsErr6 = abs(angle6 - math.sin(0.0500))
    angle7 = round(sine(100, 5), 9)
    abbsErr7 = abs(angle7 - math.sin(100))
    print("\n")
    print("Name: Name")
    print("Machine epsilon = ", machineEpsilon(1))
    print("{:<12} {:<15} {:<25} {:<3}".format('Angle(rad)', '(my sine)', 'AbsErr',
                                              '# of Terms'))
    print("{:<12} {:<15} {:<25} {:<3}".format('-20.0000', angle1, abbsErr1, numTerms))
    #print(math.sin(-20))
    print("{:<12} {:<15} {:<25} {:<3}".format('-3.1416', angle2, abbsErr2, numTerms))
    #print(math.sin(-(pie)))
    print("{:<12} {:<15} {:<25} {:<3}".format('-1.5708', angle3, abbsErr3, numTerms))
    #print(math.sin(-(pie/2)))
    print("{:<12} {:<15} {:<25} {:<3}".format('-0.5000', angle4, abbsErr4, numTerms))
    #print(math.sin(-0.5))
    print("{:<12} {:<15} {:<25} {:<3}".format('0.0000', angle5, abbsErr5, numTerms))
    #print(math.sin(0))
    print("{:<12} {:<15} {:<25} {:<3}".format('0.0500', angle6, abbsErr6, numTerms))
    #print(math.sin(0.0500))
    print("{:<12} {:<15} {:<25} {:<3}".format('100.0000', angle7, abbsErr7, numTerms))
    #print(math.sin(100))
    print("\n")
Python 三角函数 epsilon

评论

1赞 martineau 2/2/2022
只是说你“很难循环”并不是一个问题陈述。请更新您的问题并更加具体。您还应该解释“机器 Epsilon”的含义。
0赞 Colton Hancock 2/2/2022
好的,我需要使用我上面计算为 2.220446049250313e-16 的机器 epsilon。我需要计算泰勒级数,直到我的新项的 abs 值减去机器 epsilon 并计算我循环了多少次 for 循环
0赞 martineau 2/2/2022
我认为您不需要计算机器 epsilon — 请参阅 sys.float.epsilon

答:

0赞 vorrade - 2/2/2022 #1

你的正弦函数似乎不太对 - 它还应该返回所需的迭代次数。我已经获取了您的代码并对其进行了修改,以便在序列的当前值与前一个值相同时停止计算。(我还冒昧地将要计算的值放入数组中并遍历它们)。

import math

def machineEpsilon(e):
    e = 1.0
    while(1.0 + e/2.0) > 1.0:
        e = e/2.0
    return e


def sine(x):
    sign = 1
    half_pi = math.pi/2

    #converts everything into range 0..2*pi
    while x >= 2*math.pi:
        x -= 2*math.pi
    while x < 0.0:
        x += 2*math.pi

    if x > math.pi:
        x -= math.pi
        sign = -1

    swap_sign = 1
    #loops through taylor series for sine

    i = 1
    sine  = 0.0
    oldsine = 1
    iterations = 0

    while sine!=oldsine:
        oldsine = sine
        sine += swap_sign * (x ** i) / math.factorial(i)
        swap_sign *= -1
        i += 2
        iterations += 1

    return (sign * sine, iterations) # value, number of iterations

def main():
    print("\n")
    print("Name: Name")
    print("Machine epsilon = ", machineEpsilon(1))
    print("{:<12} {:<22} {:<27} {:<3}".format('Angle(rad)', '(my sine)', 'AbsErr', '# of Terms')) 
    pie = math.pi
    values = [-20,-pie,-pie/2,-0.5,0.0,0.05,100]
    for v in values:
        s,numTerms = sine(v)
        abbsErr = abs(s - math.sin(v))
        print("{:<12} {:<22} {:<27} {:<3}".format(round(v,9), s, abbsErr, numTerms))
    print("\n")

if __name__=="__main__":
    main()