private void tred2(){
  for (int j=0; j < n; j++)   d[j]=V.get(n - 1,j);
  for (int i=n - 1; i > 0; i--) {
    double scale=0.0;
    double h=0.0;
    for (int k=0; k < i; k++) {
      scale=scale + abs(d[k]);
    }
    if (scale == 0.0) {
      e[i]=d[i - 1];
      for (int j=0; j < i; j++) {
        d[j]=V.get(i - 1,j);
        V.set(i,j,0.0);
        V.set(j,i,0.0);
      }
    }
 else {
      for (int k=0; k < i; k++) {
        d[k]/=scale;
        h+=d[k] * d[k];
      }
      double f=d[i - 1];
      double g=sqrt(h);
      if (f > 0)       g=-g;
      e[i]=scale * g;
      h-=f * g;
      d[i - 1]=f - g;
      Arrays.fill(e,0,i,0.0);
      for (int j=0; j < i; j++) {
        f=d[j];
        V.set(j,i,f);
        g=e[j] + V.get(j,j) * f;
        for (int k=j + 1; k <= i - 1; k++) {
          g+=V.get(k,j) * d[k];
          e[k]+=V.get(k,j) * f;
        }
        e[j]=g;
      }
      f=0.0;
      for (int j=0; j < i; j++) {
        e[j]/=h;
        f+=e[j] * d[j];
      }
      double hh=f / (h + h);
      for (int j=0; j < i; j++) {
        e[j]-=hh * d[j];
      }
      for (int j=0; j < i; j++) {
        f=d[j];
        g=e[j];
        for (int k=j; k <= i - 1; k++) {
          V.increment(k,j,-(f * e[k] + g * d[k]));
        }
        d[j]=V.get(i - 1,j);
        V.set(i,j,0.0);
      }
    }
    d[i]=h;
  }
  for (int i=0; i < n - 1; i++) {
    V.set(n - 1,i,V.get(i,i));
    V.set(i,i,1.0);
    double h=d[i + 1];
    if (h != 0.0) {
      for (int k=0; k <= i; k++) {
        d[k]=V.get(k,i + 1) / h;
      }
      for (int j=0; j <= i; j++) {
        double g=0.0;
        for (int k=0; k <= i; k++) {
          g+=V.get(k,i + 1) * V.get(k,j);
        }
        RowColumnOps.addMultCol(V,j,0,i + 1,-g,d);
      }
    }
    RowColumnOps.fillCol(V,i + 1,0,i + 1,0.0);
  }
  for (int j=0; j < n; j++) {
    d[j]=V.get(n - 1,j);
    V.set(n - 1,j,0.0);
  }
  V.set(n - 1,n - 1,1.0);
  e[0]=0.0;
}

private void tred2 ( ) { for ( int j = 0 ; j < n ; j ++ ) d [ j ] = V . get ( n - 1 , j ) ; for ( int i = n - 1 ; i > 0 ; i -- ) { double scale = 0.0 ; double h = 0.0 ; for ( int k = 0 ; k < i ; k ++ ) { scale = scale + abs ( d [ k ] ) ; } if ( scale == 0.0 ) { e [ i ] = d [ i - 1 ] ; for ( int j = 0 ; j < i ; j ++ ) { d [ j ] = V . get ( i - 1 , j ) ; V . set ( i , j , 0.0 ) ; V . set ( j , i , 0.0 ) ; } } else { for ( int k = 0 ; k < i ; k ++ ) { d [ k ] /= scale ; h += d [ k ] * d [ k ] ; } double f = d [ i - 1 ] ; double g = sqrt ( h ) ; if ( f > 0 ) g = - g ; e [ i ] = scale * g ; h -= f * g ; d [ i - 1 ] = f - g ; Arrays . fill ( e , 0 , i , 0.0 ) ; for ( int j = 0 ; j < i ; j ++ ) { f = d [ j ] ; V . set ( j , i , f ) ; g = e [ j ] + V . get ( j , j ) * f ; for ( int k = j + 1 ; k <= i - 1 ; k ++ ) { g += V . get ( k , j ) * d [ k ] ; e [ k ] += V . get ( k , j ) * f ; } e [ j ] = g ; } f = 0.0 ; for ( int j = 0 ; j < i ; j ++ ) { e [ j ] /= h ; f += e [ j ] * d [ j ] ; } double hh = f / ( h + h ) ; for ( int j = 0 ; j < i ; j ++ ) { e [ j ] -= hh * d [ j ] ; } for ( int j = 0 ; j < i ; j ++ ) { f = d [ j ] ; g = e [ j ] ; for ( int k = j ; k <= i - 1 ; k ++ ) { V . increment ( k , j , - ( f * e [ k ] + g * d [ k ] ) ) ; } d [ j ] = V . get ( i - 1 , j ) ; V . set ( i , j , 0.0 ) ; } } d [ i ] = h ; } for ( int i = 0 ; i < n - 1 ; i ++ ) { V . set ( n - 1 , i , V . get ( i , i ) ) ; V . set ( i , i , 1.0 ) ; double h = d [ i + 1 ] ; if ( h != 0.0 ) { for ( int k = 0 ; k <= i ; k ++ ) { d [ k ] = V . get ( k , i + 1 ) / h ; } for ( int j = 0 ; j <= i ; j ++ ) { double g = 0.0 ; for ( int k = 0 ; k <= i ; k ++ ) { g += V . get ( k , i + 1 ) * V . get ( k , j ) ; } RowColumnOps . addMultCol ( V , j , 0 , i + 1 , - g , d ) ; } } RowColumnOps . fillCol ( V , i + 1 , 0 , i + 1 , 0.0 ) ; } for ( int j = 0 ; j < n ; j ++ ) { d [ j ] = V . get ( n - 1 , j ) ; V . set ( n - 1 , j , 0.0 ) ; } V . set ( n - 1 , n - 1 , 1.0 ) ; e [ 0 ] = 0.0 ; }
symmetric householder reduction to tridiagonal form .
