上机辅导讲义 MatLab简介 l、Matlab产生发展的历史 MATLAB语言的首创者是Cleve Moler:1980年前后,当时的新量西哥大学计算机系主任Moler教 授在讲授线性代数课程时,发现了用其他高级语言编程极为不便,便构思并开发了MATLAB (MATriy LABoratory,即矩阵实验室),这一软件利用了当时数值线性代数领域最高水平的EISPACK和 LINPACK两大软件包中可靠的子程序,用Fortran语言编写了集命令翻译、科学计算于一身的一套 交互式软件系统。 所谓交互式语言,是指人们给出一条命令,立即就可以得出该命令的结果。该语言无需像C和 Fortran语言那样,首先要求使用者去编写源程序,然后对之进行编译、连接,最终形成可执行文件。 这无疑会给使用者带来了极大的方便。早期的MATLAB是用Fortran语言编写的,只能作矩阵运算: 绘图也只能用极其原始的方法,即用星号描点的形式画图:内部函数也只提供了几十个。但即使其当 时的功能十分简单,当它作为兔费软件出现以来,还是吸引了大批的使用者。 Matlab中我们主要使用到的三个空间:命令空间(输入命令并执行之)),工作空间,编辑 器空间。 2、MATLAB特色举例 考虑两个矩阵A和B的乘积问题,在C语言中要实现两个矩阵的乘积并不仅仅是一组双重循环 的问题。双重循环当然是矩阵乘积所必需的,除此之外要考虑的问题很多。例如:A和B有一个是复 数矩阵怎么考虑:其中一个是复数矩阵时怎么考虑:全部是实系数矩阵时又怎么管理;这样就要在一 个程序中有4个分支,分别考虑这4种情况。然后还得判断这两个矩阵是否可乘。而考虑两个矩阵 是否可乘也并不仅仅是判断A的列数是否等于B的行数这么简单。其中一个若为标量,则它们可以 无条件地相乘。其中有标量时又得考虑实数与复数的问题等。所以说,没有几十分钟的时间,用C语 言并不可能编写出考虑各种情况的子程序。有了MATLAB这样的工具,A和B矩阵的乘积用A*B 这样简单的算式就能表示了。 【例11〗矩阵生成与运算。考虑金唐作品中经常提及的一个“数学问题”,该问题用半数学语言描述 就是:如何生成一个3x3矩阵,并将自然数1,2,,9分别置成这9个矩阵元素,才能使得每一行、 每一列、且主、反对角线上元素相加都等于一个相同的数。 这样的矩阵称为“魔方矩阵”。用MATLAB的mgc0函数,我们可以由下面的命令立即生成这 样的矩阵: >>A=magic(3) A= 816 357 492 还可以由B=magic(10)一次生成10x10的魔方矩阵
上机辅导讲义 Matlab 中我们主要使用到的三个空间:命令空间(输入命令并执行之)),工作空间,编辑 器空间
一、脚本文件和函数文件 ◆将MATLAB命令窗口中一行一行输入的命令汇集在一个文件中,这样一来要输入这 一组命令时,只需输入这一文件名。这种文件称为MATLAB的脚本文件,其文件扩 展名为.m。 ◆另一类非常重要的M文件是MATLAB函数文件,它由五部分构成 ◆函数定义行 ◆H1行 ◆函数帮助文本 ◆函数体 ◆注释 脚本文件(statl.m: %求阵列x的平均值和标准差 % m,n=size(x); ifm=1(这里=是等于,=是个赋值符号) m=n; end s1=sum(x);s2=sum(x.^2); meanl=s1/m; stdev=sqrt(s2/m-mean1.2); 函数文件(stat2.m): function[mean1,.stdev]=stat2(x)%函数定义行 %求阵列x的平均值和标准差%H1行 %调用格式为 % [mean,stdev]=stat2(x) 」函数帮助文本 [m,n]=size(x); %以下为函数体,其中可包含注释 ifm==1 m=n; end s1=sum(x);s2=sum(x.^2); meanl=s1/m; stdev=sqrt(s2/m-mean1.2); 二、函数工作空间 对以上的脚本文件statl.m和函数文件stat2.m,分别执行后,发现执行stat1.m时,产生了所 有由statl.m产生的变量,而执行stat2.m则只产生函数返回的结果变量,其它由函数文件产 生的变量只存在于特定的函数工作空间中。 这样,利用MATLAB函数设计程序时,只需考虑由函数返回的结果变量,方便设计人员: 但同时也给调试程序带来了不便,幸好MATLAB给程序设计提供了专用的调试器。 三、子函数 在一个函数文件中,可包含多个函数,其中第一个函数名应与文件名同名,其余函数统称为 这一函数的子函数,它们只能在这一函数内部才能使用。 流程控制语句可改变程序执行的流程,MATLAB有四类流程控制语句: if,else,elseif,end 条件转移语句:
一、脚本文件和函数文件 ◆ 将 MATLAB 命令窗口中一行一行输入的命令汇集在一个文件中,这样一来要输入这 一组命令时,只需输入这一文件名。这种文件称为 MATLAB 的脚本文件,其文件扩 展名为.m 。 ◆ 另一类非常重要的 M 文件是 MATLAB 函数文件,它由五部分构成 ◆ 函数定义行 ◆ H1 行 ◆ 函数帮助文本 ◆ 函数体 ◆ 注释 脚本文件(stat1.m): % 求阵列 x 的平均值和标准差 % [m,n]=size(x); if m==1(这里==是等于,=是个赋值符号) m=n; end s1=sum(x); s2=sum(x.^2); mean1=s1/m; stdev=sqrt(s2/m-mean1.^2); 函数文件(stat2.m): function [mean1,stdev]=stat2(x) %函数定义行 % 求阵列 x 的平均值和标准差 %H1 行 % 调用格式为 | % [mean,stdev]=stat2(x) | 函数帮助文本 [m,n]=size(x); %以下为函数体,其中可包含注释 if m==1 m=n; end s1=sum(x); s2=sum(x.^2); mean1=s1/m; stdev=sqrt(s2/m-mean1.^2); 二、函数工作空间 对以上的脚本文件 stat1.m 和函数文件 stat2.m, 分别执行后, 发现执行 stat1.m 时, 产生了所 有由 stat1.m 产生的变量, 而执行 stat2.m 则只产生函数返回的结果变量, 其它由函数文件产 生的变量只存在于特定的函数工作空间中。 这样,利用 MATLAB 函数设计程序时,只需考虑由函数返回的结果变量,方便设计人员; 但同时也给调试程序带来了不便,幸好 MATLAB 给程序设计提供了专用的调试器。 三、子函数 在一个函数文件中,可包含多个函数,其中第一个函数名应与文件名同名,其余函数统称为 这一函数的子函数,它们只能在这一函数内部才能使用。 流程控制语句可改变程序执行的流程,MATLAB 有四类流程控制语句: ◆ if,else,elseif,end 条件转移语句;
switch,case,otherwise,end 情况切换语句: ◆for,end 指定次重复的循环语句: ◆while,end 不定次重复的循环语句。 这些语句给MATLAB程序设计带来了极大的方便,也给设计带来了灵活性。 (1)条件语句 常用的格式为: if a<0 disp(a为负数) elseif a>0 disp(a为正数) else disp(a为零) end 可根据a的不同取值,进行不同的处理。 f语句还可以嵌套使用。 (2)情况切换语句 switch语句可根据表达式的不同取值执行不同的语句,这相当于多条if语句的嵌套使用。例 如: switch varl case-1 disp('Varl is negative one.') case 0 disp('Varl is zero.') case 1 disp('Varl is positive one.') otherwise disp('Varl is other value.') end 在case语句中可出现多个值,例如 switch var2 case (-2,-1) disp('Var2 is negative one or two.) case0 disp("Var2 is zero.') case{1,2,3} disp('Var2 is positive one,two or three.') otherwise disp('Var2 is other value.') end Switch语句还可以出现字符串,例如: switch lower(method) case linear','bilinear
◆ switch,case,otherwise,end 情况切换语句; ◆ for,end 指定次重复的循环语句; ◆ while,end 不定次重复的循环语句。 这些语句给 MATLAB 程序设计带来了极大的方便,也给设计带来了灵活性。 (1)条件语句 常用的格式为: if a<0 disp(‘a 为负数’) elseif a>0 disp(‘a 为正数’) else disp(‘a 为零’) end 可根据 a 的不同取值, 进行不同的处理。 If 语句还可以嵌套使用。 (2)情况切换语句 switch 语句可根据表达式的不同取值执行不同的语句,这相当于多条 if 语句的嵌套使用。例 如: switch var1 case -1 disp(‘Var1 is negative one.’) case 0 disp(‘Var1 is zero.’) case 1 disp(‘Var1 is positive one.’) otherwise disp(‘Var1 is other value.’) end 在 case 语句中可出现多个值, 例如 switch var2 case {-2,-1} disp('Var2 is negative one or two.') case 0 disp('Var2 is zero.') case{1,2,3} disp('Var2 is positive one, two or three.') otherwise disp('Var2 is other value.') end Switch 语句还可以出现字符串, 例如: switch lower(method) case{'linear','bilinear'}
disp('Method is linear.') case (cubic') disp('Method is cubic.) case nearest' disp('Method is nearest.') otherwise disp('Unknown method.) end (3)指定次重复循环语句 for语句用于完成指定次的重复循环语句,这是大家所熟知的形式。 例如计算201: =1 for k=1:20 【=r*k end disp(r) for语句还可以利用数组(即阵列)任意指定循环变量的值,例如 vax=-52817I 计算结果为 for x=varx 50 disp(x.^2-5*x); 6 end 24 Fo循环可以嵌套使用.例如采用二重循环可方便地进行数据的排序: 4 x=fix(100*rand(1,10));disp(x) 14 n=length(x); for i=l:n for j=n:-1:i+1 if x(j)>x(j-1) y=x(j);x(j)=x(j-1);x(j-1)=y; end end end disp(x) For循环中可采用break语句来终止循环,如上例中可利用break提高执行效率: x=fix(100*rand(1,10));disp(x) n=length(x); for i=1:n flag=-1; for j=n:-1:i+1 if x(j)>x(j-1) y=x(j);x(j)=x(j-1);x(j-1)=y;flag=0; end end if flag,break,end end
disp('Method is linear.') case{'cubic'} disp('Method is cubic.') case{'nearest'} disp('Method is nearest.') otherwise disp('Unknown method.') end (3)指定次重复循环语句 for 语句用于完成指定次的重复循环语句,这是大家所熟知的形式。 例如计算 20!: r=1; for k=1:20 r=r*k; end disp(r) for 语句还可以利用数组(即阵列)任意指定循环变量的值, 例如 varx=[-5 2 8 1 7]; for x=varx disp(x.^2-5*x); end For 循环可以嵌套使用. 例如采用二重循环可方便地进行数据的排序: x=fix(100*rand(1,10)); disp(x) n=length(x); for i=1:n for j=n:-1:i+1 if x(j)>x(j-1) y=x(j);x(j)=x(j-1);x(j-1)=y; end end end disp(x) For 循环中可采用 break 语句来终止循环,如上例中可利用 break 提高执行效率: x=fix(100*rand(1,10)); disp(x) n=length(x); for i=1:n flag=-1; for j=n:-1:i+1 if x(j)>x(j-1) y=x(j);x(j)=x(j-1);x(j-1)=y;flag=0; end end if flag,break,end end 计算结果为: 50 -6 24 -4 14
disp(x),disp(循环次数为,num2str(i)]) 四、不定次重复循环语句 wile语句可执行不定次重复的循环,它与for循环不同,在每次徇环前要判别其循环条件, 当条件为真时或非零值时,重复循环:否则结束循环。因此,在while循环中,可通过改变 循环变量来改变循环次数:但在o循环中,虽然也可以改变其循环变量,但其循环次数不 受其影响 例如: =1k=1; while r<le50 =r*k,k=k+1; end k=k-1;r=r./k;k=k-1; disp(['The ',num2str(k),!is',num2str(r va=123456-1780: a=0;k=l; while var(k) if var(k)=-1,break,end a=[a var(k).2];k=k+1; end disp(a) 1 49162536 注意:break还可用于for循环I MATLAB语言与其它语言一样,程序设计的好坏,直接影响程序的执行效率。我们结合多 年利用MATLAB进行编程的经验,给大家介绍两种行之有效的设计技术。 8循环的向量化: &阵列预分配。 一、循环的向量化 实际应用中,有些循环可直接转换成向量,这时可大大提高程序的执行效率。因此编程时, 尽量采用向量或矩阵操作,而应避免循环。 为测试程序执行的快慢,可采用tic和toc函数。 例如:tic i=0: fort=0:.01:100 i=itl;y(①=sin(t, end toc tic t=0:.01:100 y=sin(t); toc 执行时间分别为
disp(x),disp(['循环次数为',num2str(i)]) 四、不定次重复循环语句 while 语句可执行不定次重复的循环,它与 for 循环不同,在每次徇环前要判别其循环条件, 当条件为真时或非零值时,重复循环;否则结束循环。因此,在 while 循环中,可通过改变 循环变量来改变循环次数;但在 for 循环中,虽然也可以改变其循环变量,但其循环次数不 受其影响 例如: r=1; k=1; while r<1e50 r=r*k; k=k+1; end k=k-1; r=r./k; k=k-1; disp([' The ',num2str(k),'! is ',num2str(r var=[1 2 3 4 5 6 -1 7 8 0]; a=[]; k=1; while var(k) if var(k)==-1, break, end a=[a var(k).^2]; k=k+1; end disp(a) 1 4 9 16 25 36 注意: break 还可用于 for 循环! MATLAB 语言与其它语言一样,程序设计的好坏,直接影响程序的执行效率。我们结合多 年利用 MATLAB 进行编程的经验,给大家介绍两种行之有效的设计技术。 ✪ 循环的向量化; ✪ 阵列预分配。 一、循环的向量化 实际应用中,有些循环可直接转换成向量,这时可大大提高程序的执行效率。因此编程时, 尽量采用向量或矩阵操作,而应避免循环。 为测试程序执行的快慢,可采用 tic 和 toc 函数。 例如:tic i=0; for t=0:.01:100 i=i+1;y(i)=sin(t); end toc tic t=0:.01:100; y=sin(t); toc 执行时间分别为