【学习体会】Eigen和GLM在矩阵初始化和底层数据存储的差异

目录

GLM相关资料

Eigen相关资料

测试验证


GLM相关资料

https://github.com/g-truc/glm

https://glm.g-truc.net/0.9.9/api/modules.html

https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.20.pdf

通过指定向量或标量来初始化矩阵时,各分量会按**列优先(column-major)**的顺序分配给矩阵元素。

Eigen相关资料

https://github.com/PX4/eigen

https://libeigen.gitlab.io/

https://libeigen.gitlab.io/eigen/docs-3.3/

https://libeigen.gitlab.io/eigen/docs-nightly/group__TutorialAdvancedInitialization.html

Eigen 提供了一种逗号初始化器语法,使用户能够轻松设置矩阵、向量或数组的所有系数。只需列出系数,从左上角开始,从左到右、从上到下依次排列。

https://libeigen.gitlab.io/eigen/docs-nightly/group__TopicStorageOrders.html

Eigen说明了行优先和列优化的两种存储方式,并且说明Matrix默认是列优先存储

测试验证

cpp 复制代码
#include <glm/glm.hpp>
#include <Eigen/Core>
#include <iomanip>

void print_matrix(const std::string& name, const float* data, int rows, int cols) {
    std::cout << name << " 内存布局:" << std::endl;
    for (int i = 0; i < rows * cols; i++) {
        std::cout << std::setw(6) << data[i] << " ";
        if ((i + 1) % cols == 0) std::cout << std::endl;
    }
    std::cout << std::endl;
}

int main() {

    // GLM测试
    glm::mat3 glm_mat(1,2,3,4,5,6,7,8,9);
    glm::vec3 glm_vec(1,0,0);
    glm::vec3 glm_result = glm_mat * glm_vec;
    std::cout <<"glm::mat3 glm_mat(1,2,3,4,5,6,7,8,9)\n";
    std::cout << "GLM 矩阵 * [1,0,0]^T = [" 
              << glm_result.x << ", " << glm_result.y << ", " << glm_result.z << "]" 
              << " → 第一列" << std::endl;
    
    const float* glm_data = &glm_mat[0][0];
    print_matrix("glm_mat", glm_data, 3, 3);

    glm::mat3 glm_mul = glm::transpose(glm_mat)*glm::transpose(glm_mat);
    print_matrix("glm_mul", &glm_mul[0][0], 3, 3);

    // Eigen测试
    Eigen::Matrix3f eigen_mat;
    eigen_mat << 1,2,3,4,5,6,7,8,9;
    std::cout <<"Eigen::Matrix3f eigen_mat\neigen_mat << 1,2,3,4,5,6,7,8,9\n";
    Eigen::Vector3f eigen_vec(1,0,0);
    Eigen::Vector3f eigen_result = eigen_mat * eigen_vec;
    
    std::cout << "Eigen 矩阵 * [1,0,0]^T = [" 
              << eigen_result.transpose() << "]" 
              << " → 第一列" << std::endl;
    const float* eigen_data_ptr = eigen_mat.data();
    print_matrix("eigen_mat", eigen_data_ptr, 3, 3);
    std::cout << "Is row-major (via Flags)? " << ((eigen_mat.Flags & Eigen::RowMajorBit) != 0) << std::endl;
    Eigen::Matrix3f eigen_mul = eigen_mat*eigen_mat;
    print_matrix("eigen_mul", eigen_mul.data(), 3, 3);

    {
    Eigen::Matrix<float, 3, 3, Eigen::RowMajor> eigen_mat;
    eigen_mat << 1,2,3,4,5,6,7,8,9;
    std::cout <<"Eigen::Matrix<float, 3, 3, Eigen::RowMajor> eigen_mat\neigen_mat << 1,2,3,4,5,6,7,8,9\n";
    Eigen::Vector3f eigen_vec(1,0,0);
    Eigen::Vector3f eigen_result = eigen_mat * eigen_vec;
    
    std::cout << "Eigen 矩阵 * [1,0,0]^T = [" 
            << eigen_result.transpose() << "]" 
            << " → 第一列" << std::endl;
    const float* eigen_data_ptr = eigen_mat.data();
    print_matrix("eigen_mat", eigen_data_ptr, 3, 3);
    std::cout << "Is row-major (via Flags)? " << ((eigen_mat.Flags & Eigen::RowMajorBit) != 0) << std::endl;
    Eigen::Matrix<float, 3, 3, Eigen::RowMajor> eigen_mul = eigen_mat*eigen_mat;
    print_matrix("eigen_mul", eigen_mul.data(), 3, 3);
    }

    return 0;
}

输出结果:

初始化方式的差异:1)GLM矩阵初始化是按照列优先分配;2)Eigen通过逗号初始化是行优先分配

存储差异:1)GLM矩阵只有列优先存储的方式;2)Eigen默认是列优先存储,并且提供参数可以用于指定不同存储方式,比如Eigen::RowMajor和Eigen::ColMajor

因此,同样的数据输入,比如说"1,2,3,4,5,6,7,8,9",

对于glm::mat3来说,实际上是定义了矩阵如下所示:

对于Eigen::Matrix3f或者Eigen::Matrix<float, 3, 3, Eigen::RowMajor>来说,实际上是定义了矩阵如下所示,

因此,同样的数据输入,glm::mat3矩阵需要进行装置才等价于Eigen::Matrix3f矩阵

相关推荐
_OP_CHEN3 小时前
【算法基础篇】(五十七)线性代数之矩阵乘法从入门到实战:手撕模板 + 真题详解
线性代数·算法·矩阵·蓝桥杯·c/c++·矩阵乘法·acm/icpc
芷栀夏4 小时前
CANN ops-math:从矩阵运算到数值计算的全维度硬件适配与效率提升实践
人工智能·神经网络·线性代数·矩阵·cann
种时光的人13 小时前
CANN仓库核心解读:catlass夯实AIGC大模型矩阵计算的算力基石
线性代数·矩阵·aigc
Zfox_17 小时前
CANN Catlass 算子模板库深度解析:高性能矩阵乘(GEMM)原理、融合优化与模板化开发实践
线性代数·矩阵
lbb 小魔仙1 天前
面向 NPU 的高性能矩阵乘法:CANN ops-nn 算子库架构与优化技术
线性代数·矩阵·架构
空白诗1 天前
CANN ops-nn 算子解读:大语言模型推理中的 MatMul 矩阵乘实现
人工智能·语言模型·矩阵
劈星斩月1 天前
线性代数-3Blue1Brown《线性代数的本质》特征向量与特征值(12)
线性代数·特征值·特征向量·特征方程
池央1 天前
ops-nn 算子库中的数据布局与混合精度策略:卷积、矩阵乘法与 RNN 的优化实践
rnn·线性代数·矩阵
深鱼~1 天前
大模型底层算力支撑:ops-math在矩阵乘法上的优化
人工智能·线性代数·矩阵·cann
Zfox_1 天前
CANN PyPTO 编程范式深度解析:并行张量与 Tile 分块操作的架构原理、内存控制与流水线调度机制
线性代数·矩阵·架构