Как объявить собственную матрицу, а затем инициализировать ее через вложенный цикл - PullRequest
1 голос
/ 25 февраля 2020

Я хочу сделать то, что написано в заголовке, я попробовал следующий код:

typedef std::vector<std::vector<std::vector<double>>> Tensor;

// should return a matrix of shape (batch_size, 1840)
Eigen::MatrixXd flatten(Tensor x)
{
    int channels = x.size(); // always 10
    int batch = x[0].size(); // varies
    int columns = x[0][0].size(); // always 184

    Eigen::Matrix<double, Eigen::Dynamic, 1840> matrix;
    for (unsigned int b = 0; b < batch; b++)
    {
        for (unsigned int i = 0; i < columns; i++)
        {
            for (unsigned int c = 0; c < channels; c++)
            {
                matrix << x[c][b][i]; // I also tried this: matrix(b, i+c) = x[c][b][i];
            }
        }
    }
    return matrix;
}

Но код либо прерывается с сообщением abort() has been called, либо дает мне Access violation writing location 0x0000000000000000

Как правильно выполнить sh то, что я пытаюсь сделать?

1 Ответ

2 голосов
/ 25 февраля 2020

Вы никогда не говорили матрице, какого размера она должна быть. Вы должны изменить размер матрицы перед записью в нее.

Eigen::Matrix<double, Eigen::Dynamic, 1840> matrix;
matrix.resize(batch, 1840);
for (unsigned int b = 0; b < batch; b++)
    ...

Вторая проблема с вашим кодом состоит в том, что operator<< не ведет себя как push_back контейнеров std. Он инициализирует всю (надлежащего размера) матрицу сразу, а не с помощью вызовов NxMxL.

Несоответствующая проблема производительности с кодом заключается в том, что Tensor x передается по значению, в результате чего создается копия. Вместо этого передайте (постоянную) ссылку:

Eigen::MatrixXd flatten(const Tensor& x)
{ ...
...