求任何多项式函数在 x 处的切线

问题描述

问题:

我正在寻找一个包罗万象的函数,我可以用它来计算 任何 多项式函数在 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 语句,而不是有趣的符号和数学术语!

解决方法

好的,经过一天的努力,我想我已经在 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 测试了结果,它们似乎没问题,但是如果您发现任何错误,请告诉我!此外,我希望看到其他语言的结果因此,如果您有此处未提及的首选语言,请随时发布!

,

由于您询问了其他语言,这里是一个 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,c[d]);
    }
    *pdp = dp;
    return p;
}

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

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

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

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

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

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

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

double  pol_eval( double x,const double* c)
{
double  p = c[deg];
    for( int d=deg-1; d>=0; --d)
    {   p = fma( p,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,c[d]);

或者用数学术语

p = p*x + c[d];

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

dp = dp*x + p

并注意我们必须在更新 p 之前这样做

,

使用允许符号微分的 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,0]
print(polynomial(coefficients,-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,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)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...