当我发现一个简单的x^(1.0/3.0)
PGFplots 函数无法为 x 的负值生成图形时,我尝试使用pgfmathdeclarefunction
下面的方法为 CubeRoot 定义自己的函数。但是,我无法让它们工作。
\DomainMin
它可以按原样编译,但如果我将其设置为负值,就会出现问题。该CubeRootB
函数甚至无法编译,我看不出它有什么问题。
\documentclass{article}
\usepackage{tikz}
\newcommand*{\DomainMin}{0.1}
%\newcommand*{\DomainMin}{-2.0} % CubeRootA gives and error if DomainMin < 0
\tikzstyle{MyPlotStyle}=[domain=\DomainMin:2,samples=100,smooth]
\pgfmathdeclarefunction{gauss}{3}{% From links mentioned in the question
\pgfmathparse{1/(#3*sqrt(2*pi))*exp(-((#1-#2)^2)/(2*#3^2))}%
}
\pgfmathdeclarefunction{CubeRootA}{1}{%
\pgfmathparse{%
ifthenelse(equal(#1,abs(#1)),%
(#1)^(1.0/3.0),% #1 >= 0
-1.0*((abs(#1))^(1.0/3.0))% #1 is negative
)%
}%
}
\pgfmathdeclarefunction{CubeRootB}{1}{%
\pgfmathparse{%
\pgfmathifthenelse
{\pgfmathequal{#1}{\pgfmathabs{#1}}}%
{exp(ln(#1)/3.0)}% #1 >= 0
{-1.0*(exp(ln(abs(#1))/3.0))}% #1 is negative
}%
}
% Modified version of CubeRootB per Caramdir's suggestion
\pgfmathdeclarefunction{CubeRootC}{1}{%
\pgfmathparse{%
ifthenelse(
equal(#1,abs(#1)),%
exp(ln(#1)/3.0),% #1 >= 0
-1.0*(exp(ln(abs(#1))/3.0))% #1 is negative
)
}%
}
\begin{document}
\begin{tikzpicture}
\draw [help lines] (-2,-2) grid [step=0.5] (2,2);
\draw plot [MyPlotStyle] (\x,{gauss(\x,0,0.5)});
%
\draw plot [MyPlotStyle] (\x,{ CubeRootA(\x)});% Error if DomainMin < 0
%\draw plot [MyPlotStyle] (\x,{1.0+CubeRootB(\x)});% Does not compile
\draw plot [MyPlotStyle] (\x,{ CubeRootC(\x)});% Error if DomainMin < 0
\end{tikzpicture}
\end{document}
答案1
CubeRootC 的问题在于 pgf/tikz 处理 的方式ifthenelse
。我收到的错误消息表明,在处理 时ifthenelse(test,A,B)
,两个表达式A
和B
都被求值,因此只保留一个。由于两者都被求值,因此您会收到一条错误消息。我的示例设置方式可以避免这个问题。如果您想保留您的代码,只需在 true 子句中替换#1
即可 abs(#1)
。
这是我的代码版本。使用指数和对数函数是最好的方法。该pow
函数的行为与 pgf/tikz 手册中描述的不符。我移动了图以使它们不重叠。还请注意方法declare function
。我发现它更容易阅读;问题是它只局限于tikzpicture
。代码是
\documentclass{minimal}
\usepackage{tikz}
\pgfmathsetmacro{\inf}{-2}
\pgfmathsetmacro{\sup}{2}
\tikzstyle{MyPlotStyle}=[domain=\inf:\sup,samples=100,smooth]
\pgfmathdeclarefunction{CubeRootA}{1}{%
\pgfmathparse{ifthenelse(#1<0,-1,1)*exp((ln(abs(#1)))/3)}
}
\pgfmathdeclarefunction{CubeRootB}{1}{%
%\pgfmathparse{ifthenelse(#1<0,-1,1)*((abs(#1))^(1.0/3.0))}
\pgfmathparse{ifthenelse(#1<0,-1,1)*pow(abs(#1),1/3)}
}
\begin{document}
\begin{tikzpicture}
[declare function={ CubeRootC(\t)=ifthenelse(\t<0,-1,1)*exp((ln(abs(\t)))/3);}]
\draw [help lines] (-2,-2) grid [step=0.5] (2,2);
\draw[red] plot [MyPlotStyle] (\x,{CubeRootA(\x)});
\draw[blue,shift={(0,0.2)}] plot [MyPlotStyle] (\x,{CubeRootB(\x)});
\draw[green,shift={(0,-0.2)}] plot [MyPlotStyle] (\x,{CubeRootC(\x)});
\end{tikzpicture}
\end{document}
输出为
答案2
运行lualatex
\documentclass{article}
\def\cubicRoot#1{%
\directlua{%
tex.print(#1^(1/3))}}
\begin{document}
\cubicRoot{3}\par
\cubicRoot{-3}
\cubicRoot{3e-30}\par
\cubicRoot{-3e-30}
\cubicRoot{3e30}\par
\cubicRoot{-3e30}
\end{document}
以及完整情节的代码:
\documentclass{minimal}
\usepackage{tikz}
\def\cubicRoot#1{%
\directlua{%
tex.print(#1^(1/3))}}
\tikzstyle{MyPlotStyle}=[domain=-2:2,samples=100,smooth]
\begin{document}
\begin{tikzpicture}
\draw [help lines] (-2,-2) grid [step=0.5] (2,2);
\draw[red] plot [MyPlotStyle] (\x,\cubicRoot{\x});
\draw[blue,shift={(0,0.2)}] plot [MyPlotStyle] (\x,\cubicRoot{\x});
\draw[green,shift={(0,-0.2)}] plot [MyPlotStyle] (\x,\cubicRoot{\x});
\end{tikzpicture}
\end{document}
答案3
这里有一个解决方法,利用了\sqrt[3]{x}
x^3 的反函数:有点不方便,但效果很好。请注意,域实际上是范围,因为我已经切换了 x 和 y 值。
\begin{tikzpicture}[xscale=.2,yscale=.5]
\draw[xstep=1, ystep=1, gray, very thin, dotted] (-30,-4) grid (30,4);
\draw[<->] (0,-4) -- (0,4) node[above]{$y$};
\draw[->] (-30,0) -- (30,0) node[right]{$x$};
\foreach \x in {-25,5,25} \draw(\x,1pt)--(\x,-1pt) node[below=2pt,fill=white]{\begin{tiny}$\x$\end{tiny}};
\foreach \y in {2} \draw(1pt,\y)--(-1pt,\y) node[left=2pt,fill=white]{\begin{tiny}$\y$\end{tiny}};
\draw[domain=-3.1:3.1,<->] plot ({\x^(3)},\x) node[right]{$cubert(x) = \sqrt[3]{x}$};
\draw[fill=black] (0,0) circle (2pt) node[below=10pt,right=2pt]{(0,0)};
\draw[fill=black] (1,1) circle (2pt) node[left]{(1,1)};
\draw[fill=black] (8,2) circle (2pt) node[below]{(8,2)};
\draw[fill=black] (27,3) circle (2pt) node[below]{(27,3)};
\draw[fill=black] (-1,-1) circle (2pt) node[left]{(-1,-1)};
\draw[fill=black] (-8,-2) circle (2pt) node[below]{(-8,-2)};
\draw[fill=black] (-27,-3) circle (2pt) node[below]{(-27,-3)};
\end{tikzpicture}
答案4
这里有一些简单的代码!
\begin{tikzpicture}
\begin{axis}[axis lines=middle, axis line style={<->}, xmin=-10, xmax=10,ymin=-10, ymax=10, xtick = {-8,-6,-4,-2,0,2,4,6,8}, ytick = {-8,-6,-4,-2,0,2,4,6,8}, samples=200]
\addplot[domain=0:10, thick,->] {x^(1/3)};
\addplot[domain=-10:0, thick,<-] {-(abs(x)^(1/3))};
\end{axis}
\end{tikzpicture}