Search in sources :

Example 11 with FisherInformationMatrix

use of uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix in project GDSC-SMLM by aherbert.

the class PoissonGradientProcedureTest method varianceMatchesFormula.

@SeededTest
void varianceMatchesFormula() {
    // Assumptions.assumeTrue(false);
    final double[] n_ = new double[] { 20, 50, 100, 500 };
    final double[] b2_ = new double[] { 0, 1, 2, 4 };
    final double[] s_ = new double[] { 1, 1.2, 1.5 };
    final double[] x_ = new double[] { 4.8, 5, 5.5 };
    final double a = 100;
    final int size = 10;
    final Gaussian2DFunction f = GaussianFunctionFactory.create2D(1, size, size, GaussianFunctionFactory.FIT_ERF_CIRCLE, null);
    final PoissonGradientProcedure p = PoissonGradientProcedureUtils.create(f);
    final int ix = f.findGradientIndex(Gaussian2DFunction.X_POSITION);
    final int iy = f.findGradientIndex(Gaussian2DFunction.Y_POSITION);
    final double[] params = new double[1 + Gaussian2DFunction.PARAMETERS_PER_PEAK];
    for (final double n : n_) {
        params[Gaussian2DFunction.SIGNAL] = n;
        for (final double b2 : b2_) {
            params[Gaussian2DFunction.BACKGROUND] = b2;
            for (final double s : s_) {
                final double ss = s * a;
                params[Gaussian2DFunction.X_SD] = s;
                for (final double x : x_) {
                    params[Gaussian2DFunction.X_POSITION] = x;
                    for (final double y : x_) {
                        params[Gaussian2DFunction.Y_POSITION] = y;
                        p.computeFisherInformation(params);
                        final FisherInformationMatrix m1 = new FisherInformationMatrix(p.getLinear(), p.numberOfGradients);
                        final double[] crlb = m1.crlb();
                        if (crlb == null) {
                            Assertions.fail("No variance");
                        }
                        @SuppressWarnings("null") final double o1 = Math.sqrt(crlb[ix]) * a;
                        final double o2 = Math.sqrt(crlb[iy]) * a;
                        final double e = Gaussian2DPeakResultHelper.getMLPrecisionX(a, ss, n, b2, false);
                        // logger.fine(FunctionUtils.getSupplier("e = %f : o = %f %f", e, o1, o2);
                        Assertions.assertEquals(e, o1, e * 5e-2);
                        Assertions.assertEquals(e, o2, e * 5e-2);
                    }
                }
            }
        }
    }
}
Also used : ErfGaussian2DFunction(uk.ac.sussex.gdsc.smlm.function.gaussian.erf.ErfGaussian2DFunction) Gaussian2DFunction(uk.ac.sussex.gdsc.smlm.function.gaussian.Gaussian2DFunction) FisherInformationMatrix(uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix) SeededTest(uk.ac.sussex.gdsc.test.junit5.SeededTest)

Example 12 with FisherInformationMatrix

use of uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix in project GDSC-SMLM by aherbert.

the class BaseFunctionSolverTest method canFitSingleGaussian.

void canFitSingleGaussian(RandomSeed seed, FunctionSolver solver, boolean applyBounds, NoiseModel noiseModel) {
    // Allow reporting the fit deviations
    final boolean report = false;
    double[] crlb = null;
    SimpleArrayMoment moment = null;
    final double[] noise = getNoise(seed, noiseModel);
    if (solver.isWeighted()) {
        solver.setWeights(getWeights(seed, noiseModel));
    }
    final UniformRandomProvider rg = RngUtils.create(seed.getSeed());
    for (final double s : signal) {
        final double[] expected = createParams(1, s, 0, 0, 1);
        final double[] lower = createParams(0, s * 0.5, -0.3, -0.3, 0.8);
        final double[] upper = createParams(3, s * 2, 0.3, 0.3, 1.2);
        if (applyBounds) {
            solver.setBounds(lower, upper);
        }
        if (report) {
            // Compute the CRLB for a Poisson process
            final PoissonGradientProcedure gp = PoissonGradientProcedureUtils.create((Gradient1Function) ((BaseFunctionSolver) solver).getGradientFunction());
            gp.computeFisherInformation(expected);
            final FisherInformationMatrix f = new FisherInformationMatrix(gp.getLinear(), gp.numberOfGradients);
            crlb = f.crlbSqrt();
            // Compute the deviations.
            // Note this is not the same as the CRLB as the fit is repeated
            // against the same data.
            // It should be repeated against different data generated with constant
            // parameters and variable noise.
            moment = new SimpleArrayMoment();
        }
        final double[] data = drawGaussian(expected, noise, noiseModel, rg);
        for (final double db : base) {
            for (final double dx : shift) {
                for (final double dy : shift) {
                    for (final double dsx : factor) {
                        final double[] p = createParams(db, s, dx, dy, dsx);
                        final double[] fp = fitGaussian(solver, data, p, expected);
                        for (int i = 0; i < expected.length; i++) {
                            if (fp[i] < lower[i]) {
                                Assertions.fail(FunctionUtils.getSupplier("Fit Failed: [%d] %.2f < %.2f: %s != %s", i, fp[i], lower[i], Arrays.toString(fp), Arrays.toString(expected)));
                            }
                            if (fp[i] > upper[i]) {
                                Assertions.fail(FunctionUtils.getSupplier("Fit Failed: [%d] %.2f > %.2f: %s != %s", i, fp[i], upper[i], Arrays.toString(fp), Arrays.toString(expected)));
                            }
                            if (report) {
                                fp[i] = expected[i] - fp[i];
                            }
                        }
                        // Store the deviations
                        if (report) {
                            moment.add(fp);
                        }
                    }
                }
            }
        }
        // Report
        if (report) {
            logger.info(FunctionUtils.getSupplier("%s %s %f : CRLB = %s, Deviations = %s", solver.getClass().getSimpleName(), noiseModel, s, Arrays.toString(crlb), Arrays.toString(moment.getStandardDeviation())));
        }
    }
}
Also used : SimpleArrayMoment(uk.ac.sussex.gdsc.core.math.SimpleArrayMoment) PoissonGradientProcedure(uk.ac.sussex.gdsc.smlm.fitting.nonlinear.gradient.PoissonGradientProcedure) FisherInformationMatrix(uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix) UniformRandomProvider(org.apache.commons.rng.UniformRandomProvider)

Example 13 with FisherInformationMatrix

use of uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix in project GDSC-SMLM by aherbert.

the class MleLvmSteppingFunctionSolver method computeLastFisherInformationMatrix.

@Override
protected FisherInformationMatrix computeLastFisherInformationMatrix(double[] fx) {
    // The Hessian matrix refers to the log-likelihood ratio.
    // Compute and invert a matrix related to the Poisson log-likelihood.
    // This assumes this does achieve the maximum likelihood estimate for a
    // Poisson process.
    Gradient1Function localF1 = (Gradient1Function) function;
    // Capture the y-values if necessary
    if (fx != null && fx.length == localF1.size()) {
        localF1 = new Gradient2FunctionValueStore(localF1, fx);
    }
    // Add the weights if necessary
    if (weights != null) {
        localF1 = OffsetGradient1Function.wrapGradient1Function(localF1, weights);
    }
    final PoissonGradientProcedure p = PoissonGradientProcedureUtils.create(localF1);
    p.computeFisherInformation(lastA);
    if (p.isNaNGradients()) {
        throw new FunctionSolverException(FitStatus.INVALID_GRADIENTS);
    }
    // Re-use space
    p.getLinear(walpha);
    return new FisherInformationMatrix(walpha, beta.length);
}
Also used : OffsetGradient1Function(uk.ac.sussex.gdsc.smlm.function.OffsetGradient1Function) Gradient1Function(uk.ac.sussex.gdsc.smlm.function.Gradient1Function) PoissonGradientProcedure(uk.ac.sussex.gdsc.smlm.fitting.nonlinear.gradient.PoissonGradientProcedure) FisherInformationMatrix(uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix) Gradient2FunctionValueStore(uk.ac.sussex.gdsc.smlm.function.Gradient2FunctionValueStore)

Example 14 with FisherInformationMatrix

use of uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix in project GDSC-SMLM by aherbert.

the class MleLvmSteppingFunctionSolver method computeFunctionFisherInformationMatrix.

@Override
protected FisherInformationMatrix computeFunctionFisherInformationMatrix(double[] y, double[] a) {
    // Compute and invert a matrix related to the Poisson log-likelihood.
    // This assumes this does achieve the maximum likelihood estimate for a
    // Poisson process.
    // We must wrap the gradient function if weights are present.
    Gradient1Function localF1 = (Gradient1Function) function;
    if (weights != null) {
        localF1 = OffsetGradient1Function.wrapGradient1Function(localF1, weights);
    }
    final PoissonGradientProcedure p = PoissonGradientProcedureUtils.create(localF1);
    p.computeFisherInformation(a);
    if (p.isNaNGradients()) {
        throw new FunctionSolverException(FitStatus.INVALID_GRADIENTS);
    }
    return new FisherInformationMatrix(p.getLinear(), function.getNumberOfGradients());
}
Also used : OffsetGradient1Function(uk.ac.sussex.gdsc.smlm.function.OffsetGradient1Function) Gradient1Function(uk.ac.sussex.gdsc.smlm.function.Gradient1Function) PoissonGradientProcedure(uk.ac.sussex.gdsc.smlm.fitting.nonlinear.gradient.PoissonGradientProcedure) FisherInformationMatrix(uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix)

Example 15 with FisherInformationMatrix

use of uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix in project GDSC-SMLM by aherbert.

the class NonLinearFit method computeFitDeviations.

/**
 * Compute the parameter deviations using the covariance matrix of the solution.
 *
 * @param n the n
 * @param parametersVariance the parameter deviations
 * @return true, if successful
 */
private boolean computeFitDeviations(int n, double[] parametersVariance) {
    if (isMle()) {
        // The Hessian matrix refers to the log-likelihood ratio.
        // Compute and invert a matrix related to the Poisson log-likelihood.
        // This assumes this does achieve the maximum likelihood estimate for a
        // Poisson process.
        final double[][] fim = calculator.fisherInformationMatrix(n, null, func);
        if (calculator.isNaNGradients()) {
            throw new FunctionSolverException(FitStatus.INVALID_GRADIENTS);
        }
        // Use a dedicated solver optimised for inverting the matrix diagonal.
        final FisherInformationMatrix m = new FisherInformationMatrix(fim);
        setDeviations(parametersVariance, m);
        return true;
    }
    final double[] var = calculator.variance(n, null, func);
    if (var != null) {
        setDeviations(parametersVariance, var);
        return true;
    }
    return false;
}
Also used : FisherInformationMatrix(uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix)

Aggregations

FisherInformationMatrix (uk.ac.sussex.gdsc.smlm.fitting.FisherInformationMatrix)16 PoissonGradientProcedure (uk.ac.sussex.gdsc.smlm.fitting.nonlinear.gradient.PoissonGradientProcedure)5 Gradient1Function (uk.ac.sussex.gdsc.smlm.function.Gradient1Function)3 OffsetGradient1Function (uk.ac.sussex.gdsc.smlm.function.OffsetGradient1Function)3 ConvergenceException (org.apache.commons.math3.exception.ConvergenceException)2 TooManyEvaluationsException (org.apache.commons.math3.exception.TooManyEvaluationsException)2 TooManyIterationsException (org.apache.commons.math3.exception.TooManyIterationsException)2 UniformRandomProvider (org.apache.commons.rng.UniformRandomProvider)2 Gradient2FunctionValueStore (uk.ac.sussex.gdsc.smlm.function.Gradient2FunctionValueStore)2 LikelihoodWrapper (uk.ac.sussex.gdsc.smlm.function.LikelihoodWrapper)2 PoissonGammaGaussianLikelihoodWrapper (uk.ac.sussex.gdsc.smlm.function.PoissonGammaGaussianLikelihoodWrapper)2 PoissonGaussianLikelihoodWrapper (uk.ac.sussex.gdsc.smlm.function.PoissonGaussianLikelihoodWrapper)2 PoissonLikelihoodWrapper (uk.ac.sussex.gdsc.smlm.function.PoissonLikelihoodWrapper)2 LeastSquaresBuilder (org.apache.commons.math3.fitting.leastsquares.LeastSquaresBuilder)1 Optimum (org.apache.commons.math3.fitting.leastsquares.LeastSquaresOptimizer.Optimum)1 LeastSquaresProblem (org.apache.commons.math3.fitting.leastsquares.LeastSquaresProblem)1 LevenbergMarquardtOptimizer (org.apache.commons.math3.fitting.leastsquares.LevenbergMarquardtOptimizer)1 ValueAndJacobianFunction (org.apache.commons.math3.fitting.leastsquares.ValueAndJacobianFunction)1 Array2DRowRealMatrix (org.apache.commons.math3.linear.Array2DRowRealMatrix)1 ArrayRealVector (org.apache.commons.math3.linear.ArrayRealVector)1