逆行列を求める 数式の改良

数式を少し改良しました。

(define (sort-sum-values lis)
  (let ((num (apply + (filter number? lis)))
	(vals (filter symbol? lis)))
    (if (= num 0)
	(sort vals)
	(append `(,num) (sort vals)))))

(define (sort-product-values lis)
  (let ((num (apply * (filter number? lis)))
	(vals (filter symbol? lis)))
    (if (= num 1)
	(sort vals)
	(append `(,num) (sort vals)))))

(define (opti-sum a1 a2)
  (cond ((and (sum? a1) (sum? a2)) (append '(+) (sort-sum-values (append (cdr a1) (cdr a2)))))
	((sum? a1) (append '(+) (sort-sum-values (append (cdr a1) `(,a2)))))
	((sum? a2) (append '(+) (sort-sum-values (append `(,a1) (cdr a2)))))
	(else (list '+ a1 a2))))

(define (opti-product a1 a2)
  (cond ((and (product? a1) (product? a2)) (append '(*) (sort-product-values (append (cdr a1) (cdr a2)))))
	((product? a1) (append '(*) (sort-product-values (append (cdr a1) `(,a2)))))
	((product? a2) (append '(*) (sort-product-values (append `(,a1) (cdr a2)))))
	(else (list '* a1 a2))))

これを追加

(define (make-sum a1 a2)
  (cond ((=number? a1 0) a2)
        ((=number? a2 0) a1)
        ((and (number? a1) (number? a2)) (+ a1 a2))
        (else (opti-sum a1 a2))))

(define (make-product m1 m2)
  (cond ((or (=number? m1 0) (=number? m2 0)) 0)
        ((=number? m1 1) m2)
        ((=number? m2 1) m1)
        ((and (number? m1) (number? m2)) (* m1 m2))
        (else (opti-product m1 m2))))

make-sum と make-product はこんな風に直します。


改良前

gosh> (inverse-matrix '((1 0 0) (a 1 0) (b c 1)))
((1 0 0) ((* -1 a) 1 0) ((+ (* -1 b) (* (* -1 a) (* -1 c))) (* -1 c) 1))

改良後

gosh> (inverse-matrix '((1 0 0) (a 1 0) (b c 1)))
((1 0 0) ((* -1 a) 1 0) ((+ (* -1 b) (* a c)) (* -1 c) 1))

前よりはだいぶ良くなりました。