我有一个3x3矩阵“ mat”和一个实数矢量“ vec”(3x1),我想在VBA函数中对矩阵进行乘(线性代数意义上):t(vec) mat vec产生一个我可以在方程式中使用的1x1实数。
我不想与函数中的工作表进行交互。矩阵和向量中的值可以通过函数进行硬编码或计算。应该有一种简单的转置方法,然后像在MATLAB或R中那样进行几个矩阵乘法。这是我到目前为止的位置:
Public Function QuickMaths()
Dim vec As Variant
Dim mat As Variant
mat = Array(Array(1,1+1,3), _
Array(2^2,5,6), _
Array(7,8,9))
vec = Array(2*5,11,12)
QuickMaths = Application.WorksheetFunction.MMult(Application.WorksheetFunction.MMult(Application.WorksheetFunction.Transpose(vec), mat), vec)
End Function
我在工作表中从中获得#VALUE。我希望输出为1x1矩阵,但我不知道Excel VBA是否会考虑可以将标量作为单个值输出到工作表中的标量(例如Double)。
请发送帮助。
答案 0 :(得分:1)
如果您提供了预期的输出(最后您期望的特定标量),那就太好了。
根据我从您的代码和问题中收集的信息,我将假设您正在尝试执行两个步骤。第一个是:
第二个是:
(自从我做任何矩阵乘法以来已经有一段时间了,所以如果您认为我被误解了,请告诉我。)
您的第一个数组(this.setState(locationValues: list2)
)是数组的数组(不是二维数组),我不认为mat
处理(https://support.office.com/en-us/article/mmult-function-40593ed7-a3cd-4b6b-b9a3-e4ad3c7245eb)。因此,您可能需要替换:
MMULT
具有:
mat = Array(Array(1, 1 + 1, 3), _
Array(2 ^ 2, 5, 6), _
Array(7, 8, 9))
也就是说,手动分配每个数组元素可能是不切实际的,因此也许可以为您做一个小函数(请参见下面的代码中的ReDim mat(0 To 2, 0 To 2)
mat(0, 0) = 1
mat(0, 1) = 2
mat(0, 2) = 3
mat(1, 0) = 4
mat(1, 1) = 5
mat(1, 2) = 6
mat(2, 0) = 7
mat(2, 1) = 8
mat(2, 2) = 9
函数)。
根据我最近30分钟在线阅读的内容,矩阵乘法不是可交换的,并且还要求第一个矩阵中的列数必须与第二个矩阵中的行数相匹配。 (您可能已经知道所有这些,但无论如何都只提到它。)
基于上述内容,您的代码可能类似于:
FlattenAnArrayOfArrays
结束点:
Option Explicit
Public Function QuickMaths() As Variant
' This function returns a value of type Variant.
' Could return a Long/Double/numeric type; scalar should be at QuickMaths(1,1)
' But MMULT can return non-numeric values, so you risk
' getting a type mismatch error if the matrix multiplication
' is not successful (for whatever reason).
' Maybe this shouldn't be this function's concern -- or maybe it should.
Dim mat As Variant
mat = Array(Array(1, 1 + 1, 3), _
Array(2 ^ 2, 5, 6), _
Array(7, 8, 9))
mat = FlattenAnArrayOfArrays(mat)
Dim vec As Variant
vec = Array(2 * 5, 11, 12)
Dim resultantMatrix As Variant
resultantMatrix = Application.MMult(vec, mat) ' Number of columns in "vec" must match number of rows in "mat"
resultantMatrix = Application.MMult(vec, Application.Transpose(resultantMatrix))
QuickMaths = resultantMatrix
End Function
Private Function FlattenAnArrayOfArrays(ByRef arrayOfArrays As Variant) As Variant()
' Given an array of arrays, returns a two-dimensional array.
' This function is very basic and has no error handling implemented.
Dim firstArray() As Variant
firstArray = arrayOfArrays(LBound(arrayOfArrays)) ' Columns inferred from first array in "arrayOfArrays"
Dim outputArray() As Variant
ReDim outputArray(LBound(arrayOfArrays) To UBound(arrayOfArrays), LBound(firstArray) To UBound(firstArray))
Dim rowIndex As Long
For rowIndex = LBound(outputArray, 1) To UBound(outputArray, 1)
Dim columnIndex As Long
For columnIndex = LBound(outputArray, 2) To UBound(outputArray, 2)
outputArray(rowIndex, columnIndex) = arrayOfArrays(rowIndex)(columnIndex)
Next columnIndex
Next rowIndex
FlattenAnArrayOfArrays = outputArray
End Function
函数的返回值是1x1矩阵,但是您可以将其分配给单元格的值。QuickMaths
函数,则该单元格将显示返回值(没有任何问题或不需要数组公式)。