Download as pdf or txt
Download as pdf or txt
You are on page 1of 22

HÀM DO NGƯỜI DÙNG ĐỊNH

NGHĨA VÀ FUNCTION-FILE
• Function vô danh và Function inline
• Sử dụng function làm input cho function khác
• Sub function
• Nested function
• Ví dụ
FUNCTION VÔ DANH VÀ FUNCTION INLINE

Các function vô danh và inline được sử dụng để định nghĩa các hàm
có phần thân tính toán đơn giản, và không cần được lưu trữ trong
các .m file riêng biệt, có thể được định nghĩa ở bất kỳ vị trí nào
trong code. Phần thân của các function này chỉ là một dòng biểu
thức định nghĩa hàm
Function vô danh được giới thiệu trong bản MATLAB 7, thay thế
cho function inline trong các phiên bản MATLAB trước đó
Function vô danh và inline có thể có 1 hoặc nhiều input, nhưng chỉ
có thể có 1 output, không thể có nhiều output
FUNCTION VÔ DANH VÀ FUNCTION INLINE

function vô danh
name = @ (danh sách input) biểu thức
1 input 2 input 2 input
>> abscube = @(x) abs(x.^3) >> hieu1 = @(i,j) i - j >> hieu2 = @(j,i) i - j
abscube = hieu1 = hieu2 =
@(x)abs(x.^3) @(i, j) i - j @(j,i) i - j

>> a = [-1, 2, 3] >> hieu1(2,3) >> hieu2(2,3)


a = -1 2 3 ans = -1 ans = 1

>> abscube(a) >> hieu1(3,2) >> hieu2(3,2)


ans = 1 8 27 ans = 1 ans = -1

Biểu thức hàm có thể có 1 hoặc nhiều biến, sử dụng bất kỳ chữ cái nào
Biểu thức hàm có thể sử dụng các function có sẵn của MATLAB, cũng như function
được người dùng định nghĩa trước đó
Thứ tự các biến được chỉ định bằng thứ tự liệt kê trong dấu ()
FUNCTION VÔ DANH VÀ FUNCTION INLINE

function vô danh
Các function vô danh có thể sử dụng được các biến đã được định nghĩa trước đó.
Ví dụ nếu a,b,c đã được định nghĩa và gán giá trị từ trước, thì function vô danh
sau có thể được định nghĩa
>> a = 1; b = 2; c = 3;

>> parabol = @(x) a*x.^2 + b*x + c


parabol =
@(x)a*x.^2+b*x+c

>> parabol(1)
ans = 6
MATLAB sẽ ghi nhận các giá trị của a,b,c trước
>> a = 7 khi hàm parabol được định nghĩa, điều này có
a= 7 nghĩa là nếu như các biến a,b,c được gán cho
giá trị mới sau khi định nghĩa parabol thì hàm
>> parabol(1) parabol vẫn không thay đổi
ans = 6
FUNCTION VÔ DANH VÀ FUNCTION INLINE

function inline
name = inline (‘biểu thức hàm’)
1 input 2 input
>> cube = inline(‘x.^3') >> hieu = inline(‘a - b') >> hieu = inline('i - j')
cube = hieu = hieu =
Inline function: Inline function: Inline function:
cube(x) = x.^3 hieu(a,b) = a - b hieu(x) = i - j
>> hieu(2,3)
>> cube(4) >> hieu(2,3) ??? Error using ==>
ans = 64 ans = -1 inline.subsref at 17
Too many inputs to inline
>> cube([1,2,3]) >> hieu(3,2) function.
ans = 1 8 27 ans = 1

Biểu thức hàm có thể có 1 hoặc nhiều biến, sử dụng bất kỳ chữ cái nào, ngoài i, j
Biểu thức hàm có thể sử dụng các function có sẵn của MATLAB, cũng như function
được người dùng định nghĩa trước đó
FUNCTION VÔ DANH VÀ FUNCTION INLINE

function inline
Nếu biểu thức hàm có nhiều biến, thì có thể chỉ định thứ tự các biến bằng cách
liệt kê lần lượt. Nếu không liệt kê thứ tự các biến thì MATLAB mặc định thứ tự
này theo bảng chữ cái
Biểu thức hàm không sử dụng được các biến được định nghĩa trước đó (khác
biệt so với function vô danh)

>> hieu = inline('b - a') >> hieu = inline('b - a','b','a') >> a = 2


hieu = hieu = a= 2
Inline function: Inline function: >> y = inline('a*x')
hieu(a,b) = b - a hieu(b,a) = b - a y=
Inline function:
>> hieu(2,3) >> hieu(2,3) y(a,x) = a*x
ans = 1 ans = -1 >> y(3)
??? Error using ==>
inline.subsref at 14
Not enough inputs to
inline function.
SỬ DỤNG FUNCTION LÀM INPUT CHO FUNCTION KHÁC

Có nhiều trường hợp, một function có thể được sử dụng làm input
cho một function khác.
Ví dụ: MATLAB có hàm fzero dùng để tìm nghiệm của một hàm số.
Khi đó, input là hàm f(x) và khoảng xác định [a,b], output là giá trị
x0 nằm giữa a và b mà tại đó f(x0) = 0
Có hai cách cơ bản để gọi một function dùng làm input cho một
function khác:
1. Sử dụng function handles @
2. Sử dụng tên function dưới dạng chuỗi ký tự đặt trong dấu ‘’
SỬ DỤNG FUNCTION LÀM INPUT CHO FUNCTION KHÁC

1. Function handles @
Đây là ký hiệu dùng để truyền các function có sẵn, function người
dùng định nghĩa và function vô danh vào input
- Đối với các function có sẵn và các function file, các function
handle sẽ được tạo với dấu @ đặt trước tên của function
- Đối với các function vô danh và function inline, bản thân tên hàm
đó đã là function handle, không cần sử dụng dấu @ khi dùng làm
input cho các function khác
SỬ DỤNG FUNCTION LÀM INPUT CHO FUNCTION KHÁC

1. Function handles @
Ví dụ
Hàm funplot1 sau đây sẽ vẽ đồ thị của hàm fun trên đoạn [a,b]
Input: fun, a, b 4

Output: đồ thị của fun 3.5

funplot1.m 3

function funplot1(fun,a,b) 2.5

x = linspace(a,b,100); 2

y = fun(x); 1.5

h = plot(x,y);
set(h,'LineWidth',2); 1

0.5
f.m
function y = f(x) 0
-1 -0.5 0 0.5 1 1.5 2 2.5 3 3.5 4

y = x.^4 .* sqrt(3*x + 5)./((x.^2 + 1).^2);

>> funplot1(@f,-1,4) Gọi function có sẵn và function file


SỬ DỤNG FUNCTION LÀM INPUT CHO FUNCTION KHÁC

1. Function handles @
Ví dụ
Hàm funplot1 sau đây sẽ vẽ đồ thị của hàm fun trên đoạn [a,b]
Input: fun, a, b
8

Output: đồ thị của fun


6

funplot1.m 4

function funplot1(fun,a,b) 2

x = linspace(a,b,100); 0

y = fun(x);
-2
h = plot(x,y);
set(h,'LineWidth',2); -4

-6

>> cube = @(x) x.^3; -8


-2 -1.5 -1 -0.5 0 0.5 1 1.5 2

>> funplot1(cube,-2,2) Gọi function vô danh và function inline


SỬ DỤNG FUNCTION LÀM INPUT CHO FUNCTION KHÁC

2. Viết tên function trong dấu ngoặc đơn ‘’


Có thể dùng hàm feval để truyền các function có sẵn, function
người dùng định nghĩa và function vô danh vào input
- Đối với các function có sẵn và các function file, khi đưa vào input
cần đặt trong dấu ngoặc đơn ‘’
- Đối với các function vô danh và function inline, khi đưa vào input
không cần đặt trong dấu ngoặc đơn ‘’

Function feval f.m


>> feval('sqrt',64) function y = f(x)
ans = 8 y = x.^4 .* sqrt(3*x + 5)./((x.^2 + 1).^2);

>> x = feval('sin',pi/6) >> feval('f',2)


x = 0.5000 ans = 2.1226
SỬ DỤNG FUNCTION LÀM INPUT CHO FUNCTION KHÁC

2. Viết tên function trong dấu ngoặc đơn ‘’


Ví dụ
Hàm funplot2 sau đây sẽ vẽ đồ thị của hàm fun trên đoạn [a,b]
Input: fun, a, b 4

Output: đồ thị của fun 3.5

funplot2.m 3

function funplot2(fun,a,b) 2.5

x = linspace(a,b,100); 2

y = feval(fun,x); 1.5

h = plot(x,y);
set(h,'LineWidth',2); 1

0.5
f.m
function y = f(x) 0
-1 -0.5 0 0.5 1 1.5 2 2.5 3 3.5 4

y = x.^4 .* sqrt(3*x + 5)./((x.^2 + 1).^2);

>> funplot2('f',-1,4) Gọi function có sẵn và function file


SỬ DỤNG FUNCTION LÀM INPUT CHO FUNCTION KHÁC

2. Viết tên function trong dấu ngoặc đơn ‘’


Ví dụ
Hàm funplot2 sau đây sẽ vẽ đồ thị của hàm fun trên đoạn [a,b]
Input: fun, a, b
8

Output: đồ thị của fun


6

funplot2.m 4

function funplot2(fun,a,b) 2

x = linspace(a,b,100); 0

y = feval(fun,x);
-2
h = plot(x,y);
set(h,'LineWidth',2); -4

-6

>> cube = @(x) x.^3; -8


-2 -1.5 -1 -0.5 0 0.5 1 1.5 2

>> funplot2(cube,-2,2) Gọi function vô danh và function inline


VÍ DỤ: FUNCTION CÓ INPUT LÀ FUNCTION

Đề bài: Viết function tính gần đúng tích phân của một hàm số, input là f,a,b;
output là tích phân của f trên đoạn [a,b]

tichphan.m
function s = tichphan(f,a,b)
x = linspace(a,b,1e6);
y = f(x);
s = sum(y(2:end))*(b-a)/(length(x)-1);

cube.m
function y = cube(x)
y = x.^3;

>> tichphan(@cube,1,5)
ans = 156.0025

>> tichphan(@cos,1,2)
ans = 0.0678
SUB FUNCTION

Một function file có thể chứa 1 hoặc nhiều function người dùng định nghĩa.
Function đầu tiên sẽ gọi là function mẹ (function chính, primary function), các
function tiếp theo sẽ gọi là các function con (sub function)
Cách viết, lưu trữ: Các sub function có thể được viết theo thứ tự bất kỳ. Mỗi
function đều phải có dòng định nghĩa riêng. Tên của function file nên được đặt
trùng với tên của function mẹ
Công dụng: giúp việc lập trình được tổ chức tốt hơn. Toàn bộ công việc được
chia thành nhiều đầu việc nhỏ, thực hiện bởi các function con tương ứng
Gọi nhau: Bên trong function file, mỗi function đều có thể gọi bất kỳ function
nào khác trong cùng file đó. Bên ngoài function file, chỉ duy nhất function chính
có thể được gọi
Nhận diện biến của nhau: Function mẹ và các sub function đều có không gian
biến riêng, tức là các biến của các function này đều là local của riêng function đó,
và không nhận diện được các biến của nhau
VÍ DỤ: SUB FUNCTION

dientichtamgiac2.m
Đề bài: Viết function tính diện tích
function S = dientichtamgiac2(A,B,C)
tam giác ABC khi biết tọa độ 3 đỉnh AB = vecto(A,B);
của tam giác, sử dụng công thức AC = vecto(A,C);
S = dientich(AB,AC);
1
S AB  AC
2 function u = vecto(A,B)
u = B - A;
dientichtamgiac1.m
function s = dientich(AB,AC)
function S = dientichtamgiac1(A,B,C) ABAC = cross(AB,AC);
AB = B - A; s = 1/2*sqrt(sum(ABAC.^2));
AC = C - A;
ABAC = cross(AB,AC); >> a=[0 0 0]; b=[3 0 0]; c=[0 4 0];
S = 1/2*sqrt(sum(ABAC.^2)); >> dientichtamgiac2(a,b,c)
ans = 6
>> a=[0 0 0]; b=[3 0 0]; c=[0 4 0]; >> vecto(a,b)
>> dientichtamgiac1(a,b,c) ??? Undefined function or method 'vecto'
ans = 6 for input arguments of type 'double'.
NESTED FUNCTION
Cách viết, lưu trữ: Khác với subfunction, nested function và các function mẹ đều
bắt buộc phải có từ khóa end khi kết thúc function
Gọi nhau:
Sub function chỉ có hai cấp là mẹ và con, còn nested function có thể có nhiều cấp
ông bà con cháu chắt
Một nested function có thể được gọi bởi các function ở cấp kề trên, các function ở
cùng cấp, hoặc các nested function cấp dưới của nó (mẹ gọi được con, anh gọi được
em, nhưng bà không gọi được cháu, còn con cháu thì gọi được tất cả ông bà bố mẹ)
Nhận diện biến của nhau:
Khác với các sub function, các nested function và các function mẹ có thể truy cập
không gian biến của nhau
Một biến được định nghĩa ở function chính có thể được nhận diện và gán lại giá trị
trong các nested function ở mọi cấp dưới của function chính
Một biến được định nghĩa ở trong một nested function có thể được nhận diện và
gán lại giá trị trong mọi function cấp trên của nested function đó
NESTED FUNCTION
1 nested function
B được nested trong A
A, B có thể truy cập không gian biến của
nhau
A, B có thể gọi nhau
Lưu ý từ khóa end cho mỗi function A, B

2 nested function ở cùng cấp


B, C được nested trong A ở cùng một cấp bậc
A, B, C có thể truy cập không gian biến của nhau
A, B, C có thể gọi nhau
Lưu ý từ khóa end cho mỗi function A, B, C
NESTED FUNCTION

2 (nhiều) cấp nested function


A là function chính
B nested trong A (B là con A)
C nested trong B (C là con B, là cháu A)
D nested trong A
E nested trong D
A chỉ có thể gọi B và D, không thể gọi C và E
B, D có thể gọi nhau
VÍ DỤ

Đề bài: Viết một function tính toán n!, đặt tên >> giaithua1(12)
function là y = giaithua(n), trong đó n là số nguyên ans = 479001600
dương. Yêu cầu function trả lại tin nhắn báo lỗi
nếu input là một số không phải nguyên dương. >> giaithua1(-2)
Error: n khong la so nguyen duong

function y = giaithua1(n) >> a = giaithua1(-2)


if (n ==floor(n)) & (n>0) Error: n khong la so nguyen duong
y = prod([1:n]);
else Error in ==> giaithua1 at 2
fprintf('Error: n khong la so nguyen duong \n') if (n ==floor(n)) & (n>0)
end
??? Output argument "y" (and
function y = giaithua2(n) maybe others) not assigned
if (n ==floor(n)) & (n>0) during call to "C:\Users\KHOA CHKT
y = prod([1:n]); & TDH\giaithua1.m (giaithua1)".
else
fprintf('Error: n khong la so nguyen duong \n') >> a = giaithua2(-2)
y = NaN; Error: n khong la so nguyen duong
end a = NaN
VÍ DỤ
Đề bài: Viết function tính toán điểm trung bình chung (GPA) theo thang 0-4, trong đó A = 4,
B = 3, C = 2, D = 1 và E = 0, đặt tên function là av = GPA(diem,tinchi). Trong đó diem là véc tơ
có thành phần A,B,C,D,E; tinchi là véc tơ số tín chỉ. Dùng function này để tính toán cho
trường hợp diem = [‘BACEABDB’] và tinchi = [3 4 3 4 3 4 3 2].

function y = GPA(diem,tinchi) >> diem = 'BACEABDB'


tong = 0; diem =
for k = 1:length(diem) BACEABDB
switch diem(k)
case 'A' >> tinchi = [3 4 3 4 3 4 3 2]
tong = tong + 4 *tinchi(k); tinchi =
case 'B' 3 4 3 4 3 4 3 2
tong = tong + 3 *tinchi(k);
case 'C' >> GPA(diem,tinchi)
tong = tong + 2 *tinchi(k); ans =
case 'D' 2.4615
tong = tong + 1 *tinchi(k);
end
end
y = tong/sum(tinchi);

You might also like