Matlab代码:
invD = inv(D);
Dew=2*invD-E;
D 是 1000x1000 的复数矩阵。它在 0.5 秒或更短的时间内反转。
我尝试了几种将这段代码移植到 C++ 的方法,使用不同的方法,但它总是慢于 10 秒。我究竟做错了什么?Matlab 如何优化该代码?
这个matlab代码不是我写的,我只需要移植它。抱歉,我在数学方面的编码要好得多。
我很确定您使用Eigen
不正确。我尝试使用八度音阶(MATLAB 的免费替代品,可能稍微不那么优化)和以下特征码反转随机 1000x1000 矩阵。Octave 大约需要 1 秒,Eigen 大约需要 1.5 秒(我正在使用boost::timer
而不是您的计时解决方案,但这只是因为它不那么麻烦):
#include <iostream>
#include <Eigen/Dense>
#include <boost/timer/timer.hpp>
using Eigen::MatrixXcd;
int main() {
MatrixXcd m,mi;
{
boost::timer::auto_cpu_timer t;
m = MatrixXcd::Random(1000,1000);
}
{
boost::timer::auto_cpu_timer t;
mi = m.inverse();
}
std::cout << mi(4,4) << std::endl;
}
我能想到的第一个可能的罪魁祸首是编译器选项。-O2
您是否至少编译了您的 C++ 代码?
您的矩阵仍有可能具有特殊结构,因此在您的特定情况下,数值考虑会使 Eigen 算法变慢,但在考虑之前我会在别处寻找问题。
您可以使用boost::ublas并按照这些说明进行操作,而不是重新发明轮子。
我不清楚你在用那个倒数做什么。我的第一反应是大多数人不会反转矩阵。例如,LU 分解比完全反演更有效、更稳定。
我建议找到一个用 C++ 编写的线性代数库。其他在数学和编程方面都比你好得多的人已经解决了这个问题。使用他们的代码;不要自己写。
如果您有 GPU ,我还建议您查看CUDA 。
1000x1000 并不是一个非常大的矩阵。解决数百万自由度的问题并非闻所未闻。