/** * 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; }
/** * Given a JFreeChart dataset and a commons math function, return a JFreeChart dataset in which * the original x values are now accompanied by the y values predicted by the function * * @param data input JFreeChart 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 * @return JFreeChart dataset with original x values and fitted y values. */ public static XYSeries getFittedSeries(XYSeries data, FunctionType type, double[] parms) { XYSeries result = new XYSeries(data.getItemCount() * 10); double minRange = data.getMinX(); double maxRange = data.getMaxX(); double xStep = (maxRange - minRange) / (data.getItemCount() * 10); switch (type) { case NoFit: { try { XYSeries resCopy = data.createCopy(0, data.getItemCount() - 1); return resCopy; } catch (CloneNotSupportedException ex) { return null; } } case Pol1: case Pol2: case Pol3: checkParms(type, parms); PolynomialFunction polFunction = new PolynomialFunction(parms); for (int i = 0; i < data.getItemCount() * 10; i++) { double x = minRange + i * xStep; double y = polFunction.value(x); result.add(x, y); } break; case Gaussian: checkParms(type, parms); Gaussian.Parametric gf = new Gaussian.Parametric(); for (int i = 0; i < data.getItemCount() * 10; i++) { double x = minRange + i * xStep; double[] gparms = new double[3]; System.arraycopy(parms, 0, gparms, 0, 3); double y = gf.value(x, gparms) + parms[3]; result.add(x, y); } break; } return result; }