MATLAB学习笔记(二)
一、矩阵运算
矩阵分析
向量和矩阵的范数运算
使用的是norm函数以及normset函数
向量的范数定义:
∣
∣
x
∣
∣
p
=
(
∑
i
=
1
n
x
i
p
)
1
/
p
||x||_p = (\sum_{i=1}^{n}{{x_i}^{p}})^{1/p}
∣∣x∣∣p=(i=1∑nxip)1/p
上述定义就称为
∣
∣
x
∣
∣
p
||x||_p
∣∣x∣∣p称为p阶范数。其中最常用的就是1阶、二阶和
∞
\infty
∞阶。
啥意思呢。就好比一阶范数
其实就是
a
n
s
=
(
3
1
+
4
1
)
1
/
1
ans =(3^1+4^1)^{1/1}
ans=(31+41)1/1
二价呢?
是不是很熟悉
a
n
s
=
(
3
2
+
4
2
)
1
/
2
ans =(3^2+4^2)^{1/2}
ans=(32+42)1/2
依次类推就可以了。
或许在这里你们会疑问,既然norm函数
可以算二阶范数,为啥还要有normset函数
呢?
其实
normset函数
是用来估计2阶范数值得,当数据较大时用其数的结果和norm函数
几乎是一样的,但时间却快了很多!
normset(S)
:估计矩阵的2阶范数,默认相对误差是1e-6;normset(S,tol)
:使用tol作为允许的相对误差。
矩阵的秩
最稳定的算法:(不过也是最耗时的)
s = svd(A);
tol = max(size(A)*eps(max(s));
r = sum(s>tol)
-
svd函数是对SVD分解的实现,SVD分解即是奇异值分解 (sigular value decomposition,SVD),它 是一种正交矩阵分解法,是最可靠的分解法。和它类似的有特征值分解。但是值得注意的是,特征值分解只能针对方阵,而对于非方阵是无法应用特征值分解的。正如我们了解的,特征值分解是将矩阵分解为由其特征值和特征向量表示的矩阵之积的方法。需要注意只有对可对角化矩阵才可以施以特征分解。正因为特征值分解的局限性,数学家才提出SVD分解来替代特征值分解在非方阵的应用。
-
首先matlab中eps是一个函数,可以返回某一个数N的最小浮点数精度,形式例如eps(N)。eps(a)是|a|与大于|a|的最小的浮点数之间的距离,距离越小表示精度越高。
默认a=1,即eps = eps(1); 我们在matlab中敲入eps和eps(1)可以发现结果是一样的。eps = eps(1) = 2.2204e-16。
函数rank()
的用法:
rank(A)
:用默认允许误差计算矩阵的秩。rank(A,tol)
:在tol误差内。
矩阵的化零矩阵
定义:若有矩阵Z使得A*Z的元素都为0,且矩阵Z为一个正交矩阵,则称矩阵Z为矩阵A事务化零矩阵。
用法如下:
Z = null(A):
返回矩阵A的一个化零矩阵,不存在则返回空矩阵Z = null(A,'r'):
返回有理数形式的化零矩阵。
矩阵的化简rref()函数
在用MATLAB求解线性方程组的时候,可以使用 rref() 函数对矩阵进行化简,从而很方便直观的得到原方程的解,举一个简单的例子: 解下列线性方程组(应该是求矩阵的行最简形式)
则用MATLAB的rref函数解上述方程组的代码如下
A=[1 2 3
2 4 7
2 1 4]
b=[1;3;4]
rref([A b])
运行结果为
ans =
1 0 0 2/3
0 1 0 -4/3
0 0 1 1
即原方程的解为x1=2/3 x2=-4/3 x3=1
线性方程组
X =A\B
:表示求矩阵方程AX=B的解X=B\A
表示求矩阵方程XA=B的解
对于
X =A\B
,要求矩阵A和B有相同的行数,X和B有相同的列数,X的行数等于矩阵A的列数。X=B\A
性质则相反。
一般求矩阵方程AX=B的解的情况比较多。
系数矩阵A是m × \times ×n的矩阵,其中m是方程个数,n是未知数个数。有如下三种情况:
- m = n :恰定方程组。方程个数与未知数个数一样。(寻求精确值)
- m>n : 超定方程组 。方程个数大于未知数个数。(最小二乘解)
- m<n :欠定方程组。未知数个数大于方程个数。(寻求基本解)
超定线性方程组求解
一般在进行实验数据拟合时,经常遇到这种情况。
如有以下观测数据
希望得到
y
=
c
1
∗
x
+
c
2
∗
x
2
y=c1*x+c2*x^2
y=c1∗x+c2∗x2的模型来拟合。可以用以下方法:
- 那x和y用列向量表示
x = (0:0.1:1)';
y =([-0.01 0.045 0.12 0.2 0.33 0.52 0.67 0.95 1.2 1.45 1.78])'
2.然后构造系数矩阵A
A(:,1) = x';
A(:,2) = x'.^2;
3.此时方程组可以写成: A ∗ [ c 1 c 2 ] ‘ = y A*[c1 c2]` = y A∗[c1c2]‘=y 然后用‘\’来求系数c1和c2。
c = A\y %就是 Ac = y
得到:
画出图
y_fit =c(1)*x +c(2)*x.^2;
plot(x,y_fit,'-',x,y,'o')
矩阵分解
矩阵分解函数
函数 | 描述 |
---|---|
chol | Cholesky 分解 |
cholinc | 稀疏矩阵的不完全Cholesky 分解 |
lu | 矩阵LU分解 |
qr | 正交三角分解 |
svd | 奇异值分解 |
schur | 舒尔止分解 |
在MATLAB7.0中,线性方程组的求解主要基于3种基本的矩阵分解,即对称正定矩阵的Cholesky分解、一般方阵的高斯消去法和矩形矩阵的正交分解。这3种分解分别通过函数chol()、lu()和qr()实现。这3种分解都使用了三角矩阵的概念。若矩阵的所有对角线以下的元素为0,则称为上三角矩阵;若矩阵的所有对角线以上的元素为0,则称为下三角矩阵。
1.对称正定矩阵的Cholessky分解
Cholesky分解是把一个对称正定矩阵A表示为一个上三角矩阵R与其转置的乘积,示例如下:
A
=
R
′
∗
R
A=R′∗R
A=R′∗R
然而,并不是所有的对称矩阵都可以进行Cholessy分解。能进行Cholesky分解的矩阵必须是正定的,即矩阵的所有对角元素必须是正的,同时矩阵的非对角元素不会太大。
2、一般方阵的高斯消去法
使用lu()函数实现
:调用方法如下:
[L,U] = lu(X)
: X为一个方阵,L为“心理”下三角矩阵,U为上三角矩阵,满足关系X=L∗U.[L U,PI=lu(X)
:X为一个方阵,L为下三角矩阵,U为上三角矩阵,P为置换矩阵,满足关系 。P∗X=L∗U。
考虑线性方程组 AX=B, 其中,对矩阵A可以做LU分解,使得
A=L∗U
, 这样线性方程组就可以改写成 L∗U∗X=B
,由于左除算符’'可以快速处理三角矩阵,因此可以快速解出:X=U(L\N)
矩阵的行列式的值和矩阵的逆也可以利用LU分解来计算,示例如下:
det(A)=det(D)∗det(D)
inv(A)=inv(U)∗inv(L)
矩形矩阵的正交分解(正交变换)
对矩阵X进行QR分解,就是把X分解为一个正交矩阵Q和一个上三角矩阵R的乘积形式。QR分解只能对方阵进行。MATLAB的函数qr可用于对矩阵进行QR分解,其调用格式为:
- [Q,R]=qr(X):产生一个一个正交矩阵Q和一个上三角矩阵R,使之满足X=QR。
- [Q,R,E]=qr(X):产生一个一个正交矩阵Q、一个上三角矩阵R以及一个置换矩阵E,使之满足XE=QR。
实现QR分解后,线性方程组Ax=b的解x=R(Qb)或x=E(R(Qb))。
矩阵(方阵)的特征值和特征向量
d = eig(A)
:返回矩阵A的所有特征值。[V,D] = eig(A)
:返回矩阵A的所有特征值和特征向量。
二、MATLAB基本编程
MATLAB作为一种广泛应用于科学计算的工具软件,不仅具有强大的数值计算、符号计算算、矩阵运算的能力和丰富的画图功能,还可以像C语言、FORTRAN等计算机高级语言-一样进行程序设计,编写扩展名为_m的M文件,实现各种复杂的运算,这使得l MATLAB 在科研中的应用更加深入,常常作为系统仿真的工具应用。
MATLAB提供文件编辑器和编译器,这为用户带来了方便,事实上, MATLAB 自带的许多函数就是M文件函数,用户也可利用M文件来生成和扩充自己的函数库。
所谓M文件,简单来说就是用户把要实现的命令写在一个以…m作为扩展名的文件中,然后由 MATLA 系统进行解释,最后运行出结果。
脚本和函数
M文件有函数(Functions)和脚本(Scripts)两种格式。二者相同之处在于它们都是以m作为扩展名的文本文件,不进入命令窗口,而是由文本编辑器来创建外部文本文件。但是两者在语法和使用上略有区别。
函数
MATLAB中许多常用的函数(如sqrt、inv和abs等)都是函数式M文件,使用时, MATLAB获取传递给它的变量,利用操作系统所给的输入,运算得到要求的结果,然后返回这些结果。函数文件类似于一个黑箱,由函数执行的命令以及这些命令所创建的中间变量都是隐含的。运算过程中的中间变量都是局部变量(除特别声明外),存放在函数本身的工作空间内,不会和 MATLAB
基本工作空间(Base workspace)的变量相互覆盖。(对比下形参就好理解了)
- 创建函数
不能在命令行窗口创建
单击新建
,选择函数
即可
- 函数的语法格式
function语法:function [y1,…,yN] = myfun(x1,…,xM),其中[y1,…,yN]为输出量,myfun为函数名,(x1,…,xM)为函数输入量。有效的函数名称以字母字符开头,并且可以包含字母、数字或下划线。
- 示例:
% y 是返回值
%average 是函数名
% x 是函数参数
function y= average(x)
if ~isvector(x)
error('Input must be a vector')
end
y = sum(x)/length(x)
end % 函数的结束位置
- 在命令行使用
注意:
- 如果是多个返回参数:
function [y,z]= average(x)
- 函数文件中可以写多个函数,也可以互相调用。
脚本
脚本是一个扩展名为am的文件,其中包含了MATLAB的各种命令,与批处理文件很类似,在MATLAB命令窗口下直接输入此文件的主文件名, MATLAB可逐一执行在此文件内的所有命令,和在命令窗口逐行输入这些命令一样。
脚本式M文件运行产生的所有变量都是全局变量,运行脚本后,所产生的所有变量都驻留在MATLAB基本工作空间内,只要用户不使用clear命令加以清除,且MATLAB指令窗口不关闭,这些变量将一直保存。基本空间随MATLAB的启动而产生,在关闭 MATLAB 软件时该基本空间被删除。
- 创建脚本
- 使用脚本
对比,有一个区别是可见的。脚本相当于一个写在文件中的命令行语句。
函数与脚本的异同
- (1)从函数名必须与文件名相同。
- (2)脚本式M文件没有输入参数或输出参数,而函数式M文件有输入参数和输出参数。
- (3)函数可以有零个或多个输入和输出变量。函数nargin和nargout包含输入和输出变量的个数。在运行时,可以按少于M文件中规定的输入和输出变量的个数进行函数调用,但不能多于这个标称值。
从运行上看,与脚本文件不同的是,函数文件被调用时,MATLAB会专门为它开辟一个临时工作空间,称为函数工作空间(Function workspace),用来存放中间变量,当执行完函
数文件的最后一条命令或者遇到return时就结束该函数文件的运行,同时该临时函数空间及其所有的中间变量将被清除。函数工作空间相对于基本空间是临时的、独立的,在 MATLAB运行期间,可以产生任意多个临时函数空间。 - (4)在M文件中,包括脚本和函数,到第一个非注释行为止的注释行是帮助文本,当需要帮助时,返回该文本,通常用来说明文件的功能和用法。
- (5)函数M文件中的所有变量除特殊声明外都是局部变量,而脚本中的变量都是全局变量。
- (6)变量的命名可以包括字母、数字和下划线,但必须是以字母开头。并且在M文件设计中是区分大小写的。变量的长度不能超过系统函数namelengthmax所规定的值。
- (7)假设在函数文件中发生对某脚本文件的调用,那么该脚本文件运行产生的所有变量都存放于此函数空间中,而不是存在基本工作空间中。
子函数与私有目录
一个M文件可以包含一个以上的函数,其中有一个主函数,其他为子函数。这些子函数只能被同一文件中的函数(主函数或其他子函数)调用,但是不能被其他文件的函数调用。在一个M文件中,主函数必须出现在最上方,其后可接上任意数目的子函数,而且子函数的次序可随意。同一文件的主函数、子函数的工作空间都是彼此独立的,各函数间的信息可通过输入输出宗量、全局变量或跨空间指令传递。
此外,可以在某一目录中建立一个自己命名的私有目录来存放相关的函数,例如在work目录下建立一个Iscode且录,则work中的M文件(无论是脚本还是函数)即可调用rscode下的任何函数,而不必再定义其他搜寻路径。在 rscode目录下的函数,只能被其父且录的函数所调用而不能被其他目录下的函数调用。
当M文件中需要调用某一个函数时,MATLAB是按照以下顺序来搜寻的:
- 检查此函数是否是子函数;
- 检查此函数是否为私有目录的函数;
- 从所设定的搜寻路径搜索此函数
搜索过程中,只要找到与第一个文件名相符的函数就会立即取用而停止搜索。
特殊的控制语句
- echo
echo 指令— 用来控制m文件在执行过程中是否
显示
echo on — 打开所有命令文件的显示方式
echo off — 关闭所有命令文件的显示方式
echo — 在以上两者间切换
echo对于命令文件函数文件有所不同,命令文件用法简单,函数对所有命令起作用;函数文件用法较复杂,具体请help查询。
echo file on — 打开file函数文件的显示方式
echo file off — 关闭file函数文件的显示方式
echo file — 切换file函数文件的显示方式
echo on all — 打开所有函数文件的显示方式
echo off all —关闭所有函数文件的显示方式
- error
用来提示出错信息并终止当前函数运行,和
warning
与其差不多,不过其会继续运行后面的语句。
- try…catch:也是用于异常情况处理的,注意的是语块中的语句要用逗号隔开
a = 10
b = 0
try
a_n = a/b ,
catch
a_n = 0
end
input()
:用来提示用户从键盘输入数据,并接收输入值。语法格式如下
user = input('prompt') %在屏幕显示提示信息prompt,用户输入赋给变量 user
user = input('prompt','s') %返回的字符串作为文本变量而不是作为变量名或者数值
5.pause
: 此命令用于暂时中止程序的运行,等待用户按任意键继续进行。该命令在程序的调试过程和用户需要查询中间结果时使用很方便。该命令的语法格式如下:
pause %停止,按任意键开始
pause(n) %停止n秒,后继续
pause on %允许后续的pause命令终止程序的运行
pause off %禁止后续的pause命令终止程序的运行
上一篇:
MATLAB学习笔记(一)