矩阵的左乘和右乘A左乘以矩阵的左乘和右乘B和矩阵的左乘和右乘A左乘矩阵的左乘和右乘B的区别

第四章 矩阵分解_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
第四章 矩阵分解
上传于||暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩4页未读,继续阅读
你可能喜欢4454人阅读
(一)首先,无论dx还是opengl,所表示的矢量和矩阵都是依据线性代数中的标准定义的:
“矩阵A与B的乘积矩阵C的第i行第j列的元素c(ij)等于A的第i行于B的第j列的对应元素乘积的和。”(实用数学手册,科学出版社,第二版)
例如c12 = a11*b11+a12*b21+a12*b13...
(二)在明确了这一点后,然后我们再看“矩阵的存储方式”,矩阵存储方式有两种,一种是“行主序(row-major order)/行优先”,另一种就是“列主序(column-major order)/列优先”
1)Direct3D 采用行主序存储
“Effect matrix parameters and HLSL matrix variables can define whether the value is a row-major or column- however, the DirectX APIs always treat D3DMATRIX and D3DXMATRIX as row-major.”(见d3d9 document/Casting and Conversion 一节)
2)OpenGL 采用列主序存储
“The m parameter points to a 4x4 matrix of single- or double-precision floating-point values stored in column-major order. That is, the matrix is stored as follows”
(见msdn glLoadMatrixf API说明)
存储顺序说明了线性代数中的矩阵如何在线性的内存数组中存储,d3d 将每一行在数组中按行存储,而opengl将每一列存储到数组的每一行中:
    &&线性代数意义的同一个矩阵,在d3d&和 ogl 中却有不同的存储顺序
&&&&&&&&&&&&& 线代:a11,a12,a13,a14&&&&&&&&&&&&&& d3d&:& a11,a12,a13,a14&&&&&&&&&&&&&&&&&& gl: a11,a21,a31,a41
&&&&&&&&&&&&&&&&&&&&&& a21,a22,a23,a24&&&&&&&&&&&&&&&&&&&&&&&& a21,a22,a23,a24&&&&&&&&&&&&&&&&&&&&&&&a12,a22,a32,a42
&&&&&&&&&&&&&&&&&&&&&&&a31,a32,a33,a34&&&&&&&&&&&&&&&&&&&&&&&&&a31,a32,a33,a34&&&&&&&&&&&&&&&&&&&&&& a13,a23,a33,a43
&&&&&&&&&&&&&&&&&&&&&& a41,a42,a43,a44&&&&&&&&&&&&&&&&&&&&&&&& a41,a42,a43,a44&&&&&&&&&&&&&&&&&&&&&& a14,a24,a34,a44
(三)矩阵乘法顺序和规则
矩阵乘法在线性代数中的定义是确定的,然而在不同的实现中出现了“左乘”和“右乘”的区别,或者叫做“前乘(pre-multiply),后乘(post-multiply)”
这个规则取决于vector的表示形式,即行向量还是列向量。如果是行向量,其实就是一个行矩阵。那么表示线性代数意义的“行x列”,就是前乘。矩阵乘法也是如此。
&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&& &&&&&&&
D3D 是行向量,行优先存储,OpenGL是列向量,列优先存储。同一个矩阵用D3D存储还是用opengl存储虽然不同,但是变换的结果却是相同,
因为opengl 变换向量是把向量视作列向量,并同矩阵的每一列相乘,用来实现线性代数中同一个变换。
我们通常很难看到opengl变换坐标的代码,以下代码出自opengl source code,让我们一窥顶点变换的“庐山真面目”
void FASTCALL __glXForm3(__GLcoord *res, const __GLfloat v[3], const __GLmatrix *m)
&&& __GLfloat x = v[0];
&&& __GLfloat y = v[1];
&&& __GLfloat z = v[2];
&&& res-&x = x*m-&matrix[0][0] + y*m-&matrix[1][0] + z*m-&matrix[2][0]
&+ m-&matrix[3][0];
&&& res-&y = x*m-&matrix[0][1] + y*m-&matrix[1][1] + z*m-&matrix[2][1]
&+ m-&matrix[3][1];
&&& res-&z = x*m-&matrix[0][2] + y*m-&matrix[1][2] + z*m-&matrix[2][2]
&+ m-&matrix[3][2];
&&& res-&w = x*m-&matrix[0][3] + y*m-&matrix[1][3] + z*m-&matrix[2][3]
&+ m-&matrix[3][3];
可见确实如上所述,“OPENGL列向量和矩阵的每一列相乘,仍然表示线性代数行向量和矩阵的每一行相乘”
再来看一下opengl 矩阵相乘,“用a的每一列去乘b的每一行”。
** Compute r = a * b, where r can equal b.
void FASTCALL __glMultMatrix(__GLmatrix *r, const __GLmatrix *a, const __GLmatrix *b)
&&& __GLfloat b00, b01, b02, b03;
&&& __GLfloat b10, b11, b12, b13;
&&& __GLfloat b20, b21, b22, b23;
&&& __GLfloat b30, b31, b32, b33;
&&& b00 = b-&matrix[0][0]; b01 = b-&matrix[0][1];
&&&&&&& b02 = b-&matrix[0][2]; b03 = b-&matrix[0][3];
&&& b10 = b-&matrix[1][0]; b11 = b-&matrix[1][1];
&&&&&&& b12 = b-&matrix[1][2]; b13 = b-&matrix[1][3];
&&& b20 = b-&matrix[2][0]; b21 = b-&matrix[2][1];
&&&&&&& b22 = b-&matrix[2][2]; b23 = b-&matrix[2][3];
&&& b30 = b-&matrix[3][0]; b31 = b-&matrix[3][1];
&&&&&&& b32 = b-&matrix[3][2]; b33 = b-&matrix[3][3];
&&& for (i = 0; i & 4; i++) {
&r-&matrix[i][0] = a-&matrix[i][0]*b00 + a-&matrix[i][1]*b10
&&&& + a-&matrix[i][2]*b20 + a-&matrix[i][3]*b30;
&r-&matrix[i][1] = a-&matrix[i][0]*b01 + a-&matrix[i][1]*b11
&&&& + a-&matrix[i][2]*b21 + a-&matrix[i][3]*b31;
&r-&matrix[i][2] = a-&matrix[i][0]*b02 + a-&matrix[i][1]*b12
&&&& + a-&matrix[i][2]*b22 + a-&matrix[i][3]*b32;
&r-&matrix[i][3] = a-&matrix[i][0]*b03 + a-&matrix[i][1]*b13
&&&& + a-&matrix[i][2]*b23 + a-&matrix[i][3]*b33;
1。矩阵和线性变换:一一对应
矩阵是用来表示线性变换的一种工具,它和线性变换之间是一一对应的。
考虑线性变换:
a11*x1 + a12*x2 + ...+a1n*xn = x1'
a21*x1 + a22*x2 + ...+a2n*xn = x2'
am1*x1 + am2*x2 + ...+amn*xn = xm'
对应地,用矩阵来表示就是:
|a11 a12 ... a1n&& |&& |x1|&& & |x1'|
|a21 a22 ... a2n&& |&& |x2|&& & |x2'|
|...&& &&& &&&&&&&&&&&&&& |* |...|=&&& |... |
|am1 am2 ... amn |&& |xn|&& & |xm'|
也可以如下来表示:
&&&&&&&&&&&&&&&&&& |a11 a21 ... am1|
&&&&&&&&&&&&&&&&&& |a12 a22 ... am2| &
|x1 x2...xn|*|...&& &&&&&&&&&&&&&&& |= |x1' x2'... xm'|&& & &
&&&&&&&&&&&&&&&&&& |a1n a2n ... amn|
其中涉及到6个矩阵。分别为A[m*n],X[n*1],X'[m*1]以及X[1*n],A[n*m],X'[1*m]。
可以理解成向量x(x1,x2,...,xn)经过一个变换矩阵A[m*n]或A[n*m]后变成另外一个向量x'(x1',x2',...,xm'))。
2。矩阵的表示法:行矩阵 vs. 列矩阵
行矩阵和列矩阵的叫法是衍生自行向量和列向量。
其实,矩阵A[m*n]可以看成是m个n维的row vector构成的row matrix,也可看成是n个m维的column vector构成的column matrix。
其中,X[n*1]/X'[m*1]就等价于1个n/m维的column vector。X[1*n]/X'[1*m]就等价于1个n/m维的row vector。
Row matrix和Column matrix只是两种不同的表示法,前者表示把一个向量映射到矩阵的一行,后者表示把一个向量映射到矩阵的一列。
本质上体现的是同一线性变换。矩阵运算规定了它们可以通过转置运算来改变这个映射关系。
3。矩阵的相乘顺序:前乘或左乘 vs. 后乘或右乘
需要注意的是两种不同的表示法对应不同的运算顺序:
如果对一个column vector做变换,则变换矩阵(row matrix/vectors)必须出现在乘号的左边,即pre-multiply,又叫前乘或左乘。
如果对一个row vector做变换,则变换矩阵(column matrix/vectors)必须出现在乘号的右边,即post-multiply,又叫后乘或右乘。
一般不会弄错,因为矩阵乘法性质决定了相同的内维数的矩阵才能相乘。至于为什么是这个规律,为什么要row vector乘以column vector或column vector乘以row vector???想想吧。。。
所以左乘还是右乘,跟被变换的vector的表示形式相关,而非存储顺序决定。
4。矩阵的存储顺序:按行优先存储 vs. 按列优先存储
涉及到在计算机中使用矩阵时,首先会碰到存储矩阵的问题。
因为计算机存储空间是先后有序的,如何存储A[m*n]的m*n个元素是个问题,一般有两种:按行优先存储和按列优先存储。
row-major:存成a11,a12,...,amn的顺序。
column-major:存成a11,a21,...,amn的顺序。
这样问题就来了,给你一个存储好的矩阵元素集合,你不知道如何读取元素组成一个矩阵,比如你不知道a12该放在几行几列上。
所以,每个系统都有自己的规定,比如以什么规则存储的就以什么规则读取。DX使用Row-major,OGL使用Column-major.即一个相同的矩阵A[m*n]在DX和OGL中的存储序列是不一样的,这带来了系统间转换的麻烦。
不过,一个巧合的事情是:DX中,点/向量是用Row Vector来表示的,所以对应的变换矩阵是Column Matrix/Vectors,而OGL中,点/向量是用Column Vector来表示的,所以对应的变换矩阵是Row Matrix/Vectors.所以,如果在DX中对一个向量x(x1,x2,x3,1)或点(x(x1,x2,x3,1))应用A[4*4]的矩阵变换,就是x' = x(x1,x2,x3,1) * A[4*4],由于采用Row-major,所以它的存储序列是a11,a12,...,a43,a44。在OGL中,做同样的向量或点的变换,因为其使用Row
Matrix/Vectors,其应用的变换矩阵应该是A'[4*4] = A[4*4]( ' 表示Transpose/转置),就是x' = A'[4*4] * x'(x1,x2,x3,1),但是由于采用Column-major,它的存储序列正好也是a11,a12,...,a43,a44!!!
所以实际上,对DX和OGL来讲,同一个变换,存储的矩阵元素序列是一样的.比如:都是第13,14,15个元素存储了平移变化量deltaZ,deltaY,deltaZ.
/Matrix.html
http://www.gamedev.net/community/forums/topic.asp?topic_id=321862
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:152275次
积分:1801
积分:1801
排名:第15253名
原创:16篇
转载:64篇
评论:13条
(6)(1)(1)(1)(1)(6)(2)(1)(4)(3)(3)(1)(2)(1)(1)(3)(5)(13)(3)(1)(3)(2)(2)(1)(4)(1)(6)(2)矩阵A与其逆阵左乘或右乘都相等吗?
是的 根据逆矩阵的定义 A的逆矩阵B 需满足 AB=BA=E(单位矩阵)所以 矩阵A与其逆阵左乘或右乘都等于单位矩阵E !
为您推荐:
其他类似问题
A A-¹=A-¹ A=I(单位矩阵)
扫描下载二维码先介绍向量的两种运算,一个行向量乘以一个列向量称作向量的内积,又叫作点积,结果是一个数;
一个列向量乘以一个行向量称作向量的外积,外积是一种特殊的,结果是一个矩阵,
假设和b分别是一个行向量和一个列向量,那么内积、外积分别记作和,,为了讨论方便,假设每个向量的长度为2。
注意:外积在不同的地方定义方式不太一样,这里不详细讨论
定义了内积和外积以后,我们讨论矩阵的乘法。矩阵是由向量组成的,因此对矩阵不同角度的抽象,将矩阵乘法转换为向量乘法,可以使我们从不同的角度去理解矩阵的乘法。首先我们可以对于一个矩阵A(假设行和列的大小都是2),我们可以即可以把它看作由两个行向量组成的列向量,
,又可以看作是由两个列向量组成的行量,我们表示列向量,表示行向量
这样矩阵A和矩阵B的乘积按照不同的角度就可以组成四种理解方式。
一、 A是由行向量组成的列向量,B是由列向量组成的行向量
& & & & & & & & & & & & & & &&
此时AB乘积变为了两个新的向量的外积形式,按照外积定义,我们有
注意到这里面每一个都是一个向量,因此就是一个内积,计算结果就是AB矩阵第i行第j列中的元素。因此,我们可以看到,矩阵乘积是两个向量的外积,并且外积矩阵中的每一个元素是一个内积。这种方式是最直接的理解方式。
二、 A是由列向量组成的行向量,B也是由列向量组成的行向量
令C = AB, 我们考虑C的每一个列向量:
因此,矩阵C的每一个列向量,是A的列向量的一个线性组合,该线性组合中的系数是的各个元素。从这个角度说C的每一列都存在于A的列向量空间内。
三、&A是由行向量组成的列向量,B也是由行向量组成的列向量
类似于上面的情况,不过我们现在考虑C的每一个行向量:
因此,矩阵C的每一个行向量,是B的行向量的一个线性组合,该线性组合中的系数是的各个元素。从这个角度说C的每一个行向量都存在于B的行向量空间内。
四、&A是由列向量组成的行向量,B也是由行向量组成的列向量
此时AB乘积变为了两个新的向量的内积形式。按照内积定义我们有:
注意到是一个外积形式,因为是一个列向量,是一个行向量,因此C是由各个外积矩阵相加得到的。
根据以上分析,我们可以将第一种和第四种方式放到一起,第二种和第三种放到一起分别进行理解。第一种方式先将A抽象为列向量,将B抽象为行向量,从而将矩阵乘法变为了一种外积的形式,而外积矩阵中的每一个元素是一个行向量和一个列向量的内积。这种方式每次得到C的一个元素。
第四种理解方式先将A抽象为行向量,将B抽象为列向量,从而将矩阵乘法变为了一种内积形式,内积的各个组成部分又是一个外积。这种方式每次不是得到C的一个元素,而是将C看作是多个矩阵相加组成的,每次计算得到一个加数矩阵。
第二种方式将矩阵A、B都抽象为行向量,行向量的每个组成是一个列向量,A乘以B的每一个列向量得到一个新的列向量,并且该列向量存在于A的列向量空间内,A乘以B相当于是对A进行了列变换。第三种方式则将A乘以B看作是对B进行了行变换。
如果想对一个矩阵进行行变换,可以左乘一个矩阵;相应的如果想对矩阵进行列变换,可以右乘一个矩阵。这种思想被应用到高斯消元的过程中。
最后我们总结一下矩阵C(C=AB)到底是什么,C是一个矩阵,是一个多面孔的矩阵。它既是列向量组成的行向量,每个列向量是A的列空间的线性组合,又是行向量组成的列向量,每个行向量是B的行空间的线性组合;它是一个内积,内积的每个成分是一个外积,同时它又是一个外积,外积矩阵的每一个元素是一个内积。
参考资料:
[2] Introduction to Linear A &Gilbert Strang
阅读(...) 评论()刘老师,我想问下为什么说矩阵左乘向量得的是向量,矩阵右乘向量得的是矩阵.我感觉乘完都是向量了啊
浔子釉亮89
矩阵乘法的规则是:A(m×n)×B(n×s)=C(m×s)【m×n的矩阵A与n×s的矩阵B相乘的结果为m×s的矩阵C】矩阵左乘向量A(m×n)×B(n×1)=C(m×1)相乘的结果为m×1的矩阵C,即为向量矩阵右乘向量A(1×n)×B(n×s)=C(1×s)相乘的结果为1×s的矩阵C,也是向量.所以,不存在:矩阵左乘向量得的是向量,矩阵右乘向量得的是矩阵这样的说法!
为您推荐:
其他类似问题
扫描下载二维码}

我要回帖

更多关于 矩阵左乘 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信