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)
About these ads

,

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: