我编写了一个带衍生物的简单代码,但它没有采用三角函数的衍生。
from math import sin, radians
def sinus(x):
return sin(radians(x))
def derivative(func , x):
h = 0.0000000001
return (func(x+h)-func(x))/h
def f(x):
return 2*x**2+x
print(derivative(f, 5))
print(derivative(sinus, 60))
由于正弦的导数是余弦,余弦(60)是0.5,因此输出应为
21.000...
0.5
但不是输出
21.0000195011
0.00872746319658
我做错了什么或只是因为math.sin()
功能?
答案 0 :(得分:4)
至于f()
衍生物的微小差异,来自你的公式不准确。该一般差分商仅为h
的无限小值提供精确答案。计算机显然无法处理无限小的值,因此您使用了“常规”但有点小的h
值并得到了一个近似的答案。如果使用非常小的h
值,则由于计算机仅以有限精度工作,因此会出现其他问题。精度与双精度浮点数一样好。有更复杂的公式可以提供更好的答案:搜索“数字导数”。
答案 1 :(得分:1)
通常在数值计算中,执行计算任务并不像在纸上那样。主要是因为你必须关注浮点错误。因此,通过以下方式可以更好地实现衍生产品:
def derivative(func, x, h = None):
if h is None:
# Note the hard coded value found here is the square root of the
# floating point precision, which can be found from the function
# call np.sqrt(np.finfo(float).eps).
h = 1.49011611938477e-08
xph = x + h
dx = xph - x
return (func(xph) - func(x)) / dx
通过查看此内容,您可以反对dx = h
以xph - x = x + h - x = h
,但如果您实际在计算机上进行计算,则会发现这不是真的,应该到期四舍五入。另请注意,为h
选择一个好的值以获得最佳结果非常重要。现在,默认设置为python中float的机器精度的平方根。
答案 2 :(得分:1)
不,你的代码没错。
'd / dx sin(radians(x))'是1/180 π cos((π x)/180)
http://www.wolframalpha.com/input/?i=d%2Fdx+sin(radians(x))
并且在60处是~0.00872746319658
答案 3 :(得分:1)
正弦导数未按预期工作,因为sinus
将+h
部分转换为弧度,而分母将其保留为度数。您会注意到以下函数正确计算导数。
# treat h as degrees
def derivative(func, x):
h = 0.0000000001
return (func(x + h) - func(x)) / radians(h)
derivative(sinus, 60) # 0.5000468070196941
或者,h
的值可以在传递到sinus
之前转换为度。
# treat h as radians
def derivative(func, x):
h = 0.0000000001
return (func(x + degrees(h)) - func(x)) / h
derivative(sinus, 60) # 0.5000000413701855
请注意,后一个函数会产生更精确的值,因为弧度值0.00 ... 01小于其对应的度数值。但是,这两种方法都不适用于不期望以度为单位的参数的函数。
解决这个问题的唯一方法是指定输入是否以度为单位,甚至这可能不适用于更复杂的三角方程(因为当以度数表示时区分方程时,π/ 180的幂会弹出)。
def derivative(func, x, trans=lambda x: x):
h = 0.0000000001
return (func(x + trans(h)) - func(x)) / h
derivative(sinus, 60, degrees) # 0.5000000413701855