/**
  * Method used to configure and initialize instance selection model.
  *
  * @param exampleSet
  * @return
  * @throws OperatorException
  */
 @Override
 public AbstractInstanceSelectorModel configureInstanceSelectionModel(
     SelectedExampleSet exampleSet) throws OperatorException {
   // INITIALIZATION
   DistanceMeasure measure = measureHelper.getInitializedMeasure(exampleSet);
   int k = getParameterAsInt(PARAMETER_K);
   Attribute labelAttribute = exampleSet.getAttributes().getLabel();
   double[] classWeight = null;
   IISDecisionFunction loss = ISDecisionFunctionHelper.getConfiguredISDecisionFunction(this);
   if (labelAttribute.isNominal()) {
     classWeight = new double[labelAttribute.getMapping().size()];
     for (int i = 0; i < classWeight.length; i++) {
       classWeight[i] = 1.0d;
     }
     if (isParameterSet(PARAMETER_CLASS_WEIGHTS)) {
       List<String[]> classWeights = getParameterList(PARAMETER_CLASS_WEIGHTS);
       Iterator<String[]> i = classWeights.iterator();
       while (i.hasNext()) {
         String[] classWeightArray = i.next();
         String className = classWeightArray[0];
         double classWeightValue = Double.valueOf(classWeightArray[1]);
         int index = labelAttribute.getMapping().getIndex(className);
         if ((index >= 0) && (index < classWeight.length)) {
           classWeight[index] = classWeightValue;
         }
       }
     }
   }
   return new ENNInstanceSelectionModel(measure, k, loss, classWeight);
 }
  @Override
  public double[] doWork(
      ExampleSet exampleSet, Attributes attributes, double[][] points, int[] weight)
      throws OperatorException {
    DistanceMeasure measure = measureHelper.getInitializedMeasure(exampleSet);
    int n = points.length;
    int k = getParameterAsInt(PARAMETER_K);
    boolean kth = getParameterAsBoolean(PARAMETER_KTH_NEIGHBOR_DISTANCE);
    boolean parallel = getParameterAsBoolean(PARAMETER_PARALLELIZE_EVALUATION_PROCESS);
    int numberOfThreads = getParameterAsInt(PARAMETER_NUMBER_OF_THREADS);
    double[] ret = {1};

    if (n > 1) {
      if (k >= n) {
        this.logWarning(
            "Setting " + KNNAnomalyDetectionOperator.PARAMETER_K + " to #Datapoints-1.");
        k = n - 1;
        // this.setParameter(KNNAnomalyDetectionOperator.PARAMETER_K, (n-1) + "");
      }
      readModel(n, k, points, weight, measure);
      KNNEvaluator evaluator =
          new KNNEvaluator(
              knnCollection, kth, measure, parallel, numberOfThreads, this, n, k, newCollection);
      ret = evaluator.evaluate();
      model = new KNNCollectionModel(exampleSet, knnCollection, measure);
      modelOutput.deliver(model);
      knnCollection = null;
    }
    return ret;
  }
  @Override
  public void doWork() throws OperatorException {
    ExampleSet exampleSet = exampleSetInput.getData(ExampleSet.class);
    // needed for some measures
    Tools.checkAndCreateIds(exampleSet);

    DistanceMeasure measure = measureHelper.getInitializedMeasure(exampleSet);
    SimilarityMeasureObject measureObject = new SimilarityMeasureObject(measure, exampleSet);

    ObjectVisualizerService.addObjectVisualizer(measureObject, new ExampleVisualizer(exampleSet));

    similarityOutput.deliver(measureObject);
    exampleSetOutput.deliver(exampleSet);
  }
  @Override
  public void doWork() throws OperatorException {
    ExampleSet exampleSet = exampleSetInput.getData(ExampleSet.class);
    DistanceMeasure measure = measureHelper.getInitializedMeasure(exampleSet);

    // additional checks
    Tools.onlyNonMissingValues(exampleSet, getOperatorClassName(), this, new String[0]);
    Tools.checkAndCreateIds(exampleSet);

    Attribute idAttribute = exampleSet.getAttributes().getId();
    boolean idAttributeIsNominal = idAttribute.isNominal();
    DistanceMatrix matrix = new DistanceMatrix(exampleSet.size());
    Map<Integer, HierarchicalClusterNode> clusterMap =
        new HashMap<Integer, HierarchicalClusterNode>(exampleSet.size());
    int[] clusterIds = new int[exampleSet.size()];
    // filling the distance matrix
    int nextClusterId = 0;
    for (Example example1 : exampleSet) {
      checkForStop();
      clusterIds[nextClusterId] = nextClusterId;
      int y = 0;
      for (Example example2 : exampleSet) {
        if (y > nextClusterId) {
          matrix.set(nextClusterId, y, measure.calculateDistance(example1, example2));
        }
        y++;
      }
      if (idAttributeIsNominal) {
        clusterMap.put(
            nextClusterId,
            new HierarchicalClusterLeafNode(nextClusterId, example1.getValueAsString(idAttribute)));
      } else {
        clusterMap.put(
            nextClusterId,
            new HierarchicalClusterLeafNode(nextClusterId, example1.getValue(idAttribute)));
      }
      nextClusterId++;
    }

    // creating linkage method
    AbstractLinkageMethod linkage = new SingleLinkageMethod(matrix, clusterIds);
    if (getParameterAsString(PARAMETER_MODE).equals(modes[1])) {
      linkage = new CompleteLinkageMethod(matrix, clusterIds);
    } else if (getParameterAsString(PARAMETER_MODE).equals(modes[2])) {
      linkage = new AverageLinkageMethod(matrix, clusterIds);
    }

    // now building agglomerative tree bottom up
    while (clusterMap.size() > 1) {
      Agglomeration agglomeration = linkage.getNextAgglomeration(nextClusterId, clusterMap);
      HierarchicalClusterNode newNode =
          new HierarchicalClusterNode(nextClusterId, agglomeration.getDistance());
      newNode.addSubNode(clusterMap.get(agglomeration.getClusterId1()));
      newNode.addSubNode(clusterMap.get(agglomeration.getClusterId2()));
      clusterMap.remove(agglomeration.getClusterId1());
      clusterMap.remove(agglomeration.getClusterId2());
      clusterMap.put(nextClusterId, newNode);
      nextClusterId++;
    }

    // creating model
    HierarchicalClusterModel model =
        new DendogramHierarchicalClusterModel(clusterMap.entrySet().iterator().next().getValue());

    // registering visualizer
    ObjectVisualizerService.addObjectVisualizer(
        model, new ExampleVisualizer((ExampleSet) exampleSet.clone()));

    modelOutput.deliver(model);
    exampleSetOutput.deliver(exampleSet);
  }