294 subroutine minres( n, Aprod, Msolve, b, shift, checkA, precon, &
295 x, itnlim, nout, rtol, &
296 istop, itn, Anorm, Acond, rnorm, Arnorm, ynorm )
298 integer,
intent(in) :: n, itnlim, nout
299 logical,
intent(in) :: checka,
precon
300 real(
dp),
intent(in) :: b(n)
301 real(
dp),
intent(in) :: shift, rtol
302 real(
dp),
intent(out) :: x(n)
303 integer,
intent(out) :: istop, itn
304 real(
dp),
intent(out) :: anorm, acond, rnorm, arnorm, ynorm
307 subroutine aprod (n,x,y)
309 integer,
intent(in) :: n
310 real(
dp),
intent(in) :: x(n)
311 real(
dp),
intent(out) :: y(n)
314 subroutine msolve(n,x,y)
316 integer,
intent(in) :: n
317 real(
dp),
intent(in) :: x(n)
318 real(
dp),
intent(out) :: y(n)
319 end subroutine msolve
323 real(dp) :: r1(n), r2(n), v(n), w(n), w1(n), w2(n), y(n)
324 real(dp) :: alfa , beta , beta1 , cs , &
325 dbar , delta , denom , diag , &
326 eps , epsa , epsln , epsr , epsx , &
327 gamma , gbar , gmax , gmin , &
328 oldb , oldeps, qrnorm, phi , phibar, &
329 rhs1 , rhs2 , rnorml, rootl , &
330 arnorml, relarnorml, &
331 s , sn , t , tnorm2, ynorm2, z
333 logical :: debug, prnt
336 real(dp),
parameter :: zero = 0.0, one = 1.0
337 real(dp),
parameter :: ten = 10.0
338 character(len=*),
parameter :: enter =
' Enter MINRES. '
339 character(len=*),
parameter :: exitt =
' Exit MINRES. '
340 character(len=*),
parameter :: msg(-1:8) = &
341 (/
'beta2 = 0. If M = I, b and x are eigenvectors of A', &
342 'beta1 = 0. The exact solution is x = 0 ', &
343 'Requested accuracy achieved, as determined by rtol ', &
344 'Reasonable accuracy achieved, given eps ', &
345 'x has converged to an eigenvector ', &
346 'Acond has exceeded 0.1/eps ', &
347 'The iteration limit was reached ', &
348 'Aprod does not define a symmetric matrix ', &
349 'Msolve does not define a symmetric matrix ', &
350 'Msolve does not define a pos-def preconditioner ' /)
360 write(nout, 1000) enter, n, checka,
precon, itnlim, rtol, shift
380 if (
precon )
call msolve( n, b, y )
381 beta1 = dot_product(b,y)
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 = dot_product(y ,y )
401 t = dot_product(r1,r2)
403 epsa = (s + eps) * eps**0.33333
414 call aprod ( n, y, w )
415 call aprod ( n, w, r2 )
416 s = dot_product(w,w )
417 t = dot_product(y,r2)
419 epsa = (s + eps) * eps**0.33333
426 call aprod ( n, y, w )
427 arnorml = sqrt( dot_product(w,w) )
452 write(*,*)
'beta ', beta
478 call aprod ( n, v, y )
481 y = y - (beta/oldb)*r1
484 alfa = dot_product(v,y)
485 y = y - (alfa/beta)*r2
488 if (
precon )
call msolve( n, r2, y )
491 beta = dot_product(r2,y)
492 if (beta < zero)
then
498 tnorm2 = tnorm2 + alfa**2 + oldb**2 + beta**2
501 if (beta/beta1 <= ten*eps)
then
514 delta = cs * dbar + sn * alfa
515 gbar = sn * dbar - cs * alfa
521 gamma = sqrt( gbar**2 + beta**2 )
530 write(*,*)
'alfa ', alfa
531 write(*,*)
'beta ', beta
532 write(*,*)
'gamma', gamma
533 write(*,*)
'delta', delta
534 write(*,*)
'gbar ', gbar
535 write(*,*)
'epsln', epsln
536 write(*,*)
'dbar ', dbar
537 write(*,*)
'phi ', phi
538 write(*,*)
'phiba', phibar
549 w(i) = ( v(i) - oldeps*w1(i) - delta*w2(i) ) * denom
550 x(i) = x(i) + phi * w(i)
555 gmax = max( gmax, gamma )
556 gmin = min( gmin, gamma )
558 ynorm2 = z**2 + ynorm2
559 rhs1 = rhs2 - delta * z
564 anorm = sqrt( tnorm2 )
565 ynorm = sqrt( ynorm2 )
567 epsx = anorm * ynorm * eps
568 epsr = anorm * ynorm * rtol
570 if (diag == zero) diag = epsa
575 rootl = sqrt( gbar**2 +dbar**2 )
576 arnorml = rnorml*rootl
577 relarnorml = rootl / anorm;
592 if (itn >= itnlim ) istop = 5
593 if (acond >= 0.1d+0/eps) istop = 4
594 if (epsx >= beta1 ) istop = 3
599 if (qrnorm <= epsx .or. relarnorml <= eps) istop = 2
600 if (qrnorm <= epsr .or. relarnorml <= rtol) istop = 1
608 if (n <= 40 ) prnt = .true.
609 if (itn <= 10 ) prnt = .true.
610 if (itn >= itnlim - 10) prnt = .true.
611 if (mod(itn,10) == 0) prnt = .true.
612 if (qrnorm <= ten * epsx) prnt = .true.
613 if (qrnorm <= ten * epsr) prnt = .true.
614 if (relarnorml<= ten*epsx) prnt = .true.
615 if (relarnorml<= ten*epsr) prnt = .true.
616 if (acond >= 1.0d-2/eps ) prnt = .true.
617 if (istop /= 0 ) prnt = .true.
620 if ( itn == 1)
write(nout, 1200)
621 write(nout, 1300) itn, x(1), qrnorm, anorm, acond
622 if (mod(itn,10) == 0)
write(nout, 1500)
636 write(nout, 2000) exitt, istop, itn, &
637 exitt, anorm, acond, &
638 exitt, rnorm, ynorm, arnorm
639 write(nout, 3000) exitt, msg(istop)
644 1000
format(// 1p, a, 5x,
'Solution of symmetric Ax = b' &
645 /
' n =', i7, 5x,
'checkA =', l4, 12x, &
647 /
' itnlim =', i7, 5x,
'rtol =', e11.2, 5x, &
649 1200
format(// 5x,
'itn', 8x,
'x(1)', 10x, &
650 'norm(r)', 3x,
'norm(A)', 3x,
'cond(A)')
651 1300
format(1p, i8, e19.10, 3e10.2)
653 2000
format(/ 1p, a, 5x,
'istop =', i3, 14x,
'itn =', i8 &
654 / a, 5x,
'Anorm =', e12.4, 5x,
'Acond =', e12.4 &
655 / a, 5x,
'rnorm =', e12.4, 5x,
'ynorm =', e12.4, 5x,
'Arnorml =', e12.4)
656 3000
format( a, 5x, a )
subroutine precon(p, n, c, cu, a, s, nrkd)
Constrained preconditioner, decomposition.
Defines real(kind=dp) and a few constants for use in other modules.
integer, parameter, public dp
MINRES solves symmetric systems Ax = b or min ||Ax - b||_2, where the matrix A may be indefinite and/...
subroutine, public minres(n, Aprod, Msolve, b, shift, checkA, precon, x, itnlim, nout, rtol, istop, itn, Anorm, Acond, rnorm, Arnorm, ynorm)
Solution of linear equation system.