1.4 MATLAB
MATLAB是一门计算语言,它的运算指令和语法基于一系列基本的矩阵运算以及它们的扩展运算,它支持的数值元素是复数,这也是 MATLAB 区别于其他高级语言的最大特点之一,它给许多领域的计算带来了极大方便。因此,为了更好地利用 MATLAB 语言的优越性和简捷性,首先需要对 MATLAB 的数值类型、数组矩阵的基本运算、符号运算、关系运算和逻辑运算进行介绍,并给出相应示例,本部分内容是后面章节的基础。
1.4.1 MATLAB的数值类型
MATLAB包括4种基本数据类型,即双精度数组、字符串数组、元胞数组、构架数组。数值之间可以相互转化,这为其计算功能开拓了广阔空间。
1.变量与常量
变量是数值计算的基本单元。与 C 语言等其他高级语言不同,MATLAB 语言中的变量无须事先定义,一个变量以其名称在语句命令中第一次合法出现而定义,运算表达式变量中不允许有未定义的变量,也不需要预先定义变量的类型,MATLAB会自动生成变量,并根据变量的操作确定其类型。
(1)MATLAB变量命名规则
MATLAB中的变量命名规则如下:
① 变量名区分大小写,因此A与a表示的是不同的变量;
② 变量名以英文字母开始,第一个字母后可以使用字母、数字、下画线,但不能使用空格和标点符号;
③ 变量名长度不得超过31位,超过的部分将被忽略;
④ 某些常量也可以作为变量使用,如i在MATLAB中表示虚数单位,但也可以作为变量使用。
常量是指那些在MATLAB中已预先定义其数值的变量,默认的常量如表1-4所示。
表1-4 MATLAB默认常量
(2)MATLAB变量的显示
任何MATLAB语句的执行结果都可以在屏幕上显示,同时赋值给指定的变量,没有指定变量时,赋值给一个特殊的变量ans,数据的显示格式由format命令控制。format只影响结果的显示,不影响其计算与存储。MATLAB 总是以双字长浮点数(双精度)来执行所有的运算。如果结果为整数,则显示没有小数;如果结果不是整数,则输出形式如表1-5所示的几种形式。
表1-5 MATLAB的数据显示格式
(3)MATLAB变量的存储
工作空间中的变量可以用save命令存储到磁盘文件中。输入命令“save<文件名>”,将工作空间中全部变量存到“<文件名>.mat”文件中去,若省略“<文件名>”则存入文件“matlab.mat”中;命令“save<文件名><变量名集>”将“<变量名集>”指出的变量存入文件“<文件名>.mat”中。
用命令load可将变量从磁盘文件读入MATLAB工作空间,其用法为“load<文件名>”,它将“<文件名>”指出的磁盘文件中的数据依次读入名称与“<文件名>”相同的工作空间中的变量中去。若省略“<文件名>”则“matlab.mat”从中读入所有数据。
用clear命令可从工作空间中清除现存的变量。
2.字符串
字符是MATLAB中符号运算的基本元素,也是文字等表达方式的基本元素,在MATLAB中,字符串作为字符数组用单引号(’)引用到程序中,还可以通过字符串运算组成复杂的字符串。字符串数值和数字数值之间可以进行转换,也可以执行字符串的有关操作。
3.元胞数组
元胞是元胞数组(Cell Array)的基本组成部分。元胞数组与数字数组相似,以下标来区分,单元胞数组由元胞和元胞内容两部分组成,用花括号{}来表示元胞数组的内容,用圆括号()表示元胞元素。与一般的数字数组不同,元胞可以存放任何类型、任何大小的数组,而且同一个元胞数组中各元胞的内容可以不同。
【例1-7】元胞数组创建与显示示例。
在M文件编辑器中输入以下命令:
A(1,1)={'An example of cell array'}; A(1,2)={[1 2;3 4]}; A{2,1}=tf(1,[1,7]); A{2,2}={A(1,2);'This is an example'}; celldisp(A)
元胞数组A第1行用元胞数组标志法建立一个字符串和一个矩阵;第2行用元胞内容编址法,建立一个传递函数和一个由两个元素组成的元胞组,该元胞组分别是矩阵和字符串,最后,用celldisp函数显示该元胞数组A。
在命令窗口显示结果为:
A{1,1} = An example of cell array A{2,1} = tf object: 1-by-1 A{1,2} = 1 2 3 4 A{2,2}{1}{1} = 1 2 3 4 A{2,2}{2} = This is an example
4.构架数组
与元胞数组相似,构架数组(Structure Array)也能存放各类数据,使用指针方式传递数值。构架数组由结构变量名和属性名组成,用指针操作符“.”连接结构变量名和属性名。例如,可用parameter.temperature表示某一对象的温度参数,用parameter.humidity表示某一对象的湿度参数等,因此,该构架数组parameter由两个属性组成。
5.对象
面向对象的 MATLAB 语言采用了多种对象,如自动控制中常用的传递函数模型对象(tf object)、状态空间模型对象(ss object)和零极点模型对象(zpk object),一些对象之间可以相互转换,例如可以从传递函数模型对象转化为零极点模型对象,这将在后面具体介绍。
1.4.2 MATLAB的矩阵运算
MATLAB 语言最初是由专门用于矩阵运算的计算机语言发展而来的。MATLAB 语言最重要、最基本的功能就是进行实数或复数矩阵的运算,其所有的数值计算功能都是以矩阵(或数组)为基本单元来实现的,尤其是在 MATLAB 图形图像处理、信号处理和控制理论等方面涉及大量的矩阵运算。矩阵运算和数组运算在形式上有很多相似之处,但是在 MATLAB 中二者的运算性质是不同的,数组运算强调的是元素对元素的运算,而矩阵运算则采用线性代数的运算方式。读者不要把二者混为一谈,以免产生一些不可预期的错误。本节将重点介绍矩阵运算。表1-6列出了矩阵和数组的常用运算操作。
表1-6 常用的数组和矩阵操作运算
注:A、B为矩阵,S为标量。
1.矩阵的基本操作
(1)元素的提取
在矩阵操作中常常要获取矩阵中某个特殊元素,在MATLAB中可以通过A(row, column)或者A(n)来提取单个元素,获取矩阵的部分元素可以采用冒号运算符方法,具体如下。
A(:)为A的所有元素。
A(:,:)为二维矩阵A的所有元素。
A(:,k)为A的第k列,A(k,:)为A的第k行。
A(k:m)为A的第k~m个元素。
A(:,k:m)为A的第k~m列组成的子矩阵。
【例1-8】对于范德蒙矩阵A有:
>> a=[1 2 3]; >> b=vander(a) b= 1 1 1 4 2 1 9 3 1 >>b(3,1) %获得范德蒙矩阵b的第3行、第1列处的元素 ans = 9 %其中n为索引,因为矩阵中的元素是按列存储的,即149123111这样的序列 >> b(5) ans = 2
【例1-9】获取矩阵b的多个元素。
>> b=hilb(4) b= 1.0000 0.5000 0.3333 0.2500 0.5000 0.3333 0.2500 0.2000 0.3333 0.2500 0.2000 0.1667 0.2500 0.2000 0.1667 0.1429 >> c=b(1,4)+b(2,4)+b(3,4)+b(4,4) c= 0.7595 >>d=sum(b(1:4,4)) %提取矩阵的多个元素 d= 0.7595 >>f=sum(b(:)) %求所有元素之和 f= 5.0762
(2)矩阵的的转置
矩阵的转置在控制理论等问题里使用比较广泛,矩阵的转置与数组的转置操作是不一样的,在MATLAB中提供矩阵转置操作符为“‘”,而数组转置操作符为“.’”。
【例1-10】试比较矩阵的转置与数组的转置。
>> a=[1 3;1i 3i]; >>b=a' %矩阵转置 b= 1.0000 0-1.0000i 3.0000 0-3.0000i >>c=a.' %数组转置 c= 1.0000 0+1.0000i 3.0000 0+3.0000i
(3)矩阵的缩放
① 矩阵的扩大。当将数据保存在矩阵的元素之外时,矩阵将会自动增大空间来保存这个新增的元素。
【例1-11】矩阵的缩放示例。
>> A=eye(3) A= 1 0 0 0 1 0 0 0 1 >> A(2,4)=8 A= 1 0 0 0 0 1 0 8 0 0 1 0
② 矩阵的缩小。我们可以通过将行或列指定为空数组[],从而删除矩阵中的行或列。但是不能从矩阵中删除单个元素。
【例1-12】矩阵的缩小示例。
>> B=rand(3) B= 0.9501 0.4860 0.4565 0.2311 0.8913 0.0185 0.6068 0.7621 0.8214 >> B(2,3)=[] ??? Indexed empty matrix assignment is not allowed. >> B(:,3)=[] B= 0.9501 0.4860 0.2311 0.8913 0.6068 0.7621
(4)获取矩阵的信息
在矩阵数值运算的时候常常要涉及矩阵的相关信息,MATLAB提供了表1-7中常用的几个函数来获取矩阵的信息。
表1-7 获取矩阵信息的常用函数
【例1-13】应用矩阵信息函数示例。
>> C=rand(3); >> length(C) ans = 3 >> size(C) ans = 3 3 >> ndims(C) ans = 2
2.求特殊矩阵
这里将介绍一些在 MATLAB 中常用到的特殊矩阵以及稀疏矩阵,在控制理论中经常要用到这些矩阵。
(1)零矩阵和全1矩阵
MATLAB提供zeros()和ones()两个函数分别生成这两个矩阵。
【例1-14】零矩阵和全1矩阵示例。
>> A=rand(5) A= 0.4103 0.0099 0.2722 0.9318 0.2026 0.8936 0.1389 0.1988 0.4660 0.6721 0.0579 0.2028 0.0153 0.4186 0.8381 0.3529 0.1987 0.7468 0.8462 0.0196 0.8132 0.6038 0.4451 0.5252 0.6813 >> B=zeros(size(A)) B= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 >> C=ones(4,4) C= 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
(2)单位矩阵
单位矩阵是特殊矩阵中用得最多的矩阵之一,一般用I来表示单位矩阵,MATLAB提供的函数为eye。
【例1-15】求单位矩阵。
>> I=eye(4) I= 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 >> I=eye(size(B)) I= 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
(3)其他特殊矩阵(如表1-8所示)
表1-8 特殊矩阵列表
(4)特殊矩阵应用示例
1)随机矩阵和零矩阵应用示例
【例1-16】Monte Carlo评估方法。
在M文件编辑器中输入以下命令:
close all; rand('seed',.123456) NumberInside=0; PiEstimate=zeros(499,1); for k=1:499 a=-1+2*rand(99,1); b=-1+2*rand(99,1); NumberInside=NumberInside+sum(a.^2+b.^2<=1); PiEstimate(k)=(NumberInside/(k*99))*4; end plot(PiEstimate) title(sprintf('Monte Carlo Estimate of Pi=%5.3f',PiEstimate(499))); xlabel('Hundreds of Trials')
运行程序效果如图1-13所示。
图1-13 Monte Carlo评估结果
2)魔方矩阵函数magic产生的三维图形应用示例
【例1-17】在M文件编辑器中输入以下命令。
for n=9:12 subplot(2,2,n-8); surf(magic(n)); title('num2str(n)') axis off; view(30,45); axis tight end
运行程序效果如图1-14所示。
图1-14 运用magic函数产生的三维图形
3.稀疏矩阵及其示例
稀疏矩阵是一种特殊的矩阵形式,在计算机系统中,内存空间只分配给非零元素。为了能有效地提高计算机的存储效率,节省计算时间和存储空间,产生了稀疏矩阵的理论和方法。MATLAB中有4个最基本的稀疏矩阵,它们分别是单位矩阵、随机矩阵、对称随机矩阵和对称矩阵。在MATLAB中,提供了一系列的特殊函数来进行稀疏矩阵的运算,如表1-9所示。
表1-9 常用的稀疏矩阵函数
【例1-18】生成一个0-1分布的随机稀疏矩阵。
>> a=[1 6 8 4 9 5 7 2]; >> x=diag(a) x= 1 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 9 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 2 >> y=sprand(x) y= (1,1) 0.8214 (2,2) 0.4447 (3,3) 0.6154 (4,4) 0.7919 (5,5) 0.9218 (6,6) 0.7382 (7,7) 0.1763 (8,8) 0.4057 >> spy(y,'d')
最后用函数spy查看非零元素的分布情况,如图1-15所示。
图1-15 稀疏矩阵分布图
【例1-19】稀疏矩阵的存储。
因为稀疏矩阵是按列存储的,而系统访问矩阵的时候一般是按照行读取效率更高。试比较添加矩阵的行和列所用的时间。
>> s=sparse(9999,9999,1); >> tic; %开始计时 >> for n=1:999 A=s(99,:)+s(199,:); end; >> toc Elapsed time is 29.807829 seconds. >> s=sparse(9999,9999,1); >> tic; >> for n=1:999 B=s(:,99)+s(:,199); end; >> toc Elapsed time is 35.531123 seconds. >> s=sparse(9999,9999,1); >> tic; >> for n=1:999 A=s(99,:)'+s(199,:)'; A=A'; end >> toc Elapsed time is 39.239814 seconds.
从例1-19中可以很明显地看出,在编程中若是能够有效利用稀疏矩阵的存储特点将会大大提高运算效率。