2011-01-11 64 views
8

这应该很简单。我有一个功能f(x),我想要评估f'(x)在MATLAB中的给定x如何在matlab中评估函数的导数?

我所有的搜索都提出了符号数学,这不是我所需要的,我需要数值分化。

E.g.如果我定义:fx = inline('x.^2')

我想找个说f'(3),这将是6,我不想找到2x

回答

7

为了得到一个数值差(对称差),你算算(f(x+dx)-f(x-dx))/(2*dx)

fx = @(x)x.^2; 
fPrimeAt3 = (fx(3.1)-fx(2.9))/0.2; 

或者,您可以创建函数值的矢量和应用DIFF,即

xValues = 2:0.1:4; 
fValues = fx(xValues); 
df = diff(fValues)./0.1; 

注意diff需要前向差异,并假设dx等于1.

但是,在你的情况下,您最好将fx定义为polynomial,然后评估函数的导数,而不是函数值。

+0

+1为一个整洁的答案:) – posdef 2011-01-11 14:43:41

+0

我是对的,我认为我选择dx越小,我的答案就越准确。如果是的话,是否有一个非常小的实数的MATLAB常量?类似于pi的3.14 ...或者我为sqrt(-1)? – lms 2011-01-11 16:15:22

+2

@codenoob:`eps`给你一个很小的数字。但是,对于大多数实际用途而言,0.0001就足够了。另外,如果你使用多项式并使用`polyder`,则不必担心`dx`的大小。 – Jonas 2011-01-11 16:29:43

4

你尝试diff(计算差异和近似衍生物),gradient,或polyder (计算多项式的导数)函数?

您可以在MATLAB控制台上使用help <commandname>或使用帮助菜单中的功能浏览器阅读关于这些功能的更多信息。

+0

+1为更快一点:) – Jonas 2011-01-11 14:44:34

0

对于解析形式给定的功能,可以在用下面的代码的期望点评估衍生物:

syms x 
df = diff(x^2); 
df3 = subs(df, 'x', 3); 
fprintf('f''(3)=%f\n', df3); 

对于纯数值衍生物使用由纳斯和posdef已经给出的解决方案。

6

缺少符号工具箱,没有什么能阻止您使用Derivest这一自动自适应数值微分工具。

derivest(@sin,pi) 
ans = 
      -1 

对于你的例子它很好。事实上,它甚至提供了对所得近似值误差的估计。

fx = inline('x.^2'); 
[fp,errest] = derivest(fx,3) 

fp = 
      6 
errest = 
    3.6308e-14 
9

如果你的函数被称为是二次可微,使用

f'(x) = (f(x + h) - f(x - h))/2h 

这是二阶h中准确。如果它只有一次可微分,请使用

f'(x) = (f(x + h) - f(x))/h  (*) 

这是h中的第一顺序。

这是理论。实际上,事情非常棘手。由于分析比较简单,我将采用第二个公式(一阶)。做第二个练习。

第一个观察结果是,你必须确保(x + h) - x = h,否则你会得到巨大的错误。事实上,f(x + h)和f(x)彼此接近(比如2.0456和2.0467),当你减去它们时,你会失去很多有意义的数字(这里是0.0011,比x)。因此,h上的任何错误都可能对结果产生巨大影响。因此,第一步,修复一个候选人h(我会在一分钟内告诉你如何选择它),并将h'作为你的计算量h'=(x + h)-x。如果您使用的是像C这样的语言,则必须注意将h或x定义为挥发性,以便不会优化该计算。

接下来,选择h。 (*)中的错误包含两部分:截断错误和舍入错误。截断误差是因为公式并不确切:

(f(x + h) - f(x))/h = f'(x) + e1(h) 

e1(h) = h/2 * sup_{x in [0,h]} |f''(x)|哪里。

舍入误差来自f(x + h)和f(x)彼此接近的事实。它可以大致被估计为

e2(h) ~ epsilon_f |f(x)/h| 

其中epsilon_f是在F(X)(或F(X + h)时,其是接近)的计算的相对精度。这必须从您的问题进行评估。对于简单的功能,epsilon_f可以作为机器epsilon。对于更复杂的,它可能比数量级更差。

所以你想要h它最小化e1(h) + e2(h)。一同插入一切,在h优化产生

h ~ sqrt(2 * epsilon_f * f/f'') 

这必须从你的函数进行估计。你可以做出粗略的估计。如有疑问,请参阅epsilon =机器精度的h〜sqrt(epsilon)。对于h的最优选择,导数已知的相对准确度是sqrt(epsilon_f),即。一半有效数字是正确的。

总之:h =>舍入误差太小,h =>截断误差太大。

对于第二阶式中,相同的计算产量

h ~ (6 * epsilon_f/f''')^(1/3) 

和(epsilon_f)^(2/3)为衍生物的分数精度(其通常比第一个或两个显著附图将更好地订单公式,假设双精度)。

如果这太不精确,随意要求更多的方法,有很多技巧来获得更好的准确性。理查森外推法对于平稳的功能来说是一个好的开始。但是这些方法通常计算f几次,如果函数复杂,这​​可能会或不会是你想要的。

如果您打算在不同的点使用数值导数很多次,那么构造一个切比雪夫逼近就会变得很有趣。