diff options
author | Karl Berry <karl@freefriends.org> | 2010-01-03 01:14:11 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-01-03 01:14:11 +0000 |
commit | 98837e31bcd7413ffa40c85ebbce9aa3ff3fdbed (patch) | |
tree | 1ed7f18cb8a81bb3f209bf158a38f5b624c2d607 /Master/texmf-dist/tex/generic/pgfplots/liststructure/pgfplotsarray.code.tex | |
parent | 080069f58e2325db5ab0ac5f5ea584f3021bc383 (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.tex | 362 |
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}% } |