vectorxf vectorxd tutorial c++ eigen

c++ - tutorial - vectorxd size



Inicializar Eigen:: vector con std:: vector (4)

Lo he visto antes pero no recuerdo cómo inicializar eficientemente un Eigen::Vector de longitud conocida con un std::vector de la misma longitud. Aquí hay un buen ejemplo:

std::vector<double> v1 = {1.0, 2.0, 3.0}; Eigen::Vector3d v2; // Do I put it like this in here: v2(v1) ? v2 << v1[0], v1[1], v1[2]; // I know you can do it like this but // I am sure i have seen a one liner.

He leído detenidamente this página sobre la inicialización de matriz avanzada, pero no hay una explicación clara del método para realizar esta acción.


El siguiente one-liner debería ser más correcto:

std::vector<double> a = {1, 2, 3, 4}; Eigen::VectorXd b = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(a.data(), a.size());


Encontré una mejor respuesta por este enlace:

https://forum.kde.org/viewtopic.php?f=74&t=94839

Básicamente, primero crea un puntero al vector std, y luego pasa el puntero y la longitud al constructor usando Map.

Este método funciona con un objeto Vector dinámico en Eigen. Aunque traté de usar la función .data () desde el vector std como lo sugiere la primera respuesta, me da un error: la aserción estática falló: YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR

¡Pero usar este método funciona!

Solo copio y pego el código relevante del enlace aquí:

std::vector<double> v(4, 100.0); double* ptr = &v[0]; Eigen::Map<Eigen::VectorXd> my_vect(ptr, 4);


Según Eigen Doc, Vector es un typedef para Matrix, y Matrix tiene un constructor con la siguiente firma:

Matrix (const Scalar *data)

Construye una matriz de tamaño fijo inicializada con coeficientes que comienzan en datos.

Y vector reference define std::vector::data como:

std::vector::data T* data(); const T* data() const;

Devuelve el puntero a la matriz subyacente que sirve como almacenamiento de elementos. El puntero es tal que range [data(); data() + size()) [data(); data() + size()) siempre es un rango válido, incluso si el contenedor está vacío.

Entonces, podrías simplemente pasar los datos del vector como un parámetro constructor Vector3d :

Eigen::Vector3d v2(v1.data());

Además, a partir de Eigen 3.2.8, el constructor mencionado anteriormente se define como:

template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> ::Matrix(const Scalar *data) { this->_set_noalias(Eigen::Map<const Matrix>(data)); }

Como puede ver, también usa Eigen::Map , como lo señalan @ggael y @gongzhitaao.


Solo para extender la respuesta de @ggael en caso de que otros no lo noten:

De la Guía de referencia rápida: Asignación de matriz externa :

float data[] = {1,2,3,4}; Map<Vector3f> v1(data); // uses v1 as a Vector3f object Map<ArrayXf> v2(data,3); // uses v2 as a ArrayXf object Map<Array22f> m1(data); // uses m1 as a Array22f object Map<MatrixXf> m2(data,2,2); // uses m2 as a MatrixXf object