使用本征的复数矩阵矩阵乘法

时间:2019-12-16 11:07:54

标签: c++ matrix eigen matrix-multiplication complex-numbers

我正在做复杂的矩阵矩阵乘积,如此处的代码所示。 Eigen *运算符似乎没有给出正确的结果。为了验证,我还编写了另一个例程来查找产品。由此可见,结果的虚部很好,但实际部分不准确。有人可以让我知道为什么吗?

Eigen::MatrixXcd U2 = Eigen::MatrixXcd::Random(N1, computed_rank);
Eigen::MatrixXcd V2 = Eigen::MatrixXcd::Random(computed_rank, N2);
Eigen::MatrixXcd W2 = Mat::Zero(N1,N2);
for (size_t k = 0; k < computed_rank; k++) {
    W2 += U2.col(k)*V2.row(k);
}
Eigen::MatrixXcd Q = U2*V2;
Eigen::MatrixXcd E2 = Q-W2;
cout << "Err Total: " << E2.norm()/W2.norm() << endl;
cout << "Err Real: " << E2.real().norm()/W2.real().norm() << endl;
cout << "Err Imag: " << E2.imag().norm()/W2.imag().norm() << endl;

给出结果:

Err Total: 0.84969
Err Real: 1.17859
Err Imag: 1.18274e-16

我观察到当这是项目中唯一的代码片段时,没有发生此问题。但是我将此作为一个更大的项目的一部分,该项目似乎失败了。

2 个答案:

答案 0 :(得分:2)

事实证明,GNU的-ffast-math优化标志并不与所有程序兼容。我在编译较大的项目时使用了它,而在做一个孤立的项目时没有使用它。这就是失败的原因!有关更多详细信息,请参见https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

答案 1 :(得分:1)

下面是一个最小的可复制示例:文件名是test.cpp

#include<iostream>
#include<Eigen/Dense>

using namespace std;

int main() {
    int N1 = 12;
    int N2 = 12;
    int computed_rank = 5;
    Eigen::MatrixXcd U2 = Eigen::MatrixXcd::Random(N1, computed_rank);
    Eigen::MatrixXcd V2 = Eigen::MatrixXcd::Random(computed_rank, N2);
    Eigen::MatrixXcd W2 = Eigen::MatrixXcd::Zero(N1,N2);
    for (size_t k = 0; k < computed_rank; k++) {
        W2 += U2.col(k)*V2.row(k);
    }
    Eigen::MatrixXcd Q = U2*V2;
    Eigen::MatrixXcd E2 = Q-W2;
    cout << "Err Total: " << E2.norm()/W2.norm() << endl;
    cout << "Err Real: " << E2.real().norm()/W2.real().norm() << endl;
    cout << "Err Imag: " << E2.imag().norm()/W2.imag().norm() << endl;
}

使用 -ffast-math标志编译上面的会产生以下输出。

g++-9 -O4 -ffast-math test.cpp

./a.out

Err Total: 0.949251
Err Real: 1.41443
Err Imag: 1.35749e-16

不使用上面的 -ffast-math标志进行编译将产生以下输出。

g++-9 -O4 test.cpp

./a.out

Err Total: 1.35029e-16
Err Real: 1.35181e-16
Err Imag: 1.34903e-16