我有以下功能(Viviani的曲线):
Phi = @(t)[ cos(t)^2, cos(t)*sin(t), sin(t) ]
只需检查一下它是否有效:
s = linspace(0,T,1000);
plot3(cos(s).^2, cos(s).*sin(s), sin(s));
如何推导函数Phi
(可能是多次),它代表t
t
从0
到2*pi
的点Phi
中的Viviani曲线?我是否定义diff
适合这种衍生物?我已经尝试了Phi
,但它没有像我需要的那样保留Phi_d2
。
如果二阶导数为t = 0
,我需要得到它的值(例如在{{1}}中)。
我怎样才能做到这一点?
答案 0 :(得分:4)
您可以通过以下三种方式完成此任务。第一个使用subs
,第二个使用symfun
,第三个使用complex step differentiation:
% Using subs
syms t
Phi = [cos(t) cos(t).*sin(t) sin(t)];
Phi_d2 = diff(Phi,t)
double(subs(Phi_d2,t,0))
% Using symfun
syms t
Phi(t) = [cos(t) cos(t).*sin(t) sin(t)];
Phi_d2 = diff(Phi,t)
double(Phi_d2(0))
% Using complex step differentiation
Phi = @(t)[cos(t) cos(t).*sin(t) sin(t)];
h = 2^-28;
cdiff = @(f,x)imag(f(x(:)+1i*h))/h;
Phi_d2 = cdiff(Phi,0)
您可以找到执行一阶和二阶复数阶差分on my GitHub: cdiff
的函数。请注意,复数阶跃微分对高阶导数不起作用。当一个人只有一个不可微分的函数或需要快速数值一阶导数时,这是最好的。
答案 1 :(得分:3)
为了完整起见,数值解决方案不使用任何其他工具箱:
N = 999;
t = linspace(0,2*pi,N+1);
Phi = [cos(t); cos(t).*sin(t); sin(t)];
dPhi = gradient(Phi,2*pi/N)
对于非均匀间隔的参数向量,gradient
的第二个参数由间距向量而不是标量定义。 (时间或角度矢量是合适的) - 在这种情况下,显然有必要分割尺寸。 (虽然我不知道为什么。)
所以或者,尽管没有必要:
dX = gradient(Phi(1,:),t);
dY = gradient(Phi(2,:),t);
dZ = gradient(Phi(3,:),t);
dPhi = [dX; dY; dZ];