user-defined functions charturong.ee.engr.tu.ac.th/cn208
DESCRIPTION
User-Defined Functions charturong.ee.engr.tu.ac.th/CN208. จาตุรงค์ ตันติบัณฑิต ภาควิชาวิศวกรรมไฟฟ้าและคอมพิวเตอร์ มหาวิทยาลัยธรรมศาสตร์. เอกสารประกอบการสอนนี้จัดทำโดย ดร.ทรงยศ นาคอริยกุล. Introduction. - PowerPoint PPT PresentationTRANSCRIPT
User-Defined Functions
charturong.ee.engr.tu.ac.th/CN208
จาตรงค ตนตบณฑตภาควชาวศวกรรมไฟฟาและคอมพวเตอร
มหาวทยาลยธรรมศาสตร
เอกสารประกอบการสอนนจดทำาโดย ดร.ทรงยศ นาคอรยกล
2
Introduction
เราไดเรยนรการออกแบบโปรแกรมแบบ top-down design โดยการแตกปญหาใหญใหเปนปญหายอยๆซงงายตอการเขาใจและแกไข จากนนจงเขยนโปรแกรมแกปญหายอยๆเหลาน กอนทจะนำาโปรแกรมยอยๆเหลานมารวมกนเพอใชแกปญหาใหญทเราม
ในการออกแบบโปรแกรมแบบ top-down design น โปรแกรม MATLAB ใหผเขยนมโอกาสเขยนฟงกชน (function) ของตวเอง โดยเขยนหนงฟงกชนสำาหรบแกหนงปญหายอย จากนนผเขยนสามารถนำาฟงกชนเหลานมารวมกนเพอแกปญหาใหญทไดรบ
M-files ทเราไดฝกเขยนมาทงหมดไมใชฟงกชนแตเปน script files (การรวมเอาคำาสง MATLAB มารวมกนและประยกตใชในหนงโปรแกรม)
3
ประโยชนของการเขยนฟงกชนของตวเอง
1 .ตรวจสอบไดงายและไมขนกบโปรแกรมอน (independent testing of sub-tasks)
2. สามารถนำามาใชไดอกหลายครง (reusable code)3. ปองกนขอผดพลาดไดด (isolation from unintended side effects)
4
การเขยนฟงกชนของตวเองการเขยน MATLAB ฟงกชนตองเขยนเปน M-file พเศษททำางานโดยม
รปแบบดงตอไปน
function [outarg1, outarg2, …] = fname(inarg1, inarg2, …)% H1 comment line% Other comment lines
(Executable code)…
(end)
5
คำาสง function ใชแสดงจดเรมตนของฟงกชน ในบรรทดแรกคำาสง function บงบอกชอของฟงกชน และขอมลทใช (input) และผลลพธของฟงกชน (output) โดยท input argument list (inarg1, inarg2, …) จะปรากฎในเครองหมายวงเลบ ( ) (parentheses) หลงชอของฟงกชน และ output argument list (outarg1, outarg2, …) จะปรากฎในเครองหมายวงเลบสเหลยม [ ] (brackets) ทางดานซายมอของเครองหมายเทากบ ถาม output แค output เดยว เราไมจำาเปนตองใชเครองหมายวงเลบสเหลยม
แตละฟงกชนตองถกเซฟเปน .m file โดยใชชอของไฟลเปนชอเดยวกนกบชอฟงกชน นนคอถาหากเราตงชอฟงกชนวา My_fun ฟงกชนนนตองถกเซฟโดยใชชอ My_fun.m
6
ใน input argument list จะระบชอและจำานวนของตวแปรทจะใชในฟงกชนนน ชอของตวแปรนนเปนแบบตวแปรชวคราว หรอ dummy argument ซงใชสำาหรบรบคาขอมลทแทจรงเวลาทฟงกชนถกเรยกใช ชอของตวแปรเหลานจะถกกำาจดทงหลงจากท MATLAB ประมวลผลฟงกชนนนเสรจสนแลว
ใน output argument list จะระบชอและจำานวนของตวแปรทฟงกชนนนจะใหผลลพธออกมาหลงจากทฟงกชนนนทำาการประมวลผลเสรจแลว ซงมการทำางานคลายกบ input argument list
การใชคำาสง end เพอบอกวาเปนจดสนสดของฟงกชนมการเรมใชตงแต MATLAB 7.0 เปนตนไป ซงการเขยนคำาสง end เพอจบฟงกชนนนจะเขยนหรอไมเขยนกได เวลาเขยนคำาสง end เพอจบฟงกชนมกจะตามดวยการเขยน comment เพอระบวาสำาหรบฟงกชนไหน
7
การเขยน comment บรรทดแรกในฟงกชน หรอทเรยกวา H1 comment line นน ใชเพอระบหนาทหรอจดประสงคของฟงกชนนน ซง comment บรรทดแรกมความพเศษทจะถกคนหาและแสดงผลบนหนาจอเมอใชคำาสง lookfor ในหนาตางคำาสงใน MATLAB สวน comment บรรทดทเหลอทตามมาหลงจาก H1 comment line จนกระทงถงบรรทดวางบรรทดแรกหรอคำาสงททำางานไดของ MATLAB จะถกแสดงโดยใชคำาสง help
8
ตวอยางท 1 การเขยนฟงกชน function distance = dist2 (x1, y1, x2, y2)% dist2 calculates the distance between two points % Function dist2 calculates the distance between % two points (x1, y1) and (x2, y2) in a Cartesian % coordinate system
% Calculate distancedistance = sqrt((x2-x1).^2 + (y2-y1).^2);
end % function distance
9
การคนหาฟงกชนทเขยนดวยตวเอง• เมอเขยนฟงกชน dist2 เสรจ ใหเซฟลงบนฮารดดสคคอมพวเตอรโดยใชชอ
dist2.m• บนหนาตางคำาสงของ MATLAB (command window) เราสามารถ
ทดลองใชคำาสง lookfor หรอ help เพอหาคำาแนะนำาเกยวกบฟงกชน dist2 ซง MATLAB จะแสดงผลลพธออกบนหนาจอทกคำาสงทมชอ dist2 ดงน>> lookfor dist2 dist2 calculates the distance between two points DIST2STR Distance conversion to a stringEUCDIST2 Compute 2-D Euclidean distance transform.
• การใชคำาสง help จะแสดง comment ใน dist2 ไปจนถงบรรทดทวาง>> help dist2
dist2 calculates the distance between two points Function dist2 calculates the distance between two points (x1, y1) and (x2, y2) in a Cartesian coordinate system
10
การใชฟงกชน dist2
เราสามารถเรยกใชฟงกชน dist2 ไดสองวธ คอ 1. ในหนาตาง command window โดยตรง เชน หากเราตองการหา
ระยะทางระหวางจด (0, 1) กบ จด (2, 4) กทำาไดดงน
>> out = dist2 (0, 1, 2, 4)out = 3.6056
ซงจะเหนไดวาผลลพธของฟงกชน dist2 ไมจำาเปนตองใชชอตวแปรวา distance แตจะเปนชอตวแปรใดๆกได
2. เขยนและเรยกใชใน script file เหมอนการเรยกใชฟงกชน MATLAB ทวไป
11
ตวอยางการใชฟงกชนของตวเองใน script file% Script file: test_dist2.m%% Purpose: This program tests function dist2
% Get input datadisp('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 functionresult = dist2(ax, ay, bx, by);
% Write out resultfprintf('The distance between points a and b is %f\n', result);
12
ซงผลลพธของการ run ของ script file ขางตนทชอ test_dist2 มดงน>> test_dist2Calculate the distance between two points:Enter x value of point a: 0Enter y value of point a: 1Enter x value of point b: 2Enter y value of point b: 4The distance between points a and b is 3.605551
13
ตวอยางท 2 การเขยนฟงกชนจงเขยนไฟลฟงกชนเพอหาตวประกอบทงหมดของเลขจำานวนเตมบวกท
กำาหนดให กำาหนดใหฟงกชนมรปแบบการเรยกใชงานคอ fac = find_factor(num) โดยท num เปนตวเลขจำานวนเตมบวก และ เอาตพต fac เปนเวกเตอรทมตวประกอบของตวเลข num เปนสมาชก
14
function fac = find_factor(num) % find_factor finds all of the factors of a positive integer
ind = 1;for ii = 1:num % if num/ii has a remainder of 0, ii is a factor of num
if mod(num, ii) = = 0fac(ind) = ii;ind = ind + 1;
endend
end % function find_factor
15
การผานคาตวแปรในฟงกชนของ MATLAB
โปรแกรม MATLAB ใชเทคนคทเรยกวา pass-by-value ในการเรยกใชฟงกชน เมอฟงกชนถกเรยกใช MATLAB จะสรางสำาเนา (copy) ของตวแปรอนพตนและใชตวแปรสำาเนานในฟงกชน นนคอแมในฟงกชนคาของตวแปรอนพตนจะถกเปลยน คาของตวแปรตนฉบบจะไมถกเปลยนแปลง
ขอดของการใชเทคนค pass-by-value คอชวยปองกนการผดพลาดในการเขยนโปรแกรม ถงแมในฟงกชนจะม bugs แตจะไมมผลกระทบตอคาของตวแปรตนฉบบ
16
ยกตวอยางการผานคาตวแปรแบบ pass-by-value โดยการสรางฟงกชน sample ดงนfunction out = sample(a, b)fprintf('In function sample: a = %4.2f, b = %4.2f %4.2f\n', a, b);a = b(1) + 2*a;
b = a .* b;out = a + b(1);fprintf('In function sample: a = %4.2f, b = %4.2f %4.2f\n', a, b);
เราสามารถทดลองการผานคาตวแปรโดยเขยน script file ชอ test_sample.m ดงนa = 2; b = [6 4];fprintf('Before function sample: a = %4.2f, b = %4.2f %4.2f\n', a, b);out = sample(a, b);fprintf('After function sample: a = %4.2f, b = %4.2f %4.2f\n', a, b);fprintf('After function sample: out = %4.2f\n', out);
17
ผลลพธทไดจากการประมวลผลโปรแกรม test_sample ในหนาตางคำาสงคอ
>> test_sampleBefore function sample: a = 2.00, b = 6.00 4.00In function sample: a = 2.00, b = 6.00 4.00In function sample: a = 10.00, b = 60.00 40.00After function sample: a = 2.00, b = 6.00 4.00After function sample: out = 70.00
ซงจะเราจะเหนไดวา คาของตวแปร a และ b ถกเปลยนภายในฟงกชน sample แตการเปลยนแปลงนไมมผลกระทบตอตวแปรตนฉบบ
18
การเรยงตวเลข (sorting)
การเรยงตวเลข (sorting) คอการนำาตวเลขทงหมดในฐานขอมลมาจดลำาดบจากมากไปนอย หรอ จากนอยไปมาก ซงการเรยงตวเลขนมประโยชนอยางมากทางวศวกรรม
เราฝกเรยงตวเลขอยเปนประจำา จงทำาใหปญหานดเปนเรองทงาย เชนการเรยง [10 3 -1 5 8] จากนอยไปมากเปน [-1 3 5 8 10] น เราทำาไดอยางไร?
ขนตอนการเรยงตวเลขทเราคนเคยคอ เราหาตวเลขทมคานอยทสดจากตวเลขทง 5 กอน ซงนนคอตวเลข -1 จากนนเราจงมองหาตวเลขทนอยทสดตวตอไปในเลขทเหลอ [10 3 5 8] ซงคอตวเลข 3 ทำาอยางนตอไปเรอยจนกระทงตวเลขทงหมดถกเรยง กระบวนการเรยงตวเลขแบบนเรยกวา selection sort
19
Selection Sortการเรยงตวเลขทเรยกวา Selection Sort คอกระบวนการเรยงตวเลขท
งายทสด ซงการเรยงจากนอยไปมากทำาไดอยางทไดกลาวมาแลวในเบองตน
1 .คนหาตวเลขทมคานอยทสดในเวกเตอร และนำาคาตวเลขนนมาไวเปนตวแรกสดของแถวโดยสลบเปลยนตวเลขนนกบเลขตวแรกของแถว แตถาคาตวแรกของแถวมคานอยสดอยแลว ไมตองทำาอะไร
2 .ตรวจตวเลขตงแตตวท 2 เปนตนไป เพอคนหาตวเลขทมคานอยทสดตวตอไป และทำาการสลบเปลยนตวเลขนนกบเลขตวทสองของแถว แตถาคาตวทสองของแถวมคานอยทสดเปนตวทสองอยแลว ไมตองทำาอะไร
3 .ทำาแบบนไปเรอยๆ จนกระทงเหลอแค 2 ตวสดทาย หลงจากทำาการสลบเปลยนตวเลขสองตวสดทายในเวกเตอรแลว เปนอนจบการเรยงตวเลข
20
10 3 -1 5 8
-1 3 10 5 8
สลบ
ไมตองสลบ
-1 3 10 5 8
สลบ
-1 3 5 10 8
-1 3 5 8 10
สลบ
21
selection_sort(arr)
เราสามารถเขยน pseudocode สำาหรบ selection_sort ไดดงตอไปน
for (each index position ii in the arr)find kk (the index the smallest value between ii and the end of the array
arr)swap the elements at index position ii and kk
end
22
function out = selection_sort(arr)% selection_sort sorts data in ascending order
nvals = length(arr); for ii = 1:(nvals-1)
kk = find_smallest_number(arr, ii);% swap the elements at index position ii and kk if ii ~= kkif ii ~= kktemp = arr(ii);arr(ii) = arr(kk);arr(kk) = temp;end
endout = arr;
end % function selection_sort
selection_sort.m
23
function ind = find_smallest_number(arr, ii)% find_smallest_number finds the index of the smallest number in arr between ii% and the end of the arr
nvals = length(arr); ind = ii;
for jj = (ii+1):nvalsif arr(jj) < arr(ind)
ind = jj; endend end % function find_smallest_number
24
Bubble Sort
การเรยงตวเลขแบบ bubble sort เรมตนการเรยงโดยการเปรยบเทยบเลข 2 ตวแรกในฐานขอมล และสบเปลยนตำาแหนงตวเลข 2 ตวนใหอยในตำาแหนงทถกตอง จากนนจะทำาการเปรยบเทยบตวเลขตวท 2 และตวท 3 ในฐานขอมลตอไป และทำาการสบเปลยนตำาแหนงถาจำาเปน ทำาแบบนตอไปเรอยๆจนจบแถว จากนนเราจะเรมตนเปรยบเทยบเลข 2 ตวแรกในฐานขอมลใหมแบบนตอไปเรอยๆ จนกวารอบนนจะไมมการสบเปลยนเกดขน จงเปนอนจบการเรยงตวเลขแบบ bubble sort
25
ตวอยางการเรยงตวเลขแบบ bubble sort ของ [10 3 -1 5 8] ทำาไดดงน
เรยงรอบท 1:[10 3 -1 5 8] [3 10 -1 5 8] จดอนดบ 2 ตวเลขแรก[3 10 -1 5 8] [3 -1 10 5 8] จดอนดบ 2 ตวเลขตอไป[3 -1 10 5 8] [3 -1 5 10 8] [3 -1 5 10 8] [3 -1 5 8 10]
เรยงรอบท 1 มการสบเปลยนตำาแหนง 4 ครงเรยงรอบท 2:[3 -1 5 8 10] [-1 3 5 8 10] [-1 3 5 8 10] [-1 3 5 8 10] [-1 3 5 8 10] [-1 3 5 8 10][-1 3 5 8 10] [-1 3 5 8 10]
เรยงรอบท 2 มการสบเปลยนตำาแหนง 1 ครง
26
เรยงรอบท 3:[-1 3 5 8 10] [-1 3 5 8 10] [-1 3 5 8 10] [-1 3 5 8 10] [-1 3 5 8 10] [-1 3 5 8 10][-1 3 5 8 10] [-1 3 5 8 10]
เรยงรอบท 3 มการสบเปลยนตำาแหนง 0 ครง เพราะฉะนนจบการเรยงแบบ bubble sort
27
bubble_sort(arr)เราสามารถเขยน pseudocode สำาหรบ selection_sort ไดดงตอไปนwhile swap occurs
% compare two adjacent numbers and swap their positions if necessary for ii = 1:(nvals-1)
if arr(ii) > arr(ii+1) temp = arr(ii); arr(ii) = arr(ii+1); arr(ii+1) = temp;
end end
end
28
function out = bubble_sort(arr)% bubble_sort sorts data in ascending order
swap = 1;nvals = length(arr);
while swap = = 1 % while swap = = 1, continue sorting swap = 0; for ii = 1:(nvals-1) if arr(ii) > arr(ii+1) temp = arr(ii); arr(ii) = arr(ii+1); arr(ii+1) = temp; swap = 1; % swap = 1 indicates that swapping occurs end endendout = arr;
end % function bubble_sort
bubble_sort.m
29
Optional Argumentsฟงกชน MATLAB มการใชตวแปรอนพตและเอาตพตแบบมหรอไมมกได
(optional input and output arguments) ยกตวอยางเชน การใชฟงกชน plot ซงมตวแปรอนพตตงแต 2 ตว ไปจนถงมากกวา 7 ตว เปนตน ซง MATLAB รไดอยางไรวาฟงกชนเหลานมตวแปรอนพต หรอ เอาตพตกตว
MATLAB มฟงกชนพเศษสำาหรบอานจำานวนตวแปรในฟงกชน และ แสดงคำาเตอนดงตอไปน
• nargin – ใหคาจำานวนของตวแปรอนพตในฟงกชน• nargout – ใหคาจำานวนของตวแปรเอาตพตในฟงกชน• nargchk – แสดงขอความวามความผดพลาดโดยอตโนมต ถาฟงกชนทถกเรยก
มจำานวนตวแปรอนพตหรอเอาตพตมากหรอนอยเกนไป• error – แสดงขอความวามขอผดพลาด (error message) และยกเลกการเรยกฟง
กชน• warning – แสดงคำาเตอนแตใหฟงกชนทำางานตอไป• inputname -- ใหชอของตวแปรอนพตตามตำาแหนงทถกระบ
30
1. ฟงกชน nargin และ nargout ตองถกเรยกใชภายในการเขยนฟงกชน ซงจะใหคาจำานวนตวแปรอนพตและเอาตพตเวลาทฟงกชนถกเรยกใช
2. ฟงกชน nargchk สรางขอความทแสดงขอผดพลาดถาฟงกชนมจำานวนตวแปรอนพตหรอเอาตพตนอยเกนไป มรปแบบการใชงานคอmessage = nargchk(min_args, max_args, num_args);
โดยท min_args เปนจำานวนนอยทสดของตวแปรทเปนไปได max_args เปนจำานวนมากทสดของตวแปรทเปนไปได และ num_args เปนจำานวนตวแปรทแทจรงทถกเรยกใช ถาจำานวนตวแปรไมอยภายในจำานวนทกำาหนดไว ขอความผดพลาดจะถกแสดงอตโนมตในตวแปร message
3. ฟงกชน error ใชแสดงขอความวามขอผดพลาดและยกเลกการเรยกฟงกชนนน โดยมการเรยกใชคอ error(‘msg’) โดยท msg คอขอความทเรากำาหนดใหแสดงเวลาขอผดพลาดเกดขน
31
4. ฟงกชน warning ใชแสดงคำาเตอนซงจะระบชอฟงกชน และบรรทดทปญหาเกดขน แตจะปลอยใหฟงกชนทำางานตอไป โดยมการใชคอ warning(‘msg’) โดยท msg เปนขอความทแสดงคำาเตอน
5. ฟงกชน inputname ใชแสดงชอของตวแปรอนพตเวลาทฟงกชนถกเรยกใชจรง มรปแบบการใชคอ name = inputname(argno); โดยท argno เปนตำาแหนงของตวแปรอนพต เชน function myfun(x, y, z)name = inputname(2);disp(['The second argument is named ' name]);เมอฟงกชนนถกเรยกใชในหนาตางคำาสง ผลลพธคอ>> dog = 1; cat = 2;>> myfun(dog, cat)The second argument is named cat
32
ตวอยางการใช optional argumentsfunction [mag, angle] = polar_value(x, y)% polar_value converts (x,y) to (r, theta)
% angle -- Angle in degrees, msg -- Error message, mag -- Magnitude% x -- Input x value, y -- Input y value (optional)
% Check for a legal number of input argumentsmsg1 = nargchk(1,2,nargin);error(msg1);
% If the y argument is missing, set it to 0if nargin < 2
y = 0;end
33
% Check for (0,0) input arguments, and print out a warning messageif x == 0 & y == 0
msg2 = 'Both x and y are zero: angle is meaningless.';warning(msg2);
end
% Now calculate the magnitude.mag = sqrt(x.^2 + y.^2);
% If the second output is present, calculate angle in degrees.if nargout == 2
angle = atan2(y, x) * 180/pi;end
end % function polar_value
34
การทดลองเรยกใชฟงกชน polar_value
เราจะเรยกใชฟงกชน polar_value ในหนาตางคำาสง เพอทดสอบการใช optional arguments
1. ทดสอบจำานวนตวแปรอนพต>> [mag angle] = polar_value??? Error using ==> polar_valueNot enough input arguments.>> [mag angle] = polar_value(1, -1, 1)??? Error using ==> polar_valueToo many input arguments.
35
2. ทดสอบการใชคำาสง warning เมอ x = 0 และ y = 0>> [mag angle] = polar_value(0, 0)Warning: Both x and y are zero: angle is meaningless.> In polar_value at 19mag =
0angle =
0
36
3. ทดสอบการใชฟงกชน polar_value กบ 1 หรอ 2 ตวแปรอนพต>> [mag angle] = polar_value(1)mag =
1angle =
0>> [mag angle] = polar_value(1, -1)mag =
1.4142angle =
-45
37
4. ทดสอบการใชฟงกชน polar_value กบ 1 หรอ 2 ตวแปรเอาตพต>> mag = polar_value(1, -1)mag =
1.4142>> [mag angle] = polar_value(1, 0)mag =
1angle =
0