C++ 本征C++;

C++ 本征C++;,c++,linear-algebra,eigen,C++,Linear Algebra,Eigen,有没有一种简单的方法可以计算两个矩阵的逐列点积(我们称它们为A和B,类型为Eigen::MatrixXd),它们的维数mxn,而无需计算A*B,也无需求助于循环?结果向量需要具有1xn或nx1的维度。另外,我正在尝试用C++中的Egenen实现这一点。下面是我如何使用Egenen::Map(假设实矩阵,可以通过使用伴随来扩展到复数),其中行和cols表示行数/列数: #include <Eigen/Dense> #include <iostream> int main(

有没有一种简单的方法可以计算两个矩阵的逐列点积(我们称它们为
A
B
,类型为
Eigen::MatrixXd
),它们的维数
mxn
,而无需计算
A*B
,也无需求助于
循环?结果向量需要具有
1xn
nx1
的维度。另外,我正在尝试用C++中的Egenen实现这一点。

下面是我如何使用
Egenen::Map
(假设实矩阵,可以通过使用伴随来扩展到复数),其中
cols
表示行数/列数:

#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;
}
#包括
#包括
int main()
{
本征矩阵A(2,2);
本征::矩阵xDb(2,2);

A实现这一点的方法有很多,都是通过惰性评估:

res = (A.array() * B.array()).colwise().sum();
res = (A.cwiseProduct(B)).colwise().sum();
我最喜欢的是:

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

我是根据@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;
似乎对角线()解是最慢的,cwiseProduct解是最快的。
内存使用量是一样的。

元素相乘,然后求和?在MATLAB中,它将是
sum(A.*B)
。Eigen提供了这些操作,但我不知道调用的确切名称。很好!应该可以。谢谢!可以使用“Eigen::Map”若要将矩阵重塑为向量,则取其内积。@Zedd:如果我的评论提供了制作工作代码所需的提示,请回答您自己的问题,告诉未来的访问者如何使用特征函数。现在我看到您想要一个向量作为结果?也就是说,您是在\vect{result}之后,其中每个组件都是一个(I,)*B(:,i)’?是的,没错。我不确定这将如何转化为您上面的代码。一个奇怪的问题:通过在点积运算后附加对角线,Eigen是否只计算(A的第i行)点积(B的第i列)内部,以避免不必要的计算?对于这三个实现,哪一个更快?(因为第一个和第二个将避免不必要的计算)。如答案中所述,它们
都执行延迟求值
,因此最后一个只计算对角线项。它们生成的代码大致相同。您可以在编译器资源管理器上进行检查。@ggael,请随意评论。我执行了一个非常类似的测试,但使用了16x3单精度矩阵,并执行了每项操作使用
clang++-O3
我有175129131毫秒的时间,这与你的结果相似。
Dur 1 : 10.442
Dur 2 : 8.415
Dur 3 : 7.576