if (testCopy.classAttribute().isNumeric()) { throw new Exception("ClusterEvaluation: Class must be nominal!"); }
  public void evaluateClusterer(Instances test) throws Exception {    int i = 0;    int cnum;    double loglk = 0.0;    double[] dist;    double temp;    int cc = m_Clusterer.numberOfClusters();    m_numClusters = cc;    int numInstFieldWidth = (int)((Math.log(test.numInstances())/				   Math.log(10))+1);    double[] instanceStats = new double[cc];    m_clusterAssignments = new double [test.numInstances()];    Instances testCopy = test;    boolean hasClass = (testCopy.classIndex() > 0);    // If class is set then do class based evaluation as well    if (hasClass) {      AttributeFilter removeClass = new AttributeFilter();      removeClass.setAttributeIndices(""+(testCopy.classIndex()+1));      removeClass.setInvertSelection(false);      removeClass.inputFormat(testCopy);      testCopy = Filter.useFilter(testCopy, removeClass);    }    for (i=0;i<testCopy.numInstances();i++) {      try {	if (m_Clusterer instanceof DistributionClusterer) {	  temp = ((DistributionClusterer)m_Clusterer).	    densityForInstance(testCopy.instance(i));	  //	  temp = Utils.sum(dist);	  	  if (temp > 0) {	    loglk += Math.log(temp);	  }	  //	  Utils.normalize(dist);	  cnum = m_Clusterer.clusterInstance(testCopy.instance(i)); 	  // Utils.maxIndex(dist);	  m_clusterAssignments[i] = (double)cnum;	} else {	  cnum = m_Clusterer.clusterInstance(testCopy.instance(i));	  m_clusterAssignments[i] = (double)cnum;	}      }      catch (Exception e) {	throw  new Exception('\n' + "Unable to cluster instance\n" 			       + e.getMessage());      }            instanceStats[cnum]++;    }    /* // count the actual number of used clusters    int count = 0;    for (i = 0; i < cc; i++) {      if (instanceStats[i] > 0) {	count++;      }    }    if (count > 0) {      double [] tempStats = new double [count];      double [] map = new double [m_clusterAssignments.length];      count=0;      for (i=0;i<cc;i++) {	if (instanceStats[i] > 0) {	  tempStats[count] = instanceStats[i];	  map[i] = count;	  count++;	}      }      instanceStats = tempStats;      cc = instanceStats.length;      for (i=0;i<m_clusterAssignments.length;i++) {	m_clusterAssignments[i] = map[(int)m_clusterAssignments[i]];      }      } */     double sum = Utils.sum(instanceStats);    loglk /= sum;    m_clusteringResults.append("Cluster Instances\n\n");    int clustFieldWidth = (int)((Math.log(cc)/Math.log(10))+1);    for (i = 0; i < cc; i++) {      if (instanceStats[i] > 0) {	m_clusteringResults.append(Utils.doubleToString((double)i, 							clustFieldWidth, 0) 				   + "      " 				   + Utils.doubleToString(instanceStats[i],							  numInstFieldWidth, 0) 				   + " (" 				   + Utils.doubleToString((instanceStats[i] / 							   sum * 100.0)							  , 3, 0) + "%)\n");      }    }        if (m_Clusterer instanceof DistributionClusterer) {      m_clusteringResults.append("\nLog likelihood: " 				 + Utils.doubleToString(loglk, 1, 5) 				 + "\n");    }        if (hasClass) {      evaluateClustersWithRespectToClass(test);    }  }