z = sqrt(x + a1 y) + sqrt(x + a2 y)
考虑具有x > 0
、y in R
实数和复数的复数变量a1,a2 in C
。我想绘制Re(z)
相对于 的参数图Im(z)
。它看起来应该像这样:
出乎我的意料,在这个网站上搜索“复杂参数 PGFPlots”什么也没发生。
可能是因为(据我所知)PGFplots 没有复数概念,没有函数Re
,Im
无法分离实部和虚部。所以我在考虑实现复数平方根,正如 Did 在math.stackexchange.com 上的这篇文章但那会很麻烦。有没有更简单的解决方案?
答案1
我们可以尝试一下元帖子。我把它包裹在luamplib
但您可以轻松地将其改编为普通版本mpost
。我不确定这是否是一个非常强大的解决方案,但它可能成为进一步调查的基础。
\RequirePackage{luatex85}
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
% assume the pair z is a complex number and return the pair corresponding
% to the complex sqrt
def zsqrt(expr z) = dir 1/2 angle z scaled sqrt(abs(z)) enddef;
beginfig(1);
numeric xmin, xmax, ymin, ymax;
xmin = 0; xmax = 12; ymin = 1; ymax = 3;
vardef f(expr x,y) = zsqrt((x,0) + (1,1) zscaled (y,0) ) + zsqrt((x,0) + (2,+2) zscaled (y,0)) enddef;
vardef g(expr x,y) = zsqrt((x,0) - (1,1) zscaled (y,0) ) + zsqrt((x,0) + (2,-2) zscaled (y,0)) enddef;
vardef edge_path(suffix FUN)(expr xmin, xmax, ymin, ymax, s) =
for x=xmin step s until xmax: FUN(x,ymin) .. endfor
for y=ymin step s until ymax: FUN(xmax,y) .. endfor
for x=xmax step -s until xmin: FUN(x,ymax) .. endfor
for y=ymax step -s until ymin: FUN(xmin,y) .. endfor cycle
enddef;
path a, b;
a = edge_path(f,0,12,1,3,1/4) scaled 1cm;
b = edge_path(g,0,12,1,3,1/4) scaled 1cm;
fill a withcolor .8[blue,white]; draw a;
fill b withcolor .8[red+1/2green,white]; draw b;
path xx, yy;
xx = (1/2 left -- 9 right) scaled 1cm;
yy = (7/2 down -- 3 up) scaled 1cm;
drawarrow xx;
drawarrow yy;
endfig;
\end{mplibcode}
\end{document}
Metapost 弱内置了复数。基本上,您可以将pair
类型视为复数。内置运算abs
和angle
工作方式与您预期的一样,运算zscaled
执行复数乘法。
编辑
我已经将复杂的 sqrt 函数更新为更正确、更简单、更高效的版本。原始版本是:
vardef sqrtz(expr zz) =
save c, r, w;
numeric r, c;
pair w;
r = abs(zz);
w = zz + (r,0);
c = sqrt(r)/abs(w);
w scaled c
enddef;
从几何角度看,这是合理的,但对于负实数则不成立。替换版本更加稳健,并且能够更好地利用 MP 的内置函数。新版本为:
def zsqrt(expr z) = dir 1/2 angle z scaled sqrt(abs z) enddef;
如果您将对视为复数,则会angle z
给出参数,并abs z
给出模数。 dir theta
给出一个从 (1,0) 旋转 theta 度的单位向量,因此dir 1/2 angle z
会给出一个具有一半参数的单位向量z
,然后按 进行缩放,sqrt(abs z)
这就是我们想要的。
请注意,如果您尝试执行angle (0,0)
,MP 会给出错误,提示! angle(0,0) is taken as zero
。在这种情况下,这正是我们想要的,但 MP 会因为错误而停止。您可以通过编写以下内容来避免错误:
def zsqrt(expr z) = if z=origin: origin else: dir 1/2 angle z scaled sqrt(abs z) fi enddef;
这可能是最好的通用函数。