## Matrix manipulation in scheme

Here’s the code I wrote for matrix manipulation in scheme. It use lists.

### Procedure that creates new square identity matrix:

``````(define (make-matrix n)
(let outter ((i n) (result '()))
(if (= i 0)
result
(outter (- i 1)
(cons
(let inner ((j n) (row '()))
(if (= j 0)
row
(inner (- j 1) (cons (if (= i j) 1 0) row))))
result)))))
``````

### Procedure that return nth element of the list, which is the same as nth row of the matrix:

``````(define (nth list n)
(let iter ((n n) (result list))
(if (= n 0)
(car result)
(iter (- n 1)
(cdr result)))))

(define matrix-row nth)
``````

### Procedure that return nth column of the matrix:

``````(define (matrix-col M n)
(let iter ((i (length M)) (result '()))
(if (= i 0)
result
(iter (- i 1)
(cons (nth (nth M (- i 1)) n) result)))))
``````

### Procedure for multiplication of two matrices:

``````(define (matrix-mul N M)
(let rows ((i (length N)) (result '()))
(if (= i 0)
result
(rows (- i 1)
(cons
(let cols ((j (length (car M))) (row '()))
(if (= j 0)
row
(cols
(- j 1)
(cons (reduce + (map *
(matrix-row N (- i 1))
(matrix-col M (- j 1))))
row))))
result)))))
``````

### For above procedure you will need reduce procedure:

``````(define (reduce fun lst)
(let iter ((result (car lst)) (lst (cdr lst)))
(if (null? lst)
result
(iter (fun result (car lst)) (cdr lst)))))``````

### Procedure for multiplication of vector and matrix:

``````(define (matrix-vector-mul v M)
(car (matrix-mul (list v) M)))
``````

### Procedure for transpose the matrix:

``````(define (matrix-transpose M)
(if (null? (car M))
'()
(cons (map car M)
(matrix-transpose (map cdr M)))))
``````

### Tail recursive procedure for transpose the matrix:

``````(define (matrix-transpose M)
(let iter ((M M) (result '()))
(if (null? (car M))
result
(iter (map cdr M) (append result (list (map car M)))))))
``````

### Procedure that calculate the sum of two matrices:

``````(define (matrix-sum N M)
(let iter ((N N) (M M) (result '()))
(if (or (null? N) (null? M))
(reverse result)
(iter (cdr N)
(cdr M)
(cons (map + (car N) (car M)) result)))))
``````

### Shorter version of the above:

``````(define (matrix-sum N M)
(map (lambda (nrow mrow) (map + nrow mrow)) N M))
``````

### Usage:

You can use those procedures like this:

``````(define M1 '((1 2 3) (2 3 4) (3 2 1)))
(define M2 (make-matrix 3))

(write (matrix-mul M1 M2))
(newline)
(write (matrix-mul M1 '((2 3 1) (1 2 1) (1 3 1))))
(newline)
(write (matrix-sum M1 M2))
(newline)
(write (matrix-vector-mul '(2 3 1) M1)
``````