sclass Test_CompressToInterpolatedDoubleArray { settable int maxPillars = 3; settable int minX =-10, maxX = 10; settable int maxRunlength = 10; settable int nTests = 1_000; // result new AverageAndMinMax pixelErrors; int pixelErrors() { ret iround(pixelErrors.sum()); } run { simpleTests(); repeat nTests { multiSlopeTest(); } printResults(); } void simpleTests { for (double slope = -1; slope <= 1; slope += 1/8.0) singleSlopeTest(slope); printResults(); } void printResults { print(); printVars(+pixelErrors); if (pixelErrors.average() == 0) print("PERFECT!"); else if (pixelErrors.average() <= 1) print("A bit less than optimal, but only by 1 pixel"); else print("This is not good."); } void singleSlopeTest(double slope) { int n = 16; var data = intArrayFromFunction(n, i -> iround(slope*i)); testCompression(data, 2); } void testCompression(int[] data, int maxPillarsAllowed) { print(); printStruct(+data); var compressed = CompressToInterpolatedDoubleArray(data)!; printStruct(+compressed); var reconstructed = compressed!; var reconstructed2 = iroundDoubleArray(reconstructed); printStruct(+reconstructed); // Test reconstructed array assertEquals(l(data), l(reconstructed2)); for i over data: { int diff = absDiff(data[i], reconstructed2[i]); pixelErrors.add(diff); if (diff != 0) { print("pixel error " + diff + " at " + i + ": " + data[i] + "/" + reconstructed2[i]); } } // Test that we have achieved sufficient compression assertLessThanOrEqualTo("pillars", maxPillarsAllowed, compressed.nPillars()); } int randomX() { ret random_incl(minX, maxX); } void multiSlopeTest() { int nPillars = random_incl(2, maxPillars); new IntBuffer values; new IntBuffer pillars; // first pillar pillars.add(0); values.add(randomX()); // remaining pillars for (int iPillar = 1; iPillar < nPillars; iPillar++) { int value = randomX(); int runlength = random_incl(1, maxRunlength); if (runlength > 1) { int lastValue = last(values); double slope = (value-lastValue)/(double) runlength; double x = lastValue; for (int i = 1; i < runlength; i++) values.add(iround(x += slope)); } pillars.add(l(values)); values.add(value); } print(+pillars); int[] data = values.toArrayNonNull(); testCompression(data, nPillars); } }