Mapeo mutuo y copia de datos entre el tipo MatrixXd y el tipo VectorXd en la biblioteca Eigen

   1. Función de mapa de la biblioteca Eigen

   La biblioteca Eigen Mapfunciona como una poderosa herramienta para mapear datos existentes, como matrices u otras estructuras de datos de bibliotecas de álgebra lineal, en matrices o vectores propios sin la necesidad de copiar los datos. Este mapeo puede mejorar enormemente el rendimiento porque evita la copia innecesaria de datos y al mismo tiempo le permite utilizar las capacidades de la biblioteca Eigen para manipular estos datos. La siguiente es Mapuna introducción detallada a las funciones de la biblioteca Eigen:

   1. Crea un objeto de mapa :

   Para utilizar Mapuna función, primero necesita crear un Mapobjeto. Normalmente, usted especifica el tipo y el puntero de los datos que se asignarán. Por ejemplo:

double data[] = {
    
    1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
Eigen::Map<Eigen::MatrixXd> matrix(data, 2, 3);

   En este ejemplo, creamos un Mapobjeto matrixque asigna una matriz de dataflotadores de doble precisión a una matriz propia de 2x3. El puntero de datos es datay el tipo de datos es Eigen::MatrixXd(tipo de matriz genérica).

   2. Utilice datos mapeados :

   Una vez creado el objeto Map, puede usarlo como cualquier otra matriz o vector propio. Puede realizar operaciones matriciales, acceder a elementos y más. Por ejemplo:

Eigen::MatrixXd result = matrix.transpose() * matrix;

   Esta línea de código calcula matrixel producto de la transposición de y de sí misma y almacena el resultado en result.

   3. Evite la duplicación de datos :

   Una ventaja clave es que Maplos objetos no copian datos sino que hacen referencia directa a datos existentes. Esto significa que Maplas modificaciones al objeto afectarán a los datos originales y viceversa. Esto puede reducir en gran medida la sobrecarga de memoria y mejorar el rendimiento.

   4. Formato de datos y compatibilidad propia :

   MapLos objetos le permiten asignar datos externos a matrices o vectores propios de una manera que sea compatible con la biblioteca propia. Esto significa que puede interactuar con otras bibliotecas (como contenedores STL, matrices C, etc.) y utilizarlas junto con la funcionalidad de la biblioteca Eigen.

   En general, las capacidades de la biblioteca Eigen Mapnos permiten trabajar de manera eficiente con datos externos y aprovechar las capacidades de álgebra lineal de alto rendimiento de la biblioteca Eigen al tiempo que evitamos la copia innecesaria de datos. Esto es útil para aplicaciones que necesitan interactuar con otras bibliotecas o fuentes de datos externas.

   2. Mapeo del tipo MatrixXd al tipo VectorXd

   El siguiente ejemplo proporciona un ejemplo de mapeo de una variable q con 2 filas y 3 columnas de tipo Eigen::MatrixXd a un vector de columna p de tipo Eigen::VectorXd a través de la función de mapa.

#include <Eigen/Dense>
#include <iostream>

int main() {
    
    
    int n = 3; // 举例,你可以设置合适的 n 值
    Eigen::MatrixXd q(2, n);
    
    // 假设将 q 填充为一些数据
    for (int i = 0; i < 2; ++i) {
    
    
        for (int j = 0; j < n; ++j) {
    
    
            q(i, j) = static_cast<double>(i * n + j);
        }
    }
    
    // 使用 Map 将 q 映射到 VectorXd
    Eigen::Map<Eigen::VectorXd> p(q.data(), 2 * n);
    
    // 输出 q 的内容
    std::cout << "q:\n" << q << "\n";
    
    // 输出 p 的内容
    std::cout << "p:\n" << p << "\n";

    return 0;
}

   Los resultados de ejecución son los siguientes:

q:
0 1 2
3 4 5
p:
0
3
1
4
2
5

   Como se puede ver en el punto 3 de la primera parte, Maplos objetos no copian datos, sino que hacen referencia directamente a datos existentes. Esto significa que Maplas modificaciones al objeto afectarán los datos originales. Modifiquemos los elementos en el vector p, cambiemos el elemento 0 en p a 666 y el tercer elemento a 999, y luego imprimamos q y los elementos de p.

#include <Eigen/Dense>
#include <iostream>

int main() {
    
    
    int n = 3; // 举例,你可以设置合适的 n 值
    Eigen::MatrixXd q(2, n);

    // 假设将 q 填充为一些数据
    for (int i = 0; i < 2; ++i) {
    
    
        for (int j = 0; j < n; ++j) {
    
    
            q(i, j) = static_cast<double>(i * n + j);
        }
    }

    // 使用 Map 将 q 映射到 VectorXd
    Eigen::Map<Eigen::VectorXd> p(q.data(), 2 * n);

    // 输出 q 的内容
    std::cout << "原数据q:\n" << q << "\n";

    // 输出 p 的内容
    std::cout << "原数据p:\n" << p << "\n";

    // 对p中元素进行修改
    p[0] = 666;
    p[3] = 999;

    // 输出 q 的内容
    std::cout << "对p修改后q中的数据:\n" << q << "\n";

    // 输出 p 的内容
    std::cout << "对p修改后p中的数据:\n" << p << "\n";


    return 0;
}

   Los resultados de ejecución son los siguientes:

原数据q:
0 1 2
3 4 5
原数据p:
0
3
1
4
2
5
对p修改后q中的数据:
666   1   2
  3 999   5
对p修改后p中的数据:
666
  3
  1
999
  2
  5

   Se puede encontrar que si se modifican los elementos en p, los elementos correspondientes en q también se "modificarán automáticamente" porque originalmente son los mismos datos.


   3. Mapeo del tipo VectorXd al tipo MatrixXd

   De la misma manera, podemos asignar el tipo VectorXd al tipo MatrixXd, que Eigen::VectorXdes un vector de columna (1 columna y n filas), Eigen::MatrixXdpero una matriz, generalmente varias filas y varias columnas. Para Eigen::VectorXdasignar un objeto a otro Eigen::MatrixXd, debe asegurarse de que las dimensiones coincidan. Específicamente, si su objeto Eigen::VectorXd pcontiene 2n datos, puede asignarlo a un Eigen::MatrixXdobjeto 2xn.

   En el siguiente ejemplo, la variable de tipo VectorXd p contiene 2n elementos, que se asigna a una variable de tipo MatrixXd q 2xn. De manera similar, los datos en q se comparten con p, lo que significa que las modificaciones a q también afectarán a p. ,viceversa .

#include <Eigen/Dense>
#include <iostream>

int main() {
    
    
    int n = 3; // 举例,你可以设置合适的n值
    Eigen::VectorXd p(2 * n);

    // 假设将p填充为一些数据
    for (int i = 0; i < 2 * n; ++i) {
    
    
        p(i) = static_cast<double>(i);
    }

    // 使用Map将p映射到MatrixXd
    Eigen::Map<Eigen::MatrixXd> q(p.data(), 2, n);

    // 输出 p 的内容
    std::cout << "p:\n" << p << "\n";
    
    // 现在,q是一个2x3的矩阵,数据与p共享
    std::cout << "q:\n" << q << "\n";

    return 0;
}

   Los resultados de ejecución son los siguientes:

p:
0
1
2
3
4
5
q:
0 2 4
1 3 5

   4. Copiar del tipo MatrixXd al tipo VectorXd (no recomendado)

   如果不想采用以上的map映射的方法,要将Eigen::MatrixXd类型的变量p中的每个数据存储到Eigen::VectorXd类型的变量q中,也可以使用Eigen库的一些内置函数和操作来完成这个任务。以下是一种方法:

#include <Eigen/Dense>
#include <iostream>

int main() {
    
    
    Eigen::MatrixXd p(3, 3); // 创建一个3x3的矩阵
    p << 1, 2, 3,
         4, 5, 6,
         7, 8, 9;

    Eigen::VectorXd q(p.rows() * p.cols()); // 创建一个大小足够存储p中所有数据的向量

    // 将p中的数据存储到q中
    for (int i = 0; i < p.rows(); ++i) {
    
    
        for (int j = 0; j < p.cols(); ++j) {
    
    
            q(i * p.cols() + j) = p(i, j);
        }
    }

    // 打印结果
    std::cout << "p:\n" << p << "\n";
    std::cout << "q:\n" << q << "\n";

    return 0;
}

   在这个示例中,首先创建了一个3x3的Eigen::MatrixXd矩阵p,并将一些示例数据赋给它。然后,创建了一个大小足够容纳所有p中数据的Eigen::VectorXd向量q。接下来,使用嵌套的循环遍历p的每个元素,并将其复制到q中。最后,打印了p和q的值。其运行结果如下:

p:
1 2 3
4 5 6
7 8 9
q:
1
2
3
4
5
6
7
8
9

   五、VectorXd类型到MatrixXd类型的复制(不推荐)

   如果不想采用以上的map映射的方法,要将Eigen::VectorXd类型的变量q中的每个数据(共2n个)存储到Eigen::MatrixXd类型的变量p中(p是2xn的矩阵),也可以使用Eigen库的一些内置函数和操作来完成这个任务。以下是一种方法:

#include <Eigen/Core>

int main() {
    
    
    int n = 3; // 假设n为3
    Eigen::VectorXd q(2 * n); // 创建一个包含2n个数据的向量q

    // 填充向量q的数据,这里假设有6个数据
    q << 1, 2, 3, 4, 5, 6;

    Eigen::MatrixXd p(2, n); // 创建一个2x3的矩阵p

    // 将q中的数据存储到p中
    for (int i = 0; i < 2; ++i) {
    
    
        for (int j = 0; j < n; ++j) {
    
    
            p(i, j) = q(i * n + j);
        }
    }

    // 打印结果
    std::cout << "q:\n" << q << "\n";
    std::cout << "p:\n" << p << "\n";

    return 0;
}

   在这个示例中,首先创建了一个2n维的Eigen::VectorXd向量q,并向其填充了示例数据。然后,创建了一个2x3的Eigen::MatrixXd矩阵p,用于存储q中的数据。接下来,使用嵌套的循环将q中的数据复制到p中。最后,打印q和p的值。可根据实际需求和数据尺寸来调整上述中的变量n以适应不同大小的问题。调整内外循环的顺序来调整转换后数据的存储顺序。其运行结果如下:

q:
1
2
3
4
5
6
p:
1 2 3
4 5 6

Supongo que te gusta

Origin blog.csdn.net/qq_44339029/article/details/132799888
Recomendado
Clasificación