TikZで ifthenelse を用いて関数を定義するとき、
if の判定が false の場合も then 側の式が展開されますね。
たとえば
\begin{tikzpicture}[
declare function={
foo(\x)=(\x)^(10);
hoge(\x)=ifthenelse(\x<1,foo(\x),1);
hogeSAFE(\x)=ifthenelse(\x<1,foo(min(\x,1)),1);
}
]
\draw[domain=0:3,samples=40] plot (\x,{hoge(\x)});
\end{tikzpicture}
において、hoge(\x) をプロットしようとすると \x>1 のときにも
foo(\x) が計算されてしまうために dimension too large error
となります。このため hogeSAFE(\x) のようにする必要があるの
ですが、これでも無駄な計算が生じるのが気に入りません。
そこで質問なのですが、
(1) ifthenelse のこの仕様のメリットは何でしょうか?
(2) 無駄な計算の生じない書き方はありませんか?
(2)はもちろん区間別にプロットすればよいのですが、そんなコードが
大量にあると見づらくなるので、1つの関数として定義したいのです。
[(1)について]
“メリット”はやっぱり「実装が単純」であることでしょう。逆にいうと、「引数を先に評価しない」ifthenelseを実装するのは結構大変だと思われます。というのも
pgfmathでは常に「評価しながら構文解析する」戦略であるため、現存のコードだけでは「評価しないで構文解析だけする」ことができないため
だからです。なお「構文解析しないで安直に引数を読み飛ばす」ことができないのは次のような例を見ればわかるでしょう。
ifthenelse(\y>0,mod(\x,\y),0)
※余談ですが、expl3言語について今年頭に、「ブール式において、論理演算子(&&、||)の短絡評価を廃止する」という仕様変化が行われました。この理由も、「式を読み飛ばすのが困難」(つまり従来の実装はバグっていた)ということのようです。
[(2)について]
パッと思いつくのは、tikzmathを使うこと、ですね。
\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}[
declare function = {
foo(\x)=(\x)^(10);
},
evaluate = {
function hoge(\x) {
if \x < 1 then { return foo(\x); }
else { return 1; };
};
},
% pgfmathの関数(declare functionも含む)と
% tikzmathの関数は同じ名前空間にあるらしい
]
\draw[domain=0:3,samples=40] plot (\x,{hoge(\x)});
\end{tikzpicture}
\end{document}