new Instances(train, 0), m_MinNum, m_MinVariance * trainVariance, 0, m_MaxDepth);
new Instances(train, 0), m_MinNum, m_MinVarianceProp * trainVariance, 0, m_MaxDepth);
  public void buildClassifier(Instances data) throws Exception {    Random random = new Random(m_Seed);    // Check for non-nominal classes    if (!data.classAttribute().isNominal() && !data.classAttribute().isNumeric()) {      throw new UnsupportedClassTypeException("REPTree: nominal or numeric class, please.");    }    // Delete instances with missing class    data = new Instances(data);    data.deleteWithMissingClass();    // Check for empty datasets    if (data.numInstances() == 0) {      throw new Exception("REPTree: zero training instances or all instances " +			  "have missing class!");    }    // Randomize and stratify    data.randomize(random);    if (data.classAttribute().isNominal()) {      data.stratify(m_NumFolds);    }    // Split data into training and pruning set    Instances train = null;    Instances prune = null;    if (!m_NoPruning) {      train = data.trainCV(m_NumFolds, 0);      prune = data.testCV(m_NumFolds, 0);    } else {      train = data;    }    // Create array of sorted indices and weights    int[][] sortedIndices = new int[train.numAttributes()][0];    double[][] weights = new double[train.numAttributes()][0];    double[] vals = new double[train.numInstances()];    for (int j = 0; j < train.numAttributes(); j++) {      if (j != train.classIndex()) {	weights[j] = new double[train.numInstances()];	if (train.attribute(j).isNominal()) {	  // Handling nominal attributes. Putting indices of	  // instances with missing values at the end.	  sortedIndices[j] = new int[train.numInstances()];	  int count = 0;	  for (int i = 0; i < train.numInstances(); i++) {	    Instance inst = train.instance(i);	    if (!inst.isMissing(j)) {	      sortedIndices[j][count] = i;	      weights[j][count] = inst.weight();	      count++;	    }	  }	  for (int i = 0; i < train.numInstances(); i++) {	    Instance inst = train.instance(i);	    if (inst.isMissing(j)) {	      sortedIndices[j][count] = i;	      weights[j][count] = inst.weight();	      count++;	    }	  }	} else {	  	  // Sorted indices are computed for numeric attributes	  for (int i = 0; i < train.numInstances(); i++) {	    Instance inst = train.instance(i);	    vals[i] = inst.value(j);	  }	  sortedIndices[j] = Utils.sort(vals);	  for (int i = 0; i < train.numInstances(); i++) {	    weights[j][i] = train.instance(sortedIndices[j][i]).weight();	  }	}      }    }    // Compute initial class counts    double[] classProbs = new double[train.numClasses()];    double totalWeight = 0, totalSumSquared = 0;    for (int i = 0; i < train.numInstances(); i++) {      Instance inst = train.instance(i);      if (data.classAttribute().isNominal()) {	classProbs[(int)inst.classValue()] += inst.weight();	totalWeight += inst.weight();      } else {	classProbs[0] += inst.classValue() * inst.weight();	totalSumSquared += inst.classValue() * inst.classValue() * inst.weight();	totalWeight += inst.weight();      }    }    double trainVariance = 0;    if (data.classAttribute().isNumeric()) {      trainVariance = totalSumSquared - ((classProbs[0] * classProbs[0]) / totalWeight);      classProbs[0] /= totalWeight;    }    // Build tree    m_Tree = new Tree();    m_Tree.buildTree(sortedIndices, weights, train, totalWeight, classProbs,		     new Instances(train, 0), m_MinNum, m_MinVariance * trainVariance,		     0, m_MaxDepth);        // Insert pruning data and perform reduced error pruning    if (!m_NoPruning) {      m_Tree.insertHoldOutSet(prune);      m_Tree.reducedErrorPrune();    }  }