Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- % Givens rotation
- % I assume #1 < #2
- % does not use theta because it is unstable
- % #4 is cosine and #5 is sine
- defpgflabgivensrotaterow #1 and row #2 by #3 and #4 in #5{
- pgfkeys{/lab/#5/w/.get=pgflabw}
- pgfplotsforeachungroupedg@j in{1,...,pgflabw}{
- pgfkeys{/lab/#5/#1/g@j/.get=pgflabtempentrya}
- pgfkeys{/lab/#5/#2/g@j/.get=pgflabtempentryb}
- pgfmathparse{#3*pgflabtempentrya-#4*pgflabtempentryb}
- pgfkeys{/lab/#5/#1/g@j/.let=pgfmathresult}
- pgfmathparse{#4*pgflabtempentrya+#3*pgflabtempentryb}
- pgfkeys{/lab/#5/#2/g@j/.let=pgfmathresult}
- }
- }
- % I assume #1 < #2
- % does not use theta because it is unstable
- % #4 is cosine and #5 is sine
- defpgflabgivensrotatecol #1 and col #2 by #3 and #4 in #5{
- pgfkeys{/lab/#5/h/.get=pgflabh}
- pgfplotsforeachungroupedg@i in{1,...,pgflabh}{
- pgfkeys{/lab/#5/g@i/#1/.get=pgflabtempentrya}
- pgfkeys{/lab/#5/g@i/#2/.get=pgflabtempentryb}
- pgfmathparse{#3*pgflabtempentrya-#4*pgflabtempentryb}
- pgfkeys{/lab/#5/g@i/#1/.let=pgfmathresult}
- pgfmathparse{#4*pgflabtempentrya+#3*pgflabtempentryb}
- pgfkeys{/lab/#5/g@i/#2/.let=pgfmathresult}
- }
- }
- % A = QR decomposition
- defpgflabQRdecompose #1 as #2 times #3{
- pgfkeys{/lab/#1/w/.get=pgflabW}
- pgfkeys{/lab/#1/h/.get=pgflabH}
- % decide the loop boundary
- edefpgflab@H-1{thenumexprpgflabH-1}
- ifnumpgflab@H-1>pgflabW
- edefpgflab@H-1{pgflabW}
- fi
- % set Q as identity
- % set #2 as identity
- pgflabneweyeof {pgflabH} by {pgflabH} as {#2}
- % copy A to R
- % copy #1 to #3
- pgflabcopymatrix {#1} to {#3}
- % forget A, do job at Q and R
- % forget #1, do job at #2 and #3
- pgfplotsforeachungroupedd@i in{1,...,pgflab@H-1}{
- edefd@@i+1{thenumexprd@i+1}
- pgfplotsforeachungroupedd@j in{d@@i+1,...,pgflabh}{
- pgfkeys{/lab/#3/d@i/d@i/.get=pgflabtempentrya}
- pgfkeys{/lab/#3/d@j/d@i/.get=pgflabtempentryb}
- pgfmathsetmacropgflabtempradius{sqrt(pgflabtempentrya*pgflabtempentrya+pgflabtempentryb*pgflabtempentryb)}
- pgfmathsetmacropgflabtempcos{ pgflabtempentrya/pgflabtempradius} % cosine
- pgfmathsetmacropgflabtempsin{-pgflabtempentryb/pgflabtempradius} % sine
- pgflabgivensrotaterow {d@i} and row {d@j} by {pgflabtempcos} and {pgflabtempsin} in {#3}
- pgflabgivensrotatecol {d@i} and col {d@j} by {pgflabtempcos} and {pgflabtempsin} in {#2}
- eliminate one entry. check Q and Rpar
- $Q=pgflabtypeset{#2};$
- $R=pgflabtypeset{#3};$
- }
- }
- }
- pgflabread{A}{
- 0 0 0 1
- 1 0 0 0
- 0 1 0 0
- 0 0 1 0
- }
- pgflabQRdecompose A as Q times R
- documentclass{article}
- usepackage[a3paper,landscape,margin=1cm]{geometry}
- usepackage{pgfplotstable,mathtools}
- pgfplotsset{compat=newest}
- pgfkeys{/pgf/fpu,/pgf/number format/fixed}
- begin{document}
- makeatletter
- % pgfmatrix... is used
- % we use pgflab...
- % call pgfplotstable to read the data
- % put options in [] if desired
- % the options go to pgfplotstableread
- defpgflabread{
- pgfutil@ifnextchar[
- {pgflabread@opt}
- {pgflabread@opt[]}
- }
- % #1: optional option
- % #2: a name of the matrix... usually A
- defpgflabread@opt[#1]#2{
- edefpgflabname{#2}
- pgfplotstableread[header=false,#1]
- }
- % we did not provide a macro to pgfplotstable to store the table
- % we give it a temporary one called pgflabtemptable
- % and then copy it to our data structure
- longdefpgfplotstableread@impl@collectfirstarg#1#2{
- pgfplotstableread@impl@{#1}{#2}pgflabtemptable
- pgflabconverttablepgflabtemptable to matrix{pgflabname}
- }
- % this helps us to deal with pgfleys
- pgfkeys{/handlers/.let/.code=pgfkeyslet{pgfkeyscurrentpath}{#1}}
- % copy pgfplotstable table to our data structure in pgfkeys
- % #1: the macro that pgfplotstable used to store the table
- % #2: a name of the matrix
- defpgflabconverttable#1to matrix#2{
- % extract height and width
- pgfplotstablegetrowsof#1xdefpgflabh{pgfplotsretval}pgfkeys{/lab/#2/h/.let=pgflabh}
- %%%height = pgflabh par
- pgfplotstablegetcolsof#1xdefpgflabw{pgfplotsretval}pgfkeys{/lab/#2/w/.let=pgflabw}
- %%%width = pgflabw par
- % extract entries
- % c@i and c@j cannot be used outside
- pgfplotsforeachungroupedc@i in{1,...,pgflabh}{
- pgfplotsforeachungroupedc@j in{1,...,pgflabw}{
- % since fpu is on, this is easier way to do 9-1
- pgfplotstablegetelem{thenumexprc@i-1}{thenumexprc@j-1}ofpgflabtemptable
- pgfkeys{/lab/#2/c@i/c@j/.let=pgfplotsretval}
- %%%pgfplotsretval,
- }
- %%%; par
- }
- }
- pgflabread{A}{
- 3 1 -7 5 0
- -9 -4 -8 -2 9
- 4 -3 6 0 -1
- -5 8 2 -6 7
- }
- % the opposite of the previous one
- % #1: the name of the matrix
- % #2: a macro for pgfplotstable to store the table
- defpgflabconvertmatrix #1 to table #2{
- % makeup meta data
- expandafterdefcsnamestring#2@@table@nameendcsname{<inline_table>}
- % build a new list of columns
- pgfkeys{/lab/#1/h/.get=pgflabh}
- pgfkeys{/lab/#1/w/.get=pgflabw}
- pgfplotslistnew#2{0,...,thenumexprpgflabw-1}
- % fill in columns
- pgfplotsforeachungroupedc@j in{1,...,pgflabw}{
- pgfplotslistnewemptypgflabtempcolumn
- pgfplotsforeachungroupedc@i in{1,...,pgflabh}{
- pgfkeys{/lab/#1/c@i/c@j/.get=pgflabtempentry}
- expandafterpgfplotslistpushbackpgflabtempentrytopgflabtempcolumn
- }
- edefc@k{thenumexprc@j-1}
- expandafterletcsnamestring#2@c@kendcsnamepgflabtempcolumn
- }
- }
- % typeset the matrix by pgfplotstabletypeset
- defpgflabtypeset{
- pgfutil@ifnextchar[
- {pgflabtypeset@opt}
- {pgflabtypeset@opt[]}
- }
- % #1: optional option
- % #2: the name of the matrix
- defpgflabtypeset@opt[#1]#2{
- pgflabconvertmatrix #2 to table pgflabtemptable
- pgfplotstabletypeset[every head row/.style={output empty row}]pgflabtemptable
- }
- Matrix A is
- $A=pgflabtypeset{A}$
- % define row operation: switch
- % does not check boundary
- defpgflabswitchrow #1 and row #2 in #3{
- pgfkeys{/lab/#3/w/.get=pgflabw}
- pgfplotsforeachungroupeds@j in{1,...,pgflabw}{
- pgfkeys{/lab/#3/#1/s@j/.get=pgflabtempentrya}
- pgfkeys{/lab/#3/#2/s@j/.get=pgflabtempentryb}
- pgfkeys{/lab/#3/#1/s@j/.let=pgflabtempentryb}
- pgfkeys{/lab/#3/#2/s@j/.let=pgflabtempentrya}
- }
- }
- bigskip
- pgflabswitchrow 1 and row 3 in A
- switch row 1 and row 3;
- $A=pgflabtypeset{A}$
- % define column operation: switch
- % does not check boundary
- defpgflabswitchcol #1 and col #2 in #3{
- pgfkeys{/lab/#3/h/.get=pgflabh}
- pgfplotsforeachungroupeds@i in{1,...,pgflabh}{
- pgfkeys{/lab/#3/s@i/#1/.get=pgflabtempentrya}
- pgfkeys{/lab/#3/s@i/#2/.get=pgflabtempentryb}
- pgfkeys{/lab/#3/s@i/#1/.let=pgflabtempentryb}
- pgfkeys{/lab/#3/s@i/#2/.let=pgflabtempentrya}
- }
- }
- bigskip
- pgflabswitchcol 2 and col 3 in A
- switch col 2 and col 3;
- $A=pgflabtypeset{A}$
- % define row operation: multiplication
- % does not check boundary
- defpgflabmultiplyrow #1 by #2 in #3{
- pgfkeys{/lab/#3/w/.get=pgflabw}
- pgfplotsforeachungroupedm@j in{1,...,pgflabw}{
- pgfkeys{/lab/#3/#1/m@j/.get=pgflabtempentry}
- pgfmathparse{pgflabtempentry*#2}
- pgfkeys{/lab/#3/#1/m@j/.let=pgfmathresult}
- }
- }
- bigskip
- pgflabmultiplyrow 3 by -1 in A
- multiply row 3 by -1;
- $A=pgflabtypeset{A}$
- % define row operation: addition
- % does not check boundary
- defpgflabaddrow #1 by row #2 times #3 in #4{
- pgfkeys{/lab/#4/w/.get=pgflabw}
- pgfplotsforeachungroupeda@j in{1,...,pgflabw}{
- pgfkeys{/lab/#4/#1/a@j/.get=pgflabtempentrya}
- pgfkeys{/lab/#4/#2/a@j/.get=pgflabtempentryb}
- pgfmathparse{pgflabtempentrya+pgflabtempentryb*#3}
- pgfkeys{/lab/#4/#1/a@j/.let=pgfmathresult}
- }
- }
- bigskip
- pgflabaddrow 2 by row 3 times 2 in A
- add row 2 by row 3 times 2;
- $A=pgflabtypeset{A}$
- % define column operation: addition
- % does not check boundary
- defpgflabaddcol #1 by col #2 times #3 in #4{
- pgfkeys{/lab/#4/h/.get=pgflabh}
- pgfplotsforeachungroupeda@i in{1,...,pgflabh}{
- pgfkeys{/lab/#4/a@i/#1/.get=pgflabtempentrya}
- pgfkeys{/lab/#4/a@i/#2/.get=pgflabtempentryb}
- pgfmathparse{pgflabtempentrya+pgflabtempentryb*#3}
- pgfkeys{/lab/#4/a@i/#1/.let=pgfmathresult}
- }
- }
- bigskip
- pgflabaddcol 5 by col 4 times -1 in A
- add col 5 by row 4 times -1;
- $A=pgflabtypeset{A}$
- % new identity matrix
- defpgflabneweyeof #1 by #2 as #3{
- defpgflabh{#1}pgfkeys{/lab/#3/h/.let=pgflabh}
- defpgflabw{#2}pgfkeys{/lab/#3/w/.let=pgflabw}
- pgfplotsforeachungroupedn@i in{1,...,pgflabh}{
- pgfplotsforeachungroupedn@j in{1,...,pgflabw}{
- ifnumn@i=n@j
- pgfkeys{/lab/#3/n@i/n@i/.initial=1}
- else
- pgfkeys{/lab/#3/n@i/n@j/.initial=0}
- fi
- }
- }
- }
- bigskip
- pgflabneweyeof 4 by 4 as I
- identity matrix;
- $A=pgflabtypeset{I}$
- bigskip
- pgflabneweyeof 3 by 5 as B
- rectangular identity matrix;
- $B=pgflabtypeset{B}$
- % copy matrix
- defpgflabcopymatrix #1 to #2{
- pgfkeys{/lab/#1/h/.get=pgflabh}pgfkeys{/lab/#2/h/.let=pgflabh}
- pgfkeys{/lab/#1/w/.get=pgflabw}pgfkeys{/lab/#2/w/.let=pgflabw}
- pgfplotsforeachungroupedn@i in{1,...,pgflabh}{
- pgfplotsforeachungroupedn@j in{1,...,pgflabw}{
- pgfkeys{/lab/#1/n@i/n@j/.get=pgflabtempentry}
- pgfkeys{/lab/#2/n@i/n@j/.let=pgflabtempentry}
- }
- }
- }
- bigskip
- pgflabcopymatrix A to B
- copy matrix A to B;
- $B=pgflabtypeset{B}$
- % LU decomposition
- % if encounter 0, probably will result in inf or nan
- defpgflabLUdecompose #1 as #2 times #3{
- pgfkeys{/lab/#1/h/.get=pgflabh@u}
- pgfkeys{/lab/#1/w/.get=pgflabw@u}
- % decide the loop boundary
- edefpgflabh@v{thenumexprpgflabh@u-1}
- ifnumpgflabh@v>pgflabw@u
- edefpgflabh@v{pgflabw@u}
- fi
- % set L as identity
- % set #2 as identity
- pgflabneweyeof {pgflabh@u} by {pgflabh@u} as #2
- % copy A to U
- % copy #1 to #3
- pgflabcopymatrix #1 to #3
- % forget A, do job at L and U
- % forget #1, do job at #2 and #3
- pgfplotsforeachungroupedd@i in{1,...,pgflabh@v}{
- edefd@@i+1{thenumexprd@i+1}
- pgfplotsforeachungroupedd@j in{d@@i+1,...,pgflabh@u}{
- % use (d@i,d@i) to eliminate (d@j,d@i)
- pgfkeys{/lab/#3/d@i/d@i/.get=pgflabtempentrya}
- pgfkeys{/lab/#3/d@j/d@i/.get=pgflabtempentryb}
- pgfmathsetmacropgflabtempratio{pgflabtempentryb/pgflabtempentrya}
- pgflabaddcol {d@i} by col {d@j} times {pgflabtempratio} in {#2}
- pgflabaddrow {d@j} by row {d@i} times {-pgflabtempratio} in {#3}
- medskip
- eliminate one entry. check L and U par
- $L=pgflabtypeset{#2};$
- $U=pgflabtypeset{#3};$
- }
- }
- }
- clearpage
- $A=pgflabtypeset{A}$
- pgflabLUdecompose A as L times U
- % find pivot in the specific column
- % find pivot in the range (#1,#1) to (#1,end)
- % does not check boundary
- defpgflabfindpivotatcol #1 in #2{
- pgfkeys{/lab/#2/h/.get=pgflabh}
- defpgflabtempmax{-inf}
- defpgflabtempindex{0}
- pgfplotsforeachungroupedf@i in{#1,...,pgflabh}{
- pgfkeys{/lab/#2/f@i/#1/.get=pgflabtempentry}
- % compare the abs value
- pgfmathsetmacropgflabtempentry{abs(pgflabtempentry)}
- pgfmathparse{pgflabtempmax<pgflabtempentry}
- % update if necessary
- ifpgfmathfloatcomparison
- letpgflabtempmaxpgflabtempentry
- letpgflabtempindexf@i
- fi
- }
- }
- clearpage
- $A=pgflabtypeset{A}$
- find pivot at specific column: par
- pgflabfindpivotatcol 1 in A
- at col 1 it is pgflabtempmax at row pgflabtempindex par
- pgflabfindpivotatcol 2 in A
- at col 2 it is pgflabtempmax at row pgflabtempindex par
- pgflabfindpivotatcol 3 in A
- at col 2 it is pgflabtempmax at row pgflabtempindex
- % A = PLU decomposition
- % partial pivoting
- defpgflabPLUdecompose #1 as #2 times #3 times #4{
- pgfkeys{/lab/#1/h/.get=pgflabH}
- pgfkeys{/lab/#1/w/.get=pgflabW}
- % decide the loop boundary
- edefpgflab@H-1{thenumexprpgflabH-1}
- ifnumpgflab@H-1>pgflabW
- edefpgflab@H-1{pgflabW}
- fi
- % set P as identity
- % set #2 as identity
- pgflabneweyeof {pgflabH} by {pgflabH} as {#2}
- % set L as identity
- % set #3 as identity
- pgflabneweyeof {pgflabH} by {pgflabH} as {#3}
- % copy A to U
- % copy #1 to #4
- pgflabcopymatrix {#1} to {#4}
- % forget A, do job at P and L and U
- % forget #1, do job at #2 and #3 and #4
- pgfplotsforeachungroupedd@i in{1,...,pgflab@H-1}{
- pgflabfindpivotatcol {d@i} in {#4}
- pgflabswitchrow {d@i} and row {pgflabtempindex} in {#4}
- pgflabswitchcol {d@i} and col {pgflabtempindex} in {#3}
- pgflabswitchrow {d@i} and row {pgflabtempindex} in {#3}
- pgflabswitchcol {d@i} and col {pgflabtempindex} in {#2}
- parmedskip
- switch d@i{} and pgflabtempindexpar
- $P=pgflabtypeset{#2};$
- $L=pgflabtypeset{#3};$
- $U=pgflabtypeset{#4};$
- edefd@@i+1{thenumexprd@i+1}
- pgfplotsforeachungroupedd@j in{d@@i+1,...,pgflabH}{
- % use (d@i,d@i) to eliminate (d@j,d@i)
- pgfkeys{/lab/#4/d@i/d@i/.get=pgflabtempentrya}
- pgfkeys{/lab/#4/d@j/d@i/.get=pgflabtempentryb}
- pgfmathsetmacropgflabtempratio{pgflabtempentryb/pgflabtempentrya}
- pgflabaddcol {d@i} by col {d@j} times {pgflabtempratio} in {#3}
- pgflabaddrow {d@j} by row {d@i} times {-pgflabtempratio} in {#4}
- }
- parmedskip
- eliminate one column. check P and L and U par
- $P=pgflabtypeset{#2};$
- $L=pgflabtypeset{#3};$
- $U=pgflabtypeset{#4};$
- }
- }
- pgflabread{A}{
- 3 1 -7 5 0
- -9 -4 -8 -2 9
- 4 -3 6 0 -1
- -5 8 2 -6 7
- }
- bigskip
- pgflabPLUdecompose A as P times L times U
- % find pivot in the specific column and row
- % find pivot in the range (#1,#1) to (end,end)
- % does not check boundary
- defpgflabfindpivotafter#1 in #2{
- pgfkeys{/lab/#2/h/.get=pgflabh}
- pgfkeys{/lab/#2/w/.get=pgflabw}
- defpgflabtempmax{-inf}
- defpgflabtempindex{0}
- defpgflabtempjndex{0}
- pgfplotsforeachungroupedf@i in{#1,...,pgflabh}{
- pgfplotsforeachungroupedf@j in{#1,...,pgflabw}{
- pgfkeys{/lab/#2/f@i/f@j/.get=pgflabtempentry}
- % compare the abs value
- pgfmathsetmacropgflabtempentry{abs(pgflabtempentry)}
- pgfmathparse{pgflabtempmax<pgflabtempentry}
- % update if necessary
- ifpgfmathfloatcomparison
- letpgflabtempmaxpgflabtempentry
- letpgflabtempindexf@i
- letpgflabtempjndexf@j
- fi
- }
- }
- }
- % A = PLUQ decomposition
- % partial pivoting
- defpgflabPLUQdecompose #1 as #2 times #3 times #4 times #5{
- pgfkeys{/lab/#1/h/.get=pgflabH}
- pgfkeys{/lab/#1/w/.get=pgflabW}
- % decide the loop boundary
- edefpgflab@H-1{thenumexprpgflabH-1}
- ifnumpgflab@H-1>pgflabW
- edefpgflab@H-1{pgflabW}
- fi
- % set P as identity
- % set #2 as identity
- pgflabneweyeof {pgflabH} by {pgflabH} as {#2}
- % set L as identity
- % set #3 as identity
- pgflabneweyeof {pgflabH} by {pgflabH} as {#3}
- % copy A to U
- % copy #1 to #4
- pgflabcopymatrix {#1} to {#4}
- % set Q as identity
- % set #5 as identity
- pgflabneweyeof {pgflabW} by {pgflabW} as {#5}
- % forget A, do job at P and L and U
- % forget #1, do job at #2 and #3 and #4
- pgfplotsforeachungroupedd@i in{1,...,pgflab@H-1}{
- pgflabfindpivotafter {d@i} in #4
- pgflabswitchrow {d@i} and row {pgflabtempindex} in {#4}
- pgflabswitchcol {d@i} and col {pgflabtempindex} in {#3}
- pgflabswitchrow {d@i} and row {pgflabtempindex} in {#3}
- pgflabswitchcol {d@i} and col {pgflabtempindex} in {#2}
- {}
- pgflabswitchcol {d@i} and col {pgflabtempjndex} in {#4}
- pgflabswitchrow {d@i} and row {pgflabtempjndex} in {#5}
- switch (d@i{},d@i{}) and (pgflabtempindex,pgflabtempjndex) par
- $P=pgflabtypeset{#2};$
- $L=pgflabtypeset{#3};$
- $U=pgflabtypeset{#4};$
- $Q=pgflabtypeset{#5};$
- edefd@@i+1{thenumexprd@i+1}
- pgfplotsforeachungroupedd@j in{d@@i+1,...,pgflabH}{
- % use (d@i,d@i) to eliminate (d@j,d@i)
- pgfkeys{/lab/#4/d@i/d@i/.get=pgflabtempentrya}
- pgfkeys{/lab/#4/d@j/d@i/.get=pgflabtempentryb}
- pgfmathsetmacropgflabtempratio{pgflabtempentryb/pgflabtempentrya}
- pgflabaddcol {d@i} by col {d@j} times {pgflabtempratio} in {#3}
- pgflabaddrow {d@j} by row {d@i} times {-pgflabtempratio} in {#4}
- }
- eliminate one column. check P and L and U and Qpar
- $P=pgflabtypeset{#2};$
- $L=pgflabtypeset{#3};$
- $U=pgflabtypeset{#4};$
- $Q=pgflabtypeset{#5};$
- }
- }
- pgflabread{A}{
- 3 -7 5 0 1 0 1
- -9 -8 -2 9 -1 9 -4
- 4 6 0 -1 -2 -1 -3
- -5 2 -6 7 8 7 8
- -1 -2 -1 -3 4 6 0
- 7 8 7 8 -5 2 -6
- }
- bigskip
- $A=pgflabtypeset{A}$
- pgflabPLUQdecompose A as P times L times U times Q
- % new matrix with desired entry
- % entry can contain n@i and n@j
- defpgflabnewmatrixof #1 by #2 with #3 as #4{
- defpgflabh{#1}pgfkeys{/lab/#4/h/.let=pgflabh}
- defpgflabw{#2}pgfkeys{/lab/#4/w/.let=pgflabw}
- pgfplotsforeachungroupedn@i in{1,...,pgflabh}{
- pgfplotsforeachungroupedn@j in{1,...,pgflabw}{
- pgfmathparse{#3}
- pgfkeys{/lab/#4/n@i/n@j/.let=pgfmathresult}
- }
- }
- }
- clearpage
- pgflabnewmatrixof 10 by 10 with rand as C
- pgflabPLUQdecompose C as P times L times U times Q
- % debug macro
- % we can pass it to sage
- % but we need to replace negative sign by ascii's -
- defpgflabrawoutput#1{%
- pgfkeys{/lab/#1/h/.get=pgflabh}%
- pgfkeys{/lab/#1/w/.get=pgflabw}%
- matrix([%
- pgfplotsforeachungroupedt@i in{1,...,pgflabh}{%
- [%
- pgfplotsforeachungroupedt@j in{1,...,pgflabw}{%
- pgfkeys{/lab/#1/t@i/t@j/.get=pgflabtempentry}%
- pgfmathparse{pgflabtempentry}%
- pgfmathfloattosci{pgfmathresult}%
- mbox{pgfmathresult}%
- ifnumt@j<pgflabw,hskip1ptplus3ptallowbreakfi
- }%
- ]%
- ifnumt@i<pgflabh,hskip1ptplus3ptallowbreakfi
- }%
- ])%
- }
- clearpage
- C=pgflabrawoutput{C};par
- P=pgflabrawoutput{P};par
- L=pgflabrawoutput{L};par
- U=pgflabrawoutput{U};par
- Q=pgflabrawoutput{Q};par
- (C-P*L*U*Q).norm()
- end{document}
- documentclass{article}
- usepackage{pgfplotstable,mathtools}
- pgfplotsset{compat=newest}
- pgfkeys{/pgf/fpu}
- begin{document}
- % we are lazy
- % let pgfplotstable read the matrix
- pgfplotstableread[header=false]{
- 8 1 6 8
- 3 5 7 5
- 4 9 2 7
- }matrixA
- % we will store data by pgfleys
- % create a handy handler
- pgfkeys{/handlers/.let/.code=pgfkeyslet{pgfkeyscurrentpath}{#1}}
- % PS: /.initial is more like def, but we want xdef or edef or let
- % but we also need some fast macros
- pgfplotstablegetrowsofmatrixA xdefmatrixheight{pgfplotsretval}pgfkeys{/matrix/A/height/.let=matrixheight}
- pgfplotstablegetcolsofmatrixA xdefmatrixwidth{pgfplotsretval} pgfkeys{/matrix/A/width/.let=matrixwidth}
- % check data
- Matrix $A$ is pgfkeys{/matrix/A/height} by pgfkeys{/matrix/A/width}.
- In other words: par Matrix $A$ is matrixheight{} by matrixwidth{}.
- % store the entries into pgfkeys
- pgfplotsforeachungroupedi in{1,...,matrixheight}{
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- % since fpu is on, this is easier way to do 9+1
- pgfplotstablegetelem{thenumexpri-1}{thenumexprj-1}ofmatrixA
- pgfkeys{/matrix/A/i/j/.let=pgfplotsretval}
- }
- }
- % check data
- bigskip The matrix entries are: par
- pgfplotsforeachungroupedi in{1,...,matrixheight}{
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfkeys{/matrix/A/i/j},
- }
- ; par
- }
- % define row operation: switch
- defrowoperationswitch#1and#2 {
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfkeys{/matrix/A/#1/j/.get=tempmatrixentryA}
- pgfkeys{/matrix/A/#2/j/.get=tempmatrixentryB}
- pgfkeys{/matrix/A/#1/j/.let=tempmatrixentryB}
- pgfkeys{/matrix/A/#2/j/.let=tempmatrixentryA}
- }
- }
- % try and check
- rowoperationswitch3and2
- bigskip After switching row3 and row2, the matrix entries are: par
- pgfplotsforeachungroupedi in{1,...,matrixheight}{
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfkeys{/matrix/A/i/j},
- }
- ; par
- }
- % define row operation: multiplication
- defrowoperationmultiply#1by#2 {
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfkeys{/matrix/A/#1/j/.get=tempmatrixentry}
- pgfmathparse{tempmatrixentry*#2}
- pgfkeys{/matrix/A/#1/j/.let=pgfmathresult}
- }
- }
- % try and check
- rowoperationmultiply3by9
- bigskip After multiplying row3 by 9, the matrix entries are: par
- pgfplotsforeachungroupedi in{1,...,matrixheight}{
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfkeys{/matrix/A/i/j},
- }
- ; par
- }
- remember: fpu is on! par
- Human readable version par
- defpgfmathprintmatrix{
- pgfplotsforeachungroupedi in{1,...,matrixheight}{
- indent
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfkeys{/matrix/A/i/j/.get=tempmatrixentry}
- pgfmathparse{tempmatrixentry}
- clap{pgfmathprintnumber{pgfmathresult}}hskip20pt
- }
- par
- }
- }
- pgfmathprintmatrix
- % define row operation: addition
- defrowoperationadd#1by#2times#3 {
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfkeys{/matrix/A/#1/j/.get=tempmatrixentryA}
- pgfkeys{/matrix/A/#2/j/.get=tempmatrixentryB}
- pgfmathparse{tempmatrixentryA+tempmatrixentryB*#3}
- pgfkeys{/matrix/A/#1/j/.let=pgfmathresult}
- }
- }
- % try and check
- rowoperationadd1by2times-1
- bigskip After adding row2 by row1 times -1, the matrix entries are: par
- pgfmathprintmatrix
- % We do RREF by hand
- pgfkeys{/pgf/number format/fixed}
- bigskip We do RREF by hand par
- add 2 by 1 times -1: par
- rowoperationadd2by1times-1
- pgfmathprintmatrix
- medskip add 3 by 1 times -6.75: par
- rowoperationadd3by1times-6.75
- pgfmathprintmatrix
- medskip add 3 by 2 times -5.8235: par
- rowoperationadd3by2times-5.8235
- pgfmathprintmatrix
- % renew A
- pgfplotsforeachungroupedi in{1,...,matrixheight}{
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfplotstablegetelem{thenumexpri-1}{thenumexprj-1}ofmatrixA % lazy~~
- pgfkeys{/matrix/A/i/j/.let=pgfplotsretval}
- }
- }
- clearpage Restart with $A$ par
- pgfmathprintmatrix
- % Automatic RREF without row switching
- % I is different form i
- xdefmatrixheightminusone{thenumexprmatrixheight-1}
- pgfplotsforeachungroupedI in{1,...,matrixheightminusone}{
- pgfplotsforeachungroupedJ in{I,...,matrixheightminusone}{
- xdefJ{thenumexprJ+1}
- pgfkeys{/matrix/A/I/I/.get=tempmatrixentryA}
- pgfkeys{/matrix/A/J/I/.get=tempmatrixentryB}
- bigskip
- entry [I][I] is tempmatrixentryA par
- entry [J][I] is tempmatrixentryB par
- pgfmathparse{-tempmatrixentryB/tempmatrixentryA}
- xdeftemprowscaler{pgfmathresult}
- message{^^J^^JI,J,temprowscaler^^J^^J}
- add rowJ{} by rowI{} times pgfmathprintnumber{temprowscaler} par
- rowoperationaddJ byI times{temprowscaler}
- pgfmathprintmatrix
- }
- }
- % renew A
- pgfplotsforeachungroupedi in{1,...,matrixheight}{
- pgfplotsforeachungroupedj in{1,...,matrixwidth}{
- pgfplotstablegetelem{thenumexpri-1}{thenumexprj-1}ofmatrixA % lazy~~
- pgfkeys{/matrix/A/i/j/.let=pgfplotsretval}
- }
- }
- clearpage Restart with $A$ par
- pgfmathprintmatrix
- % maybe we need pivoting
- defrowoperationfindpivot{
- % find the maximal element in this column
- defmaxofthiscolumn{-inf}
- defmaxofthiscolumnindex{0}
- pgfplotsforeachungroupedK in{I,...,matrixheight}{
- pgfkeys{/matrix/A/K/I/.get=tempmatrixentry}
- % compare
- pgfmathparse{abs(tempmatrixentry)}
- lettempmatrixabsentrypgfmathresult
- pgfmathparse{maxofthiscolumn<tempmatrixabsentry}
- % update if necessary
- ifpgfmathfloatcomparison
- letmaxofthiscolumntempmatrixabsentry
- letmaxofthiscolumnindexK
- fi
- }
- }
- xdefI{1}
- rowoperationfindpivot
- For column I, the maximum is pgfmathprintnumber{maxofthiscolumn} at row maxofthiscolumnindex
- % Automatic RREF with partial pivot
- defRREFwithpivoting{
- pgfplotsforeachungroupedI in{1,...,matrixheightminusone}{
- rowoperationfindpivot
- rowoperationswitchI and{maxofthiscolumnindex}
- bigskip
- For column I, the maximum is pgfmathprintnumber{maxofthiscolumn} at row maxofthiscolumnindex par
- so we switch rowI{} and rowmaxofthiscolumnindex, the matrix entries are: par
- pgfmathprintmatrix
- pgfplotsforeachungroupedJ in{I,...,matrixheightminusone}{
- xdefJ{thenumexprJ+1}
- pgfkeys{/matrix/A/I/I/.get=tempmatrixentryA}
- pgfkeys{/matrix/A/J/I/.get=tempmatrixentryB}
- bigskip
- pgfmathparse{-tempmatrixentryB/tempmatrixentryA}
- xdeftemprowscaler{pgfmathresult}
- add rowJ{} by rowI{} times pgfmathprintnumber{temprowscaler} par
- rowoperationaddJ byI times{temprowscaler}
- pgfmathprintmatrix
- }
- }
- }
- RREFwithpivoting
- .......
- A:=Matrix([[3, 1, -7, 5, 0, 9, -9, 7, -5], [-9, -4, 22, -14, 9, 2, 7, -6, -8], [-6, -3, 15, -9, 9, 11, -2, 1, -13], [-5, 8, 2, -18, 7, -1, 8, -7, 0], [4, 6, -14, 2, 1, -5, 6, 5, -3], [-11, 5, 17, -27, 16, 10, 6, -6, -13]]);
- P:=Matrix([[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1]]);
- L:=Matrix([[1, 0, 0, 0, 0, 0], [-3, 1, 0, 0, 0, 0], [-5/3, -29/3, 1, 0, 0, 0], [4/3, -14/3, 43/94, 1, 0, 0], [-2, 1, 0, 0, 1, 0], [-11/3, -26/3, 1, 0, 0, 1]]);
- U:=Matrix([[3, 1, 0, 9, -7, 5, -9, 7, -5], [0, -1, 9, 29, 1, 1, -20, 15, -23], [0, 0, 94, 883/3, 0, 0, -601/3, 449/3, -692/3], [0, 0, 0, -1533/94, 0, 0, 1533/94, -263/94, 87/47], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]]);
- Q:=Matrix([[1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1]]);
- > with(LinearAlgebra):
- > MatrixAdd(A,-P.L.U.Q);
- [0 0 0 0 0 0 0 0 0]
- [ ]
- [0 0 0 0 0 0 0 0 0]
- [ ]
- [0 0 0 0 0 0 0 0 0]
- [ ]
- [0 0 0 0 0 0 0 0 0]
- [ ]
- [0 0 0 0 0 0 0 0 0]
- [ ]
- [0 0 0 0 0 0 0 0 0]
- documentclass[a4paper]{article}
- usepackage[hscale=0.85, vscale=0.85]{geometry}
- usepackage{xintfrac}
- usepackage{xinttools}
- usepackage{array}
- % usepackage {siunitx}
- % usepackage {numprint}
- catcode`_ 11
- makeatletter
- newwriteMATout
- immediateopenoutMATout=jobname.pluqoutrelax
- % (the typeout format is for input in Maple for example)
- defMATtypeout {MATtypeoutwith {MATtypeoutone}}%
- defMATtypeoutone #1{xintPRaw{xintRawWithZeros{#1}}}% (lacking an xintPRawWithZeros)
- defMATtypeoutwith #1#2#3{%
- edefI{xintSeq {1}{#3[I]}}% indices for rows
- edefJ{xintSeq {1}{#3[J]}}% indices for columns
- immediatewriteMATout{#2:=Matrix([[%
- xintListWithSep {], [}{xintApply { MAT_typeout_row {#1}#3}{I}}%
- ]]);}%
- }%
- defMAT_typeout_row #1#2#3{%
- xintListWithSep {, }{xintApply { MAT_typeout_one {#1}#2{#3}}{J}}%
- }%
- defMAT_typeout_one #1#2#3#4{#1{#2[#3,#4]}}%
- % we don't need all of them
- newcountMAT_cnta
- newcountMAT_cntb
- newcountMAT_cntc
- newcountMAT_cntd
- newcountMAT_cnte
- % Usage: MATsetmyMatrix{semi-colon separated rows of comma separated values}
- % example.
- % MATsetMatrixA { 1/3 , 1/4, 1/5 ;
- % 1/6 , 1/7 , 1/8 ;
- % 1/9 , 1/10 , 1/11 ; }
- % The final semi-colon is optional.
- % We indeed focus here on manipulating matrices with rational entries, the
- % code at https://tex.stackexchange.com/a/143035/4686 has the set-up for
- % floating point numbers too (in an arbitrary, user decided precision).
- defMATset {defMAT_xintin {xintRaw}MATset_ }%
- defMATset_ #1#2{%
- defMATset_name{#1}%
- edefMAT_tmpa {#2}%
- MAT_cnta xint_c_ % sets MAT_cnta to zero
- expandafterMATset_a
- romannumeral0expandafterxintzapspacesexpandafter{MAT_tmpa};!;%
- }%
- defMATset_a {futureletXINT_tokenMATset_b }%
- defMATset_b #1;{defMAT_tmpa{#1}%
- ifxXINT_token;expandafterMATset_w
- else
- ifxXINT_token!%
- expandafterexpandafterexpandafterMATset_x
- else
- expandafterexpandafterexpandafterMATset_c
- fifi }%
- defMATset_w !;{MATset_x }%
- defMATset_x {expandafterdef
- csname MAT@expandafterstringMATset_name {I}expandafterendcsname
- expandafter {theMAT_cnta }%
- expandafterdef
- csname MAT@expandafterstringMATset_name {J}expandafterendcsname
- expandafter {theMAT_cntb }%
- expandafteredef MATset_name [##1]%
- {noexpandcsname MAT@expandafterstringMATset_name
- noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
- }%
- % a bit convoluted, no comments.
- defMAT_in #1,#2,{xint_bye #2xint_gobble_ivxint_bye
- {thenumexpr #1}{thenumexpr #2}xint_gobble_iii
- {xintZapSpaces{#1}}}%
- defMATset_c {advanceMAT_cnta xint_c_i % row count ++
- MAT_cntb xint_c_ % column count initially zero
- expandafterMATset_dromannumeral0expandafter
- xintzapspacesexpandafter {MAT_tmpa},!,}%
- defMATset_d {futureletXINT_tokenMATset_e }%
- defMATset_e #1,{ifxXINT_token!expandafterMATset_a
- else
- advanceMAT_cntb xint_c_i
- expandafterdef
- csname MAT@expandafterstringMATset_name
- {theMAT_cnta}{theMAT_cntb}expandafterendcsname
- expandafter{romannumeral-`0MAT_xintin{xintZapSpacesB{#1}}}%
- expandafterMATset_dfi
- }%
- % removed toks2 et toks4 usage from https://tex.stackexchange.com/a/143035/4686
- defMATlet #1#2{%
- edefMAT@seqI{xintSeq {1}{#2[I]}}%
- edefMAT@seqJ{xintSeq {1}{#2[J]}}%
- xintFor* ##1 in {MAT@seqI}
- do{xintFor* ##2 in {MAT@seqJ}
- do{expandafterlet
- csname MAT@string#1{##1}{##2}expandafterendcsname
- csname MAT@string#2{##1}{##2}endcsname
- }}%
- expandafteredefcsname MAT@string#1{I}endcsname {#2[I]}%
- expandafteredefcsname MAT@string#1{J}endcsname {#2[J]}%
- edef #1[##1]%
- {noexpandcsname
- MAT@string#1noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
- }%
- % We need identity matrices.
- % again copied as is from https://tex.stackexchange.com/a/143035/4686
- % IDENTITY MATRIX
- % usage MATidfoo{37} defines a 37 times 37 identity matrix.
- defMATid {defMAT_tmpf{/1}MAT_id }%
- %defMATfloatid {defMAT_tmpf{}MAT_id }%
- % This identity matrix insists on coefficients written internally
- % 0[0] or 1[0], this is a remnant of
- % https://tex.stackexchange.com/a/143035/4686 whose aim is is minuscule
- % optimization when these numbers are involved in computations done by
- % the xintfrac macros.
- defMAT_id #1#2{%
- MAT_cntc #2relax
- MAT_cnta xint_c_i % 1
- xintloop
- {expandafterdefexpandafterMAT_tmpa expandafter{theMAT_cnta}%
- MAT_cntb xint_c_i % 1
- xintloop
- expandafteredef
- csname MAT@string#1{MAT_tmpa}{theMAT_cntb}endcsname
- {ifnumMAT_cntb=MAT_cnta 1else 0fi MAT_tmpf[0]}%
- ifnumMAT_cntb<MAT_cntc
- advanceMAT_cntb xint_c_i
- repeat
- ifnumMAT_cnta<MAT_cntc
- advanceMAT_cnta xint_c_i
- }repeat
- expandafterdefcsname MAT@string#1{I}expandafterendcsname
- expandafter {theMAT_cntc}%
- expandafterdefcsname MAT@string#1{J}expandafterendcsname
- expandafter {theMAT_cntc}%
- edef #1[##1]%
- {noexpandcsname
- MAT@string#1noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
- }%
- % EXCHANGING ROWS OR COLUMNS OF A GIVEN MATRIX
- defMATexchangecol #1#2#3{%
- MAT_cnta=#3[I]relax
- MAT_cntb=xint_c_i % 1
- xintloop
- expandafterletexpandafterMAT@tmp
- csname MAT@string#3{theMAT_cntb}{#1}endcsname
- expandafterlet
- csname MAT@string#3{theMAT_cntb}{#1}expandafterendcsname
- csname MAT@string#3{theMAT_cntb}{#2}endcsname
- expandafterlet
- csname MAT@string#3{theMAT_cntb}{#2}endcsname
- MAT@tmp
- ifnumMAT_cntb<MAT_cnta
- advanceMAT_cntbxint_c_i
- repeat
- }%
- % perhaps only columns "to the right" actually need exchange in usage of this
- defMATexchangerow #1#2#3{%
- MAT_cnta=#3[J]relax
- MAT_cntb=xint_c_i % 1
- xintloop
- expandafterletexpandafterMAT@tmp
- csname MAT@string#3{#1}{theMAT_cntb}endcsname
- expandafterlet
- csname MAT@string#3{#1}{theMAT_cntb}expandafterendcsname
- csname MAT@string#3{#2}{theMAT_cntb}endcsname
- expandafterlet
- csname MAT@string#3{#2}{theMAT_cntb}endcsname
- MAT@tmp
- ifnumMAT_cntb<MAT_cnta
- advanceMAT_cntbxint_c_i
- repeat
- }%
- defMATexchangerowspecial #1#2#3{%#1>#2, only columns <#2 need update
- MAT_cnta=#2relax
- MAT_cntb=xint_c_ % 0
- xintloop
- advanceMAT_cntbxint_c_i
- ifnumMAT_cntb<MAT_cnta
- expandafterletexpandafterMAT@tmp
- csname MAT@string#3{#1}{theMAT_cntb}endcsname
- expandafterlet
- csname MAT@string#3{#1}{theMAT_cntb}expandafterendcsname
- csname MAT@string#3{#2}{theMAT_cntb}endcsname
- expandafterlet
- csname MAT@string#3{#2}{theMAT_cntb}endcsname
- MAT@tmp
- repeat
- }%
- % Usage:
- % MATpluqA (A previously defined by MATset)
- % Effect: sets P, L, U, Q, to matrices in the sense of MATset,
- % so that "A=PLUQ" and it writes all matrices out
- % to some file. See initial answer about row reduction for typesetting
- % in document.
- % The code is a simple adaptation of this initial answer. Now I use MATpluq
- % prefix.
- defMATpluq #1{%
- % begingroup
- MATlet@U#1%
- edefMATpluq@rows{@U[I]}% nb of rows
- edefMATpluq@cols{@U[J]}% nb of columns.
- MATid@PMATpluq@rows
- MATid@LMATpluq@rows
- MATid@QMATpluq@cols
- defMATpluq@pivrow {0}%
- defMATpluq@pivcol {0}%
- %edefMATpluq@name {string#1}%
- letMATpluq@ifcontinueiftrue
- % Starting the reduction.
- MATtypeout{^^JA}#1%
- [A = MATdisplay@U]
- xintloop
- % Nota Bene: in the PLUQ reduction, the pivots are anyhow organized
- % along the main diagonal so pivrow and pivcol will be kept in sync over
- % the execution of the algorithm but we use two variables nevertheless.
- edefMATpluq@pivrow{thenumexprMATpluq@pivrow+xint_c_i}%
- edefMATpluq@pivcol{thenumexprMATpluq@pivcol+xint_c_i}%
- MATpluq@dopiv
- MATpluq@ifcontinue
- repeat
- % Done. The rank of the matrix is thenumexprMATpluq@pivrow-xint_c_i.par
- % endgroup
- MATtypeout{P}@P
- MATtypeout{L}@L
- MATtypeout{U}@U
- MATtypeout{Q}@Q
- [ P = MATdisplay@P]
- [ L = MATdisplay@Lqquad U = MATdisplay@U]
- [ Q = MATdisplay@Q]
- }
- defMATpluq@done {letMATpluq@ifcontinueiffalse}
- % Remark on algorithm: I hesitated about doing column permutations first,
- % rather than row permutations with the idea to recognize faster an entirely
- % vanishing row, so that we can put it at the end and ignore it entirely, in
- % effect reducing the number of rows by one, and possibly making algorithm
- % faster. But for simplicity I just keep algorithm close to the one as in my
- % initial answer. We only have to keep track in P, L, Q of the needed
- % operations.
- defMATpluq@dopiv{%
- letMATpluq@rowMATpluq@pivrow
- letMATpluq@colMATpluq@pivcol
- ifnumMATpluq@row>MATpluq@rowsrelax
- MATpluq@done
- else
- ifnumMATpluq@col>MATpluq@colsrelax
- MATpluq@done
- else
- expandafterexpandafterexpandafterMATpluq@dopiv@i
- fi
- fi
- }
- defMATpluq@dopiv@i{%
- edefMATpluq@piv@value{@U[MATpluq@row,MATpluq@col]}%
- xintifZero{MATpluq@piv@value}
- MATpluq@dopiv@steprow
- MATpluq@dopiv@ii
- }
- defMATpluq@dopiv@steprow{%
- ifnumMATpluq@row=MATpluq@rowsrelax
- par No pivot found in column MATpluq@col.par
- letMATpluq@rowMATpluq@pivrow
- expandafterMATpluq@dopiv@stepcol
- else
- edefMATpluq@row{thenumexprMATpluq@row+xint_c_i}%
- expandafterMATpluq@dopiv@i
- fi
- }
- defMATpluq@dopiv@stepcol{%
- ifnumMATpluq@col=MATpluq@colsrelax
- MATpluq@done
- else
- edefMATpluq@col{thenumexprMATpluq@col+xint_c_i}%
- expandafterMATpluq@dopiv@i
- fi
- }
- % found a pivot
- defMATpluq@dopiv@ii{%
- Pivot MATpluqprintonevalue{MATpluq@piv@value} at MATpluq@row, MATpluq@col.par
- ifnumMATpluq@col>MATpluq@pivcolrelax
- Exchange of columns MATpluq@pivcolspace and MATpluq@col.par
- MATexchangerow{MATpluq@col}{MATpluq@pivcol}@Q
- MATexchangecol{MATpluq@col}{MATpluq@pivcol}@U
- [U = MATdisplay@Uqquad Q = MATdisplay@Q]
- fi
- ifnumMATpluq@pivrow=MATpluq@rowsrelax
- edefMATpluq@pivrow{thenumexprMATpluq@pivrow+xint_c_i}%
- MATpluq@done
- else
- expandafterMATpluq@dopiv@iii
- fi
- }
- defMATpluq@dopiv@iii{%
- ifnumMATpluq@row>MATpluq@pivrowrelax
- Exchange of rows MATpluq@pivrowspace and MATpluq@row.par
- MATexchangecol{MATpluq@row}{MATpluq@pivrow}@P
- MATexchangerow{MATpluq@row}{MATpluq@pivrow}@U
- MATexchangerowspecial{MATpluq@row}{MATpluq@pivrow}@L
- [L = MATdisplay@Lqquad U = MATdisplay@U]
- [P = MATdisplay@P]
- fi
- MAT_cntcMATpluq@pivrowrelax% we are guaranteed < nb of rows
- xintloop
- advanceMAT_cntcxint_c_i
- edefMATpluq@entry{@U[MAT_cntc,MATpluq@pivcol]}%
- xintifZeroMATpluq@entry
- {% nothing to do, the L coeff is already set to zero
- }%
- {edefMATpluq@ratio
- {xintIrr{xintDiv{MATpluq@entry}{MATpluq@piv@value}}[0]}%
- expandafterlet
- csname MAT@string@L{theMAT_cntc}{MATpluq@pivcol}endcsname
- MATpluq@ratio
- Subtract from row theMAT_cntcspace the pivot row multiplied by
- MATpluqprintonevalue{MATpluq@ratio}.par
- @namedef{MAT@string@U{theMAT_cntc}{MATpluq@pivcol}}{0[0]}%
- MAT_cntdMATpluq@pivcolrelax
- xintloop
- advanceMAT_cntdxint_c_i
- unlessifnumMATpluq@cols<MAT_cntd
- expandafteredef
- csname MAT@string@U{theMAT_cntc}{theMAT_cntd}endcsname
- {xintIrr{%
- xintSub{@U[MAT_cntc,MAT_cntd]}
- {xintMul{MATpluq@ratio}{@U[MATpluq@pivrow,MAT_cntd]}}%
- }[0]}%
- repeat
- }%
- unlessifnumMATpluq@rows=MAT_cntc
- repeat
- [L = MATdisplay@Lqquad U = MATdisplay@U]
- }
- defMATpluqprintonevalue{xintPRaw}
- %defMATpluqdisplay#1{[MATdisplay#1]}%
- %% MATH MODE MATRIX DISPLAY
- makeatother
- newcommandMATdisplay [1][1.25]{MATdisplaywith [#1]{MATdisplayone}}
- defMATdisplayone {xintSignedFrac}
- newcolumntypeMATdisplaycoltype {c}
- newcolumntypeMATdisplaypreamble [1]{@{}*{#1[J]}MATdisplaycoltype@{}}
- newcommandMATdisplaywith [3][1.25]
- {left(defarraystretch{#1}%
- begin{array}{MATdisplaypreamble {#3}}
- xintListWithSep {\}
- {xintApply { MAT_display_row {#2}#3}{xintSeq {1}{#3[I]}}}
- end{array}right)%
- }%
- defMAT_display_row #1#2#3{%
- xintListWithSep {&}
- {xintApply{ MAT_display_one {#1}#2{#3}}{xintSeq {1}{#2[J]}}}%
- }%
- defMAT_display_one #1#2#3#4{#1{#2[#3,#4]}}%
- catcode`_ 8
- begin{document}pagestyle{empty}
- MATsetMatrixA { 1/3 , 1/4, 1/5 ;
- 1/6 , 1/7 , 1/8 ;
- 1/9 , 1/10 , 1/11 ; }
- MATpluqMatrixA
- See pluqout file.clearpage
- MATsetA {
- 3, -7, 5, 0, 1, 0, 1;
- -9, -8, -2, 9, -1, 9, -4;
- 4, 6, 0, -1, -2, -1, -3;
- -5, 2, -6, 7, 8, 7, 8;
- -1, -2, -1, -3, 4, 6, 0;
- 7, 8, 7, 8, -5, 2, -6;
- }
- MATpluqA
- See pluqout file.clearpage
- MATsetA {
- 2, 0, 3, 0;
- 1, 0, 0, 0;
- 0, 0, 4, 0;
- 0, 2, 0, 1;
- }
- MATpluqA
- See pluqout file.clearpage
- MATsetMatrixB {
- 3, 1, -7, 5, 0, 9, -9, 7, -5;
- -9, -4, -8, -2, 9, 2, 8, -6, -8;
- 4, -3, 6, 0, -1, 5, -4, -3, 4;
- -5, 8, 2, -6, 7, -1, 1, -7, 0;
- 3, 6, -2, -1, 8, -2, -6, 7, -7;
- 4, 6, 3, -9, 1, -5, 0, 5, -3;
- }
- MATpluqMatrixB
- See pluqout file.clearpage
- MATsetMatrixC {
- 3, 1, -7, 5, 0, 9, -9, 7, -5;
- -9, -4, 22, -14, 9, 2, 7, -6, -8;
- -6, -3, 15, -9, 9, 11, -2, 1, -13;
- -5, 8, 2, -18, 7, -1, 8, -7, 0;
- 4, 6, -14, 2, 1, -5, 6, 5, -3;
- -11, 5, 17, -27, 16, 10, 6, -6, -13;
- }
- MATpluqMatrixC
- See pluqout file for the matrices in Maple format.clearpage
- immediatecloseoutMATout
- end{document}
- documentclass{article}
- usepackage{xintfrac}
- usepackage{xinttools}
- usepackage{array}
- catcode`_ 11
- makeatletter
- newcountMAT_cnta
- newcountMAT_cntb
- newcountMAT_cntc
- newcountMAT_cntd
- newcountMAT_cnte
- % Usage: MATsetmyMatrix{semi-colon separated rows of comma separated values}
- % example.
- % MATsetMatrixA { 1/3 , 1/4, 1/5 ;
- % 1/6 , 1/7 , 1/8 ;
- % 1/9 , 1/10 , 1/11 ; }
- defMATset {defMAT_xintin {xintRaw}MATset_ }%
- defMATset_ #1#2{%
- defMATset_name{#1}%
- edefMAT_tmpa {#2}%
- MAT_cnta xint_c_ % sets MAT_cnta to zero
- expandafterMATset_a
- romannumeral0expandafterxintzapspacesexpandafter{MAT_tmpa};!;%
- }%
- defMATset_a {futureletXINT_tokenMATset_b }%
- defMATset_b #1;{defMAT_tmpa{#1}%
- ifxXINT_token;expandafterMATset_w
- else
- ifxXINT_token!%
- expandafterexpandafterexpandafterMATset_x
- else
- expandafterexpandafterexpandafterMATset_c
- fifi }%
- defMATset_w !;{MATset_x }%
- defMATset_x {expandafterdef
- csname MAT@expandafterstringMATset_name {I}expandafterendcsname
- expandafter {theMAT_cnta }%
- expandafterdef
- csname MAT@expandafterstringMATset_name {J}expandafterendcsname
- expandafter {theMAT_cntb }%
- expandafteredef MATset_name [##1]%
- {noexpandcsname MAT@expandafterstringMATset_name
- noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
- }%
- %
- defMAT_in #1,#2,{xint_bye #2xint_gobble_ivxint_bye
- {thenumexpr #1}{thenumexpr #2}xint_gobble_iii
- {xintZapSpaces{#1}}}%
- %
- defMATset_c {advanceMAT_cnta xint_c_i % row count ++
- MAT_cntb xint_c_ % column count initially zero
- expandafterMATset_dromannumeral0expandafter
- xintzapspacesexpandafter {MAT_tmpa},!,}%
- defMATset_d {futureletXINT_tokenMATset_e }%
- defMATset_e #1,{ifxXINT_token!expandafterMATset_a
- else
- advanceMAT_cntb xint_c_i
- expandafterdef
- csname MAT@expandafterstringMATset_name
- {theMAT_cnta}{theMAT_cntb}expandafterendcsname
- expandafter{romannumeral-`0MAT_xintin{xintZapSpacesB{#1}}}%
- expandafterMATset_dfi
- }%
- defMATlet #1#2{%
- edefMAT@seqI{xintSeq {1}{#2[I]}}%
- edefMAT@seqJ{xintSeq {1}{#2[J]}}%
- xintFor* ##1 in {MAT@seqI}
- do{xintFor* ##2 in {MAT@seqJ}
- do{expandafterlet
- csname MAT@string#1{##1}{##2}expandafterendcsname
- csname MAT@string#2{##1}{##2}endcsname
- }}%
- expandafteredefcsname MAT@string#1{I}endcsname {#2[I]}%
- expandafteredefcsname MAT@string#1{J}endcsname {#2[J]}%
- edef #1[##1]%
- {noexpandcsname
- MAT@string#1noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
- }%
- defMATrowreduce #1{%
- begingroup
- edefMATrr@rows{#1[I]}%
- edefMATrr@cols{#1[J]}%
- defMATrr@pivrow {0}%
- defMATrr@pivcol {0}%
- MATlet@U #1%
- letMATrr@ifcontinueiftrue
- Starting the reduction.
- MATrrdisplaymatrix@U
- xintloop
- edefMATrr@pivrow{thenumexprMATrr@pivrow+xint_c_i}%
- edefMATrr@pivcol{thenumexprMATrr@pivcol+xint_c_i}%
- MATrr@dopiv
- MATrr@ifcontinue
- repeat
- Done. The rank of the matrix is thenumexprMATrr@pivrow-xint_c_i.par
- endgroup
- }
- defMATrr@done {letMATrr@ifcontinueiffalse}
- defMATrr@dopiv{%
- letMATrr@rowMATrr@pivrow
- letMATrr@colMATrr@pivcol
- ifnumMATrr@row>MATrr@rowsrelax
- MATrr@done
- else
- ifnumMATrr@col>MATrr@colsrelax
- MATrr@done
- else
- expandafterexpandafterexpandafterMATrr@dopiv@i
- fi
- fi
- }
- defMATrr@dopiv@i{%
- edefMATrr@piv@value{@U[MATrr@row,MATrr@pivcol]}%
- xintifZero{MATrr@piv@value}
- MATrr@dopiv@steprow
- MATrr@dopiv@ii
- }
- defMATrr@dopiv@steprow{%
- ifnumMATrr@row=MATrr@rowsrelax
- letMATrr@rowMATrr@pivrow
- par No pivot found in column MATrr@pivcol.par
- expandafterMATrr@dopiv@stepcol
- else
- edefMATrr@row{thenumexprMATrr@row+xint_c_i}%
- expandafterMATrr@dopiv@i
- fi
- }
- defMATrr@dopiv@stepcol{%
- ifnumMATrr@pivcol=MATrr@colsrelax
- MATrr@done
- else
- edefMATrr@pivcol{thenumexprMATrr@pivcol+xint_c_i}%
- expandafterMATrr@dopiv@i
- fi
- }
- defMATrr@dopiv@ii{%
- ifnumMATrr@pivrow=MATrr@rowsrelax
- edefMATrr@pivrow{thenumexprMATrr@pivrow+xint_c_i}MATrr@done
- else
- expandafterMATrr@dopiv@iii
- fi
- }
- defMATrr@dopiv@iii{%
- Now using the pivot with value MATrrprintonevalue{MATrr@piv@value}
- at row MATrr@rowspace and column MATrr@pivcol.par
- ifnumMATrr@row>MATrr@pivrowrelax
- Exchange of row MATrr@rowspace with row MATrr@pivrow.par
- MAT_cntb=MATrr@pivcolrelax
- xintloop
- expandafterletexpandafterMAT@tmp
- csname MAT@string@U{MATrr@row}{theMAT_cntb}endcsname
- expandafterlet
- csname MAT@string@U{MATrr@row}{theMAT_cntb}expandafterendcsname
- csname MAT@string@U{MATrr@pivrow}{theMAT_cntb}endcsname
- expandafterlet
- csname MAT@string@U{MATrr@pivrow}{theMAT_cntb}endcsname
- MAT@tmp
- ifnumMATrr@cols>MAT_cntb
- advanceMAT_cntbxint_c_i
- repeat
- MATrrdisplaymatrix@Upar
- fi
- MAT_cntcMATrr@pivrow
- xintloop
- advanceMAT_cntcxint_c_i
- edefMATrr@entry{@U[MAT_cntc,MATrr@pivcol]}%
- xintifZeroMATrr@entry
- {}%
- {edefMATrr@ratio{xintIrr{xintDiv{MATrr@entry}{MATrr@piv@value}}[0]}%
- Subtract from row theMAT_cntcspace the pivot row multiplied by
- MATrrprintonevalue{MATrr@ratio}.par
- @namedef{MAT@string@U{theMAT_cntc}{MATrr@pivcol}}{0[0]}%
- MAT_cntdMATrr@pivcolrelax
- xintloop
- advanceMAT_cntdxint_c_i
- unlessifnumMATrr@cols<MAT_cntd
- expandafteredef
- csname MAT@string@U{theMAT_cntc}{theMAT_cntd}endcsname
- {xintIrr{%
- xintSub{@U[MAT_cntc,MAT_cntd]}
- {xintMul{MATrr@ratio}{@U[MATrr@pivrow,MAT_cntd]}}%
- }[0]}%
- repeat
- }%
- unlessifnumMATrr@rows=MAT_cntc
- repeat
- MATrrdisplaymatrix@U
- }
- defMATrrprintonevalue{xintPRaw}
- defMATrrdisplaymatrix #1{[MATdisplay#1]}%
- %% MATH MODE MATRIX DISPLAY
- makeatother
- newcommandMATdisplay [1][1.25]{MATdisplaywith [#1]{MATdisplayone}}
- defMATdisplayone {xintSignedFrac}
- newcolumntypeMATdisplaycoltype {c}
- newcolumntypeMATdisplaypreamble [1]{@{}*{#1[J]}MATdisplaycoltype@{}}
- newcommandMATdisplaywith [3][1.25]
- {left(defarraystretch{#1}%
- begin{array}{MATdisplaypreamble {#3}}
- xintListWithSep {\}
- {xintApply { MAT_display_row {#2}#3}{xintSeq {1}{#3[I]}}}
- end{array}right)%
- }%
- defMAT_display_row #1#2#3{%
- xintListWithSep {&}
- {xintApply{ MAT_display_one {#1}#2{#3}}{xintSeq {1}{#2[J]}}}%
- }%
- defMAT_display_one #1#2#3#4{#1{#2[#3,#4]}}%
- catcode`_ 8
- begin{document}
- MATsetMatrixC {
- 3, 1, -7, 5, 0, 9, -9, 7, -5;
- -9, -4, -8, -2, 9, 2, 8, -6, -8;
- -6, -3, -15, 3, 9, 11, -1, 1, -13;
- -5, 8, 2, -6, 7, -1, 1, -7, 0;
- 4, 6, 3, -9, 1, -5, 0, 5, -3;
- -11, 5, -13, -3, 16, 10, 0, -6, -13;
- }
- MATrowreduceMatrixC
- end{document}
- defMATrrprintonevalue{xintRound{2}}
- defMATrrdisplaymatrix #1{[MATdisplaywith{xintRound{2}}#1]}%
- defMATrrprintonevalue#1{xintTrunc{3}{#1}dots (=xintPRaw{#1})}
- defMATrrdisplaymatrix #1{[MATdisplay#1=MATdisplaywith{TruncWithDots{3}}#1]}%
- defTruncWithDots #1#2{xintTrunc{#1}{#2}...}
- MATsetMatrixA { 1/3 , 1/4, 1/5 ;
- 1/6 , 1/7 , 1/8 ;
- 1/9 , 1/10 , 0.09 ; }
- MATrowreduceMatrixA
Add Comment
Please, Sign In to add comment