1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- #!/usr/bin/ruby
- #
- ## https://rosettacode.org/wiki/Gauss-Jordan_matrix_inversion
- #
- func rref (M) {
- var (j, rows, cols) = (0, M.len, M[0].len)
- for r in (^rows) {
- j < cols || return M
- var i = r
- while (!M[i][j]) {
- ++i == rows || next
- i = r
- ++j == cols && return M
- }
- M[i, r] = M[r, i] if (r != i)
- M[r] = (M[r] »/» M[r][j])
- for n in (^rows) {
- next if (n == r)
- M[n] = (M[n] »-« (M[r] »*» M[n][j]))
- }
- ++j
- }
- return M
- }
- func gauss_jordan_invert (M) {
- var I = M.len.of {|i|
- M.len.of {|j|
- i == j ? 1 : 0
- }
- }
- var A = gather {
- ^M -> each {|i| take(M[i] + I[i]) }
- }
- rref(A).map { .last(M.len) }
- }
- var n = irand(3, 7)
- var A = n.of {
- n.of { irand(-10, 10) }
- }
- say gauss_jordan_invert(A).map {
- .map { "%6s" % .as_rat }.join(" ")
- }.join("\n")
- assert_eq(A.inv, gauss_jordan_invert(A))
|