Собственная ошибка при инициализации динамической матрицы - PullRequest
0 голосов
/ 11 февраля 2019

Я пытаюсь заполнить собственную матрицу (динамические строки, 2 столбца, двойные числа) из вектора, содержащего некоторую простую структуру декартовых точек, однако при использовании оператора <<.

* я получаю ошибку1003 * Пример минимального сбоя (с использованием MSVC 2017):
#include <Eigen/Dense>
#include <vector>

struct point {
    double x, y;
};

int main() {

    std::vector<point> points = {
        point{0.0, 0.0},
        point{0.5, 0.0},
        point{0.0, 1.0},
        point{0.5, 1.0},
    };

    typedef Eigen::Matrix<double, Eigen::Dynamic, 2> CoordMatrix;
    CoordMatrix X;

    for (auto& p : points)
        X << p.x, p.y;

    return 0;
}

При выполнении этого я получаю сообщение об ошибке в строке X << point.x, point.y;, говорящее: «Нет оператора <<, совпадающего с этими операндами» (это также выбрасываетпри попытке передать X << 0.0, 0.0; в режиме отладки).

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Если вы хотите использовать инициализацию <<, вы можете делать это по одной строке за раз (и, как уже сказал @ paler123, вам нужно выделить X перед сохранением значений в нем):

typedef Eigen::Matrix<double, Eigen::Dynamic, 2> CoordMatrix;
CoordMatrix X(points.size(), 2); // allocate space for matrix
Eigen::Index r=0; // or use `r` as counter in the loop
for (auto& p : points)
    X.row(r++) << p.x, p.y; // fill matrix one row per iteration

Вы также можете напрямую сопоставить память points с Eigen::Map - в этом случае вы должны убедиться, что порядок хранения соответствует и что points не изменяется, если вы все еще используете X, но X не потребует дополнительной памяти (кроме указателя и Index).

typedef Eigen::Matrix<double, Eigen::Dynamic, 2, Eigen::RowMajor> CoordMatrix;
auto X = CoordMatrix::Map(&points[0].x, points.size(), 2); // no copy happens
// X gets invalid if `points` are destructed or re-allocated.
0 голосов
/ 11 февраля 2019

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

Eigen предлагает синтаксис инициализатора запятой, который позволяет пользователю легко устанавливать все коэффициенты матрицы, вектора или массива,Просто перечислите коэффициенты, начиная с верхнего левого угла и двигаясь слева направо и сверху вниз.Размер объекта должен быть указан заранее.Если вы укажете слишком мало или слишком много коэффициентов, Эйген будет жаловаться.

Выше ясно сказано, что вам с правой стороны необходимо сопоставить размеры с левой.В вашем случае вам, вероятно, потребуется скопировать элемент вектора за элементом.Что-то вроде:

CoordMatrix X(points.size(), 2); // reserving rigth storage for the matrix
for (auto i = 0u; i < points.size(); ++i) {
  X(i, 0) = points[i].x;
  X(i, 1) = points[i].y;
}
...