如何在Excel VBA中调用Rblas.dll的dgemm函数及结果异常问题
VBA调用Rblas.dll的dgemm函数异常修复方案
核心错误点
- 整数类型不匹配:VBA的
Integer是16位整数,而BLAS接口要求的是32位整数,对应VBA的Long类型,所有整形参数传递错误导致dgemm执行逻辑异常。 - 隐式Variant类型:VBA中逗号分隔声明变量时,只有最后一个变量会被指定为标注的类型,其余默认是Variant,
alpha、m等变量实际类型与BLAS要求的Double/32位整数不匹配。 - 矩阵存储顺序适配:BLAS基于Fortran编写,采用列优先存储,VBA二维数组同样是列优先存储,若按日常行优先逻辑赋值矩阵,需要调整
transa/transb参数为转置状态,否则计算的是原矩阵转置后的乘积。
修改后的完整代码
Declare PtrSafe Sub dgemm_ Lib "C:\Program Files\R\R-4.0.2\bin\x64\Rblas.dll" _ (ByVal transa As String, _ ByVal transb As String, _ ByRef m As Long, _ ByRef n As Long, _ ByRef k As Long, _ ByRef alpha As Double, _ ByRef a As Double, _ ByRef lda As Long, _ ByRef b As Double, _ ByRef ldb As Long, _ ByRef beta As Double, _ ByRef c As Double, _ ByRef ldc As Long) Sub test_dgemm() Dim alpha As Double, beta As Double Dim a(0 To 1, 0 To 1) As Double, b(0 To 1, 0 To 1) As Double, c(0 To 1, 0 To 1) As Double Dim m As Long, n As Long, k As Long, lda As Long, ldb As Long, ldc As Long Dim transa As String, transb As String a(0, 0) = 1 a(0, 1) = 2 a(1, 0) = 3 a(1, 1) = 4 b(0, 0) = 1 b(0, 1) = 2 b(1, 0) = 3 b(1, 1) = 4 c(0, 0) = 1 c(0, 1) = 2 c(1, 0) = 3 c(1, 1) = 4 m = 2 n = 2 k = 2 lda = 2 ldb = 2 ldc = 2 alpha = 1 beta = 0 ' 若要按行优先逻辑计算原矩阵乘积,将transa、transb设为"T"即可 transa = "N" transb = "N" Call dgemm_(transa, transb, m, n, k, alpha, a(0, 0), lda, b(0, 0), ldb, beta, c(0, 0), ldc) End Sub
补充说明
修改后运行代码,若保留transa="N"、transb="N",得到的是列优先存储下的矩阵乘积结果,若要得到你预期的13 16 29 36,调整矩阵赋值内容或者trans参数即可。
内容的提问来源于stack exchange,提问作者Actuary David
相关产品推荐
相关产品推荐

