Matlab编程必备手册 北京索为高科系统技术有限公司 雒海涛 2011-02-11 编程格式规范 这儿把编程格式规范放在最前面希望大家在学习之前认真阅读该部分,对后面的matlab编程大有裨益 一.编程原则 1. 正确:能准确实现原仿真目的; 2. 高效:循环向量化,少用或不用循环,尽量调用MATLAB自带函数; 3. 清晰:养成良好的编程习惯,程序具有良好的可读性; 4. 通用:程序具高度的可移植性,同时易于扩展,避免同学之间重复工作 二. 编程规则 1. 定义变量,以英文单词小写缩写开头表示类别名,再接具体变量的英文名称英文单词,具体变量首字母大写 教研室常用类别缩写:最大值 max,最小值 min 例如:定义变量存贮临时数组TempArray的最大值 maxTempArray 依照工程大小确定变量名长短,小范围应用的变量应该用短的变量名定义务必清晰,避免混淆 2. 循环变量使用常用变量i,j,k;程序中使用复数时,采用i,j以外的循环变量以避免和虚数单位冲突,同时要在注释部分说明变量意义 3. 程序应高内聚、低耦合、模块函数化,便于移植、重复使用 4. 使用if 语句判断变量是否等于某一常数时,将常变量数写在等号之前,常数写在等号之后。
例如判断变量a是否等于100写作if a ==100 5. 用常数代替数字,少用或不用数字 例如上一条:写作if a = =100就不标准应先定义meanConst=100;为期望常量同时在注释中说明,然后在程序部分写作:if a = =const;如果要修改期望常量的话,只要在程序定义部分修改就可以,不必再逐行修改,此外还易于在该程序的基础上增加其他功能 三. 注释规则 1. 注释要用汉语,且用一个“%”连接文字作为注释开始标志程序的起始要注明作者、时间、程序功能、复杂的算法需要加上流程说明对于比较复杂的程序,由几个人协作完成,要在每一个模块的起始分别注明作者、时间、程序功能注释采用matlab的注释符号同时第一行增加关键字,便于将来程序文件较多时,使用help和lookfor查找例如: %关键字%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %此处为函数名,如果不是函数文件就取消此行 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %创建人: %日 期: %修改人: %日 期: %函数变量及功能的简单描述 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2. 对于所有有物理含义的变量、常量、数据结构声明,在声明时都必须加以注释,说明其物理含义,单位。
3. 源程序有效注释量必须在20%以上,边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性,不再有用的注释要删除注释语言必须准确、易懂、简洁,尽量不要用缩写如果接手前人的程序,在维护过程中需要对变量以及源程序作部分修改及 补充,在修改变量及程序注释的同时需要在修改的位置标明修改人的名字及修改日期 对原程序修改要及时修改注释否则有注释比没有注释还要糟糕 4. 程序内部不同功能模块要空一行,同时附注释说明模块的作用、功能这样程序结构清晰易懂,便于同学间学习交流 例如: …模块一…代码… 此处为空行 %注释说明下一模块的功能%%%%%%% …模块二…代码… 5. 一行代码不宜过长,应限制在80列之内一旦有过长代码须用MATLAB转接符号“...”连接两行代码,以便于同学之间打印程序交流因为大多是打印机的行长度为80 例 : 第一行代码 nVariable=1+1+1++1+1+1+1+1+1+11+1+1+1+1+1+1+1+1+1+1+1+1... 第二行代码 +1+1+1; 编程入门 一.前言 Matlab 作为一种广泛应用于科学计算的工具软件,不仅具有强大的数值计算、符号计算、矩阵运算能力和丰富的绘图功能,同时也具有和 C、FORTRAN 等高级语言一样进行程序设计。
利用 Matlab 的程序控制功能,可以将有关 Matlab 命令编成程序存储在一个文件中(M 文件),然后在命令窗口中运行该文件,Matlab 就会自动依次执行文件中的命令,直到全部命令执行完毕 在 Matlab 程序设计中,要充分利用 Matlab 数据结构的特点,提高编程效率 二.M文件 M 文件以 .m 为扩展名M 文件是由若干 Matlab 命令组合在一起构成的,它可以完成某些操作,也可以实现某种算法事实上,Matlab 提供的内部函数以及各种工具箱,都是利用 Matlab 语言开发的 M 文件用户也可以结合自己的工作需要,开发自己的程序或工具箱 M 文件根据调用方式的不同可以分为两类:Script:脚本文件/命令文件 ,Function:函数文件它们均是普通的 ASCII 码构成的文件M 脚本文件中包含一族由 MATLAB 语言所支持的语句,它类似于 DOS 下的批处理文件,它的执行方式很简单,用户只需在 MATLAB 的提示符 >> 下键入该 M 文件的文件名,这样 MATLAB 就会自动执行该 M 文件中的各条语句,并将结果直接返回到 MATLAB 的工作空间M 函数格式是 MATLAB 程序设计的主流,一般情况下, 不建议您使用 M 脚本文件格式编程。
MATLAB 的 M 函数是由 function 语句引导的,其基本格式如下: function [返回变量列表] = 函数名 (输入变量列表) 注释说明语句段, 由 % 引导 输入、返回变量格式的检测 函数体语句 建议:M文件名与文件内主函数名相同(matlab是以文件名做区分的,当然函数名和文件名也可以不同) 三.程序实例 1.脚本文件举例:编写一个脚本文件将华氏温度转化为摄氏温度 5(32)9=−cf 新建一个 M 文件 f2cs.m,内容如下: clear; % 清除当前工作空间中的变量 f=input('Please input Fahrenheit temperature:'); c=5*(f-32)/9; fprintf('The centigrade temperature is %g\n',c); 在命令窗口中输入 f2cs,即可执行该 M 文件 2.function文件举例:计算两个数字之和 新建一个m文件,命名为MySum.m,内如如下: function rt = MySum(x,y) rt=x+y; end 在命令窗口输入MySum(10,20)即可输出计算结果。
程序控制结构 一.顺序结构 按排列顺序依次执行各条语句,直到程序的最后,这是最简单的一种程序结构,一般涉及数据的输入输出、数据的计算或处理等 二.选择结构 选择结构 是根据给定的条件成立或不成立,分别执行不同的语句Matlab 用于实现选择结构的语句有 if 语句和 switch 语句 If条件语句 单分支结构 if expression (条件) statements (语句组) end 双分支结构 if expression (条件) statements1(语句组1) else statements2(语句组2) end 多分支结构 if expression1 (条件1) statements1(语句组1) elseif expression2 (条件2) statements2(语句组2) ... ... elseif expressionm (条件m) statementsm(语句组m) else statements(语句组) end if 语句举例 数论中的一个有趣问题:任取一个正整数,如果是偶数,用 2 除,如果是奇数,用 3 乘再加 1,反复这个过程,直到所得到的数为 1。
问:是否存在使该过程永不中止的整数? while 1 n=input('Please enter n(nonpositive quit):'); if n<=0, break; end nt=n; while n>1 if rem(n,2)==0 n=n/2; else n=3*n+1; end fprintf('\n n=%d',n); end fprintf('\n n=%d is not we need! continue ... \n', nt); end switch 语句 根据表达式的不同取值,分别执行不同的语句 switch expression (表达式) case value1 (表达式1) statement1(语句组1) case value2 (表达式2) statement2(语句组2) ... ... case valuem (表达式m) statementm(语句组m) otherwise statement (语句组) end l Matlab 首先计算 expression 的值,然后将它依次与各个 case 指令后的检测值进行比较,当比较结果为真时,就执行相应的语句组,然后跳出 switch 结构。
l 如果所有的比较结果都为假,则执行 otherwise 后面的语句组,然后跳出 switch 结构 l otherwise 指令可以不出现 l switch 后面的表达式 expression 的值可以是一个标量或字符串 三.循环结构 循环结构 是按照给定的条件,重复执行指定的语句Matlab 用于实现循环结构的语句有 for 语句和 while 语句 for 循环 for variable=expression statement(循环体) end 表达式 expression 可以是行向量,也可以是矩阵 while 循环 while expression (条件) statement(循环体) end l 循环语句可以嵌套使用 l 不能在 for 循环体内改变循环变量的值 l 为了提高代码的运行效率,应尽可能提高代码的向量化程度,避免 for 循环的使用 l 如果预先就知道循环的次数,则可以采用 for 循环;否则,如果预先无法确定循环的次数,则可以使用 while 循环 四.其它流控制语句 break 和 continue l break 语句用于终止循环的执行,即跳出最内层循环 l continue 语句用于结束本次循环,进行下一次循环 l break 和 continue 一般与 if 语句配合使用 return l return 语句用于退出正在运行的脚本或函数,通常用在函数文件中。
Matlab常用函数及函数实例 一.常用函数列表 =============================================== 小整理:MATLAB常用的基本数学函数 abs(x):纯量的绝对值或向量的长度 angle(z):复数z的相角(Phase angle) sqrt(x):开平方 real(z):复数z的实部 imag(z):复数z的虚部 conj(z):复数z的共轭复数 round(x):四舍五入至最近整数 fix(x):无论正负,舍去小数至最近整数 floor(x):地板函数,即舍去正小数至最近整数 ceil(x):天花板函数,即加入正小数至最近整数 rat(x):将实数x化为分数表示 rats(x):将实数x化为多项分数展开 sign(x):符号函数 (Signum function) 当x<0时,sign(x)=-1; 当x=0时,sign(x)=0; 当x>0时,sign(x)=1 rem(x,y):求x除以y的馀数 gcd(x,y):整数x和y的最大公因数 lcm(x,y):整数x和y的最小公倍数 exp(x):自然指数 pow2(x):2的指数 log(x):以e为底的对数,即自然对数或 log2(x):以2为底的对数 log10(x):以10为底的对数 =============================================== 小整理:MATLAB常用的三角函数 sin(x):正弦函数 cos(x):馀弦函数 tan(x):正切函数 asin(x):反正弦函数 acos(x):反馀弦函数 atan(x):反正切函数 atan2(x,y):四象限的反正切函数 sinh(x):超越正弦函数 cosh(x):超越馀弦函数 tanh(x):超越正切函数 asinh(x):反超越正弦函数 acosh(x):反超越馀弦函数 atanh(x):反超越正切函数 ==================================================== 小整理:适用於向量的常用函数有: min(x): 向量x的元素的最小值 max(x): 向量x的元素的最大值 mean(x): 向量x的元素的平均值 median(x): 向量x的元素的中位数 std(x): 向量x的元素的标准差 diff(x): 向量x的相邻元素的差 sort(x): 对向量x的元素进行排序(Sorting) length(x): 向量x的元素个数 norm(x): 向量x的欧氏(Euclidean)长度 sum(x): 向量x的元素总和 prod(x): 向量x的元素总乘积 cumsum(x): 向量x的累计元素总和 cumprod(x): 向量x的累计元素总乘积 dot(x, y): 向量x和y的内积 cross(x, y): 向量x和y的外积 (大部份的向量函数也可适用於矩阵,详见下述。
==================================================== 小整理:MATLAB的查询命令 help:用来查询已知命令的用法例如已知inv是用来计算反矩阵,键入 help inv即可得知有关inv命令的用法键入help help则显示help的用 法,请试看看!) lookfor:用来寻找未知的命令例如要寻找计算反矩阵的命令,可键入 lookfor inverse,MATLAB即会列出所有和关键字inverse相关的指令找到所需的 命令後,即可用help进一步找出其用法lookfor事实上是对所有在搜寻 路径下的M档案进行关键字对第一注解行的比对,详见後叙 =============================================== 下表即为MATLAB常用到的永久常数 小整理:MATLAB的永久常数 i或j:基本虚数单位(即) eps:系统的浮点(Floating-point)精确度 inf:无限大, 例如1/0 nan或NaN:非数值(Not a number),例如0/0 pi:圆周率 p(= 3.1415926...) realmax:系统所能表示的最大数值 realmin:系统所能表示的最小数值 nargin: 函数的输入引数个数 nargin: 函数的输出引数个数 ==================================================== 1-7、结束MATLAB 有三种方法可以结束MATLAB: 1.键入exit 2.键入quit 3.直接关闭MATLAB的命令视窗(Command window) ==================================================== 小整理:MATLAB基本绘图函数 plot: x轴和y轴均为线性刻度(Linear scale) loglog: x轴和y轴均为对数刻度(Logarithmic scale) semilogx: x轴为对数刻度,y轴为线性刻度 semilogy: x轴为线性刻度,y轴为对数刻度 ==================================================== 若要画出多条曲线,只需将座标对依次放入plot函数即可: plot(x, sin(x), x, cos(x)); 若要改变颜色,在座标对後面加上相关字串即可: plot(x, sin(x), 'c', x, cos(x), 'g'); 若要同时改变颜色及图线型态(Line style),也是在座标对後面加上相 关字串即可: plot(x, sin(x), 'co', x, cos(x), 'g*'); ==================================================== 小整理:plot绘图函数的叁数 字元 颜色字元 图线型态 y 黄色 . 点 k 黑色 o 圆 w 白色 x x b 蓝色 + + g 绿色 * * r 红色 - 实线 c 亮青色 : 点线 m 锰紫色 -. 点虚线 -- 虚线 ==================================================== 图形完成後,我们可用axis([xmin,xmax,ymin,ymax])函数来调整图轴的范 围: axis([0, 6, -1.2, 1.2]); 此外,MATLAB也可对图形加上各种注解与处理: xlabel('Input Value'); % x轴注解 ylabel('Function Value'); % y轴注解 title('Two Trigonometric Functions'); % 图形标题 legend('y = sin(x)','y = cos(x)'); % 图形注解 grid on; % 显示格线 我们可用subplot来同时画出数个小图形於同一个视窗之中: subplot(2,2,1); plot(x, sin(x)); subplot(2,2,2); plot(x, cos(x)); subplot(2,2,3); plot(x, sinh(x)); subplot(2,2,4); plot(x, cosh(x)); MATLAB还有其他各种二维绘图函数,以适合不同的应用,详见下表。
==================================================== 小整理:其他各种二维绘图函数 bar 长条图 errorbar 图形加上误差范围 fplot 较精确的函数图形 polar 极座标图 hist 累计图 rose 极座标累计图 stairs 阶梯图 stem 针状图 fill 实心图 feather 羽毛图 compass 罗盘图 quiver 向量场图 二.常用函数举例 以下我们针对每个函数举例 当资料点数量不多时,长条图是很适合的表示方式: close all; % 关闭所有的图形视窗 x=1:10; y=rand(size(x)); bar(x,y); 如果已知资料的误差量,就可用errorbar来表示下例以单位标准差来做 资料的误差量: x = linspace(0,2*pi,30); y = sin(x); e = std(y)*ones(size(x)); errorbar(x,y,e) 对於变化剧烈的函数,可用fplot来进行较精确的绘图,会对剧烈变化处进 行较密集的取样,如下例: fplot('sin(1/x)', [0.02 0.2]); % [0.02 0.2]是绘图范围 若要产生极座标图形,可用polar: theta=linspace(0, 2*pi); r=cos(4*theta); polar(theta, r); 对於大量的资料,我们可用hist来显示资料的分 情况和统计特性。
下面 几个命令可用来验证randn产生的高斯乱数分 : x=randn(5000, 1); % 产生5000个 ?=0,?=1 的高斯乱数 hist(x,20); % 20代表长条的个数 rose和hist很接近,只不过是将资料大小视为角度,资料个数视为距离,?⒂眉昊嬷票硎荆? x=randn(1000, 1); rose(x); stairs可画出阶梯图: x=linspace(0,10,50); y=sin(x).*exp(-x/3); stairs(x,y); stems可产生针状图,常被用来绘制数位讯号: x=linspace(0,10,50); y=sin(x).*exp(-x/3); stem(x,y); stairs将资料点视为多边行顶点,并将此多边行涂上颜色: x=linspace(0,10,50); y=sin(x).*exp(-x/3); fill(x,y,'b'); % 'b'为蓝色 feather将每一个资料点视复数,并以箭号画出: theta=linspace(0, 2*pi, 20); z = cos(theta)+i*sin(theta); feather(z); compass和feather很接近,只是每个箭号的起点都在圆点: theta=linspace(0, 2*pi, 20); z = cos(theta)+i*sin(theta); compass(z); -- 3.基本XYZ立体绘图命令 在科学目视表示(Scientific visualization)中,三度空间的立体图是 一个非常重要的技巧。
本章将介绍MATLAB基本XYZ三度空间的各项绘图命 令 mesh和plot是三度空间立体绘图的基本命令,mesh可画出立体网状图, plot则可画出立体曲面图,两者产生的图形都会依高度而有不同颜色下 列命令可画出由函数 形成的立体网状图: x=linspace(-2, 2, 25); % 在x轴上取25点 y=linspace(-2, 2, 25); % 在y轴上取25点 [xx,yy]=meshgrid(x, y); % xx和yy都是21x21的矩阵 zz=xx.*exp(-xx.^2-yy.^2); % 计算函数值,zz也是21x21的矩阵 mesh(xx, yy, zz); % 画出立体网状图 surf和mesh的用法类似: x=linspace(-2, 2, 25); % 在x轴上取25点 y=linspace(-2, 2, 25); % 在y轴上取25点 [xx,yy]=meshgrid(x, y); % xx和yy都是21x21的矩阵 zz=xx.*exp(-xx.^2-yy.^2); % 计算函数值,zz也是21x21的矩阵 surf(xx, yy, zz); % 画出立体曲面图 为了方便测试立体绘图,MATLAB提供了一个peaks函数,可产生一个凹凸有 致的曲面,包含了三个局部极大点及三个局部极小点,其方程式为: 要画出此函数的最快方法即是直接键入peaks: peaks z = 3*(1-x).^2.*exp(-(x.^2) - (y+1).^2) ... - 10*(x/5 - x.^3 - y.^5).*exp(-x.^2-y.^2) ... - 1/3*exp(-(x+1).^2 - y.^2) 我们亦可对peaks函数取点,再以各种不同方法进行绘图。
meshz可将曲面 加上围裙: [x,y,z]=peaks; meshz(x,y,z); axis([-inf inf -inf inf -inf inf]); waterfall可在x方向或y方向产生水流效果: [x,y,z]=peaks; waterfall(x,y,z); axis([-inf inf -inf inf -inf inf]); 下列命令产生在y方向的水流效果: [x,y,z]=peaks; waterfall(x',y',z'); axis([-inf inf -inf inf -inf inf]); meshc同时画出网状图与等高线: [x,y,z]=peaks; meshc(x,y,z); axis([-inf inf -inf inf -inf inf]); surfc同时画出曲面图与等高线: [x,y,z]=peaks; surfc(x,y,z); axis([-inf inf -inf inf -inf inf]); contour3画出曲面在三度空间中的等高线: contour3(peaks, 20); axis([-inf inf -inf inf -inf inf]); contour画出曲面等高线在XY平面的投影: contour(peaks, 20); plot3可画出三度空间中的曲线: t=linspace(0,20*pi, 501); plot3(t.*sin(t), t.*cos(t), t); 亦可同时画出两条三度空间中的曲线: t=linspace(0, 10*pi, 501); plot3(t.*sin(t), t.*cos(t), t, t.*sin(t), t.*cos(t), -t); y(2:4)-1 % 取出y的第二至第四个元素来做运算 同样的方法可用於产生公差为1的等差数列:x = 7:16 x = 7:3:16 % 公差为3的等差数列 x = linspace(4, 10, 6) % 等差数列:首项为4,末项为10,项数为6 若要重新安排矩阵的形状,可用reshape命令:B = reshape(A, 4, 2) % 4是新矩阵的列数,2是新矩阵的行数 举例来说,下列命令会产生一个长度为6的调和数列(Harmonic sequence): x = zeros(1,6); % x是一个16的零矩阵 for i = 1:6, x(i) = 1/i; end for圈可以是多层的,下例产生一个16的Hilbert矩阵h,其中为於第i 列、第j行的元素为: h = zeros(6); for i = 1:6, for j = 1:6, h(i,j) = 1/(i+j-1); end end format rat % 使用分数来表示数值 >>disp(x) 1 1/2 1/3 1/4 1/5 1/6 function output = fact(n) % FACT Calculate factorial of a given positive integer. output = 1; for i = 1:n, output = output*i; end 其中fact是函数名,n是输入引数,output是输出引数,而i则是此函数用 到的暂时变数。
要使用此函数,直接键入函数名及适当输入引数值即可: MATLAB的函数也可以是递式的(Recursive),也就是说,一个函数可以 呼叫它本身举例来说,n! =n*(n-1)!,因此前面的阶乘函数可以改成递式的写法: function output = fact(n)% FACT Calculate factorial of a given positive integer recursively. if n == 1, % Terminating condition output = 1; return; end output = n*fact(n-1); 在写一个递函数时,一定要包含结束条件(Terminating condition),否则此函数将会一再呼叫自己,永远不会停止,直到电脑的 记忆体被耗尽为止以上例而言,n==1即满足结束条件,此时我们直接将 output设为1,而不再呼叫此函数本身。