来自密集向量的 c++ 特征块对角矩阵,无需复制

c++ Eigen block diagonal matrix from dense vectors without copy

本文关键字:复制 向量 特征 c++      更新时间:2023-10-16

我有(密集和大的)行向量v_1,...,v_D,并且我需要矩阵X是块对角线(其第i个块是v_i),以便执行矩阵乘积,例如

X.transpose() * H.selfadjointView<Lower>() * X  

也就是说,X 应该是稀疏的,其第 i 行v_i

(pseudo code)
RowVectorXd v1(1,2,3), v2(4,5), v3(6,7,8,9);
SparseMatrix<double> X(3,9); 
// I need X to be
X = 1 2 3 . . . . . .
    . . . 4 5 . . . .
    . . . . . 6 7 8 9 
// where . means 0

编辑:我的问题是:是否有可能在不实际形成X或复制v_i的情况下做这个产品,而只是使用对它们的引用?我关心的是性能和内存占用。

我认为该解决方案与 Eigen::Map<...跨步...>但我无法理解。

非常感谢。

我最终找到了问题的答案。我把它贴在这里,以防其他人需要它。对于矩阵 X 的这种特定配置,我们可以直接形成

B = X^T * H * X

其中 X 如问题中所示,H 对称,没有明确形成 X。由于 X^T H X 是对称的,我们只需要形成下对角线即可使用

B.selfadjointView<Lower>() 

呼叫 B。

请注意,X^T H X 等效于 H ** W,其中 W 是以下下三角矩阵,块为

W = v_1^T * v_1
    v_2^T * v_1    v_2^T * v_2
    .              .             v_3^T * v_3
    .              .             .               ...
    .              .             .               ...
    v_D^T * v_1    v_D^T * v_2   v_D^T * v_3     ...  v_D^T * v_D

和 ** 是一个重载运算符,用于计算 H 的 (i,j) 标量和 W 中的块 (i,j) 之间的分量乘积。所以

B = H ** (v^T * v)