Giáo trình Matlab cơ bản - Chương 2: Ma trận

Khi phân tích ma trận [A] theo thuật toán Doolitte, ta dùng chương

trình ctdoodecmp.m để tính định thức của nó:

clear all, clc

a = [1 2 3 4; 3 4 5 7; 2 3 8 5; 4 9 1 4];

[l, r] = doolittle(a);

d = prod(diag(l))*prod(diag(r))

Khi phân tích ma trận [A] theo thuật toán Crout, ta dùng chương trình

ctcrotdecmp.m để tính định thức của nó:

clear all, clc

a = [1 2 3 4; 3 4 5 7; 2 3 8 5; 4 9 1 4];

[l, r] = crout(a);

d = prod(diag(l))*prod(diag(r))

Khi phân tích ma trận [A] theo thuật toán Choleski, ta dùng chương

trình ctcholdecmp.m để tính định thức của nó:

clear all, clc

a = [4 ‐2 2;‐2 2 ‐4;2 ‐4 11];

a = pascal(5);

l = choleski(a);

d = prod(diag(l))*prod(diag(lʹ))

pdf77 trang | Chuyên mục: MATLAB | Chia sẻ: tuando | Lượt xem: 470 | Lượt tải: 0download
Tóm tắt nội dung Giáo trình Matlab cơ bản - Chương 2: Ma trận, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
seholder.m:  
clear all, clc 
global c d 
a = [ 1  2  3  4; 2  7  6  5; 3  6  9  0;4  5  0  3]; 
[eval, evec] = symmateig(a) 
n = size(a, 1); 
§31. THUẬT TOÁN RUTISHAUSER 
  Cho ma trận [A] đối xứng, xác định dương, ta dùng thuật toán Crout để 
phân tích nó thành: 
  [A] = [L][R]                   (1) 
Sau đó ta xây dựng ma trận: 
  [A1] = [R][L]                  (2) 
 125
Ma trận [A1] sẽ có cùng giá trị riêng với ma trận [A]. Ta lại tiếp tục phân tích 
ma trận [A1] theo thuật toán Crout: 
  [A1] = [L1][R1]                  (3) 
Và sau đó ta xây dựng ma trận: 
  [A2] = [R1][L1] 
Tiếp tục quá trình ta nhận được ma trận: 
  [An] = [Ln][Rn] 
  [An+1] = [Rn][Ln] 
Khi n → ∞,  [An]  trở  thành ma  trận  tam giác  trên có các phần  tử  trên đường 
chéo chính là các giá trị riêng của ma trận [A]. Phép lặp này hội tụ khi [A] là 
ma trận đố xứng, xác định dương. Khi [A] không xác định dương, phép  lặp 
không ổn định. Phân tích Crout cũng không thực hiện được khi có một phần 
tử rii = 0. Ta xây dựng hàm rutishauser() để thực hiện thuật toán trên: 
function [lambda, evec] = rutishauser(a) 
% Tinh cac gia tri rieng bang thuat toan phan tich LR 
for i = 1: 500 
    s1 = diag(a); 
    [l, r] = crout(a); 
    a = r*l; 
    s2 = diag(a); 
    if abs(max(s2 ‐ s1)) < 1e‐8 
       break; 
   end 
end 
lambda = diag(a); 
n = size(lambda, 1); 
evec = zeros(n); 
c = evec; 
e = eye(n); 
for i = 1:n 
    b = a ‐ lambda(i)*e; 
    c = nulld(b); 
    evec(:, i) = c(:, 1);   
end 
 126
lambda = diag(lambda); 
Để tính các giá trị riêng của ma trận ta dùng chương trình ctrutishauser.m: 
clear all, clc 
a = [ 1 2 3 4; 5 6 7 8; 9 0 1 2; 3 4 5 6]; 
[lambda, evec] = rutishauser(a) 
§32. THUẬT TOÁN FADDEEV – LEVERIER ‐ SOURIAU 
  Cho ma trận [A]: 
  [ ]
⎡ ⎤⎢ ⎥⎢ ⎥= ⎢ ⎥⎢ ⎥⎣ ⎦
L
L
M M L M
L
11 11 1n
21 22 2n
n1 n2 nn
a a a
a a a
A
a a a
Các giá trị riêng của ma trận [A] là nghiệm của đa thức đặc trưng: 
  [ ] [ ]( )− λ =det A E 0                 (1) 
Khi khai triển định thức trên, ta được đa thức cấp n: 
  − −λ = λ − λ − λ − − =Ln n 1 n 1n 1 1 nP ( ) p p p 0           (2) 
Gọi vết của ma trận là tổng các phần tử trên đường chéo chính: 
  + + +L11 22 nntrace([A]) = a a a             (3) 
Các hệ số của đa thức (2) được xác định theo: 
  [ ] [ ] [ ]= =1 1 1p trace( B ) B A  
  [ ] [ ] [ ] [ ] [ ]( )= = −2 1 2 1 11p trace( B ) B A B p E2  
[ ] [ ] [ ] [ ] [ ]( )= = −3 3 3 2 21p trace( B ) B A B p E3  
[ ] [ ] [ ] [ ] [ ]( )− −= = −
L
n n n n 1 n 1
1p trace( B ) B A B p E
n
Giải hệ (3) ta có các giá trị riêng của [A]. 
Ta xây dựng hàm fadlev() để thực hiện thuật toán trên: 
function [lambda, evec] = fadlev(a) 
%Tim cac gia tri rieng va vec to rieng bang phuong phap Faddeev ‐ Leverrier 
n = size(a, 1); 
b = a; 
 127
for i = 1:n 
    s = 0; 
    for k = 1:n 
        s = s + b(k, k); 
    end 
    p = s/i; 
    b = a*(b ‐ p*eye(n)); 
    r(i+1) = ‐p; 
end 
r(1) = 1; 
lambda = roots(r); 
n = size(lambda, 1); 
evec = zeros(n); 
c = evec; 
e = eye(n); 
for i = 1:n 
    b = a ‐ lambda(i)*e; 
    c = nulld(b); 
    evec(:, i) = c(:, 1);   
end 
lambda = diag(lambda); 
Để tìm các giá trị riêng của ma trận ta dùng chương trình ctfaclev.m: 
clear all, clc 
a = [11 2 3 1 4; 2 9 3 5 2; 4 5 6 7 8; 3 2 1 6 7; 4 9 6 8 2]; 
[lambda, evec] = fadlev(a) 
§33. THUẬT TOÁN KRYLOV 
Đa thức đặc trưng của ma trận [A] có dạng: 
  − −λ = λ − λ − λ − − =Ln n 1 n 2n 1 1 nP ( ) p p p 0           (1) 
Ta viết lại (1) dưới dạng: 
−
=
λ = λ + λ∑n 1n in i
i 0
P ( ) p                 (2) 
Theo định lý Hamilton ‐ Kelly ta có P([A]) = 0. Xét dãy lặp: 
 128
[ ]+ =(i 1) (i)v A v   i = 0, 1,..., n‐1            (3) 
Do P([A]) = 0 nên: 
  [ ]( ) −
=
ρ = + ρ =∑n 1(0) (n) (i)i
i 0
A v v v 0              (4) 
Đặt  ⎡ ⎤= ⎣ ⎦
T(i) (i) (i)
1 nv v ,...,v  ta có: 
−
=
+ ρ =∑n 1(n) (i)j i
i 0
v v 0                  (5) 
hay: 
−
−
−
⎡ ⎤ ⎡ ⎤ρ⎡ ⎤⎢ ⎥ ⎢ ⎥⎢ ⎥ = −⎢ ⎥ ⎢ ⎥⎢ ⎥⎢ ⎥ ⎢ ⎥⎢ ⎥ρ⎣ ⎦⎣ ⎦ ⎣ ⎦
L
M L M M M
L
(n 1) (0) (n)
1 1 n 1 1
(n 1) (0) (n)
n n 0 n
v v v
v v v
            (6) 
Vì  [ ]+ =(k 1) (k)v A v  
nên: 
[ ]( )+
=
= =∑n(k 1) (k) (k)i i ,j ji
j 1
v A v a v   i = 1, 2,..., n    k = 0, 1,..., n‐1    (7) 
Tóm lại quá trình tính toán theo thuật toán Krylov như sau: 
  ‐ Chọn v(0) tuỳ ý, tính  (k)iv  theo (7) 
  ‐ Giải hệ (6) để tìm ρ 
Khi đã tìm được ρ  ta có đa thức đặc trưng.  
Ta xây dựng hàm krylov() để thực hiện thuật toán trên: 
function [lambda, evec] = krylov(a) 
% Tim gia tri rieng bang thuat toan Krylov 
n = size(a, 1); 
v = zeros(n, 1); 
v(1) = 1; 
b = zeros(n, n); 
b(:, n) = v; 
for k = 2:n 
    v = a*v; 
    b(:, n‐k+1) = v; 
end 
c = a*v; 
 129
rho = ‐b\c; 
rho = [1 rhoʹ]; 
lambda = roots(rho); 
n = size(lambda, 1); 
evec = zeros(n); 
c = evec; 
e = eye(n); 
for i = 1:n 
    b = a ‐ lambda(i)*e; 
    c = nulld(b); 
    evec(:, i) = c(:, 1);   
end 
lambda = diag(lambda); 
Để tìm giá trị riêng của ma trận ta dùng chương trình ctkrylov.m: 
clear all, clc 
a = [17 24 30 17; 8 13 20 7; 2 10 8 6; ‐23 ‐43 ‐54 ‐26]; 
[lambda, evec] = krylov(a) 
§34. THUẬT TOÁN HYMAN 
  Cho ma trận Hessenberg [B] và λ là một giá trị riêng của [B]. Ta tìm: 
  α(λ), x1(λ), x2(λ),...,xn‐1(λ) 
sao cho [X] = [x1(λ), x2(λ),...,xn‐1(λ), xn]T với xn = 1 là nghiệm của bài toán: 
  [ ] [ ]( )[ ] [ ]1B E X e− λ = α  
nghĩa là: 
1,1 1 1,2 2 1,n
2,1 1 2,2 2 2,n
n,n 1 n 1 n,n
(b )x b x b 1
b x (b )x b 1 0
b x (b )1 0− −
− λ + + + = α⎧⎪ + − λ + + =⎪⎨⎪⎪ + − λ =⎩
L
L
M  
Thay thế ngược ta có được các nghiệm xn‐1, xn‐2,..., x1 và α(λ).  
Theo quy tắc Cramer ta có: 
 130
[ ] [ ]( )
1,1
2,1
n 1,n 1
n,n 1
n
b
b 0
det
0 b 0
0 b 0
1 x
det B E
− −
−
− λ ∗ α⎡ ⎤⎢ ⎥∗⎢ ⎥− λ⎢ ⎥⎢ ⎥⎣ ⎦= = − λ  
            [ ] [ ]( )
n 1
2,1 n ,n 1( )( 1) b b
det B E
−
−α λ −= − λ
L
Do đó: 
  [ ] [ ]( )n 1
2,1 n ,n 1
( 1)( ) det B E
b b
−
−
−α λ = − λL  
Đa thức α(λ) chỉ sai khác đa thức đặc trưng p(λ) một nhân tử hằng. Do vậy ta 
có thể dùng α(λ) để tìm các giá trị riêng thay cho p(λ). Hàm alffa() thực hiện 
công việc này:  
function r = alfa(a); 
n = size(a, 1); 
b = a; 
l = 1; 
for i = 2:n 
    l = l*a(i, i‐1); 
end 
sign = (‐1)^(n‐1); 
for i = 1:n 
    s = 0; 
    for k = 1:n 
        s = s + b(k, k); 
    end 
    p = s/i; 
    b = a*(b ‐ p*eye(n)); 
    r(i+1) = ‐p; 
end 
r(1) = 1; 
r = sign*r/l; 
 131
Nếu cho một ma trận bất kì [A], ta có thể biến đổi Householder nó thành ma 
trận Hessenberg [B] đồng dạng với [A]. Sau khi có các giá trị riêng, ta tìm các 
vec tơ riêng tương ứng. Hàm hyman() thực hiện thuật toán này: 
function [lambda, evec] = hyman(a) 
%Tim cac gia tri rieng va vec to rieng bang phuong phap Hyman 
b = hessenberg(a); 
r = alfa(b); 
lambda = roots(r); 
n = size(lambda, 1); 
evec = zeros(n); 
c = evec; 
e = eye(n); 
for i = 1:n 
    b = a ‐ lambda(i)*e; 
    c = nulld(b); 
    evec(:, i) = c(:,1);   
end 
lambda = diag(lambda); 
Để  tìm các giá trị riêng và vec tơ riêng tương ứng của một ma trận ta dùng 
chương trình cthyman.m: 
clear all, clc 
a = [ 1 2 3 4; 2 5 2 3;7 1 4 1; 3 2 3 7]; 
[lambda, evec] = hyman(a) 
§35. TRỰC GIAO HOÁ ARNOLDI 
  Trong đại số tuyến tính, phương pháp Arnoldi được W. Arnoldi đưa ra 
năm 1951. Phương pháp lặp Arnoldi sử dụng trực giao hoá Gram – Schmidt 
để tạo ra dãy các vec tơ trực giao [q1], .., [qn] gọi là các vec tơ Arnoldi. Thuật 
toán cụ thể gồm các bước: 
- Cho vec tơ bất kì [q1] có  [ ]1q 1=  
- Lặp từ k = 2,3,... 
 132
• [A][qk‐1] = [qk] 
• for j = 1:k‐1 
  ∗  Tj k j,k 1q q h −⎡ ⎤⎡ ⎤ =⎣ ⎦ ⎣ ⎦  
∗  k j,k 1 jq h q−⎡ ⎤ ⎡ ⎤= ⎣ ⎦⎣ ⎦  
•  [ ]k k,k 1q h −=  
• [ ] kk
k,k 1
qq
h −
=  
Ta gọi [Qn] là ma trận tạo từ n vec tơ Arnoldi đầu tiên [q1],..,[qn] đầu tiên và 
[Hn] là ma trận (Hessenberg trên) tạo bởi n hàng đầu tiên của [H] và có: 
  [Hn] = [Q]T[A][Q]  
Ta xây dựng hàm arnoldi() thực hiện thuật toán trên:  
function [Hn, Vn] = arnoldi(A); 
k = 50; 
m = size(A, 1); 
v = rand(m, 1); 
n = size(A, 1); 
H = zeros(m+1, m); 
V = zeros(n, m+1); 
V(:,1) = v/norm(v); 
for j = 1:m 
    w = A*V(:, j); 
    for i = 1:j 
        H(i, j) = V(:, i)ʹ*w; 
        w = w ‐ H(i, j)*V(:, i); 
    end 
    H(j+1, j) = norm(w); 
    if H(j+1, j) <= eps, 
       break; 
    end 
    V(:, j+1) = w/H(j+1, j); 
end 
Hn = H(1:m, :); 
 133
Vn = V(:, 1:m); 
Để phân tích ma trận ta dùng chương trình ctarnoldi.m: 
clear all, clc 
A = [ 7 2 3 ‐1; 2 8 5 1; 3 5 12 9; ‐1 1 9 7];  
[H, V] = arnoldi(A) 
§36. TRỰC GIAO HOÁ LANCZOS 
  Cho ma trận [A] đối xứng. Ta phân tích ma trận thành các ma trận [Q] 
và [T] sao cho: 
  [A] = [Q][T][Q]T 
với:  [Q][Q]T  =  [E],  nghĩa  là  [Q]  là ma  trận  trực  giao  và  [T]  là ma  trận  ba 
đường chéo đối xứng. Thuật toán Lanczos gồm các bước: 
- Cho vec tơ [v1] có  [ ]1v 1=  
- Cho v0 = 0, β0 = 0. [V] = [v1] 
- Lặp : 
•  j 1 j j 1 j 1v A v v+ − −⎡ ⎤ ⎡ ⎤ ⎡ ⎤⎡ ⎤= −β⎣ ⎦⎣ ⎦ ⎣ ⎦ ⎣ ⎦  
•  Tj j 1alfa v v +⎡ ⎤ ⎡ ⎤= ⎣ ⎦ ⎣ ⎦  
•  j 1 j 1 jv v v+ +⎡ ⎤ ⎡ ⎤ ⎡ ⎤= − α⎣ ⎦ ⎣ ⎦ ⎣ ⎦  
•  Tj 1 j 1 j 1v v V V v+ + +⎡ ⎤ ⎡ ⎤⎡ ⎤ ⎡ ⎤ ⎡ ⎤= −⎣ ⎦ ⎣ ⎦ ⎣ ⎦⎣ ⎦ ⎣ ⎦  
•  j j 1v +⎡ ⎤β = ⎣ ⎦  
•  j 1 j 1 jv v+ +⎡ ⎤ ⎡ ⎤= β⎣ ⎦ ⎣ ⎦  
• [ ] j 1V V,v +⎡ ⎤= ⎣ ⎦  
Ta xây dựng hàm lanczos() để thực hiện thuật toán Lanczos 
function [T, Q] = lanczos(A); 
% thuat toan Lanczos cho ma tran doi xung  
n = size(A, 1); 
Q(:, 1) = rand(n, 1); 
Q(:, 1) = Q(:, 1)./norm(Q(:, 1)); 
a(1) = Q(:, 1)ʹ*A*Q(:, 1); 
Q(:, 2) = A*Q(:, 1) ‐ a(1)*Q(:, 1); 
 134
b(1) = norm(Q(:, 2)); 
Q(:, 2) = 1./b(1)*Q(:,  2); 
for i = 2:n‐1 
    a(i) = Q(:, i)ʹ*A*Q(:, i); 
    Q(:, i+1) = A*Q(:, i) ‐ a(i)*Q(:, i) ‐ b(i‐1)*Q(:, i‐1); 
    b(i) = norm(Q(:, i+1)); 
    Q(:, i+1) = 1./b(i)*Q(:, i+1); 
end 
a(n) = Q(:, n)ʹ*A*Q(:, n); 
T = diag(a) + diag(b, 1) + diag(b, ‐1); 
Để phân tích ma trận ta dùng chương trình ctlanczos.m: 
clear all, clc 
A = [4 1 3 ‐2; 1 ‐2 4 1; 3 4 1 2; ‐2 1 2 3]; 
[T, Q] = lanczos(A); 

File đính kèm:

  • pdfgiao_trinh_matlab_co_ban_chuong_2_ma_tran.pdf