Giáo trình Matlab căn bản - Chương 3: Hệ phương trình đại số tuyến tính
Phương pháp khử Gauss: Chúng ta biết rằng các nghiệm của hệ không đổi
nếu ta thay một hàng bằng tổ hợp tuyến tính của các hàng khác. Ta xét một hệ
phương trình đại số tuyến tính có ma trận [A] không suy biến với m = n = 3.
Phương trình có dạng:
11 1 12 2 13 3 1
21 1 22 2 23 3 2
31 1 32 2 33 3 3
ax ax ax b
ax ax ax b
ax ax ax b
++= ⎧
⎪
++= ⎨
⎪
++= ⎩
(1)
) Trước hết ta khử x1 ra khỏi các phương trình, ngoại trừ phương trình đầu
tiên, bằng cách nhân phương trình đầu tiên với ai1/a11 (i là chỉ số hàng) và trừ
đi mỗi phương trình đó:
(0) (0) (0) (0)
11 1 12 2 13 3 1
(1) (1) (1)
22 2 23 3 2
(1) (1) (1)
32 2 33 3 3
ax ax ax b
ax ax b
ax ax b
⎧ ++= ⎪
+= ⎨
⎪
+= ⎩
end
end
i
function x = pythag(y,z)
%tinh sqrt( y^2 + z^2 ).
rmax = max(abs([y;z]));
if (rmax == 0)
x = 0;
else
x = rmax*sqrt((y/rmax)^2 + (z/rmax)^2);
end
Để giải hệ phương trình ta dùng chương trình ctlsqr.m:
clear all, clc
maxiter = 50;
A = [ 1 3 4; 2 5 7; 3 1 2];
b = [8 14 6]ʹ;
x = lsqr(A, b, maxiter)
§26. PHƯƠNG PHÁP SYMMLQ
Liên quan đến phương pháp MINRES và CG là thuật toán SYMMLQ do
Paige và Saunders đưa ra. Ta xét hệ phương trình [A][X] = [B] với [A] là ma
trận đối xứng nhưng không cần xác định dương. Ta chọn nghiệm ban đầu là
β1[v1] = {B], [ ]1 2Bβ = . Tại lần lặp thứ k của phương pháp CG ta có được xk
sao cho [rk] = [B] ‐ [A][Xk] trực giao. Do [Vk] là cơ sở trực giao nên ta có thể đặt
[Xk] = [Vk][yk] và có:
[rk] = [B] ‐ [A][Vk][yk] = β1[v1] ‐ [Vk][Tk][yk] ‐ [ ] [ ] [ ]Tk 1 k k 1( e y ) v+ +β (1)
Do [ ] [ ]Tk kV r 0= nên nhân (1) với [ ]TkV và dùng [ ] [ ]Tk k 1V v 0+ = và [ ]Tk 1 1V v e= ta
có:
[ ] [ ] [ ][ ]Tk k 1 1 k k0 V r e T y= = β − (2)
để giải hệ (2), Paige và Saunders đề nghị thực hiện phép phân tích LQ:
[ ] [ ][ ] [ ] [ ] [ ]T Tk k k k kT L Q Q Q E= =
201
với [ ]kL là ma trận tam giác và [ ]kQ là ma trận trực giao. Thuật toán
SYMMLQ gồm các bước sau:
‐ Cho x0
‐ Tính x = xo, r = b ‐ Ax, rρ = , v r= ρ
‐ β = 0, 0β =% , c = ‐1, s = 0, k = ρ
‐ vold = 0, w = v, g = 0, g 0=%
‐ Lặp khi k < tol:
• oldv Av v= − β%
• v * vα = % , v v v= − α% %
• vβ = % , oldv v= , v v /= β%
• 1l s c= α − β% , 2l s= β
• s cα = − β − α%% , cβ = β%
• 2 20l = α + β%
• 0 0c l ,s l= α = β%
• 1 2 0ˆ ˆg g l g, g l g, g g l= − = − =% %
• x x (gc)w+(gs)v= +
• w = sw ‐ cv
• 2 2ˆk g g= +%
Ta xây dựng hàm symmlq() để thực hiện thuật toán này:
function x = symmlq(A, b, x, maxiter, tol)
%Ham thuc hien thua toan SYMMLQ voi A la ma tran doi xung
[m,n] = size(A);
n2b = norm(b);
xmin = x;
imin = 0;
tolb = tol * n2b;
r = b ‐ A * x;
normr = norm(r);
normrmin = normr;
v = r;
vold = r;
u = vold;
v = u;
202
beta1 = voldʹ * v;
beta1 = sqrt(beta1);
vv = v / beta1;
wbar = vv;
v = A * vv;
alpha = vvʹ * v;
v = v ‐ (alpha/beta1) * vold;
numer = vvʹ * v;
denom = vvʹ * vv;
v = v ‐ (numer/denom) * vv;
volder = vold;
vold = v;
u = vold;
v = u;
betaold = beta1;
beta = voldʹ * v;
beta = sqrt(beta);
gammabar = alpha;
deltabar = beta;
gamma = sqrt(gammabar^2 + beta^2);
cs = gammabar / gamma;
sn = beta / gamma;
zeta = beta1 / gamma;
epsilonzeta = 0;
normrcgcs = abs(beta1 * sn);
if (cs == 0)
normrcg = Inf;
else
normrcg = normrcgcs / abs(cs);
end
stag = 0;
for i = 1 : maxiter
vv = v / beta;
w = cs * wbar + sn * vv;
stagtest = zeros(n, 1);
ind = (x ~= 0);
203
stagtest(ind) = w(ind) ./ x(ind);
stagtest(~ind & (w ~= 0)) = Inf;
if (zeta == 0) | (abs(zeta)*norm(stagtest, inf) < eps)
stag = stag + 1;
else
stag = 0;
end
x = x + zeta * w;
wbar = sn * wbar ‐ cs * vv;
v = A * vv;
v = v ‐ (beta / betaold) * volder;
alpha = vvʹ * v;
v = v ‐ (alpha / beta) * vold;
volder = vold;
vold = v;
u = vold;
v = u;
betaold = beta;
beta = voldʹ * v;
if (beta < 0)
break
end
beta = sqrt(beta);
delta = cs * deltabar + sn * alpha;
deltazeta = ‐ delta * zeta;
gammabar = sn * deltabar ‐ cs * alpha;
epsilon = sn * beta;
deltabar = ‐ cs * beta;
gamma = sqrt(gammabar^2 + beta^2);
csold = cs;
snzeta = sn * zeta;
cs = gammabar / gamma;
sn = beta / gamma;
epszdelz = epsilonzeta + deltazeta;
epsilonzeta = ‐ epsilon * zeta;
zeta = epszdelz / gamma;
204
mrcg = norm((csold*epszdelz/gammabar ‐ snzeta)*vold);
normr = sqrt(epszdelz^2 + epsilonzeta^2);
normrcgcs = normrcgcs * abs(sn);
if (cs == 0)
normrcg = Inf;
else
normrcg = normrcgcs / abs(cs);
end
if (normr <= tolb)
r = b ‐ A * x;
normr = norm(r);
if (normr <= tolb)
break
end
end
if (normrcg <= tolb)
xcg = x + (epszdelz/gammabar) * wbar;
r = b ‐ A * xcg;
normrcg = norm(r);
if (normrcg <= tolb)
x = xcg;
break
end
end
if (stag >= 2)
break
end
if (normr < normrmin)
normrmin = normr;
xmin = x;
imin = i;
end
end
r = b ‐ A * x;
normr = norm(r);
i
205
Để giải hệ phương trình bằng thuật toán SYMMLQ ta dùng chương trình
ctsymmlq.m:
clear all, clc
A = [ 1 2 4 1;2 3 1 5;4 1 1 6;1 5 6 5];
b = [ 8 11 12 17]ʹ;
maxiter = 50;
x = [0 0 0]ʹ;
tol = 1e‐12;
x = symmlq(A, b, x, maxiter, tol)
§27. PHƯƠNG PHÁP CHEBYSHEV
Tính hội tụ của phương pháp lặp phụ thuộc vào tính chất của phổ ‐
nghĩa là của các giá trị riêng ‐ của ma trận [A]. Để cải thiện tính chất này
người ta thường biến đổi hệ phương trình tuyến tính bằng một phép biến đổi
tuyến tính thích hợp. Quá trình này được gọi là thử trước(preconditioner). Ví
dụ nếu ma trận [M] xấp xỉ ma trận hệ số [A] theo một cách nào đó, hệ được
biến đổi
[M]‐1[A][X] = [M]‐1[B]
sẽ có nghiệm như hệ phương trình [A][X] = [B] nhưng tính chất phổ của hệ số
của ma trận [M]‐1[A] có thể thuận lợi hơn.
Ta xét phương trình với [A] là ma trận đối xứng, xác định dương. Lúc
đó phổ của ma trận [A] sẽ nằm trong đoạn [λmin, λmax] với λmin, λmax là các giá
trị riêng lớn nhất và nhỏ nhất của [M]‐1[A]. Thuật toán tìm nghiệm là:
‐ cho [X0], tính [R0] = [B] ‐ [A][X0]
‐ chọn tham số α và c sao cho phổ của [A] nằm trên đoạn [d ‐ c, d + c]
hay trong ellip có tiêu điểm d ± c không chứa gốc toạ độ
và tính với n = 1, 2,..., n cho đến khi hội tụ:
[Z] = [M]‐1[R]
2
d
α = [P] = [Z] khi n = 1
[ ] [ ]2n 1n n n n n‐1
n
c P Z P
2 d
−α 1⎛ ⎞β = α = = [ ] + β⎜ ⎟ − β⎝ ⎠ khi n ≥ 2
[ ] [ ] [ ]n 1 n n nX X P+ = + α
[Rn+1] = [Rn] ‐ αn[A][Pn]
206
Ta xây dựng hàm chebyiter() để thực hiện thuật toán trên:
function x = chebyiter ( A, x, b, M, maxiter, tol )
% Cu phap x = chebyiter ( A, x, b, M, maxiter, tol )
% Dung pp lap Chebyshev de giai he pt A*x = b.
% A(n, n) ma tran doi xung, xac dinh duong
% X(n), vec to nghiem ban dau
% B(n), ve phai
% M, ma tran preconditioner
% cho M bang mt don vi neu khong thu truoc
% X(n), nghiem
if size(x, 1) == 1
x = xʹ;
end
r = b ‐ A * x;
eigs = eig ( inv ( M ) * A );
eigmax = max ( eigs );
eigmin = min ( eigs );
c = ( eigmax ‐ eigmin ) / 2.0;
d = ( eigmax + eigmin ) / 2.0;
for i = 1 : maxiter
z = M \ r;
if ( i == 1 )
p = z;
alfa = 2.0 / d;
else
beta = ( c * alfa / 2.0 )^2;
alfa = 1.0 / ( d ‐ beta );
p = z + beta * p;
end
x = x + alfa * p;
r = r ‐ alfa * A * p;
err = norm ( r );
if ( err <= tol )
break
end
207
end
Ta dùng chương trình ctchebyiter.m để giải hệ phương trình:
clear all, clc;
n = 10;
A = zeros ( n, n );
for i = 1 : n
A(i, i) = 3.0;
end
for i = 1 : n‐1
A(i, i + 1) = ‐1;
end
for i = 1 : n‐1
A(i + 1, i) = ‐1;
end
x = [1:n ]ʹ;
b = A * x;
x = ones ( n, 1 );
M = 2.0 * eye ( n );
maxiter = 50;
tol = 1e‐6;
y = chebyiter ( A, x, b, M, maxiter, tol );
fprintf(ʹNghiem cua he phuong trinh\nʹ);
fprintf(ʹ %f\nʹ, y)
§28. PHƯƠNG PHÁP QR
Ta phân tích ma trận hệ số [A] thành:
[A] = [Q][R]
Do [Q]T[Q] = [E]
nên:
[A][X] = [Q][R][X] = [B]
[Q]T[A][X] = [Q]T[Q][R][X] = [R][X] = [Q]T[B]
Do [R] là ma trận tam giác trên nên ta tìm nghiệm dễ dàng. Ta xây dựng hàm
givens() để thực hiện phép quay Givens:
208
function [c, s, r] = givens(x, y);
% tinh c, s, r sao cho [c s] [x] = [r]
% [‐s c] [y] = [0]
% voi c*c + s*s = 1;
if (y == 0)
c = 1;
s = 0;
r = x;
else
if (abs(x) >= abs(y))
t = y/x;
r = sqrt(1 + t*t);
c = 1/r;
s = t*c;
r = x*r;
else
t = x/y;
r = sqrt(1 + t*t);
s = 1/r;
c = t*s;
r = y*r;
end
end
Tiếp theo ta xây dựng hàm qrgivens() thực hiện việc tìm nghiệm của hệ
phương trình bằng thuật toán phân tích QR nhờ phép quay Givens:
function x = qrgivens(A, b);
[m, n] = size(A);
tau = zeros(n, 1);
%R = [A(1:n+1, :) b(1:n+1)];
R = [A(1:n, :) b(1:n)];
for j = 2:n
for i = 1:j‐1
[c, s, r] = givens(R(i, i), R(j, i));
R(i, i) = r;
209
R(j, i) = 0;
t = c*R(i, i+1:n+1) + s*R(j, i+1:n+1);
R(j, i+1:n+1) = ‐s*R(i, i+1:n+1) + c*R(j, i+1:n+1);
R(i, i+1:n+1) = t;
end
end
for k = n+2:m,
a = [A(k, :) b(k)];
for i = 1:n+1
[c, s, r] = givens(R(i, i),a(i));
R(i,i) = r;
a(i) = 0;
t = c*R(i, i+1:n+1) + s*a(i+1:n+1);
a(i+1:n+1) = ‐s*R(i, i+1:n+1) + c*a(i+1:n+1);
R(i, i+1:n+1) = t;
end
end
x = R(1:n, n+1);
for j = n:‐1:2
x(j) = x(j)/R(j, j);
x(1:j‐1) = x(1:j‐1) ‐ R(1:j‐1, j)*x(j);
end
x(1) = x(1)/R(1, 1);
Để giải hệ phương trình ta dùng chương trình ctqrgivens.m:
clear all, clc
A = [1 2 ‐1;2 1 1; 1 1 3];
b = [2 4 5]ʹ;
x = qrgivens(A, b)
File đính kèm:
Giáo trình Matlab căn bản - Chương 3_Hệ phương trình đại số tuyến tính.pdf

