0

タイムスタンプの 2 つのリストがあり、imu_ts を真の時間として使用し、それに最も近い vicon_ts 値を見つけようとするマップを作成しようとしています。出力は 3xd 行列で、最初の行は imu_ts インデックス、3 番目の行はそのインデックスでの UNIX 時間、2 番目の行は同じ列のタイムスタンプより上の最も近い 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を見てください。街区距離を使用し、 のデータ ポイントが のvicon_ts隣接するポイントより小さくなければならないという追加の制約も設定し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 に答える