summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-01-03 01:14:11 +0000
committerKarl Berry <karl@freefriends.org>2010-01-03 01:14:11 +0000
commit98837e31bcd7413ffa40c85ebbce9aa3ff3fdbed (patch)
tree1ed7f18cb8a81bb3f209bf158a38f5b624c2d607 /Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex
parent080069f58e2325db5ab0ac5f5ea584f3021bc383 (diff)
pgfplots 1.3 (2jan10)
git-svn-id: svn://tug.org/texlive/trunk@16576 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex')
-rw-r--r--Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex362
1 files changed, 345 insertions, 17 deletions
diff --git a/Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex b/Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex
index acc5ec7c53b..7464dc43876 100644
--- a/Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex
+++ b/Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex
@@ -7,13 +7,22 @@
%
% \pgfplotsarraynewempty
% \pgfplotsarraynew
+% \pgfplotsarrayresize
% \pgfplotsarraycopy
% \pgfplotsarraypushback
% \pgfplotsarraysize
% \pgfplotsarrayselect
+% \pgfplotsarrayset
% \pgfplotsarrayletentry
% \pgfplotsarraycheckempty
% \pgfplotsarrayforeach
+% \pgfplotsarraysort
+%
+% and a subset also for global arrays:
+% \pgfplotsarraynewemptyglobal
+% \pgfplotsarrayresizeglobal
+% \pgfplotsarraysetglobal
+% \pgfplotsarrayletentryglobal
%
% Copyright 2007/2008 by Christian Feuersänger.
%
@@ -38,9 +47,22 @@
\newif\ifpgfplotsarrayempty
% Creates a new, empty array.
-\long\def\pgfplotsarraynewempty#1{%
+\def\pgfplotsarraynewempty#1{%
\pgfplotsarray@@def{#1@size}{0}%
}
+\def\pgfplotsarraynewemptyglobal#1{%
+ \expandafter\gdef\csname\string#1@size\endcsname{0}%
+}
+
+% resizes (truncates) array #1 to size #2
+%
+% the elements won't be initialised. Use 'set' for each element.
+\def\pgfplotsarrayresize#1#2{%
+ \pgfplotsarray@@edef{#1@size}{#2}%
+}
+\def\pgfplotsarrayresizeglobal#1#2{%
+ \expandafter\xdef\csname\string#1@size\endcsname{#2}%
+}
% Invokes code '#2' if the array named '#1' exists and '#3' if it does
% not exist.
@@ -51,15 +73,30 @@
% Creates a new array with an abirtrary number of elements.
% Arguments:
% #1: the array's name (a macro name)
-% #2: the elements in the form
+% #2: the elements in one of the following forms
+% a) a '\\' terminated list:
% first\\second\\third\\ ...\\
-% like in tabular with one column.
+% like in tabular with one column. The final '\\' necessary!
+% b) a comma-separated list:
+% first,second,third,5,10,last
+% ATTENTION: arrays do not support the '...' syntax of tikz!
%
% Example:
% \pgfplotsarraynew\fooarray{First Element\\Second Element\\Third Element\\}
+% \pgfplotsarraynew\fooarray{First Element,Second Element,Third Element}
+% \pgfplotsarraynew\fooarray{0,1,2,...,10}
+%
%
-% WARNING: do NOT forget the final '\\'!
\long\def\pgfplotsarraynew#1#2{%
+ \pgfplots@check@backwards@compatible@list@format #2\\\pgfplots@EOI
+ \ifpgfplots@is@old@list@format
+ \pgfplotsarraynew@backslash{#1}{#2}%
+ \else
+ \pgfplotsarraynew@commasep{#1}{#2}%
+ \fi
+}
+
+\def\pgfplotsarraynew@backslash#1#2{%
\pgfplotsarraynewempty{#1}%
\long\def\pgfplotsarraynew@impl@rest{#2}%
\pgfutil@loop
@@ -71,8 +108,16 @@
\ifpgfplots@loop@CONTINUE
\expandafter\pgfplotsarraynew@impl\pgfplotsarraynew@impl@rest\toarray#1\relax
\pgfutil@repeat
-}
+}%
+% converts a comma-separated list (PGF foreach) to my internal list
+% structure.
+\long\def\pgfplotsarraynew@commasep#1#2{%
+ \pgfplotsarraynewempty{#1}%
+ \pgfplotsutilforeachcommasep{#2}\as\pgfplotsarraynew@elem{%
+ \expandafter\pgfplotsarraypushback\expandafter{\pgfplotsarraynew@elem}\to#1%
+ }%
+}
% helper macro for \pgfplotsarraynew
\long\def\pgfplotsarraynew@impl#1\\#2\toarray#3{%
\pgfplotsarraypushback#1\to#3\relax%
@@ -135,6 +180,9 @@
\expandafter\let\expandafter#2\csname\string#1@size\endcsname
}
+% expands to the size of array #1.
+\def\pgfplotsarraysizeof#1{\csname\string#1@size\endcsname}%
+
% Returns the #1th element of array #2 into macro #3
% Arguments:
@@ -148,14 +196,33 @@
% \elem
% Element \count1:
% \pgfplotsarrayselect\count1\of\foo\to\elem
-\long\def\pgfplotsarrayselect#1\of#2\to#3{%
+\def\pgfplotsarrayselect#1\of#2\to#3{%
\c@pgfplotsarray@tmp=#1\relax
- \expandafter\let\expandafter#3\expandafter=\csname\string#2@\the\c@pgfplotsarray@tmp\endcsname%
+ \expandafter\let\expandafter#3\csname\string#2@\the\c@pgfplotsarray@tmp\endcsname%
+}
+
+% Expands to the value at index #1 of array #2.
+% #1: a number (not a register)
+% #2: an array
+\def\pgfplotsarrayvalueofelem#1\of#2{\csname\string#2@#1\endcsname}%
+
+% Sets element '#1' of array '#2' to '#3'.
+\def\pgfplotsarrayset#1\of#2\to#3{%
+ \c@pgfplotsarray@tmp=#1\relax
+ \pgfutil@namedef{\string#2@\the\c@pgfplotsarray@tmp}{#3}%
+}
+\def\pgfplotsarraysetglobal#1\of#2\to#3{%
+ \c@pgfplotsarray@tmp=#1\relax
+ \expandafter\gdef\csname\string#2@\the\c@pgfplotsarray@tmp\endcsname{#3}%
}
\long\def\pgfplotsarrayletentry#1\of#2=#3{%
\c@pgfplotsarray@tmp=#1\relax
\expandafter\let\csname\string#2@\the\c@pgfplotsarray@tmp\endcsname=#3\relax
}
+\long\def\pgfplotsarrayletentryglobal#1\of#2=#3{%
+ \c@pgfplotsarray@tmp=#1\relax
+ \expandafter\global\expandafter\let\csname\string#2@\the\c@pgfplotsarray@tmp\endcsname=#3\relax
+}
% Sets the boolean \ifpgfplotsarrayempty depending on whether array #1 is empty
% or not.
@@ -185,27 +252,288 @@
% Element Zwei
% Element Drei
% Each single element will be grouped with TeX groups.
+%
+% During the loop, \pgfplotsarrayforeachindex expands to the current index.
\long\def\pgfplotsarrayforeach#1\as#2#3{%
\pgfplotsarray@@getsizeto{#1}{\pgfplotsarray@TMP}%
\c@pgfplotsarray@tmp=0\relax
+ \def\pgfplotsarrayforeachindex{\the\c@pgfplotsarray@tmp}%
+ \long\def\pgfplotsarray@TMPb{#3}%
\pgfutil@loop
- \ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP\relax
- \begingroup
- \expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname%
- #3%
- \endgroup
- \advance\c@pgfplotsarray@tmp by1
+ \ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP\relax
+ \begingroup
+ \expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname%
+ \pgfplotsarray@TMPb
+ \endgroup
+ \advance\c@pgfplotsarray@tmp by1
\pgfutil@repeat
+ \let\pgfplotsarrayforeachindex=\relax%
}
% The same but without groups around #3.
\long\def\pgfplotsarrayforeachungrouped#1\as#2#3{%
\pgfplotsarray@@getsizeto{#1}{\pgfplotsarray@TMP}%
\c@pgfplotsarray@tmp=0\relax
+ \def\pgfplotsarrayforeachindex{\the\c@pgfplotsarray@tmp}%
+ \long\def\pgfplotsarray@TMPb{#3}%
\pgfutil@loop
- \ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP\relax
- \expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname%
- #3%
- \advance\c@pgfplotsarray@tmp by1
+ \ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP\relax
+ \expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname%
+ \pgfplotsarray@TMPb
+ \advance\c@pgfplotsarray@tmp by1
\pgfutil@repeat
+ \let\pgfplotsarrayforeachindex=\relax%
+}
+
+\long\def\pgfplotsarrayforeachreversed#1\as#2#3{%
+ \pgfplotsarray@@getsizeto{#1}{\pgfplotsarray@TMP}%
+ \c@pgfplotsarray@tmp=\pgfplotsarray@TMP\relax
+ \def\pgfplotsarrayforeachindex{\the\c@pgfplotsarray@tmp}%
+ \long\def\pgfplotsarray@TMPb{#3}%
+ \pgfutil@loop
+ \ifnum\c@pgfplotsarray@tmp>0 %
+ \advance\c@pgfplotsarray@tmp by-1
+ \begingroup
+ \expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname%
+ \pgfplotsarray@TMPb
+ \endgroup
+ \pgfutil@repeat
+ \let\pgfplotsarrayforeachindex=\relax%
+}
+
+\long\def\pgfplotsarrayforeachreversedungrouped#1\as#2#3{%
+ \pgfplotsarray@@getsizeto{#1}{\pgfplotsarray@TMP}%
+ \c@pgfplotsarray@tmp=\pgfplotsarray@TMP\relax
+ \def\pgfplotsarrayforeachindex{\the\c@pgfplotsarray@tmp}%
+ \long\def\pgfplotsarray@TMPb{#3}%
+ \pgfutil@loop
+ \ifnum\c@pgfplotsarray@tmp>0 %
+ \advance\c@pgfplotsarray@tmp by-1
+ \expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname%
+ \pgfplotsarray@TMPb
+ \pgfutil@repeat
+ \let\pgfplotsarrayforeachindex=\relax%
+}
+
+% #1: arg1 (possibly not fully expanded)
+% #2: arg2 (possibly not fully expanded)
+% #3: code to invoke in case arg1<arg2
+% #4: code to invoke in case arg1>=arg2
+\pgfkeys{%
+ /pgfplots/array/iflessthan/.code args={#1#2#3#4}{\ifnum#1<#2\relax#3\else#4\fi},%
+ /pgfplots/array/unscope pre/.code={%
+ % That's more or less efficient (although some runtime factors
+ % could be saved).
+ \c@pgfplotsarraysort@i=0
+ \c@pgfplotsarray@tmp=\pgfplotsarraysizeof{#1}\relax
+ \pgfutil@loop
+ \ifnum\c@pgfplotsarraysort@i<\c@pgfplotsarray@tmp
+ \pgfplotsarrayselect{\c@pgfplotsarraysort@i}\of{#1}\to\pgfplots@loc@TMPa
+ \pgfplotsarrayletentryglobal\c@pgfplotsarraysort@i\of{pgfparraytmp}=\pgfplots@loc@TMPa
+ \advance\c@pgfplotsarraysort@i by1
+ \pgfutil@repeat
+ },%
+ /pgfplots/array/unscope post/.code={%
+ % copy from global temp -> #1
+ \c@pgfplotsarray@tmp=0
+ \pgfplotsarraysizetomacro{#1}\to\pgfplots@loc@TMPb
+ \pgfutil@loop
+ \ifnum\c@pgfplotsarray@tmp<\pgfplots@loc@TMPb
+ \pgfplotsarrayselect{\c@pgfplotsarray@tmp}\of{pgfparraytmp}\to\pgfplots@loc@TMPa
+ \pgfplotsarrayletentry\c@pgfplotsarray@tmp\of{#1}=\pgfplots@loc@TMPa
+ \advance\c@pgfplotsarray@tmp by1
+ \pgfutil@repeat
+ },%
+}%
+
+% Sorts array '#1' using N log N time.
+%
+% The sort key is provided as argument in
+% /pgfplots/array/iflessthan/.code args={#1#2#3#4}, see above.
+%
+% Remarks:
+% - the sorting algorithm is a sub-optimal mergesort currently -
+% but it has runtime N log N.
+% - As usual, it is very difficult to move the final result out of the
+% current scope. The initial configuration allocates a *global* copy of #1
+% to carry results out of one TeX group. This means that memory will NEVER be freed.
+% I don't see a general N log N alternative for doing so (short of discarding
+% the scopes for local groups).
+% BUT:
+% you can redefine the code key pair
+% |/pgfplots/array/unscope pre|
+% and
+% |/pgfplots/array/unscope post|
+% to define your own routine which may benefit from special needs of
+% your application. The |... pre| command is invoked JUST before the
+% \endgroup and the |... post| JUST after the |\endgroup|.
+%
+%
+% EXAMPLE:
+%--------------------------------------------------
+% \pgfplotsarraynewempty\testarray
+% \pgfplotsarraypushback503\to\testarray
+% \pgfplotsarraypushback087\to\testarray
+% \pgfplotsarraypushback512\to\testarray
+% \pgfplotsarraypushback061\to\testarray
+% \pgfplotsarraypushback908\to\testarray
+% \pgfplotsarraypushback170\to\testarray
+% \pgfplotsarraypushback897\to\testarray
+% \pgfplotsarraypushback275\to\testarray
+% \pgfplotsarraypushback653\to\testarray
+% \pgfplotsarraypushback426\to\testarray
+% \pgfplotsarraypushback154\to\testarray
+% \pgfplotsarraypushback509\to\testarray
+% \pgfplotsarraypushback612\to\testarray
+% \pgfplotsarraypushback677\to\testarray
+% \pgfplotsarraypushback765\to\testarray
+% \pgfplotsarraypushback703\to\testarray
+%
+% Unsorted:
+%
+% [\pgfplotsarrayforeach\testarray\as\elem{\elem\space}]
+%
+% \pgfplotsarraysort\testarray
+%
+% sorted:
+%
+% [\pgfplotsarrayforeach\testarray\as\elem{\elem\space}]
+%
+%--------------------------------------------------
+\def\pgfplotsarraysort#1{%
+ % I admit, the implementation is more-or less copy-paste of an
+ % experiment I had done at university. It does its job, but it is
+ % certainly not optimal.
+ \begingroup
+ \pgfkeysgetvalue{/pgfplots/array/iflessthan/.@cmd}\pgfplotsarraysort@iflt
+ \pgfplotsarraysize{#1}\to\c@pgfplotsarray@tmp
+ \pgfplotsarrayresizeglobal{pgfparraytmp}{\the\c@pgfplotsarray@tmp}%
+ \countdef\c@pgfplotsarraysort@m=0
+ \countdef\c@pgfplotsarraysort@k=1
+ \countdef\c@pgfplotsarraysort@i=2
+ \countdef\c@pgfplotsarraysort@l=3
+ \countdef\c@pgfplotsarraysort@j=4
+ \countdef\c@pgfplotsarraysort@q=5
+ \def\pgfplotsarray@mergesort@{\pgfplotsarray@mergesort{#1}}%
+ \def\pgfplotsarray@mergesort@recurse@{\pgfplotsarray@mergesort@recurse{#1}}%
+ \edef\pgfplotsarray@mergesort@@{{0}{\the\c@pgfplotsarray@tmp}}%
+ \expandafter\pgfplotsarray@mergesort@\pgfplotsarray@mergesort@@
+ %
+ % copy the complete, sorted result outside of the current scope.
+ \pgfkeysvalueof{/pgfplots/array/unscope pre/.@cmd}#1\pgfeov
+ \endgroup
+ \pgfkeysvalueof{/pgfplots/array/unscope post/.@cmd}#1\pgfeov
+}%
+
+% #1: array name,
+% #2: start offset (as string number)
+% #3: number of elems (as string number)
+\def\pgfplotsarray@mergesort#1#2#3{%
+ \ifnum#3<2
+ % ready!
+ \else
+ \c@pgfplotsarraysort@m=#3\relax
+ \divide\c@pgfplotsarraysort@m by2
+ \c@pgfplotsarraysort@q=#3\relax
+ \advance\c@pgfplotsarraysort@q by-\c@pgfplotsarraysort@m
+ \c@pgfplotsarraysort@i=\c@pgfplotsarraysort@m
+ \advance\c@pgfplotsarraysort@i by#2\relax
+ \edef\pgfplotsarray@mergesort@@{%
+ {#2}{\the\c@pgfplotsarraysort@m}% start1, N_1
+ {\the\c@pgfplotsarraysort@i}{\the\c@pgfplotsarraysort@q}% start2, N_2
+ }%
+ \expandafter\pgfplotsarray@mergesort@recurse@\pgfplotsarray@mergesort@@
+ %
+ % Merge:
+ % restore 'm':
+ \c@pgfplotsarraysort@m=#3\relax
+ \divide\c@pgfplotsarraysort@m by2
+ \c@pgfplotsarraysort@q=#3
+ \advance\c@pgfplotsarraysort@q by-\c@pgfplotsarraysort@m
+ \c@pgfplotsarraysort@k=0
+ \c@pgfplotsarraysort@l=0
+ \c@pgfplotsarraysort@i=0
+ %
+ % direct comparisons for merge:
+ \pgfutil@loop
+ \pgfplots@loop@CONTINUEtrue
+ \ifnum\c@pgfplotsarraysort@k<\c@pgfplotsarraysort@m
+ \ifnum\c@pgfplotsarraysort@l<\c@pgfplotsarraysort@q
+ \else
+ \pgfplots@loop@CONTINUEfalse
+ \fi
+ \else
+ \pgfplots@loop@CONTINUEfalse
+ \fi
+ \ifpgfplots@loop@CONTINUE
+ \c@pgfplotsarraysort@j=\c@pgfplotsarraysort@m
+ \advance\c@pgfplotsarraysort@j by\c@pgfplotsarraysort@l
+ \advance\c@pgfplotsarraysort@j by#2
+ \pgfplotsarrayselect{\c@pgfplotsarraysort@j}\of{#1}\to\pgfplotsarray@x@mpl
+ \c@pgfplotsarraysort@j=\c@pgfplotsarraysort@k
+ \advance\c@pgfplotsarraysort@j by#2
+ \pgfplotsarrayselect{\c@pgfplotsarraysort@j}\of{#1}\to\pgfplotsarray@x@k
+ \pgfplotsarraysort@iflt
+ {\pgfplotsarray@x@mpl}%
+ {\pgfplotsarray@x@k}%
+ {% x[m+l] < x[k]
+ \pgfplotsarrayletentryglobal\c@pgfplotsarraysort@i\of{pgfparraytmp}=\pgfplotsarray@x@mpl
+ \advance\c@pgfplotsarraysort@i by1
+ \advance\c@pgfplotsarraysort@l by1
+ }%
+ {% x[k] <= x[m+l]
+ \pgfplotsarrayletentryglobal\c@pgfplotsarraysort@i\of{pgfparraytmp}=\pgfplotsarray@x@k
+ \advance\c@pgfplotsarraysort@i by1
+ \advance\c@pgfplotsarraysort@k by1
+ }%
+ \pgfeov
+ \pgfutil@repeat
+ %
+ % append:
+ \pgfutil@loop
+ \ifnum\c@pgfplotsarraysort@k<\c@pgfplotsarraysort@m
+ \c@pgfplotsarraysort@j=\c@pgfplotsarraysort@k
+ \advance\c@pgfplotsarraysort@j by#2
+ \pgfplotsarrayselect{\c@pgfplotsarraysort@j}\of{#1}\to\pgfplots@loc@TMPa
+ \pgfplotsarrayletentryglobal\c@pgfplotsarraysort@i\of{pgfparraytmp}=\pgfplots@loc@TMPa
+ \advance\c@pgfplotsarraysort@i by1
+ \advance\c@pgfplotsarraysort@k by1
+ \pgfutil@repeat
+ \pgfutil@loop
+ \ifnum\c@pgfplotsarraysort@l<\c@pgfplotsarraysort@q
+ \c@pgfplotsarraysort@j=\c@pgfplotsarraysort@m
+ \advance\c@pgfplotsarraysort@j by\c@pgfplotsarraysort@l
+ \advance\c@pgfplotsarraysort@j by#2
+ \pgfplotsarrayselect{\c@pgfplotsarraysort@j}\of{#1}\to\pgfplots@loc@TMPa
+ \pgfplotsarrayletentryglobal\c@pgfplotsarraysort@i\of{pgfparraytmp}=\pgfplots@loc@TMPa
+ \advance\c@pgfplotsarraysort@i by1
+ \advance\c@pgfplotsarraysort@l by1
+ \pgfutil@repeat
+ %
+ % copy back from temporary to '#1'
+ \c@pgfplotsarraysort@i=0
+ \c@pgfplotsarraysort@k=#3
+ \pgfutil@loop
+ \ifnum\c@pgfplotsarraysort@i<\c@pgfplotsarraysort@k
+ \c@pgfplotsarraysort@j=\c@pgfplotsarraysort@i
+ \advance\c@pgfplotsarraysort@j by#2
+ \pgfplotsarrayselect{\c@pgfplotsarraysort@i}\of{pgfparraytmp}\to\pgfplots@loc@TMPa
+ \pgfplotsarrayletentry\c@pgfplotsarraysort@j\of{#1}=\pgfplots@loc@TMPa
+ \advance\c@pgfplotsarraysort@i by1
+ \pgfutil@repeat
+%\pgfplotsarraysort@DEBUGTEST{#1}{after mergesort(start=#2,n=#3):}%
+ \fi
+}%
+\long\def\pgfplotsarraysort@DEBUGTEST#1#2{%
+ \par#2\par
+ [\pgfplotsarrayforeach{#1}\as\elem{\elem\space}]\par%
+}
+% #1: array name
+% #2: start1
+% #3: N1
+% #4: start2
+% #5: N2
+\def\pgfplotsarray@mergesort@recurse#1#2#3#4#5{%
+ \pgfplotsarray@mergesort{#1}{#2}{#3}%
+ \pgfplotsarray@mergesort{#1}{#4}{#5}%
}