Связанный

Связанный

Построение графика с использованием pgfplotsфункции, определенной с использованием tikzmath functionсинтаксиса, похоже, не работает.

Сообщение об ошибке:

! Illegal unit of measure (pt inserted).
<to be read again> 
                   Y
l.30     \addplot {myAbsConditional(x)} ;

Dimensions can be in units of em, ex, in, pt, pc,
cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!
I'll assume that you meant to say pt, for printer's points.
To recover gracefully from this error, it's best to
delete the erroneous units; e.g., type `2' to delete
two letters. (See Chapter 27 of The TeXbook.)

! Missing = inserted for \ifdim.
<to be read again> 
                   Y
l.30     \addplot {myAbsConditional(x)} ;

I was expecting to see `<', `=', or `>'. Didn't.

Код :

\documentclass[tikz]{standalone}
\usetikzlibrary{math}
\usepackage{pgfplots}
\tikzmath
{
  function myAbs (\x) % this function can be plotted...
  {
    return (2 * (\x > 0) - 1 ) * \x;
  };
  function myAbsConditional(\x) % ... but not this one !
  {
    if (\x > 0) then
    {
      return \x;
    }
    else
    { 
      return -\x;
    };
  };
  % let's check that the function works :
  \a = myAbsConditional(-3);
  \b = myAbsConditional(2);
}
\begin{document}
\begin{tikzpicture}
  \begin{axis}
    %\addplot {myAbs(x)} ; % this is OK
    % the myAbsConditional function works all right ...
    \node {\a\b} ;                    
    \addplot {myAbsConditional(x)} ; % ... but cannot be plotted
  \end{axis}
\end{tikzpicture}
\end{document}

Это ошибка? Нужно ли модифицировать функцию с условием?

решение1

Это ошибка. При tikzmathразборе условия if используется следующий код

\def\tikz@math@if@@doif{%
  \pgfmathparse{\tikz@math@if@condition}%
  \ifdim\pgfmathresult pt=0pt\relax%
  \else%
      \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}%
  \fi%
  \tikz@math@parse%
}

Если вы знакомы с FPU, вы обнаружите, что код не работает, потому что \pgfmathresultis 1Y1.0e0]или что-то подобное.

Решение — принудительное преобразование при FPUвключении. Например, следующее

\def\tikz@math@if@@doif{%
    \pgfmathparse{\tikz@math@if@condition}%
    \ifpgfmathfloatparseactive%               <--- Notice this
        \pgfmathfloattofixed{\pgfmathresult}% <--- Notice this
    \fi%                                      <--- Notice this
    \ifdim\pgfmathresult pt=0pt\relax%
    \else%
        \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}%
    \fi%
    \tikz@math@parse%
}

Также нужно изменить и это.

\def\tikz@math@if@@doifelse{%
    \pgfmathparse{\tikz@math@if@condition}%
    \let\tikz@math@if@falseaction=\tikz@math@collected%
    \ifpgfmathfloatparseactive%               <--- Notice this
        \pgfmathfloattofixed{\pgfmathresult}% <--- Notice this
    \fi%                                      <--- Notice this
    \ifdim\pgfmathresult pt=0pt\relax%
        \expandafter\tikz@math\expandafter{\tikz@math@if@falseaction}%
    \else%
        \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}%
    \fi%
    \tikz@math@parse%
}

Связанный

Использование ifthenelse в pgfmathможет быть полезно.

Это больше не проблема, потому что ifthenelseтеперь это официально поддерживается. Тем не менее, идея та же самая.

MWE

\documentclass[tikz]{standalone}
\usetikzlibrary{math}
\usepackage{pgfplots}

\makeatletter
\def\tikz@math@if@@doif{%
    \pgfmathparse{\tikz@math@if@condition}%
    \ifpgfmathfloatparseactive%                 <--- Notice this
        \pgfmathfloattofixed{\pgfmathresult}%   <--- Notice this
    \fi%                                        <--- Notice this
    \ifdim\pgfmathresult pt=0pt\relax%
    \else%
        \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}%
    \fi%
    \tikz@math@parse%
}
\def\tikz@math@if@@doifelse{%
    \pgfmathparse{\tikz@math@if@condition}%
    \let\tikz@math@if@falseaction=\tikz@math@collected%
    \message{^^JCheck this: \pgfmathresult^^J}% <--- Notice this
    \ifpgfmathfloatparseactive%                 <--- Notice this
        \pgfmathfloattofixed{\pgfmathresult}%   <--- Notice this
    \fi%                                        <--- Notice this
    \message{^^JCheck again: \pgfmathresult^^J}%<--- Notice this
    \ifdim\pgfmathresult pt=0pt\relax%
        \expandafter\tikz@math\expandafter{\tikz@math@if@falseaction}%
    \else%
        \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}%
    \fi%
    \tikz@math@parse%
}

\tikzmath
{
  function myAbs (\x) % this function can be plotted...
  {
    return (2 * (\x > 0) - 1 ) * \x;
  };
  function myAbsConditional(\x) % ... but not this one !
  {
    if (\x > 0) then
    {
      return \x;
    }
    else
    { 
      return -\x;
    };
  };
  % let's check that the function works :
  \a = myAbsConditional(-3);
  \b = myAbsConditional(2);
}
\begin{document}

\begin{tikzpicture}
  \begin{axis}
    \addplot {myAbs(x)} ; % this is OK
    % the myAbsConditional function works all right ...
    \node {\a\b} ;                    
    \addplot {myAbsConditional(x)} ; % ... but cannot be plotted
  \end{axis}
\end{tikzpicture}
\end{document}

Связанный контент