10/25/2006

6.6巢狀函數

在函數中又存在另一個函數,這是MATLAB函數中基本的型態,不過大部份是另一個函數附於主函數之下,因此可以隨時呼叫。但此處所謂巢狀函數(Nested function)是處於函數內文之中,或以自己為函數重新呼叫。

撰寫一個巢狀函數與一般函數相同,亦即在函數中鉗置一個格式相同的函數:


function mainfun=A(p1, p2)%主函數
E(p1); B(p1); D(p2);A(p1,p2)
function infun1=B(p3) %第一層巢函數
C(p3);E(p3);B(p3);D(p3);A(p3,p3);

function infun1=C(p4) %第二層巢函數
     C(p4);E(p4);B(p4);D(p4);A(p4);
    end
end
function infun1=D(p3) %第一層巢函數
  F(p3);E(p3);B(p3);D(p3);

function infun1=F(p4) %第二層巢函數
     F(p4);E(p4);B(p4);D(p4);A(p4,p4);
    end
end
---
end

function main2=E(p5) %次函數
E(p5); A(p5,p5);
end


一般函數並不需要在終了加一個end,但若要做成巢狀結構,則必須以end結束。中間之函數可以再包含另一個巢狀函數,或者最外圍亦可包含多個巢狀函數。

在呼叫層次則有限制。第一層主函數可以呼叫次函數E及其下之第二層巢B與D函數,但不能呼叫其下之第三層以下如C函數。低層函數則可以呼叫其本身及同層以上之高層函數(如D可呼叫D、A、B、E等函數。

函數中之變數影響範圍則依其巢函數之位置而定。通常主函數與次函數各享有自己的工作空間,故除非利用輸入參數傳介,或宣告全域性變數,否則這兩個工作空間是相互獨立的。巢函數則與次函數不同,因為它與其直屬函數共享有工作空間。因此,巢函數本身雖有自己的獨立的空間,但由直屬函數內之變數則是共用的,因此這些變數均可能在兩個函數裡被更改。

巢函數置於某一函數之中,在執行時除非經由呼叫程序,否則不會自動執行。因為它也具有閉鎖性質,其變數也需經由輸出入參數傳輸。下面為一個計算多項式值的函數nest_fun。其輸入x 值可以為列矩陣,而係數a有三項,分別為A、B、C ,a可以有多項輸入。如此計算可以得到不同的組合。本函數利用細胞陣列rr_arry作為儲存運算結果,讀者可試著瞭解前節所介紹的功能。要顯示其內容必須使用celldisp指令。


function [rr_array]=nest_fun(x,a)
%function to find sets of polynormials.
% a: set of constants, [A B C]
% x: variables in array
% Example: rr=nest_fun(2:10,[1 2 4;2 4 8])
n=size(a);
for i=1:n
A=a(i,1);B=a(i,2);C=a(i,3);
rr_array{1,i}=['A=',num2str(A),', B=',...
num2str(B),', C=',num2str(C)];
rr_array{2,i}=polyx(x);
 end
function r=polyx(xx)
  r=A.*x.^2 + B.*x +C;
end
end


執行例:


>> rr=nest_fun(2:10,[1 2 4;2 4 8])

rr =
'A=1, B=2, C=4' 'A=2, B=4, C=8'
[1x9 double] [1x9 double]

>> celldisp(rr)

rr{1,1} =A=1, B=2, C=4
rr{2,1} = 12 19 28 39 52 67 84 103 124
rr{1,2} =A=2, B=4, C=8
rr{2,2} = 24 38 56 78 104 134 168 206 248