Search in sources :

Example 6 with WeightedObservedPoint

use of org.apache.commons.math3.fitting.WeightedObservedPoint in project ffx by mjschnie.

the class BlockAverager method residual.

/**
 * Computes a residual to the given points for the provided fit type and
 * coefficients.
 */
private double residual(List<WeightedObservedPoint> obs, FITTER fitter, double[] coeffs) {
    int n = obs.size();
    double sumydiffsq = 0.0;
    for (int i = 0; i < n; i++) {
        final double x = obs.get(i).getX() * obs.get(i).getWeight();
        final double y = obs.get(i).getY() * obs.get(i).getWeight();
        double value;
        switch(fitter) {
            case LINEAR:
                value = coeffs[0] + coeffs[1] * x;
                break;
            case LOG:
                value = coeffs[0] + coeffs[1] * log(x);
                break;
            case POWER:
                value = coeffs[0] * pow(x, coeffs[1]);
                break;
            default:
                throw new UnsupportedOperationException();
        }
        sumydiffsq += (y - value) * (y - value);
    }
    double residual = sqrt(sumydiffsq);
    return residual;
}
Also used : WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint)

Example 7 with WeightedObservedPoint

use of org.apache.commons.math3.fitting.WeightedObservedPoint in project ffx by mjschnie.

the class BlockAverager method computeBinUncertainties.

/**
 * 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
 */
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;
}
Also used : WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) PolynomialFunction(org.apache.commons.math3.analysis.polynomials.PolynomialFunction) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint)

Example 8 with WeightedObservedPoint

use of org.apache.commons.math3.fitting.WeightedObservedPoint in project ffx by mjschnie.

the class BlockAverager method linearFit.

/**
 * Returns [A,B,R^2] such that f(x)= a + b*x is minimized for the input
 * points. As described at
 * http://mathworld.wolfram.com/LeastSquaresFitting.html
 */
private double[] linearFit(List<WeightedObservedPoint> obs) {
    int n = obs.size();
    double sumx = 0.0;
    double sumy = 0.0;
    double sumxsq = 0.0;
    double sumysq = 0.0;
    double sumxy = 0.0;
    for (int i = 0; i < n; i++) {
        final double x = obs.get(i).getX() * obs.get(i).getWeight();
        final double y = obs.get(i).getY() * obs.get(i).getWeight();
        sumx += x;
        sumy += y;
        sumxsq += x * x;
        sumysq += y * y;
        sumxy += x * y;
    }
    final double xbar = sumx / n;
    final double ybar = sumy / n;
    final double ssxx = sumxsq - n * xbar * xbar;
    final double ssyy = sumysq - n * ybar * ybar;
    final double ssxy = sumxy - n * xbar * ybar;
    final double rsq = (ssxy * ssxy) / (ssxx * ssyy);
    final double a = (ybar * sumxsq - xbar * sumxy) / (sumxsq - n * xbar * xbar);
    final double b = (sumxy - n * xbar * ybar) / (sumxsq - n * xbar * xbar);
    double[] ret = { a, b, rsq };
    return ret;
}
Also used : WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint)

Example 9 with WeightedObservedPoint

use of org.apache.commons.math3.fitting.WeightedObservedPoint in project GDSC-SMLM by aherbert.

the class Fire method fitGaussian.

/**
 * Fit gaussian.
 *
 * @param x the x
 * @param y the y
 * @return new double[] { norm, mean, sigma }
 */
private static double[] fitGaussian(float[] x, float[] y) {
    final WeightedObservedPoints obs = new WeightedObservedPoints();
    for (int i = 0; i < x.length; i++) {
        obs.add(x[i], y[i]);
    }
    final Collection<WeightedObservedPoint> observations = obs.toList();
    final GaussianCurveFitter fitter = GaussianCurveFitter.create().withMaxIterations(2000);
    final GaussianCurveFitter.ParameterGuesser guess = new GaussianCurveFitter.ParameterGuesser(observations);
    double[] initialGuess = null;
    try {
        initialGuess = guess.guess();
        return fitter.withStartPoint(initialGuess).fit(observations);
    } catch (final Exception ex) {
    // We are expecting TooManyEvaluationsException.
    // Just in case there is another exception type, or the initial estimate failed
    // we catch all exceptions.
    }
    return initialGuess;
}
Also used : WeightedObservedPoints(org.apache.commons.math3.fitting.WeightedObservedPoints) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) GaussianCurveFitter(org.apache.commons.math3.fitting.GaussianCurveFitter) DataException(uk.ac.sussex.gdsc.core.data.DataException) ConversionException(uk.ac.sussex.gdsc.core.data.utils.ConversionException)

Aggregations

WeightedObservedPoint (org.apache.commons.math3.fitting.WeightedObservedPoint)9 GaussianCurveFitter (org.apache.commons.math3.fitting.GaussianCurveFitter)4 WeightedObservedPoints (org.apache.commons.math3.fitting.WeightedObservedPoints)4 TooManyEvaluationsException (org.apache.commons.math3.exception.TooManyEvaluationsException)3 DataException (uk.ac.sussex.gdsc.core.data.DataException)2 ClusterPoint (gdsc.core.clustering.ClusterPoint)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 PolynomialFunction (org.apache.commons.math3.analysis.polynomials.PolynomialFunction)1 Nullable (uk.ac.sussex.gdsc.core.annotation.Nullable)1 ClusterPoint (uk.ac.sussex.gdsc.core.clustering.ClusterPoint)1 ConversionException (uk.ac.sussex.gdsc.core.data.utils.ConversionException)1