package gdsc.smlm.function.gaussian; import org.junit.Assert; import org.junit.Test; import gdsc.core.utils.DoubleEquality; public class HoltzerAstigmatismZModelTest { protected DoubleEquality eq = new DoubleEquality(5, 1e-7); // Compute as per Numerical Recipes 5.7. // Approximate error accuracy in single precision: Ef // Step size for derivatives: // h ~ (Ef)^(1/3) * xc // xc is the characteristic scale over which x changes, assumed to be 1 (not x as per NR since x is close to zero) protected double h_ = 0.0001; //(double) (Math.pow(1e-3f, 1.0 / 3)); @Test public void canStaticComputeGradient() { double d = 0.531; double Ax = -0.0708; double Bx = -0.073; double Ay = 0.164; double By = 0.0417; canStaticComputeGradient(d, Ax, Bx); canStaticComputeGradient(d, Ay, By); } private void canStaticComputeGradient(double d, double Ax, double Bx) { double one_d2 = 1.0 / d / d; double[] ds_dz = new double[1]; double[] ds_dz2 = new double[2]; double[] ds_duz = new double[1]; double[] ds_dlz = new double[1]; for (double z = -0.5; z < 0.5; z += 0.01) { double s0 = HoltzerAstimatismZModel.getS(z, one_d2, Ax, Bx); double s1 = HoltzerAstimatismZModel.getS1(z, one_d2, Ax, Bx, ds_dz); double s2 = HoltzerAstimatismZModel.getS2(z, one_d2, Ax, Bx, ds_dz2); Assert.assertEquals(s0, s1, 0); Assert.assertEquals(s0, s2, 0); Assert.assertEquals(ds_dz[0], ds_dz2[0], 0); double uz = z + h_; double lz = z - h_; double upper = HoltzerAstimatismZModel.getS1(uz, one_d2, Ax, Bx, ds_duz); double lower = HoltzerAstimatismZModel.getS1(lz, one_d2, Ax, Bx, ds_dlz); double e1 = (upper - lower) / (uz - lz); double o1 = ds_dz[0]; // Second gradient double e2 = (ds_duz[0] - ds_dlz[0]) / (uz - lz); double o2 = ds_dz2[1]; System.out.printf("z=%f s=%f : ds_dz=%g %g (%g): d2s_dz2=%g %g (%g)\n", z, s0, e1, o1, DoubleEquality.relativeError(o1, e1), e2, o2, DoubleEquality.relativeError(o2, e2)); //double error = DoubleEquality.relativeError(o, e); if (Math.abs(z) > 0.02) Assert.assertTrue(e1 + " sign != " + o1, (e1 * o1) >= 0); Assert.assertTrue(e1 + " != " + o1, eq.almostEqualComplement(e1, o1)); if (Math.abs(z) > 0.02) Assert.assertTrue(e2 + " sign != " + o2, (e2 * o2) >= 0); Assert.assertTrue(e2 + " != " + o2, eq.almostEqualComplement(e2, o2)); } } }