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

++=

+=

+=

pdf75 trang | Chuyên mục: MATLAB | Chia sẻ: dkS00TYs | Lượt xem: 12976 | Lượt tải: 1download
Tóm tắt nội dung Giáo trình Matlab căn bản - Chương 3: Hệ phương trình đại số tuyến tính, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
 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:

  • pdfGiáo trình Matlab căn bản - Chương 3_Hệ phương trình đại số tuyến tính.pdf