package gdsc.smlm.function.gaussian.erf; import gdsc.smlm.function.Gradient1Procedure; import gdsc.smlm.function.Gradient2Function; import gdsc.smlm.function.gaussian.Gaussian2DFunction; /*----------------------------------------------------------------------------- * GDSC SMLM Software * * Copyright (C) 2017 Alex Herbert * Genome Damage and Stability Centre * University of Sussex, UK * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. *---------------------------------------------------------------------------*/ /** * Abstract base class for an 2-dimensional Gaussian function for a configured number of peaks. * <p> * The function will calculate the value of the Gaussian and evaluate the gradient of a set of parameters. The class can * specify which of the following parameters the function will evaluate:<br/> * background, signal, z-depth, position0, position1, sd0, sd1 * <p> * The class provides an index of the position in the parameter array where the parameter is expected. */ public abstract class ErfGaussian2DFunction extends Gaussian2DFunction implements Gradient2Function { public static final int Z_POSITION = 2; protected final static double ONE_OVER_ROOT2 = 1.0 / Math.sqrt(2); protected final static double ONE_OVER_ROOT2PI = 1.0 / Math.sqrt(2 * Math.PI); // Required for the PSF protected double[] deltaEx, deltaEy; protected double tB; // Required for the first gradients protected double[] du_dtx, du_dty, du_dtsx, du_dtsy; // Required for the second gradients protected double[] d2u_dtx2, d2u_dty2, d2u_dtsx2, d2u_dtsy2; /** * Instantiates a new erf gaussian 2D function. * * @param nPeaks * The number of peaks * @param maxx * The maximum x value of the 2-dimensional data (used to unpack a linear index into coordinates) * @param maxy * The maximum y value of the 2-dimensional data (used to unpack a linear index into coordinates) */ public ErfGaussian2DFunction(int nPeaks, int maxx, int maxy) { super(maxx, maxy); deltaEx = new double[nPeaks * this.maxx]; deltaEy = new double[nPeaks * this.maxy]; } /** * Creates the arrays needed to compute the first-order partial derivatives. */ protected void create1Arrays() { if (du_dtx != null) return; du_dtx = new double[deltaEx.length]; du_dty = new double[deltaEy.length]; du_dtsx = new double[deltaEx.length]; du_dtsy = new double[deltaEy.length]; } /** * Creates the arrays needed to compute the first and second order partial derivatives. */ protected void create2Arrays() { if (d2u_dtx2 != null) return; d2u_dtx2 = new double[deltaEx.length]; d2u_dty2 = new double[deltaEy.length]; d2u_dtsx2 = new double[deltaEx.length]; d2u_dtsy2 = new double[deltaEy.length]; create1Arrays(); } /** * Copy the function. * * @return a copy */ @Override abstract public ErfGaussian2DFunction copy(); /* * (non-Javadoc) * * @see gdsc.smlm.function.gaussian.Gaussian2DFunction#getShapeName() */ @Override protected String getShapeName() { // The shape parameter is used for the z-position return "Z"; } /** * Evaluates an 2-dimensional Gaussian function for a single peak. * * @param i * Input predictor * @param duda * Partial first gradient of function with respect to each coefficient * @param d2uda2 * Partial second gradient of function with respect to each coefficient * @return The predicted value */ public abstract double eval(final int i, final double[] duda, final double[] d2uda2); // Force new implementation from the base Gaussian2DFunction @Override public abstract void forEach(Gradient1Procedure procedure); /* * (non-Javadoc) * * @see gdsc.smlm.function.NonLinearFunction#initialise(double[]) */ public void initialise(double[] a) { // The base Gaussian2DFunction does all the work in NonLinearFunction#initialise(double[]). // The ERF Gaussian2DFunction does all the work in Gradient1Function.initialise1(double[]) initialise1(a); } // Force new implementation from the base Gaussian2DFunction @Override public abstract void initialise0(double[] a); // Force new implementation from the base Gaussian2DFunction @Override public abstract void initialise1(double[] a); }