Example usage for org.apache.commons.math3.fitting PolynomialCurveFitter create

List of usage examples for org.apache.commons.math3.fitting PolynomialCurveFitter create

Introduction

In this page you can find the example usage for org.apache.commons.math3.fitting PolynomialCurveFitter create.

Prototype

public static PolynomialCurveFitter create(int degree) 

Source Link

Document

Creates a default curve fitter.

Usage

From source file:com.cloudera.hts.utils.math.PolyFit.java

public static void main(String[] args) {

    double[] x = { -5.0, -4.0, -3.0, -2.0, 0, 2, 3, 4 };
    double[] y = { 21, 13, 7, 3, 1, 7, 13, 21 };

    WeightedObservedPoints obs = new WeightedObservedPoints();

    // Add points here; for instance,
    int i = 0;/*from  w w  w.j a  va  2  s .c  o  m*/
    for (double xc : x) {

        WeightedObservedPoint point = new WeightedObservedPoint(xc, y[i], 1.0);
        obs.add(xc, y[i]);

        System.out.println(xc + " " + y[i]);

        i++;

    }

    // Instantiate a third-degree polynomial fitter.
    PolynomialCurveFitter fitter = PolynomialCurveFitter.create(2);

    // Retrieve fitted parameters (coefficients of the polynomial function).
    final double[] coeff = fitter.fit(obs.toList());

    System.out.println(Arrays.toString(coeff));

}

From source file:net.liuxuan.temp.mathtest.java

public static void main(String[] args) {

    final CurveFitter fitter = new CurveFitter(new LevenbergMarquardtOptimizer());
    fitter.addObservedPoint(-1.00, 2.021170021833143);
    fitter.addObservedPoint(-0.99, 2.221135431136975);
    fitter.addObservedPoint(-0.98, 2.09985277659314);
    fitter.addObservedPoint(-0.97, 2.0211192647627025);
    // ... Lots of lines omitted ...
    fitter.addObservedPoint(0.99, -2.4345814727089854);

    // The degree of the polynomial is deduced from the length of the array containing
    // the initial guess for the coefficients of the polynomial.
    final double[] init = { 12.9, -3.4, 2.1 }; // 12.9 - 3.4 x + 2.1 x^2

    // Compute optimal coefficients.
    final double[] best = fitter.fit(new PolynomialFunction.Parametric(), init);

    // Construct the polynomial that best fits the data.
    final PolynomialFunction fitted = new PolynomialFunction(best);
    System.out.println(fitted.value(-0.995));
    ;/*w w w .j  a  v  a  2s .c  o m*/
    System.out.println(fitted.value(0.995));
    ;
    System.out.println(fitted.toString());
    ;
    System.out.println("=============================================================");
    PolynomialCurveFitter pcf = PolynomialCurveFitter.create(3);
    WeightedObservedPoints s;
    List<WeightedObservedPoint> points = new ArrayList<WeightedObservedPoint>();
    points.add(new WeightedObservedPoint(1, -1.00, 2.021170021833143));
    points.add(new WeightedObservedPoint(1, -0.99, 2.221135431136975));
    points.add(new WeightedObservedPoint(1, -0.98, 2.09985277659314));
    points.add(new WeightedObservedPoint(1, -0.97, 2.0211192647627025));
    points.add(new WeightedObservedPoint(1, 0.99, 2.4345814727089854));
    double a[] = pcf.fit(points);
    for (int i = 0; i < a.length; i++) {
        double d = a[i];
        System.out.println(d);
    }
    System.out.println(compute(a, -0.995));
    System.out.println(compute(a, 0.99));
    System.out.println(compute(a, 0.995));

}

From source file:cn.edu.xmu.tidems.control.support.TideMSUtil.java

public static double[] polynomialFit(final double[] x, final double[] y, final int order) {

    if ((x == null) || (x.length == 0) || (y == null) || (y.length == 0)) {
        throw new IllegalArgumentException("Input arrays x/y  can't be null or empty.");
    }/*from   ww w .ja  v a2 s  .co  m*/
    if (x.length != y.length) {
        throw new IllegalArgumentException("The length of arrays x, y must be equal.");
    }
    if (order < 1) {
        throw new IllegalArgumentException("Order must be greater than 0.");
    }
    if (x.length <= order) {
        throw new IllegalArgumentException("The length of array must be greater than order.");
    }
    final WeightedObservedPoints obs = new WeightedObservedPoints();
    for (int i = 0; i < x.length; i++) {
        obs.add(x[i], y[i]);
    }
    final PolynomialCurveFitter fitter = PolynomialCurveFitter.create(order);
    final double[] coeff = fitter.fit(obs.toList());
    return coeff;
}

From source file:eu.tango.energymodeller.energypredictor.CpuOnlyPolynomialEnergyPredictor.java

/**
 * This calculates the mathematical function that predicts the power
 * consumption given the cpu utilisation.
 *
 * @param host The host to get the function for
 * @return The mathematical function that predicts the power consumption
 * given the cpu utilisation.//from w w w. j a v a 2s  . c o  m
 */
private PredictorFunction<PolynomialFunction> retrieveModel(Host host) {
    PredictorFunction<PolynomialFunction> answer;
    if (modelCache.containsKey(host)) {
        /**
         * A small cache avoids recalculating the regression so often.
         */
        return modelCache.get(host);
    }
    WeightedObservedPoints points = new WeightedObservedPoints();
    for (HostEnergyCalibrationData data : host.getCalibrationData()) {
        points.add(data.getCpuUsage(), data.getWattsUsed());
    }
    PolynomialCurveFitter fitter = PolynomialCurveFitter.create(2);
    final double[] best = fitter.fit(points.toList());
    PolynomialFunction function = new PolynomialFunction(best);
    double sse = getSumOfSquareError(function, points.toList());
    double rmse = getRootMeanSquareError(sse, points.toList().size());
    answer = new PredictorFunction<>(function, sse, rmse);
    modelCache.put(host, answer);
    return answer;
}

From source file:eu.tango.energymodeller.energypredictor.CpuAndAcceleratorEnergyPredictor.java

/**
 * This calculates the mathematical function that predicts the power
 * consumption given the cpu utilisation.
 *
 * @param host The host to get the function for
 * @return The mathematical function that predicts the power consumption
 * given the cpu utilisation.// www .j  a  va 2 s.co m
 */
private PredictorFunction<PolynomialFunction> retrieveCpuModel(Host host) {
    PredictorFunction<PolynomialFunction> answer;
    if (modelCache.containsKey(host)) {
        /**
         * A small cache avoids recalculating the regression so often.
         */
        return modelCache.get(host);
    }
    WeightedObservedPoints points = new WeightedObservedPoints();
    for (HostEnergyCalibrationData data : host.getCalibrationData()) {
        points.add(data.getCpuUsage(), data.getWattsUsed());
    }
    PolynomialCurveFitter fitter = PolynomialCurveFitter.create(2);
    final double[] best = fitter.fit(points.toList());
    PolynomialFunction function = new PolynomialFunction(best);
    double sse = getSumOfSquareError(function, points.toList());
    double rmse = getRootMeanSquareError(sse, points.toList().size());
    answer = new PredictorFunction<>(function, sse, rmse);
    modelCache.put(host, answer);
    return answer;
}

From source file:ffx.utilities.BlockAverager.java

/**
 * Compute the statistical uncertainty of G in each histogram bin and
 * overall. Loop over increasing values of block size. For each, calculate
 * the block means and their standard deviation. Then limit(blockStdErr,
 * blockSize to entireTraj) == trajStdErr.
 *
 * @return aggregate standard error of the total free energy change
 *///from  w ww  .  j av a2s  . co  m
public double[] computeBinUncertainties() {
    double[][] sems = new double[numBins][maxBlockSize + 1];
    BinDev[][] binStDevs = new BinDev[numBins][maxBlockSize + 1];

    List<WeightedObservedPoint>[] obsDev = new ArrayList[numBins];
    List<WeightedObservedPoint>[] obsErr = new ArrayList[numBins];

    for (int binIndex = 0; binIndex < numBins; binIndex++) {
        logger.info(format(" Computing stdError for bin %d...", binIndex));
        obsDev[binIndex] = new ArrayList<>();
        obsErr[binIndex] = new ArrayList<>();
        for (int blockSize = 1; blockSize <= maxBlockSize; blockSize += blockSizeStep) {
            int numBlocks = (int) Math.floor(numObs / blockSize);
            binStDevs[binIndex][blockSize] = new BinDev(binIndex, blockSize);
            sems[binIndex][blockSize] = binStDevs[binIndex][blockSize].stdev / Math.sqrt(numBlocks - 1);
            obsDev[binIndex]
                    .add(new WeightedObservedPoint(1.0, blockSize, binStDevs[binIndex][blockSize].stdev));
            obsErr[binIndex].add(new WeightedObservedPoint(1.0, blockSize, sems[binIndex][blockSize]));
            if (TEST) {
                logger.info(format("  bin,blockSize,stdev,sem: %d %d %.6g %.6g", binIndex, blockSize,
                        binStDevs[binIndex][blockSize].stdev, sems[binIndex][blockSize]));
            }
        }
    }

    // Fit a function to (blockSize v. stdError) and extrapolate to blockSize == entire trajectory.
    // This is our correlation-corrected estimate of the std error for this lambda bin.
    stdError = new double[numBins];
    for (int binIndex = 0; binIndex < numBins; binIndex++) {
        logger.info(format("\n Bin %d : fitting & extrapolating blockSize v. stdError", binIndex));
        if (fitter == FITTER.POLYNOMIAL) {
            // Fit a polynomial (shitty).
            double[] coeffsPoly = PolynomialCurveFitter.create(polyDegree).fit(obsErr[binIndex]);
            PolynomialFunction poly = new PolynomialFunction(coeffsPoly);
            logger.info(format("    Poly %d:   %12.10g     %s", polyDegree, poly.value(numObs),
                    Arrays.toString(poly.getCoefficients())));
        } else if (fitter == FITTER.POWER) {
            // Fit a power function (better).
            double[] coeffsPow = powerFit(obsErr[binIndex]);
            double powerExtrapolated = coeffsPow[0] * pow(numObs, coeffsPow[1]);
            logger.info(format("    Power:     %12.10g     %s", powerExtrapolated, Arrays.toString(coeffsPow)));
        }
        // Fit a log function (best).
        double[] logCoeffs = logFit(obsErr[binIndex]);
        double logExtrap = logCoeffs[0] + logCoeffs[1] * log(numObs);
        logger.info(format("    Log sem:   %12.10g     Residual: %12.10g     Coeffs: %6.4f, %6.4f \n",
                logExtrap, logCoeffs[0], logCoeffs[1]));

        // Also try fitting a linear function for the case of uncorrelated or extremely well-converged data.
        double[] linearCoef = linearFit(obsErr[binIndex]);
        double linearExtrap = linearCoef[0] + linearCoef[1] * numObs;
        logger.info(format("    Lin. sem:  %12.10g     Residual: %12.10g     Coeffs: %6.4f, %6.4f \n",
                linearExtrap, linearCoef[0], linearCoef[1]));

        stdError[binIndex] = logExtrap;
    }
    return stdError;
}

From source file:io.warp10.continuum.gts.GTSHelper.java

/**
 * Compute local weighted regression at given tick
 * //from   w  ww  .j  ava  2s . co m
 * @param gts      : input GTS
 * @param idx      : considered as index of the first non-null neighbour at the right
 * @param tick     : tick at which lowess is achieved
 * @param q        : bandwitdth, i.e. number of nearest neighbours to consider
 * @param d        : degree of polynomial fit
 * @param weights  : optional array that store the weights
 * @param rho      : optional array that store the robustness weights
 * @param beta     : optional array that store the regression parameters
 * @param reversed : should idx be considered to be at the left instead
 */
public static double pointwise_lowess(GeoTimeSerie gts, int idx, long tick, int q, int p, double[] weights,
        double[] rho, double[] beta, boolean reversed) throws WarpScriptException {

    if (null != weights && q > weights.length || (null != rho && gts.values > rho.length)
            || (null != beta && p + 1 > beta.length)) {
        throw new WarpScriptException("Incoherent array lengths as input of pointwise_lowess");
    }
    /**
     * FIXME(JCV):
     * q = 3: 22 errors out of 100 points (at these points the value is almost equal to the value at q=2)
     * q = 4: 2 errors out of 100 points (at these points the value is almost equal to the value at q=3)
     * other q: 0 error
     * But it's not meant to be used with low value of q anyway.
     */

    //
    // Determine the 'q' closest values
    // We use two indices i and j for that, i moves forward, j moves backward from idx, until we
    // identified 'q' values (or 'n' if q > n)
    //

    int i = idx;
    int j = idx - 1;

    if (reversed) {
        i += 1;
        j += 1;
    }

    int count = 0;

    while (count < q) {
        long idist = Long.MAX_VALUE;
        long jdist = Long.MAX_VALUE;

        if (i < gts.values) {
            idist = Math.abs(tickAtIndex(gts, i) - tick);
        }

        if (j >= 0) {
            jdist = Math.abs(tickAtIndex(gts, j) - tick);
        }

        // If we exhausted the possible values
        if (Long.MAX_VALUE == idist && Long.MAX_VALUE == jdist) {
            break;
        }

        if (idist < jdist) {
            i++;
        } else {
            j--;
        }

        count++;
    }

    // The 'q' nearest values are between indices j and i (excluded)

    // Compute the maximum distance from 'tick'

    double maxdist = Math.max(j < -1 ? 0.0D : Math.abs(tickAtIndex(gts, j + 1) - tick),
            i <= 0 ? 0.0D : Math.abs(tickAtIndex(gts, i - 1) - tick));

    // Adjust maxdist if q > gtq.values

    if (q > gts.values) {
        maxdist = (maxdist * q) / gts.values;
    }

    // Compute the weights

    // Reset the weights array
    if (null == weights) {
        weights = new double[q];
    } else {
        Arrays.fill(weights, 0.0D);
    }

    int widx = 0;

    double wsum = 0.0D;

    for (int k = j + 1; k < i; k++) {
        if (0 == maxdist) {
            weights[widx] = 1.0D;
        } else {
            double u = Math.abs(gts.ticks[k] - tick) / maxdist;

            if (u >= 1.0) {
                weights[widx] = 0.0D;
            } else {

                weights[widx] = 1.0D - u * u * u;

                double rho_ = 1.0D;
                if (null != rho) {
                    // In some cases, "all rho are equal to 0.0", which should be translated to "all rho are equal" (or else there is no regression at all)
                    // So if rho equals zero we set it to a certain value which is low enough not to bias the result in case all rho are not all equals.
                    rho_ = 0.0D != rho[k] ? rho[k] : 0.000001D;
                }
                weights[widx] = rho_ * weights[widx] * weights[widx] * weights[widx];
            }
        }
        wsum += weights[widx];
        widx++;
    }

    // Regression parameters
    if (null == beta) {
        beta = new double[p + 1];
    }

    //
    // Linear polynomial fit
    //

    if (1 == p) {

        //
        // Compute weighted centroids for ticks and values
        //

        widx = 0;

        double ctick = 0.0D;
        double cvalue = 0.0D;

        for (int k = j + 1; k < i; k++) {
            ctick = ctick + weights[widx] * gts.ticks[k];
            cvalue = cvalue + weights[widx] * ((Number) valueAtIndex(gts, k)).doubleValue();
            widx++;
        }

        ctick = ctick / wsum;
        cvalue = cvalue / wsum;

        //
        // Compute weighted covariance and variance
        //

        double covar = 0.0D;
        double var = 0.0D;

        widx = 0;

        for (int k = j + 1; k < i; k++) {
            covar = covar + weights[widx] * (gts.ticks[k] - ctick)
                    * (((Number) valueAtIndex(gts, k)).doubleValue() - cvalue);
            var = var + weights[widx] * (gts.ticks[k] - ctick) * (gts.ticks[k] - ctick);
            widx++;
        }

        covar = covar / wsum;
        var = var / wsum;

        //
        // Compute regression parameters
        //

        beta[1] = 0 == var ? 0.0D : covar / var;
        beta[0] = cvalue - ctick * beta[1];

    } else {

        //
        // Quadratic-or-more polynomial fit
        //

        // filling the container with the points

        List<WeightedObservedPoint> observations = new ArrayList<WeightedObservedPoint>();

        widx = 0;
        for (int k = j + 1; k < i; k++) {
            WeightedObservedPoint point = new WeightedObservedPoint(weights[widx], (double) gts.ticks[k],
                    ((Number) valueAtIndex(gts, k)).doubleValue());
            observations.add(point);
            widx++;
        }

        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(p);
        beta = fitter.fit(observations);
        observations.clear();

    }

    //
    // Compute value at 'tick'
    //

    double estimated = beta[0];
    double tmp = 1.0D;
    for (int u = 1; u < p + 1; u++) {
        tmp *= tick;
        estimated += tmp * beta[u];
    }

    return estimated;
}

From source file:org.akvo.caddisfly.sensor.colorimetry.strip.calibration.CalibrationCard.java

@NonNull
private static Mat do1D_3DCorrection(@NonNull Mat imgMat, @Nullable CalibrationData calData)
        throws CalibrationException {

    if (calData == null) {
        throw new CalibrationException("no calibration data.");
    }/*  www  .  j ava 2  s  .  c o m*/

    final WeightedObservedPoints obsL = new WeightedObservedPoints();
    final WeightedObservedPoints obsA = new WeightedObservedPoints();
    final WeightedObservedPoints obsB = new WeightedObservedPoints();

    Map<String, double[]> calResultIllumination = new HashMap<>();
    // iterate over all patches
    try {
        for (String label : calData.getCalValues().keySet()) {
            CalibrationData.CalValue cal = calData.getCalValues().get(label);
            CalibrationData.Location loc = calData.getLocations().get(label);
            float[] LAB_color = measurePatch(imgMat, loc.x, loc.y, calData); // measure patch color
            obsL.add(LAB_color[0], cal.getL());
            obsA.add(LAB_color[1], cal.getA());
            obsB.add(LAB_color[2], cal.getB());
            calResultIllumination.put(label, new double[] { LAB_color[0], LAB_color[1], LAB_color[2] });
        }
    } catch (Exception e) {
        throw new CalibrationException("1D calibration: error iterating over all patches.", e);
    }

    // Instantiate a second-degree polynomial fitter.
    final PolynomialCurveFitter fitter = PolynomialCurveFitter.create(2);

    // Retrieve fitted parameters (coefficients of the polynomial function).
    // order of coefficients is (c + bx + ax^2), so [c,b,a]
    try {
        final double[] coefficientL = fitter.fit(obsL.toList());
        final double[] coefficientA = fitter.fit(obsA.toList());
        final double[] coefficientB = fitter.fit(obsB.toList());

        double[] valIllumination;
        double L_orig, A_orig, B_orig, L_new, A_new, B_new;

        // transform patch values using the 1d calibration results
        Map<String, double[]> calResult1D = new HashMap<>();
        for (String label : calData.getCalValues().keySet()) {
            valIllumination = calResultIllumination.get(label);

            L_orig = valIllumination[0];
            A_orig = valIllumination[1];
            B_orig = valIllumination[2];

            L_new = coefficientL[2] * L_orig * L_orig + coefficientL[1] * L_orig + coefficientL[0];
            A_new = coefficientA[2] * A_orig * A_orig + coefficientA[1] * A_orig + coefficientA[0];
            B_new = coefficientB[2] * B_orig * B_orig + coefficientB[1] * B_orig + coefficientB[0];

            calResult1D.put(label, new double[] { L_new, A_new, B_new });
        }

        // use the 1D calibration result for the second calibration step
        // Following http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html#solving-linear-least-squares-problems-and-pseudo-inverses
        // we will solve P = M x
        int total = calData.getLocations().keySet().size();
        RealMatrix coefficient = new Array2DRowRealMatrix(total, 3);
        RealMatrix cal = new Array2DRowRealMatrix(total, 3);
        int index = 0;

        // create coefficient and calibration vectors
        for (String label : calData.getCalValues().keySet()) {
            CalibrationData.CalValue calv = calData.getCalValues().get(label);
            double[] cal1dResult = calResult1D.get(label);
            coefficient.setEntry(index, 0, cal1dResult[0]);
            coefficient.setEntry(index, 1, cal1dResult[1]);
            coefficient.setEntry(index, 2, cal1dResult[2]);

            cal.setEntry(index, 0, calv.getL());
            cal.setEntry(index, 1, calv.getA());
            cal.setEntry(index, 2, calv.getB());
            index++;
        }

        DecompositionSolver solver = new SingularValueDecomposition(coefficient).getSolver();
        RealMatrix sol = solver.solve(cal);

        float a_L, b_L, c_L, a_A, b_A, c_A, a_B, b_B, c_B;
        a_L = (float) sol.getEntry(0, 0);
        b_L = (float) sol.getEntry(1, 0);
        c_L = (float) sol.getEntry(2, 0);
        a_A = (float) sol.getEntry(0, 1);
        b_A = (float) sol.getEntry(1, 1);
        c_A = (float) sol.getEntry(2, 1);
        a_B = (float) sol.getEntry(0, 2);
        b_B = (float) sol.getEntry(1, 2);
        c_B = (float) sol.getEntry(2, 2);

        //use the solution to correct the image
        double L_temp, A_temp, B_temp, L_mid, A_mid, B_mid;
        int L_fin, A_fin, B_fin;
        int ii3;
        byte[] temp = new byte[imgMat.cols() * imgMat.channels()];
        for (int i = 0; i < imgMat.rows(); i++) { // y
            imgMat.get(i, 0, temp);
            ii3 = 0;
            for (int ii = 0; ii < imgMat.cols(); ii++) { //x
                L_temp = temp[ii3] & 0xFF;
                A_temp = temp[ii3 + 1] & 0xFF;
                B_temp = temp[ii3 + 2] & 0xFF;

                L_mid = coefficientL[2] * L_temp * L_temp + coefficientL[1] * L_temp + coefficientL[0];
                A_mid = coefficientA[2] * A_temp * A_temp + coefficientA[1] * A_temp + coefficientA[0];
                B_mid = coefficientB[2] * B_temp * B_temp + coefficientB[1] * B_temp + coefficientB[0];

                L_fin = (int) Math.round(a_L * L_mid + b_L * A_mid + c_L * B_mid);
                A_fin = (int) Math.round(a_A * L_mid + b_A * A_mid + c_A * B_mid);
                B_fin = (int) Math.round(a_B * L_mid + b_B * A_mid + c_B * B_mid);

                // cap values
                L_fin = capValue(L_fin, 0, 255);
                A_fin = capValue(A_fin, 0, 255);
                B_fin = capValue(B_fin, 0, 255);

                temp[ii3] = (byte) L_fin;
                temp[ii3 + 1] = (byte) A_fin;
                temp[ii3 + 2] = (byte) B_fin;

                ii3 += 3;
            }
            imgMat.put(i, 0, temp);
        }

        return imgMat;
    } catch (Exception e) {
        throw new CalibrationException("error while performing calibration: ", e);
    }
}

From source file:org.akvo.caddisfly.sensor.colorimetry.strip.util.OpenCVUtil.java

@SuppressWarnings("UnusedParameters")
public static Mat detectStrip(Mat stripArea, StripTest.Brand brand, double ratioW, double ratioH) {
    List<Mat> channels = new ArrayList<>();
    Mat sArea = stripArea.clone();/*from   w  w w .  j  av  a2s  .co m*/

    // Gaussian blur
    Imgproc.medianBlur(sArea, sArea, 3);
    Core.split(sArea, channels);

    // create binary image
    Mat binary = new Mat();

    // determine min and max NOT USED
    Imgproc.threshold(channels.get(0), binary, 128, MAX_RGB_INT_VALUE, Imgproc.THRESH_BINARY);

    // compute first approximation of line through length of the strip
    final WeightedObservedPoints points = new WeightedObservedPoints();
    final WeightedObservedPoints corrPoints = new WeightedObservedPoints();

    double tot, yTot;
    for (int i = 0; i < binary.cols(); i++) { // iterate over cols
        tot = 0;
        yTot = 0;
        for (int j = 0; j < binary.rows(); j++) { // iterate over rows
            if (binary.get(j, i)[0] > 128) {
                yTot += j;
                tot++;
            }
        }
        if (tot > 0) {
            points.add((double) i, yTot / tot);
        }
    }

    // order of coefficients is (b + ax), so [b, a]
    final PolynomialCurveFitter fitter = PolynomialCurveFitter.create(1);
    List<WeightedObservedPoint> pointsList = points.toList();
    final double[] coefficient = fitter.fit(pointsList);

    // second pass, remove outliers
    double estimate, actual;

    for (int i = 0; i < pointsList.size(); i++) {
        estimate = coefficient[1] * pointsList.get(i).getX() + coefficient[0];
        actual = pointsList.get(i).getY();
        if (actual > LOWER_PERCENTAGE_BOUND * estimate && actual < UPPER_PERCENTAGE_BOUND * estimate) {
            //if the point differs less than +/- 10%, keep the point
            corrPoints.add(pointsList.get(i).getX(), pointsList.get(i).getY());
        }
    }

    final double[] coefficientCorr = fitter.fit(corrPoints.toList());
    double slope = coefficientCorr[1];
    double offset = coefficientCorr[0];

    // compute rotation angle
    double rotAngleDeg = Math.atan(slope) * 180 / Math.PI;

    //determine a point on the line, in the middle of strip, in the horizontal middle of the whole image
    int midPointX = binary.cols() / 2;
    int midPointY = (int) Math.round(midPointX * slope + offset);

    // rotate around the midpoint, to straighten the binary strip
    Mat dstBinary = new Mat(binary.rows(), binary.cols(), binary.type());
    Point center = new Point(midPointX, midPointY);
    Mat rotMat = Imgproc.getRotationMatrix2D(center, rotAngleDeg, 1.0);
    Imgproc.warpAffine(binary, dstBinary, rotMat, binary.size(),
            Imgproc.INTER_CUBIC + Imgproc.WARP_FILL_OUTLIERS);

    // also apply rotation to colored strip
    Mat dstStrip = new Mat(stripArea.rows(), stripArea.cols(), stripArea.type());
    Imgproc.warpAffine(stripArea, dstStrip, rotMat, binary.size(),
            Imgproc.INTER_CUBIC + Imgproc.WARP_FILL_OUTLIERS);

    // Compute white points in each row
    double[] rowCount = new double[dstBinary.rows()];
    int rowTot;
    for (int i = 0; i < dstBinary.rows(); i++) { // iterate over rows
        rowTot = 0;
        for (int j = 0; j < dstBinary.cols(); j++) { // iterate over cols
            if (dstBinary.get(i, j)[0] > 128) {
                rowTot++;
            }
        }
        rowCount[i] = rowTot;
    }

    // find width by finding rising and dropping edges
    // rising edge  = largest positive difference
    // falling edge = largest negative difference
    int risePos = 0;
    int fallPos = 0;
    double riseVal = 0;
    double fallVal = 0;
    for (int i = 0; i < dstBinary.rows() - 1; i++) {
        if (rowCount[i + 1] - rowCount[i] > riseVal) {
            riseVal = rowCount[i + 1] - rowCount[i];
            risePos = i + 1;
        }
        if (rowCount[i + 1] - rowCount[i] < fallVal) {
            fallVal = rowCount[i + 1] - rowCount[i];
            fallPos = i;
        }
    }

    // cut out binary strip
    Point stripTopLeft = new Point(0, risePos);
    Point stripBottomRight = new Point(dstBinary.cols(), fallPos);

    org.opencv.core.Rect stripAreaRect = new org.opencv.core.Rect(stripTopLeft, stripBottomRight);
    Mat binaryStrip = dstBinary.submat(stripAreaRect);

    // also cut out colored strip
    Mat colorStrip = dstStrip.submat(stripAreaRect);

    // now right end of strip
    // method: first rising edge

    double[] colCount = new double[binaryStrip.cols()];
    int colTotal;
    for (int i = 0; i < binaryStrip.cols(); i++) { // iterate over cols
        colTotal = 0;
        for (int j = 0; j < binaryStrip.rows(); j++) { // iterate over rows
            if (binaryStrip.get(j, i)[0] > 128) {
                colTotal++;
            }
        }

        //Log.d("Caddisfly", String.valueOf(colTotal));
        colCount[i] = colTotal;
    }

    stripAreaRect = getStripRectangle(binaryStrip, colCount, brand.getStripLength(), ratioW);

    Mat resultStrip = colorStrip.submat(stripAreaRect).clone();

    // release Mat objects
    stripArea.release();
    sArea.release();
    binary.release();
    dstBinary.release();
    dstStrip.release();
    binaryStrip.release();
    colorStrip.release();

    return resultStrip;
}

From source file:org.apache.solr.client.solrj.io.eval.PolyFitDerivativeEvaluator.java

@Override
public Object doWork(Object... objects) throws IOException {

    if (objects.length > 3) {
        throw new IOException("polyfitDerivative function takes a maximum of 3 arguments.");
    }/*  ww w .j  a  va 2  s. c o  m*/

    Object first = objects[0];

    double[] x = null;
    double[] y = null;
    int degree = 3;

    if (objects.length == 1) {
        //Only the y values passed

        y = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
        x = new double[y.length];
        for (int i = 0; i < y.length; i++) {
            x[i] = i;
        }

    } else if (objects.length == 3) {
        // x, y and degree passed

        Object second = objects[1];
        x = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
        y = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
        degree = ((Number) objects[2]).intValue();
    } else if (objects.length == 2) {
        if (objects[1] instanceof List) {
            // x and y passed
            Object second = objects[1];
            x = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
            y = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
        } else {
            // y and degree passed
            y = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
            x = new double[y.length];
            for (int i = 0; i < y.length; i++) {
                x[i] = i;
            }

            degree = ((Number) objects[1]).intValue();
        }
    }

    PolynomialCurveFitter curveFitter = PolynomialCurveFitter.create(degree);
    WeightedObservedPoints points = new WeightedObservedPoints();
    for (int i = 0; i < x.length; i++) {
        points.add(x[i], y[i]);
    }

    double[] coef = curveFitter.fit(points.toList());
    PolynomialFunction pf = new PolynomialFunction(coef);
    UnivariateFunction univariateFunction = pf.derivative();

    List list = new ArrayList();
    for (double xvalue : x) {
        double yvalue = univariateFunction.value(xvalue);
        list.add(yvalue);
    }

    return list;
}