绘制复杂函数的分支

时间:2018-11-09 23:16:45

标签: matlab plot visualization complex-numbers surface

我正在尝试绘制一种函数的黎曼曲面(我不确定它是否是该事物的正确名称),如下所示:

Desired result

这是我尝试过的:

r = (0:1:15)';                           % create a matrix of complex inputs
theta = pi*(-1:0.05:1);
z = r*exp(1i*theta);
w = z.^(1/2)  ;                          % calculate the complex outputs

figure('Name','Graphique complexe','units','normalized','outerposition',[ 0.08 0.1 0.8 0.55]);
subplot(121)

surf(real(z),imag(z),real(w),imag(w))    % visualize the complex function using surf
xlabel('Real(z)')
ylabel('Imag(z)')
zlabel('Real(u)')
cb = colorbar;
colormap jet;                            % gradient from blue to red
cb.Label.String = 'Imag(v)';

subplot(122)
surf(real(z),imag(z),imag(w),real(w))    % visualize the complex function using surf
xlabel('Real(z)')
ylabel('Imag(z)')
zlabel('Imag(v)')
cb = colorbar;
colormap jet;                            % gradient from blue to red
cb.Label.String = 'Real(u)';

哪些给了我以下内容:

Current result

我的问题是:

  1. 我以为我会绘制第一个图像上的内容,但是我得到了其他内容。如果不是Riemann的曲面,我该怎么绘制?

  2. 如何更改我的代码以获取最高收益?

  3. 是否可以在第一张图上使用弧度标度?

1 个答案:

答案 0 :(得分:4)

您的第一幅图显示了一个多值“函数”的多个分支。从通常意义上说,它实际上不是一个函数,因为对于给定的z,您具有多个函数值。您只能通过多次绕原点(即,角度变量中的2*pi)来重现此内容。您所绘制的是该函数的主要分支,即与从-pipi的复杂阶段相对应的工作表。

此外,还有一个更基本的问题。切换为以双精度表示的复数后,您将丢失有关原点周围其他相位的任何信息(以实+虚数表示的复数只会导致其复数的本金,该数值介于-pi之间和pi)。因此,您需要根据复数的三角形式“手动”计算平方根:

r = (0:1:15)';                           % create a matrix of complex inputs
theta = pi*(-2:0.05:2);
z = r*exp(1i*theta);
%w = z.^(1/2)  ;                          % calculate the complex outputs
w = sqrt(r)*exp(1i*theta/2);

figure('Name','Graphique complexe','units','normalized','outerposition',[ 0.08 0.1 0.8 0.55]);
subplot(121)

surf(real(z),imag(z),real(w),imag(w))    % visualize the complex function using surf
xlabel('Real(z)')
ylabel('Imag(z)')
zlabel('Real(u)')
cb = colorbar;
colormap jet;                            % gradient from blue to red
cb.Label.String = 'Imag(v)';

subplot(122)
surf(real(z),imag(z),imag(w),real(w))    % visualize the complex function using surf
xlabel('Real(z)')
ylabel('Imag(z)')
zlabel('Imag(v)')
cb = colorbar;
colormap jet;                            % gradient from blue to red
cb.Label.String = 'Real(u)';

result from polar solution

如您所见,该函数按其应有的方式工作。请注意,图中没有“弧度比例”是没有意义的。您绘制的所有内容均具有“线性”尺寸:实部和虚部。弧度仅对 angles (即theta类数量)有意义。

此外,由于我们使用极坐标进行绘制,因此您可能还注意到上面的图具有圆形边缘。可以创建矩形图,但需要做很多工作。这是部分解决方案。想法是将相同的网格缝合两次,以绘制函数的两个分支:

r0 = 15;
re = linspace(-r0, r0, 31).';                           % create a matrix of complex inputs
im = linspace(-r0, r0, 31);
z = re + 1j*im;
theta = angle(z);  % atan2(imag(z), real(z));
r = abs(z);

% concatenate the same mesh twice (plotting trick) back to back, insert nan in between
w1 = sqrt(r).*exp(1i*theta/2); % first branch
w2 = sqrt(r).*exp(1i*(theta+2*pi)/2); % second branch

z = [z, nan(size(w1,1),1), z(:,end:-1:1)];
w = [w1, nan(size(w1,1),1), w2(:,end:-1:1)];

figure('Name','Graphique complexe','units','normalized','outerposition',[ 0.08 0.1 0.8 0.55]);
subplot(121)
surf(real(z),imag(z),real(w),imag(w))    % visualize the complex function using surf
xlabel('Real(z)')
ylabel('Imag(z)')
zlabel('Real(u)')
cb = colorbar;
colormap jet;                            % gradient from blue to red
cb.Label.String = 'Imag(v)';

subplot(122)
surf(real(z),imag(z),imag(w),real(w))    % visualize the complex function using surf
xlabel('Real(z)')
ylabel('Imag(z)')
zlabel('Imag(v)')
cb = colorbar;
colormap jet;                            % gradient from blue to red
cb.Label.String = 'Real(u)';

结果如下:

result from Cartesian solution

如您所见,复杂部分看起来很奇怪。这是因为复数的相位沿负实半轴跳跃。该可以补救,但需要做很多工作,这留给读者练习。我在数据中注入nan列的原因是为了防止在第一张图中出现类似的跳跃伪像。另一种选择是分别绘制函数的两个分支,并在它们之间插入hold on,但是必须做额外的工作才能对图形上的颜色图进行标准化。

最后,请考虑不要使用jet,而是使用默认的parula颜色图。对于视力受损的人来说,喷气机非常不利,parula几乎可以感知均匀。对于这个问题的简短介绍,我建议看那些this great talk的家伙。