我想绘制以下函数的图形:
f(x)=abs(x - x^3/6 - sin(x)) 其中 -1<= x <=1
但得到了噪声(靠近x轴)曲线:代码如下:
\documentclass[11pt,border=1mm]{standalone}
\usepackage[portuguese, shorthands=off]{babel}
\usepackage[utf8]{inputenc}
\usepackage{tikz,pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin = -1,
xmax = 1,
width = 10cm]
\addplot[domain = -1:1,samples = 1000,smooth,color=blue]
{abs(x-x^3/6-sin(deg(x)))};
\end{axis}
\end{tikzpicture}
\end{document}
我怎样才能解决这个问题?
答案1
不久前也曾出现过类似的问题。如果已经猜到“噪音”的根本原因是 TeX 的计算引擎。因此解决方案是使用其他计算引擎。这里我展示了 TeX 和 Lua 的比较。在我对类似问题的回答您还可以找到引擎 gnuplot 和 l3/xfp。
% used PGFPlots v1.18.1
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
% use this `compat` level or higher to make use of the Lua calculation engine
\pgfplotsset{compat=1.12}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
cycle multiindex* list={
color\nextlist
[1 of]mark list\nextlist
},
xmin=-1,
xmax=1,
domain=-1:1,
samples=51,
smooth,
% no markers,
mark size=1pt,
trig format=rad,
]
% using TeX as calculation engine
\addplot+ [thick] {abs(\x-\x^3/6-sin(\x))};
% using Lua as calculation engine
\addplot {abs(x-x^3/6-sin(x))};
\end{axis}
\end{tikzpicture}
\end{document}
答案2
正如其他人所解释的那样,您依靠pgfmath
进行计算,而这很容易出现舍入错误。它非常适合大多数人遇到的那种计算,但您正在使用更复杂的函数。那么答案就是使用更合适的工具,即计算机代数系统来进行计算。使用包可以做到这一点sagetex
,找到这里在 CTAN 上。此软件包可让您将计算外包给开源 CAS智者而不是使用pgfmath
。结果将是可以在您的图表中使用的精确计算。
\documentclass[11pt,border=1mm]{standalone}
\usepackage{sagetex}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{sagesilent}
LowerX = -1
UpperX = 1
LowerY = -.001
UpperY = .009
step = .001
t = var('t')
g(x)= abs(x-x^3/6-sin(x))
x_coords = [t for t in srange(LowerX,UpperX,step)]
y_coords = [g(t).n(digits=6) for t in srange(LowerX,UpperX,step)]
output = r""
output += r"\begin{tikzpicture}[scale=1.0]"
output += r"\begin{axis}[xmin=%f,xmax=%f,ymin= %f,ymax=%f,width=10cm]"%(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}
\sagestr{output}
\end{document}
代码运行于可钙,如下所示:
Sage 不是您的 LaTeX 发行版的一部分,所以它将无法在您的机器上运行,除非您 1. 将该程序下载到您的机器并使其与您的 LaTeX 发行版一起工作(这可能会很麻烦)或 2. 开设一个免费的 Cocalc 帐户,这样您就可以通过互联网访问 Sage。
Sage 还允许您访问 Python,然后您也可以使用它。例如,请参见使用 sagetex 绘制康托函数。搜索此网站sagetex
,您将看到它如何用于更复杂的数学问题,例如查找矩阵的转置。
答案3
更新:
初学者遇到的一个难题是编译任何单个 Asymptote 代码,因此,我分享了一种我使用过的方法http://asymptote.ualberta.ca/,就这个。
在等待 TikZ/PGF 答案时,查看可运行的代码渐近线。
Asymptote 的特点之一:
...
受到 MetaPost 的启发,具有更简洁、更强大的类 C++ 编程语法,IEEE 浮点数值;
...
import graph;
size(350,300,false); // The boolean "false" is important.
real f(real x){ return abs(x-x^3/6-sin(x));}
guide F=graph(f,-1,1,500);
// domain -1,1
// samples 500
draw(F,1bp+blue);
limits((-1,-1e-3),(1,9*1e-3)); // See page 113 in the documentation
xaxis("$x$",BottomTop,LeftTicks(Size=4,Ticks=uniform(-1,1,10)));
yaxis("$y$",LeftRight,RightTicks(ticklabel=new string(real x){ return
format("%.3f",1e+3*x);},
Size=4,Ticks=1e-3*uniform(0,8,4)));
labelx("$.10^{-3}$",(-1,9*1e-3),N+0.7E); // See page 104 in the documentation
答案4
这(太长,不适合评论)是上述渐近线答案。这个问题很有趣,因为TikZ 中命令的[smooth]
选项不能按预期工作,这是由于 的计算限制。因此 Asymptote 是合适的选择之一。[samples]
plot
pgfmath
下面说明了sine
函数、3 阶泰勒多项式和 3 阶泰勒余数。因此,从视觉上看,T_3(x)
的近似值sin(x)
仅在原点附近才有效,此时余数几乎是水平的。
// http://asymptote.ualberta.ca/
unitsize(1cm);
size(8cm);
import graph;
usepackage("amsmath");
pen p=gray+opacity(.5);
draw((-2pi-1,0)--(2pi+1,0),p);
draw((0,-4)--(0,5),p);
// graph of sin(.)
path F=graph(sin,-2pi,2pi);
draw(Label("$y=\sin x$",EndPoint,N),F,blue);
// graph of the 3rd-order Taylor polynomial
real T3(real x){ return (x-x^3/6);}
guide G=graph(T3,-1.1pi,1.1pi);
draw(Label(scale(.8)*"$T_3(x)=x-\dfrac{x^3}{6}$",EndPoint,E),G,darkcyan);
// graph of the 3rd-order Taylor remainder
real r(real x){ return abs(x-x^3/6-sin(x));}
guide R=graph(r,-1.15pi,1.15pi,500);
draw(Label(scale(.8)*"$r_3(x)=\left|x-\dfrac{x^3}{6}-\sin x\right|$",BeginPoint),R,magenta);
shipout(bbox(5mm,invisible));