【问题标题】:Vectorize matlab code to map nearest values in two arrays向量化 matlab 代码以映射两个数组中最接近的值
【发布时间】:2013-02-06 00:37:07
【问题描述】:

我有两个时间戳列表,我正在尝试在它们之间创建一个使用 imu_ts 作为真实时间的映射,并尝试找到最接近它的 vicon_ts 值。输出是一个 3xd 矩阵,其中第一行是 imu_ts 索引,第三行是该索引处的 unix 时间,第二行是同一列中时间戳上方最接近 vicon_ts 值的索引。

到目前为止,这是我的代码,它可以工作,但它真的很慢。我不确定如何对其进行矢量化。

function tmap = sync_times(imu_ts, vicon_ts)

tstart = max(vicon_ts(1), imu_ts(1));
tstop = min(vicon_ts(end), imu_ts(end));

%trim imu data to 
tmap(1,:) = find(imu_ts >= tstart & imu_ts <= tstop);
tmap(3,:) = imu_ts(tmap(1,:));%Use imu_ts as ground truth

%Find nearest indecies in vicon data and map
vic_t = 1;
for i = 1:size(tmap,2)
    %
    while(vicon_ts(vic_t) < tmap(3,i))
        vic_t = vic_t + 1;
    end
    tmap(2,i) = vic_t;
end

时间戳已经按升序排序,所以这本质上是一个 O(n) 操作,但因为它是循环的,所以运行缓慢。有任何矢量化方式来做同样的事情吗?

编辑 它的运行速度似乎比我预期的或第一次测量的要快,所以这不再是一个关键问题。但是我很想看看这个问题是否有任何好的解决方案。

【问题讨论】:

标签: matlab optimization vectorization


【解决方案1】:

在 MATLAB 中查看 knnsearch。使用城市街区距离并附加一个约束条件,即vicon_ts 中的数据点应小于其在imu_ts 中的邻居。如果不是,则采用下一个索引。这是必需的,因为 cityblock 需要绝对距离。另一种选择(也是首选)是编写您的自定义距离函数。

【讨论】:

    【解决方案2】:

    我相信您当前的方法是合理的,我不会尝试进一步矢量化。当您尝试优化某些内部循环时,矢量化实际上可能是有害的,尤其是当您对数据的上下文了解得比 Mathworks 工程师了解的更多时(例如,它已排序)。

    当我需要优化某些代码时,我通常会寻找以下内容:

    1. 所有数组都是预先分配的(这是性能的最大驱动因素)
    2. 快速内部循环使用简单代码(Matlab 在基本命令上执行非常有效的 JIT,但必须解释其他命令。)
    3. 利用您拥有的任何特殊数据功能,例如在某些循环中使用适当的排序算法和提前退出条件。

    你已经在做这一切了。我建议不要更改。

    【讨论】:

      【解决方案3】:

      一个好的开始可能是摆脱while,尝试类似:

      for i = 1:size(tmap,2)
          C = max(0,tmap(3,:)-vicon_ts(i));
          tmap(2,i) = find(C==min(C));
      end
      

      【讨论】:

      • Find 实际上效率会更低,因为它不假定已排序的数据。因为vic_t数据是排序好的,整体复杂度已经是O(n)了,所以加上find和max就变成了O(n^2)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-23
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 2020-05-30
      • 2017-04-04
      相关资源
      最近更新 更多