示例#1
0
  /**
   * Utility to facilitate fitting data plotted in JFreeChart Provide data in JFReeChart format
   * (XYSeries), and retrieve univariate function parameters that best fit (using least squares) the
   * data. All data points will be weighted equally.
   *
   * <p>TODO: investigate whether weighting (possibly automatic weighting) can improve accuracy
   *
   * @param data xy series in JFReeChart format
   * @param type one of the Fitter.FunctionType predefined functions
   * @param guess initial guess for the fit. The number and meaning of these parameters depends on
   *     the FunctionType. Implemented: Gaussian: 0: Normalization, 1: Mean 2: Sigma
   * @return array with parameters, whose meaning depends on the FunctionType. Use the function
   *     getXYSeries to retrieve the XYDataset predicted by this fit
   */
  public static double[] fit(XYSeries data, FunctionType type, double[] guess) {

    if (type == FunctionType.NoFit) {
      return null;
    }
    // create the commons math data object from the JFreeChart data object
    final WeightedObservedPoints obs = new WeightedObservedPoints();
    for (int i = 0; i < data.getItemCount(); i++) {
      obs.add(1.0, data.getX(i).doubleValue(), data.getY(i).doubleValue());
    }

    double[] result = null;
    switch (type) {
      case Pol1:
        final PolynomialCurveFitter fitter1 = PolynomialCurveFitter.create(1);
        result = fitter1.fit(obs.toList());
        break;
      case Pol2:
        final PolynomialCurveFitter fitter2 = PolynomialCurveFitter.create(2);
        result = fitter2.fit(obs.toList());
        break;
      case Pol3:
        final PolynomialCurveFitter fitter3 = PolynomialCurveFitter.create(3);
        result = fitter3.fit(obs.toList());
        break;
      case Gaussian:
        final GaussianWithOffsetCurveFitter gf = GaussianWithOffsetCurveFitter.create();
        if (guess != null) {
          gf.withStartPoint(guess);
        }
        result = gf.fit(obs.toList());
    }

    return result;
  }
示例#2
0
 /**
  * Returns the average of the ys in a XYSeries
  *
  * @param data input data
  * @return y average
  */
 public static double getYAvg(XYSeries data) {
   double avg = 0;
   for (int i = 0; i < data.getItemCount(); i++) {
     avg += data.getY(i).doubleValue();
   }
   avg = avg / data.getItemCount();
   return avg;
 }
 /**
  * Returns <code>true</code> if all the y-values for the specified x-value are <code>null</code>
  * and <code>false</code> otherwise.
  *
  * @param x the x-value.
  * @return A boolean.
  */
 protected boolean canPrune(Number x) {
   for (int s = 0; s < this.data.size(); s++) {
     XYSeries series = (XYSeries) this.data.get(s);
     if (series.getY(series.indexOf(x)) != null) {
       return false;
     }
   }
   return true;
 }
 /**
  * Returns the value (the ordianate) of a point given its abscissa.
  *
  * @param abscissa abscissa of the considered point
  * @return return the value of the considered point (returns -1 if there is no points with the
  *     given abscissa in the signal).
  */
 public double getValueOfAbscissa(double abscissa) {
   int isInSeries = data.indexOf(abscissa);
   if (isInSeries >= 0) {
     return data.getY(isInSeries).doubleValue();
   } else {
     System.out.println("There is no point whith the abscissa " + abscissa + " in the signal.\n");
     return -1;
   }
 }
示例#5
0
  /**
   * Finds the x value corresponding to the maximum function value within the range of the provided
   * data set.
   *
   * @param type one of the Fitter.FunctionType predefined functions
   * @param parms parameters describing the function. These need to match the selected function or
   *     an IllegalArgumentEception will be thrown
   * @param data JFreeChart series, used to bracket the range in which the maximum will be found
   * @return x value corresponding to the maximum function value
   */
  public static double getXofMaxY(XYSeries data, FunctionType type, double[] parms) {
    double xAtMax = 0.0;
    double minX = data.getMinX();
    double maxX = data.getMaxX();
    switch (type) {
      case NoFit:
        //  find the position in data with the highest y value
        double highestScore = data.getY(0).doubleValue();
        int highestIndex = 0;
        for (int i = 1; i < data.getItemCount(); i++) {
          double newVal = data.getY(i).doubleValue();
          if (newVal > highestScore) {
            highestScore = newVal;
            highestIndex = i;
          }
        }
        return data.getX(highestIndex).doubleValue();
      case Pol1:
      case Pol2:
      case Pol3:
        checkParms(type, parms);
        PolynomialFunction derivativePolFunction =
            (new PolynomialFunction(parms)).polynomialDerivative();

        final double relativeAccuracy = 1.0e-12;
        final double absoluteAccuracy = 1.0e-8;
        final int maxOrder = 5;
        UnivariateSolver solver =
            new BracketingNthOrderBrentSolver(relativeAccuracy, absoluteAccuracy, maxOrder);
        xAtMax = solver.solve(100, derivativePolFunction, minX, maxX);
        break;
      case Gaussian:
        // for a Gaussian we can take the mean and be sure it is the maximum
        // note that this may be outside our range of X values, but
        // this will be caught by our sanity checks below
        xAtMax = parms[1];
    }

    // sanity checks
    if (xAtMax > maxX) xAtMax = maxX;
    if (xAtMax < minX) xAtMax = minX;

    return xAtMax;
  }
  /**
   * Displays a signal (using the JFreeChart package).
   *
   * @param useChart if set to true, the signal is displaied as a bar chart (this is used for
   *     histograms).
   */
  public void display(boolean useChart) {

    JFreeChart chart;
    int nbSamples = getNbSamples();

    if (useChart) {
      String[] categories = new String[nbSamples];
      for (int i = 0; i < nbSamples; i++) {
        categories[i] = data.getX(i).toString();
      }
      String[] categoryNames = {"Histogram"};
      double[][] categoryData = new double[1][nbSamples];
      for (int i = 0; i < nbSamples; i++) {
        categoryData[0][i] = data.getY(i).doubleValue();
      }

      CategoryDataset categoryDataset =
          DatasetUtilities.createCategoryDataset(categoryNames, categories, categoryData);

      chart =
          ChartFactory.createBarChart(
              "Histogram", // Title
              "Data Value", // X axis label
              "Number of Elements", // Y axis label
              categoryDataset, // dataset
              PlotOrientation.VERTICAL, // orientation
              true, // legends
              true, // tool tips
              true);
    } else {
      XYDataset xyDataSet = new XYSeriesCollection(this.data);
      chart =
          ChartFactory.createXYLineChart(
              "Example Dataset", // Title
              "Abscissa", // X axis label
              "Ordinate", // Y axis label
              xyDataSet, // dataset
              PlotOrientation.VERTICAL, // orientation
              true, // legends
              true, // tool tips
              true); // urls

      XYPlot plot = (XYPlot) chart.getPlot();
      XYItemRenderer r = plot.getRenderer();
      if (r instanceof XYLineAndShapeRenderer) {
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
        renderer.setSeriesShapesVisible(0, true);
        renderer.setSeriesShapesFilled(0, true);
      }
    }

    ChartFrame frame = new ChartFrame("Frame Title", chart);
    frame.setVisible(true);
    frame.setSize(512, 512);
  }
示例#7
0
  /**
   * Calculates a measure for the goodness of fit as defined here:
   * http://en.wikipedia.org/wiki/Coefficient_of_determination R^2 = 1 - (SSres/SStot) where SSres =
   * SUM(i) (yi - fi)^2 end SStot = SUM(i) (yi - yavg)^2
   *
   * @param data input data (raw data that were fitted
   * @param type function type used for fitting
   * @param parms function parameters derived in the fit
   * @return
   */
  public static double getRSquare(XYSeries data, FunctionType type, double[] parms) {

    // calculate SStot
    double yAvg = getYAvg(data);
    double ssTot = 0.0;
    for (int i = 0; i < data.getItemCount(); i++) {
      double y = data.getY(i).doubleValue();
      ssTot += (y - yAvg) * (y - yAvg);
    }

    // calculate SSres
    double ssRes = 0.0;
    for (int i = 0; i < data.getItemCount(); i++) {
      double y = data.getY(i).doubleValue();
      double f = getFunctionValue(data.getX(i).doubleValue(), type, parms);
      ssRes += (y - f) * (y - f);
    }

    return 1.0 - (ssRes / ssTot);
  }
  /**
   * Save the current signal in the file named filename.
   *
   * @param filename name of the file where to store the signal.
   */
  public void save(String filename) {
    int nbSamples = this.getNbSamples();
    String fileContent = "% Signal from Computer Exercise\n";
    fileContent += "#" + nbSamples + "\n";
    fileContent += "\n";
    for (int i = 0; i < nbSamples; i++) {
      fileContent += data.getX(i) + "\t \t" + data.getY(i) + "\n";
    }
    fileContent += "\n";

    try {
      BufferedWriter out = new BufferedWriter(new FileWriter(filename));
      out.write(fileContent);
      out.close();
    } catch (IOException e) {
      System.out.println("Could not save file " + filename + " sorry...\n");
    }
  }
 /**
  * Gives the entered value at the index index. Caution ! No check is performed on the value of the
  * index (this method may throw an outofbound exception).
  *
  * @param index of the point (abscissa, value)
  * @return the corresponding value.
  */
 public double getValueOfIndex(int index) {
   return data.getY(index).doubleValue();
 }