繁体   English   中英

C ++:将矢量重塑为3D数组

[英]C++: Reshape vector to 3D array

编辑:我已将矢量作为文本文件上传到云端硬盘,以防有人想看看: https//drive.google.com/file/d/0B0wsPU8YebRQbDUwNFYza3ljSnc/view?usp =sharing

我正在尝试将矢量h重塑为3D数组。 h包含295788个元素。 在这种情况下, height = 314width = 314depth = 3 基本上我正在尝试做的是MATLAB的重塑功能。

h = reshape(h, height, width, depth)

这是我到目前为止的尝试,但是当我打印它时,我看到的只是零,这是不对的。 我仔细检查了h包含我期待的数字。

vector<vector<vector<double> > > array3D;

int height = 314, width = 314, depth = 3;
// Set up sizes
array3D.resize(height);
for (int i = 0; i < height; ++i) {
    array3D[i].resize(width);

    for (int j = 0; j < width; ++j)
        array3D[i][j].resize(depth);
}

for (int i = 0; i < height; i++)
{
    array3D[i][0][0] = h[i];
    for (int j = 0; j < width; j++)
    {
        array3D[i][j][0] = h[i+j];
        for (int k = 0; k < depth; k++)
        {
            array3D[i][j][k] = h[i+j+k];
        }
    }
}

印刷:

for (vector<vector<vector<double>>>::const_iterator i = array3D.begin(); i != array3D.end(); ++i)
{
    for (vector<vector<double>>::const_iterator j = i->begin(); j != i->end(); ++j)
    {
        for (vector<double>::const_iterator k = j->begin(); k != j->end(); ++k)
        {
            cout << *k << ' ';
        }
    }
}

所以我的问题是,如何正确地将我的矢量转换为3D数组?

我设法通过使用Henri Menke建议的Eigen :: Tensor来做到这一点。 我最终为初始314x314x3矩阵创建了一个数组,然后为300x300x3矩阵创建了另一个数组。 这既不快也不漂亮,但就目前而言,这是我能想到的。 看起来像这样。

为了澄清:在代码中进一步计算了margin ,但在这个例子中,314x314x3矩阵的margin=7 h是具有295788个元素的向量。 nrh=314nch=314nradii=3

Tensor<int, 3> t(nrh, nch, nradii);
int counter = 0;
for (int k = 0; k < nradii; k++)
{
    for (int col = 0; col < nch; col++)
    {
        for (int row = 0; row < nrh; row++) 
        {
            t(row, col, k) = h[counter];
            counter += 1;
        }
    }
}

int height = nrh - margin * 2;
int width = nch - margin * 2;
int depth = nradii;
Tensor<int, 3> out(height, width, depth);
int count1 = 0, count2 = 0, count3 = 0;

for (int k = 0; k < depth; k++)
{
    for (int j = margin; j < nch - margin; j++)
    {
        for (int i = margin; i < nrh - margin; i++)
        {
            out(count1, count2, count3) = t(i, j, k);
            count1 += 1;
        }
        count1 = 0;
        count2 += 1;
    }
    count2 = 0;
    count3 += 1;
}

编辑:解决方案#2与Tensor.slice()

int height = nrh - margin * 2;
int width = nch - margin * 2;
int depth = nradii;
Tensor<int, 3> tensor(height, width, depth);
DSizes<ptrdiff_t, 3> indices(margin, margin, 0);
DSizes<ptrdiff_t, 3> sizes(height, width, nradii);
tensor = t.slice(indices, sizes);

怎么样:

array3D[i][j][k] = h[i*(depth*width)+j*depth+k];

这可能是也可能不是以正确的顺序扫描矢量。

请注意索引k何时重置索引j增量,因此您只需移动一个直到索引j重置,在这种情况下i递增并相同。 很容易证明这个计算只读取每个元素一次。

我通常期望widthheight然后depth ,你正在以相反的顺序扫描!

脚注:根据应用程序,使用此方法访问向量可能是值得的。 通常,事实证明它比访问矢量矢量的矢量更快。 在处理大规模阵列时,这可能是相关的。

实际上,您的代码结构已经可以,但是,有两个错误:

  • 线条

     array3D[i][0][0] = h[i]; 

     array3D[i][j][0] = h[i+j]; 

    毫无意义。 您稍后将使用该行覆盖这些条目

     array3D[i][j][k] = h[i+j+k]; 
  • h[]的索引计算错误:在添加单元格索引之前,必须将行索引乘以行的长度。 作业应如下所示:

     array3D[i][j][k] = h[(i*width+j)*depth+k]; 

    否则,你会得到相同的结果(i, j, k) == (3, 2, 1)(i, j, k) == (1, 3, 2)这显然是错误的。 在上面的指数计算中,我假设k是变化最快的维度。 如果这不是数据存储在h的顺序,则需要更改ijk并相应地调整因子。

把它们放在一起,你的赋值循环应该是:

for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        for (int k = 0; k < depth; k++) {
            array3D[i][j][k] = h[(i*width+j)*depth+k];
        }
    }
}

略有偏离主题:
如果您使用的是C而不是C ++,那么您可以“简单地”执行此操作:

size_t dataSize;
//Create a real 3D array with the dimensions (height, width, depth).
double (*array3D)[width][depth] = malloc(dataSize = height*sizeof(*array3D));
//Copy over the data from the file.
memcpy(array3D, h, dataSize);


//Print the array contents:
for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        for (int k = 0; k < depth; k++) {
            printf("%d ", array3D[i][j][k]);
        }
    }
}

这使用了一个真正的3D数组,而不是指向双精度数组指针数组的指针数组(这大致是vector<vector<vector<double>>> )。 但是,这不能在C ++中完成,因为C ++不允许像C那样具有动态大小的数组类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM