code: protected void decompose() throws MatrixException
      {
          // Return if the decomposition is valid.
          if (LU != null) return;
  
          // Create a new LU matrix and permutation vector.
          // LU is initially just a copy of the values of this system.
          LU = new SquareMatrix(this.copyValues2D());
          permutation = new int[nRows];
  
          double scales[] = new double[nRows];
  
          // Loop to initialize the permutation vector and scales.
          for (int r = 0; r < nRows; ++r) {
              permutation[r] = r;     // initially no row exchanges
  
              // Find the largest row element.
              double largestRowElmt = 0;
              for (int c = 0; c < nRows; ++c) {
                  double elmt = Math.abs(LU.at(r, c));
                  if (largestRowElmt < elmt) largestRowElmt = elmt;
              }
  
              // Set the scaling factor for row equilibration.
              if (largestRowElmt != 0) {
                  scales[r] = 1/largestRowElmt;
              }
              else {
                  throw new MatrixException(MatrixException.ZERO_ROW);
              }
          }
  
          // Do forward elimination with scaled partial row pivoting.
          forwardElimination(scales);
  
          // Check bottom right element of the permuted matrix.
          if (LU.at(permutation[nRows - 1], nRows - 1) == 0) {
              throw new MatrixException(MatrixException.SINGULAR);
          }
      }
docs: Compute the upper triangular matrix U and lower triangular
  matrix L such that A = L*U.  Store L and U together in
  matrix LU.  Compute the permutation vector permutation of
  the row indices.
  @throws matrix.MatrixException for a zero row or
  a singular matrix