matrices.scm 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. ;; ===============
  2. ;; data abstration
  3. ;; ===============
  4. (define* (make-matrix rows cols #:key (fill 'undefined))
  5. (make-array fill rows cols))
  6. (define (list->matrix lst)
  7. (let ([dimensions 2])
  8. (list->array dimensions lst)))
  9. (define (matrix->list mat)
  10. (array->list mat))
  11. (define (matrix-ref mat row-ind col-ind)
  12. (array-ref mat row-ind col-ind))
  13. (define (matrix-set! mat val . inds)
  14. (apply array-set! mat val inds))
  15. (define (matrix-shape mat)
  16. (array-shape mat))
  17. (define (matrix-row-count mat)
  18. (array-length mat))
  19. (define (matrix-col-count mat)
  20. (let ([shape (matrix-shape mat)])
  21. (let ([upper-lower-inds-col (cadr shape)])
  22. (+ (- (cadr upper-lower-inds-col)
  23. (car upper-lower-inds-col))
  24. 1))))
  25. (define (matrix-get-row mat row-ind)
  26. (define col-count (matrix-col-count mat))
  27. (define (iter col-ind)
  28. (cond [(> col-ind (- col-count 1)) '()]
  29. [else (cons (matrix-ref mat row-ind col-ind)
  30. (iter (+ col-ind 1)))]))
  31. (list->vector (iter 0)))
  32. (define (matrix-get-col mat col-ind)
  33. (define row-count (matrix-row-count mat))
  34. (define (iter row-ind)
  35. (cond [(> row-ind (- row-count 1)) '()]
  36. [else (cons (matrix-ref mat row-ind col-ind)
  37. (iter (+ row-ind 1)))]))
  38. (list->vector (iter 0)))
  39. ;; =================
  40. ;; matrix operations
  41. ;; =================
  42. (define (multiply-vectors v1 v2)
  43. (define (iter ind max-ind)
  44. (cond [(> ind max-ind) '()]
  45. [else (cons (* (vector-ref v1 ind) (vector-ref v2 ind))
  46. (iter (+ ind 1) max-ind))]))
  47. (apply + (iter 0 (- (vector-length v1) 1))))
  48. (define (matrix-multiply mat1 mat2)
  49. (let ([mat1-row-count (matrix-row-count mat1)]
  50. [mat1-col-count (matrix-col-count mat1)]
  51. [mat2-row-count (matrix-row-count mat2)]
  52. [mat2-col-count (matrix-col-count mat2)])
  53. (cond [(not (= mat1-row-count mat2-col-count))
  54. (throw 'incompatible-matrix-dimensions
  55. (simple-format #f "matrix 1 row count ~a, matrix 2 column count: ~a"
  56. mat1-row-count
  57. mat2-col-count))]
  58. [else
  59. (let ([result-mat (make-matrix mat1-row-count mat2-col-count #:fill 'undefined)])
  60. (do ([r1 0 (+ r1 1)])
  61. ([>= r1 mat1-row-count])
  62. (do ([c2 0 (+ c2 1)])
  63. ([>= c2 mat2-col-count])
  64. (matrix-set! result-mat
  65. (multiply-vectors (matrix-get-row mat1 r1)
  66. (matrix-get-col mat2 c2))
  67. r1 c2)))
  68. result-mat)])))