Mercurial > dive4elements > river
view 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 |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.artifacts.math; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; public class MovingAverage { public static double[][] simple(final double[][] values, final double radius) { final TreeMap<Double, Double> map = toMap(values); final int N = map.size(); final double[] xs = new double[N]; final double[] ys = new double[N]; int ndx = 0; for (final double x : map.keySet()) { final SortedMap<Double, Double> range = map.subMap(x - radius, true, x + radius, true); double avg = 0d; for (final double v : range.values()) { avg += v; } avg /= range.size(); xs[ndx] = x; ys[ndx] = avg; ndx++; } return new double[][] { xs, ys }; } /** Build moving average over values. Weight them. */ public static double[][] weighted(final double[][] values, final double radius) { final TreeMap<Double, Double> map = toMap(values); final int N = map.size(); final double[] xs = new double[N]; final double[] ys = new double[N]; int ndx = 0; final double _1radius = 1d / radius; for (final double x : map.keySet()) { double avg = 0d; double weights = 0d; for (final Map.Entry<Double, Double> e : map.subMap(x - radius, false, x + radius, false).entrySet()) { final Double value = e.getValue(); if (!value.isNaN()) { final double weight = 1d - Math.abs(x - e.getKey()) * _1radius; weights += weight; avg += weight * value; } } avg /= weights; xs[ndx] = x; ys[ndx] = Double.isNaN(map.get(x)) ? Double.NaN : avg; ndx++; } return new double[][] { xs, ys }; } /** From [x1,x2][y1,y2] makes {x1:y1,x2:y2}. Sorted by x! */ private static TreeMap<Double, Double> toMap(final double[][] values) { final TreeMap<Double, Double> map = new TreeMap<>(); final double[] xs = values[0]; final double[] ys = values[1]; for (int i = 0; i < xs.length; i++) { map.put(xs[i], ys[i]); } return map; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :