如何在MATLAB中获取函数的导数?

5

在现实生活中,这很简单,但你如何在Matlab中求二次或三次函数的导数呢?

例如,A*x^3 + B*x^2 + C*x + D 的导数为 3*Ax^2 + 2*B*x + C

我想在Matlab中得到这个结果,但我不知道该怎么做 :(

例如,我尝试了这个代码,但是却得到了一个愚蠢的结果(也许应该怪我自己!):

>> x = [6 3 2 1]

x =

     6     3     2     1

>> xPrime = diff(x)

xPrime =

    -3    -1    -1

通常应该返回[18 6 2] ?? 我还想知道如何对一系列数字进行此操作。例如,我希望针对n = linspace(0,10,1000)中的每个点求导数。
更新 当然,我可以手动完成此操作,但我真的很想知道如何使用matlab自己完成此操作。
现在我正在获取上面示例的切线,并且我像这样做,它有效:
x = linspace(0,10,1000);
y=A*x.^3+B*x.^2+C*x + D;
plot(x,y);
hold on;
slop=3*A.*(Location^2)+2*B.*Location+C;
b=(A.*Location.^3)+(B.*Location.^2)+(C.*Location)+D;
y2=slop*(x-Location)+b;
plot(x,y2,'--r');
legend('Graph of the function','Tangent Line');
hold off;

我想表达的是,在这一行中,我应该使用什么代替手动计算的导数?
slop=3*A.*(Location^2)+2*B.*Location+C;

谢谢!


1
你试过 polyder(p) 吗?我有一段时间没用Matlab了,不太记得,但我想这个应该可以。 - Jeff
你有没有看过 diff() 的文档?文档中说:“Y = diff(X) 计算 X 相邻元素之间的差异。” 这似乎不是你想要它做的事情。 - André Caron
4个回答

3
你想了解Matlab的符号库(基于Maple引擎)。基本思路是创建符号变量('syms'),然后以符号方式求导这些表达式。然后,你可以在一些坐标值处评估符号表达式并将其转换为函数句柄。有关语法、'syms'库等的说明,请参见此处
但在实际应用中,通常需要编写自己的数学函数。只有在特殊情况下才能分析地计算出导数,而在这些情况下,你需要编写另一个单独的数学函数来处理导数。符号库通常非常慢,它们(至少目前如此)是通过句柄生成实际函数的低效方式。
如果你只会处理多项式,那么这是一个特殊的情况,你应该能够编写一个通用的Matlab函数,它接受系数列表和值范围作为输入,并输出导数系数列表以及在这些值处评估的导数函数。以下是一个示例:
 function [d_coeffs, d_vals] = compute_poly_derivative(in_coeffs, in_values)
 num_terms = length(in_coeffs)-1;
 max_power = num_terms;

 for ii=1:num_terms
     d_coeffs[ii] = in_coeffs[ii]*max_power;
     max_power = max_power - 1;
 end

 d_vals = polyval(d_coeffs,in_values);

3
为了获得一个多项式的导数,可以使用Matlab的polyder()函数。该函数接受多项式系数的标准表示形式(向量),并将其导数作为第二个系数向量返回。您可以像这样在某个值x处计算多项式p的导数:
slop = polyval(polyder(p), x);

谢谢,但在我的情况下,我有一个像0:1000:10这样的x范围,而我想要切线线斜率的点被命名为location。我尝试使用您提供的代码行,但它并不关心这个。您有什么办法可以在我的代码中使用它?! - Dumbo
你的意思是要在点location处,绘制一条切线作为三次曲线的切线,并覆盖范围x吗?如果是这样,那么你需要使用以下代码:slop = polyval(polyder(p), location); tangent = [slop polyval(p3, location) - location*slop]; plot(x, polval(tangent, x); - Max
是的,完全正确...但是polyder(p)中的那个p是什么?还有p3呢? - Dumbo
糟糕 - 我的错!我应该在两个位置使用 p:即要对其求切线的三次多项式系数向量,按降序排列(Matlab 的正常约定)。 - Max

2
您可以使用有限差分法(finite differences)进行数值计算。MATLAB有一个函数gradient,它包含一个二阶精确格式——请参见这里
如果您正在寻求更高的精度,您可以实现自己的更高阶格式。
希望这能有所帮助。

1

diff 给出列表中相邻元素之间的差异:3-6等于-3,2-3等于-1等。

如果您有符号工具箱,则可以使用它。或者,如果您只需要多项式,自己编写也不难:

ds = poly .* fliplr(0:length(poly)-1);
ds = [0 ds(1:end-1)];

这只是通过其指数将每个系数乘以其指数(fliplr 反转列表),然后将指数向下移动一位(将列表元素向右移动一位)。

这为您提供了多项式的新表示。要在给定点 x 上评估其中之一,请尝试

sum(poly .* x .^ fliplr(0:length(poly)-1))

或许我的表述不够清晰,请您确认一下已更新的问题好吗? - Dumbo
谢谢,我尝试着将你写的代码和我自己的代码连接起来,但是我有些困惑该在哪里用你的代码替换我的代码? - Dumbo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接