zoukankan      html  css  js  c++  java
  • MATLAB 函数编写方法, 浅析MATLAB中的内联函数、匿名函数和函数函数

    http://blog.sina.com.cn/s/blog_3f9564ca01000716.html

    所谓 MATLAB 程序,大致分为两类:M 脚本文件 (M-Script) 和 M 函数 (M-function), 它们均是普通的 ASCII 码构成的文件。M 脚本文件中包含一族由 MATLAB 语言所支持的语句,它类似于 DOS 下的批处理文件,它的执行方式很简单,用户只需在 MATLAB 的提示符 >> 下键入该 M 文件的文件名,这样 MATLAB 就会自动执行该 M 文件中的各条语句,并将结果直接返回到 MATLAB 的工作空间。M 函数格式是 MATLAB 程序设计的主流,一般情况下, 不建议您使用 M 脚本文件格式编程。

      MATLAB 的 M 函数是由 function 语句引导的,其基本格式如下:

    function [返回变量列表] = 函数名 (输入变量列表) 
    注释说明语句段, 由 % 引导 
    输入、返回变量格式的检测
    函数体语句 

      这里输入和返回变量的实际个数分别由 nargin 和 nargout 两个 MATLAB 保留变量来给出,只要进入该函数,MATLAB 就将自动生成这两个变量,不论您是否直接使用这两个变量。返回变量如果多于 1 个,则应该用方括号将它们括起来,否则可以省去方括号。输入变量和返回变量之间用逗号来分割。注释语句段的每行语句都应该由百分号 % 引导,百分号后面的内容不执行,只起注释作用。用户采用 help 命令则可以显示出来注释语句段的内容。此外,正规的变量个数检测也是必要的。如果输入或返回变量格式不正确,则应该给出相应的提示。我们将通过下面的例子来演示函数编程的格式与方法。

    〖例 3-〗假设我们想生成一个 nxm 阶的 Hilbert 矩阵, 它的第 i 行第 j 列的元素值为 1/(i+j-1)。我们想在编写的函数中实现下面几点:

    • 如果只给出一个输入参数,则会自动生成一个方阵,即令 m=n
    • 在函数中给出合适的帮助信息,包括基本功能、调用方式和参数说明
    • 检测输入和返回变量的个数,如果有错误则给出错误信息

      如果调用时不要求返回变量,则将显示结果矩阵。其实在编写程序时养成一个好的习惯,无论对程序设计者还是对程序的维护者、使用者都是大有裨益的。

      采用 MATLAB 函数编写格式和上述要求,我们可以编写出一个函数

    function A=myhilb(n, m)
    %MYHILB a demonstrative M-function.
    % A=MYHILB(N, M) generates an N by M Hilbert matrix A.
    % A=MYHILB(N) generates an N by N square Hilbert matrix.
    % MYHILB(N,M) displays ONLY the Hilbert matrix, but do not return any
    % matrix back to the calling function.
    %
    %See also: HILB.

    % Designed by Professor Dingyu XUE, Northeastern University, PRC
    % 5 April, 1995, Last modified by DYX at 21 March, 2000
    if nargout>1, error('Too many output arguments.'); end
    if nargin==1, m=n;
    elseif nargin==0 | nargin>2
    error('Wrong number of iutput arguments.');
    end
    A1=zeros(n,m);
    for i=1: n
    for j=1:m
    A1(i,j)=1/(i+j-1);
    end, end
    if nargout==1, A=A1; elseif nargout==0, disp(A1); end

    这样规范编写的函数用 help 命令可以显示出其帮助信息:

    >> help myhilb
    MYHILB a demonstrative M-function.
    A=MYHILB(N, M) generates an N by M Hilbert matrix A.
    A=MYHILB(N) generates an N by N square Hilbert matrix.
    MYHILB(N,M) displays ONLY the Hilbert matrix, but do not return any
    matrix back to the calling function.

    See also: HILB.

      有了函数之后,可以采用下面的各种方法来调用它,并产生出所需的结果。

    >> A=myhilb(3,4)
    A =
    1.0000 0.5000 0.3333 0.2500
    0.5000 0.3333 0.2500 0.2000
    0.3333 0.2500 0.2000 0.1667
    >> A=myhilb(4)
    A =
    1.0000 0.5000 0.3333 0.2500
    0.5000 0.3333 0.2500 0.2000
    0.3333 0.2500 0.2000 0.1667
    0.2500 0.2000 0.1667 0.1429
    >> myhilb(4)
    1.0000 0.5000 0.3333 0.2500
    0.5000 0.3333 0.2500 0.2000
    0.3333 0.2500 0.2000 0.1667
    0.2500 0.2000 0.1667 0.1429

    MATLAB 工具箱编写技巧

      放入一个目录中的为某种目的专门编写的一组 MATLAB 函数就可以组成一个工具箱。 从某种意义上说,任何一个 MATLAB 语言的使用者都可以是工具箱的作者。在一个工具箱中,应该有一个名为 Contents.m 的文件,用来描述工具箱中所有 MATLAB 函数的名称和意义。在该文件中第 1 行应该给出该工具箱的名称,在第 2
    行中给出该工具箱的版本与修改时间等信息。然后分类地给出该工具箱中各类函数的最基本功能。注意,本文件中所有的语句都应该是注释语句,由百分号 % 引导,空行也应该由 % 引导。

      另外,因为 MATLAB是一种解释性语言,所以即使在某个或某些函数中存在语法错误,但如果没执行到该语句时可能就不会发现该错误,这在一个成功的程序设计中是不能容许的。要查出某目录中所有的M函数语法错误,首先应该用 cd 命令 进入该目录,然后运行 pcode * 命令进行伪代码转换。因为该命令会将 MATLAB 函数转换成伪代码,而在转换过程中该程序将自动翻译每一条语句,所以一旦发现有语法错误,将会停止翻译,给出错误信息。改正了该语法错误后,再重新执行 pcode 命令,直到没有错误为止。至少这样会保证目录下所有的程序不含有语法错误。

    http://379910987.blog.163.com/blog/static/33523797201161052640225/

    内联函数

           内联(inline)函数是MATLAB 7以前经常使用的一种构造函数对象的方法。在命令窗口、程序或函数中创建局部函数时,通过使用inline构造函数,而不用将其储存为一个M文件,同时又可以像使用一般函数那样调用它。

    MATLAB中的内联函数借鉴了C语言中的内联函数,在C语言中,内联函数是通过编译器控制来实现的,它只在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的时间和空间开销。在MATLAB中也有类似的性质。由于内联函数是储存于内存中而不是在M文件中,省去了文件访问的时间,加快了程序的运行效率。

    虽然内联函数有M文件不具备的一些优势,但是由于内联函数的使用,也会受到一些制约。首先,不能在内联函数中调用另一个inline函数;另外,只能由一个MATLAB表达式组成,并且只能返回一个变量。

    创建一个内联函数非常简单,就是使用inline方法,例如:

    >> f=inline('t^2-3*t-4')
    
    f =
    
         Inline function:
    
         f(t) = t^2-3*t-4

    MATLAB会通过检查字符串来推断自变量,例如上面的函数中t就是自变量,如果没有找到,将会使用x作为缺省的自变量,例如常数函数:

    >> g=inline('3')
    
    g =
    
         Inline function:
    
         g(x) = 3

    另外,对于inline也支持多元函数:

    >> h=inline('x+y')
    
    h =
    
         Inline function:
    
         h(x,y) = x+y

    这种创建方法等价于以下方法:

    >> h=inline('x+y','x','y')

    这种方式显式地指定了参数列表。

    使用内联函数也很简单,如同手写一般,以f(t) = t^2-3*t-4为例,分别计算在t=2t=4时的函数值:

    >> f(2)
    
    ans =
    
        -6
    
    >> f(4)
    
    ans =
    
         0

    对于多元函数类似。

    匿名函数

           匿名函数(anonymous function)是MATLAB 7.0版提出的一种全新的函数描述形式,和内联函数类似,可以让用户编写简单的函数而不需要创建M文件,因此,匿名函数具有inline函数的所有优点,并且效率比inline函数高,同时还具有一些独有的特点。

           事实上匿名函数很像C语言中的宏,这个从匿名函数的构造就能够看得出来,但是它比宏的功能更加强大,就是可以支持变量替换,这将在后面的示例中有所体现。

    定义一个匿名函数很简单,语法是fhandle=@(arglist) expression

    其中fhandle就是调用该函数的函数句柄(function handle),相当于C语言中的函数指针,arglist是参数列表,多个参数使用逗号分隔,Expression则是该函数的表达式,例如定义xy的平方和函数:

    >> f=@(x,y) x*x+y*y
    
    f =
    
        @(x,y)x*x+y*y

    一旦定义了匿名函数,使用方式和inline函数类似,例如计算f(3,4)

    >> f(3,4)
    
    ans =
    
        25

    前面提到,匿名函数可以使用工作空间的变量,例如创建函数f(x,y)=x^2+y^3

    >> p=2;
    
    >> q=3;
    
    >> f=@(x,y) x^p+y^q
    
    f =
    
        @(x,y)x^p+y^q

    计算f(2,3):

    >> f(2,3)

    ans =

        31

    如果修改p或者q的值,例如将q改为2

    q =

         2

    >> f(2,3)

    ans =

        31

    计算结果并没有改变,这是因为,该函数句柄保存的是函数在创建时的快照,而不是动态的访问其中的变量,如果希望获取新值,需要重新创建一次该函数,完整的方法应该是这样的:

    >> q=2;
    
    >> f=@(x,y) x^p+y^q
    
    f =
    
        @(x,y)x^p+y^q
    
    >> f(2,3)
    
    ans =
    
        13

    匿名函数会让前面的内联函数逐步退出MATLAB的舞台,事实上在设计这种类型的函数时就带有这一目的,但是为了保持程序的向下兼容,使用内联函数无疑将带来更好的兼容性。

    函数函数

           函数函数(function function)是对传入的其他函数进行操作的函数,传入的函数作为函数函数的输入参数,传入到函数函数中的函数称为传递函数(Passed function),事实上MATLAB中就有许多这样的函数,例如求解常微分方程的函数ode23ode45ode113等都是函数函数,他们的第一个参数都是传递函数。另外一个常见的函数函数是fplot,用于绘制所提供函数的图形,语法为fplot(fun,lims)

    例如绘制x取值范围为[-π,π]f=sin(x)的图形:

    >> fplot(@sin,[-pi,pi])

           图形如下:

     浅析MATLAB中的内联函数、匿名函数和函数函数 - Castor - 趁年轻,多折腾~~

      和前面两种函数不同,函数函数是比较复杂的函数了,因此必须要保存在M文件中,例如可以编写一个计算某个传递函数在给定区间上最大值、最小值和平均值的函数函数:

    function [maxy,miny,aver]=fstatic(func,a,b,n)
    
        x=linspace(a,b,n);
    
        y=func(x);
    
        maxy=max(y);
    
        miny=min(y);
    
        aver=mean(y);
    
    end

    保存为M文件后,例如统计正弦函数在[-π,π]上的最大值、最小值和平均值:

    >> fstatic(@sin,-pi,pi,100)
    
    ans =
    
        0.9999
    
    >> [max min aver]=fstatic(@sin,-pi,pi,1000)
    
    max =
    
        1.0000
    
    min =
    
       -1.0000
    
    aver =
    
     -5.9291e-018
  • 相关阅读:
    < java.util >-- Set接口
    Codeforces 627 A. XOR Equation (数学)
    Codeforces 161 B. Discounts (贪心)
    Codeforces 161 D. Distance in Tree (树dp)
    HDU 5534 Partial Tree (完全背包变形)
    HDU 5927 Auxiliary Set (dfs)
    Codeforces 27E. Number With The Given Amount Of Divisors (暴力)
    lght oj 1257
    Codeforces 219D. Choosing Capital for Treeland (树dp)
    Codeforces 479E. Riding in a Lift (dp + 前缀和优化)
  • 原文地址:https://www.cnblogs.com/MarshallL/p/4045768.html
Copyright © 2011-2022 走看看