excel 矩阵乘法使用

7vhp5slm  于 2023-10-22  发布在  其他
关注(0)|答案(3)|浏览(135)

我正在尝试用一个2x3矩阵和一个3x2矩阵相乘。但是,我没有得到预期的输出。例如,我得到的两个矩阵和输出是:input matrices and the output I get.


这是错误的输出,但我不明白如何修复它以获得正确的输出。如果你能帮忙的话,我将不胜感激。

Sub MatrixMult2()

Dim inp1(1, 2) As Integer
Dim inp2(2, 1) As Integer

Dim out(1, 1) As Integer

For j = 0 To 1
For i = 0 To 1

    inp1(i, j) = Range("A28").Cells(i + 1, j + 2)
    inp2(i, j) = Range("E28").Cells(i + 2, j + 1)

Next i
Next j

Dim temp As Integer

For a = 0 To 1
    For b = 0 To 1
        For c = 0 To 2

            temp = temp + inp1(a, c) * inp2(c, b)

        Next c
        out(a, b) = temp
        temp = 0
    Next b
Next a

For j = 0 To 1
For i = 0 To 1
Range("H28").Cells(i + 1, j + 1) = out(i, j)
Next i
Next j

End Sub
v64noz0r

v64noz0r1#

黑客帝国The Matrix
由于我对矩阵的了解仅限于第一幅图中的三句话,因此请谨慎使用其中的任何一句。
Matrix Multiplication (Wikipedia)

Excel - MMULT

表1

对于左边的示例,将以下公式复制到单元格H2中:

=MMULT(A2:C3,E2:F4)

现在选择单元格H2,并将范围扩展到I3,选择范围H2:I3,并激活单元格H2(其颜色为white,而其他单元格为gray)。单击编辑栏并使用CTRL+ ENTER +ENTER确认。当您查看公式栏时,四个单元格中的每一个(视觉上)都具有相同的公式:

{=MMULT(A2:C3,E2:F4)}

其中大括号({})仅表示这是一个数组公式。大括号已自动添加,请勿尝试手动添加。
对于右边的示例,将以下公式复制到单元格R7中:

=MMULT(N2:P5,R2:V4)

现在选择单元格R7并将范围扩展到V10,使范围R7:V10被选中,单元格R7处于活动状态(其颜色为white,而其他单元格为gray)。单击编辑栏并使用CTRL+ ENTER +ENTER确认。当您查看公式栏时,二十个单元格中的每一个(视觉上)都具有相同的公式:

{=MMULT(N2:P5,R2:V4)}

其中大括号({})仅表示这是一个数组公式。大括号已自动添加,请勿尝试手动添加。

表2

根据你的代码,你可以在单元格H28中使用以下公式:

=MMULT(A28:C29,E28:F30)

现在选择单元格H28并将范围扩展到I29,使范围H28:I29被选中,单元格H28处于活动状态(其颜色为white,而其他单元格为gray)。单击编辑栏并使用CTRL+ ENTER +ENTER确认。当您查看公式栏时,四个单元格中的每一个(视觉上)都具有相同的公式:

{=MMULT(A28:C29,E28:F30)}

其中大括号({})仅表示这是一个数组公式。大括号已自动添加,请勿尝试手动添加。

安装

调整你认为合适的常量。

Option Explicit

' The Sub Solutions

' Sub Version (No Functions Used)
Sub writeMatrixProductSub()

    Const Sheet As String = "Sheet2"
    Const rngM1 As String = "A28:C29"
    Const rngM2 As String = "E28:F30"
    Const celMP As String = "H28"

    Dim M1, M2, MP, Row1 As Long, Col1Row2 As Long, Col2 As Long, Curr As Double

    ' Read from worksheet and write to arrays.
    With ThisWorkbook.Worksheets(Sheet)
        M1 = .Range(rngM1)
        M2 = .Range(rngM2)
    End With

    ' Calculate in arrays.
    If UBound(M1, 2) <> UBound(M2) Then Exit Sub
    ReDim MP(1 To UBound(M1), 1 To UBound(M2, 2))
    For Col2 = 1 To UBound(M2, 2)
        For Row1 = 1 To UBound(M1)
            For Col1Row2 = 1 To UBound(M1, 2)
                Curr = Curr + M1(Row1, Col1Row2) * M2(Col1Row2, Col2)
            Next Col1Row2
            MP(Row1, Col2) = Curr: Curr = 0
        Next Row1
    Next Col2

    ' Check values of Matrix Product in Immediate window.
'    For Row1 = 1 To UBound(MP)
'        For Col1Row2 = 1 To UBound(MP, 2)
'            Debug.Print MP(Row1, Col1Row2)
'        Next
'    Next

    ' Write to worksheet.
    With ThisWorkbook.Worksheets(Sheet)
        .Range(celMP).Resize(UBound(MP), UBound(MP, 2)) = MP
    End With

End Sub

' Sub Version Using "WorksheetFunction.MMult" with qualified worksheet
Sub writeMatrixProductMMultSubQualify()
    Const Sheet As String = "Sheet2"
    Const rngM1 As String = "A28:C29"
    Const rngM2 As String = "E28:F30"
    Const celMP As String = "H28"
    Dim M1, M2, MP
    With ThisWorkbook.Worksheets(Sheet)
        M1 = .Range(rngM1)
        M2 = .Range(rngM2)
        If UBound(M1, 2) <> UBound(M2) Then Exit Sub
        ReDim MP(1 To UBound(M1), 1 To UBound(M2, 2))
        MP = WorksheetFunction.MMult(M1, M2)
        .Range(celMP).Resize(UBound(MP), UBound(MP, 2)) = MP
    End With
End Sub

' Sub Version Using "WorksheetFunction.MMult"
Sub writeMatrixProductMMultSub()
    Const rngM1 As String = "A28:C29"
    Const rngM2 As String = "E28:F30"
    Const celMP As String = "H28"
    Dim M1, M2, MP
    M1 = Range(rngM1)
    M2 = Range(rngM2)
    If UBound(M1, 2) <> UBound(M2) Then Exit Sub
    ReDim MP(1 To UBound(M1), 1 To UBound(M2, 2))
    MP = WorksheetFunction.MMult(M1, M2)
    Range(celMP).Resize(UBound(MP), UBound(MP, 2)) = MP
End Sub

' The Function Solutions

'  Sub Using "writeMatrixProduct" and "getMatrixProduct1"
Sub testMatrixProductSimple()
    Const rngM1 As String = "A28:C29"
    Const rngM2 As String = "E28:F30"
    Const celMP As String = "H28"
    writeMatrixProduct Range(rngM1), Range(rngM2), Range(celMP)
End Sub

'  Sub Using "writeMatrixProduct" and "getMatrixProduct1" with Checking
Sub testMatrixProductCheck()
    Const rngM1 As String = "A28:C29"
    Const rngM2 As String = "E28:F30"
    Const celMP As String = "H28"
    Dim Success As Boolean
    Success = writeMatrixProduct(Range(rngM1), Range(rngM2), Range(celMP))
    If Success Then
        MsgBox "Write was successful.", vbInformation
    Else
        MsgBox "Write was unsuccessful. Nothing written.", vbExclamation
    End If
End Sub

' The Functions

' Remarks:      2D 1-based is convenient for operating in ranges.

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Using the "getMatrixProduct1" function, writes the matrix      '
'               product of two matrices contained in ranges to another range.  '
' Returns:      A boolean indicating if the operation was successful.          '
' Remarks:      The resulting range is specified only by its first cell.       '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function writeMatrixProduct(Matrix1 As Range, Matrix2 As Range, _
  MatrixProductFirstCell As Range) As Boolean
    Dim M1, M2, MP
    On Error GoTo handleError
    M1 = Matrix1: M2 = Matrix2
    MP = getMatrixProduct1(M1, M2)
    If Not IsArray(MP) Then Exit Function
    MatrixProductFirstCell.Resize(UBound(MP), UBound(MP, 2)) = MP
    writeMatrixProduct = True
exitProcedure:
Exit Function
handleError:
    Debug.Print "Run-time error '" & Err.Number & "': " & Err.Description
    Resume exitProcedure
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Returns a 2D 1-based array containing the matrix product       '
'               of two matrices contained in 2D 1-based arrays.                '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function getMatrixProduct1(Matrix1 As Variant, Matrix2 As Variant) As Variant
    If UBound(Matrix1, 2) <> UBound(Matrix2) Then Exit Function
    Dim MP, Row1 As Long, Col1Row2 As Long, Col2 As Long, Curr As Double
    ReDim MP(1 To UBound(Matrix1), 1 To UBound(Matrix2, 2))
    For Col2 = 1 To UBound(Matrix2, 2)
        For Row1 = 1 To UBound(Matrix1)
            For Col1Row2 = 1 To UBound(Matrix1, 2)
                Curr = Curr + Matrix1(Row1, Col1Row2) * Matrix2(Col1Row2, Col2)
            Next Col1Row2
            MP(Row1, Col2) = Curr: Curr = 0
        Next Row1
    Next Col2
    getMatrixProduct1 = MP
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Returns a 2D 1-based array containing the matrix product       '
'               of two matrices contained in 2D 1-based arrays.                '
' Remarks:      While testing it turned out to be over 10 times slower than    '
'               the "getMatrixProduct1" function (needs to be verified).       '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function getMatrixProduct1M(Matrix1 As Variant, Matrix2 As Variant) As Variant
    If UBound(Matrix1, 2) <> UBound(Matrix2) Then Exit Function
    Dim MP: ReDim MP(1 To UBound(Matrix1), 1 To UBound(Matrix2, 2))
    MP = WorksheetFunction.MMult(Matrix1, Matrix2): getMatrixProduct1M = MP
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
gopyfrb3

gopyfrb32#

Sub MatrixMult2()
    Dim inp1(1, 2) As Integer
    Dim inp2(2, 1) As Integer
    Dim out(1, 1) As Integer
    Dim temp As Integer
    Dim i As Integer, j As Integer, a As Integer, b As Integer, c As Integer

    ' Initialize temp to 0
    temp = 0

    ' Populate inp1 and inp2 matrices
    For j = 0 To 2
        For i = 0 To 1
            inp1(i, j) = Range("A28").Cells(i + 1, j + 2).Value
            inp2(j, i) = Range("E28").Cells(j + 2, i + 1).Value
        Next i
    Next j

    ' Perform matrix multiplication
    For a = 0 To 1
        For b = 0 To 1
            For c = 0 To 2
                temp = temp + inp1(a, c) * inp2(c, b)
            Next c
            out(a, b) = temp
            temp = 0
        Next b
    Next a

    ' Write the result to Range("H28")
    For j = 0 To 1
        For i = 0 To 1
            Range("H28").Cells(i + 1, j + 1).Value = out(i, j)
        Next i
    Next j
End Sub
okxuctiv

okxuctiv3#

在矩阵乘法中,2x3矩阵乘以3x2矩阵将返回2x2矩阵。
通常,对于两个矩阵(A x B),矩阵乘以(B x C)返回(A x C),其中矩阵1中的列数(值B)必须等于矩阵2中的行数。

相关问题