簡體   English   中英

如何用步幅遍歷n維數組

[英]how to traverse an n-dimensional array with stride

我有一個索引問題,我試圖解決。 我有一個已知形狀的n維陣列。 我想以一個步幅(每個暗淡可能不同)遍歷數組。

對於固定的維度,我會使用嵌套for循環(小數組)並按步幅遞增:

std::vector<int> shape = {10, 10}; // h,w
int num_dim = shape.size();
std::vector<int> stride = {1,2};

for (int i = 0; i< shape[0]; i+=stride[0]) {
    for (int j = 0; j< shape[1]; j+=stride[1]) {
     //print flattened index (row major)
     printf("index: %d\n",i*shape[0]+j);
    }

}

但是我如何使用n維數組(展平)呢? 就像這樣:

std::vector<int> shape = {10, 10}; // h,w
int num_dim = shape.size();
std::vector<int> stride = {1,2};

int shape_size = 1;
for (int i = 0; i< num_dim; ++i) {
shape_size *= shape[i];
}

int ind = 0;
while (ind < shape_size) {
 // somehow incr ind by the correct amount according to stride, and shape
 // or check if the ind is in the stride (less desirable)
}
class Foo {
public:
    std::vector<int> shape = { 10, 10 }; // h,w
    std::vector<int> stride = { 1, 2 };
    std::vector<int> d = { 0, 0 };
    bool add_end = false;
    void AddStride(int index) {
        d[index] += stride[index];
        if (d[index] < shape[index]) {
            return;
        } else {
            if (index == 0) {
                add_end = true;
                return;
            }
            d[index] = 0;
            index--;
            AddStride(index);
        }
    }
    bool AddStride() {
        AddStride(d.size() - 1);
    }
};
int main() {
    Foo f;
    while(f.add_end != true) {
        //do something
        f.AddStride();
    }
}
class Traverse {
private:
    unsigned m_numDim;
    std::vector<unsigned int> m_vShape;
    std::map<unsigned int, unsigned int> m_mStrides;

public:
    Traverse( const std::vector<unsigned int>& shape, const std::vector<unsigned int>& strides );
    std::vector<unsigned int>& traverse();
}; // Traverse

// ---------------------------------------------------------------
// Traverse()
Traverse::Traverse( const std::vector<unsigned int>& shape, const std::vector<unsigned int>& strides ) {
    if ( shape.empty() || strides.empty() ) {
       return;
    }
    m_vShape = shape;
    m_numDim = m_vShape.size();

    // Here Use The Passed In Vector Of Known Strides To Create Your Map As      
    // An Association For Each Dimension With Its Stride
    for ( unsigned index = 0; index < strides.size(); index++ ) {
        m_mStrides[index+1] = strides[index];
    }         
} // Traverse

// ----------------------------------------------------------------
// traverse()
std::vector<unsigned int>& Traverse::traverse() {
    std::vector<unsigned int> vTemp;

    for ( unsigned index = 0; index < m_numDim; ++index ) {
        // Use Your Map Against Your Stored Shape Vector To Do The Traversing.
    }

    return vTemp; // Or m_vShape;
} // traverse

在這里,m_mStrides很容易知道m_mStrides.first =哪個Dimension和m_mStrides.second =該Dimension中的Stride。

這不是一個完整的工人階級,只是一個讓你入門的插圖。 我也選擇使用unsigned int而不是int,因為在處理shape的大小時,尺寸和步幅負數沒有意義,但是如果你使用已經使用int預先格式化的現有代碼就可以了,但我建議你這樣做錯誤或邊界檢查否定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM