【问题标题】:Find the tangent of any polynomial function at x求任何多项式函数在 x 处的正切
【发布时间】:2021-01-30 00:21:53
【问题描述】:

问题:

我正在寻找一个包罗万象的函数,我可以用它来计算 any 多项式函数在 x 处的正切。尽管更喜欢 JavaScript 或 Python,但我对使用的语言不感兴趣!我应该能够以 a + bx + cx^2 + dx^3 ...等格式传入任何 x 值和系数数组。

示例函数格式:

function findTangent(x, coefficients) {

  // Do differential calculus here.

  return [tangentIntercept, tangentSlope]

}

示例功能测试:

假设我有函数 y = 2 + 7x + 5x^2 + x^3 我想找到切线 x = -2 .我可以像这样调用这个函数,findTangent(-2, [2, 7, 5, 1]) 并得到这样的返回值,[-2, -1] 代表切线,y = -2 - x

注意事项:

我在 Math Stackexchange 和 Google 搜索中寻找答案,但所有结果都是数学语法而非代码。我想要一个程序化的解决方案,我更喜欢循环和 if 语句,而不是有趣的符号和数学术语!

【问题讨论】:

    标签: javascript python math polynomial-math calculus


    【解决方案1】:

    好的,经过一天的努力,我想我已经在 J​​avaScript Python 中找到了解决方案!

    The JavaScript Solution:

    function findTangent(x, coefficients) {
    
      let slope = 0
      let intercept = coefficients[0]
    
      for (let i = 1; i < coefficients.length; i++) {
    
        slope += coefficients[i] * i * Math.pow(x, i - 1)
        intercept += coefficients[i] * Math.pow(x, i)
    
      }
    
      return [intercept - slope * x, slope]
    
    }
    

    The Python Solution:

    def find_tangent(x, coefficients):
    
        slope = 0
        intercept = coefficients[0]
    
        for i, coefficient in enumerate(coefficients):
    
            if i != 0:
    
                slope += coefficient * i * pow(x, i - 1)
                intercept += coefficient * pow(x, i)
    
        return [intercept - slope * x, slope]
    

    我已经针对Symbolab Tangent Calculator 测试了结果,它们似乎还可以,但是如果您发现任何错误,请告诉我!另外,我希望看到其他语言的结果,所以如果如果您有此处未提及的首选语言,请不要犹豫发布!

    【讨论】:

    • “我更喜欢循环和 if 语句,而不是有趣的符号和数学术语!” - 哈哈。也许Array.prototype.reduce() 因为看起来更酷! :-) 看起来很棒 - 完全按照你的公式所说的那样做。
    • 感谢@RandyCasburn,我确实在某些时候拔过头发,但我认为这是我能想到的最优雅、最准确的解决方案。
    【解决方案2】:

    由于您询问了其他语言,这里有一个 C 函数,用于计算多项式在某个点的导数(和值)。我推荐的方法可以用于任何语言。

    double  pol_eval_d( double x, int deg, const double* c, double* pdp)
    {
    double  p = c[deg];
    double  dp = 0.0;
        for( int d=deg-1; d>=0; --d)
        {   dp = fma( dp, x, p);
            p = fma( p, x, c[d]);
        }
        *pdp = dp;
        return p;
    }
    

    此函数获取 x 值、多项式的次数和系数,并返回多项式在 x 处的值及其在 *pdp 中的导数。

    系数是 c[0](幂 0)、c[1](幂 1)、.. 和 c[deg](幂度)。

    它调用(C 数学库)函数 fma,为此

    fma(x,y,z) = x*y+z, except that it is evaluated with extra precision.
    

    如果你没有这样的函数,你可以用上面的表达式替换调用,虽然你会失去一点准确性。

    使用的方法是霍纳的方法。这通常比其他评估多项式的​​方法更快、更准确。

    为了解释它的工作原理,首先考虑我们不想要导数的情况。然后就可以写了

    double  pol_eval( double x, int deg, const double* c)
    {
    double  p = c[deg];
        for( int d=deg-1; d>=0; --d)
        {   p = fma( p, x, c[d]);
        }
        return p;
    }
    

    如果我们逐步了解二次方程的情况,并将 fma 调用替换为它们的数学等价物,我们会得到

    p = c[2]
    p = p*x + c[1]
    p = p*x + c[0]
    

    那是我们已经评估了

    c[0]+x*c[1]+x*x*c[2] 
    

    通过

    c[0] + x*(c[1] + x*c[2])
    

    这是霍纳的方法。

    为了计算导数,我们区分 pol_eval 中的每个项。最初p是一个常数,所以它的导数是0。然后当我们更新p时

    p = fma( p, x, c[d]);
    

    或用数学术语表示

    p = p*x + c[d];
    

    我们使用乘积规则来区分它,所以因为 c[d] 是一个常数

    dp = dp*x + p
    

    请注意,我们必须在更新之前执行此操作 p

    【讨论】:

    • 太棒了,非常感谢!我个人从未写过任何 C 语言,但这看起来不错!
    【解决方案3】:

    使用允许符号微分的 Python Sympy

    代码

    from sympy import Function, Symbol
    
    def polynomial(coeficents, degrees, x):
        '''
            Evaluate polynomial
            
            Example
                coefficients = [1, 2, 4]
                degrees = [2, 1, 0]
                
                corresponds to polynomial x^2 + 2*x + 4
        '''
        return sum([coeficents[i]*x**degrees[i] for i in range(len(coeficents))])
             
    # Using OP polynomial
    coefficients = [1, 5, 7, 2]
    degrees = [3, 2, 1, 0]
    print(polynomial(coefficients, degrees, -2))  # Output: 15
    
    # Create symbolic polynomial in x
    # Define symbolic variable x
    x = Symbol('x')  # symbolic variable x
    
    # Create polynomial in x for OP polynomial
    poly = polynomial(coefficients, degrees, x)
    print(poly)                                  # Output: x**3 + 5*x**2 + 7*x + 2
    # Evaluate at x = -2
    print(poly.subs(x, -2))                      # Output: 7  (i.e. substitute x for 1 in equation)
    
    ####################################################
    # Symbolic differentiation of polynomial 'poly'
    ####################################################
    diff_poly = poly.diff(x)
    print(diff_poly)                             # Output: 3*x**2 + 10*x + 7 (derivative of polynomial)
    # Evaluate derivative at x = -2
    print(diff_poly.subs(x, -2))                 # Output: -1   (derivate at x = -1)
    

    【讨论】:

    • 好吧,我还没用过sympy!谢谢!
    猜你喜欢
    • 2018-08-21
    • 1970-01-01
    • 2018-05-26
    • 2017-01-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2022-07-27
    • 2014-02-17
    相关资源
    最近更新 更多