使用 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 插件问题