-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstencil_pcg.m
More file actions
70 lines (49 loc) · 1.54 KB
/
stencil_pcg.m
File metadata and controls
70 lines (49 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
function [x, flg, resNew, its] = stencil_pcg(f, b, tol, maxit)
% STENCIL_PCG computes CG with 1st order approximation for f
%
% Fabio VERBOSIO, Universita` della Svizzera italiana, November 2018
%
its = 0;
flg = 1;
e = 1e-08;
x0 = zeros(size(b)); % initial guess
x = x0;
Fx = f(x);
xx = (1+e)*x;
Fxx = f(xx);
r = b - (1/e) * (Fxx - Fx); % A*x \approx (1/e) * (Fxx-Fx)
p = r;
resOld = r'*r;
resNew = resOld;
if (sqrt(resOld) < tol)
flg = 0;
%fprintf('STENCIL_CG: converged in 0 iterations (initial guess is good enough!\n');
return;
end
for its = 1:maxit
%fprintf('STENCIL_CG: %3d ', its);
Fx = f(x);
xx = x + e*p;
Fxx = f(xx);
Ap = (1/e) * (Fxx-Fx); % A*p approx. by Ap
%fprintf(' * RES. FOR Ap = %.4e * ', norm(Ap-A*p)/norm(A*p));
alpha = r'*r / (p'*Ap);
x = x + alpha * p;
rnew = r - alpha * Ap;
resNew = rnew' * rnew;
if (sqrt(resNew) < tol)
flg = 0;
break;
end
beta = resNew / resOld; % res=<r(k-1),r(k-1)>, resNew=<r(k+1),r(k+1)>
p = rnew + beta * p;
r = rnew;
resOld = resNew;
%fprintf(' - RELRES: %.4e\n', sqrt(resNew));
end
if flg == 0
%fprintf('STENCIL_CG: converged in %d iterations.\n', its);
else
%fprintf('STENCIL_CG: could NOT converge.\n');
end
end