矩阵中 “行优先“ 和 “列“ 优先

本文深入解析了行优先和列优先在矩阵表示中的概念,探讨了它们在三维空间向量平移中的应用,以及在C++代码实现中的表现形式。同时,对比了DirectX与OpenGL在处理矩阵数据时的不同,解释了两者在GPU数据提交和内存布局上的差异。
部署运行你感兴趣的模型镜像

什么是行优先和列优先?

故名思意,当我们表示一个矩阵的时候把行放在前面就是行优先,把列放在前面就是列优先。

比如 一个矩阵[m][n] , 表示为 m行n列矩阵,表示为行优先,当表示为 m 列n行的时候就是表示列优先。

一个三维空间中的向量p分别沿着x方向y方向z方向上分别平移为a,b,c距离,用行优先的平移矩阵表示为

\begin{bmatrix} 1 & 0& 0& 1\\ 0& 1& 0& 0\\ 0& 0& 1& 0\\ a& b& c& 1 \end{bmatrix} ,用一个列优先的平移矩阵表示为\begin{bmatrix} 1 & 0& 0& a\\ 0& 1& 0& b\\ 0& 0& 1& c\\ 0& 0& 0& 1 \end{bmatrix},两个矩阵的关系也不难看出其实是互为转置的。

 

行优先和列优先表示为矩阵和向量相乘的时候是什么样子的呢?

以向量p(a,b,c,1) 平移举例子:

行优先 (x,y,z,0)  *  \begin{bmatrix} 1 & 0& 0& 1\\ 0& 1& 0& 0\\ 0& 0& 1& 0\\ a& b& c& 1 \end{bmatrix} =(x +a, y+b,c+z,0);

列优先表示 \begin{bmatrix} 1 & 0& 0& a\\ 0& 1& 0& b\\ 0& 0& 1& c\\ 0& 0& 0& 1 \end{bmatrix}* \begin{pmatrix}x \\ y \\ z \\0\end{pmatrix}= \begin{pmatrix}x+a \\ y +b\\ z+c \\0\end{pmatrix}

行优先和列优先用c++代码中怎么表示呢?

答案是写法都一样

以上面的矩阵表示的c++代码举例,都可以表示为 float mat[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{a,b,c,1}};行优先表示时候,第 1行为{1,0,0,0} 。从列优先表示第 1列为\begin{pmatrix}1 \\ 0 \\ 0 \\0\end{pmatrix}

 

表示为行优先的时候mat[3]也就是第三行为(a,b,c,1),表示为列优先的时候表示\begin{pmatrix}a \\ b \\ c \\1\end{pmatrix}. 所以 不管行优先还是列优先都不会 影响c++ 代码中的表示。区别只是在于 c++ 代码表示的意义变了。原先的表示的行变成表示的列了。

提到行优先和列优先就不得不说一下dx 与 opengl 区别了,dx 中把矩阵数据提交给gpu,由hlsl 着色器处理,opengl 中把数据提交给gpu由 glsl着色器处理, dx 的c++内存布局处理是按照行优先进行处理的,opengl 的c++布局是按照列优先进行处理的,而hlsl默认内存布局方式也是按照列向量进行处理的,所以会看到 dx把数据传递到gpu端时候会进行转置,而 glsl 中默认内存布局方式 是按照列向量进行处理,传递数据时候不需要进行转置。

 

 

 

 

您可能感兴趣的与本文相关的镜像

Wan2.2-I2V-A14B

Wan2.2-I2V-A14B

图生视频
Wan2.2

Wan2.2是由通义万相开源高效文本到视频生成模型,是有​50亿参数的轻量级视频生成模型,专为快速内容创作优化。支持480P视频生成,具备优秀的时序连贯性和运动推理能力

### 三角矩阵行优先存储与优先存储的区别及实现方法 在处理三角矩阵时,为了节省存储空间,通常只存储主对角线及其一侧的非零元素。根据存储顺序的不同,可以分为**行优先存储****优先存储**两种方式,它们在数据排顺序、索引映射公式以及实现方法上存在差异。 #### 行优先存储(Row-major Order) 在行优先存储中,矩阵的元素按照**从左到右、从上到下**的顺序依次排到一维数组中。对于**下三角矩阵**,即主对角线及其以下的元素非零,每一行中非零元素的数量随着行数增加而递减。 例如,一个5×5的下三角矩阵,其非零元素数量为15(1+2+3+4+5),这些元素将按照如下顺序存储到一维数组中: ``` a₁₁, a₂₁, a₂₂, a₃₁, a₃₂, a₃₃, a₄₁, a₄₂, a₄₃, a₄₄, a₅₁, a₅₂, a₅₃, a₅₄, a₅₅ ``` 对于给定的矩阵元素位置(i, j),其中i ≥ j(下三角部分),其在一维数组中的索引k可通过以下公式计算: ``` k = i*(i - 1)/2 + j - 1 ``` 此公式来源于将前i-1行的元素数量累加,再加上当前行中j前的元素数量。 #### 优先存储(Column-major Order) 在优先存储中,矩阵的元素按照**从上到下、从左到右**的顺序依次排到一维数组中。同样以5×5的下三角矩阵为例,其非零元素将按照如下顺序存储: ``` a₁₁, a₂₁, a₃₁, a₄₁, a₅₁, a₂₂, a₃₂, a₄₂, a₅₂, a₃₃, a₄₃, a₅₃, a₄₄, a₅₄, a₅₅ ``` 对于优先存储,给定元素(i, j)的索引k可以通过以下方式计算: ``` k = j*(j - 1)/2 + i - 1 ``` 该公式反映了在优先方式下,先累计前面j-1的元素数量,再计算当前中i行前的元素数量。 #### 实现方法对比 - **数据排顺序不同**:行优先是按行依次存储,而优先是按依次存储。 - **索引计算公式不同**:行优先中使用i作为主导因素,而优先中使用j作为主导因素。 - **应用场景差异**:行优先存储更适合按行访问的场景,而优先存储更适合按访问的场景,尤其在某些编程语言中(如Fortran默认使用优先,C/C++默认使用行优先)有明确体现。 #### 示例代码:下三角矩阵行优先优先压缩存储 ```python def row_major_index(i, j): """行优先存储下的索引计算""" return i * (i - 1) // 2 + j - 1 def col_major_index(i, j): """优先存储下的索引计算""" return j * (j - 1) // 2 + i - 1 # 示例:5x5下三角矩阵 n = 5 size = n * (n + 1) // 2 array_row = [0] * size array_col = [0] * size # 填充行优先存储数组 for i in range(1, n+1): for j in range(1, i+1): k = row_major_index(i, j) array_row[k] = f"a{i}{j}" # 填充优先存储数组 for j in range(1, n+1): for i in range(1, j+1): k = col_major_index(i, j) array_col[k] = f"a{i}{j}" print("行优先存储结果:", array_row) print("优先存储结果:", array_col) ``` 通过上述代码可以清晰地看到两种存储方式在数据排顺序上的不同。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值