我想在MATLAB中以数字方式计算复值函数(全纯函数)的导数。
我在复平面上的网格中计算了函数,并且我尝试使用Cauchy-Riemann关系计算导数。
给定: u = real(f),v = imag(f),x = real(point),y = imag(point)
衍生物应由:f' = du / dx + i dv / dx = dv / dy - i du / dy
其中' d'是衍生运算符。
我尝试过以下代码:
stepx = 0.01;
stepy = 0.01;
Nx = 2/stepx +1;
Ny = 2/stepy +1;
[re,im] = meshgrid([-1:stepx:1], [-1:stepy:1]);
cplx = re + 1i*im;
z = cplx.^3;
衍生物应由:
给出f1 = diff(real(z),1,2)/stepx +1i* diff(imag(z),1,2)/stepx;
或
f2 = diff(imag(z),1,1)/stepy - 1i* diff(real(z),1,1)/stepy;
但是假设相等的两个衍生物不匹配。
我做错了什么?
让我们计算小于stepx的元素数量(假设stepx = stepy):
lm = min(size(f1));
A = f1(1:lm,1:lm);
B = f2(1:lm,1:lm);
sum(sum(abs(A - B) <= stepx))
并使用@A提出的修复程序。唐达
f1i = interp1(1 : Ny, f1, 1.5 : Ny);
f2i = interp1(1 : Nx, f2 .', 1.5 : Nx) .';
sum(sum(abs(f1i - f2i) <= stepx))
在第二种情况下,它们的差异应该小于stepx,而在第一种情况下它不是真的。
答案 0 :(得分:1)
问题在于,使用两个不同的表达式,在Matlab中进行离散化,您可以计算复平面中不同点的近似导数。假设您处于虚值y并且计算沿实轴x的差异,则第i个差值估计(x(i) + x(i + 1))/2
处的导数,即在两个后续x值之间的所有中点处。另一种方法是估计给定x的导数,但是在两个后续y值之间的所有中点。
这也导致所得矩阵的不同大小。使用第一个公式得到一个大小为201x200的矩阵,另一个大小为200x201。这是因为在第一个版本中,沿着x有200个中点,但是201个y值,反之亦然。
所以答案是,你没有做错任何事,你只是错误地解释了结果。
你可以通过沿着另一个维度明确插值来解决问题(不用于导数的那个):
f1i = interp1(1 : Ny, f1, 1.5 : Ny);
f2i = interp1(1 : Nx, f2 .', 1.5 : Nx) .';
根据您的第一个公式计算f1
,根据第二个公式计算f2
。现在两个导数都是在两个维度的中点处进行评估,这就是为什么两个矩阵都是200x200的原因。
如果你现在比较它们,你会发现它们在数值误差方面是相同的(毕竟,diff
只计算近似导数而interp1
会产生插值误差)。对于您的步长,此错误最大为1e-4,并且可以通过使用较小的步长来进一步减少。