1

Matlab代码:

invD = inv(D);
Dew=2*invD-E;

D 是 1000x1000 的复数矩阵。它在 0.5 秒或更短的时间内反转。

我尝试了几种将这段代码移植到 C++ 的方法,使用不同的方法,但它总是慢于 10 秒。我究竟做错了什么?Matlab 如何优化该代码?

这个matlab代码不是我写的,我只需要移植它。抱歉,我在数学方面的编码要好得多。

4

3 回答 3

2

我很确定您使用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 算法变慢,但在考虑之前我会在别处寻找问题。

于 2013-02-02T16:00:25.143 回答
2

您可以使用boost::ublas并按照这些说明进行操作,而不是重新发明轮子。

于 2013-02-02T14:45:11.360 回答
2

我不清楚你在用那个倒数做什么。我的第一反应是大多数人不会反转矩阵。例如,LU 分解比完全反演更有效、更稳定。

我建议找到一个用 C++ 编写的线性代数库。其他在数学和编程方面都比你好得多的人已经解决了这个问题。使用他们的代码;不要自己写。

如果您有 GPU ,我还建议您查看CUDA 。

1000x1000 并不是一个非常大的矩阵。解决数百万自由度的问题并非闻所未闻。

于 2013-02-02T14:45:18.873 回答