1. 编写自己的MATLAB程序

1.1. 脚本文件

单击按钮,打开脚本编辑窗口

所谓的脚本文件,就是将一些MATLAB命令简单的堆砌在一起保存成的M文件。

1.2. 函数文件

函数文件就是按照一定格式编写的,可由用户指定输入和输出进行调用的M文件。

函数文件由function语句引导,其格式为:

function [out1, out2,] = funname(in1, in2,)
注释说明部分(%号引导的行)
函数体

其中out1, out2, …为输出参数列表,in1, in2, …为输入参数列表,funname为函数名。

注意

  • 函数输出参数列表中提到的变量要在函数体中予以赋值;
  • 函数名与变量名的命名规则相同;
  • 函数名应与文件名相同;
  • 自编函数不要与内部函数重名,否则极易引起错误;
  • MATLAB有搜索路径限制,应把自编函数保存到搜索路径下。

【例】编写函数,对于指定的m,求使得成立的最大的正整数n和相应的y值。

function [n,y] = SumLeq(m)
% 令 y = 1^2 + 2^2 + ... + n^2,
% 求使得 y <= m 的最大的n和相应的y。
y = 0;
i = 0;
while y <= m
 i = i + 1;
 y = y + i^2;
end
n = i-1;
y = y-i^2;

函数调用方法:

>> [n,y] = SumLeq(3000)

1.3. 匿名函数(在命令窗口或脚本文件中编辑)

1. 定义格式

匿名函数由@符引导建立,其定义格式为:

       f = @ (arg1,arg2,...) expr

2. 调用格式

匿名函数的调用格式为:

       y=f(arg1,arg2,...)

【例】建立匿名函数,并求其在处的函数值。

匿名函数程序如下:

>> fun1 = @(x,y) cos(x).*sin(y)
>> x = [0,1,2];
>> y = [-1,0,1];
>> z = fun1(x,y)

【例】根据下面函数表达式编写匿名函数,

并计算函数在处的函数值。

本例程序如下:

>> fun2 = @(x)(x>=-1 & x<0).*sin(pi*x.^2)+(x>=0).*exp(1-x);
>> fun2([-0.5,0,0.5])

1.4. 嵌套函数

把一个或多个子函数放到同一个主函数的函数体内部而构成的函数称为嵌套函数。像循环的嵌套一样,嵌套函数可以是一层嵌套,也可以是多层嵌套,其一般形式如下。

【例】通过嵌套函数的方式编写函数。

function y = mainfun(x)
% 通过嵌套函数的方式编写函数
y = subfun1(x) + subfun2(x);
    % 子函数1
    function y1 = subfun1(x1)
        y1 = (x1 + 1)^2;
    end
    % 子函数2
    function y2 = subfun2(x2)
        y2 = exp(x2);
    end
y = subfun3(y);
end
%%------------------------------------------
%  子函数3
%%------------------------------------------
function y = subfun3(x)
y = sqrt(x) - 1;
end

函数的递归调用

【例】生成斐波那契数列的第 n 项。

function  y = fibonacci(n)
% 生成斐波那契数列的第n项
if (n < 0) | (round(n) ~= n) | ~isscalar(n)
    warning('输入参数应为非负整数标量');
    y = [];
    return;
elseif n < 2
    y = n;
else
    y = fibonacci(n-2)+fibonacci(n-1);
end

2. M文件

MATLAB命令有两种执行方式:命令执行方式M文件执行方式。

  • 命令执行方式:操作简单和直观,但速度慢,命令语句保留,不便今后查看和调用;
  • M文件:编程方便,便于今后查看和调用,适用于复杂问题的编程。

2.1. M文件的分类和特点

  • M脚本文件(Script File)和M函数文件(Function File)。

(1)M脚本文件一般由若干MATLAB命令和函数组合在一起,可以完成某些操作,实现特定功能。

(2) M函数文件是为了完成某个任务,将文件定义成一个函数。

  • 两种文件主要区别是:

(1)M脚本文件按照命令先后顺序编写,而M函数文件第一行必须是以function开头的函数声明行;

(2)M脚本文件没有输入参数和返回输出参数,而M函数文件可以带有输入参数和返回输出参数;

(3)M脚本文件执行完后,变量结果返回到工作空间,而函数文件定义的变量为局部变量,当函数文件执行完,这些变量不会存在工作空间。

(4)M脚本文件可以按照程序中命令先后顺序直接运行,而函数文件一般不能直接运行,需要定义输入参数,使用函数调用方式来调用它

2.2. M文件的创建和打开

1. 创建新的M文件

M文件可以用MATLAB文件编辑器来创建。

(1) 创建M脚本文件

  • 创建M脚本文件,可以从MATLAB主窗口的主页下,点击“新建脚本”
  • 选择“新建菜单”,再选择“脚本”,就能打开脚本文件编辑器窗口。

(2)创建M函数文件

创建M函数文件,可以从MATLAB主窗口的主页下,选择“新建菜单”,再选择“函数”,就能打开函数文件编辑器窗口,具体格式在下一节详细介绍。

创建M文件,还可以在MATLAB命令窗口输入命令edit,启动MATLAB文件编辑窗口后,输入文件内容后保存。

2. 打开已创建的M文件

在MATLAB语言中,打开已有的M文件有下面两种方法:

(1)菜单操作

打开已有的M函数文件,可以从MATLAB主窗口的主页下,选择“打开”,在打开窗口选择文件路径,选中M文件,点击“打开”按钮。

(2)命令操作

另外,还可以在MATLAB命令窗口输入命令:edit 文件名,就能打开已有的M文件。对打开的M文件可以进行编辑和修改,然后再存盘。

【例】建立一个M脚本文件,已知圆的半径,求圆的周长和面积。

在文件编辑窗口编写命令文件,保存脚本文件。

clear
r=5;
S=pi*r*r
P=2*pi*r
>> 
S =
   78.5398
P =
   31.4159

3. M函数文件

3.1. M函数文件的格式

function [ output_args ] = Untitled4( input_args )
%UNTITLED4 此处显示有关此函数的摘要
% 此处显示详细说明
函数体语句
end

其中,以function开头的这行,为函数声明行,是必不可少的,表示该M文件是一个函数文件。Untitled4为函数名,函数名的命名规则和变量名相同。input_args为函数的输入形参数列表,多个参数间用“,”分隔,用圆括号括起来。output_args为函数的输出形参数列表,多个参数间用“,”分隔,当输出参数两个或两个以上时,用方括号括起来。

注意:

(1)M函数文件名和声明行中的函数名最好相同,以免出错。如果不同时,MATLAB将忽略函数名而使用函数文件名,调用时使用函数文件名。

(2)注释说明要以%开头,第一注释行一般包括大写的函数文件名和函数功能信息,可以提供lookfor和help命令查询使用。第二及以后注释行为帮助文本,提供M函数文件更加详细的说明信息,通常包括函数的功能,输入和输出参数的含义,调用格式说明,以及版权信息,便于M文件查询和管理。

【例】建立一个M函数文件,已知圆的半径,求圆的周长和面积。在文件编辑窗口编写函数文件,保存脚本文件。

function [ S,P ] = fexam_3_13(r)
%FEXAM_3_13  calculates the area and perimeter of a circle of radii r
% r:圆半径,  S:圆面积,  P:圆周长
% 2023-3-3
S=pi*r*r;
P=2*pi*r;
end
在命令空间调用该函数fexam_3_13.m,结果为:
>> r=5;
>> [X,Y]=fexam_3_13(r)
X =   78.5398
Y =   31.4159

3.2. M函数文件的调用

  • 可以在命令窗口或者M脚本文件中调用M函数文件。函数调用的一般格式是:
[输出实参数列表]=函数名(输入实参数列表)
  • 需要注意,函数调用时各实参数列表出现的顺序和个数,应与函数定义时的形参数列表的顺序和个数一致,否则会出错。函数调用时,先将输入实参数传送给相应的形参数,然后再执行函数,函数将输出形参数传送给输出实参数,从而实现参数的传递。

【例】编写函数文件,实现极坐标(与直角坐标(x,y)之间的转换。已知转换公式为:

函数文件ftran.m:

function [ x,y ] = ftran( rho,thetha )
%极坐标转化为直角坐标
x=rho*cos(thetha);
y=rho*sin(thetha);
end
% 在命令窗口可以直接调用函数文件ftran.m:
>>rho=4;
>>thetha=pi/3;
>> [xx,yy]=ftran(rho,thetha)
xx =    2.0000
yy =3.4641

2.两种调用函数文件

在命令窗口直接调用函数文件ftran.m:

>>rho=4;
>>thetha=pi/3;
>> [xx,yy]=ftran(rho,thetha)
xx =   2.0000
yy =   3.4641
也可以编写调用函数文件ftran.m的M脚本文件
rho=4;
thetha=pi/3;
[xx,yy]=ftran(rho,thetha)
结果如下:
>>  
xx =    2.0000
yy =    3.4641

3.3. 主函数和子函数

1.主函数

在MATLAB中,一个M文件可以包含一个或者多个函数,但只能有一个主函数,主函数一般出现在文件最上方的函数,主函数名与M函数文件名相同。

2.子函数

在一个M函数文件中若有多个函数,则除了第一个主函数以外,其余函数都是子涵数。子函数的说明如下:

(1)子函数只能被同一文件中的函数调用,不能被其他文件调用。

(2)各子函数的次序没有限制

(3)同一文件的主函数和子函数工作空间是不同的。

【例】分段函数如下所示,编写M函数文件,使用主函数调用三个子函数y1,y2,y3的方式,实现分段函数相应曲线绘制的任务,其中,a、b和c分别从屏幕输入1、2和3。

function y = exam_3_16(z)
% 分段曲线的绘制
% z画哪条曲线
% y函数的值
a=input('请输入a:)
b=input('请输入b:')
c=input('请输入c:')
x=-3:0.1:3
if z==1
 y=y1(x,a,b,c);
elseif z==2
 y=y2(x,a,b);
elseif z==3
 y=y3(x,a,b);
end
xlabel('x')
ylabel('y')
function y=y1(x,a,b,c)
% z=1,画ax^2+bx+c的曲线
y=a*x.*x+b*x+c;
plot(x,y)
title('a*x.*x+b*x+c')
end
function y=y2(x,a,b)
%z=2,画a*sin(x)+b的曲线
y=a*sin(x)+b;
plot(x,y)
title('y=a*sin(x)+b')
end
function y=y3(x,a,b)
%z=3,画ln|a+b/x|的曲线
y=log(abs(a+b./x));
plot(x,y)
title('log(abs(a+b./x))')
end
end

3.4. 函数的参数

1.参数的传递

函数的参数传递是将主函数中的变量值传送给被调函数的输入参数,被调函数执行后,将结果通过被调函数的输出参数传送给主函数的变量。

2.参数的个数

MATLAB语言提供nargin和nargout函数获得实际调用时函数的输入和输出参数的个数。还可以用varagrin和varargout函数获得输入和输出参数的内容。

(1)nargin和nargout函数可以分别获得函数的输入和输出参数的个数。函数格式如下:

x=nargin('fun')
y=nargout('fun')

其中fun是函数名,x是函数的输入参数个数,y是函数的输出参数个数。当nargin和nargout在函数体内时,fun可以省略。

(2)MATLAB提供了varagrin和varargout函数,将函数调用时,实际传递的参数构成元胞数组,通过访问元胞数组中个元素的内容来获得输入和输出变量。

varagrin 和varargout函数的格式如下:

function y=fun(varargin)  %输入参数为varargin的函数fun
function varargout=fun(x) %输出参数为varargout的函数fun

3.5. 函数的变量

MATLAB的函数变量根据作用范围,可以分为局部变量和全局变量。

1.局部变量

局部变量(Local Variables)的作用范围是函数的内部,函数内部的变量如果没有特别声明,都是局部变量。都有自己的函数工作空间,与MATLAB工作空间是独立的,局部变量仅在函数内部执行时存在,当函数执行完,变量就消失。

2.全局变量

全局变量(Global Variables)的作用范围是全局的,可以在不同的函数和MATLAB工作空间中共享。使用全局变量可以减少参数的传递,有效地提高程序的执行效率。

全局变量在使用前必须用“global”命令声明,而且每个要共享的全局变量的函数和工作空间,都必须逐个使用“global”对该变量声明。

global 变量名

要清除全局变量可以用clear命令,命令格式如下:

clear global 变量名                %清除某个全局变量
clear global                      %清除所有的全局变量

【例】利用在工作空间和函数文件中定义全局变量,将直角坐标变为极坐标。

function [ rho,thetha ] = exam_3( )
%   exam_3利用定义全局变量求极坐标
%   rho为极坐标的半径thetha为极坐标的极角
global a b
rho=sqrt(a^2+b^2);
thetha=atan(b/a);
end
在命令空间输入下面命令,调用函数exam_3,结果如下:
>>global a b
>> a=1;
>> b=2;
[r,t]=exam_3
r =    2.2361
t =    1.1071

4. 程序调试

4.1. 命令窗口调试

MATLAB在命令窗口运行语句,或者运行M文件时,会在命令窗口提示错误信息。一般有两类错误:一类是语法错误,另一类是程序逻辑错误。

1.语法错误

语法错误一般包括文法或词法的错误,例如表达式书写错误、函数的拼写错误等。MATLAB能够自己检查出大部分的语法错误,给出相应的错误提示信息,并标出错误在程序中的行号,通过分析MATLAB给出的错误信息,不难排除程序代码中的语法错误。

2.程序逻辑错误

程序逻辑错误是指程序运行结果有错误,MATLAB系统对逻辑错误是不能检测和发现的。这时需要通过一些调试手段来发现程序中的逻辑错误,可以通过获取中间结果的方式来获得错误可能发生的程序段。采取的方法是:

(1)可以将程序中间一些结果输出到命令窗口,从而确定错误的区断。命令语句后的分号去掉,就能输出语句的结果。或者用注释%,放置在一些语句前,就能忽略这些语句的作用。逐步测试,找到逻辑错误可能出现的程序区段了。

(2)使用MATLAB的调试菜单(debug)调试。通过设置断点、控制程序单步运行等操作。

4.2. MATLAB菜单调试

  • MATLAB的文件编辑器除了能编辑,修改M文件之外,还能对程序菜单调试。
  • 通过调试菜单可以查看和修改函数工作空间中的变量,找到运行的错误。
  • 调试菜单提供设置断点,可以使得程序运行到某一行暂停运行,可以查看工作空间中的变量值,来判断断点之前语句逻辑是否正确。还可以通过调试菜单可以一行一行地运行程序,逐行检查和判断程序是否正确。
  • MATLAB调试菜单界面上有“断点”选项,该选项下有四种命令:

(1)全部清除 清除所有文件中的全部断点

(2)设置/清除 设置或清除当前行上的断点

(3)启用/禁止 启用或者禁止当前行上的断点

(4)设置条件 设置或修改条件断点

在程序某行设置断点后,程序运行到该行,就暂停下来,并在命令窗口显示:K>>,可以在K>>后输入变量名,就能显示变量的值,从而,可以分析和检查前面程序是否正确。然后可以点击调试菜单的“继续”选项,在下个断点处有暂停,这时又可以输入变量名,检查变量的值。如此重复,直到发现程序问题为止。

4.3. MATLAB调试函数

MATLAB调试程序还可以利用调试函数,如下表所示:

表 MATLAB常用调试函数

调试函数名 功能和作用 调试函数名 功能和作用
dbstop 用于在M文件中设置断点 dbstep 从断点处继续执行M文件
dbstatus 显示断点信息 dbstack 显示M文件执行时调用的堆栈等
dbtype 显示M文件文本(包括行号) dbup/dbdown 实现工作空间的切换

表中的各个调试函数的功能和作用和菜单调试用法类似,具体使用方法可以用MATLAB的帮助命令help查询。

5. 应用实例

一个典型的二阶电路系统的阶跃响应分三种情况:欠阻尼,临界阻尼和过阻尼,如下面公式所示。编写M函数文件,使用主函数调用三个子函数y1,y2,y3的方式,完成根据阻尼系数绘制下列二阶系统的阶跃输入时域相应曲线的任务。

function  y  = exam_3_19( zeta )
% 二阶系统的阶跃时间响应
%   zeta阻尼系数
%   y阶跃响应
t=0:0.1:30;
if(zeta>=0)&(zeta<1)
    y=y1(zeta,t);
elseif zeta==1
    y=y2(zeta,t);
else
    y=y3(zeta,t);
end
plot(t,y)
title(['The second order response of zeta=',num2str(zeta)])
xlabel('time(t)')
ylabel('response(y)')
function y=y1(zeta,t)
%阻尼系数0<zeta<1的二阶系统阶跃响应   
 y=1-1/sqrt(1-zeta^2)*exp(-zeta*t).*sin(sqrt(1-zeta^2)*t+atan(sqrt(1-zeta^2)/zeta));
end
function y=y2(zeta,t)
%阻尼系数zeta=1的二阶系统阶跃响应
 y=1-exp(-zeta*t).*(1+t);
end
function y=y3(zeta,t)
%阻尼系数zeta>1的二阶系统阶跃响应
sq=sqrt(zeta^2-1);        
y=1-1/(2*(1-zeta^2+zeta*sq))*exp(-(zeta-sq)*t)-1/(2*(1-zeta^2-zeta*sq))*exp(-(zeta+sq)*t);
end
end

旅客乘车旅行,可免费携带30公斤行李,超过30公斤需要支付每公斤10元,超过50公斤部分则每公斤需要支付20元托运费,编程根据每位旅客行李重量计算其应付的行李托运费。

w=input('please input the weight of passenger baggage(kg):');
if w<=30;
 disp('free');
end
if w>30 & w<=50;
 cost=(w-30)*10;
 disp('the cost is,' ),disp(cost), disp( 'yuan')
end
if w>50;
 cost=(w-50)*20+200;
 disp('the cost is,' ),disp(cost),disp( 'yuan')
end
Copyright © ZHOUWEN all right reserved,powered by GitbookLatest updated: 2023-03-18 23:37:42

results matching ""

    No results matching ""

    results matching ""

      No results matching ""