docs: protected void updateA( int w )
      {
          // much of the code below is equivalent to the rank1Update function
          // however, since &tau; has already been computed there is no need to
          // recompute it, saving a few multiplication operations
  //        for( int i = w+1; i < numCols; i++ ) {
  //            double val = 0;
  //
  //            for( int k = w; k < numRows; k++ ) {
  //                val += u[k]*dataQR[k*numCols +i];
  //            }
  //            v[i] = gamma*val;
  //        }
  
          // This is functionally the same as the above code but the order has been changed
          // to avoid jumping the cpu cache
          for( int i = w+1; i < numCols; i++ ) {
              v[i] = u[w]*dataQR[w*numCols +i];
          }
  
          for( int k = w+1; k < numRows; k++ ) {
              int indexQR = k*numCols+w+1;
              for( int i = w+1; i < numCols; i++ ) {
  //                v[i] += u[k]*dataQR[k*numCols +i];
                  v[i] += u[k]*dataQR[indexQR++];
              }
          }
  
          for( int i = w+1; i < numCols; i++ ) {
              v[i] *= gamma;
          }
  
          // end of reordered code
  
          for( int i = w; i < numRows; i++ ) {
              double valU = u[i];
  
              int indexQR = i*numCols+w+1;
              for( int j = w+1; j < numCols; j++ ) {
  //                dataQR[i*numCols+j] -= valU*v[j];
                  dataQR[indexQR++] -= valU*v[j];
              }
          }
  
          if( w < numCols ) {
              dataQR[w+w*numCols] = -tau;
          }
  
          // save the Q matrix in the lower portion of QR
          for( int i = w+1; i < numRows; i++ ) {
              dataQR[w+i*numCols] = u[i];
          }
      }