subroutine inv_det_matix(a,n,np,a_inv, & lnabsdet,signunit,ierr) implicit none ! ! Invert a matrix and calculate ln(dabs(determinant)) and the assoaciated ! sign ! !-------------Inputs------------------------------- !a: matrix to be inverted !n: the actual dimension of a !np: the declared dimension of a ! !-------------Outputs------------------------------ !a_inv: inverse matrix of a !lnabsdet: the ln(|det|a||) !signunit: det|a| = signunit*exp(lnabsdet) !ierr: =0, ok; =1, matrix a is singular integer n,np,indx(np),i,j,ierr,numneg double precision a(np,np),a_inv(np,np), & copya(np,np),d,signunit,lnabsdet ierr=0 do i=1,n do j=1,n copya(i,j)=a(i,j) a_inv(i,j)=0.0d0 enddo a_inv(i,i)=1.0d0 enddo call ludcmp(copya,n,np,indx,d,ierr) numneg=0 lnabsdet=0.0d0 do j=1,n if(copya(j,j).eq.0.0d0)then ! singular matrix and the determinant is zero ierr=1 signunit=-1.0d+100 lnabsdet=-1.0d+100 return endif if(copya(j,j).lt.0.0d0)then numneg=numneg+1 endif lnabsdet=lnabsdet+dlog(dabs(copya(j,j))) enddo if(d.lt.0.0d0)then numneg=numneg+1 endif if(mod(numneg,2).eq.0)then signunit=1.0d0 else signunit=-1.0d0 endif do j=1,n call lubksb(copya,n,np,indx,a_inv(1,j)) enddo return end subroutine svd_inv_det_matix(a,n,np,a_inv, & lnabsdet,signunit,ierr) implicit none ! ! Invert a matrix and calculate ln(dabs(determinant)) and the assoaciated ! sign ! !-------------Inputs------------------------------- !a: matrix to be inverted !n: the actual dimension of a !np: the declared dimension of a ! !-------------Outputs------------------------------ !a_inv: inverse matrix of a !lnabsdet: the ln(|det|a||) !signunit: det|a| = signunit*exp(lnabsdet) !ierr: =0, ok; =1, matrix a is singular integer n,np,indx(np),i,j,ierr double precision a(np,np),a_inv(np,np), & copya(np,np),w(np),v(np,np), & d,signunit,signunitu,signunitv, & lnabsdet,lnabsdetu,lnabsdetv,copyatrans(np,np), & vinw(np,np) ierr=0 do i=1,n do j=1,n copya(i,j)=a(i,j) enddo enddo call svdcmp(copya(1:n,1:n),n,n,np,np,w,v(1:n,1:n),ierr) do i=1,n do j=1,n vinw(i,j)=v(i,j)/w(j) enddo enddo call matrixtranspose(n,n,copya(1:n,1:n), & copyatrans(1:n,1:n)) call matrixproduct(n,n,vinw(1:n,1:n),n, & copyatrans(1:n,1:n),a_inv(1:n,1:n)) call det_matix(copya(1:n,1:n),n,n,lnabsdetu,signunitu,ierr) call det_matix(v(1:n,1:n),n,n,lnabsdetv,signunitv,ierr) lnabsdet=0.0d0 do j=1,n lnabsdet=lnabsdet+dlog(w(j)) enddo signunit=signunitu*signunitv return end subroutine det_matix(a,n,np,lnabsdet,signunit,ierr) implicit none ! ! calculate ln(dabs(determinant)) and the assoaciated sign ! !-------------Inputs------------------------------- !a: matrix to be inverted !n: the actual dimension of a !np: the declared dimension of a ! !-------------Outputs------------------------------ !lnabsdet: the ln(|det|a||) !signunit: det|a| = signunit*exp(lnabsdet) !ierr: =1, ok; =0, matrix a is singular integer n,np,indx(np),i,j,ierr,numneg double precision a(np,np),a_inv(np,np), & copya(np,np),d,signunit,lnabsdet ierr=1 do i=1,n do j=1,n copya(i,j)=a(i,j) enddo enddo call ludcmp(copya(1:n,1:n),n,np,indx,d,ierr) numneg=0 lnabsdet=0.0d0 do j=1,n if(copya(j,j).eq.0.0d0)then ! singular matrix and the determinant is zero ierr=1 signunit=-1.0d+100 lnabsdet=-1.0d+100 return endif if(copya(j,j).lt.0.0d0)then numneg=numneg+1 endif lnabsdet=lnabsdet+dlog(dabs(copya(j,j))) enddo if(d.lt.0.0d0)then numneg=numneg+1 endif if(mod(numneg,2).eq.0)then signunit=1.0d0 else signunit=-1.0d0 endif return end !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% double precision function tracematrix(m,a) implicit none integer m,i double precision a(m,m) tracematrix=0.0d0 do i=1,m tracematrix=tracematrix+a(i,i) enddo return end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine matrixproduct(ma,n,a,nb,b,c) implicit none ! ! matrix product c=ab ! integer ma,n,nb double precision a(ma,n),b(n,nb),c(ma,nb) integer i,j,k do i=1,ma do j=1,nb c(i,j)=0.0d0 do k=1,n c(i,j)=c(i,j)+a(i,k)*b(k,j) enddo enddo enddo return end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine matrixsum(m,n,a,b,c) implicit none ! ! matrix sum c=a+b ! integer m,n double precision a(m,n),b(m,n),c(m,n) integer i,j do i=1,m do j=1,n c(i,j)=a(i,j)+b(i,j) enddo enddo return end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine matrixdif(m,n,a,b,c) implicit none ! ! matrix difference c=a-b ! integer m,n double precision a(m,n),b(m,n),c(m,n) integer i,j do i=1,m do j=1,n c(i,j)=a(i,j)-b(i,j) enddo enddo return end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine matrixtranspose(m,n,a,b) implicit none ! ! matrix transpose b=a^T ! integer m,n double precision a(m,n),b(n,m) integer i,j do i=1,m do j=1,n b(j,i)=a(i,j) enddo enddo return end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& SUBROUTINE svbksb(u,w,v,m,n,mp,np,b,x) implicit none INTEGER m,mp,n,np,NMAX double precision b(mp),u(mp,np),v(np,np),w(np),x(np) PARAMETER (NMAX=1500) INTEGER i,j,jj double precision s,tmp(NMAX) do 12 j=1,n s=0.0d0 if(w(j).ne.0.0d0)then do 11 i=1,m s=s+u(i,j)*b(i) 11 continue s=s/w(j) endif tmp(j)=s 12 continue do 14 j=1,n s=0.0d0 do 13 jj=1,n s=s+v(j,jj)*tmp(jj) 13 continue x(j)=s 14 continue return END C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3. SUBROUTINE svdcmp(a,m,n,mp,np,w,v,ierr) implicit none INTEGER m,mp,n,np,NMAX,ierr double precision a(mp,np),v(np,np),w(np) PARAMETER (NMAX=1500) CU USES pythag INTEGER i,its,j,jj,k,l,nm double precision anorm,c,f,g,h,s,scaling,x,y,z, & rv1(NMAX),pythag g=0.0d0 scaling=0.0d0 anorm=0.0d0 do 25 i=1,n l=i+1 rv1(i)=scaling*g g=0.0d0 s=0.0d0 scaling=0.0d0 if(i.le.m)then do 11 k=i,m scaling=scaling+dabs(a(k,i)) 11 continue if(scaling.ne.0.0d0)then do 12 k=i,m a(k,i)=a(k,i)/scaling s=s+a(k,i)*a(k,i) 12 continue f=a(i,i) g=-dsign(dsqrt(s),f) h=f*g-s a(i,i)=f-g do 15 j=l,n s=0.0d0 do 13 k=i,m s=s+a(k,i)*a(k,j) 13 continue f=s/h do 14 k=i,m a(k,j)=a(k,j)+f*a(k,i) 14 continue 15 continue do 16 k=i,m a(k,i)=scaling*a(k,i) 16 continue endif endif w(i)=scaling*g g=0.0d0 s=0.0d0 scaling=0.0d0 if((i.le.m).and.(i.ne.n))then do 17 k=l,n scaling=scaling+dabs(a(i,k)) 17 continue if(scaling.ne.0.0d0)then do 18 k=l,n a(i,k)=a(i,k)/scaling s=s+a(i,k)*a(i,k) 18 continue f=a(i,l) g=-dsign(dsqrt(s),f) h=f*g-s a(i,l)=f-g do 19 k=l,n rv1(k)=a(i,k)/h 19 continue do 23 j=l,m s=0.0d0 do 21 k=l,n s=s+a(j,k)*a(i,k) 21 continue do 22 k=l,n a(j,k)=a(j,k)+s*rv1(k) 22 continue 23 continue do 24 k=l,n a(i,k)=scaling*a(i,k) 24 continue endif endif anorm=dmax1(anorm,(dabs(w(i))+dabs(rv1(i)))) 25 continue do 32 i=n,1,-1 if(i.lt.n)then if(g.ne.0.0d0)then do 26 j=l,n v(j,i)=(a(i,j)/a(i,l))/g 26 continue do 29 j=l,n s=0.0d0 do 27 k=l,n s=s+a(i,k)*v(k,j) 27 continue do 28 k=l,n v(k,j)=v(k,j)+s*v(k,i) 28 continue 29 continue endif do 31 j=l,n v(i,j)=0.0d0 v(j,i)=0.0d0 31 continue endif v(i,i)=1.0d0 g=rv1(i) l=i 32 continue do 39 i=min(m,n),1,-1 l=i+1 g=w(i) do 33 j=l,n a(i,j)=0.0d0 33 continue if(g.ne.0.0d0)then g=1.0d0/g do 36 j=l,n s=0.0d0 do 34 k=l,m s=s+a(k,i)*a(k,j) 34 continue f=(s/a(i,i))*g do 35 k=i,m a(k,j)=a(k,j)+f*a(k,i) 35 continue 36 continue do 37 j=i,m a(j,i)=a(j,i)*g 37 continue else do 38 j= i,m a(j,i)=0.0d0 38 continue endif a(i,i)=a(i,i)+1.0d0 39 continue do 49 k=n,1,-1 do 48 its=1,30 do 41 l=k,1,-1 nm=l-1 if((dabs(rv1(l))+anorm).eq.anorm) goto 2 if((dabs(w(nm))+anorm).eq.anorm) goto 1 41 continue 1 c=0.0d0 s=1.0d0 do 43 i=l,k f=s*rv1(i) rv1(i)=c*rv1(i) if((dabs(f)+anorm).eq.anorm) goto 2 g=w(i) h=pythag(f,g) w(i)=h h=1.0d0/h c= (g*h) s=-(f*h) do 42 j=1,m y=a(j,nm) z=a(j,i) a(j,nm)=(y*c)+(z*s) a(j,i)=-(y*s)+(z*c) 42 continue 43 continue 2 z=w(k) if(l.eq.k)then if(z.lt.0.0d0)then w(k)=-z do 44 j=1,n v(j,k)=-v(j,k) 44 continue endif goto 3 endif if(its.eq.30)then ierr=0 return endif x=w(l) nm=k-1 y=w(nm) g=rv1(nm) h=rv1(k) f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0d0*h*y) g=pythag(f,1.0d0) f=((x-z)*(x+z)+h*((y/(f+dsign(g,f)))-h))/x c=1.0d0 s=1.0d0 do 47 j=l,nm i=j+1 g=rv1(i) y=w(i) h=s*g g=c*g z=pythag(f,h) rv1(j)=z c=f/z s=h/z f= (x*c)+(g*s) g=-(x*s)+(g*c) h=y*s y=y*c do 45 jj=1,n x=v(jj,j) z=v(jj,i) v(jj,j)= (x*c)+(z*s) v(jj,i)=-(x*s)+(z*c) 45 continue z=pythag(f,h) w(j)=z if(z.ne.0.0d0)then z=1.0d0/z c=f*z s=h*z endif f= (c*g)+(s*y) x=-(s*g)+(c*y) do 46 jj=1,m y=a(jj,j) z=a(jj,i) a(jj,j)= (y*c)+(z*s) a(jj,i)=-(y*s)+(z*c) 46 continue 47 continue rv1(l)=0.0d0 rv1(k)=f w(k)=x 48 continue 3 continue 49 continue return END C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3. double precision FUNCTION pythag(a,b) double precision a,b double precision absa,absb absa=dabs(a) absb=dabs(b) if(absa.gt.absb)then pythag=absa*dsqrt(1.0d0+(absb/absa)**2) else if(absb.eq.0.0d0)then pythag=0.0d0 else pythag=absb*dsqrt(1.0d0+(absa/absb)**2) endif endif return END C (C) Copr. 1986-92 Numerical Recipes Software v%1jw#<0(9p#3. subroutine xmprove(N,NP,a,b,x,mark) implicit none INTEGER i,j,idum,N,NP,indx(N),mark double precision d,a(NP,NP),b(N),x(N),aa(NP,NP) do 12 i=1,N x(i)=b(i) do 11 j=1,N aa(i,j)=a(i,j) 11 continue 12 continue call ludcmp(aa,N,NP,indx,d,mark) if (mark .eq. 0) goto 20 call lubksb(aa,N,NP,indx,x) call mprove(a,aa,N,NP,indx,b,x) 20 continue return END SUBROUTINE mprove(a,alud,n,np,indx,b,x) implicit none INTEGER n,np,indx(n),NMAX double precision a(np,np),alud(np,np),b(n),x(n) PARAMETER (NMAX=500) CU USES lubksb INTEGER i,j double precision r(NMAX) DOUBLE PRECISION sdp do 12 i=1,n sdp=-b(i) do 11 j=1,n sdp=sdp+(a(i,j))*(x(j)) 11 continue r(i)=sdp 12 continue call lubksb(alud,n,np,indx,r) do 13 i=1,n x(i)=x(i)-r(i) 13 continue return END SUBROUTINE ludcmp(a,n,np,indx,d,mark) implicit none INTEGER n,np,indx(n),NMAX double precision d,a(np,np),TINY PARAMETER (NMAX=500,TINY=1.0d-20) INTEGER i,imax,j,k,mark double precision aamax,dum,sum,vv(NMAX) mark=1 d=1.0d0 do 12 i=1,n aamax=0.0d0 do 11 j=1,n if (dabs(a(i,j)).gt.aamax) aamax=dabs(a(i,j)) 11 continue if (aamax.eq.0.0d0) then ! singular matrix mark=0 return end if vv(i)=1.0d0/aamax 12 continue do 19 j=1,n do 14 i=1,j-1 sum=a(i,j) do 13 k=1,i-1 sum=sum-a(i,k)*a(k,j) 13 continue a(i,j)=sum 14 continue aamax=0.0d0 do 16 i=j,n sum=a(i,j) do 15 k=1,j-1 sum=sum-a(i,k)*a(k,j) 15 continue a(i,j)=sum dum=vv(i)*dabs(sum) if (dum.ge.aamax) then imax=i aamax=dum endif 16 continue if (j.ne.imax)then do 17 k=1,n dum=a(imax,k) a(imax,k)=a(j,k) a(j,k)=dum 17 continue d=-d vv(imax)=vv(j) endif indx(j)=imax if(a(j,j).eq.0.0d0)a(j,j)=TINY if(j.ne.n)then dum=1.0d0/a(j,j) do 18 i=j+1,n a(i,j)=a(i,j)*dum 18 continue endif 19 continue return END SUBROUTINE lubksb(a,n,np,indx,b) implicit none INTEGER n,np,indx(n) double precision a(np,np),b(n) INTEGER i,ii,j,ll double precision sum ii=0 do 12 i=1,n ll=indx(i) sum=b(ll) b(ll)=b(i) if (ii.ne.0)then do 11 j=ii,i-1 sum=sum-a(i,j)*b(j) 11 continue else if (sum.ne.0.0d0) then ii=i endif b(i)=sum 12 continue do 14 i=n,1,-1 sum=b(i) do 13 j=i+1,n sum=sum-a(i,j)*b(j) 13 continue b(i)=sum/a(i,i) 14 continue return END !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine svdlinsys(n,np,a,b,x) implicit none ! ! Solving a linear system ax=b through singular value decomposition integer n,np double precision a(np,np),b(np),x(np) integer i,j,ierr double precision u(np,np),w(np),v(np,np), & wmax,ftol,wmin parameter(ftol=1.0d-7) do i=1,n do j=1,n u(i,j)=a(i,j) enddo enddo call svdcmp(u(1:n,1:n),n,n,np,np,w,v(1:n,1:n),ierr) wmax=0.0d0 do j=1,n if(w(j).gt.wmax)wmax=w(j) enddo wmin=wmax*ftol do j=1,n if(w(j).lt.wmin)w(j)=0.0d0 enddo call svbksb(u(1:n,1:n),w,v(1:n,1:n),n,n,np,np,b,x) return end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& SUBROUTINE qrdcmp(a,n,np,c,d,sing) implicit none INTEGER n,np DOUBLE PRECISION a(np,np),c(n),d(n) LOGICAL sing INTEGER i,j,k DOUBLE PRECISION scaling,sigma,sum,tau sing=.false. do 17 k=1,n-1 scaling=0.0d0 do 11 i=k,n scaling=dmax1(scaling,dabs(a(i,k))) 11 continue if(scaling.eq.0.0d0)then sing=.true. c(k)=0.0d0 d(k)=0.0d0 else do 12 i=k,n a(i,k)=a(i,k)/scaling 12 continue sum=0.0d0 do 13 i=k,n sum=sum+a(i,k)**2 13 continue sigma=dsign(dsqrt(sum),a(k,k)) a(k,k)=a(k,k)+sigma c(k)=sigma*a(k,k) d(k)=-scaling*sigma do 16 j=k+1,n sum=0.0d0 do 14 i=k,n sum=sum+a(i,k)*a(i,j) 14 continue tau=sum/c(k) do 15 i=k,n a(i,j)=a(i,j)-tau*a(i,k) 15 continue 16 continue endif 17 continue d(n)=a(n,n) if(d(n).eq.0.0d0)sing=.true. return END c SUBROUTINE qrupdt(r,qt,n,np,u,v) implicit none INTEGER n,np DOUBLE PRECISION r(np,np),qt(np,np),u(np),v(np) CU USES rotate INTEGER i,j,k do 11 k=n,1,-1 if(u(k).ne.0.0d0)goto 1 11 continue k=1 1 do 12 i=k-1,1,-1 call rotate(r,qt,n,np,i,u(i),-u(i+1)) if(u(i).eq.0.0d0)then u(i)=dabs(u(i+1)) else if(dabs(u(i)).gt.dabs(u(i+1)))then u(i)=dabs(u(i))*dsqrt(1.0d0+(u(i+1)/u(i))**2) else u(i)=dabs(u(i+1))*dsqrt(1.0d0+(u(i)/u(i+1))**2) endif 12 continue do 13 j=1,n r(1,j)=r(1,j)+u(1)*v(j) 13 continue do 14 i=1,k-1 call rotate(r,qt,n,np,i,r(i,i),-r(i+1,i)) 14 continue return END c SUBROUTINE rsolv(a,n,np,d,b) implicit none INTEGER n,np DOUBLE PRECISION a(np,np),b(n),d(n) INTEGER i,j DOUBLE PRECISION sum b(n)=b(n)/d(n) do 12 i=n-1,1,-1 sum=0.0d0 do 11 j=i+1,n sum=sum+a(i,j)*b(j) 11 continue b(i)=(b(i)-sum)/d(i) 12 continue return END c SUBROUTINE rotate(r,qt,n,np,i,a,b) implicit none INTEGER n,np,i DOUBLE PRECISION a,b,r(np,np),qt(np,np) INTEGER j DOUBLE PRECISION c,fact,s,w,y if(a.eq.0.0d0)then c=0.0d0 s=dsign(1.0d0,b) else if(dabs(a).gt.dabs(b))then fact=b/a c=dsign(1.0d0/dsqrt(1.0d0+fact**2),a) s=fact*c else fact=a/b s=dsign(1.0d0/dsqrt(1.0d0+fact**2),b) c=fact*s endif do 11 j=i,n y=r(i,j) w=r(i+1,j) r(i,j)=c*y-s*w r(i+1,j)=s*y+c*w 11 continue do 12 j=1,n y=qt(i,j) w=qt(i+1,j) qt(i,j)=c*y-s*w qt(i+1,j)=s*y+c*w 12 continue return END !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine symmatindex(ndim,icolrow,indexi) implicit none integer ndim,icolrow,indexi(ndim) ! this subroutine determines the sequence number of the elements of the row i ! or column i of a symmetric matrix that is stored in compact form (diagonal included) ! The compact form stores the upper triangle of the matrix sequentially ! column by column ! 1, 2, 4, 7, 11, ! 3, 5, 8, 12, ! 6, 9, 13, ! 10 14, ! 15, ! Note that it does not matter whether it is row or column because the matrix is ! symmetric integer j,icompactpostri indexi(1)=icompactpostri(1,icolrow) do j=2,icolrow indexi(j)=indexi(j-1)+1 enddo do j=icolrow+1,ndim indexi(j)=icompactpostri(icolrow,j) enddo return end ! !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine ivarjvartri(invars,nvars,indexvars, & ivar,jvar,istart,jstart) implicit none ! !This subroutine has two functions: !1.Given the position number in the vector that stores the upper triangle ! (including the diagonal elements) of a symmetric matrix, determine the cell position ! (ivar,jvar) indices in the actual matrix. !2. Determine the starting cell position in the symmetric matrix formed by all ! elements of the nvars variables. The number of elements ! indexed by ivar or jvar is specified in indexvars. integer invars,nvars,indexvars(nvars),ivar,jvar, & istart,jstart integer n0 jvar=int((1.0d0+dsqrt(dble(8*invars-7)))/2.0d0) ivar=invars-(jvar*(jvar-1))/2 if(ivar.gt.jvar)then ! rounding error jvar=jvar+1 ivar=invars-(jvar*(jvar-1))/2 endif 20 istart=0 do n0=1,ivar-1 istart=istart+indexvars(n0) enddo istart=istart+1 jstart=0 do n0=1,jvar-1 jstart=jstart+indexvars(n0) enddo jstart=jstart+1 return end subroutine ivarjvartri !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine ivarjvaroff(invars,nvars,indexvars, & ivar,jvar,istart,jstart) implicit none ! !This subroutine has two functions: !1.Given the position number in the vector that stores the upper triangle ! (not including the diagonal elements) of a symmetric matrix, determine the cell position ! (ivar,jvar) indices in the actual matrix. !2. Determine the starting cell position in the expanded matrix. The number of elements ! indexed by ivar or jvar is specified in indexvars. integer invars,nvars,indexvars(nvars),ivar,jvar, & istart,jstart integer n0 jvar=int((3.0d0+dsqrt(dble(8*invars-7)))/2.0d0) ivar=invars-((jvar-2)*(jvar-1))/2 if(ivar.ge.jvar)then ! rounding error jvar=jvar+1 ivar=invars-((jvar-2)*(jvar-1))/2 endif istart=0 do n0=1,ivar-1 istart=istart+indexvars(n0) enddo istart=istart+1 jstart=0 do n0=1,jvar-1 jstart=jstart+indexvars(n0) enddo jstart=jstart+1 return end subroutine ivarjvaroff !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& integer function icompactpostri(irow0,jcol0) implicit none ! ! determine the position of the cell (irow,jcol) in the vector ! that stores the upper triangle of a symmetric matrix, including ! the diagonal elements. ! irow <=jcol integer irow0,jcol0 icompactpostri=irow0+(jcol0*(jcol0-1))/2 return end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& integer function icompactposoff(irow0,jcol0) implicit none ! ! determine the position of the cell (irow,jcol) in the vector ! that stores the upper triangle of a symmetric matrix, not including ! the diagonal elements. ! irow < jcol-1 integer irow0,jcol0 icompactposoff=irow0+((jcol0-1)*(jcol0-2))/2 return end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& subroutine istartjstart(ivar,jvar,nvars, & indexvars,istart,jstart) implicit none integer nvars,indexvars(nvars),ivar,jvar,istart, & jstart,n0 ! istart=0 do n0=1,ivar-1 istart=istart+indexvars(n0) enddo istart=istart+1 jstart=0 do n0=1,jvar-1 jstart=jstart+indexvars(n0) enddo jstart=jstart+1 return end subroutine istartjstart !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& integer function getwhichvar(ipos,nvars,indexvars) implicit none ! ! determine to which variable ipos belongs integer ipos,nvars,indexvars(nvars),n0,i ! n0=0 i=0 10 i=i+1 n0=n0+indexvars(i) if(ipos.le.n0)then getwhichvar=i return endif goto 10 end !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&