289 SUBROUTINE minres( n, b, r1, r2, v, w, w1, w2, x, y, &
290 aprod, msolve, checka,
precon, shift, nout , itnlim, rtol, &
291 istop, itn, anorm, acond, rnorm, ynorm )
294 EXTERNAL aprod, msolve
295 INTEGER :: n, nout, itnlim, istop, itn
297 DOUBLE PRECISION :: shift, rtol, anorm, acond, rnorm, ynorm, &
298 b(n), r1(n), r2(n), v(n), w(n), w1(n), w2(n), x(n), y(n)
305 DOUBLE PRECISION :: alfa , beta , beta1 , cs , &
306 dbar , delta , denom , diag , eps , epsa , epsln , epsr , epsx , &
307 agamma, gbar , gmax , gmin , oldb , oldeps, qrnorm, phi , phibar, &
308 rhs1 , rhs2 , s , sn , t , tnorm2, ynorm2, z
310 LOGICAL :: debug, prnt
312 DOUBLE PRECISION :: zero, one, two, ten
313 parameter( zero = 0.0d+0, one = 1.0d+0, &
314 two = 2.0d+0, ten = 10.0d+0 )
316 CHARACTER (LEN=16) :: enter, exit
317 CHARACTER (LEN=52) :: msg(-1:8)
319 DATA enter /
' Enter MINRES. '/, exit /
' Exit MINRES. '/
322 /
'beta2 = 0. If M = I, b and x are eigenvectors of A', &
323 'beta1 = 0. The exact solution is x = 0', &
324 'Requested accuracy achieved, as determined by rtol', &
325 'Reasonable accuracy achieved, given eps', &
326 'x has converged to an eigenvector',
'Acond has exceeded 0.1/eps', &
327 'The iteration limit was reached', &
328 'Aprod does not define a symmetric matrix', &
329 'Msolve does not define a symmetric matrix', &
330 'Msolve does not define a pos-def preconditioner' /
346 IF (eps <= zero)
THEN
352 CALL
daxpy( 1, one, x, 1, y, 1 )
353 IF (y(1) <= one) exit
363 WRITE(nout, 1000) enter, n, checka,
precon, itnlim, rtol, shift
378 CALL
dcopy( n, b, 1, y , 1 )
379 CALL
dcopy( n, b, 1, r1, 1 )
380 IF (
precon ) CALL msolve( n, b, y )
381 beta1 =
ddot( n, b, 1, y, 1 )
383 IF (beta1 < zero)
THEN
388 IF (beta1 == zero)
THEN
393 beta1 = sqrt( beta1 )
398 IF (checka .AND.
precon)
THEN
399 CALL msolve( n, y, r2 )
400 s =
ddot( n, y, 1, y, 1 )
401 t =
ddot( n,r1, 1,r2, 1 )
403 epsa = (s + eps) * eps**0.33333d+0
414 CALL aprod( n, y, w )
415 CALL aprod( n, w, r2 )
416 s =
ddot( n, w, 1, w, 1 )
417 t =
ddot( n, y, 1,r2, 1 )
419 epsa = (s + eps) * eps**0.33333d+0
442 CALL
dload2( n, zero, w2 )
443 CALL
dcopy( n, r1, 1, r2, 1 )
448 WRITE(*,*)
'beta ', beta
475 CALL aprod( n, v, y )
476 CALL
daxpy( n, (- shift), v, 1, y, 1 )
478 CALL
daxpy( n, (- beta/oldb), r1, 1, y, 1 )
481 alfa =
ddot( n, v, 1, y, 1 )
483 CALL
daxpy( n, (- alfa/beta), r2, 1, y, 1 )
484 CALL
dcopy( n, r2, 1, r1, 1 )
485 CALL
dcopy( n, y, 1, r2, 1 )
486 IF (
precon ) CALL msolve( n, r2, y )
489 beta =
ddot( n, r2, 1, y, 1 )
490 IF (beta < zero)
THEN
492 WRITE(*,*)
'unfortunately beta < 0 ',beta,zero
497 tnorm2 = tnorm2 + alfa**2 + oldb**2 + beta**2
500 IF (beta/beta1 <= ten*eps)
THEN
513 delta = cs * dbar + sn * alfa
514 gbar = sn * dbar - cs * alfa
520 agamma = sqrt( gbar**2 + beta**2 )
529 WRITE(*,*)
'alfa ', alfa
530 WRITE(*,*)
'beta ', beta
531 WRITE(*,*)
'gamma', agamma
532 WRITE(*,*)
'delta', delta
533 WRITE(*,*)
'gbar ', gbar
534 WRITE(*,*)
'epsln', epsln
535 WRITE(*,*)
'dbar ', dbar
536 WRITE(*,*)
'phi ', phi
537 WRITE(*,*)
'phiba', phibar
548 w(i) = ( v(i) - oldeps*w1(i) - delta*w2(i) ) * denom
549 x(i) = x(i) + phi * w(i)
554 gmax = max( gmax, agamma)
555 gmin = min( gmin, agamma)
557 ynorm2 = z**2 + ynorm2
558 rhs1 = rhs2 - delta * z
563 anorm = sqrt( tnorm2 )
564 ynorm = sqrt( ynorm2 )
566 epsx = anorm * ynorm * eps
567 epsr = anorm * ynorm * rtol
569 IF (diag == zero) diag = epsa
586 IF (itn >= itnlim ) istop = 5
587 IF (acond >= 0.1d+0/eps) istop = 4
588 IF (epsx >= beta1 ) istop = 3
589 IF (qrnorm <= epsx ) istop = 2
590 IF (qrnorm <= epsr ) istop = 1
598 IF (n <= 40 ) prnt = .true.
599 IF (itn <= 10 ) prnt = .true.
600 IF (itn >= itnlim - 10) prnt = .true.
601 IF (mod(itn,10) == 0) prnt = .true.
602 IF (qrnorm <= ten * epsx) prnt = .true.
603 IF (qrnorm <= ten * epsr) prnt = .true.
604 IF (acond >= 1.0d-2/eps ) prnt = .true.
605 IF (istop /= 0 ) prnt = .true.
608 IF ( itn == 1)
WRITE(nout, 1200)
609 WRITE(nout, 1300) itn, x(1), qrnorm, anorm, acond
610 IF (mod(itn,10) == 0)
WRITE(nout, 1500)
621 900
IF (nout > 0)
THEN
622 WRITE(nout, 2000) exit, istop, itn, exit, anorm, acond, &
624 WRITE(nout, 3000) exit, msg(istop)
630 1000 format(// 1p, a, 5x,
'Solution of symmetric Ax = b' &
631 /
' n =', i7, 5x,
'checkA =', l4, 12x,
'precon =', l4 &
632 /
' itnlim =', i7, 5x,
'rtol =', e11.2, 5x,
'shift =', e23.14)
633 1200 format(// 5x,
'itn', 8x,
'x(1)', 10x, &
634 'norm(r)', 3x,
'norm(A)', 3x,
'cond(A)')
635 1300 format(1p, i8, e19.10, 3e10.2)
637 2000 format(/ 1p, a, 5x,
'istop =', i3, 14x,
'itn =', i8 &
638 / a, 5x,
'Anorm =', e12.4, 5x,
'Acond =', e12.4 &
639 / a, 5x,
'rnorm =', e12.4, 5x,
'ynorm =', e12.4)
640 3000 format( a, 5x, a )