racket/collects/math/private/matrix/matrix-expt.rkt
Neil Toronto f40ad2ca9d `math/matrix' fixes; please merge to 5.3.2.
* Fixed type of `matrix-expt'

* Made matrix functions respect `array-strictness' parameter (mostly
  wrapping functions with `parameterize' and return values with
  `array-default-strictness'; reindentation makes changes look larger)

* Added strictness tests
2013-01-16 16:40:43 -07:00

32 lines
1.1 KiB
Racket

#lang typed/racket/base
(require "matrix-types.rkt"
"matrix-constructors.rkt"
"matrix-arithmetic.rkt"
"utils.rkt")
(provide matrix-expt)
(: matrix-expt/ns (case-> ((Matrix Real) Positive-Integer -> (Matrix Real))
((Matrix Number) Positive-Integer -> (Matrix Number))))
(define (matrix-expt/ns a n)
(define n/2 (quotient n 2))
(if (zero? n/2)
;; n = 1
a
(let ([m (* n/2 2)])
(if (= n m)
;; n is even
(let ([a^n/2 (matrix-expt/ns a n/2)])
(matrix* a^n/2 a^n/2))
;; m = n - 1
(matrix* a (matrix-expt/ns a m))))))
(: matrix-expt (case-> ((Matrix Real) Integer -> (Matrix Real))
((Matrix Number) Integer -> (Matrix Number))))
(define (matrix-expt a n)
(cond [(not (square-matrix? a)) (raise-argument-error 'matrix-expt "square-matrix?" 0 a n)]
[(negative? n) (raise-argument-error 'matrix-expt "Natural" 1 a n)]
[(zero? n) (identity-matrix (square-matrix-size a))]
[else (call/ns (λ () (matrix-expt/ns a n)))]))