我想用特征将矩阵的一部分复制到矩阵本身的另一部分。为了只在真正需要的时候才能使用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);其结果类似于:

结论
总括而言:
考虑到“有序复制”假设,
,我总是期望混叠。
这些结论正确吗?“有序复制”的假设是否正确?我认为向量化实际上可以使这个假设失效..。
发布于 2020-01-17 13:02:13
对于第1点,你是正确的。如果块不重叠,你就不会有别名问题。
但是,对于2和3,您可能有或可能没有混叠问题,这取决于本征版本、目标体系结构和编译器--本质上这些操作的结果是未定义的。也就是说,你不应该依赖于当前的行为。
如果您希望有一些显式行为(不使用临时程序),则可以手动遍历矩阵中不重叠的块。而不是
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
https://stackoverflow.com/questions/59773986
复制相似问题