Собственные вертикальные ряды укладки в матрицу - PullRequest
1 голос
/ 27 октября 2019

Я хотел бы создать матрицу размером 2N x 9, где N - это динамическое значение с помощью вертикальных стеков 2N 1x9 матриц.

Вот что я пытался сделать.

using CoefficientMatrix = Eigen::Matrix<T, Eigen::Dynamic, 9>;
using CoefficientRow = Eigen::Matrix<T, 1, 9>;

CoefficientMatrix A(2*N, 9);

for (int i = 0; i < N; i++) {
    CoefficientRow ax;
    CoefficientRow ay;
    // fill in ax and ay
    A << ax, ay;
}

Но я получаю следующую ошибку во время выполнения.

Assertion failed: (((m_row+m_currentBlockRows) == m_xpr.rows() || m_xpr.cols() == 0) && m_col == m_xpr.cols() && "Too few coefficients passed to comma initializer (operator<<)"), function finished, file /usr/local/include/eigen3/Eigen/src/Core/CommaInitializer.h, line 120.

Я попытался разобрать синтаксис утверждения, но яне знаю, на что ссылаются эти внутренние имена переменных в терминах моего кода (новичок в Eigen).

Спасибо за любую помощь.

Ответы [ 2 ]

3 голосов
/ 27 октября 2019

TLDR: напишите что-то вроде этого:

CoefficientMatrix A(2*N, 9);

for (int i = 0; i < N; i++) {
    CoefficientRow ax;
    CoefficientRow ay;
    // fill in ax and ay
    A.row(2*i)   = ax;
    A.row(2*i+1) = ay;
}

Причина вашей ошибки в том (как объяснил Ави), что operator<< предназначен для заполнения всей матрицы сразу. Фактически, вызов operator<<(Array &A, Array const &b) присваивает b верхнему левому углу A и возвращает прокси-объект, который содержит ссылку на A и отслеживает, сколько записей A уже присвоено(сохраняется в m_row, m_currentBlockRows, m_col) и перегружает operator,, что присваивает следующее выражение соответствующей позиции a и соответственно увеличивает позицию. Наконец, когда этот прокси-объект разрушается (что обычно происходит «на ;»), деструктор проверяет, все ли записи в A заполнены (и выдает ошибочное утверждение, если нет).

Если вы предпочитаете использовать синтаксис << ,, вы также можете написать:

    A.middleRows<2>(2*i) << ax, ay;

С включенной оптимизацией, которая должна генерировать тот же код, что и простая реализация, описанная выше (поэтому выберите тот, который вам легче читать).


Примечание: технически (ab) вы можете использовать (10) * * * в цикле, создав его вне цикла, присвоив его переменной, а затем используя только оператор , внутри цикла. ,Я намеренно не буду более подробно рассказывать, как это сделать ...

3 голосов
/ 27 октября 2019

Перегрузка для operator << заполняет всю матрицу за один раз. Если размеры не совпадают, вы получите ошибку времени выполнения, с которой вы столкнулись.

Посмотрите на это так. Предположим, что код работает так, как вы хотели (operator << вставил одну строку «две строки за раз»). Как работают два последовательных звонка на operator <<? Должна ли каждая матрица отслеживать, сколько раз был вызван operator <<? Или, наоборот, если была вставлена ​​частичная строка, как это следует обрабатывать?

...