gt:         for (int i = 0; i < this.getNumberOfObjects(); i++) {
context: /*
   *  RapidMiner
   *
   *  Copyright (C) 2001-2014 by RapidMiner and the contributors
   *
   *  Complete list of developers available at our web site:
   *
   *       http://rapidminer.com
   *
   *  This program is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU Affero General Public License as published by
   *  the Free Software Foundation, either version 3 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU Affero General Public License for more details.
   *
   *  You should have received a copy of the GNU Affero General Public License
   *  along with this program.  If not, see http://www.gnu.org/licenses/.
   */
  package com.rapidminer.operator.preprocessing.outlier;
  
  import java.util.Enumeration;
  import java.util.ListIterator;
  import java.util.Vector;
  
  /**
   * SearchSpace is a class for building a room full of SearchObjects (see class definition)
   * and provides various methods to place those objects into the SearchSpace (by associating
   * those Objects to the list of objects in the SearchSpace) as well as to do
   * some Outlier Tests on those Objects.
   * 
   * @author Stephan Deutsch, Ingo Mierswa
   */
  public class SearchSpace {
  
      /**
       * This variable holds the number of dimensions for the Searchroom. As
       * {@link SearchObject#dimensions} hold their own number of dimensions per
       * instance of that class, the dimensions of the SearchSpace and its associated
       * SearchObjects must not assumed to be equal. E.g. a SearchObject can have more
       * or fewer dimensions than the SearchSpace. Consistency checks should be performed
       * as necessary, but not as mandatory.
       */
      private int dimensions;
  
      /**
       * The list of SearchObjects in the SearchSpace (as a Vector class).
       * 
       */
      private Vector<SearchObject> listOfObjects;
  
      /**
       * holds the minimum value of the dimensions of all SearchObjects in the SearchSpace
       * and is updated automatically as SearchObjects are added to the SearchSpace.
       * This is to provide meta-data for statistical analysis over the SearchSpace.
       */
      private double[] minimumVectorValue;
  
      /**
       * holds the maximum value of the dimensions of all SearchObjects in the SearchSpace
       * and is updated automatically as SearchObjects are added to the SearchSpace. This is
       * to provide meta-data for statistical analysis over the SearchSpace.
       */
      private double[] maximumVectorValue;
  
      /**
       * Holds the range (interval) value of the dimensions of all SearchObjects in the
       * SearchSpace and is updated automatically as SearchObjects are added to the SearchSpace.
       * This is to provide meta-data for statistical analysis over the SearchSpace.
       */
      private double[] rangeVectorValue;
  
      /**
       * The lower bound for a potential MinPts search (e.g. a LOF search).
       */
      //private int minPtsLowerBound;
  
      /**
       * The upper bound for a potential MinPts search (e.g. a LOF search).
       */
      //private int minPtsUpperBound;
  
  
      /**
       * This constructor creates a SearchSpace with (integer) <i>dim</i> dimensions and
       * initializes all fields in the instance of that Class with zero values where appropriate.
       */
      public SearchSpace(int dim) {
          this.dimensions = dim;
          this.createListOfObjects(); // create a list of Objects mapped to this.listOfObjects
          // initialize the SearchRooms Vektor parameters by creating arrays and filling them with zeros
          this.minimumVectorValue = new double[dim];
          this.maximumVectorValue = new double[dim];
          this.rangeVectorValue = new double[dim];
          for (int i = 0; i < this.dimensions; i++) {
              this.minimumVectorValue[i] = 0;
              this.maximumVectorValue[i] = 0;
              this.rangeVectorValue[i] = 0;
          }
      }
  
      /**
       * This constructor creates a SearchSpace with (integer) <i>2</i> dimensions as a default
       * and initializes all fields in the instance of that Class with zero values where appropriate.
       */
      public SearchSpace() { // construct a searchroom with at least 2 dimensions
          this(2);
      }
  
      /**
       * This constructor creates a SearchSpace with (integer) <i>dim</i> dimensions and initializes
       * all fields in the instance of that Class with zero values where appropriate.
       */
      public SearchSpace(int dim, int minptslb, int minptsub) {
          this(dim);
          //this.minPtsLowerBound = minptslb;
          //this.minPtsUpperBound = minptsub;
      }
  
  
      /**
       * Returns the (integer) number of objects in the Searchroom (associated with it via
       * {@link #addObject(SearchObject)} to the room) as an integer value as we overall do
       * not expect the searchroom to hold more than 2 billion objects.
       * 
       */
      public int getNumberOfObjects() {
          return this.listOfObjects.size();
      }
  
      /**
       * Sets the minimum value of all SearchObjects in a SearchSpace to a value for a dimension dim.
       * 
       * @param dim
       * @param value
       */
      void setMinimumVectorValue(int dim, double value) {
          this.minimumVectorValue[dim] = value;
      }
  
      /**
       * Returns the minimum value of all SearchObjects in a SearchSpace for a dimension dim.
       * 
       * @param dim
       */
      double getMinimumVectorValue(int dim) {
          return this.minimumVectorValue[dim];
      }
  
      /**
       * Sets the maximum value of all SearchObjects in a SearchSpace to a value for a dimension dim.
       * 
       * @param dim
       * @param value
       */
      void setMaximumVectorValue(int dim, double value) {
          this.maximumVectorValue[dim] = value;
      }
  
      /**
       * Returns the maximum value of all SearchObjects in a SearchSpace for a dimension dim.
       * 
       * @param dim
       */
      double getMaximumVectorValue(int dim) {
          return this.maximumVectorValue[dim];
      }
  
      /**
       * Sets the range value (maximum - minimum) of all SearchObjects in a SearchSpace to a
       * value for a dimension dim.
       * 
       * @param dim
       * @param value
       */
      void setRangeVectorValue(int dim, double value) {
          this.rangeVectorValue[dim] = value;
      }
  
      /**
       * Returns the range value (maximum - minimum) of all SearchObjects in a SearchSpace for a
       * dimension dim.
       * 
       * @param dim
       */
      double getRangeVectorValue(int dim) {
          return this.rangeVectorValue[dim];
      }
  
      /**
       * <p>Sets the number of dimensions for the SearchSpace to dim.</p>
       * <p><em>Attention</em>: This is a value that the SearchSpace keeps for the purpose of
       * consistency checks for all SearchObjects (as each SearchObject has its own number of
       * dimensions and not all the dimensions of the SearchObjects need to be the same - to
       * give implementation freedom).</p>
       * 
       * @param dim
       */
      public void setDimensions(int dim) {
          this.dimensions = dim;
      }
  
      /**
       * Returns the number of dimensions of the SearchSpace.
       */
      public int getDimensions() {
          return this.dimensions;
      }
  
      /**
       * Creates a listOfObjects (e.g. a new Vector Class instance within the SearchSpace) and
       * is used by a constructor.
       * 
       */
      void createListOfObjects() {
          this.listOfObjects = new Vector<SearchObject>();
      }
  
      /** Delivers the list of objects. */
      public Vector<SearchObject> getSearchObjects() {
          return listOfObjects;
      }
  
      /**
       * This method returns the outlierstatus of the Searchobject (element at index i) in the
       * SearchSpace from the Searchroom's listOfObjects.
       * 
       * @param i
       * @return the boolean outlier status
       */
      public boolean getSearchObjectOutlierStatus(int i) {
          SearchObject so = this.listOfObjects.elementAt(i);
          return so.getOutlierStatus();
      }
  
      /**
       * This adds a SearchObject to the SearchSpace.
       * 
       * <p>
       * It prints a warning to STDOUT in case the dimensions of the SearchObject and
       * SearchSpace are incompatible, but as the SearchSpace can perform some operations
       * over SearchObjects with different dimensions, this is not a showstopper.
       * 
       * <p>
       * The method also automatically updates the min/max/range information the SearchSpace
       * knows for itself.
       * 
       * @param objectToAdd
       */
      public void addObject(SearchObject objectToAdd) {
          this.listOfObjects.addElement(objectToAdd); // add the object of type SearchObject to the SearchSpace
          for (int i = 0; i < this.getDimensions(); i++) {
              if (this.getMinimumVectorValue(i) > objectToAdd.getVektor(i)) {
                  this.setMinimumVectorValue(i, objectToAdd.getVektor(i));
              }
              if (this.getMaximumVectorValue(i) < objectToAdd.getVektor(i)) {
                  this.setMaximumVectorValue(i, objectToAdd.getVektor(i));
              }
              this.setRangeVectorValue(i, this.getMaximumVectorValue(i) - this.getMinimumVectorValue(i));
          }
      }
  
      /**
       * This method returns a SearchObject with the i-th index in the listOfObjects;
       * the result has to be casted to SearchObject (Vector Class speciality, as it
       * returns only a JAVA Object Class object). This is better than to access the
       * listOfObjects directly, but sadly I do not use it consistently. Maybe in the
       * cleaning-up, this will be changed.
       * 
       * @param index
       */
      public SearchObject getObject(int index) {
          return this.listOfObjects.elementAt(index);
      }
  
      /**
       * This method returns an Enumeration of all SearchObjects from a SearchSpace.
       */
      public Enumeration getObjects() {
          return this.listOfObjects.elements();
      }
  
      /**
       * Checks the dimensional integrity of the Searchroom and returns an array if int values for each object with 0 for equal dimensions of room and object, -1 for less dimensions in the room than object thinks it has and +1 for more dimensions in
       * the room than object has.
       * 
       * <p>
       * Method prints to the STDOUT a message on whether the overall integrity is given (all objects have the same dimensions as the searchroom. ATTN: this checks only those objects in the search room, e.g. which have been added to it using
       * {@link #addObject(SearchObject)}.
       */
      int[] dimensionsIntegrityCheck() {
          SearchObject sobject;
          int number = this.getNumberOfObjects();
          int[] range = new int[number];
          int checker = 0;
          for (int i = 0; i < number; i++) {
              sobject = this.listOfObjects.elementAt(i); // cast this to SearchObject from Vector class...??
              if (sobject.getDimensions() != this.dimensions) {
                  if (sobject.getDimensions() < this.dimensions) {
                      range[i] = 1;
                  }
                  range[i] = -1;
              } else {
                  range[i] = 0;
              }
              checker = checker + range[i];
          }
          return range;
      }
  
      /**
       * This method resets the Outlier Status for all Objects in the Search room to have a clean start or to have a new identification of outliers with a separate method. As this zeros all boolean outlier statuses of all objects associated to this
       * Searchroom and also zeros all outlier smooth factors, a current status list should be drawn down and stored somewhere before using this method.
       * 
       * ATTN: As this only uses references to Objects associated to a Searchroom, in case more than one Searchroom uses a (fraction) range of objects, this might override the results from other detections for those objects. But it is encouraged to
       * associate objects to only one SearchSpace and use duplications of objects with similar vektors in other SearchRooms.
       */
      public void resetOutlierStatus() {
          SearchObject sobject;
          for (int i = 0; i < this.getNumberOfObjects(); i++) {
              sobject = this.listOfObjects.elementAt(i); // cast this to SearchObject from Vector class...??
              sobject.setOutlierStatus(false);
              sobject.setOutlierFactor(0);
          }
      }
  
      /**
       * BruteForce Radius Search to determine the outlier status of an object rObject of the type SearchObject this method takes d and p as parameters acc. to distance based DB(p,D)-Outlier (Knorr, Ng) and identifies an object as being an outlier, if
       * more than a proportion p of the objects is more than distance D from rObject away.
       * 
       * The simplest approach is to make a radius search for rObject and compare its distance to all other objects step by step with D (in this case d). If more than M = N(1-p) objects are within d, than rObject is not an Outlier, else it is. Although
       * this is an approach with O(N^2) for all objects (it is O(N) for rObject), this prunes the search as soon as more than M objects are within d from rObject to get some improvement.
       */
      public void radiusODSearch(double d, double p, SearchObject rObject, int kindOfDistance) {
          int number = this.getNumberOfObjects(); // set N (number) to number of Objects in Search Room
          long m = Math.round(number * (1 - p)); // set M for Objects in Search room
          int counter = 0; // counter for objects within radius distance d
  
          for (int i = 0; i < number; i++) { // search through the whole list
              if (rObject.getDistance(this.listOfObjects.elementAt(i), kindOfDistance) < d) {
                  counter = counter + 1; // increase counter if Object(i) is within d from rObject
                  if (counter > m) {
                      break; // prune if we already have more than m objects within d from rObject
                  }
              }
          }
  
          if (counter > m) { // ok, probably not the best way, but works
              rObject.setOutlierStatus(false);
          } else {
              rObject.setOutlierStatus(true);
          }
          /*
           * as we expect to have a radius search for all objects, we store the outlier status in rObject and after the overall search simply ask all objects whether they are thinking they are now outliers or not :-)
           */
      }
  
      /**
       * This method invokes the class method radiusODSearch on all objects in the SearchSpace (associated to this Searchroom via the listOfObjects vektor). radiusODSearch does a brute force distance Outlier test based on the parameters d and p for
       * DB(p,d)-Outliers acc. to Knorr and Ng's approach to unify statistical Outlier tests. The result of the Outliertest is stored in the Objects themselves, e.g. each SearchObject knows its Outlier status (set recently, e.g. by this search) and can
       * tell it by using the SearchObject's class method getOutlierStatus() (see there!)
       * 
       * Added feature: prints progress on STDOUT for each 10% segment (app.) one hash "#" is printed to show progress if brute force should hit complexity boundaries (e.g. with a lot of dimensions as well as lots of objects). This also prints the
       * parameters d and p and N for better understanding
       * 
       */
      public void allRadiusSearch(double d, double p, int kindOfDistance) {
          int n = this.getNumberOfObjects();
          int segment = 10;
          for (int i = 0; i < n; i++) {
              this.radiusODSearch(d, p, this.listOfObjects.elementAt(i), kindOfDistance); // invoke on all objects in list
              if (100 * i / n > segment) {
                  segment = segment + 10;
              }
          }
      }
  
      /**
       * Returns the average distances measures for the objects in the SearchSpace, calculating:
       * 
       * <p>
       * mean distance
       * <p>
       * standard deviation
       * <p>
       * variance
       * 
       * The calculation is time consuming and should only be invoked if the data set is parsed for the first time (to get a feeling on it for statistical choices of parameters p and d for e.g. DB(p,d)-Outliers). It parses the objects matrix upper half
       * to build an array of distances between objects (without doubling and without the distances of objects to themselves) which should be (n^2-n)/2 distances of value.
       * 
       * @return double[3] of mean, variance and standard deviation
       */
      public double[] getAverageDistanceMeasures(int kindOfDistance) {
          double meanDistance = 0; // mean distance between objects in the SearchSpace
          double standardDeviationOfDistance = 0; // standard deviation of objects in the SearchSpace
          double varianceOfDistance = 0; // variance of distance in the SearchSpace
          double distance = 0;
          double sumOfDistance = 0;
          double[] distances = new double[(this.getNumberOfObjects() * this.getNumberOfObjects() - this.getNumberOfObjects()) / 2];
          double counter = 0; // counts number of distances
          SearchObject so; // reference to a searchObject
  
          // first we have to calculate the mean distance between objects
          for (int i = 0; i < this.getNumberOfObjects(); i++) {
              so = this.listOfObjects.elementAt(i);
              for (int j = i; j < this.getNumberOfObjects(); j++) {
                  if (i != j) {
                      distance = so.getDistance(this.listOfObjects.elementAt(j), kindOfDistance);
                      sumOfDistance = sumOfDistance + distance;
                      distances[(int) counter] = distance;
                      counter = counter + 1;
                  }
              }
          }
          meanDistance = sumOfDistance / counter;
  
          // now lets get the variance
          for (int k = 0; k < counter; k++) {
              varianceOfDistance = varianceOfDistance + Math.pow((distances[k] - meanDistance), 2);
          }
          varianceOfDistance = varianceOfDistance / counter;
          standardDeviationOfDistance = Math.sqrt(varianceOfDistance);
          double distMeasures[] = { meanDistance, varianceOfDistance, standardDeviationOfDistance };
          return distMeasures;
      }
  
      /**
       * Returns the average LOF measures for the objects in the SearchSpace, calculating:
       * 
       * <p>
       * mean LOF
       * <p>
       * standard deviation
       * <p>
       * variance
       * 
       * 
       * @return double[3] of mean, variance and standard deviation
       */
      public double[] getAverageLOFMeasures() {
          double meanLOF = 0; // mean LOF of objects in the SearchSpace
          double standardDeviationOfLOF = 0; // standard deviation of Lof of objects in the SearchSpace
          double varianceOfLOF = 0; // variance of LOF in the SearchSpace
          double sumOfLOF = 0; // calculation variable
          SearchObject so; // reference to a searchObject
  
          // first we have to calculate the mean LOF of all objects
          for (int i = 0; i < this.getNumberOfObjects(); i++) {
              so = this.listOfObjects.elementAt(i);
              sumOfLOF += so.getOutlierFactor();
          }
          meanLOF = sumOfLOF / this.getNumberOfObjects();
  
          // now lets get the variance
          for (int k = 0; k < this.getNumberOfObjects(); k++) {
              so = this.listOfObjects.elementAt(k);
              varianceOfLOF = varianceOfLOF + Math.pow((so.getOutlierFactor() - meanLOF), 2);
          }
          varianceOfLOF = varianceOfLOF / this.getNumberOfObjects();
  
          // and the standard deviation
          standardDeviationOfLOF = Math.sqrt(varianceOfLOF);
          double lofMeasures[] = { meanLOF, varianceOfLOF, standardDeviationOfLOF };
          return lofMeasures;
      }
  
      /**
       * This method returns the maximum Outlier Factor of all SearchObjects in the
       * SearchSpace. Attn: Due to initializing, the outlier factors should be greater
       * or equal to zero.
       */
      public double getMaximumOutlierFactor() {
          double maxOutlierFactor = 0;
  