Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/math/MovingAverage.java @ 9608:96c41d4f4aba
'.filtered' handling: NaN treatment improved
author | dnt_bjoernsen <d.tironi@bjoernsen.de> |
---|---|
date | Thu, 12 Sep 2019 15:39:10 +0200 |
parents | 34c15927f9d9 |
children |
comparison
equal
deleted
inserted
replaced
9607:68acd2f44609 | 9608:96c41d4f4aba |
---|---|
10 | 10 |
11 import java.util.Map; | 11 import java.util.Map; |
12 import java.util.SortedMap; | 12 import java.util.SortedMap; |
13 import java.util.TreeMap; | 13 import java.util.TreeMap; |
14 | 14 |
15 public class MovingAverage { | |
15 | 16 |
16 public class MovingAverage | 17 public static double[][] simple(final double[][] values, final double radius) { |
17 { | 18 final TreeMap<Double, Double> map = toMap(values); |
18 | 19 final int N = map.size(); |
19 public static double[][] simple(double[][] values, double radius) { | 20 final double[] xs = new double[N]; |
20 TreeMap<Double, Double> map = toMap(values); | 21 final double[] ys = new double[N]; |
21 int N = map.size(); | |
22 double [] xs = new double[N]; | |
23 double [] ys = new double[N]; | |
24 int ndx = 0; | 22 int ndx = 0; |
25 for (double x: map.keySet()) { | 23 for (final double x : map.keySet()) { |
26 SortedMap<Double, Double> range = | 24 final SortedMap<Double, Double> range = map.subMap(x - radius, true, x + radius, true); |
27 map.subMap(x-radius, true, x+radius, true); | |
28 double avg = 0d; | 25 double avg = 0d; |
29 for (double v: range.values()) { | 26 for (final double v : range.values()) { |
30 avg += v; | 27 avg += v; |
31 } | 28 } |
32 avg /= range.size(); | 29 avg /= range.size(); |
33 xs[ndx] = x; | 30 xs[ndx] = x; |
34 ys[ndx] = avg; | 31 ys[ndx] = avg; |
35 ndx++; | 32 ndx++; |
36 } | 33 } |
37 return new double [][] { xs, ys }; | 34 return new double[][] { xs, ys }; |
38 } | 35 } |
39 | 36 |
40 /** Build moving average over values. Weight them. */ | 37 /** Build moving average over values. Weight them. */ |
41 public static double[][] weighted( | 38 public static double[][] weighted(final double[][] values, final double radius) { |
42 double[][] values, | 39 final TreeMap<Double, Double> map = toMap(values); |
43 double radius | 40 final int N = map.size(); |
44 ) { | 41 final double[] xs = new double[N]; |
45 TreeMap<Double, Double> map = toMap(values); | 42 final double[] ys = new double[N]; |
46 int N = map.size(); | |
47 double [] xs = new double[N]; | |
48 double [] ys = new double[N]; | |
49 int ndx = 0; | 43 int ndx = 0; |
50 double _1radius = 1d/radius; | 44 final double _1radius = 1d / radius; |
51 for (double x: map.keySet()) { | 45 for (final double x : map.keySet()) { |
52 double avg = 0d; | 46 double avg = 0d; |
53 double weights = 0d; | 47 double weights = 0d; |
54 for (Map.Entry<Double, Double> e: | 48 for (final Map.Entry<Double, Double> e : map.subMap(x - radius, false, x + radius, false).entrySet()) { |
55 map.subMap(x-radius, false, x+radius, false).entrySet() | 49 final Double value = e.getValue(); |
56 ) { | 50 |
57 double weight = 1d - Math.abs(x - e.getKey())*_1radius; | 51 if (!value.isNaN()) { |
58 avg += weight*e.getValue(); | 52 final double weight = 1d - Math.abs(x - e.getKey()) * _1radius; |
59 weights += weight; | 53 weights += weight; |
54 avg += weight * value; | |
55 } | |
60 } | 56 } |
57 | |
61 avg /= weights; | 58 avg /= weights; |
62 xs[ndx] = x; | 59 xs[ndx] = x; |
63 ys[ndx] = avg; | 60 ys[ndx] = Double.isNaN(map.get(x)) ? Double.NaN : avg; |
64 ndx++; | 61 ndx++; |
65 } | 62 } |
66 return new double [][] { xs, ys }; | 63 return new double[][] { xs, ys }; |
67 } | 64 } |
68 | 65 |
69 /** From [x1,x2][y1,y2] makes {x1:y1,x2:y2}. Sorted by x! */ | 66 /** From [x1,x2][y1,y2] makes {x1:y1,x2:y2}. Sorted by x! */ |
70 private static TreeMap<Double, Double> toMap(double[][] values) { | 67 private static TreeMap<Double, Double> toMap(final double[][] values) { |
71 TreeMap<Double, Double> map = new TreeMap<Double, Double>(); | 68 final TreeMap<Double, Double> map = new TreeMap<>(); |
72 double [] xs = values[0]; | 69 final double[] xs = values[0]; |
73 double [] ys = values[1]; | 70 final double[] ys = values[1]; |
74 for (int i = 0; i < xs.length; i++) { | 71 for (int i = 0; i < xs.length; i++) { |
75 map.put(xs[i], ys[i]); | 72 map.put(xs[i], ys[i]); |
76 } | 73 } |
77 return map; | 74 return map; |
78 } | 75 } |