5

各次元に同じ数のアイテム(つまり、同じ「長さ」)を持つN次元配列があります。

配列に 1 次元のインデックスを指定すると、そのインデックスに関連付けられた座標を返す関数が必要になります。配列にインデックスを付ける方法は、実際には重要ではありません (配列のすべての次元が等しく、配列で動作するアルゴリズムに関して優先順位がないという意味で)。

たとえば、4x4x4 の配列がある場合、インデックス 63 は [3,3,3] を返し、インデックス 0 は [0,0,0] を返し、インデックス 5 は [1,1,0] を返す必要があります。

次の関数を作成しました。nDim は次元数、nBin は各次元の長さです。

def indicesOf(x,nDim,nBin) :
    indices = []
    for i in arange(0,nDim) :   
        index = (x/nBin**(i))%nBin
        indices.append(index)
        x -= index*nBin**i
    return indices

うまくいくようですが、この計算を行うためのより効率的な方法はありますか? 正直なところ、オンラインで解決策を見つけることができなかったので、この解決策を共有するためだけにこの質問を半分「尋ねました」。しかし、これを行うためのより効率的な方法があれば、素晴らしいです-共有してください!

上記の関数は Python で書かれていますが、私はこれを使って C (実際には CUDA) 関数のプロトタイプを作成したばかりなので、Python の素晴らしいライブラリはどれも利用できません。

以下の 2 つのサイズのパワーに関する JackOLantern と Eric のコメントを組み合わせたソリューションを次に示します。私が試したいくつかのテストケースではうまくいくようです。

def indicesPowOf2(x,nDim,nBin) :
    logWidth = math.log(nBin,2)         
    indices = [0]*nDim
    for i in arange(nDim) :
        indices[i] = x & (nBin-1)
        x = x >> int(logWidth)
    return indices
4

1 に答える 1

2

**特にこのコードを CUDA カーネルに追加する必要がある場合は、計算コストを削減するために (累乗演算子) の使用を避けることができます。

次の方法はより効率的です

void indices(int x, int nDim, int nBin, int indices[]) {
    for(int i=0;i<nDim;i++) {
        indices[i] = x % nBin;
        x /= nBin;
    }
}

nBinが 2 の累乗の場合、andを使用して>>and&を置き換えることができます。/%

于 2013-09-21T12:14:23.050 に答える