@@ 0,0 1,67 @@
+package main
+
+import (
+ "math/big"
+)
+
+type Matrix [][]big.Rat
+
+func (M Matrix) RREF() {
+ lead := 0
+ rowCount := len(M)
+ if rowCount == 0 {
+ return
+ }
+ columnCount := len(M[0])
+ zero := big.NewRat(0, 1)
+
+ for r := 0; r < rowCount; r++ {
+ if lead >= columnCount {
+ return
+ }
+ i := r
+ for M[i][lead].Cmp(zero) == 0 {
+ i++
+ if rowCount == i {
+ i = r
+ lead++
+ if columnCount == lead {
+ return
+ }
+ }
+ }
+ M[i], M[r] = M[r], M[i]
+ f := &big.Rat{}
+ f.Inv(&M[r][lead])
+ for j := range M[r] {
+ M[r][j].Mul(&M[r][j], f)
+ }
+ for i = 0; i < rowCount; i++ {
+ if i != r {
+ f.Set(&M[i][lead])
+ for j, e := range M[r] {
+ M[i][j].Sub(&M[i][j], new(big.Rat).Mul(&e, f))
+ }
+ }
+ }
+ lead++
+ }
+}
+
+// assumes `M' and `other' are valid matrices
+func (M Matrix) Equals(other Matrix) bool {
+ if len(M) != len(other) {
+ return false
+ }
+ if len(M) > 0 && len(M[0]) != len(other[0]) {
+ return false
+ }
+ for r := range M {
+ for c := range M[r] {
+ if M[r][c].Cmp(&other[r][c]) != 0 {
+ return false
+ }
+ }
+ }
+ return true
+}
@@ 0,0 1,36 @@
+package main
+
+import (
+ "math/big"
+ "testing"
+)
+
+func TestRREF(t *testing.T) {
+ mat := Matrix{
+ {*big.NewRat( 1, 1), *big.NewRat(2, 1), *big.NewRat(-1, 1), *big.NewRat( -4, 1)},
+ {*big.NewRat( 2, 1), *big.NewRat(3, 1), *big.NewRat(-1, 1), *big.NewRat(-11, 1)},
+ {*big.NewRat(-2, 1), *big.NewRat(0, 1), *big.NewRat(-3, 1), *big.NewRat( 22, 1)},
+ }
+ mat.RREF()
+ result := Matrix{
+ {*big.NewRat(1, 1), *big.NewRat(0, 1), *big.NewRat(0, 1), *big.NewRat(-8, 1)},
+ {*big.NewRat(0, 1), *big.NewRat(1, 1), *big.NewRat(0, 1), *big.NewRat( 1, 1)},
+ {*big.NewRat(0, 1), *big.NewRat(0, 1), *big.NewRat(1, 1), *big.NewRat(-2, 1)},
+ }
+ if !mat.Equals(result) {
+ t.Fail()
+ }
+
+ mat = Matrix{
+ {*big.NewRat(1, 1), *big.NewRat(3, 1), *big.NewRat(-1, 1)},
+ {*big.NewRat(0, 1), *big.NewRat(1, 1), *big.NewRat(7, 1)},
+ }
+ mat.RREF()
+ result = Matrix{
+ {*big.NewRat(1, 1), *big.NewRat(0, 1), *big.NewRat(-22, 1)},
+ {*big.NewRat(0, 1), *big.NewRat(1, 1), *big.NewRat( 7, 1)},
+ }
+ if !mat.Equals(result) {
+ t.Fail()
+ }
+}