pgfplots:addplot 在 (sin(x) - x cos(x)) / x^3 上的收敛问题

pgfplots:addplot 在 (sin(x) - x cos(x)) / x^3 上的收敛问题

f(x) = (sin(x) - x cos(x)) / x^3我正在尝试使用 pgfplots 代码绘制函数

    \begin{tikzpicture}
        \begin{axis}[]
            \addplot[domain = 0:14,smooth,samples=500, thick] {(sin(deg(x))- x * cos(deg(x))) / (x^3)};
        \end{axis}
    \end{tikzpicture}

代码可以运行,但是在收敛时会出现问题,x = 0导致在靠近原点的地方出现错误的图形: 在此处输入图片描述

我可以做些什么来解决这个问题,例如通过提高 addplot 命令的精度?

提前致谢!

答案1

如果你想一直走到 0,那么我建议使用泰勒展开式的第一个项在 0 附近

示例输出

\documentclass{article}

\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
        \begin{axis}[]
            \addplot[domain = 2:15,smooth,samples=500, thick]
            {(sin(deg(x))- x * cos(deg(x)) ) / (x^3) };
            \addplot[domain = 0:2,smooth,samples=500, thick, red]
            {(1/3 - x^2*4/5! + x^4*6/7! - x^6*8/9!};
        \end{axis}
    \end{tikzpicture}
\end{document}

这里我将泰勒展开图涂成了红色。我还夸大了泰勒展开的使用范围,将交换值置于 2 处。小于 1 的值(例如 0.5)更为合理。

答案2

问题在于分子在 0 附近是三次方,这超出了 PGF 的算术能力。

您可以使用pgfmath-xfp它来更好地处理浮点计算。请注意,您需要避免在 0 处进行计算,但这不是真正的问题。

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfmath-xfp}
\pgfplotsset{compat=1.18}

\begin{document}

\begin{tikzpicture}
\pgfmxfpdeclarefunction{foo}{1}{(sin(#1)-(#1)*cos(#1))/(#1)^3}
  \begin{axis}[]
    \addplot[domain = 0.001:14,smooth,samples=500, thick] {foo(x)};
  \end{axis}
\end{tikzpicture}

\end{document}

在此处输入图片描述

您也可以在 0 处定义该函数,但这不值得这么痛苦:

\pgfmxfpdeclarefunction{foo}{1}{ #1=0 ? 1/3 : (sin(#1)-(#1)*cos(#1))/(#1+(#1=0?1:0))^3}

由于两个表达式都需要计算,因此分母的修正是必要的,因此当 x=0 时,我把分母设为 1。

答案3

您可以使用gnuplot提供更高精度的选项。编译必须包含该-shell-escape选项。gnuplot您的框中必须有该命令。

\documentclass{article}
\usepackage{tikz,pgfplots}

\begin{document}
 \begin{tikzpicture}
        \begin{axis}[]
          \addplot[domain = 0:14,smooth,samples=500, thick] gnuplot {(sin(x)- x * cos(x)) / (x^3)};
%                                                           ^^^^^^^
        \end{axis}
    \end{tikzpicture}
  \end{document}

石墨烯

其他解决方案:

您可以使用任何能够执行此操作的软件或编程语言创建表,并将数据保存在数据文件中(例如http://ix.io/3PQw)并使用table关键字

\documentclass{article}
\usepackage{tikz,pgfplots}

\begin{document}
 \begin{tikzpicture}
        \begin{axis}[]
          \addplot[smooth, thick] table {data.dat};
%                                 ^^^^^^^
        \end{axis}
    \end{tikzpicture}
  \end{document}

此解决方案不需要编译,-shell-escape但编译速度比第一个稍慢。但是第一个解决方案比第一个解决方案快三到四倍,pgfmath-xfp比 Andrew Swann 的解决方案快近五倍。这可能对一些需要大量计算的大型文档有影响。

答案4

为了完成安德鲁的回答,你可以使用x ? y : z符号来只用一个\addplot

\documentclass{standalone}

\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
        \begin{axis}[]
          \addplot[domain = 0:15,smooth,samples=500, thick]
          { abs(x)>0.5 ? 
            (sin(deg(x))- x * cos(deg(x)) ) / (x^3) :
            (1/3 - x^2*4/5! + x^4*6/7! - x^6*8/9!
            };
        \end{axis}
    \end{tikzpicture}
\end{document}

来自 pgfmanual:? x ? y : z和:是特殊运算符,可在解析器中用作 if x then y else z 的简写

相关内容