我想绘制 x 实值的黎曼 Zeta 函数。这可能吗?我知道将其纳入其中的可能性很小。
答案1
据我所知,LaTeX 中没有集成 zeta 函数,因此您需要具备 LaTeX 高手的技能水平(以及大量的时间)才能使用纯 LaTeX 完成此操作——它不是完成这项工作的合适工具。有一种更简单的方法:由于 pgfplots 包只需要一个要绘制的坐标列表,因此让计算机代数系统处理计算,然后将它们“粘贴”到需要坐标的位置。可以使用“sagetex”包快速轻松地完成此操作,该包可让您访问计算机代数系统 Sage。由于 Sage 是专门为处理数学而构建的,因此内置支持多种功能,包括 zeta 函数。以下是在 35 行中绘制 zeta 函数的两种方法:
\documentclass{article}
\usepackage{sagetex}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{pgfplots}
\begin{document}
\begin{sagesilent}
t = var('t')
LowerY = -4
UpperY = 5
LowerX = -3
UpperX = 3
step = .01
x_coords = [t for t in srange(LowerX,UpperX,step)]
y_coords = [zeta(t).n(digits=6) for t in srange(LowerX,UpperX,step)]
output = r""
output += r"\begin{tikzpicture}[scale=.7]"
output += r"\begin{axis}[xmin=%f,xmax=%f,ymin= %f,ymax=%f]"%(LowerX,UpperX,LowerY, UpperY)
output += r"\addplot[thin, blue, unbounded coords=jump] coordinates {"
for i in range(0,len(x_coords)-1):
if (y_coords[i])<LowerY or (y_coords[i])>UpperY:
output += r"(%f , inf) "%(x_coords[i])
else:
output += r"(%f , %f) "%(x_coords[i],y_coords[i])
output += r"};"
output += r"\end{axis}"
output += r"\end{tikzpicture}"
\end{sagesilent}
\begin{center}
\sagestr{output}
\end{center}
\begin{center}
\sageplot[width=6cm]{plot(zeta(x), (x, -3, 3),ymin=-4, ymax=5,detect_poles=True)}
\end{center}
\end{document}
要使用sagetex
软件包,您需要在计算机上安装 Sage。最简单的入门方法是使用(免费)萨基马云帐户。在 tikzpicture 环境中调用 Sage 可能会出现问题,就像我在回答中遇到的那样这里,因此最好通过在环境tikzpicture
内排版整个文本来避免这种情况sagesilent
。代码基于您提供的查看窗口参数:LowerY、UpperY、LowerX、UpperX。x_coords 获取从 -3 到 3 的值,步长为 .01。y_coords 使用 Sage 并计算每个值的 zeta。您只想在窗口中绘制值,因此如果 y 值太大或太小,代码会将 y 值设置为 inf(表示无穷大)。否则,该值在查看窗口中,因此我们创建坐标而不进行调整。选项“unbounded coords=jump”将跳过不连续之处(从而使图形断开连接)。创建图片后,我们使用 \sagestr{output} 将其插入文档中。
如果您不需要 tikz/pgfplots,那么使用 Sage 的绘图功能可以以简单的方式绘制图表:\sageplot[width=6cm]{plot(zeta(x), (x, -3, 3),ymin=-4, ymax=5,detect_poles=True)}
detect_poles=True 告诉 Sage 如果看起来存在不连续性,则不要连接图。将上面的代码复制/粘贴到 Sagemath Cloud 中可获得以下内容:
因为使用了计算机代数系统,所以将函数从 zeta(x) 更改为其他函数很简单,而且代码仍然可以工作。
答案2
另一种可能性是使用接近 LaTeX 的外部绘图程序/语言,具有足够的计算能力,例如 MetaPost 或 Asymptote。这是我的快速尝试(对于 x>1),使用 MetaPost 和 LuaLaTeX,因为 MetaPost 恰好通过库与 LuaTeX 紧密集成mplib
(而且它是我最熟练的语言 ;-))。
\documentclass[12pt]{scrartcl}
\usepackage{unicode-math}
\usepackage{luamplib}
\mplibsetformat{metafun}
\mplibnumbersystem{double}
\mplibtextextlabel{enable}
\everymplib{%
verbatimtex
\leavevmode
etex;
% "Riemann sum" (heavily inspired by Herbert Voss's Lua code)
vardef riemann_sum(expr x, epsilon) =
save k, y, dy;
y = 0; k = 1;
forever:
dy := 1/(k**x);
y := y + dy; k := k + 1;
exitif abs(dy) < epsilon;
endfor;
y
enddef;
%
% Riemann curve (also heavily inspired by Herbert's Lua code)
vardef riemann_curve(expr xs, xf, n, epsilon) =
save k, x, dx;
dx = (xf-xs)/n;
(xs, riemann_sum(xs, epsilon))
for x= xs+dx step dx until xf:
-- (x, riemann_sum(x, epsilon))
endfor
enddef;
%
beginfig(1);
}
\everyendmplib{endfig;}
\begin{document}
\begin{center}
\begin{mplibcode}
% For scaling
u := 0.8cm; b = 14;
% Riemann curve between 1.01 and b = 14, with n = 100 and epsilon = 1e-6
draw riemann_curve(1.01, b, 100, 1e-6) xyscaled u withcolor red;
% Axes
drawarrow (origin -- (b, 0)) xscaled u;
drawarrow (origin -- (0, b)) yscaled u;
% Marking and labels
eps := 3bp;
labeloffset := 6bp;
for x = 1 upto b-1:
draw (x*u, -eps)--(x*u, eps); label.bot(textext("$" & decimal(x) & "$"), (x*u, 0));
draw (-eps, x*u)--(eps, x*u); label.lft(textext("$" & decimal(x) & "$"), (0, x*u));
endfor;
label.llft("$O$", origin);
label.bot("$s$", (b*u, 0));
label.lft("$\zeta$", (0, b*u));
\end{mplibcode}
\end{center}
\end{document}
MetaPost 也可以在外部使用,就像 Asymptote 一样。另一种可能性是在 LuaLaTeX 中使用一些 Lua 代码。顺便说一句,我的 MetaPost 程序很大程度上受到了 Herbert Voss 对此问题的回答中的 lua 编码的启发有点接近的主题。