使用 VBA 和 C++ DLL 的伪逆计算

Posted

技术标签:

【中文标题】使用 VBA 和 C++ DLL 的伪逆计算【英文标题】:Pseudoinverse computation using VBA and C++ DLL 【发布时间】:2016-11-17 19:57:50 【问题描述】:

我想在 Excel 中使用 VBA 对一个大的退化矩阵进行伪逆(类似于广为人知的“pinv”函数)。据我了解,excel 工具无法处理退化矩阵。

我发现没有什么比尝试实现 C++ DLL 库并链接到 VBA 更好的了。我遇到了以下问题:

我的配置是:Windows 10 x64,Office 16 x64。我使用 VS 2015 创建 DLL 作为 x64 DLL。我已经设法创建和链接简单的 DLL,甚至传递到双数组并从中获取。但是当涉及到将诸如 Armadillo 之类的数学库与动态链接的 BLAS 一起使用时,就出现了混乱。

任何使用 BLAS x64 DLL 的工作和调试代码,以防被包装为 DLL 并从 VBA 调用会使 Excel 崩溃。我已经检查了依赖项并将 BLAS/LAPACK dll 放入几乎每个合适的文件夹中。即使我不使用任何传递的参数,它也会崩溃。 Proc Monitor 显示依赖关系正常。看起来当 Excel 从 DLL 调用某些函数时会阻止来自该 DLL 的外部调用。

【问题讨论】:

【参考方案1】:

可能有点晚了,不完全符合您的要求,但我刚刚完成了一个 VBA 子程序,它计算矩阵的 Moore-Penrose 伪逆矩阵,它可能仍然对您有帮助。它遵循与 MATLAB 的“pinv”函数类似的过程并产生可比较的结果。您可以从下面的链接中获取代码。 VBA 和 MATLAB 函数的结果也汇总在一个表格中。

http://www.nicksfinancetricks.com/index.php/2017/01/08/moore-penrose-pseudoinverse-calculation/

该算法包含三个主要组成部分,包括通过 Gram-Schmidt 正交化进行的 QR 分解、奇异值分解 (SVD),以及最后去除任何奇异值以便可以制定伪逆。

【讨论】:

【参考方案2】:

我建议将任何所需的 dll 放在 .xlsb(或 .xlsm)文件的同一文件夹中,并使用以下代码进行 auto_open:

Sub auto_open()
    With ThisWorkbook
        ChDrive .Path
        ChDir .Path
    End With
    ....
End Sub

这会使当前文件夹成为第一个要搜索的名为 dll 的文件夹。

作为另一个建议,我认为您可能会使用 openblas,这是一个优化的 blas,其中还包括 lapack,并优化了一些 lapack 例程。您可能会发现已编译为“OpenBLAS-v0.2.14-Win64-int32”的版本,其中包括预编译的 dll libopenblas,以及所需的 dll libcc_s_seh、libgfortran 和 libquadmath。没有预先确定的伪逆。但是你可以看看http://mathforum.org/kb/message.jspa?messageID=1606150,它告诉你如何实现它,甚至可以在vba中实现。

【讨论】:

以上是关于使用 VBA 和 C++ DLL 的伪逆计算的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 2019 C++ dll Excel VBA 插件问题

c++ / g++ - 错误:未知的伪操作:`。位置'

尝试调试调用 C++ DLL 的 VBA,“未加载 wntdll.pdb”

使用指针调用 C++ DLL 函数

Excel 不会从 C++ DLL 加载函数

在其他计算机 C++ 中运行包含 MFC 类的 Dll