docs: private void multipleNodeDeletion(final double[][] mat, final BiclusterCandidate cand) {
      cand.updateRowAndColumnMeans(mat, false);
      cand.computeMeanSquaredDeviation(mat);
  
      // Note: assumes that cand.residue = H(I,J)
      while(cand.residue > delta) {
        final boolean[] modified = { false, false };
  
        // Step 2: remove rows above threshold
        if(cand.rowcard > MIN_ROW_REMOVE_THRESHOLD) {
          final double alphaResidue = alpha * cand.residue;
          cand.visitColumn(mat, 0, CellVisitor.SELECTED, new CellVisitor() {
            @Override
            public boolean visit(double val, int row, int col, boolean selrow, boolean selcol) {
              assert (selrow);
              if(cand.computeRowResidue(mat, row, false) > alphaResidue) {
                cand.selectRow(row, false);
                modified[0] = true;
              }
              return (cand.rowcard > MIN_ROW_REMOVE_THRESHOLD);
            }
          });
  
          // Step 3: update residue
          if(modified[0]) {
            cand.updateRowAndColumnMeans(mat, false);
            cand.computeMeanSquaredDeviation(mat);
          }
        }
  
        // Step 4: remove columns above threshold
        if(cand.colcard > MIN_COLUMN_REMOVE_THRESHOLD) {
          final double alphaResidue = alpha * cand.residue;
          cand.visitRow(mat, 0, CellVisitor.SELECTED, new CellVisitor() {
            @Override
            public boolean visit(double val, int row, int col, boolean selrow, boolean selcol) {
              assert (selcol);
              if(cand.computeColResidue(mat, col) > alphaResidue) {
                cand.selectColumn(col, false);
                modified[1] = true;
              }
              return (cand.colcard > MIN_COLUMN_REMOVE_THRESHOLD);
            }
          });
          if(modified[1]) {
            cand.updateRowAndColumnMeans(mat, false);
            cand.computeMeanSquaredDeviation(mat);
          }
        }
  
        if(LOG.isDebuggingFine()) {
          LOG.debugFine("Residue in Alg 2: " + cand.residue + " " + cand.rowcard + "x" + cand.colcard);
        }
        // Step 5: if nothing has been removed, try removing single nodes.
        if(!modified[0] && !modified[1]) {
          break;
          // Will be executed next in main loop, as per algorithm 4.
          // singleNodeDeletion();
        }
      }
    }