猿问

Python - 计算 arcsin 时不准确

我正在尝试在不使用任何外部库的情况下在 Python 中实现 arcsin。


这是我的代码:


from time import process_time as pt


class TrigoCalc(metaclass=__readonly):

    # This class evaluates various Trigonometric functions 

    # including Inverse Trigonometric functions

    def __setattr__(self, name, value):

        raise Exception("Value can't be changed")

    


    @staticmethod

    def asin(x):

        '''Implementation from Taylor series

        asin(x) => summation[(2k)! * x^(2k + 1) / (2^(2k) * (k!)^2 * (2k + 1))]

                  k = [0, inf)

        x should be real

        '''

        # a0 = 1                                                                           

        # a1 = 1/(2*3)                                                                     

        # a2 = 1/2 * 3/(4*5) 

        # a3 = 1/2 * 3/4 * 5/(6*7)

        # a4 = 1/2 * 3/4 * 5/6 * 7/(8*9)

        # a5 = 1/2 * 3/4 * 5/6 * 7/8 * 9/(10*11)

        # a6 = 1/2 * 3/4 * 5/6 * 7/8 * 9/10 * 11/(12*13)

        # a7 = 1/2 * 3/4 * 5/6 * 7/8 * 9/10 * 11/12 * 13/(14*15)

        # a8 = 1/2 * 3/4 * 5/6 * 7/8 * 9/10 * 11/12 * 13/14 * 15/(16*17)

        # a9 = 1/2 * 3/4 * 5/6 * 7/8 * 9/10 * 11/12 * 13/14 * 15/16 * 17/(18*19)

        # a10 = 1/2 * 3/4 * 5/6 * 7/8 * 9/10 * 11/12 * 13/14 * 15/16 * 17/18 * 19/(20*21)

        

        # taking 10 coefficients for arriving at a common sequence

        

        # N = n, D = n + 1; (N/D) --> Multiplication, number of times the coefficient number, n >= 1

        

        start_time = pt()


        coeff_list = []

        NUM_ITER = 10000

        for k in range(NUM_ITER):

            if k == 0:

                coeff_list.append(1)

            else:

                N = 1

                D = N + 1

                C = N/D

                if k >= 2:

                    for i in range(k-1):

                        N += 2; D += 2

                        C = C * N/D

                coeff_list.append(C)

        



吃鸡游戏
浏览 167回答 2
2回答

翻翻过去那场雪

的问题arcsin(1)是它arcsin(x)在 x=1 处垂直(导数无限增长)。像泰勒级数这样的多项式逼近跟不上。您的收敛速度非常慢,并且需要大量的项才能获得合适的近似值。你需要改变你处理问题的方式。例如,对于小的 x,y = sin(pi/2 - x)近似为1 - x^2/2,您可以从中推导出近似值asin(y) = pi/2 - sqrt(2 - 2*y)。此近似值适用于非常接近 1 的值 - 您可以直接使用它。如果你努力一点,你可以证明确切的身份asin(x) = pi/2 - 2*asin( sqrt( (1-x)/2 ) )使用此恒等式,您可以使用适用于接近 0 的asin(x)x 的现有函数来计算接近 1 的 x 。asin例如:要计算,asin(0.99)您将计算:asin(0.99) = pi/2 - 2*asin( sqrt( (1-.99)/2 ) )            = pi/2 - 2*asin( sqrt(.005) )            = pi/2 - 2*asin(0.07071067811865475)... 然后您将使用您现有的算法来获得 的高质量近似值asin(0.07071067811865475)。这是在生产质量数学库实现中使用的技术 - 例如参见OpenLibm或fdlibm。

慕村225694

一个非常基本的近似值将给出sum from 0 to N近似值(以弧度表示)。在这里,您以度为单位给出结果,因为度和弧度之间存在大致的比率,您需要将arcsin 设置为近似值。arcsin1e(-N)1e2NUM_ITER = 1e(N+2)1e(-N)因此,对于您的具体问题,您需要使用N = 1(大约 1 分)进行测试,因此NUM_ITER = 1e(1+2) = 1,000. 这一点都不精确,但可以让您了解您正在寻找的价值。然后,如果您想查找确切的值,我看不到每次都使用精确的数学方法(无论 x.point 精度如何)。但是,您可以使用二分法算法来查找NUM_ITER,如果它是您算法的目标。第一近似值将减少您的计算时间。精确的近似值来自比率 orx^O(n)和4^O(n),4^O(n)更大。我们可以用 来近似求和项O(1/10^n)。如果有人可以进行精确的微积分,我将非常高兴看到它。
随时随地看视频慕课网APP

相关分类

Python
我要回答