From fe07fad912321dd693db2c4970c0c61ea413d11e Mon Sep 17 00:00:00 2001 From: Panagiotis Liakos Date: Fri, 8 Apr 2022 00:32:19 +0300 Subject: [PATCH] fixed swing accuracy error --- .../gorilla/DecompressorSwingFilter.java | 4 +- .../compression/gorilla/LinearFunction.java | 6 +- .../aueb/compression/gorilla/SwingFilter.java | 78 +++++++-------- .../compression/gorilla/CompressTest.java | 97 ++++++++++++++----- 4 files changed, 115 insertions(+), 70 deletions(-) diff --git a/src/main/java/gr/aueb/compression/gorilla/DecompressorSwingFilter.java b/src/main/java/gr/aueb/compression/gorilla/DecompressorSwingFilter.java index 3ba3812..640cefb 100644 --- a/src/main/java/gr/aueb/compression/gorilla/DecompressorSwingFilter.java +++ b/src/main/java/gr/aueb/compression/gorilla/DecompressorSwingFilter.java @@ -2,7 +2,6 @@ import java.util.List; -import gr.aueb.compression.gorilla.PmcMR.Constant; import gr.aueb.compression.gorilla.SwingFilter.SwingSegment; public class DecompressorSwingFilter { @@ -12,7 +11,7 @@ public class DecompressorSwingFilter { private boolean endOfStream = false; private int currentElement = 0; private int currentTimestampOffset = 0; - + public DecompressorSwingFilter(List swingSegments) { this.swingSegments = swingSegments; } @@ -40,6 +39,7 @@ private void next() { if (currentElement < swingSegments.size()) { swingSegment = swingSegments.get(currentElement); storedVal = swingSegment.getLine().get(swingSegment.getInitialTimestamp()); + currentTimestampOffset = 1; } else { endOfStream = true; diff --git a/src/main/java/gr/aueb/compression/gorilla/LinearFunction.java b/src/main/java/gr/aueb/compression/gorilla/LinearFunction.java index af530d8..664cf45 100644 --- a/src/main/java/gr/aueb/compression/gorilla/LinearFunction.java +++ b/src/main/java/gr/aueb/compression/gorilla/LinearFunction.java @@ -24,12 +24,12 @@ public LinearFunction(long ts, float vs, long te, float ve) { /** Public Methods **/ public float get(long ts) { - return this.a * ts + this.b; + return (float) (this.a * ts + this.b); } /** Instance Variables **/ - public final float a, b; - + public final double a, b; + @Override public String toString() { return String.format("%fx+%f", a, b); diff --git a/src/main/java/gr/aueb/compression/gorilla/SwingFilter.java b/src/main/java/gr/aueb/compression/gorilla/SwingFilter.java index 9cf6ffc..8c4d923 100644 --- a/src/main/java/gr/aueb/compression/gorilla/SwingFilter.java +++ b/src/main/java/gr/aueb/compression/gorilla/SwingFilter.java @@ -6,17 +6,17 @@ public class SwingFilter { - - + + public List filter(Collection points, float epsilon) { - + List swingSegments = new ArrayList<>(); - + Point first = null; LinearFunction uiOld = null; LinearFunction liOld = null; Point last = null; - + for (Point point : points) { last = point; if (first == null) { @@ -25,7 +25,7 @@ public List filter(Collection points, float epsilon) { else { if (uiOld != null && liOld !=null && (uiOld.get(point.getTimestamp()) < point.getValue() || liOld.get(point.getTimestamp()) > point.getValue())) { LinearFunction line = new LinearFunction(first.getTimestamp(), first.getValue(), point.getTimestamp(), (uiOld.get(point.getTimestamp()) + liOld.get(point.getTimestamp())) / 2); -// System.out.println("need to start new line: " + line.toString()); +// System.out.println("need to start new line: " + line.toString() + " : " + first.getTimestamp() + " " + (point.getTimestamp() - 1)); swingSegments.add(new SwingSegment(first.getTimestamp(), point.getTimestamp() - 1, line)); uiOld = null; liOld = null; @@ -33,7 +33,7 @@ public List filter(Collection points, float epsilon) { } else { LinearFunction uiNew = new LinearFunction(first.getTimestamp(), first.getValue(), point.getTimestamp(), point.getValue() + epsilon); LinearFunction liNew = new LinearFunction(first.getTimestamp(), first.getValue(), point.getTimestamp(), point.getValue() - epsilon); - + if (uiOld == null || uiOld.get(point.getTimestamp()) > uiNew.get(point.getTimestamp())) { uiOld = uiNew; // System.out.println("resetting upper: " + uiOld); @@ -41,11 +41,11 @@ public List filter(Collection points, float epsilon) { if (liOld == null || liOld.get(point.getTimestamp()) < liNew.get(point.getTimestamp())) { liOld = liNew; // System.out.println("resetting lower: " + liOld); - } + } } } } - + if (uiOld != null && liOld !=null) { // System.out.println("need to start new line"); LinearFunction line = new LinearFunction(first.getTimestamp(), first.getValue(), last.getTimestamp(), (uiOld.get(last.getTimestamp()) + liOld.get(last.getTimestamp())) / 2); @@ -54,45 +54,45 @@ public List filter(Collection points, float epsilon) { LinearFunction line = new LinearFunction(first.getTimestamp(), first.getValue(), first.getTimestamp() + 1, first.getValue()); swingSegments.add(new SwingSegment(first.getTimestamp(), first.getTimestamp(), line)); } - + return swingSegments; } - - + + public class SwingSegment { - + private long initialTimestamp; private long finalTimestamp; private LinearFunction line; - + public SwingSegment(long initialTimestamp, long finalTimestamp, LinearFunction line) { this.initialTimestamp = initialTimestamp; this.finalTimestamp = finalTimestamp; this.line = line; } - + public long getFinalTimestamp() { return finalTimestamp; } - + public long getInitialTimestamp() { return initialTimestamp; } - + public LinearFunction getLine() { return line; } - + @Override public String toString() { return String.format("%d-%d: %f", getInitialTimestamp(), getFinalTimestamp(), getLine()); } - + } - + /** * - * + * * // initialization 1. (t1,X1) = getNext();(t2,X2) = getNext(); 2. Make a recording: (t0’,X0’) = (t1,X1); @@ -122,22 +122,22 @@ public String toString() { 17. if (tj,Xj) falls more than εi below uik in the xi dimension 18. “Swing down” uik such that it passes through (tk,xk) and (tj,Xj+Vd(i,εi)); - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * lines = [] line_first_timestamp, line_first_value = None, None coefficients_up, coefficients_down = None, None @@ -182,7 +182,7 @@ public String toString() { # Raises a warning if there is one point only, line_first_timestamp == timestamp lines.append([line_first_timestamp, np.polyfit(x=[line_first_timestamp, timestamp], y=[line_first_value, value], deg=1)]) - * + * * */ - + } diff --git a/src/test/java/gr/aueb/compression/gorilla/CompressTest.java b/src/test/java/gr/aueb/compression/gorilla/CompressTest.java index 7687611..e5e5644 100644 --- a/src/test/java/gr/aueb/compression/gorilla/CompressTest.java +++ b/src/test/java/gr/aueb/compression/gorilla/CompressTest.java @@ -335,7 +335,7 @@ public void testPrecisionLossy32ForBaselWindSpeed() throws IOException { filename, totalSize, totalSize / (totalBlocks * TimeseriesFileReader.DEFAULT_BLOCK_SIZE), maxPrecisionError, (maxValue - minValue), 100* maxPrecisionError / (maxValue - minValue), totalTrailingDiff / totalCases1, totalCases0 / total, totalCases1 / total, totalCases2 / total)); } } - + @Test public void testPmcMRFilterForBaselWindSpeed() throws IOException { for (int logOfError = -10; logOfError < 10; logOfError++) { @@ -354,10 +354,10 @@ public void testPmcMRFilterForBaselWindSpeed() throws IOException { points.add(new Point(timestamp++, value.floatValue())); } List constants = new PmcMR().filter(points, ((float) Math.pow(2, logOfError))); - + totalBlocks += 1; totalSize += constants.size() * 2 * 32; - + DecompressorPmcMr d = new DecompressorPmcMr(constants); for(Double value : values) { @@ -373,9 +373,9 @@ public void testPmcMRFilterForBaselWindSpeed() throws IOException { System.out.println(String.format("PMC-MR %s - Size : %d, Bits/value: %.2f, error: %f, Range: %.2f, (%.2f%%)", filename, totalSize, totalSize / (totalBlocks * TimeseriesFileReader.DEFAULT_BLOCK_SIZE), maxPrecisionError, (maxValue - minValue), 100* maxPrecisionError / (maxValue - minValue))); } - + } - + @Test public void testPmcMRFilterForBaselTemp() throws IOException { for (int logOfError = -10; logOfError < 10; logOfError++) { @@ -394,10 +394,10 @@ public void testPmcMRFilterForBaselTemp() throws IOException { points.add(new Point(timestamp++, value.floatValue())); } List constants = new PmcMR().filter(points, ((float) Math.pow(2, logOfError))); - + totalBlocks += 1; totalSize += constants.size() * 2 * 32; - + DecompressorPmcMr d = new DecompressorPmcMr(constants); for(Double value : values) { @@ -413,7 +413,7 @@ public void testPmcMRFilterForBaselTemp() throws IOException { System.out.println(String.format("PMC-MR %s - Size : %d, Bits/value: %.2f, error: %f, Range: %.2f, (%.2f%%)", filename, totalSize, totalSize / (totalBlocks * TimeseriesFileReader.DEFAULT_BLOCK_SIZE), maxPrecisionError, (maxValue - minValue), 100* maxPrecisionError / (maxValue - minValue))); } - + } @Test @@ -434,10 +434,10 @@ public void testSwingFilterForBaselWindSpeed() throws IOException { points.add(new Point(timestamp++, value.floatValue())); } List segments = new SwingFilter().filter(points, ((float) Math.pow(2, logOfError))); - + totalBlocks += 1; totalSize += segments.size() * 3 * 32; - + DecompressorSwingFilter d = new DecompressorSwingFilter(segments); for(Double value : values) { @@ -453,9 +453,9 @@ public void testSwingFilterForBaselWindSpeed() throws IOException { System.out.println(String.format("SwingFilter %s - Size : %d, Bits/value: %.2f, error: %f, Range: %.2f, (%.2f%%)", filename, totalSize, totalSize / (totalBlocks * TimeseriesFileReader.DEFAULT_BLOCK_SIZE), maxPrecisionError, (maxValue - minValue), 100* maxPrecisionError / (maxValue - minValue))); } - + } - + @Test public void testSwingFilterForBaselTemp() throws IOException { for (int logOfError = -10; logOfError < 10; logOfError++) { @@ -474,10 +474,10 @@ public void testSwingFilterForBaselTemp() throws IOException { points.add(new Point(timestamp++, value.floatValue())); } List segments = new SwingFilter().filter(points, ((float) Math.pow(2, logOfError))); - + totalBlocks += 1; totalSize += segments.size() * 3 * 32; - + DecompressorSwingFilter d = new DecompressorSwingFilter(segments); for(Double value : values) { @@ -486,19 +486,19 @@ public void testSwingFilterForBaselTemp() throws IOException { Float decompressedValue = d.readValue(); double precisionError = Math.abs(value.doubleValue() - decompressedValue); maxPrecisionError = (precisionError > maxPrecisionError) ? precisionError : maxPrecisionError; - assertEquals(value.doubleValue(), decompressedValue, Math.pow(2, logOfError + 6), "Value did not match"); + assertEquals(value.doubleValue(), decompressedValue, Math.pow(2, logOfError), "Value did not match"); } } System.out.println(String.format("SwingFilter %s - Size : %d, Bits/value: %.2f, error: %f, Range: %.2f, (%.2f%%)", filename, totalSize, totalSize / (totalBlocks * TimeseriesFileReader.DEFAULT_BLOCK_SIZE), maxPrecisionError, (maxValue - minValue), 100* maxPrecisionError / (maxValue - minValue))); } - + } - + @Test public void testSwingFilterSimple() throws IOException { - for (int logOfError = -1; logOfError < 0; logOfError++) { + for (int logOfError = -10; logOfError < -9; logOfError++) { Collection values = new ArrayList<>(); values.add(0.0); values.add(3.2399998); @@ -506,6 +506,51 @@ public void testSwingFilterSimple() throws IOException { values.add(1.1384199); values.add(3.4152596); values.add(4.3349743); + values.add(5.95906); + values.add(5.495161); + values.add(4.0249224); + values.add(2.0991426); + values.add(4.452954); + values.add(7.0911775); + values.add(6.9527545); + values.add(6.379216); + values.add(5.506941); + values.add(2.5959969); + values.add(2.8799999); + values.add(3.6179552); + values.add(4.1046314); + values.add(10.086427); + values.add(11.570515); + values.add(11.212135); + values.add(9.885262); + values.add(8.049845); + values.add(5.4477882); + values.add(2.2768397); + values.add(1.4399999); + values.add(2.16); + values.add(6.12); + values.add(9.826088); + values.add(15.778518); + values.add(15.807239); + values.add(16.75064); + values.add(19.66536); + values.add(19.930477); + values.add(19.586117); + values.add(18.448023); + values.add(16.946787); + values.add(16.09969); + values.add(14.408997); + values.add(12.074766); + values.add(13.207634); + values.add(11.966953); + values.add(12.55879); + values.add(11.435313); + values.add(16.179987); + values.add(19.826164); + values.add(22.065973); + values.add(20.929594); + values.add(19.652176); + double maxValue = Double.MIN_VALUE; double minValue = Double.MAX_VALUE; int timestamp = 0; @@ -517,10 +562,10 @@ public void testSwingFilterSimple() throws IOException { points.add(new Point(timestamp++, value.floatValue())); } List lines = new SwingFilter().filter(points, ((float) Math.pow(2, logOfError))); - + totalBlocks += 1; totalSize += lines.size() * 3 * 32; - + DecompressorSwingFilter d = new DecompressorSwingFilter(lines); for(Double value : values) { @@ -536,7 +581,7 @@ public void testSwingFilterSimple() throws IOException { } } } - + //@Test public void testPmcMRfilterSimple() throws IOException { for (int logOfError = -10; logOfError < 10; logOfError++) { @@ -558,10 +603,10 @@ public void testPmcMRfilterSimple() throws IOException { points.add(new Point(timestamp++, value.floatValue())); } List constants = new PmcMR().filter(points, ((float) Math.pow(2, logOfError))); - + totalBlocks += 1; totalSize += constants.size() * 2 * 32; - + DecompressorPmcMr d = new DecompressorPmcMr(constants); for(Double value : values) { @@ -577,9 +622,9 @@ public void testPmcMRfilterSimple() throws IOException { System.out.println(String.format("Lossy32 %s - Size : %d, Bits/value: %.2f", "simple", totalSize, totalSize / (totalBlocks * TimeseriesFileReader.DEFAULT_BLOCK_SIZE))); } - - + + } - + }