// Eigen2.java // The procedure eigen computes both the eigenvalues and eigenvectors // of arbitrary n by n complex matrix. // This is a Java version of an Ada version of a NAG Fortran // library subroutine. // Some Fortran labels have been preserved for traceability package myjava; import myjava.*; public strictfp class Eigen2 { public static void eigen(Complex A[][], Complex lambda[], Complex vec[][], boolean fail[]) { System.out.println("Eigene.eigen(A, lambda, vec, fail)"); // driver for computing eigenvalues and eigenvectors if(A==null || lambda==null || vec==null) { System.out.println("Error in Eigen2.eigen,"+ " null or inconsistent array sizes."); return; } int n = A.length; if(A[0].length!=n || vec.length!=n || vec[0].length!=n || lambda.length!=n) { System.out.println("Error in Eigen.eigen,"+ " inconsistent array sizes."); return; } fail[0] = false; // special cases if(n<1) {System.out.println("zero size matrix"); return;} int rowcol[] = new int[n]; Complex B[][] = new Complex[n][n]; ComplexMatrix.copy(A, B); if(n==1) { lambda[0] = B[0][0]; vec[0][0] = new Complex(1.0, 0.0); return; } if(n==2) { twobytwo(B, lambda, vec); return; } System.out.println("calling cxhess"); cxhess(B, rowcol); for(int i=0; i sumabs(x)) { x = A[j][m-1]; i = j; } } if(i != m) { // rowcol row column interchange of H t = rowcol[m]; rowcol[m] = rowcol[i]; rowcol[i] = t; for(int j=m-1; j 0.0) { y = y.divide(x); A[ii][m-1] = y; for(int j=m; j0; ii--) //for i in reverse A'FIRST+1..A'LAST-1 loop { j = rowcol[ii]; for(k=ii+1; klow; kk--) // 300 { System.out.println("300 kk="+kk); ahr = sumabs(A[kk][kk-1]); aahr = acc * (sumabs(A[kk-1][kk-1]) + sumabs(A[kk][kk])); if(ahr <= aahr) { k = kk; break; } } // 300 System.out.println("exiting 300 with k="+k); if(k == ien) break L280; //exit L280 when k = ien; // 780 if(itn <= 0) { fail[0] = true; return; } // compute shift if(its == 10 || its == 20) { S = new Complex(Math.abs(A[ien][ien-1].real()) + Math.abs(A[ien-1][ien-2].real()) , Math.abs(A[ien][ien-1].imaginary()) + Math.abs(A[ien-1][ien-2].imaginary())); } else { S = A[ien][ien]; x = A[ien-1][ien].multiply(A[ien][ien-1]); if(sumabs(x) > 0.0) { y = (A[ien-1][ien-1].subtract(S)).divide(new Complex(2.0, 0.0)); z = ((y.multiply(y)).add(x)).sqrt(); if(y.real() * z.real() + y.imaginary() * z.imaginary() < 0.0) { z = z.negate(); } yy = y.add(z); S = S.subtract(x.divide(yy)); } // end if; } // end if; // 400 for(int i=low; i<=ien; i++) // for i in low..ien loop // 420 { A[i][i] = A[i][i].subtract(S); } // end loop; // 420 T = T.add(S); its = its + 1; itn = itn - 1; j = k + 1; // look for two consecutive small sub-diagonal elements xr = sumabs(A[ien-1][ien-1]); yr = sumabs(A[ien][ien-1]); zr = sumabs(A[ien][ien]); m = k; for(mm=ien-1; mm>=j; mm--) // for mm in reverse j..ien-1 loop // 460 { System.out.println("460 mm="+mm+", m="+m+", j="+j); yi = yr; yr = sumabs(A[mm][mm-1]); xi = zr; zr = xr; xr = sumabs(A[mm-1][mm-1]); if(yr <= (acc * zr/yi *( zr + xr + xi ))) { m = mm; break; } } //end loop; // 460 // triangular decomposition A = L*R for(int i=m+1; i<=ien; i++) //for i in m+1..ien loop // 620 { System.out.println("620 mm="+mm+", m="+m+", i="+i); x = A[i-1][i-1]; y = A[i][i-1]; if(sumabs(x) >= sumabs(y)) { z = y.divide(x); lambda[i] = new Complex(-1.0, 0.0 ); } else { // interchange rows of A for(int jj=i-1; jj 0.0) { for(int i=low; i<=jj; i++) // for i in low .. j loop // 660 { z = A[i][jj-1]; A[i][jj-1] = A[i][jj]; A[i][jj] = z; } // end loop; // 660 for(int i=low; ilow; ien--) // for ien in reverse low+1..N loop { x = lambda[ien]; for(int i=ien-1; i>=low; i--) // for i in reverse low .. ien - 1 loop { z = A[i][ien]; for(int jj=i+1; jj=0; jj--) // for j in reverse A'RANGE loop { for(int i=0; i