《使用者定义函式.ppt》由会员分享,可在线阅读,更多相关《使用者定义函式.ppt(35页珍藏版)》请在三一办公上搜索。
1、使用者定義函式,黃聰明 國立臺灣師範大學數學系 http:/math.ntnu.edu.tw/min,使用函式的效益,個別測試子任務程式碼能重複使用 減少整個程式開發所需要的時間與心力 簡化程式的除錯工作避免無心的錯誤函式從擁有一連串資料(輸入引數清單)的程式中,接收所需的輸入資料,並經由輸出引數清單傳回結果給程式。每個函式都擁有自己的獨立變數,並且在自己的工作區內執行,與其他的函式及所呼叫的程式無關。在呼叫函式中唯一可以被函式看見的變數,只有這些輸入引數,而函式中唯一能被呼叫程式看見的變數,也只有輸出引數。某一函式不小心犯下的程式錯誤,只會影響到此函式內的變數,不會影響整個程式工作區內的變數
2、。,使用者定義函式,1,5-1 MATLAB 函式介紹,使用者定義函式,2,function out1,out2,.=funname(in1,in2,.)statements,儲存之檔案名稱須與函式名稱一樣,計算點(x1,y1)與點(x2,y2)的距離,使用者定義函式,3,function distance=dist2(x1,y1,x2,y2)%DIST2 Calculate the distance between two points%Function DIST2 calculates the distance between%two points(x1,y1)and(x2,y2)in a
3、 Cartesian%coordinate system.%Calling sequence:%distance=dist2(x1,y1,x2,y2)%Define variables:%x1-x-position of point 1%y1-y-position of point 1%x2-x-position of point 2%y2-y-position of point 2%distance-Distance between points%Calculate distance.distance=sqrt(x2-x1).2+(y2-y1).2);end%function dist2,l
4、ookfor distanceDIST2 Calculate the distance between two points,呼叫 dist2,使用者定義函式,4,%Get input data.disp(Calculate the distance between two points:);ax=input(Enter x value of point a:);ay=input(Enter y value of point a:);bx=input(Enter x value of point b:);by=input(Enter y value of point b:);%Evaluate
5、 functionresult=dist2(ax,ay,bx,by);%Write out result.fprintf(The distance between points a and b is%fn,result);,function distance=dist2(x1,y1,x2,y2),在函式呼叫之前的工作區,使用者定義函式,5,在函式呼叫期間的工作區,使用者定義函式,6,在函式呼叫之後的工作區,使用者定義函式,7,5-2 MATLAB的變數傳遞方式:按值傳遞,使用者定義函式,8,MATLAB程式使用pass-by-value的方式,進行程式與函式間的溝通聯絡,當程式呼叫函式時,MA
6、TLAB便複製實質引數,並傳遞這些實質引數的備份提供函式使用。,使用者定義函式,9,function out=sample(a,b)fprintf(In sample:a=%f,b=%f%fn,a,b);a=b(1)+2*a;b=a.*b;out=a+b(1);fprintf(In sample:a=%f,b=%f%fn,a,b);,輸入引數值改變,a=2;b=6 4;fprintf(Before sample:a=%f,b=%f%fn,a,b);out=sample(a,b);fprintf(After sample:a=%f,b=%f%fn,a,b);fprintf(After sampl
7、e:out=%fn,out);,test_sampleBefore sample:a=2.000000,b=6.000000 4.000000In sample:a=2.000000,b=6.000000 4.000000In sample:a=10.000000,b=60.000000 40.000000After sample:a=2.000000,b=6.000000 4.000000After sample:out=70.000000,範例:資料排序(由小到大),使用者定義函式,10,程 式 要 求,使用者定義函式,11,使用者輸入任意數量的資料,以遞增的順序來排序資料,輸出排序過的資
8、料,使用者定義函式,12,function out=ssort(a)%Get the length of the array to sortnvals=size(a,2);%Sort the input arrayfor ii=1:nvals-1%Find the minimum value in a(ii)through a(n)iptr=ii;for jj=ii+1:nvals if a(jj)a(iptr)iptr=jj;end end%iptr now points to the minimum value,so swap a(iptr)%with a(ii)if ii=iptr.if
9、 ii=iptr temp=a(ii);a(ii)=a(iptr);a(iptr)=temp;endend%Pass data back to callerout=a;,使用者定義函式,13,%Prompt for the number of values in the data setnvals=input(Enter number of values to sort:);%Preallocate arrayarray=zeros(1,nvals);%Get input valuesfor ii=1:nvals%Prompt for next value string=Enter value
10、 int2str(ii):;array(ii)=input(string);End%Now sort the datasorted=ssort(array);%Display the sorted result.fprintf(nSorted data:n);for ii=1:nvals fprintf(%8.4fn,sorted(ii);end,test_ssortEnter number of values to sort:6Enter value 1:-5Enter value 2:4Enter value 3:-2Enter value 4:3Enter value 5:-2Enter
11、 value 6:0Sorted data:-5.0000-2.0000-2.0000 0.0000 3.0000 4.0000,5-3 選擇性的引數,使用者定義函式,14,nargin:決定函式實際輸入變數的個數,nargout:決定函式實際輸出變數的個數,nargchk:假如用來呼叫函式的引數太少或太 多,這個函式將傳回一個標準的錯 誤訊息,error:顯示錯誤的訊息,並放棄執行產生錯 誤的函式,warning:顯示警告的訊息,並繼續執行函式,使 用 語 法,使用者定義函式,15,message=nargchk(min_args,max_args,num_args);,引數的最小數目,引數
12、的最大數目,實際引數的數目,error(msg);,warning(msg);,範例,使用者定義函式,16,輸入直角座標(x,y),轉換成極座標 輸出,如果只輸入一個引數,則函式假設y值為0,如果呼叫此函式的敘述式只有一個輸出引數,則傳回距離值,angle:angle in degreemag:magnitude,if nargin 2 y=0;end,if nargout=2 angle=atan2(y,x)*180/pi;end,使用者定義函式,17,function mag,angle=polar_value(x,y)%POLAR_VALUE Converts(x,y)to(r,thet
13、a)%Check for a legal number of input arguments.narginchk(1,2);%If the y argument is missing,set it to 0.if nargin 2 y=0;end%a warning message.if x=0 end,mag angle=polar_value(1,-1)mag=1.4142angle=-45,5-4 使用共用記憶體分享資料,使用者定義函式,18,global var1 var2 var3,共用記憶體(Global memory)是一種特別型態的記憶體,能在任何的工作區內存取如果一個變數在函
14、式中被宣告為全域變數,則這個變數將被存放在共用記憶體內,而不會存放在局部的工作區。如果在另一個函式中有相同名稱的變數被宣告為全域變數,則這個變數也將對應到與第一個函式中變數相同的記憶體位址。,全域變數的使用原則,使用者定義函式,19,範例:亂數產生器,使用者定義函式,20,Modulo function:是非負整數,產生一個介於0到134455的數列,若未知8121,28411及134456,則無法猜測此數列,每個產生的數字出現在數列的機率均相等(均勻分佈),使用者定義函式,21,利用modulo function來設計一個亂數產生器,以輸出在0,1)範圍的實數,問題,方法,要求,給予modu
15、lo function之初始值,以下列方式產生介於0與1之間的實數:,函式能夠產生並回傳亂數數列的陣列,函式必須有一個或兩個輸入引數(n及m),用以設定傳回的陣列大小。,如果只有一個引數,函式傳回 的陣列。,如果有兩個引數,函式傳回 的陣列。,亂數之初始值,由另一函式來指定。,使用者定義函式,22,function ran=random0(n,m)%RANDOM0 Generate uniform random numbers in 0,1)%Declare global valuesglobal ISEED%Seed for random number generator%Check for
16、 a legal number of input arguments.narginchk(1,2);%If the m argument is missing,set it to n.if nargin 2 m=n;end%Initialize the output arrayran=zeros(n,m);%Now calculate random valuesfor ii=1:n for jj=1:m ISEED=mod(8121*ISEED+28411,134456);ran(ii,jj)=ISEED/134456;endend,function seed(new_seed)%Declar
17、e global valuesglobal ISEED msg=nargchk(1,1,nargin);error(msg);%Save seednew_seed=round(new_seed);ISEED=abs(new_seed);,測試結果,使用者定義函式,23,seed(1024)random0(4)ans=0.0598 1.0000 0.0905 0.2060 0.2620 0.6432 0.6325 0.8392 0.6278 0.5463 0.7551 0.4554 0.3177 0.9105 0.1289 0.6230,ISEED?Undefined function or v
18、ariable ISEED.,random0(4)ans=0.2266 0.3858 0.5876 0.7880 0.8415 0.9287 0.9855 0.1314 0.0982 0.6585 0.0543 0.4256 0.2387 0.7153 0.2606 0.8922,5-6 含函式的函式,使用者定義函式,24,是一種輸入引數包含其他函式名稱的函式,而這些傳入函式名稱的函式,會在含函式的函式執行過程中,被呼叫來使用。,fzero:內建函式,找出只含一個變數函式之零點,fzero(cos,0 pi)ans=1.5708,fzero(x)exp_2(x),0 pi)ans=0.6931
19、,function val=exp_2(x)val=exp(x)-2;,fzero(exp_2,0 pi)ans=0.6931,fzero(exp_2,0 pi)ans=0.6931,內建函式 eval,使用者定義函式,25,eval(string),eval 會針對string字元字串求值,x=1;str=exp(num2str(x)-1;res=eval(str)res=1.7183,for d=1:10 s=load August int2str(d).mat eval(s)end,x=eval(sin(pi/4)x=0.7071,s=load August1.mats=load Aug
20、ust2.mats=load August3.mat-etc.-,使用者定義函式,26,內建函式 feval,feval(fun,value),feval 會針對M檔案中的(fun)函式,在特定輸入值(value)下計算其函式值,feval(sin,pi/4)ans=0.7071,feval(exp_2,0)ans=-1,feval(exp_2,0)ans=-1,function val=exp_2(x)val=exp(x)-2;,feval(x)exp_2(x),0)ans=-1,使用者定義函式,27,範例,問題,要求,步驟,在特定的數值區間,產生一個含函式的函式,用來畫出任一個MATLAB
21、單一變數的函式圖形。,函式需要兩個輸入引數,第一個引數為被畫出圖形的函式名稱,第二個引數為兩個元素的向量,此為函式圖形的範圍,檢查合法的引數個數,檢查第二個引數是否擁有兩個元素,在初始點與結束點之間,計算函式的數值,繪圖並標示函式圖形,使用者定義函式,28,function quickplot(fun,xlim)%QUICKPLOT Generate quick plot of a function%Check for a legal number of input arguments.narginchk(2,2);%Check the second argument to see if it
22、 has two elements.if(size(xlim,1)=1 end,quickplot(sin,-2*pi 2*pi),5-7 子函式、專用函式與巢狀函式,使用者定義函式,29,一個M檔案可以包含一個以上的函數,主函數與子函數的位置,一個主函數(Primary Function),其他則為子函數(Subfunctions),主函數必須與檔案名稱一樣,子函數只能被同檔案中的函數(主函數或子函數)呼叫,但不可被不同檔案的其他函數呼叫,主函數必需出現在最上方,其後接上任意數目的子函數,子函數的次序並無任何限制,使用者定義函式,30,圖例,私有化目錄(Private Directory),
23、使用者定義函式,31,在目錄中建立名稱為 private 的私有化目錄,存放與這目錄相關的函數,目錄 private 之下的函數,只能被其父目錄函數所呼叫,不能被其他目錄的函數來呼叫,函 數 搜 尋 次 序,使用者定義函式,32,從 M 檔案呼叫一個函數時,MATLAB 搜尋函數的次序,檢查此函數是否為子函數,檢查此函數是否為私有化目錄的函數,從系統所設定的搜尋路徑找尋此函數,MATLAB 找到第一個檔名相符的函數,即會立即取用,巢 狀 函 式,使用者定義函式,33,圖例,使用者定義函式,34,function res=test_nested_1%Define some variables.a
24、=1;b=2;x=0;y=9;%Display variables before call to fun1fprintf(Before call to fun1:n);fprintf(a,b,x,y=%2d%2d%2d%2dn,a,b,x,y);%Call nested function fun1x=fun1(x);%Display variables after call to fun1fprintf(nAfter call to fun1:n);fprintf(a,b,x,y=%2d%2d%2d%2dn,a,b,x,y);%Declare a nested function functio
25、n res=fun1(y)%Display variables at start of call to fun1 fprintf(nAt start of call to fun1:n);fprintf(a,b,x,y=%2d%2d%2d%2dn,a,b,x,y);y=y+5;a=a+1;res=y;%Display variables at end of call to fun1 fprintf(nAt end of call to fun1:n);fprintf(a,b,x,y=%2d%2d%2d%2dn,a,b,x,y);end%function fun1end%function test_nested_1,test_nested_1Before call to fun1:a,b,x,y=1 2 0 9At start of call to fun1:a,b,x,y=1 2 0 0At end of call to fun1:a,b,x,y=2 2 0 5After call to fun1:a,b,x,y=2 2 5 9,