1

現在、template1Dという1D配列に書き込まれたtemplateという変数に5D配列があり、3456(8 * 12 * 3 * 4 * 3)エントリのハッシュテーブルがあります。Matlabでは、次のように多次元配列にアクセスしました。

template{idx_r, idx_l, idx_rho, idx_alpha, idx_beta}

ただし、インデックスはそれぞれ0〜7、0〜11、0〜2、0〜3、0〜2であるため、全体的なインデックス番号を取得する最も簡単な方法はわかりません。テンプレート配列内の適切なセグメントを適切に取得するためのこれらの5つのインデックス。そのようなハッシュ関数を適切に作成するための最も簡単な方法は何でしょうか?

4

5 に答える 5

7

ここで何をしようとしているのか正確にはわかりませんが、関数 ind2sub と sub2ind を検討しましたか? 彼らは助けるかもしれません。MATLAB は 1 ベースであるため、0 と 1 ベースのインデックスについて考慮する必要がある場合があります。

――ローレン

于 2009-05-28T11:56:19.220 に答える
3

フラット配列として配置された2D配列の場合、最初のインデックスに最初の次元のサイズを掛けて、2番目のインデックスを追加します。同様に、5次元では、次のようになります。

index = (((i1*l1 + i2)*l2 + i3)*l3 + i4)*l4 + i5;
于 2009-05-28T06:10:36.863 に答える
2

確かに線形インデックスを計算するために自分で計算を行うことができますが ( Talが指摘したように)、組み込み関数SUB2INDを使用すると、よりクリーンで読みやすくなります( Lorenが指摘したように)。あなたの例では、次のように使用します。

index = sub2ind([8 12 3 4 3], idx_r, idx_l, idx_rho, idx_alpha, idx_beta);

すべてのインデックスが 0 ベースの場合、SUB2IND に渡す前にそれぞれに 1 を追加する必要があります。

編集:

SUB2IND からの結果と一致するように、MATLAB で自分で線形インデックスを正しく計算する方法を確認したい場合は、次のコードを使用します。

index = (((idx_beta*4 + idx_alpha)*3 + idx_rho)*12 + idx_l)*8 + idx_r + 1;

この式で使用する必要があるインデックスは 0 ベースである必要があり、SUB2IND に渡されるインデックスは 1 ベースである必要があることに注意してください。この方程式を任意の次元数Nに一般化するには、次のようにします。

index = (...(idx(N)*sz(N-1) + idx(N-1))*sz(N-2) + ...)*sz(1) + idx(1) + 1;

またはより簡潔に:

index = 1 + sum(idx.*cumsum([1 sz(1:(N-1))]));

ここで、idxは各次元の 0 ベースのインデックス値の配列であり、szは各次元のサイズの配列です。

于 2009-05-28T16:08:05.950 に答える
2

文字列を使用してハッシュすることを検討しましたか? 16 進数にすることもできます。

5文字

#Character 0 is in the range '0'...'7',
#Character 1 is in the range '0'...'B',
#Character 2 is in the range '0'...'2',
#Character 3 is in the range '0'...'3',
#Character 4 is in the range '0'...'2'

16 進数としての文字列の優れた点の 1 つは、変換が必要になった場合に、簡単に int...err... unsigned long long 表現を使用できることです。

于 2009-05-28T06:04:31.197 に答える
0

質問を正しく理解したかどうかわからないので、理解したことを述べます。

  • 多次元行列を表す特定のサイズの配列があります。
  • 5次元ベクトルを配列の実位置に変換したい

最初にそれをカプセル化するクラスを作成し、5 つの引数 (std::size_t、unsigned int など) で定義された operator() を提供します。この operator() は、最初に範囲をチェックする必要があります (おそらく例外をスローし、すべての引数を最終位置に変換します。

最も単純な変換は次のとおりです。

size_t position( size_t idx_r, size_t idx_l, size_t idx_rho, size_t idx_alpha, size_t idx_beta )
{
   size_t pos = (((((((idx_r * dim_l) + idx_l) * dim_rho) + idx_rho) * dim_alpha) + idx_alpha) * dim_beta) + idx_beta;
   return pos;
}

dim_XXXは、次元 XXX のマトリックスのサイズを表します

多くの操作を実行している場合は、インターフェイスを変更せずに異なる順序でデータを内部的に表すことを検討して、キャッシュヒット率を向上させることをお勧めします。

一般的なアルゴリズムは、1 つの次元の各インデックスを次の次元要素に変換し、その次元にオフセットを追加します。最も簡単な例は、2 次元システムです。10 列の配列の行 3 列 2 にアクセスするには (行ごとに格納すると仮定し、引数のために 1 から数えます)、最初に 3 行目の開始点、つまり行ごとに 3 * 10 要素を計算します。次に、行 2 (列 2) 内にオフセットを追加します。

それを 3 次元配列に拡張する場合は、まず平面のインデックスに平面のサイズを掛けて探している平面を見つけ、次に前のアルゴリズムを使用する必要があります。

size_t position( size_t x, size_t y, size_t z )
{
   size_t start_of_plane_z = z * dim_y * dim_x; // z * size_of_plane
   size_t start_of_row_y = y * dim_x; // y * size_of_row
   size_t offset_inside_row = x;

   return start_of_plane_z + start_of_row_y + offset_inside_row;
}

ここで、いくつかの基本的な代数を適用して、方程式を次のように変えることができます。

size_t pos = (((z * dim_y) + y) * dim_x) + x;

これにより、乗算の数が減り、より多くの次元の定義が容易になります。

于 2009-05-28T06:25:24.687 に答える