summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty')
-rw-r--r--Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty443
1 files changed, 443 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty b/Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty
new file mode 100644
index 00000000000..acb02e3b143
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/pgfplots/pgfmathlog.sty
@@ -0,0 +1,443 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Package pgfmathlog.sty.
+%
+% This file provides the public functions
+%
+% \pgfmathnormalisedfloatingpoint#1\to#2\powten#3
+% like
+% \pgfmathnormalisedfloatingpoint 412.02451e-5to\M\powten\E
+%
+% and
+% \pgfmathlog
+% \pgfmathlog@
+% which both assign \pgfmathresult to the natural number of a given
+% number (without units).
+%
+% It is based on Till Tantaus pgfmath package which comes as part of
+% the PGF bundle, but it provides its own number parsing routines to
+% circumvent TeXs limited real number representations.
+%
+% Copyright 2007/2008 by Christian Feuersänger.
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\ProvidesPackage{pgfmathlog}[2008/26/01 Version 0.9.]
+\RequirePackage{pgf}[2007/01/01]
+
+% Computes a normalised floating point representation for #1 of the
+% form
+% [+-]X.XXXXXXX*10^C
+% where
+% X.XXXXXX is a mantisse with first number != 0
+% and C is a count.
+%
+% This method does NOT use TeX Registers to represent the numbers! The
+% computation is COMPLETELY STRING BASED.
+% This allows numbers such at 10000000 or 5.23e-10 to be represented
+% properly, although TeX-registers would produce overflow/underflow
+% errors in these cases.
+%
+% It is to be used to compute logs, because log(X*10^Y) = log(X) + log(10)*Y
+%
+% Arguments:
+% #1 a -possibly non-normalized- number representation. Accepted input
+% format is
+% [+-]XXXXX.XXXXXX
+% [+-]XXXXX.XXXXXXeXXXX
+% [+-]0.0000XXXXXX
+% [+-]0.0000XXXXXXeXXXX
+% NOT accepted input format is
+% [+-]XXXXX [the period is missing]
+% [+-]XXXXXe10 [the period is missing]
+% [+-]0000.XXXXXX [leading zeros not supported]
+% [+-]XXXXX.XXXXXXEXXXXX [E notation not yet implemented]
+% #2 a macro name. \def#2{.....} will be used to assign the mantisse.
+% #3 a macro name. \def#3{.....} will be used to assign the exponent (base 10).
+%
+% Example:
+% \def\normalize#1{%
+% \pgfmathnormalisedfloatingpoint#1\to\M\powten\E
+% \[ #1 \mapsto \M\cdot 10^{\E} \]
+% }
+% \normalize{123.41251}%
+% \normalize{3.26101452e-06}%
+\def\pgfmathnormalisedfloatingpoint#1\to#2\powten#3{%
+ \pgfmathnormalisedfloatingpoint@impl@possibly@signed#1\to#2\powten{#3}%
+}
+
+% first character MAY be + or -. This is checked, then
+% \pgfmathnormalisedfloatingpoint@impl@positive will be called for the
+% absolute value. The sign is inserted afterwards.
+\def\pgfmathnormalisedfloatingpoint@impl@possibly@signed#1#2\to#3\powten#4{%
+ \def\pgfmathlogTMP{#1}%
+ \def\pgfmathlogTMPB{-}%
+ \if\pgfmathlogTMP\pgfmathlogTMPB
+ \pgfmathnormalisedfloatingpoint@impl@positive@possibly@noperiod#2.\to#3\powten{#4}%
+ \edef#3{-#3}%
+ \else
+ \def\pgfmathlogTMPB{+}%
+ \if\pgfmathlogTMP\pgfmathlogTMPB
+ \pgfmathnormalisedfloatingpoint@impl@positive@possibly@noperiod#2.\to#3\powten{#4}%
+ \else
+ \pgfmathnormalisedfloatingpoint@impl@positive@possibly@noperiod#1#2.\to#3\powten{#4}%
+ \fi
+ \fi
+}
+
+% XXXX -> XXXX.0
+% XXXX.YYY -> XXXX.YYYY
+\def\pgfmathnormalisedfloatingpoint@impl@positive@possibly@noperiod#1.#2\to#3\powten#4{%
+ %\tracingmacros=2\tracingcommands=2
+ \def\pgfmathlogTMP{#2}%
+ \ifx\pgfmathlogTMP\empty
+ \pgfmathnormalisedfloatingpoint@impl@positive@noperiod@possibly@SCI#1e\to#3\powten{#4}%
+ \else
+ \expandafter\pgfmathnormalisedfloatingpoint@impl@positive\pgfmathlog@pop@last@of@two@dots#1.#2\to#3\powten{#4}%
+ \fi
+}
+\def\pgfmathlog@pop@last@of@two@dots#1.#2.{#1.#2}%
+
+\def\pgfmathnormalisedfloatingpoint@impl@positive@noperiod@possibly@SCI#1e#2\to#3\powten#4{%
+ \def\pgfmathlogTMP{#2}%
+ \ifx\pgfmathlogTMP\empty
+ % this case applies to
+ % 1234 -> 1234.0
+ \pgfmathnormalisedfloatingpoint@impl@positive#1.0\to#3\powten{#4}%
+ \else
+ % this case applies to
+ % 1e1 -> 1.0e1
+ % in this case, #1e#2 = 1e1e, so we have to discard a suffix 'e'.
+ \edef\pgfmathlogTMP{#1.0e\pgfmathlog@popsuffix@e@expansion#2}%
+ \expandafter\pgfmathnormalisedfloatingpoint@impl@positive\pgfmathlogTMP\to#3\powten{#4}%
+ \fi
+}
+
+% XXXXX.XXXXX -> X.XXXXXXX * 10^4
+% 0.0000XXXXX -> X.XXXX * 10^{-5}
+%
+% or
+% XXXX.XXXXXeYYY -> X.XXXXXX* 10^{3+YYY}
+% 0.0000XXXXeYYY -> X.XXX* 10^{-5+YYY}
+%
+% this version does not accept a sign. A period is required.
+\def\pgfmathnormalisedfloatingpoint@impl@positive#1#2.#3\to#4\powten#5{%
+% \begingroup
+% FIXME! restore variables!!
+ %\tracingmacros=2\tracingcommands=2
+ %\tracingmacros=0\tracingcommands=0
+ \pgfmathnormalisedfloatingpoint@positive@getexisting@exponent@e#3e\preexponentto\preexponentstring\exponenttocount\c@pgf@counta
+ % will \c@pgf@counta will be initialised in the line above
+ % \c@pgf@counta=0
+ \ifnum#1=0
+ % the case 0.0000XXXX
+ % does also handle 0.0000XXXXeXXX
+ \def\pgfmathlogTMP{#2}%
+ \ifx\pgfmathlogTMP\empty
+ \c@pgf@countb=0
+ \expandafter\pgfmathlog@count@leading@zeros\preexponentstring\to\c@pgf@countb
+ \advance\c@pgf@countb by1
+ \advance\c@pgf@counta by-\c@pgf@countb
+ \edef#5{\the\c@pgf@counta}%
+ \expandafter\pgfmathlog@assignmantisse\preexponentstring\to#4\countdownzerosfrom\c@pgf@countb
+ \else
+ % the case 000.0000XXXXX
+ % is not allowed and does not make sense.
+ \errmessage{INVALID NUMBER FORMAT: leading zeros 00*.* not supported yet}%
+ \fi
+ \else
+ % the case NXXXXX.XXXXXXX
+ % or NXXXXXX.XXXXXXeXXXX
+ % where N in [1-9]
+ \pgfmathlog@strlen#1#2\to\c@pgf@counta
+ \advance\c@pgf@counta by-1
+ \edef#4{#1.#2\preexponentstring}%
+ \edef#5{\the\c@pgf@counta}%
+ \fi
+ %\tracingmacros=0\tracingcommands=0
+% \endgroup
+}
+
+% parses scientific notation and returns the exponent and everything
+% before the exponent like
+%
+% XXXXXXXeYYYY -> \def#2{XXXXXXX} #3=YYYY
+% or
+% XXXXXXXXe -> \def#2{XXXXXXXX} #3=0
+%
+% Examples:
+% - \pgfmathnormalisedfloatingpoint@exponent@e123456e\preexponentto\M\exponenttocount\acount
+% \M->123456
+% \acount=0
+% Please note that the input was 123456e -> at least 'e' is expected!
+%
+% - \pgfmathnormalisedfloatingpoint@exponent@e123456e-10e\preexponentto\M\exponenttocount\acount
+% \M->123456
+% \acount=-10
+% Again, the suffix 'e' is REQUIRED. This allows to reduce \ifs.
+\def\pgfmathnormalisedfloatingpoint@positive@getexisting@exponent@e#1e#2\preexponentto#3\exponenttocount#4{%
+ \def#3{#1}%
+ \def\pgfmathlogTMP{#2}%
+ \ifx\pgfmathlogTMP\empty
+ #4=0
+ \else
+ \pgfmathlog@popsuffix@e#2\tocount{#4}%
+ \fi
+}
+
+% XXXXXe -> #2=XXXXX where X in [+-0-9].
+\def\pgfmathlog@popsuffix@e#1e\tocount#2{%
+ #2=#1
+}
+
+\def\pgfmathlog@popsuffix@e@expansion#1e{%
+ #1%
+}%
+
+% 00000XXXXXX -> X.XXXXX
+% Inputs:
+% #1 = 00000XXXXXX
+% #2 a macro name
+% #3 a count in which the number of zeros plus one is contained (i.e.
+% the number of shifts).
+\def\pgfmathlog@assignmantisse#1\to#2\countdownzerosfrom#3{%
+ \toks0={#1}%
+ \loop
+ \ifnum#3=1
+ \else
+ \expandafter\pgfmathlog@popfirst\the\toks0\to{\toks0}%
+ \advance#3 by-1
+ \repeat
+ \edef\pgfmathlog@assignmantisseTMP{\the\toks0}%
+ \ifx\pgfmathlog@assignmantisseTMP\empty
+ % The case 0.0 * 10^0
+ \def#2{0.0}%
+ \else
+ \expandafter\pgfmathlog@insertperiod\the\toks0\to{#2}%
+ \fi
+}
+
+% XXXXXX -> X.XXXXX into #3
+\def\pgfmathlog@insertperiod#1#2\to#3{%
+ \def\pgfmathlogTMP{#2}%
+ \ifx\pgfmathlogTMP\empty
+ \def#3{#1.0}%
+ \else
+ \def#3{#1.#2}%
+ \fi
+}
+
+% discards the first token.
+\def\pgfmathlog@popfirst#1#2\to#3{%
+ #3={#2}%
+}
+
+% adds the string length of #1#2 into the count register #3.
+%
+% The register won't be initialised to zero!
+\def\pgfmathlog@strlen#1#2\to#3{%
+ \advance#3 by1
+ \def\pgfmathlogTMP{#2}%
+ \ifx\pgfmathlogTMP\empty
+ \else
+ \pgfmathlog@strlen#2\to{#3}%
+ \fi
+}
+
+% Adds the number of leadings zeros of #1#2 into the count register
+% #3.
+%
+% The register won't be initialised to zero!
+\def\pgfmathlog@count@leading@zeros#1#2\to#3{%
+ \ifnum#1=0
+ \advance#3 by1
+ \def\pgfmathlogTMP{#2}%
+ \ifx\pgfmathlogTMP\empty
+ \else
+ \pgfmathlog@count@leading@zeros#2\to{#3}%
+ \fi
+ \fi
+}
+
+% Evaluates the natural logarithm, log(x) for 0.1<=x<=1.
+% @see \pgfmathlog@ for the general method.
+% NON ACCURATE ENOUGH!
+\def\pgfmathlogzeroone#1{%
+ \begingroup%
+ \message{EVAL log(#1) STARTS:}%
+ \pgfmath@x=#1pt\relax
+ \pgfmath@y=\pgfmath@x
+ \advance\pgfmath@x by-1pt
+ \advance\pgfmath@y by 1pt
+ \pgfmathdivide{\pgfmath@x}{\pgfmath@y}%
+ % pgfmath@ya = tmp := (#1 -1)/ (#1+1)
+ \expandafter\pgfmath@ya\pgfmathresult pt
+ % pgfmath@xa := [ (#1 -1)/ (#1+1) ]^2
+ \pgfmathmultiply{\pgfmathresult}{\pgfmathresult}%
+ \expandafter\pgfmath@xa\pgfmathresult pt
+ % returnvalue:
+ \pgfmath@y=0pt
+ % loop counter:
+ \c@pgfmath@counta=0
+ % j:
+ \c@pgfmath@countb=1
+ \loop
+ \ifnum\c@pgfmath@counta<6
+ \let\multmp=\pgfmath@ya
+ \divide\pgfmath@ya by\c@pgfmath@countb
+ \advance\pgfmath@y by\pgfmath@ya
+ \let\pgfmath@ya=\multmp
+ \advance\c@pgfmath@countb by2
+ \message{[tmp *= x*x tmp =\the\pgfmath@ya, x*x=\the\pgfmath@xa]}%
+ \pgfmathmultiply{\pgfmath@ya}{\pgfmath@xa}%
+ \expandafter\pgfmath@ya\pgfmathresult pt
+ \advance\c@pgfmath@counta by1
+ \message{[cur/2 = \the\pgfmath@y]}%
+ \repeat
+ \multiply\pgfmath@y by2
+ \message{fertiges Resultat fuer log(#1): \the\pgfmath@y}%
+ \pgfmath@returnone\pgfmath@y%
+ \endgroup%
+}
+
+
+% Computes a good guess for log(X.XXXX) where the input number should
+% be between 0 < x < 10.
+%
+% If it is not in this range, the returned value will be bad.
+%
+% For use in the newton implementation of log(x). Please note that we
+% first compute a normalized floating point representation of x, and
+% the mantisse is always between 0 and 10.
+\def\pgfmathlog@smaller@ten@newton@startval#1#2#3\to#4{%
+ \ifnum0<#1\relax
+ \def\axis@TMP{#2}%
+ \def\axis@TMPB{.}%
+ \ifx\axis@TMP\axis@TMPB
+ \ifcase#1
+ \errmessage{pgfmathlog.sty: INTERNAL ERROR: should not happen!
+ [\#1=0 should have been caught before!]}%
+ \or#4=0.53062825106217pt
+ \or#4=0.993pt
+ \or#4=1.308pt
+ \or#4=1.5pt
+ \or#4=1.71pt
+ \or#4=1.872pt
+ \or#4=2.01pt
+ \or#4=2.145pt
+ \or#4=2.24pt
+ \fi
+% \message{Newton: Start value \the#4 assigned}%
+ \else
+% \message{Kein Komma an zweiter stelle (statt dessen: #2); Nehme standardstartwert.}%
+ #4=0.1pt
+ \fi
+ \else
+% \message{Argument #1 <= 0. Nehme standardstartwert.}%
+ #4=0.1pt
+ \fi
+}
+
+% Computes log(x) into \pgfmathresult.
+%
+% REMARK
+% This method does NOT use TeX Registers to represent the numbers! The
+% computation is COMPLETELY STRING BASED.
+% This allows numbers such at 10000000 or 5.23e-10 to be represented
+% properly, although TeX-registers would produce overflow/underflow
+% errors in these cases.
+%
+% The natural logarithm is computed using log(X*10^Y) = log(X) + log(10)*Y
+\def\pgfmathlog@#1{%
+ \pgfmathlog@newton{#1}%
+}
+
+% Public interface method. This is expected to use \pgfmathparse but
+% it DOESN'T do that. \pgfmathparse naturally can't handle numbers
+% which exceed TeX's numerical capabilities. However, exponentials are
+% typically either too large or too small for TeX.
+%
+% @see \pgfmathnormalisedfloatingpoint for how we parse arguments.
+% @see \pgfmathlog@
+\def\pgfmathlog#1{%
+ \pgfmathlog@newton{#1}%
+}
+
+\def\pgfmathlog@tonumber#1pt{#1}
+
+% Invokes command #1 with #2 without the 'pt' suffix.
+\def\invokepgf@math@one#1#2{%
+ %\edef\pgfmath@resulttemp{\pgf@sys@tonumber{#2}}%
+ %\expandafter#1\expandafter{\pgfmath@resulttemp}%
+ \edef\pgfmath@resulttemp{{\pgf@sys@tonumber{#2}}}%
+ \expandafter#1\pgfmath@resulttemp%
+}
+
+% Expands #2 using \edef and invokes #1 with the resulting string.
+%
+% Example:
+% \pgfmath@y=7.9pt
+% \pgfmathlog@invoke@expanded\pgfmathexp@{{\pgf@sys@tonumber{\pgfmath@y}}}%
+% will invoke
+% \pgfmathexp@{7.9}
+\def\pgfmathlog@invoke@expanded#1#2{%
+ \edef\pgfmath@resulttemp{#2}%
+ \expandafter#1\pgfmath@resulttemp
+}
+
+% This implementation of log(X) is done with a newton method applied to x-exp(y) = 0.
+% The implementation \pgfmathexp is used for exp(y).
+%
+% see \pgfmathlog@
+\def\pgfmathlog@newton#1{%
+ \begingroup%
+ % compute #1 = M*10^E with normalised mantisse M = [+-]*[1-9].XXXXX
+ \pgfmathnormalisedfloatingpoint#1\to\newtoninput@mantisse\powten\newtoninput@exponent
+ %
+ % Now, compute log(#1) = log(M) + E*log(10)
+% \message{EVAL log(#1) = log(\newtoninput@mantisse) + \newtoninput@exponent*log(10) mit newton STARTS:}%
+ % input argument into \pgfmath@x
+ \expandafter\pgfmath@x\newtoninput@mantisse pt
+ \ifdim\pgfmath@x>0pt
+ % return value:
+ \expandafter\pgfmathlog@smaller@ten@newton@startval\newtoninput@mantisse\to\pgfmath@y
+ % loop counter:
+ \c@pgfmath@counta=0
+ \loop
+ %\message{Newton iter \#\the\c@pgfmath@counta: log(\newtoninput@mantisse) = \the\pgfmath@y }%
+ \ifnum\c@pgfmath@counta<2
+ % \pgfmathexp\pgfmath@y%
+ \pgfmathlog@invoke@expanded\pgfmathexp@{{\pgf@sys@tonumber{\pgfmath@y}}}%
+ \let\tmp=\pgfmathresult
+ %\pgfmathdivide\pgfmath@x\tmp%
+ \pgfmathlog@invoke@expanded\pgfmathdivide@{{\pgf@sys@tonumber{\pgfmath@x}}{\tmp}}%
+ \expandafter\pgfmath@ya\pgfmathresult pt
+ \advance\pgfmath@y by\pgfmath@ya
+ \advance\pgfmath@y by-1pt
+ \advance\c@pgfmath@counta by1
+ \repeat
+ \pgfmath@x=2.302585pt% = log(10)
+ \multiply\expandafter\pgfmath@x\newtoninput@exponent
+ \advance\pgfmath@y by\pgfmath@x
+%\message{Newton final result: log(\newtoninput@mantisse)+\newtoninput@exponent*log(10) = \the\pgfmath@y [ nur \newtoninput@exponent * log(10) = \the\pgfmath@x]}%
+ \pgfmath@returnone\pgfmath@y%
+ \else
+ \global\let\pgfmathresult=\empty%
+ \fi
+ \endgroup%
+}
+