      subroutine eigen_sym_up(N,A,W)
      implicit none
!
!compute the eigenvalues and eigenvectors of a symmetrical matrix.
!A: On entry, A is a symmetrical matrix with its upper triangle filled.
!   on exit, A contains the normalized eigenvectors in its columns.
!W: contains the eigenvalues in descending order. 
      
      CHARACTER          JOBZ, UPLO
      INTEGER            INFO, LDA, LWORK, N
      DOUBLE PRECISION   A(N, N), W( N ), WORK(3*N-1)
      double precision p
      integer i,j
      
      JOBZ='V'
      UPLO='U'
      LWORK=3*N-1
      LDA=N
      call DSYEV(JOBZ,UPLO,N,A(1:N,1:N),LDA,W,WORK,LWORK,INFO)
*  INFO    (output) INTEGER
*          = 0:  successful exit
*          < 0:  if INFO = -i, the i-th argument had an illegal value
*          > 0:  if INFO = i, the algorithm failed to converge; i
*                off-diagonal elements of an intermediate tridiagonal
*                form did not converge to zero.
      if(INFO.lt.0)then
        write(*,*)'The ',-INFO,
     &            'th argument in DSYEV has an illegal value'
        stop
      endif
      if(INFO.gt.0)then
        write(*,*)'The algorithm failed to converge'
        stop
      endif
        
! Change the eigenvalue array from ascending to descending order and rearrange
! the eigen vectors accordingly.
!---------------------------------------------
      do i=1,N/2
        p=W(i)
        W(i)=W(N-i+1)
        W(N-i+1)=p
        do j=1,N
          p=A(j,i)
          A(j,i)=A(j,N-i+1)
          A(j,N-i+1)=p
        enddo
      enddo
!---------------------------------------------
      return
      end
