Package jmt.engine.jwat

Source Code of jmt.engine.jwat.VariableNumber

/**   
* Copyright (C) 2006, Laboratorio di Valutazione delle Prestazioni - Politecnico di Milano

* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

package jmt.engine.jwat;

import java.util.ArrayList;

import jmt.engine.jwat.filters.FilterOnVariable;
import jmt.engine.jwat.input.VariableMapping;
import jmt.engine.jwat.workloadAnalysis.exceptions.TrasformException;
import jmt.gui.jwat.JWATConstants;

/**
* Description: This class represents a single variable which contains numerical
* values. It provides statistics information and variable transofrmations and
* sampling operations
*
* @author Brambilla Davide Matr 667986, Fumagalli Claudio 667971
* Created: 1-ago-2006
* Modified: 27-dec-2006
*
*/
public class VariableNumber implements JWATConstants {
  /* Transformation codes */
  public static final short LOGARITHMIC = 0;
  public static final short MINMAX = 1;
  public static final short STDEV = 2;
  public static final short SAMPLING = 3;
  public static final short NONE = 4;
  /* List of observations sorted according to this variable */
  protected Observation[] obsValue;
  /* Original observations value keep as backup for undo sampling transformations */
  protected Observation[] originalValue;
  /* Variable name */
  protected String name;
  /* Index of this variable in the observation */
  protected int nVar;
  /* Type of variable */
  private short varType;
  /* Univariate statistics object */
  private ArrayList<UnivariateStatistics> varUniStatsTransf = new ArrayList<UnivariateStatistics>(); // UnivariateStatistics
  /* Current statistics info */
  private short statsUniCurrentIndexTransf = 0;
  /* List of transformations applied to variable */
  private ArrayList<Integer> listOfTransfs = new ArrayList<Integer>(); //Integer
  /* Dimensions of intervals and intervals */
  private final int intervalGraphSize = 1000;
  private int[] intervalGraph = new int[intervalGraphSize + 1];
  /* Number of observations */
  private int numOss = 0;
  /* Indeicates if it is sampled */
  private boolean sampled = false;
  /*Mapping della varaibile*/
  protected VariableMapping mapping = null;

  /**
   * Constructor, creates new numerical variable.
   * @param valObs
   *            list of observations already sorted by this variable
   * @param vName
   *            variable's name
   * @param pos
   *            variable's positione in observation
   * @param varMapping
   *            mapping object (null)
   */
  public VariableNumber(Observation[] valObs, String vName, int pos, short type, VariableMapping varMapping) {
    name = vName;
    nVar = pos;
    numOss = valObs.length;
    varType = type;
    originalValue = new Observation[valObs.length];
    // Saving observations
    for (int i = 0; i < numOss; i++) {
      originalValue[i] = valObs[i];
    }
    mapping = varMapping;
    obsValue = originalValue;
    // Initializes remaining parameters
    varUniStatsTransf.add(new UnivariateStatistics(obsValue, nVar));
    calculateIntervals();
  }

  public VariableMapping getMapping() {
    return mapping;
  }

  /**
   * Returns Index-th value of the variable
   * @param Index
   *            index of variable's value desired
   * @return value of Index-th value
   * @throws ArrayIndexOutOfBoundsException
   *             throws if Index is < 0 or > numbero of observations
   */
  public double getValue(int Index) throws ArrayIndexOutOfBoundsException {
    if (Index < 0 || Index > obsValue.length) {
      throw new ArrayIndexOutOfBoundsException();
    } else {
      return obsValue[Index].getIndex(nVar);
    }
  }

  /**
   * Returns the index-th value of the var-th variable of the observaion
   * @param Index
   *            index of variable's value desired
   * @param var
   *            variable index
   * @return index-th value of the var-th variable
   * @throws ArrayIndexOutOfBoundsException
   *             throws if Index is < 0 or > numbero of observations or var <
   *             0 or > number of variables ( elements of observation )
   */
  public double getValue(int Index, int var) throws ArrayIndexOutOfBoundsException {
    if (Index < 0 || Index > obsValue.length) {
      throw new ArrayIndexOutOfBoundsException();
    } else {
      return obsValue[Index].getIndex(var);
    }
  }

  /**
   * Returns object holding current univariate variable statistics
   * @return <code>univariateStatistics</code>
   */
  public UnivariateStatistics getUniStats() {
    return varUniStatsTransf.get(statsUniCurrentIndexTransf);
  }

  /**
   * Returns element corresponding to the ind quantile
   * @param ind
   *            quantile
   * @return element corresponding to the ind quantile
   */
  public double getQuantile(int ind) {
    double quant = 0;
    int[] quantili = varUniStatsTransf.get(statsUniCurrentIndexTransf).getQuantili();

    if (this.Size() % 2 == 0) {
      quant = (obsValue[quantili[ind - 1]].getIndex(nVar) + obsValue[quantili[ind - 1] - 1].getIndex(nVar)) / 2;
    } else {
      quant = obsValue[quantili[ind - 1]].getIndex(nVar);
    }
    return quant;
  }

  /**
   * Returns number of observations
   * @return number of observations
   */
  public int Size() {
    return obsValue.length;
  }

  /**
   * Returns variable's index
   * @return variable's index
   */
  public int getIndex() {
    return nVar;
  }

  /**
   * Return variable's name
   * @return variable's name
   */
  public String getName() {
    return name;
  }

  /**
   * Returns variable's type
   * @return variable's type
   */
  public short getType() {
    return varType;
  }

  // This method calculates index of intervals used to plot graphs
  private void calculateIntervals() {
    intervalGraph[0] = 0;
    int posIntG = 1;
    double range = varUniStatsTransf.get(statsUniCurrentIndexTransf).getRangeValue();
    double min = varUniStatsTransf.get(statsUniCurrentIndexTransf).getMinValue();
    int nInsG = 0;

    for (int i = 0; i < numOss; i++) {
      // Graph interval ( 1000 intervals )
      if (obsValue[i].getIndex(nVar) <= range * (0.001 * posIntG) + min || obsValue[i].getIndex(nVar) > range + min) {
        nInsG++;
      } else {
        if (nInsG == 0) {
          intervalGraph[posIntG] = intervalGraph[posIntG - 1];
        } else {
          intervalGraph[posIntG] = i - 1;
        }
        posIntG++;
        nInsG = 0;
        i--;
      }
      if (posIntG == 1001) {
        break;
      }
    }
    for (; posIntG < 1001; posIntG++) {
      intervalGraph[posIntG] = obsValue.length - 1;
    }
    intervalGraph[1000] = obsValue.length - 1;
  }

  /** ******* TRANSFORMATIONS SECTION ********* */

  /**
   * Perform one of the transformations
   * @param index
   *            transformation to apply
   * @throws TrasformException
   *             throws if it isn't possible to apply transformation
   */
  public void doTransformation(int index) throws TrasformException {
    // Checks if this is a numeric variable otherwise no transformation
    if (varType == NUMERIC) {
      switch (index) {
        case LOGARITHMIC:
          setLogTransformation();
          break;
        case STDEV:
          setStandardTransformation();
          break;
        case MINMAX:
          setMaxMinTransformation();
          break;
      }
    } else {
      throw new TrasformException("This in not a NUMERIC variable");
    }
    calculateIntervals();
  }

  /**
   * Performs logarithmic transformation 10 based
   * @throws TrasformException
   *             if exists al least one value <= 0
   */
  private void setLogTransformation() throws TrasformException {
    if (isLogTrasformable()) {
      for (int i = 0; i < numOss; i++) {
        obsValue[i].setIndex(nVar, Math.log(obsValue[i].getIndex(nVar)) / Math.log(10));
      }
      addTrasf(LOGARITHMIC);
    } else {
      throw new TrasformException("Logarithmic transformation not allowed");
    }
  }

  /**
   * Performs min/max transformation (value - minimum) / (maximum - minimum)
   */
  private void setMaxMinTransformation() {
    for (int i = 0; i < numOss; i++) {
      obsValue[i].setIndex(nVar, (obsValue[i].getIndex(nVar) - varUniStatsTransf.get(statsUniCurrentIndexTransf).getMinValue())
          / (varUniStatsTransf.get(statsUniCurrentIndexTransf).getRangeValue()));
    }
    addTrasf(MINMAX);
  }

  /**
   * Performs the following transformation (value - mean) / (standard deviation)
   */
  private void setStandardTransformation() {
    for (int i = 0; i < numOss; i++) {
      obsValue[i].setIndex(nVar, (obsValue[i].getIndex(nVar) - varUniStatsTransf.get(statsUniCurrentIndexTransf).getMean())
          / varUniStatsTransf.get(statsUniCurrentIndexTransf).getDevStd());
    }
    addTrasf(STDEV);
  }

  /**
   * Adds transformations info to variable
   * @param transf
   *            transformation applied
   */
  private void addTrasf(short transf) {
    listOfTransfs.add(new Integer(transf));
    // Stores new statistics after transformation applied
    varUniStatsTransf.add(new UnivariateStatistics(obsValue, nVar));
    statsUniCurrentIndexTransf += 1;
  }

  /**
   * Undo last transformation applied to variable if exists
   */
  public boolean undoLastTrasf() {
    if (listOfTransfs.size() > 0) {
      switch (listOfTransfs.get(listOfTransfs.size() - 1).intValue()) {
        case LOGARITHMIC:
          undoLogTrasformation();
          calculateIntervals();
          break;
        case STDEV:
          undoStandardTransformation();
          calculateIntervals();
          break;
        case MINMAX:
          undoMaxMinTransformation();
          calculateIntervals();
          break;
        case SAMPLING:
          undoSampling();
          undoLastTrasf();
          calculateIntervals();
          return true;
      }
    }
    return false;
  }

  /**
   * Undo a logarithmic transformation
   */
  private void undoLogTrasformation() {
    // Removes last Log transformation
    for (int i = 0; i < numOss; i++) {
      obsValue[i].setIndex(nVar, Math.pow(10, obsValue[i].getIndex(nVar)));
    }
    listOfTransfs.remove(listOfTransfs.size() - 1);
    // Removes associated statistics
    varUniStatsTransf.remove(varUniStatsTransf.size() - 1);
    statsUniCurrentIndexTransf -= 1;
  }

  /**
   * Undo min/max transformation (value - minimum) / (maximum - minimum)
   */
  private void undoMaxMinTransformation() {
    double oldMin = varUniStatsTransf.get(varUniStatsTransf.size() - 2).getMinValue();
    double oldMax = varUniStatsTransf.get(varUniStatsTransf.size() - 2).getMaxValue();

    for (int i = 0; i < numOss; i++) {
      obsValue[i].setIndex(nVar, obsValue[i].getIndex(nVar) * (oldMax - oldMin) + oldMin);
    }
    listOfTransfs.remove(listOfTransfs.size() - 1);
    // Removes associated statistics
    varUniStatsTransf.remove(varUniStatsTransf.size() - 1);
    statsUniCurrentIndexTransf -= 1;
  }

  /**
   * Undo the following transformation (value - mean) / (standard deviation)
   */
  private void undoStandardTransformation() {
    double oldDevStd = varUniStatsTransf.get(varUniStatsTransf.size() - 2).getDevStd();
    double oldMean = varUniStatsTransf.get(varUniStatsTransf.size() - 2).getMean();

    for (int i = 0; i < numOss; i++) {
      obsValue[i].setIndex(nVar, (obsValue[i].getIndex(nVar) * oldDevStd) + oldMean);
    }
    listOfTransfs.remove(listOfTransfs.size() - 1);
    // Removes associated statistics
    varUniStatsTransf.remove(varUniStatsTransf.size() - 1);
    statsUniCurrentIndexTransf -= 1;
  }

  /**
   * Check if logarithmic transformation is applyable to variable
   * @return If logarithm is applyable
   */
  private boolean isLogTrasformable() {
    return ((obsValue[0].getIndex(nVar) > 0));
  }

  /**
   * Returns names of transformations
   * @return Array of transformation's names
   */
  public static String[] getTrasfName() {
    String[] ret = { "Logarithmic", "MinMax", "StandardDev" };
    return ret;
  }

  /**
   *
   * @return
   */
  public String getTrasfStr() {
    String[] trasfName = { "Log", "Mm", "SD" };
    String ret = "";
    int j = 0;
    int i;

    for (i = 0; i < listOfTransfs.size(); i++) {
      if (listOfTransfs.get(i).intValue() != SAMPLING) {
        ret += trasfName[listOfTransfs.get(i).intValue()] + "(";
        j++; //D
      }
    }
    ret += "X";
    for (i = 0; i < j; i++) {
      ret += ")";
    }
    return ret;
  }

  /** ******** METHODS FOR PLOT ********** */
  // Indica la variabile compagna nel plot del grafico
  private int val;
  // Valore di start e end intervallo di visualizzazione variabile
  private int PosS;
  private int PosE;
  // Valori min e max della variabile gemella nel grafico
  private double minV;
  private double maxV;

  public double getDimInt() {
    return varUniStatsTransf.get(statsUniCurrentIndexTransf).getRangeValue() / 1000;
  }

  public int getNumeroOssPerInt() {
    return PosE - PosS;
  }

  public int getStartInt(int j) {
    return intervalGraph[(j - 1) * 10];
  }

  public int getEndInt(int j) {
    return intervalGraph[j * 10];
  }

  /**
   * Restituisce il valore relativo all'indice pos dell'array degli intervalli
   * @param Index
   *            Indice dell'array degli intervalli
   * @return Restituzione del valore realtivo ad uno limite dell'intervallo
   */
  public double getIntValue(int Index) {

    return (obsValue[numOss - 1].getIndex(nVar) - obsValue[0].getIndex(nVar)) * 0.01 * Index + obsValue[0].getIndex(nVar);
  }

  /**
   * Restituisce il valore relativo all'indice pos dell'array degli intervalli
   * @param Index
   *            Indice dell'array degli intervalli
   * @return Restituzione del valore realtivo ad uno limite dell'intervallo
   */
  public double getIntValueG(int Index) {
    return (obsValue[numOss - 1].getIndex(nVar) - obsValue[0].getIndex(nVar)) * 0.001 * Index + obsValue[0].getIndex(nVar);

  }

  /**
   * Impostazione per la ricerca dei punti all'interno di un intervallo per il plot
   * @param min
   *            Limite inferiore dell'intervallo come indice dell'array degli intervalli
   * @param max
   *            Limite superiore dell'intervallo come indice dell'array degli intervalli
   * @param minv
   *            Limite inferiore come valore della variabile compagna dello scatter plot
   * @param maxv
   *            Limite superiore come valore della variabile compagna dello scatter plot
   * @param n
   *            Posizone della variabile compagna nello scatter plot nelle osservazioni
   */
  public void setRangeIntervallo(int min, int max, double minv, double maxv, int n) {
    // Settaggio delle informazioni per restituizione osservazioni da plottare
    minV = minv;
    maxV = maxv;
    val = n;
    PosS = intervalGraph[min];
    PosE = intervalGraph[max];
  }

  /**
   * Restituisce il prossimo indice se esiste dell'osservazione da plottare che corrisponde alle restrizioni
   * impostate con setRangeQuantili
   *
   * @return indice che soddisfa le condizioni
   */
  public int getNextInt() throws Exception {
    while (obsValue[PosS].getIndex(val) < minV || obsValue[PosS].getIndex(val) > maxV) {
      PosS++;
      if (PosS > PosE) {
        throw new Exception();
      }
    }
    if (PosS > PosE) {
      throw new Exception();
    }
    return PosS++;

  }

  /**
   * Restituisce il range tra posizioni di intervalli
   * @param min
   *            posizone minima dell'intervallo
   * @param max
   *            posizone massima dell'intervallo
   * @return range tra i due intervalli
   */
  public double getIntRange(int min, int max) {
    return (obsValue[numOss - 1].getIndex(nVar) - obsValue[0].getIndex(nVar)) * 0.01 * (max - min);
  }

  /**
   * Restituisce il range tra posizioni di intervalli
   * @param min
   *            posizone minima dell'intervallo
   * @param max
   *            posizone massima dell'intervallo
   * @return range tra i due intervalli
   */
  public double getIntRangeG(int min, int max) {
    return (obsValue[numOss - 1].getIndex(nVar) - obsValue[0].getIndex(nVar)) * 0.001 * (max - min);
  }

  /**
   * NON UTILIZZATO ERRATO
   * Restituisce l'array degli intervalli
   * @return vettore contenente le posizioni delle variabili che delimitano gli intervalli
   */
  /*public int[] getInterval() {
    return interval;
  }*/

  public int getIndex(double value) {
    int i = 0;
    for (i = 0; i < intervalGraph.length; i++) {
      if (value <= obsValue[intervalGraph[i]].getIndex(nVar)) {
        return i;
      }
    }
    return i - 1;
  }

  public int getIndexMin(double value) {
    int i = 0;
    for (i = 0; i < intervalGraph.length; i++) {
      if (value <= obsValue[intervalGraph[i]].getIndex(nVar)) {
        return i;
      }
    }
    return i - 1;
  }

  public int getIndexMax(double value) {
    int i = 0;
    for (i = 0; i < intervalGraph.length; i++) {
      if (value < obsValue[intervalGraph[i]].getIndex(nVar)) {
        return i;
      }
    }
    return i - 1;
  }

  public int[] getInterval1000() {
    return intervalGraph;
  }

  /**
   * Applies filter to variable
   *
   * @param filter
   * @return
   */
  public int applySampling(FilterOnVariable filter) {
    int j = 1;

    sampled = true;
    listOfTransfs.add(new Integer(SAMPLING));
    ArrayList<Observation> temp = new ArrayList<Observation>(); //Observation
    for (int i = 0; i < obsValue.length; i++) {
      if (filter.isMatching(obsValue[i], i)) {
        temp.add(obsValue[i]);
        obsValue[i].setID(j++);
      } else {
        obsValue[i].setValid(false);
      }
    }
    obsValue = new Observation[temp.size()];
    temp.toArray(obsValue);

    temp.clear();
    temp = null;

    numOss = obsValue.length;
    varUniStatsTransf.add(new UnivariateStatistics(obsValue, nVar));
    statsUniCurrentIndexTransf += 1;
    calculateIntervals();
    return numOss;
  }

  /**
   * Sync variable respect with another variable sampling
   *
   * @param size
   */
  public void updateOnSampling(int size) {
    listOfTransfs.add(new Integer(SAMPLING));
    int i = 0;
    Observation[] temp = new Observation[size];
    // obsValue = new Observation[size];
    for (Observation element : obsValue) {
      if (element.isValid()) {
        temp[i++] = element;
      }
    }
    obsValue = temp;
    temp = null;

    numOss = obsValue.length;
    varUniStatsTransf.add(new UnivariateStatistics(obsValue, nVar));
    statsUniCurrentIndexTransf += 1;
    calculateIntervals();
  }

  public void undoSampling() {
    resetSampling();
    resetValidity();
  }

  private void resetValidity() {
    for (int i = 0; i < originalValue.length; i++) {
      originalValue[i].setValid(true);
      originalValue[i].setID(i);
    }
  }

  public void resetSampling() {
    sampled = false;
    while (listOfTransfs.size() > 0 && listOfTransfs.get(listOfTransfs.size() - 1).intValue() != SAMPLING) {
      undoLastTrasf();
    }
    obsValue = originalValue;
    numOss = obsValue.length;
    listOfTransfs.remove(listOfTransfs.size() - 1);
    varUniStatsTransf.remove(statsUniCurrentIndexTransf);
    statsUniCurrentIndexTransf -= 1;
    // Removes all others SAMPLING in array
    int p = listOfTransfs.size() - 1;
    for (int i = p; i >= 0; i--) {
      if (listOfTransfs.get(i).intValue() == SAMPLING) {
        listOfTransfs.remove(i);
        varUniStatsTransf.remove(i + 1);
        statsUniCurrentIndexTransf -= 1;
      }
    }
    calculateIntervals();
  }

  public boolean isSampled() {
    return sampled;
  }

  public Observation[] getCurObs() {
    return obsValue;
  }

  public int getObsID(int Index) {
    if (Index < 0 || Index > obsValue.length) {
      throw new ArrayIndexOutOfBoundsException();
    } else {
      return obsValue[Index].getID();
    }
  }

  //Update 28/10/2006: + aggiunta funzione per recupero numero trasformazioni esistenti per la variabile
  //           + spostamento reset della validity a ID in matrixOsservazioni
  //           + aggiunte funzioni separate per operazione trasformazione variabili per clustering
  //           ? controllare con Fuma se le statistiche sono necessarie dopo la trasf altrimenti non si ricalcolano
  public int getNumOfTransf() {
    return listOfTransfs.size();
  }

  /* These two functions are used only to transform and antitransform variable
   * for the clutering operation.As you can see aonly STDEV and MINMAX tranformations
   * are allowed and no control on variable's type are performed.
   */
  public void doClusteringTrasformation(int index) {
    switch (index) {
      case STDEV:
        setStandardTransformation();
        break;
      case MINMAX:
        setMaxMinTransformation();
        break;
      default:
    }
  }

  public void undoClueringTrasformation() {
    switch (listOfTransfs.get(listOfTransfs.size() - 1).intValue()) {
      case STDEV:
        undoStandardTransformation();
        break;
      case MINMAX:
        undoMaxMinTransformation();
        break;
    }
  }
}
TOP

Related Classes of jmt.engine.jwat.VariableNumber

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.