Exercise 2.37. Suppose we represent vectors v = (vi) as sequences of numbers, and matrices m = (mij) as sequences of vectors (the rows of the matrix). For example, the matrix
is represented as the sequence ((1 2 3 4) (4 5 6 6) (6 7 8 9)). With this representation, we can use sequence operations to concisely express the basic matrix and vector operations. These operations (which are described in any book on matrix algebra) are the following:
We can define the dot product as17
(define (dot-product v w) (accumulate + 0 (map * v w)))
Fill in the missing expressions in the following procedures for computing the other matrix operations. (The procedure accumulate-n is defined in exercise 2.36.)
(define (matrix-*-vector m v) (map <??> m)) (define (transpose mat) (accumulate-n <??> <??> mat)) (define (matrix-*-matrix m n) (let ((cols (transpose n))) (map <??> m)))
I wrote the following solutions:
(define (accumulate op initial items)
(if (null? items)
initial
(op (car items) (accumulate op initial (cdr items)))))
(define (accumulate-n op init seqs)
(if (null? (car seqs))
null
(cons (accumulate op init (map (lambda (x) (car x)) seqs))
(accumulate-n op init (map (lambda (x) (cdr x)) seqs)))))
(define (dot-product v w)
(accumulate + 0 (map * v w)))
(define (matrix-*-vector m v)
(accumulate-n +
0
(map (lambda (row)
(map (lambda (i j) (* i j)) row v)) m)))
(define (transpose mat)
(accumulate-n (lambda (x y) (cons x y)) null mat))
(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map (lambda (m-row)
(accumulate-n +
0
(map (lambda (col)
(map * m-row col))
cols))) m)))
(define m1 (list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9)))
(define m2 (list (list 10 20 30) (list 40 50 60) (list 70 80 90) (list 100 110 120)))
(define v1 (list 10 20 30 40))
What do you think?