当从Eigen :: Matrix复制一个块到同一矩阵的另一个块时,会出现什么混叠问题?

问题描述 投票:0回答:1

我想使用特征值将矩阵的一部分复制到矩阵本身的另一部分中。我想确保从别名方面理解后果,以便仅在确实需要时才使用eval()

说我有以下内容:

MatrixXd M(4,4);
M << 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16;
M.block( some indices ) = M.block( some other indices )

我认为应该考虑3种情况:

情况1:块不重叠

这根本不是问题。一个例子是:

M.topLeftCorner(2,2) = M.bottomRightCorner(2,2);

给予我们:“链接到图像”

情况2:方块重叠;目标块中的第一个位置位于源块中的第一个位置之前

一个例子是:

M.topLeftCorner(2,2) = M.block(1,0,2,2);

在这种情况下,我希望这样的事情发生:“链接到图像”

我相信这不会是别名的示例。但是,要获得这种行为,就需要保证从左上角开始依次在两个块中逐行进行依次复制元素。

情况3:方块重叠;目标块中的第一个位置在源头中的第一个之后]

[在这里,我期望混叠。一个例子是:

M.block(1,0,2,2) = M.topLeftCorner(2,2);

类似于结果:”链接到图像“

结论

总结:

  1. 在第一种情况下,我会not期望出现别名
  2. 考虑到“有序副本”的假设,在第二种情况下我不会假设出现混叠
  3. 我会[[总是在第三种情况下会出现别名
这些结论正确吗? “有序副本”的假设是否正确?我认为矢量化实际上可以使这个假设无效...
eigen3
1个回答
0
投票
您对点1是正确的。如果块不重叠,则不会出现混叠问题。

但是,对于2.和3.,您可能会或可能不会出现混叠问题,具体取决于Eigen版本,目标体系结构和编译器-本质上这些操作的结果是不确定的。也就是说,您不应该依赖当前的行为。

[如果要具有某些明确的行为(不使用临时对象),则可以手动循环遍历矩阵的非重叠块。代替

M.topLeftCorner(2,2) = M.block(1,0,2,2);

您可以这样写:

for(int c=0; c<2; ++c) M.block(0,c,2,1) = M.block(0,c+1,2,1);

或者更好的是,重新考虑整体算法,以避免在矩阵内部复制重叠的块。

有关别名的更多详细信息,请参见此页面:http://eigen.tuxfamily.org/dox-devel/group__TopicAliasing.html

© www.soinside.com 2019 - 2024. All rights reserved.