Eigen C ++中的逐列点积

时间:2014-11-20 02:11:02

标签: c++ linear-algebra eigen

是否有一种简单的方法可以评估2个矩阵的列式点积(我们称之为AB,类型为Eigen::MatrixXd),其维度为mxn ,不评估A*B或不必诉诸for循环?生成的向量需要具有1xnnx1的维度。另外,我正在尝试用C ++中的Eigen做到这一点

3 个答案:

答案 0 :(得分:9)

有很多方法可以实现这一点,所有方法都执行延迟评估:

res = (A.array() * B.array()).colwise().sum();
res = (A.cwiseProduct(B)).colwise().sum();

我的最爱:

res = (A.transpose() * B).diagonal();

答案 1 :(得分:0)

以下是我使用Eigen::Map的方法(假设真实矩阵,可以通过调整伴随扩展到复数),其中rowscols表示数字行/列:

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

int main()
{
    Eigen::MatrixXd A(2, 2);
    Eigen::MatrixXd B(2, 2);
    A << 1, 2, 3, 4;
    B << 5, 6, 7, 8;

    int rows = 2, cols = 2;

    Eigen::VectorXd vA = Eigen::Map<Eigen::VectorXd>(
                             const_cast<double *>(A.data()), rows * cols, 1);
    Eigen::VectorXd vB = Eigen::Map<Eigen::VectorXd>(
                             const_cast<double *>(B.data()), rows * cols, 1);

    double inner_prod = (vA.transpose() * vB).sum();

    std::cout << inner_prod << std::endl;
}

答案 2 :(得分:0)

我根据@ggael的答案进行了实验。

MatrixXd A = MatrixXd::Random(600000,30);
MatrixXd B = MatrixXd::Random(600000,30);

MatrixXd res;
clock_t start, end;
start = clock();
res.noalias() = (A * B.transpose()).diagonal();
end = clock();
cout << "Dur 1 : " << (end - start) / (double)CLOCKS_PER_SEC << endl;

MatrixXd res2;
start = clock();
res2 = (A.array() * B.array()).rowwise().sum();
end = clock();
cout << "Dur 2 : " << (end - start) / (double)CLOCKS_PER_SEC << endl;

MatrixXd res3;
start = clock();
res3 = (A.cwiseProduct(B)).rowwise().sum();
end = clock();
cout << "Dur 3 : " << (end - start) / (double)CLOCKS_PER_SEC << endl;

输出为:

Dur 1 : 10.442
Dur 2 : 8.415
Dur 3 : 7.576

似乎对角线()解决方案是最慢的解决方案。 cwiseProduct一种是最快的。 而且内存使用量是相同的。