针对论坛上关于构造函数的问题,我尝试自己构造一些函数。我似乎无法让ifthenelse
TikZ/PGF 中的函数正常工作。以下是一个例子:
\documentclass[]{minimal}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\begin{document}
%this works
\pgfmathdeclarefunction{f}{0}{%
\pgfmathparse{x^2}%
}
%this does not work
\pgfmathdeclarefunction{g}{0}{%
\pgfmathparse{ifthenelse(x<0,-x^2,x^2)}%
}
\begin{tikzpicture}
\begin{axis}[every axis plot post/.append style={
mark=none,domain=-2:2,smooth},
axis x line*=bottom, axis y line*=left, enlargelimits=upper]
\addplot {f};
\addplot {g};
\end{axis}
\end{tikzpicture}
\end{document}
答案1
fpu
这是pgfplots 所使用的库的一个问题:该ifthenelse
命令未在 中实现fpu
,因此它会回退到正常的 pgfmath 例程,该例程随后会遇到参数的浮点格式问题,因为数字是以 形式处理的1Y1.0e0]
。
为了避免这种情况,fpu
可以使用以下方法在新定义的数学函数中禁用该库
\pgfkeys{/pgf/fpu=false}
但是,pgfplots 传递的 x 值仍然是浮点格式,因此必须将其转换为定点格式:
\pgfmathfloattofixed{\x}
\let\x=\pgfmathresult
如果fpu
库未激活,此操作将失败,因为\pgfmathfloattofixed{\x}
不知道如何处理定点数。因此我们需要使用 来\pgflibraryfpuifactive
测试是否fpu
处于活动状态,并且仅在处于活动状态时才转换数字。
现在 x 是一个正常的定点数,并且所有常见的 pgfmath 函数都应该可以工作。
但是,pgfmath 引擎的精度不如fpu
,因此可能不太适合回到它。
由于这ifthenelse
不是一个非常复杂的函数,我们可以自己定义它:
\pgfmathdeclarefunction{ifthenelsefpu}{3}{ %}
\pgfmathparse{#1*#2 + !#1*#3} %
}
可以像原始函数一样使用。
我已将这两种方法放入下面的示例文档中:
\documentclass{article}
\usepackage{pgfplots}
\pgfmathdeclarefunction{ifthenelsefpu}{3}{%
\pgfmathparse{#1*#2 + !#1*#3}%
}
\pgfmathdeclarefunction{f}{1}{%
\pgfmathparse{ifthenelsefpu(#1<0,#1^2,#1)}%
}
\pgfmathdeclarefunction{g}{1}{%
\pgflibraryfpuifactive{%
\pgfkeys{/pgf/fpu=false}%
\pgfmathfloattofixed{#1}%
\let\x=\pgfmathresult%
}%
{%
\pgfmathparse{#1}%
\let\x=\pgfmathresult%
}%
\pgfmathparse{ifthenelse(\x<0,(\x)^2,\x)}%
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[every axis plot post/.append style={
mark=none,domain=-3:3,smooth},
axis x line*=bottom, axis y line*=left, enlargelimits=upper]
\addplot {f(x+0.5)};
\addplot {g(x-1)};
\end{axis}
\end{tikzpicture}
%Code for showing that the functions work outside pgfplots
\pgfmathf{-3}\pgfmathresult
\pgfmathg{-3}\pgfmathresult
\end{document}