public static void qrupdt_f77(int n, double a[][],
                             double u[], double v[]) {

/*

Here is a copy of the qrupdt FORTRAN documentation:


      SUBROUTINE QRUPDT(NR,N,A,U,V)
C
C PURPOSE
C -------
C FIND AN ORTHOGONAL (N*N) MATRIX (Q*) AND AN UPPER TRIANGULAR (N*N)
C MATRIX (R*) SUCH THAT (Q*)(R*)=R+U(V+)
C
C PARAMETERS
C ----------
C NR           --> ROW DIMENSION OF MATRIX
C N            --> DIMENSION OF PROBLEM
C A(N,N)      <--> ON INPUT:  CONTAINS R
C                  ON OUTPUT: CONTAINS (R*)
C U(N)         --> VECTOR
C V(N)         --> VECTOR
C

*/

      int k,km1,ii,i,j;
      double t1,t2;

// DETERMINE LAST NON-ZERO IN U(.)

      k = n;

      while (u[k] == 0 && k > 1) {

         k--;

      }

// (K-1) JACOBI ROTATIONS TRANSFORM
// R + U(V+) --> (R*) + (U(1)*E1)(V+)
// WHICH IS UPPER HESSENBERG

      km1 = k - 1;

      for (ii = 1; ii <= km1; ii++) {

         i = km1 - ii + 1;

         if (u[i] == 0.0) {

            Uncmin_f77.qraux1_f77(n,a,i);
            u[i] = u[i+1];

         } else {

            Uncmin_f77.qraux2_f77(n,a,i,u[i],-u[i+1]);
            u[i] = Math.sqrt(u[i]*u[i] + u[i+1]*u[i+1]);

         }

      }

// R <-- R + (U(1)*E1)(V+)

      for (j = 1; j <= n; j++) {

         a[1][j] += u[1]*v[j];

      }

// (K-1) JACOBI ROTATIONS TRANSFORM UPPER HESSENBERG R
// TO UPPER TRIANGULAR (R*)

      km1 = k - 1;

      for (i = 1; i <= km1; i++) {

         if (a[i][i] == 0.0) {

            Uncmin_f77.qraux1_f77(n,a,i);

         } else {

            t1 = a[i][i];
            t2 = -a[i+1][i];

            Uncmin_f77.qraux2_f77(n,a,i,t1,t2);

         }

      }

      return;

   }