Matrix scheme中的矩阵乘法,列表列表

Matrix scheme中的矩阵乘法,列表列表,matrix,scheme,racket,apply,transpose,Matrix,Scheme,Racket,Apply,Transpose,我开始研究这个计划,但我不了解其中的一些内容。我在用球拍 我编写了以下代码: (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)))) 在mult_mat中,我将转置矩阵B的每个向量中的矩阵A相

我开始研究这个计划,但我不了解其中的一些内容。我在用球拍

我编写了以下代码:

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

mult_mat
中,我将转置矩阵B的每个向量中的矩阵A相乘。 它很好用

我在网上发现了一个代码,它以一种我不理解的方式进行乘法运算:

(define (matrix-multiply matrix1 matrix2)
  (map
   (λ (row)
     (apply map
       (λ column
         (apply + (map * row column)))
       matrix2))
   matrix1))
(define (matrixMultiply matrix1 matrix2)
    (define matrix2Transpose (matrixTranspose matrix2) ) ; Calculate matrix2 transpose to prevent recalculation in future
    (map 
        (lambda (row) ; Step1. Iterate through matrix1 rows
            (map
                (lambda (column) ; Step3. Iterate through matrix2 columns
                    (apply + (map * row column)) ; Step4. Multiply rows and columns by peer to peer and add them
                    ; Example: 
                    ; If row be (1 2) and column be (5 7) then:
                    ; Map part does: ((1 * 5) (2 * 7)) -> (5 14)
                    ; Apply part does: 5 + 14 -> 19
                )
                matrix2Transpose ; Step2. Use matrix2 transpose to get columns for every iteration
            )
        )
        matrix1
    )
)

(define (matrixTranspose matrix)
    (apply map (lambda _ _) matrix)
)

(display 
    (matrixMultiply '((1 2) (3 4)) '((5 6) (7 8)) )
)
在这段代码中,
是矩阵a的列表,但我不明白
是如何更新的

这部分代码:
(apply+(map*行-列))
是向量
和向量

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

我不明白它是怎么工作的

谢谢。

啊,旧的
(应用map foo\u a\u list)
技巧。非常聪明

实际上
(应用映射(cons列表A))
(应用映射列表A)
相同。这就是
apply
的工作定义

尝试一些具体的例子通常有助于“获得成功”:

这样最后一个参数的元素,
”((1 2 3)(10 20 30))
被拼接到整个
应用映射…
表单中

矩阵变换(列表列表,真的)

你有吗

(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_列…
,没有括号。在
((λ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
作为其参数处理这些行时,lambda函数将相应地一致地应用于每一行的后续数字;从而实现与显式转置相同的效果。但现在增加的好处是,我们不需要转置将结果放回正确的形式,就像我们在第一个版本中所做的那样

这很聪明,也很好


因此,有了这些理解,让我们试着重新阅读原始代码,看看我们是否也能看到它的本来面目

(define (matrix-multiply matrix1 matrix2)
  (map
   (λ (row)
     (apply map
       (λ column      ;; <<------ no parens!
         (apply + (map * row column)))
       matrix2))
   matrix1))
(定义(矩阵乘矩阵x1矩阵x2)
(地图
(λ(世界其他地区)
(应用地图)

(λcolumn;;如果您更喜欢使用while循环(对于初学者来说可能更容易),我建议将问题分成7个主要帮助函数(以及一些其他简单函数):

这不是最有效的方法(到目前为止),但很容易理解

  • getRow mat i:获取矩阵mat的第i行(列表列表)

    (定义(getRow mat i)
    (一)
    
    (定义(元素列表n)
    (如果(=n0)
    (车辆清单)
    (第n个元素(cdr列表)(-n1)))
    
  • getCol mat i:获取矩阵mat的第i列(列表列表)

    (定义(getCol mat i)
    (定义col(列表))
    (定义第0行)
    (而(<行(长度垫))
    (设置!列(附加列(列表(第一行数值)))
    (设置!第行(+第1行)))
    上校)
    
    (定义(值材料i)
    (第n个元件(第n个元件材料i)j))
    
  • listmultlist1 list2:对两个列表执行元素相乘

    (定义(listmultlist1 list2)
    (如果(不是(空?列表1))
    (cons(*(车辆列表1)(车辆列表2))(车辆列表MULT(cdr列表1)(cdr列表2)))
    空)
    
  • sum aList:计算列表中所有元素的总和

    (定义(总和列表)
    (如果为空,则为空)
    0
    (+(car-aList)(sum(cdr-aList‘‘‘)’))
    
  • 长度列表:查找列表的长度

    (定义(长度列表)
    (如果(空?列表)
    0
    (+1(长度(cdr列表()())))
    
  • 新建矩阵m n val:创建一个填充val的m×n矩阵

    (定义(newMatrix m n val)
    (定义i0)
    (定义行(列表值))
    (定义mat(列表))
    (如果(=n0)
    (名单)
    (开始
    (while(
  • setValueAtIJ mat i val:在mat中的位置i、j处设置值val(基于0)

    (定义(setValueAtIJ mat i val)
    (set!mat(setNthElementFinal mat i(setNthElementFinal(nthElement mat i)j val)))
    垫)
    
  • 这些都可以组合起来创建矩阵乘法函数

    (定义(矩阵结果mat1 mat2)
    (定义mat1Dim(列表(长度mat1)(长度(元素mat1 0)))
    (定义mat2Dim(列表(长度mat2)(长度(元素mat2 0)))
    (定义i0)
    (定义j 0)
    (定义新矩阵(新矩阵(car mat1Dim)(car(cdr mat2Dim))0))
    (如果(不是(=(车辆(cdr mat1Dim))(车辆mat2Dim)))
    无效的
    (开始
    (while(
    此解决方案可能不是编写它的最佳方式,但很容易理解:

    (define (matrix-multiply matrix1 matrix2)
      (map
       (λ (row)
         (apply map
           (λ column
             (apply + (map * row column)))
           matrix2))
       matrix1))
    
    (define (matrixMultiply matrix1 matrix2)
        (define matrix2Transpose (matrixTranspose matrix2) ) ; Calculate matrix2 transpose to prevent recalculation in future
        (map 
            (lambda (row) ; Step1. Iterate through matrix1 rows
                (map
                    (lambda (column) ; Step3. Iterate through matrix2 columns
                        (apply + (map * row column)) ; Step4. Multiply rows and columns by peer to peer and add them
                        ; Example: 
                        ; If row be (1 2) and column be (5 7) then:
                        ; Map part does: ((1 * 5) (2 * 7)) -> (5 14)
                        ; Apply part does: 5 + 14 -> 19
                    )
                    matrix2Transpose ; Step2. Use matrix2 transpose to get columns for every iteration
                )
            )
            matrix1
        )
    )
    
    (define (matrixTranspose matrix)
        (apply map (lambda _ _) matrix)
    )
    
    (display 
        (matrixMultiply '((1 2) (3 4)) '((5 6) (7 8)) )
    )
    
    输出: