【SICP练习】66 练习2.37
练习2.37
这道题花了我太长的时间了,一开始我就把题目中的m看成了w。然后题中给出的dot-product的两个参数我还以为一个是向量另一个是矩阵。怎么算都算不出来,直到看到“返回求和...”里的w只有一个i而没有j。好了,那么开始按照题目的要求来做题了。
既然发现了自己的错误,那么就知道了dot-product是干嘛的了,它可以用来求一个矩阵中的一列和一个向量的积。因此定义出matrix-*-vector就不难了。
(define (matrix-*-vector m v)
(map (lambda (col)
(dot-product col v))
m))
下面就来用题目中的数据来测试一下。
(matrix-*-vector ‘( (1 2 3 4) (4 5 6 6)(6 7 8 9) ) )
;Value: (30 56 80)
接下来我们来看看transpose,之所以把matrix-*-matrix放在最后是因为其的定义中需要transpose。
(define (transpose mat)
(accumulate-n cons ‘() mat))
看似这么一行代码,但其功能可强大了。
(transpose ‘((1 2 3 4) (4 5 6 6) (6 7 89)))
;Value: ((1 4 6) (2 5 7) (3 6 8) (4 69))
如果这里accumulate的变化有什么不明白的,可以回过头看看练习2.33的解答中的截图。而accumulate-n只不过是个accumulate的外壳而已,在变换中accumulate-n都将会慢慢变成accumulate。
在线性代数里我们学过,两个矩阵的乘积mn的第一列第一行的值等于m的第一列和n的第一行的点积,mn的第一列第二行的值等于m的第一列和n的第二行的点积……
(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map (lambda (col-of-m)
(matrix-*-vector colscol-of-m))
m)))
版权声明:本文为 NoMasp柯于旺 原创文章,如需转载请联系本人。