1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package org.jrobin.graph;
27
28 import org.jrobin.core.Util;
29
30 import java.util.Arrays;
31
32 class Normalizer {
33 final private double[] timestamps;
34 final int count;
35 final double step;
36
37 Normalizer(long tStart, long tEnd, int count) {
38 this.count = count;
39 this.step = (tEnd - tStart) / (count - 1);
40 this.timestamps = new double[count];
41 for (int i = 0; i < count; i++) {
42 this.timestamps[i] = tStart + ((double) i / (double) (count - 1)) * (tEnd - tStart);
43 }
44 }
45
46 double[] getTimestamps() {
47 return timestamps;
48 }
49
50 double[] normalize(long[] rawTimestamps, double[] rawValues) {
51 int rawCount = rawTimestamps.length;
52 long rawStep = rawTimestamps[1] - rawTimestamps[0];
53
54 if (rawCount == count && rawStep == step && rawTimestamps[0] == timestamps[0]) {
55 return getCopyOf(rawValues);
56 }
57
58 double[] values = new double[count];
59 Arrays.fill(values, Double.NaN);
60 for (int rawSeg = 0, seg = 0; rawSeg < rawCount && seg < count; rawSeg++) {
61 double rawValue = rawValues[rawSeg];
62 if (!Double.isNaN(rawValue)) {
63 long rawLeft = rawTimestamps[rawSeg] - rawStep;
64 while (seg < count && rawLeft >= timestamps[seg]) {
65 seg++;
66 }
67 boolean overlap = true;
68 for (int fillSeg = seg; overlap && fillSeg < count; fillSeg++) {
69 double left = timestamps[fillSeg] - step;
70 double t1 = Math.max(rawLeft, left);
71 double t2 = Math.min(rawTimestamps[rawSeg], timestamps[fillSeg]);
72 if (t1 < t2) {
73 values[fillSeg] = Util.sum(values[fillSeg], (t2 - t1) * rawValues[rawSeg]);
74 }
75 else {
76 overlap = false;
77 }
78 }
79 }
80 }
81 for (int seg = 0; seg < count; seg++) {
82 values[seg] /= step;
83 }
84 return values;
85 }
86
87 private static double[] getCopyOf(double[] rawValues) {
88 int n = rawValues.length;
89 double[] values = new double[n];
90 System.arraycopy(rawValues, 0, values, 0, n);
91 return values;
92 }
93 }
94