package gdsc.smlm.filters; import gdsc.smlm.TestSettings; import gdsc.smlm.filters.AverageFilter; import gdsc.smlm.filters.SumFilter; import java.util.ArrayList; import java.util.Arrays; import org.junit.Assert; import org.junit.Test; public class FilterTest { private gdsc.core.utils.Random rand; private boolean debug = false; int[] primes = new int[] { 113, 97, 53, 29 }; int[] boxSizes = new int[] { 15, 9, 5, 3, 2, 1 }; private float[] floatClone(int[] data1) { float[] data2 = new float[data1.length]; for (int i = data2.length; i-- > 0;) data2[i] = data1[i]; return data2; } private float[] floatClone(float[] data1) { float[] data2 = Arrays.copyOf(data1, data1.length); return data2; } private float[] floatCreateData(int width, int height) { float[] data = new float[width * height]; for (int i = data.length; i-- > 0;) //data[i] = i; data[i] = rand.next(); //rand.shuffle(data); return data; } private int[] intClone(int[] data1) { int[] data2 = Arrays.copyOf(data1, data1.length); return data2; } private int[] intCreateData(int width, int height) { int[] data = new int[width * height]; for (int i = data.length; i-- > 0;) data[i] = i; rand.shuffle(data); return data; } private double speedUpFactor(long slowTotal, long fastTotal) { return (1.0 * slowTotal) / fastTotal; } @Test public void floatRollingBlockSumNxNInternalIsFasterThanRollingBlockAverageNxNInternal() { org.junit.Assume.assumeTrue(TestSettings.RUN_SPEED_TESTS); rand = new gdsc.core.utils.Random(-300519); SumFilter filter = new SumFilter(); AverageFilter filter2 = new AverageFilter(); int iter = 50; ArrayList<float[]> dataSet = new ArrayList<float[]>(iter); for (int i = iter; i-- > 0;) { dataSet.add(floatCreateData(primes[0], primes[0])); } ArrayList<Long> fastTimes = new ArrayList<Long>(); // Initialise filter.rollingBlockSumNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); filter2.rollingBlockAverageNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); for (int boxSize : boxSizes) for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter.rollingBlockSumNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; fastTimes.add(time); } long slowTotal = 0, fastTotal = 0; int index = 0; for (int boxSize : boxSizes) { long boxSlowTotal = 0, boxFastTotal = 0; for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter2.rollingBlockAverageNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; long fastTime = fastTimes.get(index++); slowTotal += time; fastTotal += fastTime; boxSlowTotal += time; boxFastTotal += fastTime; if (debug) System.out .printf("float rollingBlockAverageNxNInternal [%dx%d] @ %d : %d => rollingBlockSumNxNInternal %d = %.2fx\n", width, height, boxSize, time, fastTime, speedUpFactor(time, fastTime)); //Assert.assertTrue(String.format("Not faster: [%dx%d] @ %d : %d > %d", width, height, boxSize, // blockTime, time), blockTime < time); } //if (debug) System.out.printf( "float rollingBlockAverageNxNInternal %d : %d => rollingBlockSumNxNInternal %d = %.2fx\n", boxSize, boxSlowTotal, boxFastTotal, speedUpFactor(boxSlowTotal, boxFastTotal)); // Assert.assertTrue(String.format("Not faster: Block %d : %d > %d", boxSize, boxFastTotal, boxSlowTotal), // boxFastTotal < boxSlowTotal); } System.out.printf("float rollingBlockAverageNxNInternal %d => rollingBlockSumNxNInternal %d = %.2fx\n", slowTotal, fastTotal, speedUpFactor(slowTotal, fastTotal)); if (TestSettings.ASSERT_SPEED_TESTS) Assert.assertTrue(String.format("Not faster: %d > %d", fastTotal, slowTotal), fastTotal < slowTotal); } @Test public void floatRollingBlockAverageNxNInternalIsFasterThanBlockMedianNxNInternal() { org.junit.Assume.assumeTrue(TestSettings.RUN_SPEED_TESTS); rand = new gdsc.core.utils.Random(-300519); AverageFilter filter1 = new AverageFilter(); MedianFilter filter2 = new MedianFilter(); int iter = 10; ArrayList<float[]> dataSet = new ArrayList<float[]>(iter); for (int i = iter; i-- > 0;) { dataSet.add(floatCreateData(primes[0], primes[0])); } ArrayList<Long> fastTimes = new ArrayList<Long>(); // Initialise filter1.rollingBlockAverageNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); filter2.blockMedianNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); for (int boxSize : boxSizes) for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter1.rollingBlockAverageNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; fastTimes.add(time); } long slowTotal = 0, fastTotal = 0; int index = 0; for (int boxSize : boxSizes) { long boxSlowTotal = 0, boxFastTotal = 0; for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter2.blockMedianNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; long fastTime = fastTimes.get(index++); slowTotal += time; fastTotal += fastTime; boxSlowTotal += time; boxFastTotal += fastTime; if (debug) System.out .printf("float blockMedianNxNInternal [%dx%d] @ %d : %d => rollingBlockAverageNxNInternal %d = %.2fx\n", width, height, boxSize, time, fastTime, speedUpFactor(time, fastTime)); //Assert.assertTrue(String.format("Not faster: [%dx%d] @ %d : %d > %d", width, height, boxSize, // blockTime, time), blockTime < time); } //if (debug) System.out.printf("float blockMedianNxNInternal %d : %d => rollingBlockAverageNxNInternal %d = %.2fx\n", boxSize, boxSlowTotal, boxFastTotal, speedUpFactor(boxSlowTotal, boxFastTotal)); // Assert.assertTrue(String.format("Not faster: Block %d : %d > %d", boxSize, boxFastTotal, boxSlowTotal), // boxFastTotal < boxSlowTotal); } System.out.printf("float blockMedianNxNInternal %d => rollingBlockAverageNxNInternal %d = %.2fx\n", slowTotal, fastTotal, speedUpFactor(slowTotal, fastTotal)); if (TestSettings.ASSERT_SPEED_TESTS) Assert.assertTrue(String.format("Not faster: %d > %d", fastTotal, slowTotal), fastTotal < slowTotal); } @Test public void floatRollingBlockAverageNxNInternalIsFasterThanRollingMedianNxNInternal() { org.junit.Assume.assumeTrue(TestSettings.RUN_SPEED_TESTS); rand = new gdsc.core.utils.Random(-300519); AverageFilter filter1 = new AverageFilter(); MedianFilter filter2 = new MedianFilter(); int iter = 10; ArrayList<float[]> dataSet = new ArrayList<float[]>(iter); for (int i = iter; i-- > 0;) { dataSet.add(floatCreateData(primes[0], primes[0])); } ArrayList<Long> fastTimes = new ArrayList<Long>(); // Initialise filter1.rollingBlockAverageNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); filter2.rollingMedianNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); for (int boxSize : boxSizes) for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter1.rollingBlockAverageNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; fastTimes.add(time); } long slowTotal = 0, fastTotal = 0; int index = 0; for (int boxSize : boxSizes) { long boxSlowTotal = 0, boxFastTotal = 0; for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter2.rollingMedianNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; long fastTime = fastTimes.get(index++); slowTotal += time; fastTotal += fastTime; boxSlowTotal += time; boxFastTotal += fastTime; if (debug) System.out .printf("float rollingMedianNxNInternal [%dx%d] @ %d : %d => rollingBlockAverageNxNInternal %d = %.2fx\n", width, height, boxSize, time, fastTime, speedUpFactor(time, fastTime)); //Assert.assertTrue(String.format("Not faster: [%dx%d] @ %d : %d > %d", width, height, boxSize, // blockTime, time), blockTime < time); } //if (debug) System.out.printf("float rollingMedianNxNInternal %d : %d => rollingBlockAverageNxNInternal %d = %.2fx\n", boxSize, boxSlowTotal, boxFastTotal, speedUpFactor(boxSlowTotal, boxFastTotal)); // Assert.assertTrue(String.format("Not faster: Block %d : %d > %d", boxSize, boxFastTotal, boxSlowTotal), // boxFastTotal < boxSlowTotal); } System.out.printf("float rollingMedianNxNInternal %d => rollingBlockAverageNxNInternal %d = %.2fx\n", slowTotal, fastTotal, speedUpFactor(slowTotal, fastTotal)); if (TestSettings.ASSERT_SPEED_TESTS) Assert.assertTrue(String.format("Not faster: %d > %d", fastTotal, slowTotal), fastTotal < slowTotal); } @Test public void floatRollingBlockAverageNxNInternalIsFasterThanGaussianNxNInternal() { org.junit.Assume.assumeTrue(TestSettings.RUN_SPEED_TESTS); rand = new gdsc.core.utils.Random(-300519); AverageFilter filter1 = new AverageFilter(); GaussianFilter filter2 = new GaussianFilter(); int iter = 10; ArrayList<float[]> dataSet = new ArrayList<float[]>(iter); for (int i = iter; i-- > 0;) { dataSet.add(floatCreateData(primes[0], primes[0])); } ArrayList<Long> fastTimes = new ArrayList<Long>(); // Initialise filter1.rollingBlockAverageNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); filter2.convolveInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0] / 3.0); for (int boxSize : boxSizes) for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter1.rollingBlockAverageNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; fastTimes.add(time); } long slowTotal = 0, fastTotal = 0; int index = 0; for (int boxSize : boxSizes) { long boxSlowTotal = 0, boxFastTotal = 0; for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter2.convolveInternal(data, width, height, boxSize / 3.0); time = System.nanoTime() - time; long fastTime = fastTimes.get(index++); slowTotal += time; fastTotal += fastTime; boxSlowTotal += time; boxFastTotal += fastTime; if (debug) System.out .printf("float convolveInternal [%dx%d] @ %d : %d => rollingBlockAverageNxNInternal %d = %.2fx\n", width, height, boxSize, time, fastTime, speedUpFactor(time, fastTime)); //Assert.assertTrue(String.format("Not faster: [%dx%d] @ %d : %d > %d", width, height, boxSize, // blockTime, time), blockTime < time); } //if (debug) System.out.printf("float convolveInternal %d : %d => rollingBlockAverageNxNInternal %d = %.2fx\n", boxSize, boxSlowTotal, boxFastTotal, speedUpFactor(boxSlowTotal, boxFastTotal)); // Assert.assertTrue(String.format("Not faster: Block %d : %d > %d", boxSize, boxFastTotal, boxSlowTotal), // boxFastTotal < boxSlowTotal); } System.out.printf("float convolveInternal %d => rollingBlockAverageNxNInternal %d = %.2fx\n", slowTotal, fastTotal, speedUpFactor(slowTotal, fastTotal)); if (TestSettings.ASSERT_SPEED_TESTS) Assert.assertTrue(String.format("Not faster: %d > %d", fastTotal, slowTotal), fastTotal < slowTotal); } @Test public void floatRollingBlockAverageNxNInternalIsFasterThanAreaAverageNxNInternal() { org.junit.Assume.assumeTrue(TestSettings.RUN_SPEED_TESTS); rand = new gdsc.core.utils.Random(-300519); AverageFilter filter1 = new AverageFilter(); AreaAverageFilter filter2 = new AreaAverageFilter(); int iter = 10; ArrayList<float[]> dataSet = new ArrayList<float[]>(iter); for (int i = iter; i-- > 0;) { dataSet.add(floatCreateData(primes[0], primes[0])); } ArrayList<Long> fastTimes = new ArrayList<Long>(); // Initialise //filter1.rollingBlockAverageNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); //filter2.areaAverageInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0] - 0.05); for (int boxSize : boxSizes) for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); // Initialise for (float[] data : dataSet2) filter1.rollingBlockAverageNxNInternal(data.clone(), width, height, boxSize); long time = System.nanoTime(); for (float[] data : dataSet2) filter1.rollingBlockAverageNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; fastTimes.add(time); } long slowTotal = 0, fastTotal = 0; int index = 0; for (int boxSize : boxSizes) { long boxSlowTotal = 0, boxFastTotal = 0; for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (float[] data : dataSet) dataSet2.add(floatClone(data)); // Initialise for (float[] data : dataSet2) filter2.areaAverageUsingAveragesInternal(data.clone(), width, height, boxSize - 0.05); long time = System.nanoTime(); for (float[] data : dataSet2) filter2.areaAverageUsingAveragesInternal(data, width, height, boxSize - 0.05); time = System.nanoTime() - time; long fastTime = fastTimes.get(index++); slowTotal += time; fastTotal += fastTime; boxSlowTotal += time; boxFastTotal += fastTime; if (debug) System.out .printf("float areaAverageInternal [%dx%d] @ %d : %d => rollingBlockAverageNxNInternal %d = %.2fx\n", width, height, boxSize, time, fastTime, speedUpFactor(time, fastTime)); //Assert.assertTrue(String.format("Not faster: [%dx%d] @ %d : %d > %d", width, height, boxSize, // blockTime, time), blockTime < time); } //if (debug) System.out.printf("float areaAverageInternal %d : %d => rollingBlockAverageNxNInternal %d = %.2fx\n", boxSize, boxSlowTotal, boxFastTotal, speedUpFactor(boxSlowTotal, boxFastTotal)); // Assert.assertTrue(String.format("Not faster: Block %d : %d > %d", boxSize, boxFastTotal, boxSlowTotal), // boxFastTotal < boxSlowTotal); } System.out.printf("float areaAverageInternal %d => rollingBlockAverageNxNInternal %d = %.2fx\n", slowTotal, fastTotal, speedUpFactor(slowTotal, fastTotal)); if (TestSettings.ASSERT_SPEED_TESTS) Assert.assertTrue(String.format("Not faster: %d > %d", fastTotal, slowTotal), fastTotal < slowTotal); } @Test public void floatRollingBlockSumNxNInternalIsFasterThanIntRollingBlockSumNxNInternal() { org.junit.Assume.assumeTrue(TestSettings.RUN_SPEED_TESTS); rand = new gdsc.core.utils.Random(-300519); SumFilter filter = new SumFilter(); int iter = 50; ArrayList<int[]> dataSet = new ArrayList<int[]>(iter); for (int i = iter; i-- > 0;) { dataSet.add(intCreateData(primes[0], primes[0])); } ArrayList<Long> fastTimes = new ArrayList<Long>(); // Initialise filter.rollingBlockSumNxNInternal(intClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); filter.rollingBlockSumNxNInternal(floatClone(dataSet.get(0)), primes[0], primes[0], boxSizes[0]); for (int boxSize : boxSizes) for (int width : primes) for (int height : primes) { ArrayList<float[]> dataSet2 = new ArrayList<float[]>(iter); for (int[] data : dataSet) dataSet2.add(floatClone(data)); long time = System.nanoTime(); for (float[] data : dataSet2) filter.rollingBlockSumNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; fastTimes.add(time); } long slowTotal = 0, fastTotal = 0; int index = 0; for (int boxSize : boxSizes) { long boxSlowTotal = 0, boxFastTotal = 0; for (int width : primes) for (int height : primes) { ArrayList<int[]> dataSet2 = new ArrayList<int[]>(iter); for (int[] data : dataSet) dataSet2.add(intClone(data)); long time = System.nanoTime(); for (int[] data : dataSet2) filter.rollingBlockSumNxNInternal(data, width, height, boxSize); time = System.nanoTime() - time; long fastTime = fastTimes.get(index++); slowTotal += time; fastTotal += fastTime; boxSlowTotal += time; boxFastTotal += fastTime; if (debug) System.out .printf("int rollingBlockSumNxNInternal [%dx%d] @ %d : %d => float rollingBlockSumNxNInternal %d = %.2fx\n", width, height, boxSize, time, fastTime, speedUpFactor(time, fastTime)); //Assert.assertTrue(String.format("Not faster: [%dx%d] @ %d : %d > %d", width, height, boxSize, // blockTime, time), blockTime < time); } //if (debug) System.out.printf( "int rollingBlockSumNxNInternal %d : %d => float rollingBlockSumNxNInternal %d = %.2fx\n", boxSize, boxSlowTotal, boxFastTotal, speedUpFactor(boxSlowTotal, boxFastTotal)); Assert.assertTrue(String.format("Not faster: Block %d : %d > %d", boxSize, boxFastTotal, boxSlowTotal), boxFastTotal < boxSlowTotal); } System.out.printf("int rollingBlockSumNxNInternal %d => float rollingBlockSumNxNInternal %d = %.2fx\n", slowTotal, fastTotal, speedUpFactor(slowTotal, fastTotal)); if (TestSettings.ASSERT_SPEED_TESTS) Assert.assertTrue(String.format("Not faster: %d > %d", fastTotal, slowTotal), fastTotal < slowTotal); } // TODO // int sum faster than float sum // Internal version vs complete version -> Is the speed hit significant? }