Millepede-II  V04-00-00_preview
 All Classes Files Functions Variables Enumerator Pages
minres.f90
Go to the documentation of this file.
1 
2 ! Code converted using TO_F90 by Alan Miller
3 ! Date: 2012-03-16 Time: 11:06:43
4 
7 
288 
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 )
292 
293  IMPLICIT NONE
294  EXTERNAL aprod, msolve
295  INTEGER :: n, nout, itnlim, istop, itn
296  LOGICAL :: checka, precon
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)
299 
300  EXTERNAL ddot , dnrm2
301  DOUBLE PRECISION :: ddot , dnrm2
302 
303  ! Local variables
304 
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
309  INTEGER :: i
310  LOGICAL :: debug, prnt
311 
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 )
315 
316  CHARACTER (LEN=16) :: enter, exit
317  CHARACTER (LEN=52) :: msg(-1:8)
318 
319  DATA enter /' Enter MINRES. '/, exit /' Exit MINRES. '/
320 
321  DATA msg &
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' /
331  ! ------------------------------------------------------------------
332 
333  debug = .false.
334 
335  ! ------------------------------------------------------------------
336  ! Compute eps, the machine precision. The call to daxpy is
337  ! intended to fool compilers that use extra-length registers.
338  ! 31 May 1999: Hardwire eps so the debugger can step thru easily.
339  ! ------------------------------------------------------------------
340  eps = 2.22d-16 ! Set eps = zero here if you want it computed.
341 
342  eps = 0.0d0 !!!!!!!!!!!!!!!
343  gmin = 0.0d0
344  gmax = 0.0d0
345 
346  IF (eps <= zero) THEN
347  eps = two**(-12)
348  DO
349  eps = eps / two
350  x(1) = eps
351  y(1) = one
352  CALL daxpy( 1, one, x, 1, y, 1 )
353  IF (y(1) <= one) exit
354  END DO
355  eps = eps * two
356  END IF
357  ! WRITE(*,*) 'computed epsilon is ',eps !!!!!!!!!!!!!!!
358 
359  ! ------------------------------------------------------------------
360  ! Print heading and initialize.
361  ! ------------------------------------------------------------------
362  IF (nout > 0) THEN
363  WRITE(nout, 1000) enter, n, checka, precon, itnlim, rtol, shift
364  END IF
365  istop = 0
366  itn = 0
367  anorm = zero
368  acond = zero
369  rnorm = zero
370  ynorm = zero
371  CALL dload2( n, zero, x )
372 
373  ! ------------------------------------------------------------------
374  ! Set up y and v for the first Lanczos vector v1.
375  ! y = beta1 P' v1, where P = C**(-1).
376  ! v is really P' v1.
377  ! ------------------------------------------------------------------
378  CALL dcopy( n, b, 1, y , 1 ) ! y = b
379  CALL dcopy( n, b, 1, r1, 1 ) ! r1 = b
380  IF ( precon ) CALL msolve( n, b, y )
381  beta1 = ddot( n, b, 1, y, 1 )
382 
383  IF (beta1 < zero) THEN ! m must be indefinite.
384  istop = 8
385  go to 900
386  END IF
387 
388  IF (beta1 == zero) THEN ! b = 0 exactly. Stop with x = 0.
389  istop = 0
390  go to 900
391  END IF
392 
393  beta1 = sqrt( beta1 ) ! Normalize y to get v1 later.
394 
395  ! ------------------------------------------------------------------
396  ! See if Msolve is symmetric.
397  ! ------------------------------------------------------------------
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 )
402  z = abs( s - t )
403  epsa = (s + eps) * eps**0.33333d+0
404  IF (z > epsa) THEN
405  istop = 7
406  go to 900
407  END IF
408  END IF
409 
410  ! ------------------------------------------------------------------
411  ! See if Aprod is symmetric.
412  ! ------------------------------------------------------------------
413  IF (checka) THEN
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 )
418  z = abs( s - t )
419  epsa = (s + eps) * eps**0.33333d+0
420  IF (z > epsa) THEN
421  istop = 6
422  go to 900
423  END IF
424  END IF
425 
426  ! ------------------------------------------------------------------
427  ! Initialize other quantities.
428  ! ------------------------------------------------------------------
429  oldb = zero
430  beta = beta1
431  dbar = zero
432  epsln = zero
433  qrnorm = beta1
434  phibar = beta1
435  rhs1 = beta1
436  rhs2 = zero
437  tnorm2 = zero
438  ynorm2 = zero
439  cs = - one
440  sn = zero
441  CALL dload2( n, zero, w ) ! w = 0
442  CALL dload2( n, zero, w2 ) ! w2 = 0
443  CALL dcopy( n, r1, 1, r2, 1 ) ! r2 = r1
444 
445  IF (debug) THEN
446  WRITE(*,*) ' '
447  WRITE(*,*) 'b ', b
448  WRITE(*,*) 'beta ', beta
449  WRITE(*,*) ' '
450  END IF
451 
452  ! ------------------------------------------------------------------
453  ! Main iteration loop.
454  ! ------------------------------------------------------------------
455  DO
456  itn = itn + 1 ! k = itn = 1 first time through
457  IF (istop /= 0) exit
458 
459  !-----------------------------------------------------------------
460  ! Obtain quantities for the next Lanczos vector vk+1, k = 1, 2,...
461  ! The general iteration is similar to the case k = 1 with v0 = 0:
462  !
463  ! p1 = Operator * v1 - beta1 * v0,
464  ! alpha1 = v1'p1,
465  ! q2 = p2 - alpha1 * v1,
466  ! beta2^2 = q2'q2,
467  ! v2 = (1/beta2) q2.
468  !
469  ! Again, y = betak P vk, where P = C**(-1).
470  ! .... more description needed.
471  !-----------------------------------------------------------------
472  s = one / beta ! Normalize previous vector (in y).
473  CALL dscal2( n, s, y, v ) ! v = vk if P = I
474 
475  CALL aprod( n, v, y )
476  CALL daxpy( n, (- shift), v, 1, y, 1 )
477  IF (itn >= 2) THEN
478  CALL daxpy( n, (- beta/oldb), r1, 1, y, 1 )
479  END IF
480 
481  alfa = ddot( n, v, 1, y, 1 ) ! alphak
482 
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 )
487 
488  oldb = beta ! oldb = betak
489  beta = ddot( n, r2, 1, y, 1 ) ! beta = betak+1^2
490  IF (beta < zero) THEN
491  istop = 6
492  WRITE(*,*) 'unfortunately beta < 0 ',beta,zero
493  exit
494  END IF
495 
496  beta = sqrt( beta ) ! beta = betak+1
497  tnorm2 = tnorm2 + alfa**2 + oldb**2 + beta**2
498 
499  IF (itn == 1) THEN ! Initialize a few things.
500  IF (beta/beta1 <= ten*eps) THEN ! beta2 = 0 or ~ 0.
501  istop = -1 ! Terminate later.
502  END IF
503  !tnorm2 = alfa**2
504  gmax = abs( alfa ) ! alpha1
505  gmin = gmax ! alpha1
506  END IF
507 
508  ! Apply previous rotation Qk-1 to get
509  ! [deltak epslnk+1] = [cs sn][dbark 0 ]
510  ! [gbar k dbar k+1] [sn -cs][alfak betak+1].
511 
512  oldeps = epsln
513  delta = cs * dbar + sn * alfa ! delta1 = 0 deltak
514  gbar = sn * dbar - cs * alfa ! gbar 1 = alfa1 gbar k
515  epsln = sn * beta ! epsln2 = 0 epslnk+1
516  dbar = - cs * beta ! dbar 2 = beta2 dbar k+1
517 
518  ! Compute the next plane rotation Qk
519 
520  agamma = sqrt( gbar**2 + beta**2 ) ! gammak
521  cs = gbar / agamma ! ck
522  sn = beta / agamma ! sk
523  phi = cs * phibar ! phik
524  phibar = sn * phibar ! phibark+1
525 
526  IF (debug) THEN
527  WRITE(*,*) ' '
528  WRITE(*,*) 'v ', v
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
538  WRITE(*,*) ' '
539  END IF
540 
541  ! Update x.
542 
543  denom = one/agamma
544 
545  DO i = 1, n
546  w1(i) = w2(i)
547  w2(i) = w(i)
548  w(i) = ( v(i) - oldeps*w1(i) - delta*w2(i) ) * denom
549  x(i) = x(i) + phi * w(i)
550  END DO
551 
552  ! Go round again.
553 
554  gmax = max( gmax, agamma)
555  gmin = min( gmin, agamma)
556  z = rhs1 / agamma
557  ynorm2 = z**2 + ynorm2
558  rhs1 = rhs2 - delta * z
559  rhs2 = - epsln * z
560 
561  ! Estimate various norms and test for convergence.
562 
563  anorm = sqrt( tnorm2 )
564  ynorm = sqrt( ynorm2 )
565  epsa = anorm * eps
566  epsx = anorm * ynorm * eps
567  epsr = anorm * ynorm * rtol
568  diag = gbar
569  IF (diag == zero) diag = epsa
570 
571  qrnorm = phibar
572  rnorm = qrnorm
573 
574  ! Estimate cond(A).
575  ! In this version we look at the diagonals of R in the
576  ! factorization of the lower Hessenberg matrix, Q * H = R,
577  ! where H is the tridiagonal matrix from Lanczos with one
578  ! extra row, beta(k+1) e_k^T.
579 
580  acond = gmax / gmin
581 
582  ! See if any of the stopping criteria are satisfied.
583  ! In rare cases, istop is already -1 from above (Abar = const*I).
584 
585  IF (istop == 0) THEN
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
591  END IF
592 
593 
594  ! See if it is time to print something.
595 
596  IF (nout > 0) THEN
597  prnt = .false.
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.
606 
607  IF ( prnt ) THEN
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)
611  END IF
612  END IF
613 
614  END DO
615  ! ------------------------------------------------------------------
616  ! End of main iteration loop.
617  ! ------------------------------------------------------------------
618 
619  ! Display final status.
620 
621 900 IF (nout > 0) THEN
622  WRITE(nout, 2000) exit, istop, itn, exit, anorm, acond, &
623  exit, rnorm, ynorm
624  WRITE(nout, 3000) exit, msg(istop)
625  END IF
626 
627  return
628 
629 
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)
636 1500 format(1x)
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 )
641 
642 END SUBROUTINE minres