Guest User

Untitled

a guest
Nov 19th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.89 KB | None | 0 0
  1. % Givens rotation
  2. % I assume #1 < #2
  3. % does not use theta because it is unstable
  4. % #4 is cosine and #5 is sine
  5. defpgflabgivensrotaterow #1 and row #2 by #3 and #4 in #5{
  6. pgfkeys{/lab/#5/w/.get=pgflabw}
  7. pgfplotsforeachungroupedg@j in{1,...,pgflabw}{
  8. pgfkeys{/lab/#5/#1/g@j/.get=pgflabtempentrya}
  9. pgfkeys{/lab/#5/#2/g@j/.get=pgflabtempentryb}
  10. pgfmathparse{#3*pgflabtempentrya-#4*pgflabtempentryb}
  11. pgfkeys{/lab/#5/#1/g@j/.let=pgfmathresult}
  12. pgfmathparse{#4*pgflabtempentrya+#3*pgflabtempentryb}
  13. pgfkeys{/lab/#5/#2/g@j/.let=pgfmathresult}
  14. }
  15. }
  16.  
  17. % I assume #1 < #2
  18. % does not use theta because it is unstable
  19. % #4 is cosine and #5 is sine
  20. defpgflabgivensrotatecol #1 and col #2 by #3 and #4 in #5{
  21. pgfkeys{/lab/#5/h/.get=pgflabh}
  22. pgfplotsforeachungroupedg@i in{1,...,pgflabh}{
  23. pgfkeys{/lab/#5/g@i/#1/.get=pgflabtempentrya}
  24. pgfkeys{/lab/#5/g@i/#2/.get=pgflabtempentryb}
  25. pgfmathparse{#3*pgflabtempentrya-#4*pgflabtempentryb}
  26. pgfkeys{/lab/#5/g@i/#1/.let=pgfmathresult}
  27. pgfmathparse{#4*pgflabtempentrya+#3*pgflabtempentryb}
  28. pgfkeys{/lab/#5/g@i/#2/.let=pgfmathresult}
  29. }
  30. }
  31.  
  32. % A = QR decomposition
  33. defpgflabQRdecompose #1 as #2 times #3{
  34. pgfkeys{/lab/#1/w/.get=pgflabW}
  35. pgfkeys{/lab/#1/h/.get=pgflabH}
  36. % decide the loop boundary
  37. edefpgflab@H-1{thenumexprpgflabH-1}
  38. ifnumpgflab@H-1>pgflabW
  39. edefpgflab@H-1{pgflabW}
  40. fi
  41. % set Q as identity
  42. % set #2 as identity
  43. pgflabneweyeof {pgflabH} by {pgflabH} as {#2}
  44. % copy A to R
  45. % copy #1 to #3
  46. pgflabcopymatrix {#1} to {#3}
  47. % forget A, do job at Q and R
  48. % forget #1, do job at #2 and #3
  49. pgfplotsforeachungroupedd@i in{1,...,pgflab@H-1}{
  50. edefd@@i+1{thenumexprd@i+1}
  51. pgfplotsforeachungroupedd@j in{d@@i+1,...,pgflabh}{
  52. pgfkeys{/lab/#3/d@i/d@i/.get=pgflabtempentrya}
  53. pgfkeys{/lab/#3/d@j/d@i/.get=pgflabtempentryb}
  54. pgfmathsetmacropgflabtempradius{sqrt(pgflabtempentrya*pgflabtempentrya+pgflabtempentryb*pgflabtempentryb)}
  55. pgfmathsetmacropgflabtempcos{ pgflabtempentrya/pgflabtempradius} % cosine
  56. pgfmathsetmacropgflabtempsin{-pgflabtempentryb/pgflabtempradius} % sine
  57. pgflabgivensrotaterow {d@i} and row {d@j} by {pgflabtempcos} and {pgflabtempsin} in {#3}
  58. pgflabgivensrotatecol {d@i} and col {d@j} by {pgflabtempcos} and {pgflabtempsin} in {#2}
  59. eliminate one entry. check Q and Rpar
  60. $Q=pgflabtypeset{#2};$
  61. $R=pgflabtypeset{#3};$
  62. }
  63. }
  64. }
  65. pgflabread{A}{
  66. 0 0 0 1
  67. 1 0 0 0
  68. 0 1 0 0
  69. 0 0 1 0
  70. }
  71. pgflabQRdecompose A as Q times R
  72.  
  73. documentclass{article}
  74. usepackage[a3paper,landscape,margin=1cm]{geometry}
  75. usepackage{pgfplotstable,mathtools}
  76. pgfplotsset{compat=newest}
  77. pgfkeys{/pgf/fpu,/pgf/number format/fixed}
  78. begin{document}
  79.  
  80.  
  81. makeatletter
  82. % pgfmatrix... is used
  83. % we use pgflab...
  84.  
  85. % call pgfplotstable to read the data
  86. % put options in [] if desired
  87. % the options go to pgfplotstableread
  88. defpgflabread{
  89. pgfutil@ifnextchar[
  90. {pgflabread@opt}
  91. {pgflabread@opt[]}
  92. }
  93.  
  94. % #1: optional option
  95. % #2: a name of the matrix... usually A
  96. defpgflabread@opt[#1]#2{
  97. edefpgflabname{#2}
  98. pgfplotstableread[header=false,#1]
  99. }
  100.  
  101. % we did not provide a macro to pgfplotstable to store the table
  102. % we give it a temporary one called pgflabtemptable
  103. % and then copy it to our data structure
  104. longdefpgfplotstableread@impl@collectfirstarg#1#2{
  105. pgfplotstableread@impl@{#1}{#2}pgflabtemptable
  106. pgflabconverttablepgflabtemptable to matrix{pgflabname}
  107. }
  108.  
  109. % this helps us to deal with pgfleys
  110. pgfkeys{/handlers/.let/.code=pgfkeyslet{pgfkeyscurrentpath}{#1}}
  111.  
  112. % copy pgfplotstable table to our data structure in pgfkeys
  113. % #1: the macro that pgfplotstable used to store the table
  114. % #2: a name of the matrix
  115. defpgflabconverttable#1to matrix#2{
  116. % extract height and width
  117. pgfplotstablegetrowsof#1xdefpgflabh{pgfplotsretval}pgfkeys{/lab/#2/h/.let=pgflabh}
  118. %%%height = pgflabh par
  119. pgfplotstablegetcolsof#1xdefpgflabw{pgfplotsretval}pgfkeys{/lab/#2/w/.let=pgflabw}
  120. %%%width = pgflabw par
  121. % extract entries
  122. % c@i and c@j cannot be used outside
  123. pgfplotsforeachungroupedc@i in{1,...,pgflabh}{
  124. pgfplotsforeachungroupedc@j in{1,...,pgflabw}{
  125. % since fpu is on, this is easier way to do 9-1
  126. pgfplotstablegetelem{thenumexprc@i-1}{thenumexprc@j-1}ofpgflabtemptable
  127. pgfkeys{/lab/#2/c@i/c@j/.let=pgfplotsretval}
  128. %%%pgfplotsretval,
  129. }
  130. %%%; par
  131. }
  132. }
  133. pgflabread{A}{
  134. 3 1 -7 5 0
  135. -9 -4 -8 -2 9
  136. 4 -3 6 0 -1
  137. -5 8 2 -6 7
  138. }
  139.  
  140. % the opposite of the previous one
  141. % #1: the name of the matrix
  142. % #2: a macro for pgfplotstable to store the table
  143. defpgflabconvertmatrix #1 to table #2{
  144. % makeup meta data
  145. expandafterdefcsnamestring#2@@table@nameendcsname{<inline_table>}
  146. % build a new list of columns
  147. pgfkeys{/lab/#1/h/.get=pgflabh}
  148. pgfkeys{/lab/#1/w/.get=pgflabw}
  149. pgfplotslistnew#2{0,...,thenumexprpgflabw-1}
  150. % fill in columns
  151. pgfplotsforeachungroupedc@j in{1,...,pgflabw}{
  152. pgfplotslistnewemptypgflabtempcolumn
  153. pgfplotsforeachungroupedc@i in{1,...,pgflabh}{
  154. pgfkeys{/lab/#1/c@i/c@j/.get=pgflabtempentry}
  155. expandafterpgfplotslistpushbackpgflabtempentrytopgflabtempcolumn
  156. }
  157. edefc@k{thenumexprc@j-1}
  158. expandafterletcsnamestring#2@c@kendcsnamepgflabtempcolumn
  159. }
  160. }
  161.  
  162. % typeset the matrix by pgfplotstabletypeset
  163. defpgflabtypeset{
  164. pgfutil@ifnextchar[
  165. {pgflabtypeset@opt}
  166. {pgflabtypeset@opt[]}
  167. }
  168.  
  169. % #1: optional option
  170. % #2: the name of the matrix
  171. defpgflabtypeset@opt[#1]#2{
  172. pgflabconvertmatrix #2 to table pgflabtemptable
  173. pgfplotstabletypeset[every head row/.style={output empty row}]pgflabtemptable
  174. }
  175. Matrix A is
  176. $A=pgflabtypeset{A}$
  177.  
  178. % define row operation: switch
  179. % does not check boundary
  180. defpgflabswitchrow #1 and row #2 in #3{
  181. pgfkeys{/lab/#3/w/.get=pgflabw}
  182. pgfplotsforeachungroupeds@j in{1,...,pgflabw}{
  183. pgfkeys{/lab/#3/#1/s@j/.get=pgflabtempentrya}
  184. pgfkeys{/lab/#3/#2/s@j/.get=pgflabtempentryb}
  185. pgfkeys{/lab/#3/#1/s@j/.let=pgflabtempentryb}
  186. pgfkeys{/lab/#3/#2/s@j/.let=pgflabtempentrya}
  187. }
  188. }
  189. bigskip
  190. pgflabswitchrow 1 and row 3 in A
  191. switch row 1 and row 3;
  192. $A=pgflabtypeset{A}$
  193.  
  194. % define column operation: switch
  195. % does not check boundary
  196. defpgflabswitchcol #1 and col #2 in #3{
  197. pgfkeys{/lab/#3/h/.get=pgflabh}
  198. pgfplotsforeachungroupeds@i in{1,...,pgflabh}{
  199. pgfkeys{/lab/#3/s@i/#1/.get=pgflabtempentrya}
  200. pgfkeys{/lab/#3/s@i/#2/.get=pgflabtempentryb}
  201. pgfkeys{/lab/#3/s@i/#1/.let=pgflabtempentryb}
  202. pgfkeys{/lab/#3/s@i/#2/.let=pgflabtempentrya}
  203. }
  204. }
  205. bigskip
  206. pgflabswitchcol 2 and col 3 in A
  207. switch col 2 and col 3;
  208. $A=pgflabtypeset{A}$
  209.  
  210. % define row operation: multiplication
  211. % does not check boundary
  212. defpgflabmultiplyrow #1 by #2 in #3{
  213. pgfkeys{/lab/#3/w/.get=pgflabw}
  214. pgfplotsforeachungroupedm@j in{1,...,pgflabw}{
  215. pgfkeys{/lab/#3/#1/m@j/.get=pgflabtempentry}
  216. pgfmathparse{pgflabtempentry*#2}
  217. pgfkeys{/lab/#3/#1/m@j/.let=pgfmathresult}
  218. }
  219. }
  220. bigskip
  221. pgflabmultiplyrow 3 by -1 in A
  222. multiply row 3 by -1;
  223. $A=pgflabtypeset{A}$
  224.  
  225. % define row operation: addition
  226. % does not check boundary
  227. defpgflabaddrow #1 by row #2 times #3 in #4{
  228. pgfkeys{/lab/#4/w/.get=pgflabw}
  229. pgfplotsforeachungroupeda@j in{1,...,pgflabw}{
  230. pgfkeys{/lab/#4/#1/a@j/.get=pgflabtempentrya}
  231. pgfkeys{/lab/#4/#2/a@j/.get=pgflabtempentryb}
  232. pgfmathparse{pgflabtempentrya+pgflabtempentryb*#3}
  233. pgfkeys{/lab/#4/#1/a@j/.let=pgfmathresult}
  234. }
  235. }
  236. bigskip
  237. pgflabaddrow 2 by row 3 times 2 in A
  238. add row 2 by row 3 times 2;
  239. $A=pgflabtypeset{A}$
  240.  
  241. % define column operation: addition
  242. % does not check boundary
  243. defpgflabaddcol #1 by col #2 times #3 in #4{
  244. pgfkeys{/lab/#4/h/.get=pgflabh}
  245. pgfplotsforeachungroupeda@i in{1,...,pgflabh}{
  246. pgfkeys{/lab/#4/a@i/#1/.get=pgflabtempentrya}
  247. pgfkeys{/lab/#4/a@i/#2/.get=pgflabtempentryb}
  248. pgfmathparse{pgflabtempentrya+pgflabtempentryb*#3}
  249. pgfkeys{/lab/#4/a@i/#1/.let=pgfmathresult}
  250. }
  251. }
  252. bigskip
  253. pgflabaddcol 5 by col 4 times -1 in A
  254. add col 5 by row 4 times -1;
  255. $A=pgflabtypeset{A}$
  256.  
  257. % new identity matrix
  258. defpgflabneweyeof #1 by #2 as #3{
  259. defpgflabh{#1}pgfkeys{/lab/#3/h/.let=pgflabh}
  260. defpgflabw{#2}pgfkeys{/lab/#3/w/.let=pgflabw}
  261. pgfplotsforeachungroupedn@i in{1,...,pgflabh}{
  262. pgfplotsforeachungroupedn@j in{1,...,pgflabw}{
  263. ifnumn@i=n@j
  264. pgfkeys{/lab/#3/n@i/n@i/.initial=1}
  265. else
  266. pgfkeys{/lab/#3/n@i/n@j/.initial=0}
  267. fi
  268. }
  269. }
  270. }
  271. bigskip
  272. pgflabneweyeof 4 by 4 as I
  273. identity matrix;
  274. $A=pgflabtypeset{I}$
  275.  
  276. bigskip
  277. pgflabneweyeof 3 by 5 as B
  278. rectangular identity matrix;
  279. $B=pgflabtypeset{B}$
  280.  
  281. % copy matrix
  282. defpgflabcopymatrix #1 to #2{
  283. pgfkeys{/lab/#1/h/.get=pgflabh}pgfkeys{/lab/#2/h/.let=pgflabh}
  284. pgfkeys{/lab/#1/w/.get=pgflabw}pgfkeys{/lab/#2/w/.let=pgflabw}
  285. pgfplotsforeachungroupedn@i in{1,...,pgflabh}{
  286. pgfplotsforeachungroupedn@j in{1,...,pgflabw}{
  287. pgfkeys{/lab/#1/n@i/n@j/.get=pgflabtempentry}
  288. pgfkeys{/lab/#2/n@i/n@j/.let=pgflabtempentry}
  289. }
  290. }
  291. }
  292. bigskip
  293. pgflabcopymatrix A to B
  294. copy matrix A to B;
  295. $B=pgflabtypeset{B}$
  296.  
  297. % LU decomposition
  298. % if encounter 0, probably will result in inf or nan
  299. defpgflabLUdecompose #1 as #2 times #3{
  300. pgfkeys{/lab/#1/h/.get=pgflabh@u}
  301. pgfkeys{/lab/#1/w/.get=pgflabw@u}
  302. % decide the loop boundary
  303. edefpgflabh@v{thenumexprpgflabh@u-1}
  304. ifnumpgflabh@v>pgflabw@u
  305. edefpgflabh@v{pgflabw@u}
  306. fi
  307. % set L as identity
  308. % set #2 as identity
  309. pgflabneweyeof {pgflabh@u} by {pgflabh@u} as #2
  310. % copy A to U
  311. % copy #1 to #3
  312. pgflabcopymatrix #1 to #3
  313. % forget A, do job at L and U
  314. % forget #1, do job at #2 and #3
  315. pgfplotsforeachungroupedd@i in{1,...,pgflabh@v}{
  316. edefd@@i+1{thenumexprd@i+1}
  317. pgfplotsforeachungroupedd@j in{d@@i+1,...,pgflabh@u}{
  318. % use (d@i,d@i) to eliminate (d@j,d@i)
  319. pgfkeys{/lab/#3/d@i/d@i/.get=pgflabtempentrya}
  320. pgfkeys{/lab/#3/d@j/d@i/.get=pgflabtempentryb}
  321. pgfmathsetmacropgflabtempratio{pgflabtempentryb/pgflabtempentrya}
  322. pgflabaddcol {d@i} by col {d@j} times {pgflabtempratio} in {#2}
  323. pgflabaddrow {d@j} by row {d@i} times {-pgflabtempratio} in {#3}
  324.  
  325. medskip
  326. eliminate one entry. check L and U par
  327. $L=pgflabtypeset{#2};$
  328. $U=pgflabtypeset{#3};$
  329. }
  330. }
  331. }
  332. clearpage
  333. $A=pgflabtypeset{A}$
  334. pgflabLUdecompose A as L times U
  335.  
  336. % find pivot in the specific column
  337. % find pivot in the range (#1,#1) to (#1,end)
  338. % does not check boundary
  339. defpgflabfindpivotatcol #1 in #2{
  340. pgfkeys{/lab/#2/h/.get=pgflabh}
  341. defpgflabtempmax{-inf}
  342. defpgflabtempindex{0}
  343. pgfplotsforeachungroupedf@i in{#1,...,pgflabh}{
  344. pgfkeys{/lab/#2/f@i/#1/.get=pgflabtempentry}
  345. % compare the abs value
  346. pgfmathsetmacropgflabtempentry{abs(pgflabtempentry)}
  347. pgfmathparse{pgflabtempmax<pgflabtempentry}
  348. % update if necessary
  349. ifpgfmathfloatcomparison
  350. letpgflabtempmaxpgflabtempentry
  351. letpgflabtempindexf@i
  352. fi
  353. }
  354. }
  355. clearpage
  356. $A=pgflabtypeset{A}$
  357. find pivot at specific column: par
  358. pgflabfindpivotatcol 1 in A
  359. at col 1 it is pgflabtempmax at row pgflabtempindex par
  360. pgflabfindpivotatcol 2 in A
  361. at col 2 it is pgflabtempmax at row pgflabtempindex par
  362. pgflabfindpivotatcol 3 in A
  363. at col 2 it is pgflabtempmax at row pgflabtempindex
  364.  
  365. % A = PLU decomposition
  366. % partial pivoting
  367. defpgflabPLUdecompose #1 as #2 times #3 times #4{
  368. pgfkeys{/lab/#1/h/.get=pgflabH}
  369. pgfkeys{/lab/#1/w/.get=pgflabW}
  370. % decide the loop boundary
  371. edefpgflab@H-1{thenumexprpgflabH-1}
  372. ifnumpgflab@H-1>pgflabW
  373. edefpgflab@H-1{pgflabW}
  374. fi
  375. % set P as identity
  376. % set #2 as identity
  377. pgflabneweyeof {pgflabH} by {pgflabH} as {#2}
  378. % set L as identity
  379. % set #3 as identity
  380. pgflabneweyeof {pgflabH} by {pgflabH} as {#3}
  381. % copy A to U
  382. % copy #1 to #4
  383. pgflabcopymatrix {#1} to {#4}
  384. % forget A, do job at P and L and U
  385. % forget #1, do job at #2 and #3 and #4
  386. pgfplotsforeachungroupedd@i in{1,...,pgflab@H-1}{
  387. pgflabfindpivotatcol {d@i} in {#4}
  388. pgflabswitchrow {d@i} and row {pgflabtempindex} in {#4}
  389. pgflabswitchcol {d@i} and col {pgflabtempindex} in {#3}
  390. pgflabswitchrow {d@i} and row {pgflabtempindex} in {#3}
  391. pgflabswitchcol {d@i} and col {pgflabtempindex} in {#2}
  392. parmedskip
  393. switch d@i{} and pgflabtempindexpar
  394. $P=pgflabtypeset{#2};$
  395. $L=pgflabtypeset{#3};$
  396. $U=pgflabtypeset{#4};$
  397. edefd@@i+1{thenumexprd@i+1}
  398. pgfplotsforeachungroupedd@j in{d@@i+1,...,pgflabH}{
  399. % use (d@i,d@i) to eliminate (d@j,d@i)
  400. pgfkeys{/lab/#4/d@i/d@i/.get=pgflabtempentrya}
  401. pgfkeys{/lab/#4/d@j/d@i/.get=pgflabtempentryb}
  402. pgfmathsetmacropgflabtempratio{pgflabtempentryb/pgflabtempentrya}
  403. pgflabaddcol {d@i} by col {d@j} times {pgflabtempratio} in {#3}
  404. pgflabaddrow {d@j} by row {d@i} times {-pgflabtempratio} in {#4}
  405. }
  406. parmedskip
  407. eliminate one column. check P and L and U par
  408. $P=pgflabtypeset{#2};$
  409. $L=pgflabtypeset{#3};$
  410. $U=pgflabtypeset{#4};$
  411. }
  412. }
  413. pgflabread{A}{
  414. 3 1 -7 5 0
  415. -9 -4 -8 -2 9
  416. 4 -3 6 0 -1
  417. -5 8 2 -6 7
  418. }
  419. bigskip
  420. pgflabPLUdecompose A as P times L times U
  421.  
  422. % find pivot in the specific column and row
  423. % find pivot in the range (#1,#1) to (end,end)
  424. % does not check boundary
  425. defpgflabfindpivotafter#1 in #2{
  426. pgfkeys{/lab/#2/h/.get=pgflabh}
  427. pgfkeys{/lab/#2/w/.get=pgflabw}
  428. defpgflabtempmax{-inf}
  429. defpgflabtempindex{0}
  430. defpgflabtempjndex{0}
  431. pgfplotsforeachungroupedf@i in{#1,...,pgflabh}{
  432. pgfplotsforeachungroupedf@j in{#1,...,pgflabw}{
  433. pgfkeys{/lab/#2/f@i/f@j/.get=pgflabtempentry}
  434. % compare the abs value
  435. pgfmathsetmacropgflabtempentry{abs(pgflabtempentry)}
  436. pgfmathparse{pgflabtempmax<pgflabtempentry}
  437. % update if necessary
  438. ifpgfmathfloatcomparison
  439. letpgflabtempmaxpgflabtempentry
  440. letpgflabtempindexf@i
  441. letpgflabtempjndexf@j
  442. fi
  443. }
  444. }
  445. }
  446.  
  447. % A = PLUQ decomposition
  448. % partial pivoting
  449. defpgflabPLUQdecompose #1 as #2 times #3 times #4 times #5{
  450. pgfkeys{/lab/#1/h/.get=pgflabH}
  451. pgfkeys{/lab/#1/w/.get=pgflabW}
  452. % decide the loop boundary
  453. edefpgflab@H-1{thenumexprpgflabH-1}
  454. ifnumpgflab@H-1>pgflabW
  455. edefpgflab@H-1{pgflabW}
  456. fi
  457. % set P as identity
  458. % set #2 as identity
  459. pgflabneweyeof {pgflabH} by {pgflabH} as {#2}
  460. % set L as identity
  461. % set #3 as identity
  462. pgflabneweyeof {pgflabH} by {pgflabH} as {#3}
  463. % copy A to U
  464. % copy #1 to #4
  465. pgflabcopymatrix {#1} to {#4}
  466. % set Q as identity
  467. % set #5 as identity
  468. pgflabneweyeof {pgflabW} by {pgflabW} as {#5}
  469. % forget A, do job at P and L and U
  470. % forget #1, do job at #2 and #3 and #4
  471. pgfplotsforeachungroupedd@i in{1,...,pgflab@H-1}{
  472. pgflabfindpivotafter {d@i} in #4
  473.  
  474. pgflabswitchrow {d@i} and row {pgflabtempindex} in {#4}
  475. pgflabswitchcol {d@i} and col {pgflabtempindex} in {#3}
  476. pgflabswitchrow {d@i} and row {pgflabtempindex} in {#3}
  477. pgflabswitchcol {d@i} and col {pgflabtempindex} in {#2}
  478. {}
  479. pgflabswitchcol {d@i} and col {pgflabtempjndex} in {#4}
  480. pgflabswitchrow {d@i} and row {pgflabtempjndex} in {#5}
  481.  
  482. switch (d@i{},d@i{}) and (pgflabtempindex,pgflabtempjndex) par
  483. $P=pgflabtypeset{#2};$
  484. $L=pgflabtypeset{#3};$
  485. $U=pgflabtypeset{#4};$
  486. $Q=pgflabtypeset{#5};$
  487. edefd@@i+1{thenumexprd@i+1}
  488. pgfplotsforeachungroupedd@j in{d@@i+1,...,pgflabH}{
  489. % use (d@i,d@i) to eliminate (d@j,d@i)
  490. pgfkeys{/lab/#4/d@i/d@i/.get=pgflabtempentrya}
  491. pgfkeys{/lab/#4/d@j/d@i/.get=pgflabtempentryb}
  492. pgfmathsetmacropgflabtempratio{pgflabtempentryb/pgflabtempentrya}
  493. pgflabaddcol {d@i} by col {d@j} times {pgflabtempratio} in {#3}
  494. pgflabaddrow {d@j} by row {d@i} times {-pgflabtempratio} in {#4}
  495. }
  496.  
  497. eliminate one column. check P and L and U and Qpar
  498. $P=pgflabtypeset{#2};$
  499. $L=pgflabtypeset{#3};$
  500. $U=pgflabtypeset{#4};$
  501. $Q=pgflabtypeset{#5};$
  502. }
  503. }
  504. pgflabread{A}{
  505. 3 -7 5 0 1 0 1
  506. -9 -8 -2 9 -1 9 -4
  507. 4 6 0 -1 -2 -1 -3
  508. -5 2 -6 7 8 7 8
  509. -1 -2 -1 -3 4 6 0
  510. 7 8 7 8 -5 2 -6
  511. }
  512. bigskip
  513. $A=pgflabtypeset{A}$
  514. pgflabPLUQdecompose A as P times L times U times Q
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535. % new matrix with desired entry
  536. % entry can contain n@i and n@j
  537. defpgflabnewmatrixof #1 by #2 with #3 as #4{
  538. defpgflabh{#1}pgfkeys{/lab/#4/h/.let=pgflabh}
  539. defpgflabw{#2}pgfkeys{/lab/#4/w/.let=pgflabw}
  540. pgfplotsforeachungroupedn@i in{1,...,pgflabh}{
  541. pgfplotsforeachungroupedn@j in{1,...,pgflabw}{
  542. pgfmathparse{#3}
  543. pgfkeys{/lab/#4/n@i/n@j/.let=pgfmathresult}
  544. }
  545. }
  546. }
  547. clearpage
  548. pgflabnewmatrixof 10 by 10 with rand as C
  549. pgflabPLUQdecompose C as P times L times U times Q
  550.  
  551. % debug macro
  552. % we can pass it to sage
  553. % but we need to replace negative sign by ascii's -
  554. defpgflabrawoutput#1{%
  555. pgfkeys{/lab/#1/h/.get=pgflabh}%
  556. pgfkeys{/lab/#1/w/.get=pgflabw}%
  557. matrix([%
  558. pgfplotsforeachungroupedt@i in{1,...,pgflabh}{%
  559. [%
  560. pgfplotsforeachungroupedt@j in{1,...,pgflabw}{%
  561. pgfkeys{/lab/#1/t@i/t@j/.get=pgflabtempentry}%
  562. pgfmathparse{pgflabtempentry}%
  563. pgfmathfloattosci{pgfmathresult}%
  564. mbox{pgfmathresult}%
  565. ifnumt@j<pgflabw,hskip1ptplus3ptallowbreakfi
  566. }%
  567. ]%
  568. ifnumt@i<pgflabh,hskip1ptplus3ptallowbreakfi
  569. }%
  570. ])%
  571. }
  572. clearpage
  573. C=pgflabrawoutput{C};par
  574. P=pgflabrawoutput{P};par
  575. L=pgflabrawoutput{L};par
  576. U=pgflabrawoutput{U};par
  577. Q=pgflabrawoutput{Q};par
  578. (C-P*L*U*Q).norm()
  579.  
  580. end{document}
  581.  
  582. documentclass{article}
  583. usepackage{pgfplotstable,mathtools}
  584. pgfplotsset{compat=newest}
  585. pgfkeys{/pgf/fpu}
  586. begin{document}
  587.  
  588.  
  589.  
  590. % we are lazy
  591. % let pgfplotstable read the matrix
  592. pgfplotstableread[header=false]{
  593. 8 1 6 8
  594. 3 5 7 5
  595. 4 9 2 7
  596. }matrixA
  597.  
  598. % we will store data by pgfleys
  599. % create a handy handler
  600. pgfkeys{/handlers/.let/.code=pgfkeyslet{pgfkeyscurrentpath}{#1}}
  601. % PS: /.initial is more like def, but we want xdef or edef or let
  602.  
  603. % but we also need some fast macros
  604. pgfplotstablegetrowsofmatrixA xdefmatrixheight{pgfplotsretval}pgfkeys{/matrix/A/height/.let=matrixheight}
  605. pgfplotstablegetcolsofmatrixA xdefmatrixwidth{pgfplotsretval} pgfkeys{/matrix/A/width/.let=matrixwidth}
  606.  
  607. % check data
  608. Matrix $A$ is pgfkeys{/matrix/A/height} by pgfkeys{/matrix/A/width}.
  609. In other words: par Matrix $A$ is matrixheight{} by matrixwidth{}.
  610.  
  611.  
  612.  
  613. % store the entries into pgfkeys
  614. pgfplotsforeachungroupedi in{1,...,matrixheight}{
  615. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  616. % since fpu is on, this is easier way to do 9+1
  617. pgfplotstablegetelem{thenumexpri-1}{thenumexprj-1}ofmatrixA
  618. pgfkeys{/matrix/A/i/j/.let=pgfplotsretval}
  619. }
  620. }
  621.  
  622. % check data
  623. bigskip The matrix entries are: par
  624. pgfplotsforeachungroupedi in{1,...,matrixheight}{
  625. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  626. pgfkeys{/matrix/A/i/j},
  627. }
  628. ; par
  629. }
  630.  
  631.  
  632.  
  633. % define row operation: switch
  634. defrowoperationswitch#1and#2 {
  635. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  636. pgfkeys{/matrix/A/#1/j/.get=tempmatrixentryA}
  637. pgfkeys{/matrix/A/#2/j/.get=tempmatrixentryB}
  638. pgfkeys{/matrix/A/#1/j/.let=tempmatrixentryB}
  639. pgfkeys{/matrix/A/#2/j/.let=tempmatrixentryA}
  640. }
  641. }
  642.  
  643. % try and check
  644. rowoperationswitch3and2
  645. bigskip After switching row3 and row2, the matrix entries are: par
  646. pgfplotsforeachungroupedi in{1,...,matrixheight}{
  647. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  648. pgfkeys{/matrix/A/i/j},
  649. }
  650. ; par
  651. }
  652.  
  653.  
  654.  
  655. % define row operation: multiplication
  656. defrowoperationmultiply#1by#2 {
  657. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  658. pgfkeys{/matrix/A/#1/j/.get=tempmatrixentry}
  659. pgfmathparse{tempmatrixentry*#2}
  660. pgfkeys{/matrix/A/#1/j/.let=pgfmathresult}
  661. }
  662. }
  663.  
  664. % try and check
  665. rowoperationmultiply3by9
  666. bigskip After multiplying row3 by 9, the matrix entries are: par
  667. pgfplotsforeachungroupedi in{1,...,matrixheight}{
  668. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  669. pgfkeys{/matrix/A/i/j},
  670. }
  671. ; par
  672. }
  673. remember: fpu is on! par
  674. Human readable version par
  675. defpgfmathprintmatrix{
  676. pgfplotsforeachungroupedi in{1,...,matrixheight}{
  677. indent
  678. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  679. pgfkeys{/matrix/A/i/j/.get=tempmatrixentry}
  680. pgfmathparse{tempmatrixentry}
  681. clap{pgfmathprintnumber{pgfmathresult}}hskip20pt
  682. }
  683. par
  684. }
  685. }
  686. pgfmathprintmatrix
  687.  
  688.  
  689.  
  690. % define row operation: addition
  691. defrowoperationadd#1by#2times#3 {
  692. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  693. pgfkeys{/matrix/A/#1/j/.get=tempmatrixentryA}
  694. pgfkeys{/matrix/A/#2/j/.get=tempmatrixentryB}
  695. pgfmathparse{tempmatrixentryA+tempmatrixentryB*#3}
  696. pgfkeys{/matrix/A/#1/j/.let=pgfmathresult}
  697. }
  698. }
  699.  
  700. % try and check
  701. rowoperationadd1by2times-1
  702. bigskip After adding row2 by row1 times -1, the matrix entries are: par
  703. pgfmathprintmatrix
  704.  
  705.  
  706.  
  707. % We do RREF by hand
  708. pgfkeys{/pgf/number format/fixed}
  709. bigskip We do RREF by hand par
  710. add 2 by 1 times -1: par
  711. rowoperationadd2by1times-1
  712. pgfmathprintmatrix
  713.  
  714. medskip add 3 by 1 times -6.75: par
  715. rowoperationadd3by1times-6.75
  716. pgfmathprintmatrix
  717.  
  718. medskip add 3 by 2 times -5.8235: par
  719. rowoperationadd3by2times-5.8235
  720. pgfmathprintmatrix
  721.  
  722.  
  723.  
  724. % renew A
  725. pgfplotsforeachungroupedi in{1,...,matrixheight}{
  726. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  727. pgfplotstablegetelem{thenumexpri-1}{thenumexprj-1}ofmatrixA % lazy~~
  728. pgfkeys{/matrix/A/i/j/.let=pgfplotsretval}
  729. }
  730. }
  731. clearpage Restart with $A$ par
  732. pgfmathprintmatrix
  733.  
  734.  
  735.  
  736. % Automatic RREF without row switching
  737. % I is different form i
  738. xdefmatrixheightminusone{thenumexprmatrixheight-1}
  739. pgfplotsforeachungroupedI in{1,...,matrixheightminusone}{
  740. pgfplotsforeachungroupedJ in{I,...,matrixheightminusone}{
  741. xdefJ{thenumexprJ+1}
  742. pgfkeys{/matrix/A/I/I/.get=tempmatrixentryA}
  743. pgfkeys{/matrix/A/J/I/.get=tempmatrixentryB}
  744. bigskip
  745. entry [I][I] is tempmatrixentryA par
  746. entry [J][I] is tempmatrixentryB par
  747. pgfmathparse{-tempmatrixentryB/tempmatrixentryA}
  748. xdeftemprowscaler{pgfmathresult}
  749. message{^^J^^JI,J,temprowscaler^^J^^J}
  750. add rowJ{} by rowI{} times pgfmathprintnumber{temprowscaler} par
  751. rowoperationaddJ byI times{temprowscaler}
  752. pgfmathprintmatrix
  753. }
  754. }
  755.  
  756.  
  757.  
  758. % renew A
  759. pgfplotsforeachungroupedi in{1,...,matrixheight}{
  760. pgfplotsforeachungroupedj in{1,...,matrixwidth}{
  761. pgfplotstablegetelem{thenumexpri-1}{thenumexprj-1}ofmatrixA % lazy~~
  762. pgfkeys{/matrix/A/i/j/.let=pgfplotsretval}
  763. }
  764. }
  765. clearpage Restart with $A$ par
  766. pgfmathprintmatrix
  767.  
  768.  
  769.  
  770. % maybe we need pivoting
  771. defrowoperationfindpivot{
  772. % find the maximal element in this column
  773. defmaxofthiscolumn{-inf}
  774. defmaxofthiscolumnindex{0}
  775. pgfplotsforeachungroupedK in{I,...,matrixheight}{
  776. pgfkeys{/matrix/A/K/I/.get=tempmatrixentry}
  777. % compare
  778. pgfmathparse{abs(tempmatrixentry)}
  779. lettempmatrixabsentrypgfmathresult
  780. pgfmathparse{maxofthiscolumn<tempmatrixabsentry}
  781. % update if necessary
  782. ifpgfmathfloatcomparison
  783.  
  784. letmaxofthiscolumntempmatrixabsentry
  785. letmaxofthiscolumnindexK
  786. fi
  787. }
  788. }
  789. xdefI{1}
  790. rowoperationfindpivot
  791. For column I, the maximum is pgfmathprintnumber{maxofthiscolumn} at row maxofthiscolumnindex
  792.  
  793.  
  794.  
  795. % Automatic RREF with partial pivot
  796. defRREFwithpivoting{
  797. pgfplotsforeachungroupedI in{1,...,matrixheightminusone}{
  798. rowoperationfindpivot
  799. rowoperationswitchI and{maxofthiscolumnindex}
  800. bigskip
  801. For column I, the maximum is pgfmathprintnumber{maxofthiscolumn} at row maxofthiscolumnindex par
  802. so we switch rowI{} and rowmaxofthiscolumnindex, the matrix entries are: par
  803. pgfmathprintmatrix
  804. pgfplotsforeachungroupedJ in{I,...,matrixheightminusone}{
  805. xdefJ{thenumexprJ+1}
  806. pgfkeys{/matrix/A/I/I/.get=tempmatrixentryA}
  807. pgfkeys{/matrix/A/J/I/.get=tempmatrixentryB}
  808. bigskip
  809. pgfmathparse{-tempmatrixentryB/tempmatrixentryA}
  810. xdeftemprowscaler{pgfmathresult}
  811. add rowJ{} by rowI{} times pgfmathprintnumber{temprowscaler} par
  812. rowoperationaddJ byI times{temprowscaler}
  813. pgfmathprintmatrix
  814. }
  815. }
  816. }
  817. RREFwithpivoting
  818.  
  819. .......
  820.  
  821. 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]]);
  822. 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]]);
  823. 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]]);
  824. 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]]);
  825. 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]]);
  826.  
  827. > with(LinearAlgebra):
  828. > MatrixAdd(A,-P.L.U.Q);
  829. [0 0 0 0 0 0 0 0 0]
  830. [ ]
  831. [0 0 0 0 0 0 0 0 0]
  832. [ ]
  833. [0 0 0 0 0 0 0 0 0]
  834. [ ]
  835. [0 0 0 0 0 0 0 0 0]
  836. [ ]
  837. [0 0 0 0 0 0 0 0 0]
  838. [ ]
  839. [0 0 0 0 0 0 0 0 0]
  840.  
  841. documentclass[a4paper]{article}
  842. usepackage[hscale=0.85, vscale=0.85]{geometry}
  843. usepackage{xintfrac}
  844. usepackage{xinttools}
  845. usepackage{array}
  846. % usepackage {siunitx}
  847. % usepackage {numprint}
  848.  
  849. catcode`_ 11
  850. makeatletter
  851.  
  852. newwriteMATout
  853. immediateopenoutMATout=jobname.pluqoutrelax
  854.  
  855. % (the typeout format is for input in Maple for example)
  856. defMATtypeout {MATtypeoutwith {MATtypeoutone}}%
  857. defMATtypeoutone #1{xintPRaw{xintRawWithZeros{#1}}}% (lacking an xintPRawWithZeros)
  858. defMATtypeoutwith #1#2#3{%
  859. edefI{xintSeq {1}{#3[I]}}% indices for rows
  860. edefJ{xintSeq {1}{#3[J]}}% indices for columns
  861. immediatewriteMATout{#2:=Matrix([[%
  862. xintListWithSep {], [}{xintApply { MAT_typeout_row {#1}#3}{I}}%
  863. ]]);}%
  864. }%
  865. defMAT_typeout_row #1#2#3{%
  866. xintListWithSep {, }{xintApply { MAT_typeout_one {#1}#2{#3}}{J}}%
  867. }%
  868. defMAT_typeout_one #1#2#3#4{#1{#2[#3,#4]}}%
  869.  
  870. % we don't need all of them
  871. newcountMAT_cnta
  872. newcountMAT_cntb
  873. newcountMAT_cntc
  874. newcountMAT_cntd
  875. newcountMAT_cnte
  876.  
  877. % Usage: MATsetmyMatrix{semi-colon separated rows of comma separated values}
  878. % example.
  879. % MATsetMatrixA { 1/3 , 1/4, 1/5 ;
  880. % 1/6 , 1/7 , 1/8 ;
  881. % 1/9 , 1/10 , 1/11 ; }
  882. % The final semi-colon is optional.
  883.  
  884. % We indeed focus here on manipulating matrices with rational entries, the
  885. % code at https://tex.stackexchange.com/a/143035/4686 has the set-up for
  886. % floating point numbers too (in an arbitrary, user decided precision).
  887.  
  888. defMATset {defMAT_xintin {xintRaw}MATset_ }%
  889.  
  890. defMATset_ #1#2{%
  891. defMATset_name{#1}%
  892. edefMAT_tmpa {#2}%
  893. MAT_cnta xint_c_ % sets MAT_cnta to zero
  894. expandafterMATset_a
  895. romannumeral0expandafterxintzapspacesexpandafter{MAT_tmpa};!;%
  896. }%
  897. defMATset_a {futureletXINT_tokenMATset_b }%
  898. defMATset_b #1;{defMAT_tmpa{#1}%
  899. ifxXINT_token;expandafterMATset_w
  900. else
  901. ifxXINT_token!%
  902. expandafterexpandafterexpandafterMATset_x
  903. else
  904. expandafterexpandafterexpandafterMATset_c
  905. fifi }%
  906. defMATset_w !;{MATset_x }%
  907. defMATset_x {expandafterdef
  908. csname MAT@expandafterstringMATset_name {I}expandafterendcsname
  909. expandafter {theMAT_cnta }%
  910. expandafterdef
  911. csname MAT@expandafterstringMATset_name {J}expandafterendcsname
  912. expandafter {theMAT_cntb }%
  913. expandafteredef MATset_name [##1]%
  914. {noexpandcsname MAT@expandafterstringMATset_name
  915. noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
  916. }%
  917. % a bit convoluted, no comments.
  918. defMAT_in #1,#2,{xint_bye #2xint_gobble_ivxint_bye
  919. {thenumexpr #1}{thenumexpr #2}xint_gobble_iii
  920. {xintZapSpaces{#1}}}%
  921. defMATset_c {advanceMAT_cnta xint_c_i % row count ++
  922. MAT_cntb xint_c_ % column count initially zero
  923. expandafterMATset_dromannumeral0expandafter
  924. xintzapspacesexpandafter {MAT_tmpa},!,}%
  925. defMATset_d {futureletXINT_tokenMATset_e }%
  926. defMATset_e #1,{ifxXINT_token!expandafterMATset_a
  927. else
  928. advanceMAT_cntb xint_c_i
  929. expandafterdef
  930. csname MAT@expandafterstringMATset_name
  931. {theMAT_cnta}{theMAT_cntb}expandafterendcsname
  932. expandafter{romannumeral-`0MAT_xintin{xintZapSpacesB{#1}}}%
  933. expandafterMATset_dfi
  934. }%
  935.  
  936. % removed toks2 et toks4 usage from https://tex.stackexchange.com/a/143035/4686
  937. defMATlet #1#2{%
  938. edefMAT@seqI{xintSeq {1}{#2[I]}}%
  939. edefMAT@seqJ{xintSeq {1}{#2[J]}}%
  940. xintFor* ##1 in {MAT@seqI}
  941. do{xintFor* ##2 in {MAT@seqJ}
  942. do{expandafterlet
  943. csname MAT@string#1{##1}{##2}expandafterendcsname
  944. csname MAT@string#2{##1}{##2}endcsname
  945. }}%
  946. expandafteredefcsname MAT@string#1{I}endcsname {#2[I]}%
  947. expandafteredefcsname MAT@string#1{J}endcsname {#2[J]}%
  948. edef #1[##1]%
  949. {noexpandcsname
  950. MAT@string#1noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
  951. }%
  952.  
  953. % We need identity matrices.
  954. % again copied as is from https://tex.stackexchange.com/a/143035/4686
  955. % IDENTITY MATRIX
  956. % usage MATidfoo{37} defines a 37 times 37 identity matrix.
  957. defMATid {defMAT_tmpf{/1}MAT_id }%
  958. %defMATfloatid {defMAT_tmpf{}MAT_id }%
  959. % This identity matrix insists on coefficients written internally
  960. % 0[0] or 1[0], this is a remnant of
  961. % https://tex.stackexchange.com/a/143035/4686 whose aim is is minuscule
  962. % optimization when these numbers are involved in computations done by
  963. % the xintfrac macros.
  964. defMAT_id #1#2{%
  965. MAT_cntc #2relax
  966. MAT_cnta xint_c_i % 1
  967. xintloop
  968. {expandafterdefexpandafterMAT_tmpa expandafter{theMAT_cnta}%
  969. MAT_cntb xint_c_i % 1
  970. xintloop
  971. expandafteredef
  972. csname MAT@string#1{MAT_tmpa}{theMAT_cntb}endcsname
  973. {ifnumMAT_cntb=MAT_cnta 1else 0fi MAT_tmpf[0]}%
  974. ifnumMAT_cntb<MAT_cntc
  975. advanceMAT_cntb xint_c_i
  976. repeat
  977. ifnumMAT_cnta<MAT_cntc
  978. advanceMAT_cnta xint_c_i
  979. }repeat
  980. expandafterdefcsname MAT@string#1{I}expandafterendcsname
  981. expandafter {theMAT_cntc}%
  982. expandafterdefcsname MAT@string#1{J}expandafterendcsname
  983. expandafter {theMAT_cntc}%
  984. edef #1[##1]%
  985. {noexpandcsname
  986. MAT@string#1noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
  987. }%
  988.  
  989. % EXCHANGING ROWS OR COLUMNS OF A GIVEN MATRIX
  990. defMATexchangecol #1#2#3{%
  991. MAT_cnta=#3[I]relax
  992. MAT_cntb=xint_c_i % 1
  993. xintloop
  994. expandafterletexpandafterMAT@tmp
  995. csname MAT@string#3{theMAT_cntb}{#1}endcsname
  996. expandafterlet
  997. csname MAT@string#3{theMAT_cntb}{#1}expandafterendcsname
  998. csname MAT@string#3{theMAT_cntb}{#2}endcsname
  999. expandafterlet
  1000. csname MAT@string#3{theMAT_cntb}{#2}endcsname
  1001. MAT@tmp
  1002. ifnumMAT_cntb<MAT_cnta
  1003. advanceMAT_cntbxint_c_i
  1004. repeat
  1005. }%
  1006. % perhaps only columns "to the right" actually need exchange in usage of this
  1007. defMATexchangerow #1#2#3{%
  1008. MAT_cnta=#3[J]relax
  1009. MAT_cntb=xint_c_i % 1
  1010. xintloop
  1011. expandafterletexpandafterMAT@tmp
  1012. csname MAT@string#3{#1}{theMAT_cntb}endcsname
  1013. expandafterlet
  1014. csname MAT@string#3{#1}{theMAT_cntb}expandafterendcsname
  1015. csname MAT@string#3{#2}{theMAT_cntb}endcsname
  1016. expandafterlet
  1017. csname MAT@string#3{#2}{theMAT_cntb}endcsname
  1018. MAT@tmp
  1019. ifnumMAT_cntb<MAT_cnta
  1020. advanceMAT_cntbxint_c_i
  1021. repeat
  1022. }%
  1023. defMATexchangerowspecial #1#2#3{%#1>#2, only columns <#2 need update
  1024. MAT_cnta=#2relax
  1025. MAT_cntb=xint_c_ % 0
  1026. xintloop
  1027. advanceMAT_cntbxint_c_i
  1028. ifnumMAT_cntb<MAT_cnta
  1029. expandafterletexpandafterMAT@tmp
  1030. csname MAT@string#3{#1}{theMAT_cntb}endcsname
  1031. expandafterlet
  1032. csname MAT@string#3{#1}{theMAT_cntb}expandafterendcsname
  1033. csname MAT@string#3{#2}{theMAT_cntb}endcsname
  1034. expandafterlet
  1035. csname MAT@string#3{#2}{theMAT_cntb}endcsname
  1036. MAT@tmp
  1037. repeat
  1038. }%
  1039.  
  1040.  
  1041. % Usage:
  1042. % MATpluqA (A previously defined by MATset)
  1043. % Effect: sets P, L, U, Q, to matrices in the sense of MATset,
  1044. % so that "A=PLUQ" and it writes all matrices out
  1045. % to some file. See initial answer about row reduction for typesetting
  1046. % in document.
  1047. % The code is a simple adaptation of this initial answer. Now I use MATpluq
  1048. % prefix.
  1049. defMATpluq #1{%
  1050. % begingroup
  1051. MATlet@U#1%
  1052. edefMATpluq@rows{@U[I]}% nb of rows
  1053. edefMATpluq@cols{@U[J]}% nb of columns.
  1054. MATid@PMATpluq@rows
  1055. MATid@LMATpluq@rows
  1056. MATid@QMATpluq@cols
  1057. defMATpluq@pivrow {0}%
  1058. defMATpluq@pivcol {0}%
  1059. %edefMATpluq@name {string#1}%
  1060. letMATpluq@ifcontinueiftrue
  1061. % Starting the reduction.
  1062. MATtypeout{^^JA}#1%
  1063. [A = MATdisplay@U]
  1064. xintloop
  1065. % Nota Bene: in the PLUQ reduction, the pivots are anyhow organized
  1066. % along the main diagonal so pivrow and pivcol will be kept in sync over
  1067. % the execution of the algorithm but we use two variables nevertheless.
  1068. edefMATpluq@pivrow{thenumexprMATpluq@pivrow+xint_c_i}%
  1069. edefMATpluq@pivcol{thenumexprMATpluq@pivcol+xint_c_i}%
  1070. MATpluq@dopiv
  1071. MATpluq@ifcontinue
  1072. repeat
  1073. % Done. The rank of the matrix is thenumexprMATpluq@pivrow-xint_c_i.par
  1074. % endgroup
  1075. MATtypeout{P}@P
  1076. MATtypeout{L}@L
  1077. MATtypeout{U}@U
  1078. MATtypeout{Q}@Q
  1079. [ P = MATdisplay@P]
  1080. [ L = MATdisplay@Lqquad U = MATdisplay@U]
  1081. [ Q = MATdisplay@Q]
  1082. }
  1083.  
  1084. defMATpluq@done {letMATpluq@ifcontinueiffalse}
  1085.  
  1086. % Remark on algorithm: I hesitated about doing column permutations first,
  1087. % rather than row permutations with the idea to recognize faster an entirely
  1088. % vanishing row, so that we can put it at the end and ignore it entirely, in
  1089. % effect reducing the number of rows by one, and possibly making algorithm
  1090. % faster. But for simplicity I just keep algorithm close to the one as in my
  1091. % initial answer. We only have to keep track in P, L, Q of the needed
  1092. % operations.
  1093.  
  1094. defMATpluq@dopiv{%
  1095. letMATpluq@rowMATpluq@pivrow
  1096. letMATpluq@colMATpluq@pivcol
  1097. ifnumMATpluq@row>MATpluq@rowsrelax
  1098. MATpluq@done
  1099. else
  1100. ifnumMATpluq@col>MATpluq@colsrelax
  1101. MATpluq@done
  1102. else
  1103. expandafterexpandafterexpandafterMATpluq@dopiv@i
  1104. fi
  1105. fi
  1106. }
  1107.  
  1108. defMATpluq@dopiv@i{%
  1109. edefMATpluq@piv@value{@U[MATpluq@row,MATpluq@col]}%
  1110. xintifZero{MATpluq@piv@value}
  1111. MATpluq@dopiv@steprow
  1112. MATpluq@dopiv@ii
  1113. }
  1114.  
  1115. defMATpluq@dopiv@steprow{%
  1116. ifnumMATpluq@row=MATpluq@rowsrelax
  1117. par No pivot found in column MATpluq@col.par
  1118. letMATpluq@rowMATpluq@pivrow
  1119. expandafterMATpluq@dopiv@stepcol
  1120. else
  1121. edefMATpluq@row{thenumexprMATpluq@row+xint_c_i}%
  1122. expandafterMATpluq@dopiv@i
  1123. fi
  1124. }
  1125.  
  1126. defMATpluq@dopiv@stepcol{%
  1127. ifnumMATpluq@col=MATpluq@colsrelax
  1128. MATpluq@done
  1129. else
  1130. edefMATpluq@col{thenumexprMATpluq@col+xint_c_i}%
  1131. expandafterMATpluq@dopiv@i
  1132. fi
  1133. }
  1134.  
  1135. % found a pivot
  1136. defMATpluq@dopiv@ii{%
  1137. Pivot MATpluqprintonevalue{MATpluq@piv@value} at MATpluq@row, MATpluq@col.par
  1138. ifnumMATpluq@col>MATpluq@pivcolrelax
  1139. Exchange of columns MATpluq@pivcolspace and MATpluq@col.par
  1140. MATexchangerow{MATpluq@col}{MATpluq@pivcol}@Q
  1141. MATexchangecol{MATpluq@col}{MATpluq@pivcol}@U
  1142. [U = MATdisplay@Uqquad Q = MATdisplay@Q]
  1143. fi
  1144. ifnumMATpluq@pivrow=MATpluq@rowsrelax
  1145. edefMATpluq@pivrow{thenumexprMATpluq@pivrow+xint_c_i}%
  1146. MATpluq@done
  1147. else
  1148. expandafterMATpluq@dopiv@iii
  1149. fi
  1150. }
  1151.  
  1152. defMATpluq@dopiv@iii{%
  1153. ifnumMATpluq@row>MATpluq@pivrowrelax
  1154. Exchange of rows MATpluq@pivrowspace and MATpluq@row.par
  1155. MATexchangecol{MATpluq@row}{MATpluq@pivrow}@P
  1156. MATexchangerow{MATpluq@row}{MATpluq@pivrow}@U
  1157. MATexchangerowspecial{MATpluq@row}{MATpluq@pivrow}@L
  1158. [L = MATdisplay@Lqquad U = MATdisplay@U]
  1159. [P = MATdisplay@P]
  1160. fi
  1161. MAT_cntcMATpluq@pivrowrelax% we are guaranteed < nb of rows
  1162. xintloop
  1163. advanceMAT_cntcxint_c_i
  1164. edefMATpluq@entry{@U[MAT_cntc,MATpluq@pivcol]}%
  1165. xintifZeroMATpluq@entry
  1166. {% nothing to do, the L coeff is already set to zero
  1167. }%
  1168. {edefMATpluq@ratio
  1169. {xintIrr{xintDiv{MATpluq@entry}{MATpluq@piv@value}}[0]}%
  1170. expandafterlet
  1171. csname MAT@string@L{theMAT_cntc}{MATpluq@pivcol}endcsname
  1172. MATpluq@ratio
  1173. Subtract from row theMAT_cntcspace the pivot row multiplied by
  1174. MATpluqprintonevalue{MATpluq@ratio}.par
  1175. @namedef{MAT@string@U{theMAT_cntc}{MATpluq@pivcol}}{0[0]}%
  1176. MAT_cntdMATpluq@pivcolrelax
  1177. xintloop
  1178. advanceMAT_cntdxint_c_i
  1179. unlessifnumMATpluq@cols<MAT_cntd
  1180. expandafteredef
  1181. csname MAT@string@U{theMAT_cntc}{theMAT_cntd}endcsname
  1182. {xintIrr{%
  1183. xintSub{@U[MAT_cntc,MAT_cntd]}
  1184. {xintMul{MATpluq@ratio}{@U[MATpluq@pivrow,MAT_cntd]}}%
  1185. }[0]}%
  1186. repeat
  1187. }%
  1188. unlessifnumMATpluq@rows=MAT_cntc
  1189. repeat
  1190. [L = MATdisplay@Lqquad U = MATdisplay@U]
  1191. }
  1192.  
  1193. defMATpluqprintonevalue{xintPRaw}
  1194. %defMATpluqdisplay#1{[MATdisplay#1]}%
  1195.  
  1196. %% MATH MODE MATRIX DISPLAY
  1197.  
  1198. makeatother
  1199.  
  1200. newcommandMATdisplay [1][1.25]{MATdisplaywith [#1]{MATdisplayone}}
  1201. defMATdisplayone {xintSignedFrac}
  1202. newcolumntypeMATdisplaycoltype {c}
  1203. newcolumntypeMATdisplaypreamble [1]{@{}*{#1[J]}MATdisplaycoltype@{}}
  1204. newcommandMATdisplaywith [3][1.25]
  1205. {left(defarraystretch{#1}%
  1206. begin{array}{MATdisplaypreamble {#3}}
  1207. xintListWithSep {\}
  1208. {xintApply { MAT_display_row {#2}#3}{xintSeq {1}{#3[I]}}}
  1209. end{array}right)%
  1210. }%
  1211. defMAT_display_row #1#2#3{%
  1212. xintListWithSep {&}
  1213. {xintApply{ MAT_display_one {#1}#2{#3}}{xintSeq {1}{#2[J]}}}%
  1214. }%
  1215. defMAT_display_one #1#2#3#4{#1{#2[#3,#4]}}%
  1216.  
  1217. catcode`_ 8
  1218.  
  1219. begin{document}pagestyle{empty}
  1220. MATsetMatrixA { 1/3 , 1/4, 1/5 ;
  1221. 1/6 , 1/7 , 1/8 ;
  1222. 1/9 , 1/10 , 1/11 ; }
  1223.  
  1224. MATpluqMatrixA
  1225.  
  1226. See pluqout file.clearpage
  1227.  
  1228. MATsetA {
  1229. 3, -7, 5, 0, 1, 0, 1;
  1230. -9, -8, -2, 9, -1, 9, -4;
  1231. 4, 6, 0, -1, -2, -1, -3;
  1232. -5, 2, -6, 7, 8, 7, 8;
  1233. -1, -2, -1, -3, 4, 6, 0;
  1234. 7, 8, 7, 8, -5, 2, -6;
  1235. }
  1236.  
  1237. MATpluqA
  1238.  
  1239. See pluqout file.clearpage
  1240.  
  1241. MATsetA {
  1242. 2, 0, 3, 0;
  1243. 1, 0, 0, 0;
  1244. 0, 0, 4, 0;
  1245. 0, 2, 0, 1;
  1246. }
  1247.  
  1248. MATpluqA
  1249.  
  1250. See pluqout file.clearpage
  1251.  
  1252. MATsetMatrixB {
  1253. 3, 1, -7, 5, 0, 9, -9, 7, -5;
  1254. -9, -4, -8, -2, 9, 2, 8, -6, -8;
  1255. 4, -3, 6, 0, -1, 5, -4, -3, 4;
  1256. -5, 8, 2, -6, 7, -1, 1, -7, 0;
  1257. 3, 6, -2, -1, 8, -2, -6, 7, -7;
  1258. 4, 6, 3, -9, 1, -5, 0, 5, -3;
  1259. }
  1260.  
  1261. MATpluqMatrixB
  1262.  
  1263. See pluqout file.clearpage
  1264.  
  1265. MATsetMatrixC {
  1266. 3, 1, -7, 5, 0, 9, -9, 7, -5;
  1267. -9, -4, 22, -14, 9, 2, 7, -6, -8;
  1268. -6, -3, 15, -9, 9, 11, -2, 1, -13;
  1269. -5, 8, 2, -18, 7, -1, 8, -7, 0;
  1270. 4, 6, -14, 2, 1, -5, 6, 5, -3;
  1271. -11, 5, 17, -27, 16, 10, 6, -6, -13;
  1272. }
  1273.  
  1274. MATpluqMatrixC
  1275.  
  1276. See pluqout file for the matrices in Maple format.clearpage
  1277.  
  1278. immediatecloseoutMATout
  1279. end{document}
  1280.  
  1281. documentclass{article}
  1282. usepackage{xintfrac}
  1283. usepackage{xinttools}
  1284. usepackage{array}
  1285.  
  1286. catcode`_ 11
  1287. makeatletter
  1288.  
  1289. newcountMAT_cnta
  1290. newcountMAT_cntb
  1291. newcountMAT_cntc
  1292. newcountMAT_cntd
  1293. newcountMAT_cnte
  1294.  
  1295. % Usage: MATsetmyMatrix{semi-colon separated rows of comma separated values}
  1296. % example.
  1297. % MATsetMatrixA { 1/3 , 1/4, 1/5 ;
  1298. % 1/6 , 1/7 , 1/8 ;
  1299. % 1/9 , 1/10 , 1/11 ; }
  1300.  
  1301. defMATset {defMAT_xintin {xintRaw}MATset_ }%
  1302.  
  1303. defMATset_ #1#2{%
  1304. defMATset_name{#1}%
  1305. edefMAT_tmpa {#2}%
  1306. MAT_cnta xint_c_ % sets MAT_cnta to zero
  1307. expandafterMATset_a
  1308. romannumeral0expandafterxintzapspacesexpandafter{MAT_tmpa};!;%
  1309. }%
  1310. defMATset_a {futureletXINT_tokenMATset_b }%
  1311. defMATset_b #1;{defMAT_tmpa{#1}%
  1312. ifxXINT_token;expandafterMATset_w
  1313. else
  1314. ifxXINT_token!%
  1315. expandafterexpandafterexpandafterMATset_x
  1316. else
  1317. expandafterexpandafterexpandafterMATset_c
  1318. fifi }%
  1319. defMATset_w !;{MATset_x }%
  1320. defMATset_x {expandafterdef
  1321. csname MAT@expandafterstringMATset_name {I}expandafterendcsname
  1322. expandafter {theMAT_cnta }%
  1323. expandafterdef
  1324. csname MAT@expandafterstringMATset_name {J}expandafterendcsname
  1325. expandafter {theMAT_cntb }%
  1326. expandafteredef MATset_name [##1]%
  1327. {noexpandcsname MAT@expandafterstringMATset_name
  1328. noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
  1329. }%
  1330. %
  1331. defMAT_in #1,#2,{xint_bye #2xint_gobble_ivxint_bye
  1332. {thenumexpr #1}{thenumexpr #2}xint_gobble_iii
  1333. {xintZapSpaces{#1}}}%
  1334. %
  1335. defMATset_c {advanceMAT_cnta xint_c_i % row count ++
  1336. MAT_cntb xint_c_ % column count initially zero
  1337. expandafterMATset_dromannumeral0expandafter
  1338. xintzapspacesexpandafter {MAT_tmpa},!,}%
  1339. defMATset_d {futureletXINT_tokenMATset_e }%
  1340. defMATset_e #1,{ifxXINT_token!expandafterMATset_a
  1341. else
  1342. advanceMAT_cntb xint_c_i
  1343. expandafterdef
  1344. csname MAT@expandafterstringMATset_name
  1345. {theMAT_cnta}{theMAT_cntb}expandafterendcsname
  1346. expandafter{romannumeral-`0MAT_xintin{xintZapSpacesB{#1}}}%
  1347. expandafterMATset_dfi
  1348. }%
  1349.  
  1350. defMATlet #1#2{%
  1351. edefMAT@seqI{xintSeq {1}{#2[I]}}%
  1352. edefMAT@seqJ{xintSeq {1}{#2[J]}}%
  1353. xintFor* ##1 in {MAT@seqI}
  1354. do{xintFor* ##2 in {MAT@seqJ}
  1355. do{expandafterlet
  1356. csname MAT@string#1{##1}{##2}expandafterendcsname
  1357. csname MAT@string#2{##1}{##2}endcsname
  1358. }}%
  1359. expandafteredefcsname MAT@string#1{I}endcsname {#2[I]}%
  1360. expandafteredefcsname MAT@string#1{J}endcsname {#2[J]}%
  1361. edef #1[##1]%
  1362. {noexpandcsname
  1363. MAT@string#1noexpandMAT_in ##1,noexpandxint_bye,endcsname }%
  1364. }%
  1365.  
  1366. defMATrowreduce #1{%
  1367. begingroup
  1368. edefMATrr@rows{#1[I]}%
  1369. edefMATrr@cols{#1[J]}%
  1370. defMATrr@pivrow {0}%
  1371. defMATrr@pivcol {0}%
  1372. MATlet@U #1%
  1373. letMATrr@ifcontinueiftrue
  1374. Starting the reduction.
  1375. MATrrdisplaymatrix@U
  1376. xintloop
  1377. edefMATrr@pivrow{thenumexprMATrr@pivrow+xint_c_i}%
  1378. edefMATrr@pivcol{thenumexprMATrr@pivcol+xint_c_i}%
  1379. MATrr@dopiv
  1380. MATrr@ifcontinue
  1381. repeat
  1382. Done. The rank of the matrix is thenumexprMATrr@pivrow-xint_c_i.par
  1383. endgroup
  1384. }
  1385.  
  1386. defMATrr@done {letMATrr@ifcontinueiffalse}
  1387.  
  1388. defMATrr@dopiv{%
  1389. letMATrr@rowMATrr@pivrow
  1390. letMATrr@colMATrr@pivcol
  1391. ifnumMATrr@row>MATrr@rowsrelax
  1392. MATrr@done
  1393. else
  1394. ifnumMATrr@col>MATrr@colsrelax
  1395. MATrr@done
  1396. else
  1397. expandafterexpandafterexpandafterMATrr@dopiv@i
  1398. fi
  1399. fi
  1400. }
  1401.  
  1402. defMATrr@dopiv@i{%
  1403. edefMATrr@piv@value{@U[MATrr@row,MATrr@pivcol]}%
  1404. xintifZero{MATrr@piv@value}
  1405. MATrr@dopiv@steprow
  1406. MATrr@dopiv@ii
  1407. }
  1408.  
  1409. defMATrr@dopiv@steprow{%
  1410. ifnumMATrr@row=MATrr@rowsrelax
  1411. letMATrr@rowMATrr@pivrow
  1412. par No pivot found in column MATrr@pivcol.par
  1413. expandafterMATrr@dopiv@stepcol
  1414. else
  1415. edefMATrr@row{thenumexprMATrr@row+xint_c_i}%
  1416. expandafterMATrr@dopiv@i
  1417. fi
  1418. }
  1419.  
  1420. defMATrr@dopiv@stepcol{%
  1421. ifnumMATrr@pivcol=MATrr@colsrelax
  1422. MATrr@done
  1423. else
  1424. edefMATrr@pivcol{thenumexprMATrr@pivcol+xint_c_i}%
  1425. expandafterMATrr@dopiv@i
  1426. fi
  1427. }
  1428.  
  1429. defMATrr@dopiv@ii{%
  1430. ifnumMATrr@pivrow=MATrr@rowsrelax
  1431. edefMATrr@pivrow{thenumexprMATrr@pivrow+xint_c_i}MATrr@done
  1432. else
  1433. expandafterMATrr@dopiv@iii
  1434. fi
  1435. }
  1436.  
  1437. defMATrr@dopiv@iii{%
  1438. Now using the pivot with value MATrrprintonevalue{MATrr@piv@value}
  1439. at row MATrr@rowspace and column MATrr@pivcol.par
  1440. ifnumMATrr@row>MATrr@pivrowrelax
  1441. Exchange of row MATrr@rowspace with row MATrr@pivrow.par
  1442. MAT_cntb=MATrr@pivcolrelax
  1443. xintloop
  1444. expandafterletexpandafterMAT@tmp
  1445. csname MAT@string@U{MATrr@row}{theMAT_cntb}endcsname
  1446. expandafterlet
  1447. csname MAT@string@U{MATrr@row}{theMAT_cntb}expandafterendcsname
  1448. csname MAT@string@U{MATrr@pivrow}{theMAT_cntb}endcsname
  1449. expandafterlet
  1450. csname MAT@string@U{MATrr@pivrow}{theMAT_cntb}endcsname
  1451. MAT@tmp
  1452. ifnumMATrr@cols>MAT_cntb
  1453. advanceMAT_cntbxint_c_i
  1454. repeat
  1455. MATrrdisplaymatrix@Upar
  1456. fi
  1457. MAT_cntcMATrr@pivrow
  1458. xintloop
  1459. advanceMAT_cntcxint_c_i
  1460. edefMATrr@entry{@U[MAT_cntc,MATrr@pivcol]}%
  1461. xintifZeroMATrr@entry
  1462. {}%
  1463. {edefMATrr@ratio{xintIrr{xintDiv{MATrr@entry}{MATrr@piv@value}}[0]}%
  1464. Subtract from row theMAT_cntcspace the pivot row multiplied by
  1465. MATrrprintonevalue{MATrr@ratio}.par
  1466. @namedef{MAT@string@U{theMAT_cntc}{MATrr@pivcol}}{0[0]}%
  1467. MAT_cntdMATrr@pivcolrelax
  1468. xintloop
  1469. advanceMAT_cntdxint_c_i
  1470. unlessifnumMATrr@cols<MAT_cntd
  1471. expandafteredef
  1472. csname MAT@string@U{theMAT_cntc}{theMAT_cntd}endcsname
  1473. {xintIrr{%
  1474. xintSub{@U[MAT_cntc,MAT_cntd]}
  1475. {xintMul{MATrr@ratio}{@U[MATrr@pivrow,MAT_cntd]}}%
  1476. }[0]}%
  1477. repeat
  1478. }%
  1479. unlessifnumMATrr@rows=MAT_cntc
  1480. repeat
  1481. MATrrdisplaymatrix@U
  1482. }
  1483.  
  1484. defMATrrprintonevalue{xintPRaw}
  1485. defMATrrdisplaymatrix #1{[MATdisplay#1]}%
  1486.  
  1487. %% MATH MODE MATRIX DISPLAY
  1488.  
  1489. makeatother
  1490.  
  1491. newcommandMATdisplay [1][1.25]{MATdisplaywith [#1]{MATdisplayone}}
  1492. defMATdisplayone {xintSignedFrac}
  1493.  
  1494. newcolumntypeMATdisplaycoltype {c}
  1495. newcolumntypeMATdisplaypreamble [1]{@{}*{#1[J]}MATdisplaycoltype@{}}
  1496.  
  1497. newcommandMATdisplaywith [3][1.25]
  1498. {left(defarraystretch{#1}%
  1499. begin{array}{MATdisplaypreamble {#3}}
  1500. xintListWithSep {\}
  1501. {xintApply { MAT_display_row {#2}#3}{xintSeq {1}{#3[I]}}}
  1502. end{array}right)%
  1503. }%
  1504.  
  1505. defMAT_display_row #1#2#3{%
  1506. xintListWithSep {&}
  1507. {xintApply{ MAT_display_one {#1}#2{#3}}{xintSeq {1}{#2[J]}}}%
  1508. }%
  1509.  
  1510. defMAT_display_one #1#2#3#4{#1{#2[#3,#4]}}%
  1511.  
  1512. catcode`_ 8
  1513.  
  1514. begin{document}
  1515. MATsetMatrixC {
  1516. 3, 1, -7, 5, 0, 9, -9, 7, -5;
  1517. -9, -4, -8, -2, 9, 2, 8, -6, -8;
  1518. -6, -3, -15, 3, 9, 11, -1, 1, -13;
  1519. -5, 8, 2, -6, 7, -1, 1, -7, 0;
  1520. 4, 6, 3, -9, 1, -5, 0, 5, -3;
  1521. -11, 5, -13, -3, 16, 10, 0, -6, -13;
  1522. }
  1523.  
  1524. MATrowreduceMatrixC
  1525.  
  1526. end{document}
  1527.  
  1528. defMATrrprintonevalue{xintRound{2}}
  1529. defMATrrdisplaymatrix #1{[MATdisplaywith{xintRound{2}}#1]}%
  1530.  
  1531. defMATrrprintonevalue#1{xintTrunc{3}{#1}dots (=xintPRaw{#1})}
  1532. defMATrrdisplaymatrix #1{[MATdisplay#1=MATdisplaywith{TruncWithDots{3}}#1]}%
  1533. defTruncWithDots #1#2{xintTrunc{#1}{#2}...}
  1534. MATsetMatrixA { 1/3 , 1/4, 1/5 ;
  1535. 1/6 , 1/7 , 1/8 ;
  1536. 1/9 , 1/10 , 0.09 ; }
  1537.  
  1538. MATrowreduceMatrixA
Add Comment
Please, Sign In to add comment