⍝ Gauss-Jordan elimination:
try←{⍺←⊢ ⍝ gauss_jordan vs primitive ⌹.
⎕ct←1e¯13 ⍝ slightly more tolerant comparison.
fuzz0←{↑⍺⍺/⍺ ⍵+⎕ct>|⍺ ⍵} ⍝ 0-fuzzy comparison.
(⍺⌹⍵)≡fuzz0 ⍺ gauss_jordan ⍵
}
⍝ The dfns.dws test scripts are used in Dyalog's overnight QA check to prove
⍝ the integrity of each version of the interpreter on each supported hardware
⍝ platform. In the above test, comparison around 0 has been made slightly more
⍝ tolerant to accommodate small differences in compiler optimisation in differ-
⍝ ent compilers.
⍝ monadic ---------------------------
try ↑(1 1 2)(¯1 ¯2 3)(3 ¯7 4)
1
try ↑(4 8 4 0)(1 4 7 2)(1 5 4 ¯3)(1 3 0 ¯2)
1
try ↑(1 2 3)(¯3 1 5)(2 4 ¯1)
1
⍝ dyadic ----------------------------
(3 4⍴⍳12) try ↑(1 1 2)(¯1 ¯2 3)(3 ¯7 4)
1
(3 4⍴⍳12) try ↑(1 2 3)(¯3 1 5)(2 4 ¯1)
1
(4 5⍴⍳12) try ↑(4 8 4 0)(1 4 7 2)(1 5 4 ¯3)(1 3 0 ¯2)
1
hil←{÷1+∘.+⍨(⍳⍵)-⎕io} ⍝ order ⍵ Hilbert matrix.
gauss_jordan∘hil¨ 0 to 5
┌┬─┬─────┬─────────────┬──────────────────────┬───────────────────────────────────┐
││1│ 4 ¯6│ 9 ¯36 30│ 16 ¯120 240 ¯140│ 25 ¯300 1050 ¯1400 630│
││ │¯6 12│¯36 192 ¯180│¯120 1200 ¯2700 1680│ ¯300 4800 ¯18900 26880 ¯12600│
││ │ │ 30 ¯180 180│ 240 ¯2700 6480 ¯4200│ 1050 ¯18900 79380 ¯117600 56700│
││ │ │ │¯140 1680 ¯4200 2800│¯1400 26880 ¯117600 179200 ¯88200│
││ │ │ │ │ 630 ¯12600 56700 ¯88200 44100│
└┴─┴─────┴─────────────┴──────────────────────┴───────────────────────────────────┘
⍝ We can modify the function to use rational numbers for perfect precision:
gauss_jordan_rats←{⎕IO←0 ⍝ Rational Gauss-Jordan.
elim←{ ⍝ elimination of row/col ⍺.
mat←⍵ ⍝ name matrix for updating.
v←⍺+{⍵⍳⌈/⍵}{×/*⌿⊃⌽⍵}¨⍺↓mat[;⍺] ⍝ index of pivot row.
mat[⍺ v;]←mat[v ⍺;] ⍝ exchange ⍺th and pth rows.
mat[⍺;]←mat[⍺;]q¨mat[⍺;⍺] ⍝ reduce col diagonal to 1.
mul←mat[;⍺]p¨¯2↑¨⍺≠⍳⊃⍴⍵ ⍝ multiplier.
mat d¨mul∘.p mat[⍺;] ⍝ reduce col off-diagonals to 0.
}
0::⎕SIGNAL ⎕EN ⍝ pass back error to caller.
⍺←{0,⊂⍵ rats 1}¨=/↑⍳⍴⍵ ⍝ id matrix for monadic case.
p←×rats prodquot ⍝ rational product.
q←÷rats prodquot ⍝ .. quotient.
d←+rats diff(-rats) ⍝ .. difference.
(⍴⍺)⍴(0 1×⍴⍵)↓↑elim/(⌽⍳⌊/⍴⍵),⊂⍵,⍺ ⍝ elimination/ ··· 2 1 0 (⍵,⍺)
}
prodquot←{ ⍝ product/quotient.
(s a)(t b)←⍺ ⍵ ⍝ signs and fractions.
((s≠t)>0∊a,b)(a ⍺⍺ b) ⍝ rule-of-signs.
}
diff←{ ⍝ difference.
(s a)(t b)←⍺ ⍵ ⍝ signs and fractions.
s≠t:s(a ⍺⍺ b) ⍝ differing signs:
≥/{×/*⌿⍵}¨a b:s(a ⍵⍵ b) ⍝ ⍺≥⍵: ⍺-⍵
(~s)(b ⍵⍵ a) ⍝ ⍺<⍵: -⍵-⍺
}
hilr←{ ⍝ rational ⍵-Hilbert matrix.
{0 ⍵}∘{1 rats ⍵}¨1+∘.+⍨(⍳⍵)-⎕IO
}
fmt←{ ⍝ ⍺-separated rational format.
↑⍺{ ⍝ ⍺ is separator.
(⍺/'¯'),↑⍺⍺{⍺,⍺⍺,⍵}/{ ⍝ sign, unsigned fraction.
⍕↑×nats/*nats⌿⍵,1 ⍝ using nats for precision.
}¨|(1 0=⊂↑{⍵>0}/↓⍵)/¨⊂⍵ ⍝ numerator/denominator.
}/⍵ ⍝ sign/fraction pair.
}
align←{ ⍝ ⍺-aligned columns.
⍵,⍨¨({(⌈⌿⍵)-[⊃⌽⍳⍴⍴⍵]⍵}⍵⍳¨⍺)/¨' '
}
show←'/'∘align∘('/'∘fmt¨) ⍝ display rational matrix.
⍕show hilr 5 ⍝ 5-Hilbert.
1/1 1/2 1/3 1/4 1/5
1/2 1/3 1/4 1/5 1/6
1/3 1/4 1/5 1/6 1/7
1/4 1/5 1/6 1/7 1/8
1/5 1/6 1/7 1/8 1/9
⍕show gauss_jordan_rats hilr 5 ⍝ inverse of 5-Hilbert.
25/1 ¯300/1 1050/1 ¯1400/1 630/1
¯300/1 4800/1 ¯18900/1 26880/1 ¯12600/1
1050/1 ¯18900/1 79380/1 ¯117600/1 56700/1
¯1400/1 26880/1 ¯117600/1 179200/1 ¯88200/1
630/1 ¯12600/1 56700/1 ¯88200/1 44100/1
⍝∇ gauss_jordan nats rats factors to
Back to: code
Back to: Workspaces