跳轉到內容

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/
華夏公益教科書