跳转到内容

MATLAB 编程/便携函数

来自维基教科书,开放世界中的开放书籍

MATLAB 中的函数

[编辑 | 编辑源代码]

函数是由一系列顺序表达式语句(也称为伪算法)组成的一个集合,这些语句组合在一起执行一项任务。在 MATLAB 中,函数在单独的文件中定义。文件名称和函数名称必须相同。函数在其自己的工作区(也称为局部工作区)中操作变量,该工作区独立于您在 MATLAB 命令提示符下访问的工作区(称为基础工作区)。

函数可以接受多个输入参数,并且可以返回多个输出参数。


函数的语法如下:

function [y1,...,yN] = myfunc(x1,...,xM)

其中,语法声明了一个名为 myfunc 的函数,该函数接受输入 x1,...,xM 并返回输出 y1,...,yN
此声明语句必须是函数中的第一条可执行语句。有效的函数名称以字母字符开头,可以包含字母、数字或下划线。

在单独的文件中创建函数

[编辑 | 编辑源代码]
Screenshot of MATLAB on how to select "Function"
MATLAB 关于如何选择“函数”的截图

要创建新函数,请在“主页”选项卡上,单击“新建”-->“函数”,它将创建一个类似于以下内容的模板:

function [outputArg1,outputArg2] = untitled2(inputArg1,inputArg2)
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here
outputArg1 = inputArg1;
outputArg2 = inputArg2;
end

声明函数

[编辑 | 编辑源代码]

为了演示函数的用处,我们将以一个假设的情况为例:
最近,您的班级里有一些来自美国的交换生,他们一直在抱怨外面的天气很热。当他们在天气应用程序上查看时,他们惊呼外面的天气是100 度。但是对于那些以前从未使用过英制单位的人来说,您可能会想知道,现在外面的温度是多少呢?

因此,为了解决这个问题,您可能需要创建一个自定义函数来将华氏度转换为摄氏度。
首先,我们必须知道华氏度转换为摄氏度的公式,该公式如下:

在“主页”选项卡上,单击“新建”-->“函数”。

function [Ce] = convertTemp(Fa)
% Convert from Fahrenheit to Celcius

Ce = (Fa-32)*(5/9);
end

单击保存按钮将函数保存为 convertTemp.m 文件。
注意:文件名必须与函数名称相同,否则它将无法工作!

然后,在当前文件夹面板中,选择您刚才保存函数文件的目录。

调用函数

[编辑 | 编辑源代码]

要调用新创建的函数,请执行以下操作:在命令窗口面板中,键入以下命令,如所示:

>> convertTemp(100)

ans =
   37.7778

因此,外面的天气几乎是38 摄氏度

函数的优点

[编辑 | 编辑源代码]

您可能会问,为什么这样做有利呢?

好吧,从上面的练习中,您可以看到,您可以只键入函数名称来执行计算,尤其是对于重复性任务。
试想一下,例如上面的例子,只键入函数 convertTemp 而不是每次手动输入公式,将会节省大量时间。

函数类型

[编辑 | 编辑源代码]

函数类型包括:

  • 匿名函数
  • 局部函数
  • 嵌套函数
  • 私有函数
  • 内联函数(在未来版本中已淘汰)

匿名函数

[编辑 | 编辑源代码]

匿名函数允许您在不创建程序文件的情况下定义函数,只要函数包含单个语句即可。匿名函数的一个常见应用是定义数学表达式而不创建单独的文件。

匿名函数的语法如下:

        output = @(arguments) expression

其中,output = 要返回的输出 arguments = 要传递的必需输入 expression = 单个公式/逻辑

它可以接受多个输入并返回一个输出。它们只能包含单个可执行语句。

这里,我们有一个将华氏度转换为摄氏度的示例。

>> convTempF = @(Fa) (Fa-32)*(5/9);
>> convTempF(88)

ans =
   31.1111

>> convTempF(60)

ans =
   15.5556

另一个示例是使用匿名函数将分钟转换为秒(注意:1 分钟等于 60 秒)。

  >> convert_min_to_s = @(t) t*60;
  >> convert_min_to_s(4)

  ans =
     240

局部函数

[编辑 | 编辑源代码]

有时在数学中,您可能会遇到一个问题,您可能会发现一个用例,其中函数最好在它自己的函数中计算。
与其运行单独的函数来获取一个输出,您只需要运行一个函数来获取多个输出。这就是局部函数的作用。
为了进一步说明,在一个函数文件中,第一个函数称为主函数或父函数。文件中的其他函数称为局部函数,它们可以在主函数之后的任何位置出现。局部函数只能被同一文件中的其他函数看到。它们等同于其他编程语言中的子例程,有时称为子函数。

局部函数的应用是在一个复杂的函数中,将其分解为更小的函数块会更容易,并且我们确定这些函数将在同一个函数中使用,而不是在其他函数中使用。

局部函数示例

[编辑 | 编辑源代码]

为了说明示例,我们将创建一个名为 statistik 的函数,该函数将接收一系列数字,并返回基本统计函数的输出,例如最大值、最小值、平均值和标准差。我们将向它提供一串随机数,它将生成所有常见的统计结果。

首先,我们需要创建一个名为 statistik 的函数,请按照 在单独的文件中创建函数 中的说明操作。

function [max,min,ave,stdev]  = statistik(v) % this is the main function and can call to other local functions
% The function where it takes arguments of series and it will calculate the basic statistic info
% min function selects the smallest number in the series 
% max function selects the largest number in the series
% ave function calculate the average of the series
% stdev function calculate the standard deviations
max = maxf(v);
min = minf(v);
ave = avef(v);
stdev = stdevf(v);
end %end of function statistik

function a=maxf(v) 
%Sub function selects the largest number in the series
a = max(v);
end %end of function maxf

function b= minf(v)
%Sub function selects the smallest number in the series 
b = min(v);
end %end of function minf

function c = avef(v)
%Sub function to calculate the average of the series
c = mean(v);
end %end of function avef

function d = stdevf(v)
%Sub function to calculate the std dev of the series
d = std(v);
end %end of function stdevf

在单独的文件中创建 statistik 函数后,我们使用 randi 函数在命令窗口中生成一组随机数。

>> V = randi(50,1,10)

V =
    25    29    12    23    49    28    27    12    25    32

我们在命令窗口中按如下所示调用函数 statistik
[maximum,minimum,average,stdeviation]=statistik(V)

maximum =
    49

minimum =
    12

average =
   26.2000

stdeviation =
   10.4435

虽然您无法从命令行或其他文件中的函数调用局部函数,但您可以使用 help 函数访问其帮助信息。
指定文件和局部函数的名称,用大于号(>)分隔。

>> help statistik>avef
 Sub function to calculate the average of the series

嵌套函数

[编辑 | 编辑源代码]

嵌套函数是指完全嵌套在主函数内部的函数。
嵌套函数和局部函数之间的主要区别在于,嵌套函数可以使用在父函数中定义的变量,而无需显式地将这些变量作为参数传递。

嵌套函数的要求

[编辑 | 编辑源代码]

(a) 要在一个程序文件中嵌套任何函数,该文件中的所有函数都必须使用 end 语句。
(b) 嵌套函数不能定义在任何程序控制语句内部,例如 if/elseif/else、switch/case、for、while 或 try/catch。
(c) 可以直接使用函数名称或使用使用 @ 运算符创建的函数句柄(参见匿名函数)来调用嵌套函数。
(d) 嵌套函数或包含它们的函数中的所有变量必须显式定义。也就是说,您不能调用分配变量值的函数或脚本,除非这些变量已存在于函数工作区中。

嵌套函数的示例

[编辑 | 编辑源代码]
圆柱形金属锭

我们有一个假设情况,我们需要估计圆柱形金属锭的重量。
首先,在我们开始计算金属锭的重量之前,我们需要将问题分解成更小的部分。
为了计算金属的重量,我们需要计算密度,在计算密度之前我们需要计算金属的体积。

为了开始,在我们开始了解金属锭的体积之前,我们首先计算圆柱形底部的表面积,即圆形。
圆形的面积定义为
, r 是底圆的半径。

我们可以使用圆形的面积来计算圆柱体的体积。

, h 是圆柱体的高度。

最后,我们使用体积和密度来计算重量。

其中 D 是密度。

如何增加缩进

在 MATLAB 中,我们制定了这样的公式。
注意:对于除了主函数之外的嵌套函数,我们需要缩进函数。编辑 -> 缩进。

注意

function[]=ingot_calc()
    %This function is to calculate the price of an cylindrical ingot
    r = 3 ; % radius of base circle
    h = 10; % height of ingot
    d = 4.5;% density of the metal
    ar = circle_area;
    vo = volume;
    we = weight;
    

    function a = circle_area
       %calculate area of circle for the radius 
       a=pi*r*r; 
       at=['Area of circle is ',num2str(a,'%8.2f') , ' cm2'];
       disp(at)
    end
    
    function v = volume
        %calculate volume 
        v = ar* h;
        vt=['Volume of the ingot is ',num2str(v,'%8.2f') , 'cm3'];
        disp(vt)
    end
    
    function w = weight
        %calculate weight
        w = vo*d;
        wt=['The weight of ingot is ',num2str(w,'%8.2f'), ' g'];
        disp(wt)
    end
end

当我们在命令窗口中调用 ingot_calc 函数时,它应该显示这些值。

>> ingot_calc
Area of circle is 28.27 cm2
Volume of the ingot is 282.74cm3
The weight of ingot is 1272.35 g

内联函数

[编辑 | 编辑源代码]

内联函数目前正在逐步淘汰。应改用匿名函数。此处包含内联函数是为了提供信息。

 >> convert_s_to_ms = inline('x*1000','x');
 >> convert_s_to_ms(20)
 ans =
     20000

函数句柄

[编辑 | 编辑源代码]
户外嘉年华帐篷

函数句柄 是充当函数的抽象引用的双精度数。句柄允许将方程式传递给另一个函数以进行直接求值。匿名函数对于命令行求值或在同一个 m 文件中进行多次求值非常有用。

符号 @ 返回内置于 Matlab 或在 M 文件中定义的函数的句柄。

为了说明示例,我们需要像图片所示的那样搭建一个帐篷,但我们需要计算出搭建嘉年华帐篷所需的帆布数量。因此,我们将创建两个独立的函数,分别接收圆锥体的半径和斜高(圆锥体)以及圆柱体的半径和高度(圆柱体)。

为了温习一下,圆锥体表面积的公式(记住我们关注斜面积,忽略底面积)是
圆柱体表面的公式(记住没有计算圆柱体的一侧圆形)是
, 其中 r 是圆柱体和圆锥体的共享半径,l 是圆锥体斜高的长度,最后 h 是圆柱体的高度。

按照 在单独的文件中创建函数 中的步骤开始创建 totalsurftent

function [surfcone,surfcylin]  = totalsurftent(r,l,h)
% The function where it takes arguments of r,l,h to calculate surface area of cylinder and cone
% r is radius
% l is slanting lenth of cone
% h is cylinder height
surfcone = sacone(r,l);
surfcylin = sacylin(r,h);
end

function on=sacone(r,l) 
%Sub function to calculate face area of cylinder
on = pi*r*l;
end

function yl= sacylin(r,h)
%Sub function to calculate face area of cylinder   
yl = (2*pi*r*h)+(pi*r^2);
end

我们可以通过键入以下命令来了解表面积。

>> %Testing out the custom functions totalsurftent
>> [areacone,areasurfcylin]  = totalsurftent(3,3,3)

areafcone =
   28.2743

areacylin =
   84.8230


M 文件中的函数句柄

[编辑 | 编辑源代码]

如果您不熟悉 M 文件,请跳过此部分并返回。

函数句柄将一个 M 文件函数 传递给另一个函数。当然,这可以让您更好地控制传递的内容,并使您的程序更通用,因为它允许您传递 任何 M 文件(只要它满足其他要求,例如具有正确的输入参数数量等)。其功能类似于 C++ 中的函数指针。

要将 M 文件传递给函数,您必须先编写 M 文件,例如这样

function xprime = f(t,x)
xprime = x;

将其保存为 myfunc.m。要将其传递给另一个函数(例如 ODE 积分器),请使用 @ 符号,如下所示

>> ode45(@myfunc, [0:15], 1)

与匿名函数相比,使用函数句柄的一个优点是,您可以在 M 文件中求值多个方程式,从而允许您执行诸如求解 系统 ODE 而不是仅求解一个 ODE 等操作。匿名函数将您限制为一个方程式。

如何编写接受函数句柄的函数

[编辑 | 编辑源代码]

函数可以接受函数句柄。为此,请在标题中将它们定义为变量,然后像调用函数一样调用句柄。

% myadd adds two variables together
function result = myfunc(func, a, b);
result = func(a, b);

[in a separate m-file]
function sum = myadd(a, b)
sum = a+b;

您发送给 myfunc 的命令如下所示

>> result = myfunc(@myadd, 1, 2);
result = 3

参考文献

[编辑 | 编辑源代码]

[1] [2] [3]

  1. https://blogs.mathworks.com/loren/2008/01/16/nested-functions-and-variable-scope/
  2. https://web.archive.org/web/20220727140850/https://www.geeksforgeeks.org/functions-in-matlab/
  3. https://web.archive.org/web/20220730143213/https://www.educba.com/matlab-functions/
华夏公益教科书