Tải bản đầy đủ (.pdf) (17 trang)

Phương pháp lặp Conjugate Gradient và ứng dụng giải hệ phương trình tuyến tính

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (724.54 KB, 17 trang )

ĐẠI HỌC QUỐC GIA TP. HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC BÁCH KHOA
Mơn: Đại Số Tuyến Tính

BÁO CÁO BÀI TẬP LỚN
ĐỀ TÀI SỐ 31
SỬ DỤNG PHƯƠNG PHÁP LẶP CONJUGATE GRADIENT ĐỂ
GIẢI HỆ PHƯƠNG TRÌNH TUYẾN TÍNH
Nhóm 3 - Lớp DT01
Nguyễn Xn Anh

2010872

Phan Trung Anh

1912608

Trần Ngọc Thùy Trinh

2115076

Thân Thái Tuấn

2115190

Nguyễn Trương Tiến Đạt

1952648

GVHD: TS Đặng Văn Vinh
Thành phố Hồ Chí Minh - 2022




MỤC LỤC
I. Cơ sở lý thuyết:............................................................................................................ 3
A. Giới thiệu chung về các phương pháp lặp ................................................................. 3
1. Đặt vấn đề: ............................................................................................................... 3
2. Tính chất của các phương pháp lặp: ........................................................................ 3
B. Phương pháp lặp Conjugate Gradient ........................................................................ 3
1. Giới thiệu chung : .................................................................................................... 3
2. Nội dung: ................................................................................................................. 4
a. Định nghĩa: ........................................................................................................... 4
b. Bổ đề: ................................................................................................................... 4
c. Chứng minh: ......................................................................................................... 4
Nhận xét: Để giải hệ Ax = b, ta không cần nghịch đảo ma trận và chỉ cần sử dụng
phép tính các tích trong. Khai triển của x* có thể coi là kết quả của vòng lặp n lần
với bước nhảy  i pi .................................................................................................. 4
3. Thuật toán: ............................................................................................................... 4
a. Định lý 1: .............................................................................................................. 4
b. Định lý 2:.............................................................................................................. 5
c. Hệ quả: ................................................................................................................. 5
d. Thuật toán: ........................................................................................................... 5
4. Điều kiện hội tụ của phương pháp lặp ..................................................................... 6
II. Chương trình sử dụng thuật toán Conjugate Gradient để giải hệ và nêu các ứng
dụng vào các bài toán thực tế. ......................................................................................... 6
III. Tài liệu tham khảo .................................................................................................. 17


I. Cơ sở lý thuyết:
A. Giới thiệu chung về các phương pháp lặp
1. Đặt vấn đề:

- Khi ma trận rất lớn và thưa (tỉ lệ các phần tử khác 0 rất ít), phương pháp khử Gauss,
các phương pháp phân rã đôi khi sẽ không hiệu quả (yêu cầu bộ nhớ lớn, làm biến mất
tính “thưa”).
- Thay vào đó, ta xem xét các phương pháp lập để giải hệ, tìm ra nghiệm gần đúng.
- Phương pháp lặp có hiệu quả về chi phí đối với các hệ lớn và thưa, đặc biệt là khi ma
trận A có cấu trúc đối xứng (thường xuất hiện khi rời rạc hóa phương trình đạo hàm
riêng).
2. Tính chất của các phương pháp lặp:
- Phần lớn các phương pháp lặp được xây dựng dựa trên kỹ thuật phân tách ma trận hệ
số: Xét hệ phương trình Ax = b với A  R nn là ma trận không suy biến. Ta tách A
thành hiệu A = M – N với M thỏa mãn điều kiện sao cho hệ Mz = f dễ dàng giải được.
Khi đó, hệ Ax = b trở thành Mx = Nx + b.
- Vì hệ Mz = f dễ dàng giải được, tức là dễ dàng tính được M-1f với mọi f. Do đó có
thể viết x =M-1Nx + M-1 b
- Từ đó gợi ý cho ta xây dựng phương pháp lặp như sau: Cho trước xấp xỉ ban đầu x(0)
ta tuần tự tính các x(k) theo cơng thức: x(k+1) = M-1Nx(k) + M-1b, k = 0,1,2,… cho đến
khi dãy hội tụ (có điều kiện, đánh giá được sai số).
B. Phương pháp lặp Conjugate Gradient
1. Giới thiệu chung :
Phương pháp Gradient liên hợp (Conjugate Gradient) được Hestenses và Stiefel nêu ra
đầu tiên vào những năm 1950 để giải hệ phương trình đại số tuyến tính (PTĐSTT). Vì
việc giải một hệ phương trình tuyến tính tương đương với việc tìm cực tiểu của một
hàm toàn phương xác định dương nên năm 1960 Fletcher – Reeves đã cải biên và phát
triển nó thành phương pháp Gradient liên hợp cho cực tiểu không ràng buộc. Phương
pháp Gradient liên hợp (CG) chỉ cần tới đạo hàm bậc nhất nhưng làm tăng hiệu quả và
độ tin cậy của thuật tốn. Trên cơ sở đó, bài báo cáo thuật toán CG và cài đặt thử
nghiệm trên Matlab.


2. Nội dung:

a. Định nghĩa:
Cho A  R nn là ma trận đối xứng xác định dương. Hệ k vectơ
( pi 

n

 p0 , p1 ,..., pk 

, pi  0) được gọi là A-trực giao (liên hợp) nếu: piT Api  0, i  j

b. Bổ đề:
Nếu hệ k vectơ  p0 , p1 ,..., pk  ( pi 

n

, pi  0) là A-liên hợp thì độc lập tuyến tính.

c. Chứng minh:
 k 1



k 1





j 1


Giả sử pk  1 p1  2 p2  ...  k 1 pk 1 thì pk T Apk  pk T A    j p j     j pk T Ap j  0
j 1

Giả sử x* là nghiệm của Ax = b và  p0 , p1 ,..., pn 1 là hệ n vectơ A-liên hợp trong

n

.

Khi đó hệ  p0 , p1 ,..., pn 1 độc lập tuyến tính, nên x*   0 p0  1 p1  ...   n1 pn1
 n 1



 j 0



Do đó, piT Ax*  piT    j p j    i piT Api
piT Ax*
piT b

Từ đó suy ra  i  T
pi Api piT Api
n 1

n 1

i 0


i 0

Như vậy, i không phụ thuộc vào x* và vì vậy, ta có: x*    i pi  

piT b
pi
piT Api

Nhận xét: Để giải hệ Ax = b, ta không cần nghịch đảo ma trận và chỉ cần sử dụng
phép tính các tích trong. Khai triển của x* có thể coi là kết quả của vòng lặp n lần với
bước nhảy  i pi
3. Thuật toán:
a. Định lý 1:
Cho  p0 , p1 ,..., pn 1 là hệ n vectơ A-liên hợp và x(0) 
Thực hiện bước lặp bao gồm:
 Cập nhật bước nhảy: x( k 1)  x( k )   k pk

n

là phương án ban đầu bất kì.


 Tính Gradient của f: r ( k )  b  Ax( k )
 Tính:  k 

pkT r ( k ) pk (b  Ax ( k ) )

piT Api
piT Api


Đến bước thứ n thì x( n)  x*
b. Định lý 2:
Cho  p0 , p1 ,..., pn 1 là hệ n vectơ A-liên hợp và x(0) 
x( k 1)  x( k )   k pk ,  k 

n

là phương án ban đầu bất kì.

pkT r ( k )
piT Api
1

1





Khi đó x ( k )  arg min  xT Ax  xT b  , x ( k )  arg min  xT Ax  xT b 
x  x  p
x x  B
2
2


k 1

k 1


0

k

c. Hệ quả:
Với giả thiết như trong định lý 2, ta có:


r ( k )  Bk với mọi k



piT r ( k )  0 với mọi 0  i  k



  B0  B1  ...  Bn 

n

Ta thấy x( k ) cực tiểu hóa f(x) trên x0  Bk nên x( n) cực tiểu hóa f(x) trên

n

d. Thuật tốn:
Thuật tốn Gradient liên hợp như sau:
Lấy x(0) 

n


và tính ( Bk được chọn sao cho pk 1 và pk là A-liên hợp): Khởi đầu,

r0  b  Ax(0) , p0  r0 và lặp theo k:
x( k 1)  x( k )   k pk ,  k 
r ( k 1)  r ( k )   k Apk

pkT r ( k )
piT Api


pk 1  r

( k 1)

pkT Ar ( k 1)
  k pk ,  k  T
(Gram  Schmidt )
pk Apk

Ta thấy rằng phương pháp Gradient liên hợp nếu khơng có sai số tính tốn thì sẽ dừng
sau khơng quá n bước và thu được nghiệm đúng. Tuy nhiên trong q trình giải có sai
số tính tốn nên phương pháp Gradient liên hợp coi như phương pháp lặp để tìm nghiệm
gần đúng.
4. Điều kiện hội tụ của phương pháp lặp
Giả sử chúng ta áp dụng Conjugate Gradient với một hệ xác định dương Ax = b. Khi
k

  1 
đó A-chuẩn của sai số sẽ thỏa mãn
 2 

 với k  0
x  x0 A


1


x  xk A

Khi đó   cond 2 ( A) 

max
là 2- số điều kiện chuẩn của ma trận A.
min

Hệ số lặp  với  là số điều kiện của ma trận A. Theo đó, ta suy ra được giới hạn
trên của số lần lặp lại theo  .
1

2

xx A

k
Nếu   0 , ta có k  ln    , khi đó

2  
x  x0 A

II. Chương trình sử dụng thuật toán Conjugate Gradient để giải hệ và nêu các

ứng dụng vào các bài toán thực tế.
1. Ứng dụng để giải hệ phương trình tuyến tính
VD: Cần 3 thành phần khác nhau A, B và C, để sản xuất một lượng hợp chất
hóa học nào đó. A, B và C phải được hòa tan trong nước một cách riêng biệt
trước khi chúng kết hợp lại để tạo ra hợp chất hóa học. Biết rằng nếu kết hợp
dung dịch chứa A với tỉ lệ 1.5 g/cm3 với dung dịch chứa B với tỉ lệ 0.8 g/cm3 và
dung dịch chứa C với tỉ lệ 1.2 g/cm3 thì tạo ra 13,2 g hợp chất hóa học đó. Nếu
tỉ lệ của A, B, C trong phương án này thay đổi thành tương ứng 0.8, 3.2 và 1
g/cm3 (trong khi thể tích là giống nhau), khi đó 20.6 g chất hóa học sẽ được tạo
ra. Cuối cùng, nếu tỉ lệ tương ứng là 1.2, 1 và 4.6 g/cm3, thì sẽ tạo ra 17.6 g hợp
chất. Thể tích của dung dịch chứa A, B và C là bao nhiêu?


Gọi x, y, z tương ứng là thể tích (cm3) của phương án chứa A, B và C. Khi đó
1.5x là khối lượng của A trong trường hợp đầu, 0.8y là khối lượng của B và
1.2z là khối lượng của C. Cộng lại với nhau, ba khối lượng này sẽ tạo ra 13.2 g.
Do đó: 1.5x +0.8 y +1.2z = 13.2. Tương tự cho hai trường hợp còn lại, ta có hệ
phương trình tuyến tính:
1.5 x  0.8 y  1.2 z  13.2
 1,5 0,8 1, 2   x   13, 2 



  
0.8 x  3.2 y  z  20.6 hay  0,8 3, 2 1   y  =  20, 6 
1.2 z  y  4.6 z  17.6
 1, 2 1 4, 6   z   17, 6 




  

 x0   0 
Chọn xđầu =  y0  =  0 
 z  0
 0  
clear
clf
close all
clc
A = input('Nhap vao ma tran A ')
b = input ('Nhap vao ma tran b ')
[h,g] = size(b);
x = input ('Chon mot gia tri x bat ki ');
r = b-A*x;
p = b - A*x;
i=1;
while norm(r) > 1e-3
a = r'*r./(p'*A*p);
if h == 2
m = x(1,1);
n = x(2,1);
s = [m,n];
if i == 1
plot(m,n, '.')
hold on
end
if i > 1
plot([k(1) s(1)],[k(2) s(2)])
hold on

end
i = i+1;
k = [m,n];
end
if h
m
n
o
s

== 3
= x(1,1);
= x(2,1);
= x(3,1);
= [m,n,o]
if i == 1
plot3(m,n,o, '.')


hold on
end
if i > 1
plot3([k(1) s(1)],[k(2) s(2)],[k(3) s(3)])
hold on
end
i = i+1;
k = [m,n,o];
x =
t =
r =

bet
p =
end
X =

end
x + a*p;
r'*r;
r - a*A*p;
= r'*r/t ;
r + bet*p;
x
if h == 2
m = X(1,1);
n = X(2,1);
plot(m,n,'*')
plot([x(1) k(1)],[x(2) k(2)])
hold on
xlabel('x')
ylabel('y')
grid on
end
if h == 3
m = X(1,1);
n = X(2,1);
o = X(3,1);
plot3(m,n,o,'*')
plot3([x(1) k(1)],[x(2) k(2)],[x(3) k(3)])
hold on
xlabel('x')

ylabel('y')
zlabel('z')
grid on
end


Ta được kết quả

 x  5.1185

Vậy  y  4.6987
 z  1.4694



2. Ứng dụng trong xóa mờ hình ảnh (Deblurring Images using the
Conjugate Gradient Method)
Ngoài ra, phương pháp lặp Conjugate Gradient cịn có ứng dụng trong việc xóa
mờ hình ảnh. Để thực hiện được điều này, ta dùng matlab để chạy chương trình
được viết sẵn. Sau khi hồn tất, ta thu được kết quả như hình ảnh bên dưới.

Ảnh gốc

Ảnh bị làm mờ

Ảnh đã được xoá mờ
Applying the Blur:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
function v = psf(sigma,x,y)

% returns the value of the point spread function
% We're using a Gaussian PSF (truncated far away from
% its center -- the origin).
if x >= -8 & x <= 8 & y >= -8 & y <= 8


v = exp(-sigma*(x.^2+y.^2));
else
v = 0;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
function g = applyGaussianPSF(sigma, f, x)
% Returns the blurred graph of f
% if x = 0 the mesh plot is generated,
% otherwise it is not graphed.
% sigma determines how much the light is spread
% (How bad the blur is.)
% Get size
[m n] = size(f);
% create Toeplitz blocks
for i = -8:8
for k = 1:n
c(k) = psf(sigma, i, k-1);
r(k) = psf(sigma, i, 1-k);
end;
block(i+9,1:n,1:n) = toeplitz(c,r);
end;
% apply the convolution product row by row
for i = 1:m

g(i,1:n) = zeros(1,n);
% apply convolution product
% to the graph on row i
for j = -8:8
if i-j >= 1 & i-j <= m
b(:,:) = block(j+9,:,:);
g(i,1:n) = g(i,1:n) + f(i-j,1:n) * b;
end;
end;
end;
if x == 0, mesh(g); end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
Solving for the Image:


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
function n = inner_product(x,y)
% turn x and y into columns by transposing each row
% into a column and concatenating together.
% then find regular inner product
% (x and y are sz x ?? matrices)
sz = size(x,1);
n = 0;
for i = 1:sz
n = n + x(i,:) * y(i,:)' ;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%

function [g, error, niter, flag] = CGmethod(sigma, g, f,
maxit, tol)
% Conjugate Gradient method for solving linear systems.
%
% sigma is a parameter for the Gaussian psf
%
% We are solving "Ag = f":
% g as input is the initial guess at a solution and then
% g as output is the solution to the system.
% f is the blurred image.
%
% maxit is the maximum number of iterations to attempt
% niter is the number of iterations actually preformed
% error is the difference between the exact answer and our
answer
% tol is the allowable error
% flag is set to 1 if the function returns before error <=
tol
flag = 0;
niter = 0;
% r is the residual (error).
r = f - applyGaussianPSF(sigma,g,1);
% Initial search direction.
d = r;


% norm of f (as a vector: turn rows into cols and
concatenate)
norm_f = sqrt(inner_product(f,f));
if(norm_f == 0.0), norm_f = 1.0; end;

error = sqrt(inner_product(r,r)) / norm_f;
for niter = 1:maxit
if(error < tol), return, end; % bail out if the error
is small enough.
% multiply our search direction by the blur matrix.
Ad = applyGaussianPSF(sigma,d,1);
% the square of the blur matrix norm of d.
inp_Ad_d = inner_product(Ad,d);
% Step size (how far to move along the gradient
direction).
alpha = inner_product(r,d) / inp_Ad_d;
% Improve the
g = g + alpha * d;
% update the residual (error).
r = f - applyGaussianPSF(sigma,g,1);
% the conjugate factor to force our search directions
% to be orthogonal (in some sense).
beta = -inner_product(r,Ad) / inp_Ad_d;
% New search direction.
d = r + beta * d;
% measure the relative error.
error = sqrt(inner_product(r,r)) / norm_f;
end;
if(error > tol) flag = 1; end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
Wrapper Functions for Demos:


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%
function B = blur(pic, gry, flag)
% Blurs "pic" (a jpeg) and returns the blurred image.
% The image is converted to grayscale if gry = 1 and
% the image is displayed if flag = 1.
%
%
%
A

Load up the picture. A is a m by n matrix if grayscale
and an m by n by 3 tensor if in color (think 3 matrices
stacked on top of each other -- one each for RGB values.
= loadImage(pic, gry, 0);

if gry == 0 % Color
% Blur Red, Greens, and then Blues.
B(:,:,1) = applyGaussianPSF(0.1, A(:,:,1), 1);
B(:,:,2) = applyGaussianPSF(0.1, A(:,:,2), 1);
B(:,:,3) = applyGaussianPSF(0.1, A(:,:,3), 1);
else % Grayscale
B = applyGaussianPSF(0.1, A, 1);
end;
if flag == 1 % Display the image
figure;
if gry == 1
colormap(gray(256));
% rescale to make image show up.
x = max([max(max(B)),0.000001]);
scaleB = (1/x)*B;

else
% rescale to make image show up.
x = max([max(max(max(B))),0.000001]);
scaleB = (1/x)*B;
end;
%image(myImg);
imshow(scaleB);
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
function A = deblur(B, n, gry, flag)
% Deblurs the image stored in the matrix/tensor B
% and returns the "unblurred" image.
% The image is considered to be grayscale if gry = 1
% and the image is displayed if flag = 1.


% Our initial "guess" to feed into the CG method is the
zero image.
A = zeros(size(B));
if gry == 0 % Color
% Run the CG method on RGB values.
% Each call to the CG method is iterated n times.
[A(:,:,1), error, niter, flag] = CGmethod(0.1,
A(:,:,1), B(:,:,1), n, 0);
[A(:,:,2), error, niter, flag] = CGmethod(0.1,
A(:,:,2), B(:,:,2), n, 0);
[A(:,:,3), error, niter, flag] = CGmethod(0.1,
A(:,:,3), B(:,:,3), n, 0);
else % Grayscale

% Each call to the CG method is iterated n times.
[A, error, niter, flag] = CGmethod(0.1, A, B, n, 0);
end;
% Display image when flag is 1.
if flag == 1
figure;
if gry == 1
colormap(gray(256));
% rescale to make image show up.
x = max([max(max(A)),0.000001]);
scaleA = (1/x)*A;
else
% rescale to make image show up.
x = max([max(max(max(A))),0.000001]);
scaleA = (1/x)*A;
end;
%image(myImg);
imshow(scaleA);
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
function myImg = loadImage(pic, gry, flag)
% This function loads the file "pic" (should be a jpeg).
% If gry = 0, it's loaded as a color picture.


% If gry = 1, it's turned into a grayscale image.
% flag determines whether the image is displayed.
% flag = 0 not shown / flag = 1 shown
myImg = imread(pic);

if gry == 1
tmp = .2989*myImg(:,:,1) + .5870*myImg(:,:,2) +
.1140*myImg(:,:,3);
myImg = tmp;
end;
if flag == 1
figure;
if gry == 1
colormap(gray(256));
end;
%image(myImg);
imshow(myImg);
end;
% convert to double so the image can be manipulated.
myImg = double(myImg);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
function f = cityScape(x)
% Returns the graph of the skyline
% if x = 0 then mesh plot is generated,
% otherwise it is not graphed.
f = zeros(160,100);
%f = zeros(64);
f(21:44,20:30) = 1;
f(16:49,40:45) = 2;
f(11:55,50:55) = 3;
f(30:40,50:55) = 2.2;
if x == 0
mesh(f);
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
function Z = GaussianPSF(sigma,x)
% Returns the n by n graph of the point spread function


% if x = 0 the mesh plot is generated,
% otherwise, it is not graphed.
% sigma determines how much the light is spread.
[X,Y] = meshgrid(-8:8,-8:8);
Z = exp(-sigma*(X.^2+Y.^2));
if x == 0, mesh(-8:8,-8:8,Z);
end;
III. Tài liệu tham khảo
1. Đặng Văn Vinh, Giáo trình Đại số tuyến tính
2. Nguyen Hung Chinh, 16/09/2021, Giải số hệ phương trình Đại số tuyến tính
(Phần 8) - Nhóm các phương pháp lặp
/>2. Nguyễn Thị Hồng Xuyên, 2020, Phương pháp hướng Gradient liên hợp cho
bài toán tối ưu lồi trên tập điểm bất động của ánh xạ không giãn
3. Deblurring Images using the Conjugate Gradient Method in Matlab
/>n5pZPk9rUzThxwqLg0Lyey95kFu5Pm4PhbxZKeg-9pqMwkw
4. Jonathan Richard Shewchuk, 04/08/1994, An Introduction to
the Conjugate Gradient Method Without the Agonizing Pain
/>


×