我有一个索引问题,我正在尝试解决。 我有一个已知形状的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)
}
答案 0 :(得分:0)
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();
}
}
答案 1 :(得分:0)
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预先格式化的现有代码就可以了,但我建议做错误或边界检查否定。
答案 2 :(得分:0)
这是一篇很好的文章解释它:https://ajcr.net/stride-guide-part-1/ 阅读关于 n 维步幅的第 2 部分以及文章的第 2 部分(在第 1 部分顶部找到链接)