Download presentation
Presentation is loading. Please wait.
Published byRidwan Dharmawijaya Modified 6年之前
1
范洪源 hyfan@ntnu.edu.tw http://math.ntnu.edu.tw/~hyfan 臺灣師範大學數學系
使用者定義函式 范洪源 臺灣師範大學數學系
2
使用函式的效益 個別測試子任務 程式碼能重複使用 避免無心的錯誤 減少整個程式開發所需要的時間與心力 簡化程式的除錯工作
函式從擁有一連串資料(輸入引數清單)的程式中,接收所需的輸入資料,並經由輸出引數清單傳回結果給程式。 每個函式都擁有自己的獨立變數,並且在自己的工作區內執行,與其他的函式及所呼叫的程式無關。 在呼叫函式中唯一可以被函式看見的變數,只有這些輸入引數,而函式中唯一能被呼叫程式看見的變數,也只有輸出引數。 某一函式不小心犯下的程式錯誤,只會影響到此函式內的變數,不會影響整個程式工作區內的變數。 使用者定義函式 T.-M. Hwang
3
5.1 MATLAB函式介紹 function [out1, out2, ...] = funname(in1, in2, ...) statements 輸出引數 函式名稱 輸入引數 儲存之檔案名稱須與函式名稱一樣 使用者定義函式 T.-M. Hwang
4
計算點(x1,y1)與點(x2,y2)的距離 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 Cartesian % coordinate system. % % Calling sequence: % distance = dist2(x1, y1, x2, y2) % Define variables: % x x-position of point 1 % y y-position of point 1 % x x-position of point 2 % y y-position of point 2 % distance -- Distance between points % Calculate distance. distance = sqrt((x2-x1).^2 + (y2-y1).^2); end % function dist2 儲存之檔案名稱為 dist2.m H1 comment line >> lookfor distance DIST2 Calculate the distance between two points >> help dist2 DIST2 Calculate the distance between two points Function DIST2 calculates the distance between two points (x1,y1) and (x2,y2) in a Cartesian coordinate system. Calling sequence: distance = dist2(x1, y1, x2, y2) 使用者定義函式 T.-M. Hwang
5
呼叫 dist2 % 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 function result = dist2 (ax, ay, bx, by); % Write out result. fprintf('The distance between points a and b is %f\n',result); function distance = dist2(x1, y1, x2, y2) 使用者定義函式 T.-M. Hwang
6
在函式呼叫之前的工作區 使用者定義函式 T.-M. Hwang
7
在函式呼叫期間的工作區 使用者定義函式 T.-M. Hwang
8
在函式呼叫之後的工作區 使用者定義函式 T.-M. Hwang
9
5.2 MATLAB的變數傳遞方式:按值傳遞 MATLAB程式使用pass-by-value的方式,進行程式與函式間的溝通聯絡,當程式呼叫函式時,MATLAB便複製實質引數,並傳遞這些實質引數的備份提供函式使用。 使用者定義函式 T.-M. Hwang
10
function out = sample(a, b)
fprintf('In sample: a = %f, b = %f %f\n',a,b); a = b(1) + 2*a; b = a .* b; out = a + b(1); 輸入引數值改變 a = 2; b = [6 4]; fprintf('Before sample: a = %f, b = %f %f\n',a,b); out = sample(a,b); fprintf('After sample: a = %f, b = %f %f\n',a,b); fprintf('After sample: out = %f\n',out); >> test_sample Before sample: a = , b = In sample: a = , b = In sample: a = , b = After sample: a = , b = After sample: out = 使用者定義函式 T.-M. Hwang
11
範例:資料排序(由小到大) 使用者定義函式 T.-M. Hwang
12
程式要求 使用者輸入任意數量的資料 以遞增的順序來排序資料 輸出排序過的資料 使用者定義函式 T.-M. Hwang
13
function out = ssort(a) % Get the length of the array to sort
nvals = size(a,2); % Sort the input array for 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 % iptr now points to the minimum value, so swap a(iptr) % with a(ii) if ii ~= iptr. if ii ~= iptr temp = a(ii); a(ii) = a(iptr); a(iptr) = temp; % Pass data back to caller out = a; 使用者定義函式 T.-M. Hwang
14
% Prompt for the number of values in the data set
nvals = input('Enter number of values to sort: '); % Preallocate array array = zeros(1,nvals); % Get input values for ii = 1:nvals % Prompt for next value string = ['Enter value ' int2str(ii) ': ']; array(ii) = input(string); End % Now sort the data sorted = ssort(array); % Display the sorted result. fprintf('\nSorted data:\n'); fprintf(' %8.4f\n',sorted(ii)); end >> test_ssort Enter number of values to sort: 6 Enter value 1: -5 Enter value 2: 4 Enter value 3: -2 Enter value 4: 3 Enter value 5: -2 Enter value 6: 0 Sorted data: 0.0000 3.0000 4.0000 使用者定義函式 T.-M. Hwang
15
5.3 選擇性的引數 nargin:決定函式實際輸入變數的個數 nargout:決定函式實際輸出變數的個數
nargchk:假如用來呼叫函式的引數太少或太多,這個函式將傳回一個標準的錯誤訊息 error:顯示錯誤的訊息,並放棄執行產生錯誤的函式 warning:顯示警告的訊息,並繼續執行函式 使用者定義函式 T.-M. Hwang
16
使用語法 message = nargchk(min_args, max_args, num_args); 引數的最小數目 引數的最大數目
實際引數的數目 error(‘msg’); 可與nargchk互相搭配,當程式發生錯誤時,便會產生一個錯誤訊息 錯誤訊息的字元字串 warning(‘msg’); 使用者定義函式 T.-M. Hwang
17
範例 輸入直角座標(x,y),轉換成極座標 輸出 如果只輸入一個引數,則函式假設y值為0
如果呼叫此函式的敘述式只有一個輸出引數,則傳回距離值 angle : angle in degree mag :magnitude if nargin < 2 y = 0; end if nargout == 2 angle = atan2(y,x) * 180 / pi; end 使用者定義函式 T.-M. Hwang
18
>> [mag angle] = polar_value ??? Error using ==> polar_value
1 angle = function [mag, angle] = polar_value(x,y) %POLAR_VALUE Converts (x,y) to (r,theta) % Check for a legal number of input arguments. msg = nargchk(1,2,nargin); error(msg); % If the y argument is missing, set it to 0. if nargin < 2 y = 0; end % a warning message. if x == 0 & y == 0 msg = 'Both x and y are zero: angle is meaningless!'; warning(msg); % Now calculate the magnitude. mag = sqrt(x.^2 + y.^2); % If the second output argument is present, calculate % angle in degrees. if nargout == 2 angle = atan2(y,x) * 180/pi; >> [mag angle] = polar_value(0,0) Warning: Both x and y are zero: angle is meaningless! > In polar_value at 32 mag = angle = >> [mag angle] = polar_value(1,-1) mag = 1.4142 angle = -45 >> [mag angle] = polar_value ??? Error using ==> polar_value Not enough input arguments. >> [mag angle] = polar_value(1,-1,1) ??? Error using ==> polar_value Too many input arguments. 使用者定義函式 T.-M. Hwang
19
5.4 使用共用記憶體分享資料 共用記憶體(Global memory)是一種特別型態的記憶體,能在任何的工作區內存取
global var1 var2 var3 … 存放在共用記憶體內的變數 共用記憶體(Global memory)是一種特別型態的記憶體,能在任何的工作區內存取 如果一個變數在函式中被宣告為全域變數,則這個變數將被存放在共用記憶體內,而不會存放在局部的工作區。 如果在另一個函式中有相同名稱的變數被宣告為全域變數,則這個變數也將對應到與第一個函式中變數相同的記憶體位址。 使用者定義函式 T.-M. Hwang
20
全域變數的使用原則 盡量少用全域變數 使用全域變數,請遵循下列兩原則 檢視工作空間的變數,輸入whos global
全域變數使程式的流程不透明,造成程式除錯或維護的困難 使用全域變數,請遵循下列兩原則 使用前一定要宣告 使用全部大寫或較長的變數名稱,以資區別 檢視工作空間的變數,輸入whos global 清除所有工作空間的全域變數 X,需使用 clear global X 使用者定義函式 T.-M. Hwang
21
範例:亂數產生器 Modulo function: 是非負整數 產生一個介於0到134455的數列
若未知8121, 28411及134456,則無法猜測此數列 每個產生的數字出現在數列的機率均相等(均勻分佈) 問題:利用modulo function來設計一個亂數產生器,以輸出在[0, 1)範圍的實數 使用者定義函式 T.-M. Hwang
22
給予modulo function之初始值
方法 給予modulo function之初始值 以下列方式產生介於0與1之間的實數: 要求 如果只有一個引數,函式傳回 的陣列。 函式能夠產生並回傳亂數數列的陣列 函式必須有一個或兩個輸入引數(n及m),用以設定傳回的陣列大小。 如果有兩個引數,函式傳回 的陣列。 亂數之初始值 由另一函式來指定 使用者定義函式 T.-M. Hwang
23
function seed(new_seed) % Declare global values global ISEED
function ran = random0(n,m) %RANDOM0 Generate uniform random numbers in [0,1) % Declare global values global ISEED % Seed for random number generator % Check for a legal number of input arguments. msg = nargchk(1,2,nargin); error(msg); % If the m argument is missing, set it to n. if nargin < 2 m = n; end % Initialize the output array ran = zeros(n,m); % Now calculate random values for ii = 1:n for jj = 1:m ISEED = mod(8121*ISEED , ); ran(ii,jj) = ISEED / ; function seed(new_seed) % Declare global values global ISEED msg = nargchk(1,1,nargin); error(msg); % Save seed new_seed = round(new_seed); ISEED = abs(new_seed); 使用者定義函式 T.-M. Hwang
24
測試結果 >> seed(1024) >> random0(4) ans =
>> random0(4) ans = >> ISEED ??? Undefined function or variable 'ISEED'. 使用者定義函式 T.-M. Hwang
25
5.6 含函式的函式 是一種輸入引數包含其他函式名稱的函式,而這些傳入函式名稱的函式,會在含函式的函式執行過程中,被呼叫來使用。
fzero:內建函式,找出只含一個變數函式之零點 >> fzero('cos',[0 pi]) ans = 1.5708 >> fzero('exp(x)-2',[0 pi]) ans = 0.6931 >> pi] ) ans = 0.6931 function val = exp_2(x) val = exp(x) - 2; >> fzero('exp_2' ,[0 pi] ) ans = 0.6931 使用者定義函式 T.-M. Hwang
26
內建函式eval eval(string) >> x = eval('sin(pi/4)') x = 0.7071
>> str = ['exp(' num2str(x) ') - 1']; >> res = eval(str) res = 1.7183 s = load August1.mat load August2.mat load August3.mat - etc. - for d=1:10 s = ['load August' int2str(d) '.mat'] eval(s) end 使用者定義函式 T.-M. Hwang
27
內建函式feval feval(fun,value) >> feval('exp_2' , 0) ans = -1
feval 會針對M檔案中的(fun)函式,在特定輸入值(value)下計算其函式值 >> 0) ans = -1 >> feval('sin',pi/4) ans = 0.7071 function val = exp_2(x) val = exp(x) - 2; 使用者定義函式 T.-M. Hwang
28
範例: 問題:在特定的數值區間,產生一個含函式的函式,用來畫出任一個MATLAB單一變數的函式圖形。 第一個引數為被畫出圖形的函式名稱 要求
第二個引數為兩個元素的向量,此為函式圖形的範圍 函式需要兩個輸入引數 步驟 if ( size(xlim,1) == 1 & … size(xlim,2) == 2 ) | ... ( size(xlim,1) == 2 & … size(xlim,2) == 1 ) statements else error('Incorrect number of elements in xlim.'); end msg = nargchk(2,2,nargin); error(msg); 檢查合法的引數個數 檢查第二個引數是否擁有兩個元素 在初始點與結束點之間,計算函式的數值 繪圖並標示函式圖形 使用者定義函式 T.-M. Hwang
29
function quickplot(fun,xlim)
%QUICKPLOT Generate quick plot of a function % Check for a legal number of input arguments. msg = nargchk(2,2,nargin); error(msg); % Check the second argument to see if it has two elements. if ( size(xlim,1) == 1 & size(xlim,2) == 2 ) | ... ( size(xlim,1) == 2 & size(xlim,2) == 1 ) n_steps = 100; step_size = (xlim(2) - xlim(1)) / n_steps; x = xlim(1):step_size:xlim(2); y = feval(fun,x); plot(x,y); title(['\bfPlot of function ' fun '(x)']); xlabel('\bfx'); ylabel(['\bf' fun '(x)']); else error('Incorrect number of elements in xlim.'); end >> quickplot('sin') ??? Error using ==> quickplot Not enough input arguments. >> quickplot('sin', -2*pi) ??? Error using ==> quickplot Not enough input arguments. >> quickplot('sin', [-2*pi 2*pi]) 使用者定義函式 T.-M. Hwang
30
5.7 子函式、專用函式與巢狀函式 主函數與子函數的位置 一個 M 檔案可以包含一個以上的函數
一個主函數(Primary Function) 其他則為子函數(Subfunctions) 主函數必須與檔案名稱一樣 子函數只能被同檔案中的函數(主函數或子函數)呼叫,但不可被不同檔案的其他函數呼叫 主函數與子函數的位置 主函數必需出現在最上方 其後接上任意數目的子函數 子函數的次序並無任何限制 使用者定義函式 T.-M. Hwang
31
圖例 使用者定義函式 T.-M. Hwang
32
私有化目錄(Private Directory)
存放與這目錄相關的函數 目錄 private 之下的函數,只能被其父目錄函數所呼叫,不能被其他目錄的函數來呼叫 使用者定義函式 T.-M. Hwang
33
函數搜尋次序 從 M 檔案呼叫一個函數時,MATLAB 搜尋函數的次序 MATLAB 找到第一個檔名相符的函數,即會立即取用
檢查此函數是否為子函數 檢查此函數是否為私有化目錄的函數 從系統所設定的搜尋路徑找尋此函數 MATLAB 找到第一個檔名相符的函數,即會立即取用 使用者定義函式 T.-M. Hwang
34
巢狀函式 圖例 NEED 使用者定義函式 T.-M. Hwang
35
>> test_nested_1 Before call to fun1: a, b, x, y = 1 2 0 9
function res = test_nested_1 % Define some variables. a = 1; b = 2; x = 0; y = 9; % Display variables before call to fun1 fprintf('Before call to fun1:\n'); fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y); % Call nested function fun1 x = fun1(x); % Display variables after call to fun1 fprintf('\nAfter call to fun1:\n'); % Declare a nested function function res = fun1(y) % Display variables at start of call to fun1 fprintf('\nAt start of call to fun1:\n'); y = y + 5; a = a + 1; res = y; % Display variables at end of call to fun1 fprintf('\nAt end of call to fun1:\n'); end % function fun1 end % function test_nested_1 >> test_nested_1 Before call to fun1: a, b, x, y = At start of call to fun1: a, b, x, y = At end of call to fun1: a, b, x, y = After call to fun1: a, b, x, y = 使用者定義函式 T.-M. Hwang
Similar presentations