两个矩阵的C ++高效按元素匹配

问题描述

我正在使用C ++和Eigen库来完成匹配任务。但是,结果效率很低。下面将描述任务和我当前的解决方案。

任务

该任务涉及两个大小相同的大地图mapLmapR。匹配过程按行进行。例如,r-th的{​​{1}}行中的元素将与mapL的{​​{1}}行中的元素匹配。两个匹配元素的值可能不完全相同,因此我需要在r-th中寻找差异最小的元素。

要计算差异,请执行以下步骤:

  1. 提取mapR的{​​{1}}行中的元素。
  2. 提取mapR的{​​{1}}行。
  3. r-th的元素减去mapL的行。
  4. r-th中的每个元素重复上述步骤。

示例

一个示例将有助于理解上述过程。假设我们有

mapR

对于mapR中的第一个元素,我想获得向量mapL用于后续的计算

mapL

当前解决方

在构建C ++代码时,我尝试使用mapL = [ 1 2 3 4,5; 6 7 8 9 10; 11 12 13 14 15]; mapR = [ 5 4 3 2,1; 10 9 8 7 6; 15 14 13 12 11]; mapL对过程进行矢量化处理。下面显示了示例代码

difference

问题

上面的代码在我的机器上(VS 2017,发布模式,x64)大约需要61s来遍历每一行。我已经在MATLAB中实现了类似的代码,仅需6秒钟。有什么方法可以提高C ++代码的效率吗?我刚接触C ++,因此,如果我错过任何重要的概念,请告诉我。非常感谢!

编辑

经过更多测试,我发现了一种更有效的方法来完成任务。对我的原始代码进行性能分析表明,difference = [5 4 3 2 1] - [1] = [4 3 2 1 0]; .replicate操作消耗了大量的计算能力(〜90%)。使用嵌套循环需要不到3s的时间才能完成相同的任务。新代码如下:

.colwise

解决方法

两个建议:

  • 默认情况下,Eigen按列优先顺序存储矩阵。通过定义

    ,使用行优先顺序可能会有所帮助
    using RowMajorMatrixXf = Matrix<float,Dynamic,RowMajor>;
    

    并使用它而不是MatrixXf来使行在内存中是连续的。

  • .row(r)方法返回一个表达式对象,该对象本身并不复制内存。但是将其分配给VectorXf或ArrayXf会创建一个副本。您可以按住decltype(mapL)::RowXpr rowL = mapL.row(r)之类的表达式对象来消除副本。