public static void tql2 ( int n , double d [ ] , double e [ ] , double v [ ] [ ] ) { // This is derived from the Algol procedures tql2, by // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding // Fortran subroutine in EISPACK. System . arraycopy ( e , 1 , e , 0 , n - 1 ) ; e [ n - 1 ] = 0.0 ; double f = 0.0 ; double tst1 = 0.0 ; double eps = Math . pow ( 2.0 , - 52.0 ) ; for ( int l = 0 ; l < n ; l ++ ) { // Find small subdiagonal element tst1 = Math . max ( tst1 , Math . abs ( d [ l ] ) + Math . abs ( e [ l ] ) ) ; int m = l ; while ( m < n ) { if ( Math . abs ( e [ m ] ) <= eps * tst1 ) { break ; } m ++ ; } // If m == l, d[l] is an eigenvalue, // otherwise, iterate. if ( m > l ) { int iter = 0 ; do { iter = iter + 1 ; // (Could check iteration count here.) // Compute implicit shift f += specificShift ( l , n , d , e ) ; // Implicit QL transformation. implicitQLTransformation ( l , m , n , v , d , e ) ; // Check for convergence. } while ( Math . abs ( e [ l ] ) > eps * tst1 ) ; } d [ l ] = d [ l ] + f ; e [ l ] = 0.0 ; } // Sort eigenvalues and corresponding vectors. sortEigenValues ( n , d , v ) ; }
Symmetric tridiagonal QL algorithm taken from JAMA package .