% Copyright 2007 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 adpated from ideas due to Rouben Rostamian.
%
% Calcluate the Eulidean 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@exponent{#2}%
		\pgfmath@x#1pt\relax%
		\ifdim\pgfmath@x<0pt\relax%
			\pgfmath@x-\pgfmath@x%
			\edef\pgfmath@sci@sign{-}%	
			\expandafter\edef\expandafter\pgfmath@temp\expandafter{\expandafter\pgfmath@gobbleone#1}%		
		\else%
			\edef\pgfmath@sci@sign{+}%
			\edef\pgfmath@temp{#1}%
		\fi%
		\expandafter\pgfmath@in@\expandafter.\expandafter{#1}%
		\ifpgfmath@in@%
		\else%
			\edef\pgfmath@temp{\pgfmath@temp.0}%
		\fi%
		\expandafter\pgfmath@scientific@@\pgfmath@temp00000000000\pgfmath@}

\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<-4\relax%
                  \pgfmath@x0pt\relax%
                \else%
		\c@pgfmath@countb\c@pgfmath@counta%
		\ifnum\c@pgfmath@counta<0\relax%
			\c@pgfmath@counta-\c@pgfmath@counta%
		\fi%
		\pgfmathpow@{10}{\the\c@pgfmath@counta}%
		\afterassignment\pgfmath@gobbletilpgfmath@
		\c@pgfmath@countc\pgfmathresult\relax\pgfmath@
		\edef\pgfmath@sci@factor{\the\c@pgfmath@countc}%
		\ifnum\c@pgfmath@countb<0\relax%
			% xE-y: easy...
			\pgfmath@x\pgfmath@sci@int.\pgfmath@sci@mantissaA pt\relax%
			\divide\pgfmath@x\pgfmath@sci@factor\relax%
		\else%
			% xE+y: 
			% 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%
		\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{%
    \ifx\pgfmath@token@stop#1%
    \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 compatability 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 compatability with old code.
\def\pgfmathmin#1#2{%
	\pgfmathparse{#1,#2}%
	\expandafter\pgfmathmin@\expandafter{\pgfmathresult}%
}

