<< Previous exercise (2.36) | Index | Next exercise (2.38) >>


I find it a bit mind-boggling that we're essentially using cons, car, cdr, and recursion/iteration to invert a matrix.

 ;; Accumulates the result of the first and the already-accumulated 
 ;; rest. 
 (define (accumulate op initial sequence) 
   (if (null? sequence) 
       (op (car sequence) 
           (accumulate op initial (cdr sequence))))) 
 ;; accumulate-n 
 (define (accumulate-n op init sequence) 
   (define nil '()) 
   (if (null? (car sequence)) 
       (cons (accumulate op init (map car sequence)) 
             (accumulate-n op init (map cdr sequence))))) 
 (define matrix (list (list 1 2 3 4) (list 5 6 7 8) (list 9 10 11 12))) 
 (define (dot-product v1 v2) 
   (accumulate + 0 (map * v1 v2))) 
 ;; Test 
 (dot-product (list 1 2 3) (list 4 5 6)) 
 ;; a. 
 (define (matrix-*-vector m v) 
   (map (lambda (m-row) (dot-product m-row v)) 
 ;; Test 
 (matrix-*-vector matrix (list 2 3 4 5)) 
 ;; b. 
 (define nil '()) 
 (define (transpose m) 
   (accumulate-n cons nil m)) 
 ;; Test 
 (transpose matrix) 
 ;; c. 
 (define (matrix-*-matrix m n) 
   (let ((n-cols (transpose n))) 
     (map (lambda (m-row) 
            (map (lambda (n-col)  
                   (dot-product m-row n-col))  
 ;; But the inner map is just matrix-*-vector, so here's better: 
 (define (matrix-*-matrix m n) 
   (let ((n-cols (transpose n))) 
     (map (lambda (m-row) (matrix-*-vector n-cols m-row)) 
 ;; Test 
 (matrix-*-matrix matrix (list (list 1 2) (list 1 2) (list 1 2) (list 1 2))) 


Above is incorrect, Matrix times Vector results in another Matrix.

 ;We need to use accumulate 
 (define (matrix-*-vector m v) 
   (map (lambda (x) (accumulate cons '() (map * x v))) m)) 
 ;Additional procedure 
 (define (vector-*-vector w v) 
   (map * w v)) 
 ;This one is like previous one 
 (define (transpose mat) 
   (accumulate-n cons '() mat)) 
 ;Here x are m's rows and y are n's columns 
 ; We use map, to get whole row and column 
 ; and later feed vector-*-vector with them  
 (define (matrix-*-matrix m n) 
   (let ((cols (transpose n))) 
     (map (lambda (x y) (vector-*-vector x y)) m cols)))