练习2.37。假设我们将向量v= (vi)表示为数列,矩阵m= (mij)表示为向量序列(矩阵的行)。例如,矩阵

表示为序列((1 2 3 4) (4 5 6 6) (6 7 8 9))。通过这种表示,我们可以使用序列运算简洁地表示基本矩阵和向量运算。这些操作(在任何关于矩阵代数的书中都有描述)如下:

我们可以定义点积as17 (定义(点积v)(累计+0 (map *v)),在以下计算其他矩阵操作的过程中填充缺少的表达式。(练习2.36中定义了过程累加-n)。(定义(矩阵-*-向量m)(映射 m)) (定义(转置垫)(累积-n mat)) (定义(矩阵-*-矩阵m) (let ((cols (transpose n) ( m))
我编写了以下解决方案:
(define (accumulate op initial items)
(if (null? items)
initial
(op (car items) (accumulate op initial (cdr items)))))
(define (accumulate-n op init seqs)
(if (null? (car seqs))
null
(cons (accumulate op init (map (lambda (x) (car x)) seqs))
(accumulate-n op init (map (lambda (x) (cdr x)) seqs)))))
(define (dot-product v w)
(accumulate + 0 (map * v w)))
(define (matrix-*-vector m v)
(accumulate-n +
0
(map (lambda (row)
(map (lambda (i j) (* i j)) row v)) m)))
(define (transpose mat)
(accumulate-n (lambda (x y) (cons x y)) null mat))
(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map (lambda (m-row)
(accumulate-n +
0
(map (lambda (col)
(map * m-row col))
cols))) m)))
(define m1 (list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9)))
(define m2 (list (list 10 20 30) (list 40 50 60) (list 70 80 90) (list 100 110 120)))
(define v1 (list 10 20 30 40))你认为如何?
发布于 2011-04-15 19:47:52
您对transpose的定义是正确的,尽管它可以简洁地写成:
(define (transpose mat)
(accumulate-n cons null mat))其余两个定义可以通过使用前面定义的函数编写得更简洁。注意,将矩阵乘成向量在概念上与获得向量的点积和矩阵的每一行是相同的。因此,可以将matrix-*-vector定义为:
(define (matrix-*-vector m v)
(map (lambda (row) (dot-product v row)) m))上述定义满足了演习的要求。
同样,A到B的矩阵乘法与转置B和对A的每一行执行矩阵向量乘法相同,因此,可以将matrix-*-matrix定义为:
(define (matrix-*-matrix m n)
(let
((cols (transpose n)))
(map (lambda (row) (matrix-*-vector cols row)) m)))如果你想走得比练习要求的更远,你可以考虑使用函数赛跑。Currying允许将函数逐步应用于参数。如果您的方案实现提供了curry函数,您可以编写:
(define (matrix-*-vector m v)
(map (curry dot-product v) m))
(define (matrix-*-matrix m n)
(map (curry matrix-*-vector (transpose n)) m))https://codereview.stackexchange.com/questions/1802
复制相似问题