SUBROUTINE SLLDEF(ELAM,EPS,A,B,K,TOL,IFAIL) DOUBLE PRECISION ELAM,EPS,A,B,TOL INTEGER K,IFAIL C C This subroutine computes numerically the eigenvalues of a C left-definite right-indefinite regular Sturm-Liouville problem. C C It is written in FORTRAN 77 and requires that the user already C have installed LAPACK version 3. If you do not have LAPACK, go C to C www.netlib.org/lapack C C and follow the instructions for installing the software on your C system. SLLDEF must be linked with the LAPACK library at compile C time. C C C C The problems solved by SLLDEF consist of a differential equation C C -(p(x)y')' + q(x)y = lambda w(x) y, x in (a,b), C C to be satisfied together with coupled boundary conditions of C the form C C c11 y(b) + c12 y(a) = d11 py'(b) - d12 py'(a) C c21 y(b) + c22 y(a) = d21 py'(b) - d22 py'(a) C C Problems of this form have eigenvalues which are unbounded both C above and below and which can be indexed according to the scheme C C \lambda_{-k} \leq \lambda{-k+1} \leq ... \leq \lambda_{-1} C \leq \lambda_{-0} < 0 < \lambda_{+0} \leq \lambda_{1} \leq ... C \leq \lambda_{k} \leq ... C C C Parameters: C ----------- C C ELAM: (input/output, double precision real): On input with K C nonzero, ELAM can be assigned any value. On input with K=0, C ELAM should be assigned a negative or a positive value depending C on whether \lambda_{-0} or \lambda_{+0} is to be calculated. C C On exit with IFAIL=0: the computed eigenvalue approximation. C C EPS: (input/output, double precision real): On input, EPS should C be assigned a positive value. In general, the routine will work C faster when EPS is a good estimate of the distance between the C input value of EPS and the eigenvalue sought. On output, EPS is C overwritten. C C A,B: (input, double precision reals): On input, the endpoints of C the interval on which the problem is posed. The interval must be C finite with A < B. C C K: (input, integer): The index of the eigenvalue sought. This may C be any integer, but note that if K=0 then the input value of ELAM C must be nonzero. C C TOL: (input, double precision real): The tolerance for the numerical C integration. TOL must be strictly positive. In general, reducing C the value of TOL will improve the accuracy of the computed C eigenvalue. C C IFAIL: (input/output, integer): On entry, IFAIL must have one of the C values -1, 0 or 1. On exit, IFAIL will be 0 unless an error is C detected. If IFAIL was 0 or 1 on entry then an error message will C be printed in the event of an error. If IFAIL was 0 on entry then C the execution of the program will be terminated. C C User Supplied Routines C ---------------------- C C The user must supply the coefficients p(x), q(x) and w(x) appearing C in the differential equation by writing DOUBLE PRECISION FUNCTIONS C having the names P, Q and W as follows: C C DOUBLE PRECISION FUNCTION P(X) C DOUBLE PRECISION X C C P = (assign value as a function of X) C C RETURN C END C C DOUBLE PRECISION FUNCTION Q(X) C DOUBLE PRECISION X C C Q = (assign value as a function of X) C C RETURN C END C C DOUBLE PRECISION FUNCTION W(X) C DOUBLE PRECISION X C C W = (assign value as a function of X) C C RETURN C END C C The functions P, Q and W must be such as to make the problem left C definite and must be such that W is negative on a set of positive C measure and positive on a set of positive measure. In practice the C performance of the code will be much slower if the coefficients C P, Q and W are not smooth functions. C C The user must also write a subroutine called BCS to supply the C coefficients c11, c12, c21, c22, d11, d12, d21 and d22 appearing C in the boundary conditions. Its specification must be as follows. C C SUBROUTINE BCS(C,D,N) C INTEGER N C DOUBLE PRECISION C(N,N),D(N,N) C C C(1,1) = c11 C C(1,2) = c12 C C (etc). C C RETURN C END C C The integer N is an input parameter. Its value must not be changed C by BCS. C C C The matrices C and D returned by this routine must satisfy the C condition C C C(1,1)*D(2,1)+C(1,2)*D(2,2)-C(2,1)*D(1,1)-C(2,2)*D(1,2) = 0. C C This is necessary for self-adjointness. C C --------------------------------------------------------------------- C EXTERNAL USUB1,USUB2 INTEGER N PARAMETER (N=2) INTEGER KNOBS,IWORK,ILWK PARAMETER (IWORK=N*(16+73*N)+65,ILWK=N,KNOBS=60) INTEGER LWK(ILWK) DOUBLE PRECISION WORK(IWORK) COMPLEX*16 CWORK(N*(N+65)) CALL SL11F(ELAM,EPS,A,B,K,N,TOL,USUB1,USUB2,KNOBS,WORK, & IWORK,LWK,ILWK,CWORK,IFAIL) RETURN END SUBROUTINE USUB1(X,ELAM,S11,S12,S21,S22,N) DOUBLE PRECISION X,ELAM,S11(N,N),S12(N,N),S21(N,N),S22(N,N) DOUBLE PRECISION P,Q,W EXTERNAL P,Q,W C Remark: The differential equation is -(Py')'+Qy = ELAM.W.y. C The DOUBLE PRECISION functions providing the coefficient values C MUST be called P, Q and W. DO 10 I = 1,N DO 20 J = 1,N S11(J,I) = 0.D0 S12(J,I) = 0.D0 S21(J,I) = 0.D0 S22(J,I) = 0.D0 20 CONTINUE 10 CONTINUE S11(1,1) = ELAM*W(X)-Q(X) S22(1,1) = 1.D0/P(X) RETURN END SUBROUTINE USUB2(IEND,ISING,X,U,V,NDIM,N,ELAM) INTEGER IEND,NDIM,N LOGICAL ISING DOUBLE PRECISION U(NDIM,N),V(NDIM,N) DOUBLE PRECISION C(N,N),D(N,N) DOUBLE PRECISION TEST ISING = .FALSE. IF (IEND.EQ.0) THEN C Provide boundary condition at left hand end: U(1,1) = 1.D0 U(2,1) = 1.D0 U(1,2) = 0.D0 U(2,2) = 0.D0 V(1,1) = 0.D0 V(2,1) = 0.D0 V(1,2) = 1.D0 V(2,2) = -1.D0 ELSE CALL BCS(C,D,N) C Remark: the routine BCS returns the 2x2 matrices C and D which C specify the boundary conditions in the form C C c11 y(b) + c12 y(a) = d11 py'(b) - d12 py'(a) C c21 y(b) + c22 y(a) = d21 py'(b) - d22 py'(a) C C The routine MUST be called BCS and, for the time being, only real C boundary conditions are supported. C C TEST = C(1,1)*D(2,1)+C(1,2)*D(2,2) & -C(2,1)*D(1,1)-C(2,2)*D(1,2) IF (ABS(TEST).GT.1.0D-6) THEN WRITE (6,FMT=*) & 'Your boundary conditions are not selfadjoint' STOP END IF U(1,1) = D(1,1) U(2,1) = D(1,2) U(1,2) = D(2,1) U(2,2) = D(2,2) V(1,1) = C(1,1) V(2,1) = C(1,2) V(1,2) = C(2,1) V(2,2) = C(2,2) END IF RETURN END C --------------------------------------------------------------------- SUBROUTINE SL11F(ELAM,EPS,A,B,K,N,TOL,USUB1,USUB2,KNOBS,WORK, & IWORK,LWK,ILWK,CWORK,IFAIL) C C Bug fixed on 8th September 1997 C C Specification: SL11F solves Hamiltonian eigenvalue problems which are C reducible to the form of a first order matrix differential equation C Theta' = i Theta Omega(x,lambda,Theta), C where Theta is a unitary matrix prescribed by boundary conditions at C x=a and x=b. C C Variables: C elam: double precision. On entry elam should be set to an approximation C to the eigenvalue to be found. The value of elam is not important C in determining the accuracy of the final result but it may affect C run times. On exit, elam specifies the approximation to the C eigenvalue computed by SL11F. C eps: double precision. On entry eps should be set to a positive real C number of an order of magnitude such that the true eigenvalue C lies within [elam-C*eps,elam+C*eps] where by elam we mean the C initial approximation provided by the user, and C is a constant C of modest size. Again the value of eps is not critical. In cases C where absolutely no prior information is available it would be C acceptable in almost all cases to set elam = 0 and eps = 10 on C entry. C a,b: double precision. On entry a and b specify the finite regular endpoints C of the interval on which the problem is posed. Unchanged on exit. C k: integer. The index of the eigenvalue sought. For many problems k=0 C specifies the lowest eigenvalue (e.g. for problems derived from C formally self-adjoint even-order differential operators). However C for other problems there exist eigenvalues for any integer value C of the index k, positive or negative. Unchanged on exit. C n: integer. The dimension of the system, i.e. the size of the matrix C Theta. Unchanged on exit. C tol: double precision. On entry tol should have a positive value. It is C intended that the smaller tol is, the smaller will be the error in C the final approximation elam returned by the code. The value of C tol is unchanged on exit. C knobs: integer. Used to control the maximum number of miss-distance C evaluations carried out by the code. The number of miss-distance C evaluations will be max(60,knobs). knobs is unchanged on exit. C work: double precision array of dimension iwork. Used as workspace. C iwork: integer. On entry iwork must be at least n*(16+n*(33+2*nsampl))+25+ C 2*nsampl. Unchanged on exit. C lwk: integer array of dimension ilwk. Used as workspace. C ilwk: integer. On entry ilwk must be at least n. Unchanged on exit. C cwork: complex*16 array of dimension at least N*(N+65). Used as workspace. C ifail: integer. On entry, ifail must have one of the values -1,0,1. C On successful exit ifail will have the value 0. Any other value C indicates a failure. C C User Supplied Subroutines USUB1 and USUB2. C C USUB1: C C SUBROUTINE usub1(x,elam,s11,s12,s21,s22,n) C INTEGER n C DOUBLE PRECISION x,elam,s11(n,n),s12(n,n),s21(n,n),s22(n,n) C C This routine must specify in s11, s12, s21 and s22 the values of the C four coefficient matrix functions of x and lambda (elam) occurring C in the Hamiltonian system. It must not change the values of x, elam, C or n. C C USUB2: C C SUBROUTINE usub2(iend,ising,x,u,v,ndim,n,elam) C INTEGER iend,ndim,n C LOGICAL ising C DOUBLE PRECISION x,elam,u(ndim,n),v(ndim,n) C C If iend=0 on entry then USUB2 must specify the boundary condition at C x=a, while if iend=1 then USUB2 must specify the boundary condition C at x=b. The parameter ising must be assigned the value .false. before C returning. The parameters x, elam, ndim and n must not be changed by C USUB2. The specification of boundary conditions is achieved as follows: C a boundary condition C transpose(A1).U + transpose(A2).V = 0 C is specified by setting C U = A2, V = -A1 C and returning. C C END of brief documentation. C C .. Parameters .. INTEGER NSAMPL PARAMETER (NSAMPL=20) C .. C .. Local Scalars .. DOUBLE PRECISION C,EL,EU,TOLC05 INTEGER IFLAG,IFO,IREST,ISAMPL,ISIGIL,ISIGIR,ISIGRL,ISIGRR,KNTMAX, & NREC CHARACTER*6 SRNAME C .. C .. Scalar Arguments .. DOUBLE PRECISION A,B,ELAM,EPS,TOL INTEGER IFAIL,ILWK,IWORK,K,KNOBS,N C .. C .. Array Arguments .. C IWORK must be at least n*(16+(33+2*nsampl)*n)+25+2*nsampl. With nsampl=10 C this gives n*(16+53*n)+45, with nsampl=20 we get n*(16+73*n)+65 DOUBLE PRECISION WORK(IWORK) INTEGER LWK(ILWK) COMPLEX*16 CWORK(N*(N+65)) C .. C .. Subroutine Arguments .. EXTERNAL USUB1,USUB2 C .. C .. External Subroutines .. EXTERNAL CHOOSC,SOLVSY C .. C .. Intrinsic Functions .. INTRINSIC MAX,SQRT C .. C .. External Functions .. DOUBLE PRECISION XM2AJF INTEGER PM1ABF EXTERNAL XM2AJF,PM1ABF C .. C .. Local Arrays .. CHARACTER*80 REC(2) C .. SRNAME = 'SL11F' IFO = IFAIL C First do the input checks. IF (A.GE.B .OR. N.LT.2 .OR. TOL.LE.0.0D0 .OR. & IWORK.LT.N* (16+ (33+2*NSAMPL)*N)+25+2*NSAMPL .OR. & ILWK.LT.N .OR. EPS.LE.0.0D0) THEN C We have an input error IFLAG = 1 IF (A.GE.B) THEN WRITE (REC,FMT=9000) A,B NREC = 2 GO TO 10 ELSE IF (N.LT.2) THEN WRITE (REC,FMT=9010) N NREC = 2 GO TO 10 ELSE IF (TOL.LE.0.0D0) THEN WRITE (REC,FMT=9020) TOL NREC = 2 GO TO 10 ELSE IF (IWORK.LT.N* (16+ (33+2*NSAMPL)*N)+25+2*NSAMPL) THEN WRITE (REC,FMT=9030) N* (16+ (33+2*NSAMPL)*N) + 25 + & 2*NSAMPL,IWORK NREC = 2 GO TO 10 ELSE IF (ILWK.LT.N) THEN WRITE (REC,FMT=9040) N,ILWK NREC = 2 GO TO 10 ELSE IF (EPS.LE.0.0D0) THEN WRITE (REC,FMT=9050) EPS NREC = 2 GO TO 10 ELSE END IF END IF ISIGRL = 1 ISIGIL = N*N + 1 ISIGRR = 2*N*N + 1 ISIGIR = 3*N*N + 1 IREST = 4*N*N + 1 ISAMPL = 40*N*N + 4*N + 1 KNTMAX = MAX(60,KNOBS) TOLC05 = 1.0D-2 IFAIL = 0 C = 0.50D0* (A+B) CALL SOLVSY(A,B,C,K,ELAM,EPS,EL,EU,USUB1,USUB2,TOL,TOLC05, & WORK(IREST),WORK(ISIGRL),WORK(ISIGIL),N,WORK(ISIGRR), & WORK(ISIGIR),N,LWK,N,KNTMAX,CWORK,IFAIL) IF (IFAIL.EQ.0) THEN C Choose a better matching point and repeat CALL CHOOSC(A,B,C,EL,EU,TOL,USUB1,USUB2,WORK,LWK,N,K,NSAMPL, & WORK(N* (16+33*N)+25+2*NSAMPL+1),CWORK, & IFAIL) IF (IFAIL.EQ.0) THEN TOLC05 = MAX(1.0D-1*TOL,SQRT(XM2AJF(0.0D0))) ELAM = 0.50D0* (EU+EL) EPS = 0.50D0* (EU-EL) CALL SOLVSY(A,B,C,K,ELAM,EPS,EL,EU,USUB1,USUB2,TOL,TOLC05, & WORK(IREST),WORK(ISIGRL),WORK(ISIGIL),N, & WORK(ISIGRR),WORK(ISIGIR),N,LWK,N,KNTMAX, & CWORK,IFAIL) IF (IFAIL.EQ.0) THEN RETURN END IF END IF END IF IFLAG = IFAIL IF (IFAIL.EQ.7) THEN WRITE (REC,FMT=9060) NREC = 2 IFLAG = 2 ELSE IF (IFAIL.EQ.12 .OR. IFAIL.EQ.14) THEN WRITE (REC,FMT=9070) NREC = 2 IFLAG = 3 ELSE IF (IFAIL.EQ.13 .OR. IFAIL.EQ.15) THEN WRITE (REC,FMT=9080) NREC = 2 IFLAG = 4 ELSE IF (IFAIL.EQ.10 .OR. IFAIL.EQ.11 .OR. IFAIL.EQ.16 .OR. & IFAIL.EQ.17) THEN WRITE (REC,FMT=9090) NREC = 2 IFLAG = 5 ELSE IF (IFAIL.EQ.9 .OR. IFAIL.EQ.18) THEN WRITE (REC,FMT=9100) NREC = 2 IFLAG = 6 ELSE IF (IFAIL.EQ.20) THEN WRITE (REC,FMT=9110) NREC = 2 IFLAG = 7 ELSE IF (IFAIL.EQ.21) THEN WRITE (REC,FMT=9120) NREC = 2 IFLAG = 8 ELSE IF (IFAIL.EQ.19) THEN WRITE (REC,FMT=9130) NREC = 2 IFLAG = 9 END IF 10 IFAIL = PM1ABF(IFO,IFLAG,SRNAME,NREC,REC) 9000 FORMAT (' ** A must be less than B, you have',/,' ** A = ',g18.8, & ' B = ',g18.8) 9010 FORMAT (' ** N must be at least 2, you have',/,' ** N = ',i8) 9020 FORMAT (' ** TOL must be strictly positive, you have',/, & ' ** TOL = ',g18.8) 9030 FORMAT (' ** IWORK must be at least ',i8,' you have',/, & ' ** IWORK = ',i8) 9040 FORMAT (' ** ILWK must be at least',i8,' you have',/, & ' ** ILWK = ',i8) 9050 FORMAT (' ** EPS must be strictly positive, you have',/, & ' ** EPS = ',g18.8) 9060 FORMAT (' ** Too many attempts have been made to find',/, & ' ** required eigenvalue; try increasing EPS') 9070 FORMAT (' ** Failure in FM2BJF when trying to convert boundary',/, & ' ** conditions from user variables to H-matrix variables') 9080 FORMAT (' ** The boundary conditions supplied do not',/, & ' ** satisfy the rank condition') 9090 FORMAT (' ** An H-matrix has occurred whose exponential',/, & ' ** cannot be accurately computed') 9100 FORMAT (' ** A failure has occurred on a call to FM2AJF;',/, & ' ** cannot find eigenvalues of central miss-matrix') 9110 FORMAT (' ** An H-matrix has arisen which cannot be',/, & ' ** diagonalised; try reducing TOL') 9120 FORMAT (' ** Too many unsuccessful attempts have been made',/, & ' ** to find an initial stepsize') 9130 FORMAT (' ** Too many unsuccessful attempts have been made',/, & ' ** to find a suitable next stepsize') END C ---------------------------------------------------------------------- SUBROUTINE SOLVSY(A,B,C,K,ELAM,EPS,EL,EU,COFMAT,SYSBC,TOL,TOLC05, & WORK,SIGRL,SIGIL,ISIGL,SIGRR,SIGIR,ISIGR,LWK,N, & KNTMAX,CWORK,IFAIL) C This subroutine is a modified version of the usual subroutine by the same C name provided with the package SL11F. It has been modified to cope with C left-definite 2nd order Sturm-Liouville problems with possibly-coupled C boundary conditions and assumes that the miss distance function C D(lambda) is monotone decreasing when lambda < 0, monotone increasing C when lambda > 0, and zero when lambda lies in the range (lambda_{-0}, C lambda_{+0}), where lambda_{-0}<0