第8章M文件函数 使用 MATLAB函数时,例如inv,abs,ange和sqrt, MATLAB获取传递给它的变量, 利用所给的输入,计算所要求的结果。然后,把这些结果返回。由函数执行的命令,以及由 这些命令所创建的中间变量,都是隐含的。所有可见的东西是输入和输出,也就是说函数是 一个黑箱 这些属性使得函数成为强有力的工具,用以计算命令。这些命令包括在求解一些大的问 题时,经常出现的有用的数学函数或命令序列。由于这个强大的功能, MATLAB提供了 个创建用户函数的结构,并以M文件的文本形式存储在计算机上。 MATLAB函数 flipper是 一个M文件函数良好的例子。 functiony =fliplr(x) 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文件函数必须遵循以下特定的规则。除此之外,它们有许多的重要属性。包括: 函数名和文件名必须相同。例如,函数fipr存储在名为 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 4, N= SIZE(X) returns the number of rows and columns in separate output variables 如果函数仅用一个输出参量调用,就返回一个二元素的行,它包含行数和列数。相反, 如果出现两个输出参量,size分别返回行和列。在M文件函数里,变量 nargout可用来检 验输出参量的个数,并按要求修正输出变量的创建。 9.当一个函数说明一个或多个输出变量,但没有要求输出时,就简单地不给输出变量 赋任何值。 MATLAB函数toc阐明了这个属性 TOC Read the stopwatch timer TOC, by itself, prints the 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 If 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=fun(x,y,z)中的x,那么就将它拷贝到函数 的工作空间。因此,为了节约存储和增加速度,最好是从大数组中抽取元素,然后对它们作 修正,而不是使整个数组拷贝到函数的工作空间。 13.如果变量说明是全局的函数可以与其它函数、 MATLAB工作空间和递归调用本身 共享变量。为了在函数内或 MATLAB工作空间中访问全局变量,在每一个所希望的工作空 间,变量必须说明是全局的。全局变量使用的例子可以在 MATLAB函数tic和toc中看到, 它们合在一起工作如一个跑表。 function tic TIc Start a stopwatch timer The sequence of commands any stuff %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.MA∏LAB以搜寻脚本文件的同样方式搜寻函数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)