(module matrix-test "../matrix-lang.ss"
(require (planet schematics/schemeunit:2/test)
(planet schematics/schemeunit:2/text-ui))
(define (random-matrix m n)
(for/matrix m n
((i (in-range (* m n))))
(random (* 2 m n))))
(define (random-vector n)
(build-vector n (lambda (i) (random (* n 2)))))
(define tests
(test-suite
"simple-matrix.plt test suite"
(test-case
"matrix-ref and matrix-set!"
(let ((m (make-matrix 2 3 '#(1 2 3 4 5 6))))
(check-equal? (matrix-ref m 1 1) 5))
(for ((i (in-range 100)))
(let ((m (random-matrix 5 10)))
(let ((i (random 5))
(j (random 10))
(x (random)))
(matrix-set! m i j x)
(check-equal? (matrix-ref m i j) x)))))
(test-case
"matrix-transpose"
(for ((i (in-range 100)))
(let ((m (random-matrix (add1 (random 10)) (add1 (random 10)))))
(check-equal? m (matrix-transpose (matrix-transpose m))))))
(test-case
"algebraic operations on matrices"
(for ((i (in-range 100)))
(let ((i (add1 (random 10)))
(j (add1 (random 10))))
(let ((m1 (random-matrix i j))
(m2 (random-matrix i j)))
(check-equal? (+ m1 m2 (- m2)) m1)
(check-equal? (+ m1 m1) (* m1 2))
(check-equal? (+ m1 m1) (* 2 m1))
(check-equal? (+ (- m1 m2) m2) m1)
(check-equal? (- m1 m2) (* -1 (- m2 m1)))
(check-equal? (- m1 m2) (/ (- m2 m1) -1))))))
(test-case
"algebraic operations on vectors (and dot product)"
(check-equal? (* '#(15 21) '#(1 2)) 57)
(for ((i (in-range 100)))
(let ((n (random 10)))
(let ((v1 (random-vector n))
(v2 (random-vector n)))
(check-equal? (+ v1 v1) (* v1 2))
(check-equal? (+ v1 v1) (* 2 v1))
(check-equal? (+ v1 v2 (- v2)) v1)
(check-equal? (- v1 v2) (* -1 (- v2 v1)))
(check-equal? (/ v1 -1) (- v1))
(check-equal? (* v1 v2) (* v2 v1))))))
(test-case
"matrix-vector operations"
(for ((i (in-range 100)))
(let ((ni (random 10))
(nj (random 10)))
(let ((m (random-matrix ni nj))
(vi (random-vector ni))
(vj (random-vector nj)))
(check-equal? (* m vj) (* vj (matrix-transpose m)))
(check-equal? (* vi m) (* (matrix-transpose m) vi))
(check-equal? (* vi (matrix-identity ni) vi) (* vi vi))
(check-equal? (* vi m vj) (* vj (matrix-transpose m) vi))))))
(test-case
"matrix*"
(for ((i (in-range 100)))
(let ((v (random-vector 4)))
(check-equal? (make-matrix 2 2 v) (apply matrix* 2 2 (vector->list v))))))))
(test/text-ui tests 'verbose))