protected void householder( int j )
    {
        // find the element with the largest absolute value in the column and make a copy
        int index = j+j*numCols;
        double max = 0;
        for( int i = j; i < numRows; i++ ) {

            double d = u[i] = dataQR[index];

            // absolute value of d
            if( d < 0 ) d = -d;
            if( max < d ) {
                max = d;
            }
            index += numCols;
        }

        if( max == 0.0 ) {
            gamma = 0;
            error = true;
        } else {
            // compute the norm2 of the matrix, with each element
            // normalized by the max value to avoid overflow problems
            tau = 0;
            for( int i = j; i < numRows; i++ ) {
                u[i] /= max;
                double d = u[i];
                tau += d*d;
            }
            tau = Math.sqrt(tau);

            if( u[j] < 0 )
                tau = -tau;

            double u_0 = u[j] + tau;
            gamma = u_0/tau;
            for( int i = j+1; i < numRows; i++ ) {
                u[i] /= u_0;
            }
            u[j] = 1;
            tau *= max;
        }

        gammas[j] = gamma;
    }