求任意多项式函数在 x 处的正切
Find the tangent of any polynomial function at x
问题:
我正在寻找可用于计算 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])
并得到一个像这样的 return 值,[-2, -1]
代表切线,y = -2 - x .
备注:
我在 Math Stackexchange 和 Google 搜索中寻找答案,但所有结果都是数学语法而不是代码。我想要一个程序化的解决方案,与有趣的符号和数学术语相比,我更喜欢循环和 if 语句!
好吧,经过一天的努力,我想我已经在 JavaScript 和 Python!
中找到了解决方案
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]
}
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 测试了结果,它们似乎没问题,但是 如果您发现任何错误,请告诉我! 另外,我很乐意查看其他语言的结果,所以如果您有此处未提及的首选语言,请不要犹豫 post!
使用 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)
既然你问过其他语言,这里有一个 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 值、多项式的次数和系数以及 returns 多项式在 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
之前执行此操作
自动接受的答案很好,这是我的看法;
为了提高效率,可以将以下代码放在单个 .reduce()
语句下,但我想将其保留在扩展形式中以帮助说明;
function tangent(x,as){
var y = as.reduce((p,c,i) => p+c*x**i), // find the y value at x
m = as.map((a,i) => a*i) // find the derivative
.reduce((p,c,i) => p+c*x**(i-1)); // find the slope m at x
return [y-m*x,m]; // find the line from y & m
}
var line = tangent(-2, [2, 7, 5, 1]);
console.log(`The equation of the tangent line is "y = ${line[1]}x${(Math.sign(line[0])+"")[0]}${Math.abs(line[0])}"`);
问题:
我正在寻找可用于计算 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])
并得到一个像这样的 return 值,[-2, -1]
代表切线,y = -2 - x .
备注:
我在 Math Stackexchange 和 Google 搜索中寻找答案,但所有结果都是数学语法而不是代码。我想要一个程序化的解决方案,与有趣的符号和数学术语相比,我更喜欢循环和 if 语句!
好吧,经过一天的努力,我想我已经在 JavaScript 和 Python!
中找到了解决方案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]
}
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 测试了结果,它们似乎没问题,但是 如果您发现任何错误,请告诉我! 另外,我很乐意查看其他语言的结果,所以如果您有此处未提及的首选语言,请不要犹豫 post!
使用 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)
既然你问过其他语言,这里有一个 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 值、多项式的次数和系数以及 returns 多项式在 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
之前执行此操作自动接受的答案很好,这是我的看法;
为了提高效率,可以将以下代码放在单个 .reduce()
语句下,但我想将其保留在扩展形式中以帮助说明;
function tangent(x,as){
var y = as.reduce((p,c,i) => p+c*x**i), // find the y value at x
m = as.map((a,i) => a*i) // find the derivative
.reduce((p,c,i) => p+c*x**(i-1)); // find the slope m at x
return [y-m*x,m]; // find the line from y & m
}
var line = tangent(-2, [2, 7, 5, 1]);
console.log(`The equation of the tangent line is "y = ${line[1]}x${(Math.sign(line[0])+"")[0]}${Math.abs(line[0])}"`);