teichmann@4630: package de.intevation.flys.artifacts.math;
rrenkert@4625: 
rrenkert@4625: import java.util.Map;
rrenkert@4625: import java.util.SortedMap;
rrenkert@4625: import java.util.TreeMap;
rrenkert@4625: 
rrenkert@4625: 
rrenkert@4625: public class MovingAverage
rrenkert@4625: {
rrenkert@4625: 
rrenkert@4625:     public static double[][] simple(double[][] values, double radius) {
rrenkert@4625:         TreeMap<Double, Double> map = toMap(values);
teichmann@4631:         int N = map.size();
teichmann@4631:         double [] xs = new double[N];
teichmann@4631:         double [] ys = new double[N];
rrenkert@4625:         int ndx = 0;
rrenkert@4625:         for (double x: map.keySet()) {
rrenkert@4625:             SortedMap<Double, Double> range =
rrenkert@4625:                 map.subMap(x-radius, true, x+radius, true);
rrenkert@4625:             double avg = 0d;
teichmann@4631:             for (double v: range.values()) {
rrenkert@4625:                 avg += v;
rrenkert@4625:             }
rrenkert@4625:             avg /= range.size();
teichmann@4631:             xs[ndx] = x;
teichmann@4631:             ys[ndx] = avg;
rrenkert@4625:             ndx++;
rrenkert@4625:         }
teichmann@4631:         return new double [][] { xs, ys };
rrenkert@4625:     }
rrenkert@4625: 
rrenkert@4625:     public static double[][] weighted(double[][] values, double radius) {
rrenkert@4625:         TreeMap<Double, Double> map = toMap(values);
teichmann@4631:         int N = map.size();
teichmann@4631:         double [] xs = new double[N];
teichmann@4631:         double [] ys = new double[N];
rrenkert@4625:         int ndx = 0;
teichmann@4631:         double _1radius = 1d/radius;
rrenkert@4625:         for (double x: map.keySet()) {
rrenkert@4625:             double avg = 0d;
rrenkert@4625:             double weights = 0d;
rrenkert@4625:             for (Map.Entry<Double, Double> e:
rrenkert@4625:                 map.subMap(x-radius, false, x+radius, false).entrySet()
rrenkert@4625:             ) {
teichmann@4631:                 double weight = 1d - Math.abs(x - e.getKey())*_1radius;
rrenkert@4625:                 avg += weight*e.getValue();
rrenkert@4625:                 weights += weight;
rrenkert@4625:             }
rrenkert@4625:             avg /= weights;
teichmann@4631:             xs[ndx] = x;
teichmann@4631:             ys[ndx] = avg;
rrenkert@4625:             ndx++;
rrenkert@4625:         }
teichmann@4631:         return new double [][] { xs, ys };
rrenkert@4625:     }
rrenkert@4625: 
rrenkert@4625:     private static TreeMap<Double, Double> toMap(double[][] values) {
rrenkert@4625:         TreeMap<Double, Double> map = new TreeMap<Double, Double>();
teichmann@4631:         double [] xs = values[0];
teichmann@4631:         double [] ys = values[1];
teichmann@4631:         for (int i = 0; i < xs.length; i++) {
teichmann@4631:             map.put(xs[i], ys[i]);
rrenkert@4625:         }
rrenkert@4625:         return map;
rrenkert@4625:     }
rrenkert@4625: }