package de.lmu.ifi.dbs.elki.algorithm.clustering.correlation;

import org.junit.Test;

import de.lmu.ifi.dbs.elki.JUnit4Test;
import de.lmu.ifi.dbs.elki.algorithm.AbstractSimpleAlgorithmTest;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.DoubleVector;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParameterization;

/**
 * Performs a full ORCLUS run, and compares the result with a clustering derived
 * from the data set labels. This test ensures that ORCLUS performance doesn't
 * unexpectedly drop on this data set (and also ensures that the algorithms
 * work, as a side effect).
 * 
 * @author Elke Achtert
 * @author Katharina Rausch
 */
public class TestORCLUSResults extends AbstractSimpleAlgorithmTest implements JUnit4Test {
  /**
   * Run ORCLUS with fixed parameters and compare the result to a golden
   * standard.
   * 
   * @throws ParameterException on errors.
   */
  @Test
  public void testORCLUSResults() {
    Database db = makeSimpleDatabase(UNITTEST + "correlation-hierarchy.csv", 450);

    ListParameterization params = new ListParameterization();
    // these parameters are not picked too smartly - room for improvement.
    params.addParameter(ORCLUS.K_ID, 3);
    params.addParameter(ORCLUS.L_ID, 1);
    params.addParameter(ORCLUS.SEED_ID, 1);

    // setup algorithm
    ORCLUS<DoubleVector> orclus = ClassGenericsUtil.parameterizeOrAbort(ORCLUS.class, params);
    testParameterizationOk(params);

    // run ORCLUS on database
    Clustering<Model> result = orclus.run(db);

    testFMeasureHierarchical(db, result, 0.77989);
    testClusterSizes(result, new int[] { 22, 32, 396 });
  }

  /**
   * Run ORCLUS with fixed parameters and compare the result to a golden
   * standard.
   * 
   * @throws ParameterException on errors.
   */
  @Test
  public void testORCLUSSkewedDisjoint() {
    Database db = makeSimpleDatabase(UNITTEST + "correlation-skewed-disjoint-3-5d.ascii", 601);
  
    // Setup algorithm
    ListParameterization params = new ListParameterization();
    params.addParameter(ORCLUS.K_ID, 3);
    params.addParameter(ORCLUS.L_ID, 4);
    params.addParameter(ORCLUS.SEED_ID, 2);
  
    ORCLUS<DoubleVector> orclus = ClassGenericsUtil.parameterizeOrAbort(ORCLUS.class, params);
    testParameterizationOk(params);
  
    // run ORCLUS on database
    Clustering<Model> result = orclus.run(db);
    testFMeasure(db, result, 0.8276336);
    testClusterSizes(result, new int[] { 167, 200, 234 });
  }
}
@@ -1828,11 +1828,12 @@
 0.77
-989
+5313
 );%0A 
@@ -1877,18 +1877,18 @@
  %7B 2
-2
+6
 , 
-3
 2
+7
 , 39
-6
+7
  %7D);
@@ -2189,19 +2189,17 @@
 , 601);%0A
-  
 %0A
+
     // S
@@ -2401,14 +2401,12 @@
 ID, 
-2
+9
 );%0A
-  
 %0A   
@@ -2537,11 +2537,9 @@
 s);%0A
-  
 %0A
+
     
@@ -2647,13 +2647,13 @@
  0.8
-27633
+68786
 6);%0A
@@ -2698,10 +2698,10 @@
  %7B 1
-6
 7
+0
 , 20
@@ -2705,17 +2705,17 @@
  200, 23
-4
+1
  %7D);%0A  %7D

Fix unit test - ORCLUS stability has changed because of numerical changes in centroid computation. Yes, ORCLUS is this unstable!