(仅供参考)Matlab编写与调用函数

(仅供参考)Matlab编写与调用函数
(仅供参考)Matlab编写与调用函数

MATLAB 学习指南

第六章.编写与调用函数

在这一章中,我们讨论如何用多源代码文件来构造一个程序。首先,解释代码文件在MATLAB中如何工作。在编译语言中,例如FORTRAN,C ,或C++,代码被存储在一个或多个源文件中,在进行编译的时候,这些源文件组合在一起

形成了一个单独的可执行文件。作为一种解释型语言,MATLAB以一种更广泛的方式来处理多个源文件。MATLAB代码被放入带有扩展名.m的ASCII文件(或称m-文件)中。MATLAB 6 有一个集成字处理与调试应用程序,尽管会用到其它编辑程序如vi或emacs,集成字处理与调试应用程序仍是编译m-文件的首选程序。

有两种不同的m-文件。一种是脚本文件,它是一种最简单的文件,仅仅将MATLAB中的指令收集在一起。当在交互提示符处输入文件名执行脚本文件时,MATLAB在m-文件内读取并执行指令,就好像指令是我们输入的。而且,似乎我们能够削减m-文件的内容并将削减过的内容传到MATLAB指令窗口中。这种m-文件的用法将在6.1节中给予概述。

在6.2节中要讨论的第二种m-文件包含一个单一函数,此函数名与此m-文件名相同。这种m-文件包含一段独立的代码,这段代码具有一个明确规定的输入/输出界面;那就是说,传给这段代码一列空变量arg1,arg2,…,这段独立代码就能够被调用,然后返回输出值out1,out2,…。一个函数m-文件的第一个非注释行包含函数标头,其形式如下:

此m-文件以返回指令结束,将执行程序返回到函数被调用的位置。或者在交互指令提示符处或者在另一个m-文件内,无论何时用下列指令调用函数代码,函数代码都将被执行。

输入映射到空变量:arg1=var1,arg2=var2,等等。在函数主体内,输出值被分配给了变量out1,out2,等等。当遇到返回值时,当前值out1,out2,…在函数被调用处被映射到变量outvar1,outvar2,…。在用可变长度自变量和输出变量列表编写函数时,MATLAB允许更多的自由。例如,也可以使用下列指令来调用函数。

在此情况下,仅返回一个单一输出变量,这个变量在出口处包含函数变量out1的值。输入和输出自变量可能是字符串,数值,向量,矩阵,或者更高级的数据结构。

为什么使用函数呢?因为从每门计算机科学课程中可知,把一个大的程序分割

成多个可以单独执行一个被明确规定的和被注释过的任务的小程序会使大程序

易读,易于修改,不易于出错。在MATLAB中,先为程序编写一个主文件,或者是一个脚本文件或者更好的话,是一个能够返回一个单一整数的函数m-文件(返回1表示程序执行成功,0表示不完全程序执行,负值表示出现运行误差),这个主文件是程序的进入点。通过把m-文件当作函数来调用,此程序文件可以

调用其它m-文件中的代码。但是,如果没有编译过程将所有的源代码文件结合起来,当一个函数被调用时,MATLAB又怎能知道去哪找这个函数呢?

MATLAB的程序内存包含一个搜索路径列表,使用指令path可以查看列表的内容,此列表存储目录名,包括包含函数m-文件的目录名。起初,路径仅将包含MATLAB内部函数如sin(),exp(),…的目录编入列表。正如6.2节中所证明的那样,使用指令addpath便可向此列表中添加包含用于当前计划的m-文件的每一个目录名。然后,当MATLAB代码解释程序遇到一个函数时,比如说带有文件名filename的函数,此代码解释程序便开始从路径列表的最顶端开始一直向下搜索目录,寻找一个文件filename.m。当找到后,MATLAB代码解释程序便以上述方式执行此文件的代码。由于这个原因,m-文件的文件名必须要和函数名相一致;事实上,只需要考虑文件名。

6.1. 编写与运行m-文件

尽管MATLAB可以从命令行开始被交互运行,通过建立一个文本文件,你能够编写一个MATLAB程序。此文本文件包含你希望MATLAB执行的指令,这些指令是按照它们出现在文件中的顺序被执行的。包含MATLAB程序的文本文件的标准文件扩展名为.m。在MATLAB指令窗口中,选择下拉菜单File->New->M-file 打开集成MATLAB文本编辑程序来编写一个m-文件。此实用软件与文字处理软件非常相似,所以对于编写和保存m-文件的用处这里就不做具体解释了。

举个例子,把此节作为一个文件“MATLAB_tutorial_c6s1.m”,这个文件仅有下列可执行指令。

通过输入文件名,我们可从提示符处运行这一m-文件

如果现在输入“whos”,我们可以看到,在程序末端存储在内存中的变量在运行完m-文件后仍然存储在内存中。这是因为我们已经把m-文件编写为一个脚本文件,在脚本文件中,我们只是将一个文件中的若干指令收集在一起,然后,当脚本文件运行时,代码会逐一执行这些指令。这就好像是我们把指令输入到了交互对话窗口。m-文件更普遍的应用是隔离一个独立函数中的一系列指令,这将在下一节中得到解释。

6.2. 带有函数的结构化程序设计

非结构化程序方法

在这一节中,我们将会论证子程序的应用:编写结构化的,条理清晰的程序。我们使用一个极其简单和熟悉的例子,就是我们在4.1节中遇到的简单的一维PDE问题。首先,在这个m-文件中,我们可以使用一个程序来解决这个问题,此程序能把所有的指令结合到一个文件中。这个“非结构化”的方法对于非常小的程序来说是很合适的,但随着程序规模的扩大,这一方法很快就会使程序变得混乱。

我们现在设定使用Dirichlet边界条件离散PDE的矩阵的值。

设定数值

接下来,我们设定每个边界处的函数值。

我们现在创造一个关于问题右边的向量。

现在,我们调用标准MATLAB解算程序。

然后,我们将结果制图。

尽管把所有指令结合在一起的方法对小程序很适用,但对于大程序却变得很不

实用。

结构化程序设计方法

注意:在运行此文件之前,其它包含子程序的m-文件必须已经存在。

首先,我们定义点数

我们现在创造一个包含格点的向量。

在MATLAB中,每个函数都被存储在相同文件名的不同m-文件中。当你在交互对话提示符处或者另一个脚本或函数m-文件中调用函数时,MATLAB会在包含函数的一列目录中进行搜索,直到找到文件名合适的m-文件。然后,函数执行包含在所找到的m-文件内的MATLAB代码。当我们编写包含函数的m-文件时,在我们使用m-文件之前,我们必须告诉MATLAB它们在哪;那就是说,我们必须将m-文件的目录名增加到搜索途径中。

使用指令“path”,我们可以查看搜索途径当前的内容。

指令“pwd”返回到当前目录。

我们使用指令“addpath”将带有子程序的目录加入到这一搜索列表中。使用“rmpath”可将目录移出列表。

下列函数可以计算矩阵A的值。函数调用的语句结构如下:[out1,out2,…]

=func_name(in1,in2,…),其中输入自变量是in1,in2,…函数的输出被存储在out1,out2,…。在这里,输入变量是矩阵A的维数,num_pts,输出变量是A和iflag,一个整数可以告诉我们是否代码被成功地执行。

从以下代码也可以看到函数中的局部变量i的存在对于改变调用点i的值毫无影响。

接下来,我们要求使用者输入边界处的函数值。

我们现在调用可以计算RHS向量值的另一个子程序。

我们现在对系统求解。

然后,我们将输出结果制图。

最后,清空内存。

m-文件的第一可执行行使用“function”指令来声明子程序名和子程序的输入/输出结构。

如果Ndim<1,出现错误,因为矩阵的维数不能小于1。

如果(Ndim<1)代表错误

我们返回m-文件的控制权,这个m-文件未执行余下代码便调用了此子程序。

首先,我们使用稀疏矩阵格式来声明A。

我们为b_RHS分配空间并将它初始化使其值等于零。

现在,我们具体指定从边界条件中得到的第一个和最后一个分量。

接着,我们具体指定内部点。

6.3. 直接插入函数

有时,我们不想单独编写m-文件来定义一个函数,因为这样做很麻烦,所以,我们定义了一个直接插入函数。我们想要定义函数

我们使用下式来定义此函数

然后,我们直接调用这个函数

我们也可以使用向量和矩阵作为输入变量来定义函数。

输入下面的函数名便可查看函数的定义

尽管这很方便,但是直接插入函数的执行速度却很慢。

6.4. 作为函数自变量的函数

列于下方的函数,trig_func_1,在a,b和x的值给定的情况下,能够返回函数f(x)=a*sin(x)+b*cos(x)的值。

列于下方的函数,plot_trig_1,能在定义域0到2*pi上将函数绘图。

下列代码要求使用者输入a和b的值,然后,通过将函数名作为一个自变量包含在列表中来使用plot_trig对trig_func_1作图。

确保当前的方向处在正确的路径上

首先,在0到2*pi上创造一个向量

接下来,创造一个函数值向量,使用“feval”指令,我们可以间接地求自变量函数的值。

然后,作图。

相关主题
相关文档
最新文档