每个能爱上代数的人,都是含着金钥匙出生的。——题记
反正笔者是学不好了QAQ,不过计算机上的基本操作还是要会的。日常使用中,主要用到的还是线性代数,下文主要就说它吧。而能呈现在电脑上的线性代数必然离不开向量和矩阵了。接下来就把一些基本操作放在这里,具体原理神马的,代数课本还是需要翻出来好好复习一番的。
零、特殊数与基本操作
不多说了,和数学课本上一样一样的。下面左边是命令右边是含义。
eps 极小量(一般是e-16量级)
pi 圆周率
i,j 复数虚部
inf 无穷大
……
一、创建向量和矩阵
(1)赋值创造
中间无论用空格还是逗号都行,换行用分号:例如下面的例子:
A=[0 1 2 3 4 8 6] 1×7的行向量
B=[0 1 2;3 4 5;6 7 8] 3×3的矩阵
C=[0 1 3 5 8 2]' 6×1的列向量('代表转置)
O=[ ] 生成空矩阵
(2)特殊矩阵
D=zeros(x,y) 创建一个x*y的零矩阵
E=ones(x,y) 创建一个x*y的全一矩阵
F=eye(x,y) 创建一个x*y的,a_{x,x}都是1,其余元素都是0的矩阵
以上操作都可以简写成~(x),这样创建的就是x*x的方阵。
G=magic(3) 创建幻方(当然不一定是3阶的,不过只能是方阵)
H=rand(x,y) 创建所有元素都是[0,1]之间随机数的x*y矩阵
……
不一而足。感觉用得最多的还是手输和下面的冒号操作:
(3)冒号命令创建向量、linspace命令
十分实用!至少笔者写10个代码要用50+个冒号表达式,linspace作用类似。且看下面的例子:
A1=1:0.1:10 创建一个从1开始,10结束,步长为0.1的相邻等差向量
B1=1:10 跟上面始末是一样的,由于默认步长为1,这里可以省略步长
C1=linspace(0,10) 创建一个0开始,10结束的1*100矩阵。说到这儿有人会问,为什么会有linspace这个命令呢?不难发现,如果这时候敲C=0:0.1:10的话,元素会有101个,而不是100个!自然,得到的步长就不是想要的了。不过,我更主要用它作图,毕竟写这个命令就不用算步长了。
D1=linspace(0,10,1000) 跟上面一样,不过是1*1000矩阵。
(4)矩阵组合
如果行或列匹配,那么大的矩阵可以直接写成分块形式。
C=[A B] 写成一行
C=[A;B] 写成一列
二、矩阵的运算
(1)加减法:略
(2)乘法:分为矩阵乘法和点乘两种。
在点乘的时候,要求两个矩阵是完全匹配的。写法形如C=A.*B,这里A,B的行数列数都要求一样。
如果不写那个“.”,那么作的是矩阵乘法,要求第一个矩阵列数等于第二个矩阵行数。
(3)求方阵的逆:命令为inv(A),其中A为非奇异方阵。
(4)除法:分为左除、右除和点除
C=A/B %iff C=A*inv(B)
C=A\B %iff C=inv(A)*B
C=A./B %requires same dimension
感觉左除、右除用的都很少,相反向量之间点除用的很多。
(5)求行列式:det(A) %requires square
(6)求指数:exp(A)
(7)求范数:norm(A,param)
这里的param代表参数,分别可以求1-范数,2-范数,无穷范数(inf),Frobenius范数(写法:norm(A,'fro'))
(8)求矩阵秩、迹:分别为rank(A)和tr(A),和手写是一致的。
(9)矩阵的转置:右边打一撇即可,如B=A',C=[0,1,2,3]'
……
三、矩阵的特殊操作
(1)Schur分解(也称Jordan分解)
求矩阵的Schur(Jordan)标准型。一般用以下两种格式:
B=schur(A) 求Schur标准型
[B,P]=schur(A) 不光求出Schur标准型,还求出过渡矩阵(B为标准型)
(2)LU-分解(高斯消元分解)
将一个矩阵分解为上三角乘下三角。满足方程:PX=LU(P为置换矩阵)
写法:[L,U,P]=lu(X),其中L为上三角矩阵,U为下三角矩阵,P为置换矩阵。
(3)求特征值和特征向量
写法:[X,D]=eig(A) 其中X为特征向量组成的矩阵,而D为一个对角矩阵,每个元素都是一个特征值。
……
四、矩阵的访问与使用
访问矩阵时,标号一律从1开始(这和其他编程语言从0开始相差很大):
A=1:5;
A(1)
返回值是1,而不是2.
……
基本这些操作也就足够用了。当然后面还需要什么,可以慢慢补充。还是不能太着急呀。
另外需要说明的是,MATLAB里的矩阵运算快到令人无法想象。比如说下面的例子:
计算1+1/(2^2)+1/(3^2)+...
使用MATLAB的矩阵运算,则极为快(甚至快过C/C++里直接写循环),下面以计算到10000000为例:
A=1:10000000;
A1=1./A %iff ones(1,10000000)./A
SUM=A1*A1'
完成了计算,在我的电脑上大概需要0.39秒,比C++直接写循环要快一些。
但是要在MATLAB里写循环……我敢打赌你会有砸电脑的冲动的。所以虽然for循环是个好东西,但在这里还是能少用就少用的好。这一点和其他的编程语言有很大的区别。