eigen3 - 将一个块从 Eigen::Matrix 复制到同一矩阵的另一个块时,会出现什么混叠问题?
问题描述
我想使用 Eigen 将矩阵的一部分复制到矩阵本身的另一部分。我想确保了解别名的后果,以便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 点是正确的。如果块不重叠,则不会出现混叠问题。
但是,对于 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
推荐阅读
- r - R 未能圆 126.5
- python - 如何从 shtml 链接集合中抓取或下载 pdf?
- css - 背景位置未固定在页面上
- angular - 空警报控制器输入 - 离子
- string - 如何同时接受 Vec
和 Vec 作为 Rust 中的函数 arg - java - 将两个 @GetMapping 映射到同一个 @RestController 到 Spring Boot
- scala - Sbt - 指定依赖扩展
- msbuild - 如何使用道具文件(NuGet)从 csproj 中排除文件
- r - 在 Shiny 中获得正确的圈数
- node.js - 如何在 ANTLR 中正确编写具有后视功能的规则