%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This is a helper package with an elementary array datastructure, % featuring O(1) index access and O(N) creation, deletion, copy. % % The following macros are supplied: % % \pgfplotsarraynewempty % \pgfplotsarraynew % \pgfplotsarrayresize % \pgfplotsarraycopy % \pgfplotsarraypushback % \pgfplotsarraysize % \pgfplotsarrayselect % \pgfplotsarrayset % \pgfplotsarrayletentry % \pgfplotsarraycheckempty % \pgfplotsarrayforeach % \pgfplotsarraysort % \pgfplotsarraybinarysearch % % and a subset also for global arrays: % \pgfplotsarraynewemptyglobal % \pgfplotsarrayresizeglobal % \pgfplotsarraysetglobal % \pgfplotsarrayletentryglobal % % 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 . % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcount\c@pgfplotsarray@tmp \newif\ifpgfplotsarrayempty % Creates a new, empty array. \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{% \c@pgfplotsarray@tmp=#2 \pgfplotsarray@@edef{#1@size}{\the\c@pgfplotsarray@tmp}% } \def\pgfplotsarrayresizeglobal#1#2{% \c@pgfplotsarray@tmp=#2 \expandafter\xdef\csname\string#1@size\endcsname{\the\c@pgfplotsarray@tmp}% } % Invokes code '#2' if the array named '#1' exists and '#3' if it does % not exist. \def\pgfplotsarrayifdefined#1#2#3{% \pgfutil@ifundefined{#1@size}{#3}{#2}% }% % Creates a new array with an abirtrary number of elements. % Arguments: % #1: the array's name (a macro name) % #2: the elements in one of the following forms % a) a '\\' terminated list: % first\\second\\third\\ ...\\ % 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} % % \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 } % #1 the array's name (a macro name % #2 a list created by \pgfplotslistnew \def\pgfplotsarrayfrompgfplotslist#1#2{% \pgfplotsarraynewempty#1% \pgfplotslistforeachungrouped#2\as\pgfplotsarray@TMPa{% \expandafter\pgfplotsarraypushback\expandafter{\pgfplotsarray@TMPa}\to#1% }% }% \def\pgfplotsarraynew@backslash#1#2{% \pgfplotsarraynewempty{#1}% \long\def\pgfplotsarraynew@impl@rest{#2}% \pgfutil@loop \ifx\pgfplotsarraynew@impl@rest\pgfutil@empty \pgfplots@loop@CONTINUEfalse \else \pgfplots@loop@CONTINUEtrue \fi \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% \def\pgfplotsarraynew@impl@rest{#2}% } \def\pgfplotsarray@@let#1=#2{% \def\pgfplotsarray@TMP@@{\expandafter\let\csname\string#1\endcsname}% \expandafter\pgfplotsarray@TMP@@\csname\string#2\endcsname }% \def\pgfplotsarray@@#1#2{% \expandafter#1\csname\string#2\endcsname }% \def\pgfplotsarray@@def#1{% \expandafter\def\csname\string#1\endcsname }% \def\pgfplotsarray@@edef#1{% \expandafter\edef\csname\string#1\endcsname }% \def\pgfplotsarray@@getsizeto#1#2{% \pgfplotsarraysize{#1}\to\c@pgfplotsarray@tmp \edef#2{\the\c@pgfplotsarray@tmp}% }% % Copies array #1 to array #2. \def\pgfplotsarraycopy#1\to#2{% \pgfplotsarray@@let{#2@size}={#1@size}% \pgfplotsarray@@getsizeto{#1}{\pgfplotsarray@TMP}% \c@pgfplotsarray@tmp=0 \pgfutil@loop \ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP \pgfplotsarray@@let{#2@\the\c@pgfplotsarray@tmp}={#1@\the\c@pgfplotsarray@tmp}% \advance\c@pgfplotsarray@tmp by1 \pgfutil@repeat } % #1: the item to append % #2: the array as macro name % Example: % \pgfplotsarraypushback Next last element\to\fooarray \long\def\pgfplotsarraypushback#1\to#2{% \pgfplotsarraysize{#2}\to\c@pgfplotsarray@tmp \pgfplotsarray@@def{#2@\the\c@pgfplotsarray@tmp}{#1}% \advance\c@pgfplotsarray@tmp by1 \pgfplotsarray@@edef{#2@size}{\the\c@pgfplotsarray@tmp}% } \long\def\pgfplotsarraypushbackglobal#1\to#2{% \pgfplotsarraysize{#2}\to\c@pgfplotsarray@tmp \pgfplotsarray@@\gdef{#2@\the\c@pgfplotsarray@tmp}{#1}% \advance\c@pgfplotsarray@tmp by1 \pgfplotsarray@@\xdef{#2@size}{\the\c@pgfplotsarray@tmp}% } \long\def\pgfplotsarraypushbackglobal#1\to#2{% \pgfplotsarraysize{#2}\to\c@pgfplotsarray@tmp \pgfplotsarray@@\gdef{#2@\the\c@pgfplotsarray@tmp}{#1}% \advance\c@pgfplotsarray@tmp by1 \pgfplotsarray@@\xdef{#2@size}{\the\c@pgfplotsarray@tmp}% } % Counts the number of elements in array #1, storing it into the count % register #2. % Example: % \pgfplotsarraysize\foo\to{\count0}% % \the\count0 \long\def\pgfplotsarraysize#1\to#2{% #2=\csname\string#1@size\endcsname\relax } \long\def\pgfplotsarraysizetomacro#1\to#2{% \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: % #1: a count 0,...,N-1 where N is the array size. % You may specify a number of a count. % #2: a array % #3: a macro name % Example: % Element 0: % \pgfplotsarrayselect0\of\foo\to\elem % \elem % Element \count1: % \pgfplotsarrayselect\count1\of\foo\to\elem \def\pgfplotsarrayselect#1\of#2\to#3{% \c@pgfplotsarray@tmp=#1\relax \expandafter\let\expandafter#3\csname\string#2@\the\c@pgfplotsarray@tmp\endcsname% \ifx#3\relax \pgfplotsthrow{no such element}{#1}{No such element: \string\pgfplotsarrayselect\the\c@pgfplotsarray@tmp\string\of{\string#2}}\pgfeov% \fi } % 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 } % Defines \pgfplotsretval to be a text-representation of the array. % It will contain \t to separate cells. % \def\pgfplotsarraytotext#1{% \begingroup \pgfplotsapplistXnewempty\pgfplotsretval@ \pgfplotsarrayforeachungrouped#1\as\entry{% \pgfmathfloatparsenumber\entry \pgfmathfloattosci\pgfmathresult \edef\entry{\pgfmathresult\noexpand\t}% \expandafter\pgfplotsapplistXpushback\entry\to\pgfplotsretval@ }% \pgfplotsapplistXlet\pgfplotsretval=\pgfplotsretval@ \pgfmath@smuggleone\pgfplotsretval \endgroup } % Sets the boolean \ifpgfplotsarrayempty depending on whether array #1 is empty % or not. % Example: % % \pgfplotsarraycheckempty\fooarray % \ifpgfplotsarrayempty % List fooarray is empty! % \else % List is not empty. % \fi \def\pgfplotsarraycheckempty#1{% \ifnum\csname\string#1@size\endcsname=0 \pgfplotsarrayemptytrue \else \pgfplotsarrayemptyfalse \fi } % Iterates through each array element, names it #2 and calls code #3. % Example: % \pgfplotsarraynew\fooarray{Eins\\Zwei\\Drei\\}% % \pgfplotsarrayforeach\fooarray\as\foo{Element \foo\par}% % results in % Element Eins % 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{% % FIXME : add support for \breakforeach \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% \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}% \pgfutil@loop \ifnum\c@pgfplotsarray@tmp<\pgfplotsarray@TMP\relax \expandafter\let\expandafter#2\expandafter=\csname\string#1@\the\c@pgfplotsarray@tmp\endcsname% \begingroup \toks0={#3}% \xdef\pgfplotsarray@glob@TMP{% \the\toks0 % % restore loop state: \c@pgfplotsarray@tmp=\the\c@pgfplotsarray@tmp\space \noexpand\def\noexpand\pgfplotsarray@TMP{\pgfplotsarray@TMP}% }% \endgroup \pgfplotsarray@glob@TMP \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% } \pgfkeys{% /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/iflessthan/.code args={#1#2#3#4}, see docs in % pgfplotsutil.code.tex. % % 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}] % %-------------------------------------------------- % % @see \pgfplotsutilsortthree % @see \pgfplotsutilsortfour \def\pgfplotsarraysort{% \pgfutil@ifnextchar[{\pgfplotsarraysort@opt}{\pgfplotsarraysort@opt[]}% }% \def\pgfplotsarraysort@opt[#1]#2{% % 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 (that means: it is slow). \begingroup \pgfqkeys{/pgfplots/array}{#1}% \pgfkeysifdefined{/pgfplots/array/iflessthan/.@cmd}{% \pgfplots@warning{Warning: /pgfplots/array/iflessthan/.@cmd is deprecated. Please use /pgfplots/iflessthan/.@cmd instead.}% \pgfkeysgetvalue{/pgfplots/array/iflessthan/.@cmd}\pgfplotsarraysort@iflt }{% \pgfkeysgetvalue{/pgfplots/iflessthan/.@cmd}\pgfplotsarraysort@iflt }% \pgfplotsarraysize{#2}\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{#2}}% \def\pgfplotsarray@mergesort@recurse@{\pgfplotsarray@mergesort@recurse{#2}}% \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}#2\pgfeov \endgroup \pgfkeysvalueof{/pgfplots/array/unscope post/.@cmd}#2\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 \begingroup \pgfplotsarraysort@iflt {\pgfplotsarray@x@mpl}% {\pgfplotsarray@x@k}% {% x[m+l] < x[k] \aftergroup\pgfplots@loc@tmptrue }% {% x[k] <= x[m+l] \aftergroup\pgfplots@loc@tmpfalse }% \pgfeov \endgroup \ifpgfplots@loc@tmp \pgfplotsarrayletentryglobal\c@pgfplotsarraysort@i\of{pgfparraytmp}=\pgfplotsarray@x@mpl \advance\c@pgfplotsarraysort@i by1 \advance\c@pgfplotsarraysort@l by1 \else \pgfplotsarrayletentryglobal\c@pgfplotsarraysort@i\of{pgfparraytmp}=\pgfplotsarray@x@k \advance\c@pgfplotsarraysort@i by1 \advance\c@pgfplotsarraysort@k by1 \fi \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}% } % A simple, ungrouped insert sort algorithm for small arrays. % % for i := 1; i < N; ++i do % begin % value := A[i]; % j := i - 1; % done := false; % repeat % if A[j] > value then % begin % A[j + 1] := A[j]; % j := j - 1; % if j < 0 then % done := true; % end % else % done := true; % until done; % A[j + 1] := value; % end; \def\pgfplotsarrayinsertionsort#1{% \pgfkeysgetvalue{/pgfplots/iflessthan/.@cmd}\pgfplotsarraysort@iflt \pgfplotsarraysizetomacro#1\to\pgfplotsarrayinsertionsort@N \c@pgf@countd=1 \pgfplotsarrayinsertionsort@{#1}% }% \def\pgfplotsarrayinsertionsort@#1{% \ifnum\c@pgf@countd<\pgfplotsarrayinsertionsort@N\relax \pgfplotsarrayselect\c@pgf@countd\of#1\to\pgfplotsarrayinsertionsort@v % \c@pgf@countb=\c@pgf@countd \advance\c@pgf@countb by-1 % \pgfplotsarrayinsertionsort@@{#1}% \advance\c@pgf@countb by1 \pgfplotsarrayletentry\c@pgf@countb\of#1=\pgfplotsarrayinsertionsort@v % \advance\c@pgf@countd by1 \expandafter\pgfplotsarrayinsertionsort@\expandafter#1% \fi } \def\pgfplotsarrayinsertionsort@@#1{% \pgfplotsarrayselect\c@pgf@countb\of#1\to\pgfplotsarrayinsertionsort@j \pgfplotsarraysort@iflt{\pgfplotsarrayinsertionsort@v}{\pgfplotsarrayinsertionsort@j} {% \advance\c@pgf@countb by1 \pgfplotsarrayletentry\c@pgf@countb\of#1=\pgfplotsarrayinsertionsort@j \advance\c@pgf@countb by-2 \ifnum\c@pgf@countb<0 \let\pgfplotsarrayinsertionsort@@next\relax% \else \def\pgfplotsarrayinsertionsort@@next{\pgfplotsarrayinsertionsort@@#1}% \fi }{% \let\pgfplotsarrayinsertionsort@@next\relax% }\pgfeov% \pgfplotsarrayinsertionsort@@next }% % applies a binary seach for value '#2' on array '#1', starting with % index '#3' (inclusive) and ending in index '#4' (exclusive). % % Returns: \pgfplotsretval, the index of the search key, if it is % contained in the array; otherwise, (-(insertion point) - 1). The % insertion point is defined as the point at which the key would be % inserted into the array: the index of the first element greater than % the key, or a.length if all elements in the array are less than the % specified key. Note that this guarantees that the return value will % be >= 0 if and only if the key is found. % \def\pgfplotsarraybinarysearch#1#2#3#4{% \begingroup \edef\targetvalue{#2}% \pgfkeysgetvalue{/pgfplots/iflessthan/.@cmd}\pgfplotsarray@iflt \let\mid=\c@pgf@counta \let\left=\c@pgf@countb \let\right=\c@pgf@countc \left=#3\relax \right=#4\relax \advance\right by-1 % make it inclusive \let\pgfplotsretval\pgfutil@empty % \pgfutil@loop \ifnum\left>\right \pgfplots@loop@CONTINUEfalse \else \pgfplots@loop@CONTINUEtrue \fi \ifpgfplots@loop@CONTINUE \mid=\right \advance\mid by -\left \divide\mid by2 % \advance\mid by\left % \pgfplotsarrayselect\mid\of#1\to\midvalue \pgfplotsarray@iflt{\targetvalue}{\midvalue}{% \right=\mid \advance\right by-1 % }{% \pgfplotsarray@iflt{\midvalue}{\targetvalue}{% \left=\mid \advance\left by1 % }{% % found it! abort loop! \left=\right \advance\left by1 % \edef\pgfplotsretval{\the\mid}% }% \pgfeov% }% \pgfeov% \pgfutil@repeat % \ifx\pgfplotsretval\pgfutil@empty \advance\left by1 % \left=-\left \edef\pgfplotsretval{\the\left}% \fi \pgfmath@smuggleone\pgfplotsretval \endgroup }%