[ Home ] [ News ] [ Contact ] [ Search ]

 ==> Download Software
 nextnano³ documentation

 Copyright notice
 About us
 Useful Links
 Publications
 
 * password protected

 

 
 

Numerical Library


Overview

Algorithms

  • CG
    conjugate gradient
    - stable and robust
    - symmetric positive defnite
  • PCG
    preconditioned conjugate gradient
    ICCG = incomplete Choleski decomposition
    MICCG = modified incomplete Choleski decomposition (MODULE miccg3DdV)
  • CGNE
    conjugate gradient on normal equations
    - minimization of error
    AAHx=AHb
    Craig's method
  • CGNR
    AHAx=AHb
    conjugate gradient on residual
    - minimization of residual, equivalent to LSQR
    (+ row protection method as preconditioning = with use of block Jacobi or block SSOR preconditioning)
    CGNR and CGNE converge slowly for nonhermitian A (therefore: GMRES, restarted GMRES(m))
  • CGS
    conjugate gradient squared
  • BiCG
    biconjugate gradient
  • BiCGSTAB (Vorst)
    biconjugate gradient stabilized
    - based on unsymmetric Lanczos
  • GMRES
    generalised minimal residual
    - guaranteed to converge if A is definite
  • GMRES(m)
    restarted GMRES
  • FMRES
    CG with variable preconditioning Flexible GMRES
  • GMRESR
  • LSQR
  • GMERR
  • QMR (Freund)
    quasi-minimal residual
    - QMR uses look-ahead Lanczos process to generate basis vectors
    - more stable and robust than GMRES, BiCGSTAB
    - half the work and storage for hermitian/symmetric matrices
    - + Sonneveld's trick
    - QMR is mathematically equivalent to MINRES in the special case of A Hermititan.
    - MINRES and SYMMLQ require a symmetric positive definite preconditioner wheresas QMR only a symmetric one.
    - QMR will converge fast if the eigenvalues are clustered aound 1.
  • QMRSTAB
  • MINRES
    - only symmetric positive definite preconditioner
    - without preconditioning symmetric QMR and MINRES are mathematically equivalent
  • SYMMLQ
    - only symmetric positive definite preconditioner
    - less sensitive to ill-conditioned A than MINRES but often takes more steps
    - Both SYMMLQ and MINRES use the Hermitian Lanczos recursion to generate an orthonormal basis for the Krylov subspaces (3-term recurrence).
  • SYMMBK
    - slightly less expensive variant of SYMMLQ
  • TFQMR (Freund)
    transpose-free quasi-minimal residual
    no need for AT, only A is need
  • ORTHODIR
    - guaranteed to converge if A is definite
    - shift-inverse
  • ORTHOMIN
    - similar to GMRES
    - similar to generalized CG residual method
  • ORTHORES

Matrix Type

  • symmetric positive definite
    guaranteed to converge: CG, PCG, ICCG, MICCG, ICCG/MICCG
    - Choleski decomposition leads to trianguar decomposition
  • symmetric indefinite
    QMR, MINRES, SYMMLQ
    - SYMMLQ less sensitive to ill-conditioned A than MINRES but often takes more steps
    - MINRES and SYMMLQ don't allow an indefinite preconditioner, but QMR does.
    (CGNE, CGNR)
    - SYMMLQ and MINRES are standard algorithms for symmetric indefinite systems but they require a symmetric positive preconditioner M=M1M2 where M2=M1T. This is a problem for highly indefinite systems as you need a preconditioner that is also highly indefinite to better approximate A.
    - Solution: use symmetric QMR. This is an adaption to the general nonsymmetric QMR.
  • M-Matrix
    (aij<0 for i unequal j, A is nonsingular, A-1>0)
    PCG (VORST method ICCG-MICCG)
  • H-Matrix
    (diagonally dominant (somewhat))
  • hermitian positive definite
  • hermitian indefinite
    QMR, TFQMR, GMRES, BiCGSTAB
  • complex symmetric
    QMR, TFQMR, GMRES, BiCGSTAB
  • definite
    (i.e. the symmetric part (A+AT)/2 or its negative is symmetric positive definite)
    guaranteed to converge: ORTHODIR, GMRES
  • unsymmetric
    QMR, TFQMR, GMRES, GMRES(m), BiCGSTAB, CGR

Preconditioners

  • Jacobi
    D-1
  • SSOR
    (L+D)D-1(D+LT)
    - mixed preconditioning is more efficient because of Eisenstat's trick
    - The CGNE/SSOR and CGNR/SSOR will not brake down if A is nonsingular since then the matrices ATA or AAT are symmetric positive definite.
    - extend SSOR preconditioner to indefinite matrices
  • CGNE/ILQ (Craig's method)
  • CGNR/ILQ
  • LU
    lower-upper factorization
    - for indefinite matrices the LU decomposition could lead to numerical instabilities
  • ILU
    incomplete LU preconditioning with positional dropping ILU(k)
    ILU for indefinite matrices:
    - LU sometimes inaccurate, i.e. not close to A, due to small pivots
    - L or U sometimes not diagonally dominant
  • ILUT
    incomplete LU preconditioning with numerical dropping ILUT(k)
  • MILU
    modified incomplete LU preconditioning with positional dropping MILU(k)
  • incomplete QR (Saad)
  • polynomial preconditioning
    It is difficult to find a good polynomial in the case of indefinite matrices.
  • use symmetric positive definite preconditioner to cluster eigenvalues around 1 and -1
    use symmetric indefinite preconditioner to cluster eigenvalues around 1

Summary

  • Hermitian matrices have special spectral properties.
  • Roughly speaking, Krylov subspace methods are most effective for coefficient matrices A whose spectrum, except for possibly a few isolated eigenvalues, is contained in a half-plane which excludes the origin of the complex plane.
    All Krylov.subspace iterations converge very slowly for highly indefinite coefficient matrices.
    Krylov space methods normally do not require any a priori spectral information and there are methods in this class especially designed for indefinite and nonsymmetric problems.
  • We should point out, however, that the incomplete Cholesky factorisation is not guaranteed to exist for an arbitrary positive definite symmetric matrix. (should be somehow diagonal dominant)
  • The convergence of conjugate gradients depends on the distribution of the eigenvalues (spectrum) of the matrix.
  • The main difficulty in indefinite preconditioning can be explained as follows. The Krylov subspace methods converge fast when the eigenvalues are clustered, say aroung 1. This means, that the preconditioner, often viewed as an approximation to the inverse of the given matrix, must transfer the eigenvalues to 1. It may easily happen that, due to approximation errors that are intentionally made in order to keep the process efficient, eigenvalues are transferred to values close to 0. In that case the convergence of Krylov subspace methods will be slow, and it may happen that the unpreconditioned iteration process converges faster than the preconditioned iteration.
    Complex-valued problems can be treated as the problems discussed in this paper, in particular Hermitian problems can be treated as real symmetric ones by replacing AT by AH , and by the appropriate change of innerproduct.
  • The Lanczos method reduces to only one recursion for the case of A Hermitian or complex symmetric.

 

Fermi-Functions and Exponential-Function

The MODULE fermi_functions contains several subroutines and functions for the evaluation of Fermi-Dirac integrals and the exponential function.

MODULE EXPONENT_FUNCTION

function exponentV(argV,typeC,factorlesshuge) result(valueV)
!-------------------------------------------------------------------------------
! Function allows one to call predefined functions of exp(argV) for any argument
! from -INF to +INF and returns an accurate value. Routine serves purpose to
! prevent overflow and roundoff-errors by using appropriate reordering or
! Talyor expansion before calling exp-function. Max. error is of the order
! of 10^-32 on Suns and Decs.
!
! depending on typeC, returns vector-valued function of exp(argV)
! input ..
! argV = V, vector, argument of exponential 
! maybe scalar but result is vector of at least length 1
! typeC .. character that specifies function to be evaluated
! factorlesshuge .. optional argument relevant only for typeC='exp'
! ensures exp(argV) < HUGE * factorlesshuge 
! where HUGE is largest representable number (10^308)
! example: factorlesshuge=1.d-20 causes upper bound of result
! to be HUGE * 1.d-20 = 10^(308-20)
! output ..
! valueV , vector of same length as argV, whereby
!
! typeC = 'exp' ... valueV = exp(V)
! typeC = 'fermi' ... valueV = 1/(1+exp(V))
! typeC = 'bernexp' ... valueV = V exp(V)/(exp(V)-1)
! typeC = 'bern' ... valueV = V /(exp(V)-1)
! typeC = 'lnexp' ... valueV = ln(1+exp(V))
! -------------------------------------------------------------------------------------------------------------

!------------------------------------------------------------------------------  
FUNCTION fermi_trap_levelV(argV,gV,ch) result(valueV)
!---------------------------------------------------------------- 
!
! calculates 1/(1+gV*exp(argV)) for ch='fc'
! -exp(argV)/(1+gV*exp(argV))^2 for ch='df'
!
!----------------------------------------------------------------

MODULE FERMI_FUNCTIONS

!--------------------------------------------------------------------------------
!
! 1. FUNCTION fermi3_2

! 2. FUNCTION fermi1_2
!
! 3. FUNCTION fermi_min_1_2

! 4. FUNCTION fermi_min_3_2
!
!--------------------------------------------------------------------------------

!---------------------------------------------------------------------------------
FUNCTION fermi1_2(x,ch,err) result(erg)
!---------------------------------------------------------------------------------

! calculates fermiintegral of order j=1/2
!
!             /       j 
!     2     |      z
! ---------  |  ------------------- dz 
! sqrt(pi) |   exp(z-x) + 1
!            / 
!
! in this case VAN HALEN/PULFREY is taken
! err is set to 1.0d10
!
! VAN HALEN attains a precision of only 1.0d-4 to 1.0d-5 between 2.0 and 4.0
! therefore modified version of WONG et alias
!---------------------------------------------------------------------------------
!
! input:
!
! x ... real(8) 
!
! ch ... character(len=1)
! = '1' : precision 5.0d-3 (AYMERICH-HUMET)
! = '2' : precision 5.0d-6 (VAN HALEN, PULFREY)
!
! err ... real(8) : precision , if ch='3' is chosen
!
!---------------------------------------------------------------------------------

!---------------------------------------------------------------------------------
FUNCTION fermi_min_1_2(x,ch,err) result(erg)
!---------------------------------------------------------------------------------

! calculates fermiintegral of order j=-1/2
!
!             /        j 
!    1       |     z
! ----------  | ------------------  dz 
! sqrt(pi)  | exp(z-x) + 1
!            / 
!
!---------------------------------------------------------------------------------
!
! input:
!
! x ... real(8) 
!
! ch ... character(len=1)
!
! = '2','1' : precision 6.1d-6 (VAN HALEN, PULFREY)
!
! err ... real(8) : precision , if ch='3' is chosen
!
! VAN HALEN : basis functions from his paper
! coefficients calculated by sth
!---------------------------------------------------------------------------------

Newton method (with line minimization)

The Newton method in subroutine newton is used to calculate the roots of a functional.

!------------------------------------------------------------------------------------------------------------------
SUBROUTINE newton(xV,ctrl,iter,tolf,tolmin,stpmx,ALF,newton_correction,calculate_function,calculate_gradient)
!------------------------------------------------------------------------------------------------------------------
! based on Numerical Recipes
! modified by sth 23.10.1998
!
! calculates root of N-dim. nonlinear equation by a globally convergent Newton's method
! On entry, xV is the initial guess
! ctrl = .true. , if routine has converged to a local minimum. Restart with different initial value
! = .false. on normal return
! iter (output) number of iterations
! (input) maximum number of iterations
!
! tolf ... convergence criterion on function values
! tolmin ... criterion for deciding whether spurious convergence to a minimum has occurred
! tolx ... convergence criterion on dx
! stpmx ... scaled maximum step length allowed in line searches
!
!
! User must provide following SUBROUTINES:
!
! SUBROUTINE newton_correction(dxV,xV,fV)
! given xV,fV (input) this subroutine calculates one newton correction step dxV :
! fdjac*dxV = -fV
!
! SUBROUTINE calculate_function(xV,fV)
! calculates value of function whose root should be calculated
!
! SUBROUTINE calculate_gradient(xV,fV,gradientV)
! calculates gradient fV*fdjac for linesearch
! note: fmin=0.5*fV*fV ==> fV=0 <=> 0 = grad fmin = fV * fdjacV ^= matmult(fV,fdjac)
!
!------------------------------------------------------------------------------------------------------------------ 

 

Conjugate Gradient for real, symmetric matrices

!=========================================================
subroutine cg (n, xV, iter, resid, info, brhs_V , matvec , psolve)
!-----------------------------------------------------------------------------------
! Univ. of Tennessee and Oak Ridge National Laboratory 
! October 1, 1993 
! Details of this algorithm are described in "Templates for the 
! Solution of Linear Systems: Building Blocks for Iterative
! Methods", Barrett, Berry, Chan, Demmel, Donato, Dongarra,
! Eijkhout, Pozo, Romine, and van der Vorst, SIAM Publications, 
! 1993. (ftp netlib2.cs.utk.edu; cd linalg; get templates.ps).
!
! converted to f90 and modified by pv, 3-29-98 , modified by sth, 10-30-98
!
! CG solves the linear system PmatrixM * xV = brhs_V using the
! Conjugate Gradient iterative method with preconditioning.
!
! Convergence test: ( norm( brhs_V - PmatrixM * xV ) / norm( brhs_V ) ) < TOL.
! For other measures, see the above reference.
! --Done in CGREVCOM.
! input/output ....
! n on entry, the dimension of the matrix. unchanged on exit.
! xv(n) on input, the initial guess. this is commonly set to the zero
! vector. on exit, if info = 0, the iterated approximate solution.
! set by cgrevcom.
! iter on input, the maximum iterations to be performed. on output, actual
! number of iterations performed. set by cgrevcom.
! resid on input, the allowable convergence measure for
! norm( PchargeV - PmatrixM*xV ) / norm( PchargeV ). on output,
! the final value of this measure.set by cgrevcom.
!
! info (output) . set by cgrevcom()
!
! brhs_V right handside of equation to be solved

!
! matvec (subroutine)
! The user must provide a subroutine to perform the matrix-vector product 
! yV := alpha*PmatrixM*xV + beta*yV
! where alpha and beta are scalars, xV and yV are vectors, and PmatrixM
! is the Poisson matrix. Vector xV must remain unchanged. The solution 
! is over-written on vector yV. The call is:

! call matvec( alpha, xV, beta, yV ) 


! psolve ( subroutine)
! The user must provide a subroutine to perform the preconditioner 
! solve routine for the linear system 

! M*xV = bV, 

! where xV and bV are given vectors, and M a matrix. Vector bV must 
! remain unchanged. The solution is over-written on vector xV. 
! The call is:
!
! call psolve( xV, bV) 

! ============================================================

 

BiConjugate Gradient for real, nonsymmetric matrices

!================================================================
SUBROUTINE BICGSTAB (N, xV, ITER, RESID, INFO, brhs_V , matvec , psolve)
!------------------------------------------------------------------------------- 
!
! -- Iterative template routine --
! Univ. of Tennessee and Oak Ridge National Laboratory
! October 1, 1993
! Details of this algorithm are described in "Templates for the
! Solution of Linear Systems: Building Blocks for Iterative
! Methods", Barrett, Berry, Chan, Demmel, Donato, Dongarra,
! Eijkhout, Pozo, Romine, and van der Vorst, SIAM Publications,
! 1993. (ftp netlib2.cs.utk.edu; cd linalg; get templates.ps).
!
! converted to f90 and modified by pv, 4-29-98
!
! BICGSTAB solves the linear system JmatrixM*xV = RecombV using the
! BiConjugate Gradient Stabilized iterative method with
! preconditioning.
!
! Convergence test: ( norm( RecombV - JmatrixM*xV ) / norm( RecombV ) ) < TOL.
! For other measures, see the above reference.
!
! Arguments
! =========
!
! N (input) INTEGER.
! On entry, the dimension of the matrix.
! Unchanged on exit.
! xV (input/output) DOUBLE PRECISION array, dimension N.
! On input, the initial guess. This is commonly set to
! the zero vector.
! On exit, if INFO = 0, the iterated approximate solution.
! ITER (input/output) INTEGER
! On input, the maximum iterations to be performed.
! On output, actual number of iterations performed.
! RESID (input/output) DOUBLE PRECISION
! On input, the allowable convergence measure for
! norm(RecombV - JmatrixM*xV ) / norm( RecombV ).
! On output, the final value of this measure.
! preconC chosen preconditioner, can be one of
! 'jacbi' .. Jacobi preconditioner
! 'ident' .. no preconditioner applied
! 'dilu' .. dilu preconditioner
! INFO (output) INTEGER 
! = 0: Successful exit. Iterated approximate solution returned
! > 0: Convergence to tolerance not achieved. This will be 
! set to the number of iterations performed. 
! < 0: Illegal input parameter, or breakdown occurred 
! during iteration. 
! Illegal parameter: 
! -1: matrix dimension N < 0 
! -2: can no longer occur in f90 version (pv) 
! -3: Maximum number of iterations ITER <= 0. 
! BREAKDOWN: If parameters RHO or OMEGA become smaller 
! than some tolerance, the program will terminate.
! Here we check against tolerance BREAKTOL.
! -10: RHO < BREAKTOL: RHO and RTLD have become
! orthogonal.
! -11: OMEGA < BREAKTOL: S and T have become
! orthogonal relative to T'*T.
! BREAKTOL is set in function GETBREAK.
!
! input via module currentmatrix (passed to subroutines of bicgstab) ....
! JdiagV(n), JsubdiagV(n),JsupdiagV(n) ..current matrix in form of 
! main, sub- and super-diagonal
! RecombV(n) ... right hand side of current equation
!
! workM (workspace) real array, dimension (n,7) 
! Workspace for residual, direction vector, etc.
! Note that vectors R and S shared the same workspace.
!
! routines called ..
!
! matvec (subroutine)
! The user must provide a subroutine to perform the
! matrix-vector product
!
! yV := alpha*JmatrixM*xV + beta*yV,
!
! where alpha and beta are scalars, xV and yV are vectors, 
! and JmatrixM is the current matrix. Vector xV must remain unchanged. 
! The solution is over-written on vector yV.
!
! The call is:

! CALL matvec( ALPHA, xV, BETA, YV )
!
!
! PSOLVE (subroutine)
! The user must provide a subroutine to perform the
! preconditioner solve routine for the linear system
!
! M*xV = bV,
!
! where xV and bV are vectors, and M a matrix. Vector bV must
! remain unchanged.
! The solution is over-written on vector bV.
!
! The call is:
! CALL PSOLVE( xV, bV )
!
! ==============================================================

 

Iterative Eigensolver for real, symmetric matrices (ARNOLDI)

subroutine eigensolver_real_arpack(NDIM,EIGENVECTORL,WHICH_EIGVALC,MAX_EIGVAL,&
TOLERANCE,MAX_ITERATIONS,SIGMA,RESID_LIN_EQ,IPROBLEM,NC, &
eigenvalueV,eigenvectorM,lin_equation_solver_arnoldi,matvec)
!-----------------------------------------------------------------------------
! diagonalize symmetric Hamiltonian matrix with Arnoldi iteration
! compute max_eigval lowest eigenvalues
! input ... 
! ndim .. actual size of Hamilton = number of grid points
! eigenvectorL .. T calculate eigenvalues+eigenvectors, F only former
! which_eigvalC(2) .. which eigenvalues are to be computed, can be
! 'LA','SA','LM','SM','BE' ... 1.letter:
! large/small/bothends,
! 2.letter:algebraic/in magnitude
! max_eigval .. compute that many eigenvalues <=ndim, 
! starting with lowest
! tolerance ... convergence criterion, may be set to 0.d0
! (-> epsilon(0d0))
! max_iterations .. maximum number of iterations
! sigma ........ in shift-invert mode, 
! eigenvalues near a point sigma_si are sought 

! output ... 
! eigenvalueV(1:max_eigval) ... eigenvalues in eV 
! eigenvectorM(1:ndim, 1:max_eigval) ...eigenvectors psi, 
! nc ... number of eigenvalues that converged
!
!-----------------------------------------------------------------------------
!
! USER must provide following routines as input:
!
! 1. SUBROUTINE lin_equation_solver_arnoldi(ndim,yV,xV,resid_lin_eq,ierr,&
! sigma)
! calculates yV = inv[A-sigma*I]*xV
! resid_lin_eq ... tolerance
! ierr .. output, if ierr/=0 routine failed
! sigma .. real number, see above
!
! 2. SUBROUTINE matvec(ndim,xV,yV)
!
! calculates yV = Matrix*xV
!
!------------------------------------------------
!
! uses arpack and lapack routines (contained in arpack_sg.f)
!
!-----------------------------------------------------------------------------

 

Iterative Eigensolver for real, symmetric matrices (Conjugate Gradient)

subroutine eigensolver_realsym(ndim,num_ev,eigenvaluesV,eigenfunctionsM, &
init,itere_max,itsub_max,eps_itere,eps_itsub,info_itere,info_itsub, &
iwrite,matrix_vector,precond,inner_product)
!------------------------------------------------------------------------------
!
! eigensolver for real symmetric matrices (symmetric with respect to the
! inner product)
! calculates the num_ev LOWEST eigenvalues
! matrix is only accessed through the three user-defined subroutines
!
!------------------------------------------------------------------------------
!
! ndim (input) ... dimension of the matrix
! num_ev (input) ... number of eigenvalues to be calculated
!
! eigenvaluesV (input/output) ... real,dimension(num_ev)
! contains eigenvalues on return
! for init/=0 input values are taken as initial guess
! eigenfunctionsM (input/output) ... real,dimension(ndim,num_ev)
! contains eigenfunctions on return
!
! for init/=0 input values are taken as initial guess
! init (input) ... /=0 --> the program takes input values of eigenvaluesV and
! eigenfunctionsM as initial guess
! in this case eigenfunctions must be normalized
! =0 --> initial guess is generated by random numbers
!
! itere_max (input/output) ... maximum number of outer iterations
! contains actual number of iterations on return
! eps_itere (input/output) ... precision for outer loop
! contains actual precision on return
! info_itere (output) ... =0 ,if precision is reached within itere_max
! =1 ,oterwise
!
! itsub_max (input/output) ... maximum number of inner iterations
! contains actual number of iterations on return
! eps_itsub (input/output) ... precision for inner loop
! contains actual precision on return
! info_itsub (output) ... =0 ,if precision is reached within itsub_max
! =1 ,otherwise
!
! iwrite (input) ... =0 --> no information printed
! /=0 --> information printed
!
!-----------------------------------------------------------------------------
!
! subroutine matrix_vector(ndim,x_inV,x_outV) 
! integer,intent(in) :: ndim
! real(8),dimension(ndim),intent(in) :: x_inV
! real(8),dimension(ndim),intent(out) :: x_outV
!
! calculates matrix-vector product : x_outV = Matrix * x_inV
!
!---------------------------------------------------------------
!
! subroutine precond(ndim,x_inV,x_outV)
! integer,intent(in) :: ndim
! real(8),dimension(ndim),intent(in) :: x_inV
! real(8),dimension(ndim),intent(out) :: x_outV
!
! preconditions the vector x_inV --> x_outV
!
!--------------------------------------------------------------
!
! subroutine inner_product(ndim,x_in1V,x_in2V,inn_prod)
! integer :: ndim
! real(8),dimension(ndim),intent(in) :: x_in1V,x_in2V
! real(8),intent(out) :: inn_prod
!
! calculates inner product: inn_prod = <x_in1V|x_in2V>
!
!------------------------------------------------------------------------------

 

Iterative Eigensolver for hermitian matrices (ARNOLDI)

SUBROUTINE arnoldi_complex(ndim,eigenvectorL,which_eigvalC,max_eigval, &
tolerance,max_iterations,sigma,resid_lin_eq,iproblem, &
eigenvalueV,eigenvectorM,lin_equation_solver_arnoldi, &
matvec)
!-------------------------------------------------------------------------

! diagonalize complex matrix with Arnoldi iteration
! compute max_eigval lowest eigenvalues
!
! note: the ARPACK routines used can handle also nonhermitian matrices
! therefore eigenvalueV and eigenvectorV are complex
! If your matrix is hermitian, the same routines are recommended
! to be used, according to the ARPACK manual.
! Although the eigenvalues must be real in this case, there may be
! small imaginary parts due to round-off errors
!
! input ..
!
! ndim ... actual size of matrix
! eigenvectorL ... T calculate eigenvalues+eigenvectors, F former only
! which_eigvalC(2).. which eigenvalues are to be computed, can be
! 'LR','SR','LM','SM','LI','SI'
! 1.letter: large/small
! 2.letter: in magnitude/real/imaginary
! should be 'LM' in inverse shift mode
! max_eigval ... compute that many eigenvalues <= ndim, starting with 1
! must be <= ndim/3 
! tolerance ...convergence criterion, may be set to 0.d0(-> epsilon(0d0))
! max_iterations .. maximum number of iterations
! sigma ... in shift-invert mode,
! eigenvalues near a point sigma are sought
! resid_lin_eq ... in shift-invert mode
! tolerance for solving the linear equation
! should be slightly smaller than tolerance above
! iproblem ... =1 normal mode
! =3 inverse shift mode
!
! output ..
!
! eigenvalueV(1:max_eigval) .. eigenvalues of matrix (real)
! sorted in descending order
! eigenvectorM(1:ndim,1:max_eigval) .. eigenvectors, if eigenvectorL = T
!
!---------------------------------------------
!
! USER must provide following routines as input:
!
! 1. SUBROUTINE lin_equation_solver_arnoldi(ndim,yV,xV,resid_lin_eq,ierr,&
! sigma)
! calculates yV = inv[A-sigma*I]*xV
! resid_lin_eq ... tolerance
! ierr .. output, if ierr/=0 routine failed
! sigma .. complex number, see above
!
! 2. SUBROUTINE matvec_arnoldi_complex(ndim,xV,yV)
!
! calculates yV = Matrix*xV
!
!------------------------------------------------
!
! uses arpack routines (contained in arpack_kp.f)
! and lapack routines
! included with -xlic_lib=sunperf on sun
!--------------------------------------------------------------------------------------------------------------------------

 

Iterative Eigensolver for hermitian matrices (Conjugate Gradient)

!-------------------------------------------------------------------------------------------------------------------
subroutine eigensolver_hermitian(ndim,num_ev,eigenvaluesV,eigenfunctionsM, &
init,itere_max,itsub_max,eps_itere,eps_itsub,info_itere,info_itsub, &
iwrite,matrix_vector,precond,inner_product)
!--------------------------------------------------------------------------------------------------------------------
!
! eigensolver for complex,hermitian matrices (hermitian with respect to the
! inner product)
! calculates the num_ev LOWEST eigenvalues
! matrix is only accessed through the three user-defined subroutines
!
!------------------------------------------------------------------------------
!
! ndim (input) ... dimension of the matrix
! num_ev (input) ... number of eigenvalues to be calculated
!
! eigenvaluesV (input/output) ... real,dimension(num_ev)
! contains eigenvalues on return
! for init/=0 input values are taken as initial guess
! eigenfunctionsM (input/output) ... complex,dimension(ndim,num_ev)
! contains eigenfunctions on return
!
! for init/=0 input values are taken as initial guess
! init (input) ... /=0 --> the program takes input values of eigenvaluesV and
! eigenfunctionsM as initial guess
! in this case eigenfunctions must be normalized
! =0 --> initial guess is generated by random numbers
!
! itere_max (input/output) ... maximum number of outer iterations
! contains actual number of iterations on return
! eps_itere (input/output) ... precision for outer loop
! contains actual precision on return
! info_itere (output) ... =0 ,if precision is reached within itere_max
! =1 ,oterwise
!
! itsub_max (input/output) ... maximum number of inner iterations
! contains actual number of iterations on return
! eps_itsub (input/output) ... precision for inner loop
! contains actual precision on return
! info_itsub (output) ... =0 ,if precision is reached within itsub_max
! =1 ,otherwise
!
! iwrite (input) ... =0 --> no information printed
! /=0 --> information printed
!
!-----------------------------------------------------------------------------
!
! subroutine matrix_vector(ndim,x_inV,x_outV) 
! integer,intent(in) :: ndim
! complex(8),dimension(ndim),intent(in) :: x_inV
! complex(8),dimension(ndim),intent(out) :: x_outV
!
! calculates matrix-vector product : x_outV = Matrix * x_inV
!
!---------------------------------------------------------------
!
! subroutine precond(ndim,x_inV,x_outV)
! integer,intent(in) :: ndim
! complex(8),dimension(ndim),intent(in) :: x_inV
! complex(8),dimension(ndim),intent(out) :: x_outV
!
! preconditions the vector x_inV --> x_outV
!
!--------------------------------------------------------------
!
! subroutine inner_product(ndim,x_in1V,x_in2V,inn_prod)
! integer :: ndim
! complex(8),dimension(ndim),intent(in) :: x_in1V,x_in2V
! complex(8),intent(out) :: inn_prod
!
! calculates inner product: inn_prod = <x_in1V|x_in2V>
!
!------------------------------------------------------------------------------

   
Last modified: 09-Jun-2011