方案中的矩阵乘法,列表列表 [英] Matrix multiplication in scheme, List of lists

查看:164
本文介绍了方案中的矩阵乘法,列表列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始研究Scheme,但我不了解其中的一些内容.我正在使用DrRacket.

I started to study Scheme and I do not understand some of it. I'm using 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中,我将矩阵A乘以转置矩阵B的每个向量. 效果很好.

In mult_mat, I multiply the matrix A in each vector of the transpose matrix B. It works fine.

我在网上找到了一个以我不了解的方式进行乘法运算的代码:

I found a code on the web that makes the multiplication in a way that I don't understand:

(define (matrix-multiply matrix1 matrix2)
  (map
   (λ (row)
     (apply map
       (λ column
         (apply + (map * row column)))
       matrix2))
   matrix1))

在此代码中,row是矩阵A的列表的列表,但我不理解column的更新方式.

In this code, row is a list of the lists of matrix A, but I don't understand how the column updates.

这部分代码:(apply + (map * row column))是向量row和向量column

This part of the code: (apply + (map * row column)) is the dot product of vector row and vector column

例如:A是矩阵2X3,B是矩阵3X2,如果我写的是1而不是(apply + (map * row column)),那么我将得到一个矩阵2X2,其条目值为1

For example: A is a matrix 2X3 and B is a matrix 3X2 and if instead of (apply + (map * row column)) I write 1, then I'll get a matrix 2X2 with entries valued 1

我不知道它是如何工作的.

I don't understand how it works.

谢谢.

推荐答案

啊,旧的( apply map foo _a_list_ )技巧.非常聪明.

Ah, the old ( apply map foo _a_list_ ) trick. Very clever.

实际上(apply map (cons list A))(apply map list A)相同.这就是apply定义的工作方式.

In fact (apply map (cons list A)) is the same as (apply map list A). That's just how apply is defined to work.

尝试一些具体示例通常有助于获取":

Trying out some concrete examples usually helps to "get it":

(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))

矩阵转置. (实际上是列表列表.)

Matrix transposition. (list of lists, really.)

所以你有

(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获取打包在列表中的所有参数:

Notice it's (λ B_column ..., without parentheses. In ((λ args ...) x y z), when the lambda is entered, args gets all the arguments packaged in a list:

((λ args ...) x y z)
=
(let ([args (list x y z)])
  ...)

也请注意

      (apply map
             (λ B_column
               (apply + (map * A_row B_column)))
             B)

遵循相同的棘手"模式.实际上与

follows the same "tricky" pattern. It's in fact the same as

      (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)))
             (map cdr B_row1)
             (map cdr B_row2)
             ....
             (map 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函数相应地统一应用于每行的后续数字;从而达到与显式换位相同的效果.但是现在增加的好处是,我们不需要将结果转回适当的格式,因为我们需要处理您的第一个版本.

Thus, by applying the map, the matrix is "opened up" into the list of its rows, and then when map gets to work on these rows as its arguments, the lambda function gets applied to each row's subsequent numbers, in unison, correspondingly; thus achieving the same effect as the explicit transposition had. But now the added bonus is, we don't need to transpose the result back into the proper form, as we have to do with your first version.

这个很聪明.

这篇关于方案中的矩阵乘法,列表列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆