0

我有两个时间戳列表,我正在尝试在它们之间创建一个使用 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) 操作,但因为它是循环的,所以运行缓慢。任何矢量化的方法来做同样的事情?

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

4

3 回答 3

1

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

当我需要优化某些代码时,我通常会寻找的东西是:

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

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

于 2013-02-05T16:37:07.350 回答
1

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

于 2013-02-05T16:21:22.530 回答
0

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

for i = 1:size(tmap,2)
    C = max(0,tmap(3,:)-vicon_ts(i));
    tmap(2,i) = find(C==min(C));
end
于 2013-02-05T16:18:11.567 回答