123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- ;; ===============
- ;; data abstration
- ;; ===============
- (define* (make-matrix rows cols #:key (fill 'undefined))
- (make-array fill rows cols))
- (define (list->matrix lst)
- (let ([dimensions 2])
- (list->array dimensions lst)))
- (define (matrix->list mat)
- (array->list mat))
- (define (matrix-ref mat row-ind col-ind)
- (array-ref mat row-ind col-ind))
- (define (matrix-set! mat val . inds)
- (apply array-set! mat val inds))
- (define (matrix-shape mat)
- (array-shape mat))
- (define (matrix-row-count mat)
- (array-length mat))
- (define (matrix-col-count mat)
- (let ([shape (matrix-shape mat)])
- (let ([upper-lower-inds-col (cadr shape)])
- (+ (- (cadr upper-lower-inds-col)
- (car upper-lower-inds-col))
- 1))))
- (define (matrix-get-row mat row-ind)
- (define col-count (matrix-col-count mat))
- (define (iter col-ind)
- (cond [(> col-ind (- col-count 1)) '()]
- [else (cons (matrix-ref mat row-ind col-ind)
- (iter (+ col-ind 1)))]))
- (list->vector (iter 0)))
- (define (matrix-get-col mat col-ind)
- (define row-count (matrix-row-count mat))
- (define (iter row-ind)
- (cond [(> row-ind (- row-count 1)) '()]
- [else (cons (matrix-ref mat row-ind col-ind)
- (iter (+ row-ind 1)))]))
- (list->vector (iter 0)))
- ;; =================
- ;; matrix operations
- ;; =================
- (define (multiply-vectors v1 v2)
- (define (iter ind max-ind)
- (cond [(> ind max-ind) '()]
- [else (cons (* (vector-ref v1 ind) (vector-ref v2 ind))
- (iter (+ ind 1) max-ind))]))
- (apply + (iter 0 (- (vector-length v1) 1))))
- (define (matrix-multiply mat1 mat2)
- (let ([mat1-row-count (matrix-row-count mat1)]
- [mat1-col-count (matrix-col-count mat1)]
- [mat2-row-count (matrix-row-count mat2)]
- [mat2-col-count (matrix-col-count mat2)])
- (cond [(not (= mat1-row-count mat2-col-count))
- (throw 'incompatible-matrix-dimensions
- (simple-format #f "matrix 1 row count ~a, matrix 2 column count: ~a"
- mat1-row-count
- mat2-col-count))]
- [else
- (let ([result-mat (make-matrix mat1-row-count mat2-col-count #:fill 'undefined)])
- (do ([r1 0 (+ r1 1)])
- ([>= r1 mat1-row-count])
- (do ([c2 0 (+ c2 1)])
- ([>= c2 mat2-col-count])
- (matrix-set! result-mat
- (multiply-vectors (matrix-get-row mat1 r1)
- (matrix-get-col mat2 c2))
- r1 c2)))
- result-mat)])))
|