cdstep()
, implements one iteration
of the conjugate-direction method. It is based upon Jon Claerbout's
cgstep()
program Claerbout (1994) and uses an analogous
naming convention. Vectors in the data space are denoted by double
letters.
liter = min0(iter,niter)
do i= 1, n # initial direction
s(i,liter) = g(i)
do i= 1, m
ss(i,liter) = gg(i)
do j= 1, liter-1 { # update direction
alpha = ddot(m,gg,ss(1,j))/ssn(j)
do i= 1, n
s(i,liter) = s(i,liter) - alpha * s(i,j)
do i= 1, m
ss(i,liter) = ss(i,liter) - alpha * ss(i,j)
}
ssn(liter) = dmax1(ddot(m,ss(1,liter),ss(1,liter)),1.d-35)
if (liter == niter) {
do j= 1, niter-1 {
ssn(j) = ssn(j+1)
do i= 1, n
s(i,j) = s(i,j+1)
do i= 1, m
ss(i,j) = ss(i,j+1)
}
}
alpha = ddot(m,ss(1,liter),rr)/ssn(liter)
do i= 1, n # update solution
x(i) = x(i) + alpha * s(i,liter)
do i= 1, m # update residual
rr(i) = rr(i) - alpha * ss(i,liter)
return; end
double precision function ddot( n, x, y)
integer i, n; real x(n), y(n); double precision val
val = 0.; do i=1,n { val = val + x(i) * y(i) }
ddot = val; return; end
# A step of conjugate-direction descent.
#
subroutine cdstep( niter,iter, n, x, g, s, m, rr, gg, ss,ssn)
integer i,j,liter, niter,iter, n, m
real x(n), rr(m), # solution, residual
g(n), gg(m), # direction, conjugate direction
s(n,niter), ss(m,niter) # step, conjugate step
double precision ddot, alpha, ssn(niter)
In addition to the previous steps (array
s
) and their conjugate counterparts (array
ss
), the program stores the squared norms (array
ssn
) to avoid recomputation.
For practical reasons, the number of remembered iterations
niter
can actually be smaller than the total number of
iterations. The value niter=2
corresponds to the
conjugate-gradient method. The value niter=1
corresponds to the
steepest-descent method. The iteration process should start with
iter = 1
, corresponding to the first steepest-descent iteration
in the method of conjugate gradients.