連立方程式
逆行列を求める関数までかいた。
ベクトルの加減算、スカラ倍、内積、絶対値と
行列の表示、加減算、スカラ倍、行列同士の積、べき乗、n次の単位行列、逆行列をつくるなり計算するなりなもの。
(define (vecplus v1 v2) (map + v1 v2)) (define (vecminus v1 v2) (map - v1 v2)) (define (vecmulti s v) (map (lambda (a) (* a s)) v)) (define (vecdiv v s) (map (lambda (a) (/ a s)) v)) (define (innr_product v1 v2) (fold + 0 (map * v1 v2))) (define (vecabs v) (sqrt (fold + 0 (map (lambda (a) (* a a)) v)))) (define (matprint m) (define (iter t) (if (null? t) (print #\)) (let ((a 1)) (print (car t)) (iter (cdr t))))) (print #\() (iter m)) (define (matplus m1 m2) (map vecplus m1 m2)) (define (matminus m1 m2) (map vecminus m1 m2)) (define (mattimes s m) (map (lambda (v) (vecmulti s v)) m)) (define (matmulti m1 m2) (map (lambda (v1) (let loop ((v2 m2)) (if (null? (car v2)) '() (cons (innr_product v1 (map car v2)) (loop (map cdr v2)))))) m1)) (define (matpower m s) (let loop ((c m) (t s)) (if (> t 1) (loop (matmulti c m) (- t 1)) c))) (define (mattranp m) (let loop ((t m)) (if (null? (car t)) '() (cons (map car t) (loop (map cdr t)))))) (define (mkmatunit n) (let loop ((i n)) (if (> i 0) (cons (let mkvec ((j n)) (if (> j 0) (cons (if (= i j) 1 0) (mkvec (- j 1))) '())) (loop (- i 1))) '()))) (define (matrev m) (define (phase m e c nf) (let ((d (vecdiv (car m) (list-ref (car m) c))) (f (vecdiv (car e) (list-ref (car m) c)))) (if (null? (cdr m)) (values (list d) (list f)) (receive (r1 r2) (phase (map (lambda (v) (vecminus v (vecmulti (list-ref v c) d))) (cdr m)) (map (lambda (v i) (vecminus v (vecmulti (list-ref i c) f))) (cdr e) (cdr m)) (nf c 1) nf) (values (cons d r1) (cons f r2)))))) (let* ((n (length m)) (e (mkmatunit n))) (receive (t1 t2) (phase m e 0 +) (receive (r ans) (phase (reverse t1) (reverse t2) (- n 1) -) (reverse ans)))))