# sicp-ex-2.37

yc

``` (define (accumulate ops initial sequence)
(if (null? sequence)
initial
(ops (car sequence)
(accumulate ops initial (cdr sequence)))))

(define (accumulate-n op init seqs)
(if (null? (car seqs))
()
(cons (accumulate op init (map car seqs))
(accumulate-n op init (map cdr seqs)))))

(define (dot-product v w)
(accumulate + 0 (map * v w)))

(define (matrix-*-vector m v)
(map (lambda (w)
(dot-product v w)) m))

(define (transpose m)
(accumulate-n cons () m))

(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map (lambda (v) (matrix-*-vector cols v)) m)))
```

jz

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

```
;; Accumulates the result of the first and the already-accumulated
;; rest.
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))

;; accumulate-n
(define (accumulate-n op init sequence)
(define nil '())
(if (null? (car sequence))
nil
(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))
m))

;; 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))
n-cols))
m)))

;; 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))
m)))

;; Test
(matrix-*-matrix matrix (list (list 1 2) (list 1 2) (list 1 2) (list 1 2)))

```

intarga

Mine looks similar to jz's, but I'm posting with evaluation commented after the expressions, so people can double check their solutions.

``` (define my-matrix (list (list 1 2 3 4)
(list 4 5 6 6)
(list 6 7 8 9)))

(define (dot-product v w)
(accumulate + 0 (map * v w)))

(dot-product (car my-matrix)
(car (cdr my-matrix))) ; 56

(define (matrix-*-vector m v)
(map (lambda (mi) (dot-product mi v)) m))

(matrix-*-vector my-matrix (car my-matrix)) ; (30 56 80)

(define (transpose m)
(accumulate-n cons '() m))

(transpose my-matrix) ; ((1 4 6) (2 5 7) (3 6 8) (4 6 9))

(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map (lambda (mi)
(map (lambda (nj)
(dot-product mi nj))
cols))
m)))

(matrix-*-matrix my-matrix (transpose my-matrix)) ; ((30 56 80) (56 113 161) (80 161 230))
(matrix-*-matrix (list (list 1 2)
(list 3 4))
(list (list 1 2)
(list 3 4))) ; ((7 10) (15 22))
```