%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This is a helper package with an elementary (full) matrix datastructure, % featuring O(1) index access and O(N) creation, deletion, copy. % % The following macros are supplied: % % \pgfplotsmatrixnewempty % \pgfplotsmatrixresize % \pgfplotsmatrixsize % \pgfplotsmatrixselect % \pgfplotsmatrixset % \pgfplotsmatrixletentry % \pgfplotsmatrixforeach % \pgfplotsmatrixLUdecomp % \pgfplotsmatrixLUsolve % % % 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 . % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Creates a new, empty matrix. \def\pgfplotsmatrixnewempty#1{% \pgfplotsarray@@def{#1@rows}{0}% \pgfplotsarray@@def{#1@cols}{1}% } % resizes (truncates) matrix #1 to #2 rows and #3 cols. % % the elements won't be initialised. Use 'set' for each element. \def\pgfplotsmatrixresize#1#2#3{% \pgfplotsarray@@edef{#1@rows}{#2}% \pgfplotsarray@@edef{#1@cols}{#3}% } % Invokes code '#2' if the matrix named '#1' exists and '#3' if it does % not exist. \def\pgfplotsmatrixifdefined#1#2#3{% \pgfutil@ifundefined{#1@rows}{#3}{#2}% }% % Counts the number of rows/cols in matrix #1, storing it into the count % registers #2, #3. % Example: % \pgfplotsmatrixsize\foo\to{\count0}{\count1}% % \the\count0, \the\count1 \long\def\pgfplotsmatrixsize#1\to#2#3{% #2=\csname\string#1@rows\endcsname\relax #3=\csname\string#1@cols\endcsname\relax } \long\def\pgfplotsmatrixsizetomacro#1\to#2#3{% \expandafter\let\expandafter#2\csname\string#1@rows\endcsname \expandafter\let\expandafter#3\csname\string#1@cols\endcsname } % Returns the (#1,#2) element of matrix #3 into macro #4 % Arguments: % #1: a row index 0,...,N-1 where N is rowcount. % #1 must expand to an integer. % #2: a col index 0,...,N-1 where N is colcount. % #2 must expand to an integer. % #3: a matrix % #4: a macro name % Example: % Element 0: % \pgfplotsmatrixselect0,1\of\foo\to\elem % \elem % Element \count1: % \pgfplotsmatrixselect\count1,2\of\foo\to\elem \def\pgfplotsmatrixselect#1,#2\of#3\to#4{% \expandafter\let\expandafter#4\csname\string#3@#1,#2\endcsname% \ifx#4\relax \pgfplotsthrow{no such element}{#1,#2}{No such element: \string\pgfplotsmatrixselect#1,#2\string\of{\string#3}}\pgfeov% \fi } % Expands to the value (#1,#2) of matrix #3. % #1: a row index (not a register) % #2: a col index % #3: a matrix \def\pgfplotsmatrixvalueofelem#1,#2\of#3{\csname\string#3@#1,#2\endcsname}% % Sets element '#1,#2' of matrix '#3' to '#4'. \def\pgfplotsmatrixset#1,#2\of#3\to#4{% \pgfutil@namedef{\string#3@#1,#2}{#4}% } \long\def\pgfplotsmatrixletentry#1,#2\of#3=#4{% \expandafter\let\csname\string#3@#1,#2\endcsname=#4\relax } % During the loop, \pgfplotsmatrixforeachrowindex expands to the % current row index and \pgfplotsmatrixforeachcolindex to the actual % col index. It invokes \pgfplotsmatrixforeachrowend after each % complete row. % % This macro uses % \c@pgf@counta,\c@pgf@countb,\c@pgf@countc,\c@pgf@countd \long\def\pgfplotsmatrixforeach#1\as#2#3{% \pgfplotsmatrixsize#1\to\c@pgf@countc\c@pgf@countd \long\def\pgfplotsmatrixforeach@{#3}% \def\pgfplotsmatrixforeach@assign##1{\def#2{##1}}% \def\pgfplotsmat@select##1,##2\to{\pgfplotsmatrixselect##1,##2\of#1\to}% \def\pgfplotsmatrixforeachrowindex{\the\c@pgf@counta}% \def\pgfplotsmatrixforeachcolindex{\the\c@pgf@countb}% \c@pgf@counta=0 \pgfplotsmatrixforeach@loop \let\pgfplotsmatrixforeachcolindex\relax \let\pgfplotsmatrixforeachrowindex\relax% }% \let\pgfplotsmatrixforeachrowend=\relax \def\pgfplotsmatrixforeach@loop{% \ifnum\c@pgf@counta<\c@pgf@countc \c@pgf@countb=0 \pgfplotsmatrixforeach@loop@ % \pgfplotsmatrixforeachrowend % \advance\c@pgf@counta by1 \expandafter\pgfplotsmatrixforeach@loop \fi }% \def\pgfplotsmatrixforeach@loop@{% \ifnum\c@pgf@countb<\c@pgf@countd \pgfplotsmat@select\the\c@pgf@counta,\the\c@pgf@countb\to\pgfplotsmat@Aij \expandafter\pgfplotsmatrixforeach@assign\expandafter{\pgfplotsmat@Aij}% \pgfplotsmatrixforeach@ % \advance\c@pgf@countb by1 \expandafter\pgfplotsmatrixforeach@loop@ \fi }% % Defines \pgfplotsretval to be a text-representation of the matrix. % It will contain '\n' as newline macro and \t to separate cells. % \def\pgfplotsmatrixtotext#1{% \begingroup \pgfplotsapplistXnewempty\pgfplotsretval@ \def\pgfplotsmatrixforeachrowend{% \pgfplotsapplistXpushback\n\to\pgfplotsretval@ }% \pgfplotsmatrixforeach#1\as\entry{% \pgfmathfloatparsenumber\entry \pgfmathfloattosci\pgfmathresult \edef\entry{\pgfmathresult\noexpand\t}% \expandafter\pgfplotsapplistXpushback\entry\to\pgfplotsretval@ }% \pgfplotsapplistXlet\pgfplotsretval=\pgfplotsretval@ \pgfmath@smuggleone\pgfplotsretval \endgroup } % Takes a matrix #1 and replaces it by its LU decomposition. % The LU decomposition uses implicit pivoting; the pivoting % information is stored in a permutation array #2 and a sign macro #3. % % It is to be used together with \pgfplotsmatrixsolveLEQS. % % #1: the input matrix (square size) % #2: a macro name; will be used to store the permutation array for % the pivoting. % #3: a macro name, will contain the sign of the permutation (either % +1 or -1). % % The algorithm has been converted from Numerical Recipes in C (I did % not copy the comments, though). You find the complete reference in % Chapter 2 of Numerical Recipes. % % If the matrix is singular, an exception will be raised. % If the matrix is singular up to working precision, % \pgfplotsmatrixLUdecompwarnsingular will be invoked and the % algorithm continues with a small threshold. % % All arithmetics is computed with \pgfplotscoordmath{default} (which % is float in the initial configuration). Use % \pgfplotssetcoordmathfor{default}{pgfbasic} to switch it to standard % pgf arithmetics. % % ATTENTION. This routine re-uses the four counters % \c@pgf@counta,...\c@pgf@countd. % Furthermore, it does not free any memory. % Make sure you use it inside of local scopes. \def\pgfplotsmatrixLUdecomp#1\perm#2\sign#3{% \let\pgfplotsmat@i=\c@pgf@counta \let\pgfplotsmat@imax=\c@pgf@countb \let\pgfplotsmat@j=\c@pgf@countc \let\pgfplotsmat@k=\c@pgf@countd \countdef\pgfplotsmat@n=0 \let\pgfplotsmat@big=\pgfutil@empty \let\pgfplotsmat@dum=\pgfutil@empty \let\pgfplotsmat@sum=\pgfutil@empty \let\pgfplotsmat@temp=\pgfutil@empty \pgfplotsmatrixsize#1\to\pgfplotsmat@n\c@pgf@countd \ifnum\c@pgf@countd=\pgfplotsmat@n \else \pgfplots@error{Sorry, \string\pgfplotsmatrixLUdecomp\space expected an n x n matrix, but got \the\pgfplotsmat@n\space x \the\c@pgf@countd.}% \fi \pgfplotsarraynewempty\pgfplotsmat@vv \pgfplotsarrayresize\pgfplotsmat@vv\pgfplotsmat@n \pgfplotsarrayresize#2\pgfplotsmat@n \def\pgfplotsmat@parity{1}% \def\pgfplotsmat@select##1,##2\to{\pgfplotsmatrixselect##1,##2\of#1\to}% \def\pgfplotsmat@letentry##1,##2={\pgfplotsmatrixletentry##1,##2\of#1=}% \def\pgfplotsmat@letpermentry##1={\pgfplotsarrayletentry##1\of#2=}% % \pgfplotsmat@i=0 \pgfplotsmatrixLUdecomp@scalingloop % \ifnum\pgfplotsmat@n>0 % this is used for error recovery. % \pgfplotsmat@j=0 \pgfplotsmatrixLUdecomp@mainloop@j % \let#3=\pgfplotsmat@parity \fi }% \def\pgfplotsmatrixLUdecomp@scalingloop{% \ifnum\pgfplotsmat@i<\pgfplotsmat@n \pgfplotscoordmath{default}{zero}% \let\pgfplotsmat@big=\pgfmathresult % \pgfplotsmat@j=0 \pgfplotsmatrixLUdecomp@scalingloop@ % \pgfplotscoordmath{default}{if is}{\pgfplotsmat@big}{0}{% \pgfplotsthrow{invalid argument}{\pgfplots@loc@TMPa}{Singular matrix in \string\pgfplotsmatrixLUdecomp}\pgfeov% \pgfplotsmat@n=-1 }{% \pgfplotscoordmath{default}{op}{reciprocal}{{\pgfplotsmat@big}}% \pgfplotsarrayletentry\pgfplotsmat@i\of\pgfplotsmat@vv=\pgfmathresult }% % \advance\pgfplotsmat@i by1 \expandafter\pgfplotsmatrixLUdecomp@scalingloop \fi }% \def\pgfplotsmatrixLUdecomp@scalingloop@{% \ifnum\pgfplotsmat@j<\pgfplotsmat@n % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@j\to\pgfplotsmat@Aij \pgfplotscoordmath{default}{parsenumber}{\pgfplotsmat@Aij}% \let\pgfplotsmat@Aij=\pgfmathresult \pgfplotsmat@letentry\the\pgfplotsmat@i,\the\pgfplotsmat@j=\pgfplotsmat@Aij % \pgfplotscoordmath{default}{op}{abs}{{\pgfplotsmat@Aij}}% \let\pgfplotsmat@temp=\pgfmathresult \pgfplotscoordmath{default}{max}{\pgfplotsmat@temp}{\pgfplotsmat@big}% \let\pgfplotsmat@big=\pgfmathresult % \advance\pgfplotsmat@j by1 \expandafter\pgfplotsmatrixLUdecomp@scalingloop@ \fi }% \def\pgfplotsmatrixLUdecomp@mainloop@j{% \ifnum\pgfplotsmat@j<\pgfplotsmat@n % \pgfplotsmat@i=0 \pgfplotsmatrixLUdecomp@mainloop@j@i % \pgfplotscoordmath{default}{zero}% \let\pgfplotsmat@big=\pgfmathresult % \pgfplotsmat@i=\pgfplotsmat@j \pgfplotsmatrixLUdecomp@mainloop@j@i@second % \ifnum\pgfplotsmat@j=\pgfplotsmat@imax \else % interchange rows... \pgfplotsmat@k=0 \pgfplotsmatrixLUdecomp@mainloop@j@k % \c@pgfplotsarray@tmp=-\pgfplotsmat@parity\relax% \edef\pgfplotsmat@parity{\the\c@pgfplotsarray@tmp}% % % FIXME : this here is DIFFERENT. Seems there is something % missing in Numerical Recipes book \pgfplotsarrayselect\pgfplotsmat@j\of\pgfplotsmat@vv\to\pgfplotsmat@dum %\pgfplotsarrayselect\pgfplotsmat@imax\of\pgfplotsmat@vv\to\pgfplotsmat@temp %\pgfplotsarrayletentry\pgfplotsmat@j\of\pgfplotsmat@vv=\pgfplotsmat@temp \pgfplotsarrayletentry\pgfplotsmat@imax\of\pgfplotsmat@vv=\pgfplotsmat@dum \fi % \edef\pgfplotsmat@dum{\the\pgfplotsmat@imax}% \pgfplotsmat@letpermentry\pgfplotsmat@j=\pgfplotsmat@dum % \pgfplotsmat@select\the\pgfplotsmat@j,\the\pgfplotsmat@j\to\pgfplotsmat@Ajj \pgfplotscoordmath{default}{if is}{\pgfplotsmat@Ajj}{0}{% \pgfplotscoordmath{default}{parsenumber}{1e-15}% \pgfplotsmatrixLUdecompwarnsingular \pgfplotsmat@letentry\the\pgfplotsmat@j,\the\pgfplotsmat@j=\pgfmathresult }{% }% % % \advance\pgfplotsmat@j by1 \ifnum\pgfplotsmat@j=\pgfplotsmat@n \advance\pgfplotsmat@j by-1 \else \advance\pgfplotsmat@j by-1 \pgfplotsmat@select\the\pgfplotsmat@j,\the\pgfplotsmat@j\to\pgfplotsmat@Ajj \pgfplotscoordmath{default}{op}{reciprocal}{{\pgfplotsmat@Ajj}}% \let\pgfplotsmat@dum=\pgfmathresult \pgfplotsmat@i=\pgfplotsmat@j \advance\pgfplotsmat@i by1 \pgfplotsmatrixLUdecomp@mainloop@j@i@final \fi \advance\pgfplotsmat@j by1 \expandafter\pgfplotsmatrixLUdecomp@mainloop@j \fi }% \def\pgfplotsmatrixLUdecompwarnsingular{% \pgfplotswarning{linear system singular}\pgfeov% }% \def\pgfplotsmatrixLUdecomp@mainloop@j@i{% \ifnum\pgfplotsmat@i<\pgfplotsmat@j % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@j\to\pgfplotsmat@sum \pgfplotsmat@k=0 \pgfplotsmatrixLUdecomp@mainloop@j@i@k \pgfplotsmat@letentry\the\pgfplotsmat@i,\the\pgfplotsmat@j=\pgfplotsmat@sum % \advance\pgfplotsmat@i by1 \expandafter\pgfplotsmatrixLUdecomp@mainloop@j@i \fi }% \def\pgfplotsmatrixLUdecomp@mainloop@j@i@k{% \ifnum\pgfplotsmat@k<\pgfplotsmat@i % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@k\to\pgfplotsmat@Aik \pgfplotsmat@select\the\pgfplotsmat@k,\the\pgfplotsmat@j\to\pgfplotsmat@Akj \pgfplotscoordmath{default}{op}{multiply}{{\pgfplotsmat@Aik}{\pgfplotsmat@Akj}}% \pgfplotscoordmath{default}{op}{subtract}{{\pgfplotsmat@sum}{\pgfmathresult}}% \let\pgfplotsmat@sum=\pgfmathresult % \advance\pgfplotsmat@k by1 \expandafter\pgfplotsmatrixLUdecomp@mainloop@j@i@k \fi } \def\pgfplotsmatrixLUdecomp@mainloop@j@i@second{% \ifnum\pgfplotsmat@i<\pgfplotsmat@n % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@j\to\pgfplotsmat@sum % \pgfplotsmat@k=0 \pgfplotsmatrixLUdecomp@mainloop@j@i@second@k \pgfplotsmat@letentry\the\pgfplotsmat@i,\the\pgfplotsmat@j=\pgfplotsmat@sum % \pgfplotscoordmath{default}{op}{abs}{{\pgfplotsmat@sum}}% \pgfplotscoordmath{default}{op}{multiply}{{\pgfmathresult}{\pgfplotsarrayvalueofelem\the\pgfplotsmat@i\of\pgfplotsmat@vv}}% \let\pgfplotsmat@dum=\pgfmathresult \pgfplotscoordmath{default}{if less than}{\pgfplotsmat@dum}{\pgfplotsmat@big}{% }{% \let\pgfplotsmat@big=\pgfplotsmat@dum \pgfplotsmat@imax=\pgfplotsmat@i }% % \advance\pgfplotsmat@i by1 \expandafter\pgfplotsmatrixLUdecomp@mainloop@j@i@second \fi }% \def\pgfplotsmatrixLUdecomp@mainloop@j@i@second@k{% \ifnum\pgfplotsmat@k<\pgfplotsmat@j % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@k\to\pgfplotsmat@Aik \pgfplotsmat@select\the\pgfplotsmat@k,\the\pgfplotsmat@j\to\pgfplotsmat@Akj \pgfplotscoordmath{default}{op}{multiply}{{\pgfplotsmat@Aik}{\pgfplotsmat@Akj}}% \pgfplotscoordmath{default}{op}{subtract}{{\pgfplotsmat@sum}{\pgfmathresult}}% \let\pgfplotsmat@sum=\pgfmathresult % \advance\pgfplotsmat@k by1 \expandafter\pgfplotsmatrixLUdecomp@mainloop@j@i@second@k \fi }% \def\pgfplotsmatrixLUdecomp@mainloop@j@k{% \ifnum\pgfplotsmat@k<\pgfplotsmat@n % \pgfplotsmat@select\the\pgfplotsmat@imax,\the\pgfplotsmat@k\to\pgfplotsmat@dum \pgfplotsmat@select\the\pgfplotsmat@j,\the\pgfplotsmat@k\to\pgfplotsmat@Ajk \pgfplotsmat@letentry\the\pgfplotsmat@imax,\the\pgfplotsmat@k=\pgfplotsmat@Ajk \pgfplotsmat@letentry\the\pgfplotsmat@j,\the\pgfplotsmat@k=\pgfplotsmat@dum % \advance\pgfplotsmat@k by1 \expandafter\pgfplotsmatrixLUdecomp@mainloop@j@k \fi } \def\pgfplotsmatrixLUdecomp@mainloop@j@i@final{% \ifnum\pgfplotsmat@i<\pgfplotsmat@n % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@j\to\pgfplotsmat@Aij \pgfplotscoordmath{default}{op}{multiply}{{\pgfplotsmat@Aij}{\pgfplotsmat@dum}}% \pgfplotsmat@letentry\the\pgfplotsmat@i,\the\pgfplotsmat@j=\pgfmathresult % \advance\pgfplotsmat@i by1 \expandafter\pgfplotsmatrixLUdecomp@mainloop@j@i@final \fi } % Solves the set of n linear equations Ax = b where A = LU is given in % (#1,#2) and b = #3. % % #1: is a result of \pgfplotsmatrixLUdecomp % #2: is the permutation vector returned by \pgfplotsmatrixLUdecomp % #3: the right hand side. On output, it will be *overwritten* with % the solution. % % The algorithm has been converted from Numerical Recipes in C (I did % not copy the comments, though). You find the complete reference in % Chapter 2 of Numerical Recipes. \def\pgfplotsmatrixLUbacksubst#1\perm#2\inout#3{% \let\pgfplotsmat@i=\c@pgf@counta \let\pgfplotsmat@ii=\c@pgf@countb \let\pgfplotsmat@j=\c@pgf@countc \let\pgfplotsmat@n=\c@pgf@countd \let\pgfplotsmat@sum=\pgfutil@empty \pgfplotsmatrixsize#1\to\pgfplotsmat@n\c@pgf@counta \pgfplotsarraysize#3\to\c@pgf@counta \ifnum\c@pgf@counta=\pgfplotsmat@n \def\pgfplotsmat@select##1,##2\to{\pgfplotsmatrixselect##1,##2\of#1\to}% \def\pgfplotsmat@selectperm##1\to{\pgfplotsarrayselect##1\of#2\to}% \def\pgfplotsmat@selectb##1\to{\pgfplotsarrayselect##1\of#3\to}% \def\pgfplotsmat@letresult##1={\pgfplotsarrayletentry##1\of#3=}% % \pgfplotsmat@ii=-1 \pgfplotsmat@i=0 \pgfplotsmatrixLUbacksubst@loop@i % \pgfplotsmat@i=\pgfplotsmat@n \advance\pgfplotsmat@i by-1 \pgfplotsmatrixLUbacksubst@loop@i@backw \else \pgfplots@error{Sorry, \string\pgfplotsmatrixLUbacksubst\space expected a vector of length \the\pgfplotsmat@n\space, not \the\c@pgf@counta}% \fi }% \def\pgfplotsmatrixLUbacksubst@loop@i{% \ifnum\pgfplotsmat@i<\pgfplotsmat@n % \pgfplotsmat@selectperm\pgfplotsmat@i\to\pgfplotsmat@ip \pgfplotsmat@selectb\pgfplotsmat@ip\to\pgfplotsmat@sum \pgfplotsmat@selectb\pgfplotsmat@i\to\pgfplotsmat@temp % \pgfplotscoordmath{default}{parsenumber}{\pgfplotsmat@sum}% \let\pgfplotsmat@sum=\pgfmathresult \pgfplotscoordmath{default}{parsenumber}{\pgfplotsmat@temp}% \let\pgfplotsmat@temp=\pgfmathresult % \pgfplotsmat@letresult\pgfplotsmat@ip=\pgfplotsmat@temp % \ifnum\pgfplotsmat@ii<0 \pgfplotscoordmath{default}{if is}{\pgfplotsmat@sum}{0}{% }{% \pgfplotsmat@ii=\pgfplotsmat@i }% \else \pgfplotsmat@j=\pgfplotsmat@ii \pgfplotsmatrixLUbacksubst@loop@i@j \fi \pgfplotsmat@letresult\pgfplotsmat@i=\pgfplotsmat@sum % \advance\pgfplotsmat@i by1 \expandafter\pgfplotsmatrixLUbacksubst@loop@i \fi }% \def\pgfplotsmatrixLUbacksubst@loop@i@j{% \ifnum\pgfplotsmat@j<\pgfplotsmat@i % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@j\to\pgfplotsmat@Aij \pgfplotsmat@selectb\pgfplotsmat@j\to\pgfplotsmat@temp \pgfplotscoordmath{default}{op}{multiply}{{\pgfplotsmat@temp}{\pgfplotsmat@Aij}}% \pgfplotscoordmath{default}{op}{subtract}{{\pgfplotsmat@sum}{\pgfmathresult}}% \let\pgfplotsmat@sum=\pgfmathresult % \advance\pgfplotsmat@j by1 \expandafter\pgfplotsmatrixLUbacksubst@loop@i@j \fi }% \def\pgfplotsmatrixLUbacksubst@loop@i@backw{% \ifnum\pgfplotsmat@i<0 \else % \pgfplotsmat@selectb\pgfplotsmat@i\to\pgfplotsmat@sum \pgfplotsmat@j=\pgfplotsmat@i \advance\pgfplotsmat@j by1 \pgfplotsmatrixLUbacksubst@loop@i@backw@j % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@i\to\pgfplotsmat@Aii \pgfplotscoordmath{default}{op}{divide}{{\pgfplotsmat@sum}{\pgfplotsmat@Aii}}% \pgfplotsmat@letresult\pgfplotsmat@i=\pgfmathresult % \advance\pgfplotsmat@i by-1 \expandafter\pgfplotsmatrixLUbacksubst@loop@i@backw \fi }% \def\pgfplotsmatrixLUbacksubst@loop@i@backw@j{% \ifnum\pgfplotsmat@j<\pgfplotsmat@n % \pgfplotsmat@select\the\pgfplotsmat@i,\the\pgfplotsmat@j\to\pgfplotsmat@Aij \pgfplotsmat@selectb\pgfplotsmat@j\to\pgfplotsmat@temp \pgfplotscoordmath{default}{op}{multiply}{{\pgfplotsmat@temp}{\pgfplotsmat@Aij}}% \pgfplotscoordmath{default}{op}{subtract}{{\pgfplotsmat@sum}{\pgfmathresult}}% \let\pgfplotsmat@sum=\pgfmathresult % \advance\pgfplotsmat@j by1 \expandafter\pgfplotsmatrixLUbacksubst@loop@i@backw@j \fi }% % Solves the linear equation system Ax = b. % #1: the matrix A % #2: the right-hand-side b. On output, #2 will contain the solution % and A will be overwritten. % % ATTENTION. This routine re-uses the four counters % \c@pgf@counta,...\c@pgf@countd. % Furthermore, it does not free any memory. % Make sure you use it inside of local scopes. \def\pgfplotsmatrixsolveLEQS#1=#2{% \pgfplotsmatrixLUdecomp#1\perm\pgfplotsmatrix@perm\sign\pgfplotsmatrix@sign \pgfplotsmatrixLUbacksubst#1\perm\pgfplotsmatrix@perm\inout#2% }%