gpt4 book ai didi

方案中的矩阵乘法,列表列表

转载 作者:行者123 更新时间:2023-12-04 01:27:58 26 4
gpt4 key购买 nike

我开始研究Scheme,但我不明白其中的一些。我正在使用 DrRacket。

我写了以下代码:

(define mult_mat
(λ (A B)
(Trans_Mat (map (λ (x) (mul_Mat_vec A x))
(Trans_Mat B)))))

使用这个函数:
(define Trans_Mat
(λ (A)
(apply map (cons list A))))
(define mul_Mat_vec
(λ (A v)
(map (λ (x) (apply + (map * x v)))
A)))

mult_mat ,我在转置矩阵 B 的每个向量中乘以矩阵 A。
它工作正常。

我在网上找到了一个代码,它以一种我不明白的方式进行乘法:
(define (matrix-multiply matrix1 matrix2)
(map
(λ (row)
(apply map
(λ column
(apply + (map * row column)))
matrix2))
matrix1))

在此代码中, row是矩阵 A 的列表,但我不明白 column更新。

这部分代码: (apply + (map * row column))是向量的点积 row和矢量 column
例如:A 是一个 2X3 矩阵,B 是一个 3X2 矩阵,如果不是 (apply + (map * row column))我写 1 ,然后我将得到一个矩阵 2X2,其条目值为 1
我不明白它是如何工作的。

谢谢。

最佳答案

啊,老( apply map foo _a_list_ )诡计。非常聪明。
事实上(apply map (cons list A))(apply map list A) 相同.就是这样apply被定义为工作。
尝试一些具体的例子通常有助于“明白”:

(apply map       list '((1 2 3)  (10 20 30)) )
=
(apply map (cons list '((1 2 3) (10 20 30))))
=
(apply map (list list '(1 2 3) '(10 20 30) ))
=
( map list '(1 2 3) '(10 20 30) )
=
'((1 10) (2 20) (3 30))
使最后一个参数的元素 '((1 2 3) (10 20 30)) ,拼接成整体 apply map ...形式。
矩阵转置(列表列表,真的)。
所以你有了
(define (mult_mat A B)
(Trans_Mat (map (λ (B_column) (mul_Mat_vec A B_column))
(Trans_Mat B))))

(define (Trans_Mat A)
(apply map list A))

(define (mul_Mat_vec A v)
(map (λ (A_row) (apply + (map * A_row v)))
A))

(define (matrix-multiply A B)
(map
(λ (A_row)
(apply map
(λ B_column
(apply + (map * A_row B_column)))
B))
A))
注意它是 (λ B_column ... , 没有括号。在 ((λ args ...) x y z) ,当输入 lambda 时, args获取打包在列表中的所有参数:
((λ args ...) x y z)
=
(let ([args (list x y z)])
...)
还要注意
      (apply map
(λ B_column
(apply + (map * A_row B_column)))
B)
遵循相同的“棘手”模式。它实际上是一样的
      (apply map (cons
(λ B_column
(apply + (map * A_row B_column)))
B ) )
=
( map
(λ B_column
(apply + (map * A_row B_column)))
B_row1
B_row2
....
B_rowN )
=
(cons (let ([B_column_1 (map car B)])
(apply + (map * A_row B_column_1)))
(map (λ B_column
(apply + (map * A_row B_column)))
(cdr B_row1)
(cdr B_row2)
....
(cdr B_rowN)) )
=
(cons
(apply (λ B_column (apply + (map * A_row B_column)))
(map car B))
(apply map
(λ B_column
(apply + (map * A_row B_column)))
(map cdr B)))
根据 map 的定义.
因此,通过应用 map ,矩阵被“打开”成它的元素列表行,然后当多参数 map开始处理这些行作为其参数,lambda 函数相应地一致地应用于每一行的后续数字;从而达到与显式转置相同的效果。但现在额外的好处是,我们不需要像第一个版本那样将结果转回正确的形式。
这很聪明,也很好。

因此,有了所有这些理解,让我们尝试重新阅读原始代码,看看我们是否也能看到它的原貌。
(define (matrix-multiply matrix1 matrix2)
(map
(λ (row)
(apply map
(λ column ;; <<------ no parens!
(apply + (map * row column)))
matrix2))
matrix1))
内容如下:对于每个 rowmatrix1 , 多参数 map lambdamatrix2 . matrix2本身也是一个行列表;当我们多参数- map在行上, lambda依次应用于行中的每一列。
因此,对于 matrix1 中的每一行, 对于 matrix2 中的每一列, 按元素乘以该行和该列,然后对结果求和;从而将每一行转换为这些总和的列表。这显然只有在行的长度和每列的长度相同时才有效:如果第一个矩阵的“宽度”和第二个矩阵的“高度”相同。

关于方案中的矩阵乘法,列表列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52184095/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com