Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/LinearInterpolator.java @ 9602:6b2496d71936
Reimplemented baseline for tkh. Extended area-dataset to be able to draw baseline.
author | gernotbelger |
---|---|
date | Tue, 12 Feb 2019 14:08:16 +0100 |
parents | 45f1ad66560e |
children |
line wrap: on
line source
/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde * Software engineering by * Björnsen Beratende Ingenieure GmbH * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt * * 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.sinfo.util; import java.util.Map.Entry; import java.util.NavigableMap; import java.util.TreeMap; import org.dive4elements.river.artifacts.math.Linear; import org.dive4elements.river.artifacts.model.Calculation; import gnu.trove.TDoubleArrayList; /** * Helper for interpolating values from a piecewise linear function defined by discrete values. * * @author Gernot Belger */ public final class LinearInterpolator { private final NavigableMap<Double, Double> data; private final double maxDistance; private Calculation problems; public static LinearInterpolator create(final Calculation problems, final TDoubleArrayList xs, final TDoubleArrayList ys, final double maxDistance) { if (xs.size() != ys.size()) throw new IllegalArgumentException("Array sizes must be equal"); if (xs.size() < 2) throw new IllegalArgumentException("Array must have at least 2 values"); final NavigableMap<Double, Double> data = new TreeMap<>(); for (int i = 0; i < xs.size(); i++) { final double x = xs.getQuick(i); final double y = ys.getQuick(i); data.put(x, y); } return new LinearInterpolator(problems, data, maxDistance); } private LinearInterpolator(final Calculation problems, final NavigableMap<Double, Double> data, final double maxDistance) { this.problems = problems; this.data = data; this.maxDistance = maxDistance; } public double value(final double value) { final Entry<Double, Double> floorEntry = this.data.floorEntry(value); final Entry<Double, Double> ceilingEntry = this.data.ceilingEntry(value); if (floorEntry == null || ceilingEntry == null) return Double.NaN; final double floorKey = floorEntry.getKey(); final double floorValue = floorEntry.getValue(); final double ceilingKey = ceilingEntry.getKey(); final double ceilingValue = ceilingEntry.getValue(); if (Math.abs(floorKey - ceilingKey) > this.maxDistance && this.problems != null) { this.problems.addProblem(value, "linearInterpolator.maxdistance", this.maxDistance * 1000); this.problems = null; } return Linear.linear(value, floorKey, ceilingKey, floorValue, ceilingValue); } }