docs: private void singleNodeDeletion(final double[][] mat, final BiclusterCandidate cand) {
      // Assume that cand.residue is up to date!
      while(cand.residue > delta && (cand.colcard > 2 || cand.rowcard > 2)) {
        // Store current maximum. Need final mutable, so use arrays.
        final double[] max = { Double.NEGATIVE_INFINITY };
        final int[] best = { -1, -1 };
  
        // Test rows
        if(cand.rowcard > 2) {
          cand.visitColumn(mat, 0, CellVisitor.SELECTED, new CellVisitor() {
            @Override
            public boolean visit(double val, int row, int col, boolean selrow, boolean selcol) {
              assert (selrow);
              double rowResidue = cand.computeRowResidue(mat, row, false);
              if(max[0] < rowResidue) {
                max[0] = rowResidue;
                best[0] = row;
              }
              return false;
            }
          });
        }
  
        // Test columns:
        if(cand.colcard > 2) {
          cand.visitRow(mat, 0, CellVisitor.SELECTED, new CellVisitor() {
            @Override
            public boolean visit(double val, int row, int col, boolean selrow, boolean selcol) {
              assert (selcol);
              double colResidue = cand.computeColResidue(mat, col);
              if(max[0] < colResidue) {
                max[0] = colResidue;
                best[1] = col;
              }
              return false;
            }
          });
        }
  
        if(best[1] >= 0) { // then override bestrow!
          cand.selectColumn(best[1], false);
        }
        else {
          assert (best[0] >= 0);
          cand.selectRow(best[0], false);
        }
        // TODO: incremental update could be much faster?
        cand.updateRowAndColumnMeans(mat, false);
        cand.computeMeanSquaredDeviation(mat);
        if(LOG.isDebuggingFine()) {
          LOG.debugFine("Residue in Alg 1: " + cand.residue + " " + cand.rowcard + "x" + cand.colcard);
        }
      }
    }