% Copyright 2019 by Mark Wibrow
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Public License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.

% This file defines the mathematical functions and operators.
%
% Version 1.414213 29/9/2007

% veclen function adapted from ideas due to Rouben Rostamian.
%
% Calculate the Euclidean length of a 2D vector.
%
%
\pgfmathdeclarefunction{veclen}{2}{%
  \begingroup%
    \pgfmath@x#1pt\relax%
    \pgfmath@y#2pt\relax%
        \ifdim\pgfmath@x<0pt\relax%
            \pgfmath@x-\pgfmath@x%
        \fi%
        \ifdim\pgfmath@y<0pt\relax%
            \pgfmath@y-\pgfmath@y%
        \fi%
        \ifdim\pgfmath@x=0pt\relax%
            \pgfmath@x\pgfmath@y%
        \else%
            \ifdim\pgfmath@y=0pt\relax%
            \else%
                \ifdim\pgfmath@x>\pgfmath@y%
                    \pgfmath@xa\pgfmath@x%
                    \pgfmath@x\pgfmath@y%
                    \pgfmath@y\pgfmath@xa%
                \fi%
                % We use a scaling factor to reduce errors.
                \ifdim\pgfmath@y>10000pt\relax%
                    \c@pgfmath@counta1500\relax%
                \else%
                    \ifdim\pgfmath@y>1000pt\relax%
                        \c@pgfmath@counta150\relax%
                    \else%
                        \ifdim\pgfmath@y>100pt\relax%
                            \c@pgfmath@counta50\relax%
                        \else%
                            \c@pgfmath@counta1\relax%
                        \fi%
                    \fi%
                \fi%
                \divide\pgfmath@x\c@pgfmath@counta\relax%
                \divide\pgfmath@y\c@pgfmath@counta\relax%
                \pgfmathreciprocal@{\pgfmath@tonumber{\pgfmath@y}}%
                \pgfmath@x\pgfmathresult\pgfmath@x%
                \pgfmath@xa\pgfmath@tonumber{\pgfmath@x}\pgfmath@x%
                \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@xa}}%
                %
                % Use A+x^2*(B+x^2*(C+x^2*(D+E*x^2)))
                % where
                % A = +1.000012594
                % B = +0.4993615349
                % C = -0.1195159052
                % D = +0.04453994279
                % E = -0.01019210944
                %
                \pgfmath@x-0.01019210944\pgfmath@xa%
                \advance\pgfmath@x0.04453994279pt\relax%
                \pgfmath@x\pgfmath@temp\pgfmath@x%
                \advance\pgfmath@x-0.1195159052pt\relax%
                \pgfmath@x\pgfmath@temp\pgfmath@x%
                \advance\pgfmath@x0.4993615349pt\relax%
                \pgfmath@x\pgfmath@temp\pgfmath@x%
                \advance\pgfmath@x1.000012594pt\relax%
                \ifdim\pgfmath@y<0pt\relax%
                    \pgfmath@y-\pgfmath@y%
                \fi%
                \pgfmath@x\pgfmath@tonumber{\pgfmath@y}\pgfmath@x%
                % Invert the scaling factor.
                \multiply\pgfmath@x\c@pgfmath@counta\relax%
            \fi%
        \fi%
        \pgfmath@returnone\pgfmath@x%
    \endgroup%
}

% Hyperbolic functions contributed by Martin Heller.
%
\pgfmathdeclarefunction{cosh}{1}{%
    \begingroup
        \edef\pgfmath@arg{#1}%
        \pgfmathexp@{\pgfmath@arg}%
        \pgfmath@x=\pgfmathresult pt\relax%
        \pgfmathexp@{-\pgfmath@arg}%
        \advance\pgfmath@x by\pgfmathresult pt\relax%
        \divide\pgfmath@x by2\relax%
        \pgfmath@returnone\pgfmath@x%
    \endgroup}

\pgfmathdeclarefunction{sinh}{1}{%
    \begingroup
        \edef\pgfmath@arg{#1}%
        \pgfmathexp@{\pgfmath@arg}%
        \pgfmath@x=\pgfmathresult pt\relax%
        \pgfmathexp@{-\pgfmath@arg}%
        \advance\pgfmath@x by-\pgfmathresult pt\relax%
        \divide\pgfmath@x by2\relax%
        \pgfmath@returnone\pgfmath@x%
    \endgroup
}%

\pgfmathdeclarefunction{tanh}{1}{%
    \begingroup
        \edef\pgfmath@arg{#1}%
        \pgfmathsinh@{\pgfmath@arg}%
        \pgfmath@x=\pgfmathresult pt\relax%
        \pgfmathcosh@{\pgfmath@arg}%
        \pgfmath@y=\pgfmathresult pt\relax%
        \pgfmathdivide@{\pgfmath@tonumber{\pgfmath@x}}{\pgfmath@tonumber{\pgfmath@y}}%
        \pgfmath@x=\pgfmathresult pt\relax%
        \pgfmath@returnone\pgfmath@x%
    \endgroup
}%

% \pgfmathscientific
%
% Return the value of #1e#2
%
% e.g. \pgfmathscientific{1.23456789123}{4}
%
% defines \pgfmathresult as 12345.67891
%
% NB These arguments *are not parsed*, as the long mantissa would be lost.
%
\def\pgfmathscientific#1#2{%
    \begingroup%
        \edef\pgfmath@sci@mantissa{#1}%
        \edef\pgfmath@sci@exponent{#2}%
        \expandafter\pgfmath@scientific@sign@mantissa\pgfmath@sci@mantissa\pgfmath@
        \expandafter\pgfmath@in@\expandafter.\expandafter{#1}%
        \ifpgfmath@in@%
        \else%
            \edef\pgfmath@sci@mantissa{\pgfmath@sci@mantissa.0}%
        \fi%
        \expandafter\pgfmath@scientific@@\pgfmath@sci@mantissa00000000000\pgfmath@}

\def\pgfmath@scientific@sign@mantissa#1\pgfmath@{%
    \c@pgfmath@counta=0
    \pgfmath@scientific@sign@mantissa@#1\pgfmath@
}
\def\pgfmath@scientific@sign@mantissa@#1{%
    \ifx\pgfmath@#1%
        \pgfmath@error{Missing number in input}% input was only signs or spaces
    \fi
    \ifx-#1%
        \advance\c@pgfmath@counta1
        \expandafter\pgfmath@gobbleone
    \else\ifx+#1%
        \expandafter\expandafter\expandafter\pgfmath@gobbleone
    \else
        \expandafter\expandafter\expandafter\pgfmath@scientific@sign@mantissa@end
    \fi\fi
    #1\pgfmath@scientific@sign@mantissa@
}
\def\pgfmath@scientific@sign@mantissa@end#1\pgfmath@scientific@sign@mantissa@#2\pgfmath@{%
    \edef\pgfmath@sci@sign{\ifodd\c@pgfmath@counta-\else+\fi}%
    \edef\pgfmath@sci@mantissa{#1#2}%
}

\def\pgfmath@scientific@@#1.#2#3#4#5#6{%
        \edef\pgfmath@sci@int{#1}%
        \edef\pgfmath@sci@mantissaA{#2#3#4#5#6}%
        \pgfmath@scientific@@@}

\def\pgfmath@scientific@@@#1#2#3#4#5#6\pgfmath@{%
        \edef\pgfmath@sci@mantissaB{#1#2#3#4#5}%
        \c@pgfmath@counta\pgfmath@sci@exponent\relax%
        \ifnum\c@pgfmath@counta<-9
            % 10^10 exceeds the range of a TeX count, and any value that
            % fits a \dimen rounds below 1sp once divided by it, so flush
            % such tiny numbers to zero.
            \pgfmath@x0pt
        \else%
            \c@pgfmath@countb\c@pgfmath@counta%
            \ifnum\c@pgfmath@counta<0\relax%
                \c@pgfmath@counta-\c@pgfmath@counta%
            \fi%
            % Calculating 10^|exponent| using \pgfmathpow@ would overflow already for
            % exponents of 5 or larger, because that exceeds \maxdimen.  We can work around
            % that to some extent by calculating 10^|exponent| by repeated multiplication of
            % 10 in a loop with a TeX count that has a larger range than a \dimen and allows
            % us to go all the way to 10^10.
            \begingroup
                \aftergroup\c@pgfmath@countc\aftergroup1%
                \pgfutil@loop\ifnum\c@pgfmath@counta>0
                    \aftergroup0%
                    \advance\c@pgfmath@counta-1
                \pgfutil@repeat
            \endgroup
            \relax
            \edef\pgfmath@sci@factor{\the\c@pgfmath@countc}%
            \pgfmath@xa0.\pgfmath@sci@mantissaA pt
            \c@pgfmath@countc\pgfmath@xa\relax
            \c@pgfmath@counta\pgfmath@sci@int\relax
            \ifnum\c@pgfmath@countb<0\relax%
                % xE-y: divide in scaled points (sp).  Forming the dividend in sp
                % instead of as the dimension \pgfmath@sci@int.\pgfmath@sci@mantissaA pt
                % avoids "Dimension too large" for integer parts up to 32767 and lets
                % us reapply the sign. The following code calculates:
                % x = sign * ((int * 65536 + round(mantissaA * 65536) / factor) sp
                \multiply\c@pgfmath@counta65536
                \advance\c@pgfmath@counta\c@pgfmath@countc\relax
                \divide\c@pgfmath@counta\pgfmath@sci@factor\relax
                \pgfmath@x\pgfmath@sci@sign\the\c@pgfmath@counta sp
            \else%
                % xE+y: in contrast to \dimen calculations that signal "Dimension
                % too large" the count multiplications below wrap silently on
                % 32-bit overflow, which for an out-of-range value could yield a
                % wrong, in-range-looking result.  So we first detect overflow by
                % checking that the mantissa does not exceed \maxdimen/factor (in
                % sp) and raise an error before performing the calculation.
                \c@pgfmath@countd\maxdimen
                \divide\c@pgfmath@countd\pgfmath@sci@factor\relax
                \ifnum\c@pgfmath@counta>16383
                    \pgfmath@error{You've asked me to compute %
                        `\pgfmath@sci@sign\pgfmath@sci@mantissa e\pgfmath@sci@exponent', %
                        but the result is too large}{}%
                    \pgfmath@x\pgfmath@sci@sign\maxdimen
                \else
                    \multiply\c@pgfmath@counta65536
                    \advance\c@pgfmath@counta\c@pgfmath@countc\relax
                    \ifnum\c@pgfmath@counta>\c@pgfmath@countd
                        \pgfmath@error{You've asked me to compute %
                            `\pgfmath@sci@sign\pgfmath@sci@mantissa e\pgfmath@sci@exponent', %
                            but the result is too large}{}%
                        \pgfmath@x\pgfmath@sci@sign\maxdimen
                    \else
                        % Must do this way so as not lose digits in a long mantissa. Sigh...
                        \c@pgfmath@counta\pgfmath@sci@int%
                        \c@pgfmath@countb\pgfmath@sci@mantissaA%
                        \multiply\c@pgfmath@counta\pgfmath@sci@factor\relax%
                        \multiply\c@pgfmath@countb\pgfmath@sci@factor\relax%
                        \c@pgfmath@countc\c@pgfmath@countb%
                        \divide\c@pgfmath@countb100000\relax%
                        \advance\c@pgfmath@counta\c@pgfmath@countb%
                        \multiply\c@pgfmath@countb100000\relax%
                        \advance\c@pgfmath@countc-\c@pgfmath@countb%
                        \c@pgfmath@countb\pgfmath@sci@mantissaB\relax%
                        \multiply\c@pgfmath@countb\pgfmath@sci@factor\relax%
                        \divide\c@pgfmath@countb100000\relax%
                        \advance\c@pgfmath@countc\c@pgfmath@countb%
                        \advance\c@pgfmath@countc100000\relax%
                        \edef\pgfmath@sci@result{\pgfmath@sci@sign\the\c@pgfmath@counta.\expandafter\pgfmath@gobbleone\the\c@pgfmath@countc pt}%
                        \pgfmath@x\pgfmath@sci@result\relax%
                    \fi
                \fi
            \fi
        \fi
        \pgfmath@returnone\pgfmath@x%
    \endgroup}



% width function.
%
\pgfmathdeclarefunction{width}{1}{%
    \begingroup%
        \setbox\pgfmath@box=\hbox{{\pgfmath@selectfont{#1}}}%
        \pgfmath@x=\wd\pgfmath@box%
        \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
        \pgfmath@smuggleone\pgfmathresult%
    \endgroup%
}


% height function.
%
\pgfmathdeclarefunction{height}{1}{%
    \begingroup%
        \setbox\pgfmath@box=\hbox{{\pgfmath@selectfont{#1}}}%
        \pgfmath@x=\ht\pgfmath@box%
        \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
        \pgfmath@smuggleone\pgfmathresult%
    \endgroup%
}

% depth function.
%
\pgfmathdeclarefunction{depth}{1}{%
    \begingroup%
        \setbox\pgfmath@box=\hbox{{\pgfmath@selectfont{#1}}}%
        \pgfmath@x=\dp\pgfmath@box%
        \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
        \pgfmath@smuggleone\pgfmathresult%
    \endgroup%
}


% array function.
%
\pgfmathdeclarefunction{array}{2}{%
    \begingroup%
        \afterassignment\pgfmath@gobbletilpgfmath@\pgfmath@count=#2\relax\pgfmath@%
        \expandafter\pgfmatharray@@#1\pgfmath@stop%
}

\def\pgfmath@token@stop{\pgfmath@stop}%
\def\pgfmatharray@@#1{%
    \def\pgfmath@temp{#1}%
    \advance\pgfmath@count by-1\relax%
    \ifx\pgfmath@temp\pgfmath@token@stop%
        \pgfmath@error{Array index out of bounds.}{}%
        \def\pgfmathresult{0}%
        \pgfmath@smuggleone\pgfmathresult\endgroup%
        \let\pgfmath@next=\relax%
    \else%
        \ifnum\pgfmath@count=-1\relax%
            \def\pgfmathresult{#1}%
            \let\pgfmath@next=\pgfmatharray@@@%
        \else%
            \let\pgfmath@next=\pgfmatharray@@%
        \fi%
    \fi%
    \pgfmath@next}

\def\pgfmatharray@@@#1\pgfmath@stop{%
    \pgfmath@smuggleone\pgfmathresult\endgroup%
}

% dim function: return dimension of an array
% dim({1,2,3}) return 3
% dim({{1,2,3},{4,5,6}}) return 2
\pgfmathdeclarefunction{dim}{1}{%
  \begingroup
    \pgfmath@count=0\relax
    \expandafter\pgfmath@dim@i\pgfutil@firstofone#1{\pgfmath@token@stop}%
    \edef\pgfmathresult{\the\pgfmath@count}%
    \pgfmath@smuggleone\pgfmathresult%
  \endgroup}

\def\pgfmath@dim@i#1#{%
  \pgfutil@ifempty{#1}{}{\advance\pgfmath@count by 1}%
  \pgfmath@dim@ii{#1}}

\def\pgfmath@dim@ii#1#2{%
  \ifx\pgfmath@token@stop#2%
  \else
    \advance\pgfmath@count by 1\relax
    \expandafter\pgfmath@dim@i
  \fi}


% max function.
%
\pgfmathdeclarefunction{max}{...}{%
    \begingroup%
        \pgfmath@x=-16383pt\relax%
        \pgfmathmax@@#1{}}

\def\pgfmathmax@@#1{%
    \def\pgfmath@temp{#1}%
    \ifx\pgfmath@temp\pgfmath@empty%
        \let\pgfmath@next=\pgfmathmax@@@%
    \else%
        \ifdim#1pt>\pgfmath@x%
            \pgfmath@x=#1pt\relax%
        \fi%
        \let\pgfmath@next=\pgfmathmax@@%
    \fi%
    \pgfmath@next}

\def\pgfmathmax@@@{\pgfmath@returnone\pgfmath@x\endgroup}%

% For computability with old code.
\def\pgfmathmax#1#2{%
    \pgfmathparse{#1,#2}%
    \expandafter\pgfmathmax@\expandafter{\pgfmathresult}%
}

% min function.
%
\pgfmathdeclarefunction{min}{...}{%
    \begingroup%
        \pgfmath@x=16383pt\relax%
        \pgfmathmin@@#1{}}

\def\pgfmathmin@@#1{%
    \def\pgfmath@temp{#1}%
    \ifx\pgfmath@temp\pgfmath@empty%
        \let\pgfmath@next=\pgfmathmin@@@%
    \else%
        \ifdim#1pt<\pgfmath@x%
            \pgfmath@x=#1pt\relax%
        \fi%
        \let\pgfmath@next=\pgfmathmin@@%
    \fi%
    \pgfmath@next}

\def\pgfmathmin@@@{\pgfmath@returnone\pgfmath@x\endgroup}%

% For computability with old code.
\def\pgfmathmin#1#2{%
    \pgfmathparse{#1,#2}%
    \expandafter\pgfmathmin@\expandafter{\pgfmathresult}%
}



% scalar function.
%
\pgfmathdeclarefunction{scalar}{1}{%
  \def\pgfmathresult{#1}%
  \global\pgfmathunitsdeclaredfalse%
}
