[英]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.