This is an automated email from the ASF dual-hosted git repository.

leirui pushed a commit to branch research/area-visualization
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit ec0a3cebce1cd4b23f50066dd21bd73fc801f279
Author: Lei Rui <[email protected]>
AuthorDate: Mon Jan 27 00:47:47 2025 +0800

    swab"
---
 .../java/org/apache/iotdb/db/query/eBUG/SWAB.java  | 311 +++++++++------------
 .../java/org/apache/iotdb/db/query/eBUG/Test7.java |  67 +++++
 .../java/org/apache/iotdb/db/query/eBUG/Test8.java |  65 +++++
 3 files changed, 260 insertions(+), 183 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/query/eBUG/SWAB.java 
b/server/src/main/java/org/apache/iotdb/db/query/eBUG/SWAB.java
index 574f59e3bf4..31b2f02ea86 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/eBUG/SWAB.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/eBUG/SWAB.java
@@ -1,6 +1,5 @@
 package org.apache.iotdb.db.query.eBUG;
 
-import java.io.*;
 import java.util.*;
 
 
@@ -82,12 +81,7 @@ public class SWAB {
         }
 
         // 计算L2误差,注意归一化还原
-        return sumY2 * baseY * baseY
-                + k * k * sumX2 * baseX * baseX
-                + 2 * k * b * sumX * baseX
-                - 2 * b * sumY * baseY
-                - 2 * k * sumXY * baseX * baseY
-                + b * b * (rx - lx + 1);
+        return sumY2 * baseY * baseY + k * k * sumX2 * baseX * baseX + 2 * k * 
b * sumX * baseX - 2 * b * sumY * baseY - 2 * k * sumXY * baseX * baseY + b * b 
* (rx - lx + 1);
     }
 
     public static double myLA_withTimestamps(List<Point> points, int lx, int 
rx) {
@@ -110,8 +104,7 @@ public class SWAB {
         return tmp;
     }
 
-    public static List<Point> seg_bottomUp_maxerror_withTimestamps(
-            List<Point> points, double maxError, Object[] prefixSum, boolean 
debug) {
+    public static List<Point> seg_bottomUp_maxerror_withTimestamps(List<Point> 
points, double maxError, Object[] prefixSum, boolean debug) {
         int total = points.size();
         if (total < 3) {
             return points; // 不足 3 个点无法形成三角形
@@ -151,8 +144,7 @@ public class SWAB {
         }
 
         // 使用优先队列构建 minHeap
-        PriorityQueue<Triangle> triangleHeap =
-                new PriorityQueue<>(Comparator.comparingDouble(t -> t.area));
+        PriorityQueue<Triangle> triangleHeap = new 
PriorityQueue<>(Comparator.comparingDouble(t -> t.area));
         Collections.addAll(triangleHeap, triangles); // complexity TODO O(n) 
or O(nlogn)?
 
         int fakeCnt = 0;
@@ -166,10 +158,7 @@ public class SWAB {
             if (tri.isDeleted) {
                 fakeCnt--; // 取出了一个被标记删除点
                 if (debug) {
-                    System.out.println(
-                            ">>>bottom-up, remaining "
-                                    + triangleHeap.size()
-                                    + " triangles (including those marked for 
removal)");
+                    System.out.println(">>>bottom-up, remaining " + 
triangleHeap.size() + " triangles (including those marked for removal)");
                 }
                 continue;
             }
@@ -199,17 +188,13 @@ public class SWAB {
 
                 double mc;
                 if (prefixSum == null) {
-                    mc = myLA_withTimestamps(points,
-                            tri.prev.indices[0], tri.prev.indices[2]);
+                    mc = myLA_withTimestamps(points, tri.prev.indices[0], 
tri.prev.indices[2]);
                 } else {
-                    mc = myLA_withTimestamps(points,
-                            prefixSum, tri.prev.indices[0], 
tri.prev.indices[2]);
+                    mc = myLA_withTimestamps(points, prefixSum, 
tri.prev.indices[0], tri.prev.indices[2]);
                 }
                 tri.prev.area = mc;
                 if (debug) {
-                    System.out.println("(2) updating point on the left "
-                            + points.get(tri.prev.indices[1])
-                            + ", ranging [" + tri.prev.indices[0] + "," + 
tri.prev.indices[2] + "]");
+                    System.out.println("(2) updating point on the left " + 
points.get(tri.prev.indices[1]) + ", ranging [" + tri.prev.indices[0] + "," + 
tri.prev.indices[2] + "]");
                 }
 
                 // 重新加入堆
@@ -239,17 +224,13 @@ public class SWAB {
 
                 double mc;
                 if (prefixSum == null) {
-                    mc = myLA_withTimestamps(points,
-                            tri.next.indices[0], tri.next.indices[2]);
+                    mc = myLA_withTimestamps(points, tri.next.indices[0], 
tri.next.indices[2]);
                 } else {
-                    mc = myLA_withTimestamps(points,
-                            prefixSum, tri.next.indices[0], 
tri.next.indices[2]);
+                    mc = myLA_withTimestamps(points, prefixSum, 
tri.next.indices[0], tri.next.indices[2]);
                 }
                 tri.next.area = mc;
                 if (debug) {
-                    System.out.println("(3) updating point on the right "
-                            + points.get(tri.next.indices[1])
-                            + ", ranging [" + tri.next.indices[0] + "," + 
tri.next.indices[2] + "]");
+                    System.out.println("(3) updating point on the right " + 
points.get(tri.next.indices[1]) + ", ranging [" + tri.next.indices[0] + "," + 
tri.next.indices[2] + "]");
                 }
 
                 // 重新加入堆
@@ -259,10 +240,7 @@ public class SWAB {
                 fakeCnt++; // 表示heap里多了一个被标记删除的假点
             }
             if (debug) {
-                System.out.println(
-                        ">>>bottom-up, remaining "
-                                + triangleHeap.size()
-                                + " triangles (including those marked for 
removal)");
+                System.out.println(">>>bottom-up, remaining " + 
triangleHeap.size() + " triangles (including those marked for removal)");
             }
         }
 
@@ -294,8 +272,18 @@ public class SWAB {
         return i - 1; // 从0开始,并且是从0到i-1的左闭右闭
     }
 
-
     public static List<Point> swab_framework(List<Point> points, double 
maxError, int m, boolean debug) {
+        return swab_framework(points, maxError, m, null, debug);
+    }
+
+    public static List<Point> swab_framework(List<Point> points, double 
maxError, int m, Object[] prefixSum, boolean debug) {
+        if (debug) {
+            if (prefixSum != null) {
+                // deprecated
+                System.out.println("enable prefix sum for accelerating L2 
error computation");
+            }
+        }
+
         // 在这里给Point添加全局排序idx, 用于全局定位
         for (int i = 0; i < points.size(); i++) {
             points.get(i).index = i;
@@ -307,139 +295,125 @@ public class SWAB {
         // m在这里的含义是分段数,虽然SWAB不能直接控制分段数,但是也需要这个参数来确定buffer大小
         int bs = (int) Math.floor((double) points.size() / m * 6);  // buffer 
size
         int lb = bs / 2, ub = bs * 2;
+        if (lb == 0) {
+            lb += 2; // lb最小为2,否则陷入循环,因为joint buffer里至少会留一个点
+            ub += 2;
+        }
         if (debug) {
             System.out.println("bs=" + bs + ", lb=" + lb + ", ub=" + ub);
         }
 
         int buffer_startIdx = 0; // 左闭
-        int buffer_endIdx = bs; // 右开。
-        // 注意虽然joint,但是buffer和remaining points是断开的
-        // buffer: [0:bs] 左闭右开
+        int buffer_endIdx = bs; // 右开
+        // 注意虽然joint,但是buffer和remaining points是buffer_endIdx处是不重叠的
+        // buffer: [0:bs) 左闭右开
         // remaining: [bs:] 左闭
 
-//        List<Point> w = points.subList(0, bs); // 浅复制 左闭右开
-//        List<Point> remaining_points = points.subList(bs, points.size()); // 
TODO
-
-        List<Point> segTs = new ArrayList<>(); // TODO
+        List<Point> segTs = new ArrayList<>();
         segTs.add(points.get(0)); //全局首点
 
-//        int base = 0; // global base
-//        if (debug) {
-//            System.out.println("base=" + base);
-//        }
         boolean needBottomUp = true; // false when only output, no input
-        int reuseIdx = 0; // TODO
-        List<Point> sampled = Collections.emptyList(); // TODO
+        int reuseIdx = 0; // 注意这里当needBottomUp=false的时候是直接取用上一轮的bottomup 
points但是base从reuseIdx开始
+        List<Point> sampled = Collections.emptyList();
         while (true) {
             if (debug) {
                 
System.out.println("#####################################################");
-                System.out.println("buffer data=" + (buffer_endIdx - 
buffer_startIdx)
-                        + ", remaining data=" + (points.size() - 
buffer_endIdx));
+                System.out.println("buffer data: [" + buffer_startIdx + "," + 
buffer_endIdx + ")" + ", remaining data: [" + buffer_endIdx + "," + 
points.size() + ")");
                 System.out.println("reBottomUp:" + needBottomUp);
             }
 
             if (needBottomUp) {
-
                 if (debug) {
                     System.out.println(">>>>bottom up on the buffer");
                 }
-                reuseIdx = 0;
-                sampled = seg_bottomUp_maxerror_withTimestamps(
-                        points.subList(buffer_startIdx, buffer_endIdx),
-                        maxError, null, false);
-                // TODO prefix sum acc
+                reuseIdx = 0; // 重置
+                if (prefixSum == null) {
+                    sampled = 
seg_bottomUp_maxerror_withTimestamps(points.subList(buffer_startIdx, 
buffer_endIdx),
+                            maxError, null, false);
+                } else {
+                    // deprecated
+                    double[] prefixSumX = Arrays.copyOfRange((double[]) 
prefixSum[0], buffer_startIdx, buffer_endIdx);
+                    double[] prefixSumY = Arrays.copyOfRange((double[]) 
prefixSum[1], buffer_startIdx, buffer_endIdx);
+                    double[] prefixSumX2 = Arrays.copyOfRange((double[]) 
prefixSum[2], buffer_startIdx, buffer_endIdx);
+                    double[] prefixSumY2 = Arrays.copyOfRange((double[]) 
prefixSum[3], buffer_startIdx, buffer_endIdx);
+                    double[] prefixSumXY = Arrays.copyOfRange((double[]) 
prefixSum[4], buffer_startIdx, buffer_endIdx);
+                    if (buffer_startIdx > 0) {
+                        for (int i = 0; i < prefixSumX.length; i++) {
+                            prefixSumX[i] -= ((double[]) 
prefixSum[0])[buffer_startIdx - 1];
+                        }
+                        for (int i = 0; i < prefixSumY.length; i++) {
+                            prefixSumY[i] -= ((double[]) 
prefixSum[1])[buffer_startIdx - 1];
+                        }
+                        for (int i = 0; i < prefixSumX2.length; i++) {
+                            prefixSumX2[i] -= ((double[]) 
prefixSum[2])[buffer_startIdx - 1];
+                        }
+                        for (int i = 0; i < prefixSumY2.length; i++) {
+                            prefixSumY2[i] -= ((double[]) 
prefixSum[3])[buffer_startIdx - 1];
+                        }
+                        for (int i = 0; i < prefixSumXY.length; i++) {
+                            prefixSumXY[i] -= ((double[]) 
prefixSum[4])[buffer_startIdx - 1];
+                        }
+                    }
+                    Object[] prefixSumPart = new Object[]{prefixSumX, 
prefixSumY, prefixSumX2, prefixSumY2, prefixSumXY,
+                            prefixSum[5], prefixSum[6]};
+                    sampled = 
seg_bottomUp_maxerror_withTimestamps(points.subList(buffer_startIdx, 
buffer_endIdx),
+                            maxError, prefixSumPart, false);
+                    // TODO prefixsum加速 但是由于精度问题,再加上maxError控制,结果有时候不会完全相同
+                }
 
 
                 // TODO eBUG also
 //                sampled = 
eBUG.buildEffectiveArea(points.subList(buffer_startIdx, buffer_endIdx), 0, 
false, m);
             }
 
+            if (debug) {
+                System.out.println("number of bottomUp points=" + 
(sampled.size() - reuseIdx));
+                System.out.println("---------------------------------");
+            }
+
             if (sampled.size() - reuseIdx >= 2) { // 左边输出一个segment
                 if (debug) {
                     System.out.println(">>>>left output a segment:["
-                            + sampled.get(0 + reuseIdx).index + "," + 
sampled.get(1 + reuseIdx) + "]");
+                            + sampled.get(reuseIdx).index + "," + 
sampled.get(1 + reuseIdx).index + "]");
                 }
-//                Map<String, Integer> firstSegment = segment.get(0);
-//                firstSegment.put("lx", firstSegment.get("lx") + base);
-//                firstSegment.put("rx", firstSegment.get("rx") + base);
-//                sampled.get(1).index += base; // # note that no need to add 
base later for segment(1)
-                segTs.add(sampled.get(1 + reuseIdx));
-
-                buffer_startIdx = sampled.get(1 + reuseIdx).index;
-
-//                if (sampled.size() == 2) {
-//                    // 更新buffer w
-//                    buffer_startIdx = buffer_endIdx - 1; // 注意左开右闭
-////                    w = w.subList(w.size() - 1, w.size()); // last point 
in buffer for joint
-//
-//                    // 更新base
-//                    // NOTE python start from 0 not 1
-//                    // NOTE segment(0) rx already add base! i.e., segment(0) 
rx is already global position
-////                    base = sampled.get(1).index;
-//                } else {
-//                    // 更新buffer w
-//                    int out = sampled.get(1).index - sampled.get(0).index + 
1;
-//
-//                    // 更新base
-//                    w = w.subList(out - 1, w.size()); // last point in 
buffer for joint
-//                    buffer_startIdx = sampled.get(1).index;
-////                    base = base + sampled.get(1).index; // 
对于joint来说,这个既是第一段的结尾又是第二段的开始位置
-//                }
+                segTs.add(sampled.get(1 + reuseIdx)); // 分段右端点
+                buffer_startIdx = sampled.get(1 + reuseIdx).index; // 
buffer起点右移
             }
 
             if (debug) {
-                System.out.println("buffer data: [" + buffer_startIdx + "," + 
buffer_endIdx + "]");
+                System.out.println("buffer data: [" + buffer_startIdx + "," + 
buffer_endIdx + ")" + ", remaining data: [" + buffer_endIdx + "," + 
points.size() + ")");
                 System.out.println("---------------------------------");
             }
-            if (buffer_endIdx >= points.size()) { // TODO no more point added 
into buffer w
+
+            if (buffer_endIdx >= points.size()) { // no more point added into 
buffer w
                 if (debug) {
                     System.out.println(">>>>no more data remaining");
                 }
                 // Add remaining segments and break if no more input data
-                if (sampled.size() - reuseIdx > 2) {
-                    // 注意此时segment并没有把上面“左边输出一个segment”的第一个segment pop出去
-                    // 更新base
-                    // 这次不需要re-bottomUp了,所以回退到本次分段起点,这样后面的相对位置加上base才是绝对位置
-                    // NOTE segments does NOT have their index recalculated by 
bottom-up to start from 0,
-                    // therefore minus the previously added segment[1]["lx"]
-//                    base = base - sampled.get(1).index;
-                    for (int k = 2 + reuseIdx; k < sampled.size(); k++) {
-//                        Map<String, Integer> seg = segment.get(k);
-//                        seg.put("lx", seg.get("lx") + base);
-//                        seg.put("rx", seg.get("rx") + base);
-                        // 注意此时segment并没有把上面“左边输出一个segment”的第一个segment pop出去!
-                        // 所以要从第二个segment开始继续输出,同时注意python从0开始计数
-//                        sampled.get(k).index += base;
+                if (sampled.size() - reuseIdx > 2) { // more than one segment, 
其中第一段segment已经在上面被记录了,但是没有被移出去
+                    if (debug) {
+                        System.out.println(">>>>so just left output all 
remaining segments");
+                    }
+                    for (int k = 2 + reuseIdx; k < sampled.size(); k++) { // 
全局尾点就在这里输出
                         segTs.add(sampled.get(k));
+                        if (debug) {
+                            System.out.println("output: " + sampled.get(k));
+                        }
                     }
                 }
                 break;
             }
 
             if ((buffer_endIdx - buffer_startIdx) >= lb) {
-                // buffer w上面已经更新了,已经是去除了左边输出的第一个segment之后的剩余的点
                 if (debug) {
                     System.out.println(">>>>no need adding the sliding segment 
from right because len(w) >= lb");
                 }
                 needBottomUp = false;
 
-                // 更新base
-                // 这次不需要re-bottomUp了,所以回退到本次分段起点,这样后面的相对位置加上base才是绝对位置
-                // NOTE segments does NOT have their index recalculated by 
bottom-up to start from 0,
-                // therefore minus the previously added segment[1]["lx"]
-//                base = base - sampled.get(1).index;
-
-                // 
注意此步骤不要在更新base之前执行!!!因为上面更新base时假设“左边输出一个segment”的第一个segment还没有pop
-                // 注意这里真的把上面“左边输出一个segment”的第一个segment pop出去了,
-                // 因为下一轮迭代要直接用剩余的segment
-//                segment.remove(0);  // Pop the first segment
-//                sampled.remove(0); // TODO 这个复杂度?
-                reuseIdx++; // TODO
+                reuseIdx++; // 这样简单,不需要sampled.remove(0)复杂度
                 if (debug) {
                     System.out.println("next iteration uses the remaining 
segment without re-bottomUp, reuseIdx=" + reuseIdx);
                 }
-
-                // # assume lb>1, at least two segments
             } else {
                 if (debug) {
                     System.out.println(">>>>adding the sliding segment from 
right because len(w) < lb");
@@ -449,88 +423,59 @@ public class SWAB {
                 while ((buffer_endIdx - buffer_startIdx) < lb && 
(points.size() - buffer_endIdx) > 0) {
                     // 从0开始,并且rx是从0开始的右闭 [0,rx]一共rx+1个点
                     List<Point> remaining_points = 
points.subList(buffer_endIdx, points.size());
-                    int rx = nextSlidingWindowWithTimestamps(remaining_points, 
maxError, null); // TODO prefixsum加速
+                    int rx;
+                    if (prefixSum == null) {
+                        rx = nextSlidingWindowWithTimestamps(remaining_points, 
maxError, null);
+                    } else {
+                        // deprecated
+                        double[] prefixSumX = Arrays.copyOfRange((double[]) 
prefixSum[0], buffer_endIdx, points.size());
+                        double[] prefixSumY = Arrays.copyOfRange((double[]) 
prefixSum[1], buffer_endIdx, points.size());
+                        double[] prefixSumX2 = Arrays.copyOfRange((double[]) 
prefixSum[2], buffer_endIdx, points.size());
+                        double[] prefixSumY2 = Arrays.copyOfRange((double[]) 
prefixSum[3], buffer_endIdx, points.size());
+                        double[] prefixSumXY = Arrays.copyOfRange((double[]) 
prefixSum[4], buffer_endIdx, points.size());
+                        if (buffer_endIdx > 0) {
+                            for (int i = 0; i < prefixSumX.length; i++) {
+                                prefixSumX[i] -= ((double[]) 
prefixSum[0])[buffer_endIdx - 1];
+                            }
+                            for (int i = 0; i < prefixSumY.length; i++) {
+                                prefixSumY[i] -= ((double[]) 
prefixSum[1])[buffer_endIdx - 1];
+                            }
+                            for (int i = 0; i < prefixSumX2.length; i++) {
+                                prefixSumX2[i] -= ((double[]) 
prefixSum[2])[buffer_endIdx - 1];
+                            }
+                            for (int i = 0; i < prefixSumY2.length; i++) {
+                                prefixSumY2[i] -= ((double[]) 
prefixSum[3])[buffer_endIdx - 1];
+                            }
+                            for (int i = 0; i < prefixSumXY.length; i++) {
+                                prefixSumXY[i] -= ((double[]) 
prefixSum[4])[buffer_endIdx - 1];
+                            }
+                        }
+                        Object[] prefixSumPart = new Object[]{prefixSumX, 
prefixSumY, prefixSumX2, prefixSumY2, prefixSumXY,
+                                prefixSum[5], prefixSum[6]};
+                        rx = nextSlidingWindowWithTimestamps(remaining_points, 
maxError, prefixSumPart);
+                        // TODO prefixsum加速 但是由于精度问题,再加上maxError控制,结果有时候不会完全相同
+                    }
                     if ((buffer_endIdx - buffer_startIdx) + (rx + 1) > ub) {
                         // # avoid more than ub
                         rx = ub - (buffer_endIdx - buffer_startIdx) - 1;
                     }
-                    buffer_endIdx += (rx + 1); // TODO
-//                    w.addAll(remaining_points.subList(0, rx + 1)); // TODO
-//                    remaining_points = remaining_points.subList(rx + 1, 
remaining_points.size());
+                    buffer_endIdx += (rx + 1); // buffer终点右移
                     if (debug) {
                         System.out.println("input len=" + (rx + 1));
                     }
                 }
-            }
 
-            if (debug) {
-                System.out.println("buffer data: [" + buffer_startIdx + "," + 
buffer_endIdx + "), "
-                        + "remaining data: [" + buffer_endIdx + "," + 
points.size() + ")");
-                if ((buffer_endIdx - buffer_startIdx) < lb) {
-                    System.out.println("warn less");
-                }
-                if ((buffer_endIdx - buffer_startIdx) > ub) {
-                    System.out.println("warn more");
+                if (debug) {
+                    System.out.println("buffer data: [" + buffer_startIdx + 
"," + buffer_endIdx + ")" + ", remaining data: [" + buffer_endIdx + "," + 
points.size() + ")");
+                    if ((buffer_endIdx - buffer_startIdx) < lb) {
+                        System.out.println("warn less");
+                    }
+                    if ((buffer_endIdx - buffer_startIdx) > ub) {
+                        System.out.println("warn more");
+                    }
                 }
             }
         }
         return segTs;
     }
-
-    public static void main(String[] args) {
-        Random rand = new Random(10);
-        String input = "D:\\datasets\\regular\\tmp2.csv";
-        boolean hasHeader = false;
-        int timeIdx = 0;
-        int valueIdx = 1;
-        int N = 100;
-//        Polyline polyline = Tool.readFromFile(input, hasHeader, timeIdx, 
valueIdx, N);
-        Polyline polyline = new Polyline();
-        for (int i = 0; i < N; i += 1) {
-            double v = rand.nextInt(1000);
-            polyline.addVertex(new Point(i, v));
-        }
-        try (FileWriter writer = new FileWriter("raw.csv")) {
-            // 写入CSV头部
-            writer.append("x,y,z\n");
-
-            // 写入每个点的数据
-            for (int i = 0; i < polyline.size(); i++) {
-                Point point = polyline.get(i);
-                writer.append(point.x + "," + point.y + "," + point.z + "\n");
-            }
-            System.out.println(polyline.size() + " Data has been written");
-        } catch (IOException e) {
-            System.out.println("Error writing to CSV file: " + e.getMessage());
-        }
-
-        long startTime = System.currentTimeMillis();
-        Object[] prefixSum = prefixSum(polyline.getVertices());
-        long endTime = System.currentTimeMillis();
-        System.out.println("Time taken to precompute prefix sum: " + (endTime 
- startTime) + "ms");
-
-        double maxError = 1000000000;
-        int m = 10;
-
-        // 33s worst-case O(n2)因为没有prefix 
sum加速计算L2误差,但是实际达不到worst-case所以实际运行不会那么大耗时
-        startTime = System.currentTimeMillis();
-        List<Point> sampled = swab_framework(polyline.getVertices(), maxError, 
m, true);
-        endTime = System.currentTimeMillis();
-        System.out.println("Time taken: " + (endTime - startTime) + "ms");
-
-        for (Point p : sampled) {
-            System.out.println(p);
-        }
-        System.out.println(sampled.size());
-
-        try (PrintWriter writer = new PrintWriter(new File("output.csv"))) {
-            // 写入字符串
-            for (int i = 0; i < sampled.size(); i++) {
-                writer.println(sampled.get(i).x + "," + sampled.get(i).y);
-            }
-
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
-    }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/eBUG/Test7.java 
b/server/src/main/java/org/apache/iotdb/db/query/eBUG/Test7.java
new file mode 100644
index 00000000000..7590d40914d
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/eBUG/Test7.java
@@ -0,0 +1,67 @@
+package org.apache.iotdb.db.query.eBUG;
+
+import java.io.*;
+import java.util.List;
+import java.util.Random;
+
+import static org.apache.iotdb.db.query.eBUG.SWAB.swab_framework;
+
+public class Test7 {
+    // 用于验证java swab实现正确性
+    public static void main(String[] args) {
+        Random rand = new Random(10);
+        String input = "D:\\datasets\\regular\\tmp2.csv";
+        boolean hasHeader = false;
+        int timeIdx = 0;
+        int valueIdx = 1;
+        int N = 10000;
+        Polyline polyline = Tool.readFromFile(input, hasHeader, timeIdx, 
valueIdx, N);
+//        Polyline polyline = new Polyline();
+//        for (int i = 0; i < N; i += 1) {
+//            double v = rand.nextInt(1000);
+//            polyline.addVertex(new Point(i, v));
+//        }
+        try (FileWriter writer = new FileWriter("raw.csv")) {
+            // 写入CSV头部
+            writer.append("x,y,z\n");
+
+            // 写入每个点的数据
+            for (int i = 0; i < polyline.size(); i++) {
+                Point point = polyline.get(i);
+                writer.append(point.x + "," + point.y + "," + point.z + "\n");
+            }
+            System.out.println(polyline.size() + " Data has been written");
+        } catch (IOException e) {
+            System.out.println("Error writing to CSV file: " + e.getMessage());
+        }
+
+//        long startTime = System.currentTimeMillis();
+//        Object[] prefixSum = prefixSum(polyline.getVertices());
+//        long endTime = System.currentTimeMillis();
+//        System.out.println("Time taken to precompute prefix sum: " + 
(endTime - startTime) + "ms");
+
+        double maxError = 0.2;
+        int m = 1000;
+
+        // 33s worst-case O(n2)因为没有prefix 
sum加速计算L2误差,但是实际达不到worst-case所以实际运行不会那么大耗时
+        long startTime = System.currentTimeMillis();
+        List<Point> sampled = swab_framework(polyline.getVertices(), maxError, 
m, null, true);
+        long endTime = System.currentTimeMillis();
+        System.out.println("Time taken: " + (endTime - startTime) + "ms");
+
+//        for (Point p : sampled) {
+//            System.out.println(p);
+//        }
+        System.out.println(sampled.size());
+
+        try (PrintWriter writer = new PrintWriter(new File("output.csv"))) {
+            // 写入字符串
+            for (int i = 0; i < sampled.size(); i++) {
+                writer.println(sampled.get(i).x + "," + sampled.get(i).y);
+            }
+
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/eBUG/Test8.java 
b/server/src/main/java/org/apache/iotdb/db/query/eBUG/Test8.java
new file mode 100644
index 00000000000..93b2ddf531c
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/eBUG/Test8.java
@@ -0,0 +1,65 @@
+package org.apache.iotdb.db.query.eBUG;
+
+import java.io.*;
+import java.util.List;
+import java.util.Random;
+
+import static org.apache.iotdb.db.query.eBUG.SWAB.prefixSum;
+import static org.apache.iotdb.db.query.eBUG.SWAB.swab_framework;
+
+public class Test8 {
+    // 用于测试SWAB速度
+    public static void main(String[] args) {
+        Random rand = new Random(10);
+        String input = "D:\\datasets\\regular\\tmp2.csv";
+        boolean hasHeader = false;
+        int timeIdx = 0;
+        int valueIdx = 1;
+        int N = 1000_0000;
+//        Polyline polyline = Tool.readFromFile(input, hasHeader, timeIdx, 
valueIdx, N);
+        Polyline polyline = new Polyline();
+        for (int i = 0; i < N; i += 1) {
+            double v = rand.nextInt(1000);
+            polyline.addVertex(new Point(i, v));
+        }
+        try (FileWriter writer = new FileWriter("raw.csv")) {
+            // 写入CSV头部
+            writer.append("x,y,z\n");
+
+            // 写入每个点的数据
+            for (int i = 0; i < polyline.size(); i++) {
+                Point point = polyline.get(i);
+                writer.append(point.x + "," + point.y + "," + point.z + "\n");
+            }
+            System.out.println(polyline.size() + " Data has been written");
+        } catch (IOException e) {
+            System.out.println("Error writing to CSV file: " + e.getMessage());
+        }
+
+//        Object[] prefixSum = prefixSum(polyline.getVertices());
+
+        double maxError = 20000000;
+        int m = 10000;
+
+        // 33s worst-case O(n2)因为没有prefix 
sum加速计算L2误差,但是实际达不到worst-case所以实际运行不会那么大耗时
+        long startTime = System.currentTimeMillis();
+        List<Point> sampled = swab_framework(polyline.getVertices(), maxError, 
m, null, false);
+        long endTime = System.currentTimeMillis();
+        System.out.println("Time taken: " + (endTime - startTime) + "ms");
+
+//        for (Point p : sampled) {
+//            System.out.println(p);
+//        }
+        System.out.println(sampled.size());
+
+        try (PrintWriter writer = new PrintWriter(new File("output.csv"))) {
+            // 写入字符串
+            for (int i = 0; i < sampled.size(); i++) {
+                writer.println(sampled.get(i).x + "," + sampled.get(i).y);
+            }
+
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+}

Reply via email to