第8章M文件函数 使用 MATLAB函数时,例如inw,abs,ange和sqrt, MATLAB获取传递给它的变量, 利用所给的输入,计算所要求的结果。然后,把这些结果返回。由函数执行的命令,以及由 这些命令所创建的中间变量,都是隐含的。所有可见的东西是输入和输出,也就是说函数是 一个黑箱 这些属性使得函数成为强有力的工具,用以计算命令。这些命令包括在求解一些大的问 题时,经常出现的有用的数学函数或命令序列。由于这个强大的功能, MATLAB提供了 个创建用户函数的结构,并以M文件的文本形式存储在计算机上。 MATLAB函数 flipper是 一个M文件函数良好的例子。 FLIPLR Flip matrix in the left/right direction FLIPLR(X) returns X with row preserved and columns flipped in the left/right direction X=l 2 3 becomes 3 2 1 456 654 See also FLIPUD. ROt90 %o Copyright(c)1984-94 by The Math Works, Inc Im, n]=size(x) 1) 一个函数M文件与脚本文件类似之处在于它们都是一个有m扩展名的文本文件。如同 脚本M文件一样,函数M文件不进入命令窗口,而是由文本编辑器所创建的外部文本文件 一个函数的M文件与脚本文件在通信方面是不同的。函数与 MATLAB工作空间之间的通 信,只通过传递给它的变量和通过它所创建的输出变量。在函数内中间变量不出现在 MATLAB工作空间,或与 MATLAB工作空间不交互。正如上面的例子所看到的,一个 数的M文件的第一行把M文件定义为一个函数,并指定它的名字。它与文件名相同,但没 有m扩展名。它也定义了它的输入和输出变量。接下来的注释行是所展示的文本,它与帮 助命令: help fliplr相对应。第一行帮助行称为Hl行,是由 lookfor命令所搜索的行。 最后,M文件的其余部分包含了 MATLAB创建输出变量的命令。 8.1规则和属性
第 8 章 M 文 件 函 数 使用 MATLAB 函数时,例如 inv, abs, angle 和 sqrt,MATLAB 获取传递给它的变量, 利用所给的输入,计算所要求的结果。然后,把这些结果返回。由函数执行的命令,以及由 这些命令所创建的中间变量,都是隐含的。所有可见的东西是输入和输出,也就是说函数是 一个黑箱。 这些属性使得函数成为强有力的工具,用以计算命令。这些命令包括在求解一些大的问 题时,经常出现的有用的数学函数或命令序列。由于这个强大的功能,MATLAB 提供了一 个创建用户函数的结构,并以 M 文件的文本形式存储在计算机上。MATLAB 函数 fliplr 是 一个 M 文件函数良好的例子。 function y = fliplr(x) % FLIPLRFlip matrix in the left/right direction. % FLIPLR(X) returns X with row preserved and columns flipped % in the left/right direction. % % X = 1 2 3 becomes 3 2 1 % 4 5 6 6 5 4 % % See also FLIPUD, ROT90. % Copyright (c) 1984-94 by The MathWorks, Inc. [m, n] = size(x); y = x(: , n : -1 : 1); 一个函数 M 文件与脚本文件类似之处在于它们都是一个有.m 扩展名的文本文件。如同 脚本 M 文件一样,函数 M 文件不进入命令窗口,而是由文本编辑器所创建的外部文本文件。 一个函数的 M 文件与脚本文件在通信方面是不同的。函数与 MATLAB 工作空间之间的通 信,只通过传递给它的变量和通过它所创建的输出变量。在函数内中间变量不出现在 MATLAB 工作空间,或与 MATLAB 工作空间不交互。正如上面的例子所看到的,一个函 数的 M 文件的第一行把 M 文件定义为一个函数,并指定它的名字。它与文件名相同,但没 有.m 扩展名。它也定义了它的输入和输出变量。接下来的注释行是所展示的文本,它与帮 助命令: » help fliplr 相对应。第一行帮助行称为 H1 行,是由 lookfor 命令所搜索的行。 最后,M 文件的其余部分包含了 MATLAB 创建输出变量的命令。 8.1 规则和属性
M文件函数必须遵循以下特定的规则。除此之外,它们有许多的重要属性。包括: 函数名和文件名必须相同。例如,函数 fliplr存储在名为 fliplr.m文件中 2. MATLAB头一次执行一个M文件函数时,它打开相应的文本文件并将命令编辑成 存储器的内部表示,以加速执行以后所有的调用。如果函数包含了对其它M文件函数的引 用,它们也同样被编译到存储器。普通的脚本M文件不被编译,即使它们是从函数M文件 内调用;打开脚本M文件,调用一次就逐行进行注释 3.在函数M文件中,到第一个非注释行为止的注释行是帮助文本。当需要帮助时, 返回该文本。例如,) help fliplr返回上述前八行注释 4.第一行帮助行,名为Hl行,是由 lookfor命令搜索的行。 5.函数可以有零个或更多个输入参量。函数可以有零个或更多个输出参量 6.函数可以按少于函数M文件中所规定的输入和输出变量进行调用,但不能用多于 函数M文件中所规定的输入和输出变量数目。如果输入和输出变量数目多于函数M文件中 function语句一开始所规定的数目,则调用时自动返回一个错误。 7.当函数有一个以上输出变量时,输出变量包含在括号内。例如,ⅣV,D=eig(A)。不 要把这个句法与等号右边的V,D相混淆。右边的V,D|是由数组V和D所组成 8.当调用一个函数时,所用的输入和输出的参量的数目,在函数内是规定好的。函数 工作空间变量 nargin包含输入参量个数:;函数工作空间变量 nargout包含输出参量个数 事实上,这些变量常用来设置缺省输入变量,并决定用户所希望的输出变量。例如,考虑 MATLAB函数 linspace functiony =linspace(dl, d2, n) LINSPACE Linearly spaced vector LINSPACE(xl, x2) generates a row vector of 100 linearly equally spaced points between xl and x2 LINSPACE(xl, X2, N) generates N points between xl and x2 See also LOGSPACE %o Copyright(c)1984-94 by The Math Works, Inc if nargin= 2 dl+(0.n-2)+(d2-dl)/(n-1)d2] 这里,如果用户只用两个输入参量调用 linspace,例如 linspace(0,10), linspace产生 100个数据点。相反,如果输入参量的个数是3,例如, linspace(0,10,50),第三个参量决定 数据点的个数。 可用一个或两个输出参量调用的函数的一个例子是 MATLAB函数size。尽管这个函数 不是一个M文件函数(它是一个内置函数),sie函数的帮助文本说明了它的输出参量的选择
M 文件函数必须遵循以下特定的规则。除此之外,它们有许多的重要属性。包括: 1. 函数名和文件名必须相同。例如,函数 fliplr 存储在名为 fliplr.m 文件中。 2. MATLAB 头一次执行一个 M 文件函数时,它打开相应的文本文件并将命令编辑成 存储器的内部表示,以加速执行以后所有的调用。如果函数包含了对其它 M 文件函数的引 用,它们也同样被编译到存储器。普通的脚本 M 文件不被编译,即使它们是从函数 M 文件 内调用;打开脚本 M 文件,调用一次就逐行进行注释。 3. 在函数 M 文件中,到第一个非注释行为止的注释行是帮助文本。当需要帮助时, 返回该文本。例如, » help fliplr 返回上述前八行注释。 4. 第一行帮助行,名为 H1 行,是由 lookfor 命令搜索的行。 5. 函数可以有零个或更多个输入参量。函数可以有零个或更多个输出参量。 6. 函数可以按少于函数 M 文件中所规定的输入和输出变量进行调用,但不能用多于 函数 M 文件中所规定的输入和输出变量数目。如果输入和输出变量数目多于函数 M 文件中 function 语句一开始所规定的数目,则调用时自动返回一个错误。 7. 当函数有一个以上输出变量时,输出变量包含在括号内。例如,[V,D] = eig(A)。不 要把这个句法与等号右边的[V,D] 相混淆。右边的[V,D] 是由数组 V 和 D 所组成。 8. 当调用一个函数时,所用的输入和输出的参量的数目,在函数内是规定好的。函数 工作空间变量 nargin 包含输入参量个数;函数工作空间变量 nargout 包含输出参量个数。 事实上,这些变量常用来设置缺省输入变量,并决定用户所希望的输出变量。例如,考虑 MATLAB 函数 linspace : function y = linspace(d1, d2, n) % LINSPACE Linearly spaced vector. % LINSPACE(x1, x2) generates a row vector of 100 linearly % equally spaced points between x1 and x2. % LINSPACE(x1, x2, N) generates N points between x1 and x2. % % See also LOGSPACE, :. % Copyright (c) 1984-94 by The MathWorks, Inc. if nargin == 2 n = 100; end y = [d1+(0:n-2)*(d2-d1)/(n-1) d2] ; 这里,如果用户只用两个输入参量调用 linspace ,例如 linspace(0,10) ,linspace 产生 100 个数据点。相反,如果输入参量的个数是 3,例如,linspace(0,10,50),第三个参量决定 数据点的个数。 可用一个或两个输出参量调用的函数的一个例子是 MATLAB 函数 size。尽管这个函数 不是一个M文件函数(它是一个内置函数),size函数的帮助文本说明了它的输出参量的选择
SIZE Matrix dimensions D= SIZE(X), for M-by-N matrix X, returns the two-element row vector D=[M, N containing the number of rows and columns in the matrix M,N=SIZE(X)returns the number of rows and columns in separate output variables 如果函数仅用一个输出参量调用,就返回一个二元素的行,它包含行数和列数。相反, 如果出现两个输出参量,size分别返回行和列。在M文件函数里,变量 nargout可用来检 验输出参量的个数,并按要求修正输出变量的创建。 9.当一个函数说明一个或多个输出变量,但没有要求输出时,就简单地不给输出变量 赋任何值。 MATLAB函数toc阐明了这个属性 unction t= toc TOC Read the stopwatch timer TOC, by itself, pri t=TOC, saves the elapsed time in t, instead of printing it out See also TIC, ETIME, CLOCK, CPUTIME Copyright(c)1984-94 by The Math Works, Inc TOC uses EtiMe and the value of clocK saved by tic global TICTOC if nargout<I elapsed time = etime(clock, TICTOC) t= etime(clock, TICTOC) 如果用户用不以输出参量调用toc,例如,》toc,就不指定输出变量t的值,函数在 命令窗口显示函数工作空间变量 elapsed time,但在 MATLAB工作空间里不创建变量。相 反,如果toc是以》 out=toc调用,则按变量out将消逝的时间返回到命令窗口。 10.函数有它们自己的专用工作空间,它与 MATLAB的工作空间分开。函数内变量与 MATLAB工作空间之间唯一的联系是函数的输入和输出变量。如果函数任一输入变量值发 生变化,其变化仅在函数内出现,不影响 MATLAB工作空间的变量。函数内所创建的变量 只驻留在函数的工作空间,而且只在函数执行期间临时存在,以后就消失。因此,从一个调 用到下一个调用,在函数工作空间变量存储信息是不可能的。(然而,如下所述,使用全局 变量就提供这个特征。) 11.如果一个预定的变量,例如,pi,在 MATLAB工作空间重新定义,它不会延伸
SIZE Matrix dimensions. D = SIZE(X), for M-by-N matrix X, returns the two-element row vector D = [M, N] containing the number of rows and columns in the matrix. [M, N] = SIZE(X) returns the number of rows and columns in separate output variables. 如果函数仅用一个输出参量调用,就返回一个二元素的行,它包含行数和列数。相反, 如果出现两个输出参量,size 分别返回行和列。在 M 文件函数里,变量 nargout 可用来检 验输出参量的个数,并按要求修正输出变量的创建。 9. 当一个函数说明一个或多个输出变量,但没有要求输出时,就简单地不给输出变量 赋任何值。MATLAB 函数 toc 阐明了这个属性。 function t = toc % TOC Read the stopwatch timer. % TOC, by itself, prints the elapsed time since TIC was used. % t = TOC; saves the elapsed time in t, instead of printing it out. % % See also TIC, ETIME, CLOCK, CPUTIME. % Copyright (c) 1984-94 by The MathWorks, Inc. % TOC uses ETIME and the value of CLOCK saved by TIC. global TICTOC if nargout < 1 elapsed_time = etime(clock, TICTOC) else t = etime(clock, TICTOC); end 如果用户用不以输出参量调用 toc ,例如, » toc,就不指定输出变量 t 的值,函数在 命令窗口显示函数工作空间变量 elapsed_time ,但在 MATLAB 工作空间里不创建变量。相 反,如果 toc 是以 » out=toc 调用,则按变量 out 将消逝的时间返回到命令窗口。 10. 函数有它们自己的专用工作空间,它与 MATLAB 的工作空间分开。函数内变量与 MATLAB 工作空间之间唯一的联系是函数的输入和输出变量。如果函数任一输入变量值发 生变化,其变化仅在函数内出现,不影响 MATLAB 工作空间的变量。函数内所创建的变量 只驻留在函数的工作空间,而且只在函数执行期间临时存在,以后就消失。因此,从一个调 用到下一个调用,在函数工作空间变量存储信息是不可能的。(然而,如下所述,使用全局 变量就提供这个特征。) 11. 如果一个预定的变量,例如,pi, 在 MATLAB 工作空间重新定义,它不会延伸
到函数的工作空间。逆向有同样的属性,即函数内的重新定义变量不会延伸到 MATLAB的 工作空间中。 12.当调用一个函数时,输入变量不会拷贝到函数的工作空间,但使它们的值在函数 内可读。然而,改变输入变量内的任何值,那么数组就拷贝到函数工作空间。进而,按缺省 如果输出变量与输入变量相同,例如,函数x=fu(x,y,z)中的x,那么就将它拷贝到函数 的工作空间。因此,为了节约存储和增加速度,最好是从大数组中抽取元素,然后对它们作 修正,而不是使整个数组拷贝到函数的工作空间。 13.如果变量说明是全局的函数可以与其它函数、 MATLAB工作空间和递归调用本身 共享变量。为了在函数内或 MATLAB工作空间中访问全局变量,在每一个所希望的工作空 间,变量必须说明是全局的。全局变量使用的例子可以在 MATLAB函数tic和toc中看到, 它们合在一起工作如一个跑表。 function tic TIc Start a stopwatch timer The sequence of commands any stuff TOC %o prints the time required for the stuf See also TOC, CLOCK, ETIME, CPUTIME Copyright(c)1984-94 by The Math Works, Inc o TIC simply stores CLOCK in a global variable global TICTOC IICTOC clock function t=toc TOC, by itself, prints the elapsed time since TIC was used t=TOC; saves the elapsed time in t, instead of printing it out See also TIC ETIME. CLOCK. CPUTIME o Copyright(c)1984-94 by The Math Works, Inc o TOC uses EtIMe and the value of cloCk saved by tic global TICTOC if'n
到函数的工作空间。逆向有同样的属性,即函数内的重新定义变量不会延伸到 MATLAB 的 工作空间中。 12. 当调用一个函数时,输入变量不会拷贝到函数的工作空间,但使它们的值在函数 内可读。然而,改变输入变量内的任何值,那么数组就拷贝到函数工作空间。进而,按缺省, 如果输出变量与输入变量相同,例如,函数 x=fun(x, y, z) 中的 x ,那么就将它拷贝到函数 的工作空间。因此,为了节约存储和增加速度,最好是从大数组中抽取元素,然后对它们作 修正,而不是使整个数组拷贝到函数的工作空间。 13. 如果变量说明是全局的,函数可以与其它函数、MATLAB 工作空间和递归调用本身 共享变量。为了在函数内或 MATLAB 工作空间中访问全局变量,在每一个所希望的工作空 间,变量必须说明是全局的。全局变量使用的例子可以在 MATLAB 函数 tic 和 toc 中看到, 它们合在一起工作如一个跑表。 function tic % TIC Start a stopwatch timer. % The sequence of commands % TIC % any stuff % TOC % prints the time required for the stuff. % % See also TOC, CLOCK, ETIME, CPUTIME. % Copyright (c) 1984-94 by The MathWorks, Inc. % TIC simply stores CLOCK in a global variable. global TICTOC TICTOC = clock; function t = toc % TOC Read the stopwatch timer. % TOC, by itself, prints the elapsed time since TIC was used. % t = TOC; saves the elapsed time in t, instead of printing it out. % % See also TIC, ETIME, CLOCK, CPUTIME. % Copyright (c) 1984-94 by The MathWorks, Inc. % TOC uses ETIME and the value of CLOCK saved by TIC. global TICTOC if nargout < 1
elapsed time etime(clock, TICTOC) t=etime(clock, TICTOC) 在函数tic中,变量 TICTOC说明为全局的,因此它的值由调用函数cock来设定 以后在函数toc中,变量 TICTOC也说明为全局的,让toc访问存储在 TICTOC中的值。 利用这个值,toc计算自执行函数tic以来消逝的时间。值得注意的是,变量 TICTOC存在 于tic和toc的工作空间,而不在 MATLAB工作空间 14.实际编程中,无论什么时候应尽量避免使用全局变量。要是用了全局变量,建议 全局变量名要长,它包含所有的大写字母,并有选择地以首次出现的M文件的名字开头。 如果遵循建议,则在全局变量之间不必要的互作用减至最小。例如,如果另一函数或 MATLAB工作空间说明 TICTOC为全局的,那么它的值在该函数或 MATLAB工作空间内 可被改变,而函数toc会得到不同的、可能是无意义的结果 15. MATLAB以搜寻脚本文件的同样方式搜寻函数M文件。例如,输入》cow, MATLAB首先认为cow是一个变量。如果它不是,那么 MATLAB认为它是一个内置函数。 如果还不是, MATLAB检查当前cowm的目录或文件夹。如果它不存在, MATLAB就检 查cowm在 MATLAB搜寻路径上的所有目录或文件夹。如需要更多的信息,请参阅本书的 2.10节或 MATLAB用户指南中“ MATLAB搜寻路径” 16.从函数M文件内可以调用脚本文件。在这种情况下,脚本文件查看函数工作空间, 不查看 MATLAB工作空间。从函数M文件内调用的脚本文件不必用调用函数编译到内存 函数每调用一次,它们就被打开和解释。因此,从函数M文件内调用脚本文件减慢了函数 的执行 17.函数可以递归调用。即M文件函数能调用它们本身。例如,考虑一个傻函数 iforgot function iforgot(n) IFORGOT Recursive Function Call Example %o Copyright(c)1996 by Prentice-Hall, Inc if nargin==0. n=20:end ifn>I disp( i will remember to do my homework. iforgot(n-1) disp( Maybe NOT!) 调用这个函数产生 >)iforgot(10)
elapsed_time = etime(clock,TICTOC) else t = etime(clock,TICTOC); end 在函数 tic 中,变量 TICTOC 说明为全局的,因此它的值由调用函数 clock 来设定。 以后在函数 toc 中,变量 TICTOC 也说明为全局的,让 toc 访问存储在 TICTOC 中的值。 利用这个值,toc 计算自执行函数 tic 以来消逝的时间。值得注意的是,变量 TICTOC 存在 于 tic 和 toc 的工作空间,而不在 MATLAB 工作空间。 14. 实际编程中,无论什么时候应尽量避免使用全局变量。要是用了全局变量,建议 全局变量名要长,它包含所有的大写字母,并有选择地以首次出现的 M 文件的名字开头。 如果遵循建议,则在全局变量之间不必要的互作用减至最小。例如,如果另一函数或 MATLAB 工作空间说明 TICTOC 为全局的,那么它的值在该函数或 MATLAB 工作空间内 可被改变,而函数 toc 会得到不同的、可能是无意义的结果。 15. MATLAB 以搜寻脚本文件的同样方式搜寻函数 M 文件。例如,输入» cow , MATLAB 首先认为 cow 是一个变量。如果它不是,那么 MATLAB 认为它是一个内置函数。 如果还不是,MATLAB 检查当前 cow.m 的目录或文件夹。如果它不存在,MATLAB 就检 查 cow.m 在 MATLAB 搜寻路径上的所有目录或文件夹。如需要更多的信息,请参阅本书的 2.10 节或 MATLAB 用户指南中“MATLAB 搜寻路径”。 16. 从函数 M 文件内可以调用脚本文件。在这种情况下,脚本文件查看函数工作空间, 不查看 MATLAB 工作空间。从函数 M 文件内调用的脚本文件不必用调用函数编译到内存。 函数每调用一次,它们就被打开和解释。因此,从函数 M 文件内调用脚本文件减慢了函数 的执行。 17. 函数可以递归调用。即 M 文件函数能调用它们本身。例如,考虑一个傻函数 iforgot: function iforgot(n) % IFORGOT Recursive Function Call Example % Copyright (c) 1996 by Prentice-Hall,Inc if nargin==0,n=20;end if n>1 disp(' I will remember to do my homework. ') iforgot(n-1) else disp(' Maybe NOT! ') end 调用这个函数产生 » iforgot(10)