view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowVelocityKmModelValues.java @ 9096:9bd4505a20dc

Fixed removing duplicates
author mschaefer
date Sat, 26 May 2018 15:41:47 +0200
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.flowdepth;

import org.apache.commons.math.analysis.interpolation.LinearInterpolator;
import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;

import gnu.trove.TDoubleArrayList;
import gnu.trove.TIntArrayList;

/**
 * Sorted arrays of a station's q, v, and tau model values, running in parallel
 *
 * @author Matthias Schäfer
 *
 */
public class FlowVelocityKmModelValues {

    /***** FIELDS *****/

    /**
     * Km
     */
    private final double km;

    /**
     * The station's discharge model values, sorted in ascending order
     */
    private final TDoubleArrayList qs;

    /**
     * Same q values count used to calculate mean
     */
    private final TIntArrayList counts;

    /**
     * The station's main section velocity for the q values
     */
    private final TDoubleArrayList vmains;

    /**
     * The station's shear stress (tau) values for the q values
     */
    private final TDoubleArrayList taus;

    /**
     * Discharge found by the last findQ
     */
    private double findQ;

    /**
     * Velocity found by the last {@link findQ}
     */
    private double vmainFound;

    /**
     * Shear stress found by the last {@link findQ}
     */
    private double tauFound;

    /**
     * Whether qFound has been interpolated
     */
    private boolean isInterpolated;

    /**
     * Real linear interpolator for q and v values
     */
    private PolynomialSplineFunction vInterpolator;

    /**
     * Real linear interpolator for q and tau values
     */
    private PolynomialSplineFunction tauInterpolator;

    /***** CONSTRUCTORS *****/

    /**
     * Constructor with km parameter
     */
    public FlowVelocityKmModelValues(final double km) {
        this.km = km;
        this.qs = new TDoubleArrayList();
        this.counts = new TIntArrayList();
        this.vmains = new TDoubleArrayList();
        this.taus = new TDoubleArrayList();
        this.vInterpolator = null;
        this.tauInterpolator = null;
    }

    /**
     * Copy constructor with new km
     */
    public FlowVelocityKmModelValues(final double km, final FlowVelocityKmModelValues src) {
        this(km);
        src.copyTo(this.qs, this.counts, this.vmains, this.taus);
    }

    /***** METHODS *****/

    /**
     * Number of the q-v-tau tuples
     */
    public int size() {
        return this.qs.size();
    }

    /**
     * Km
     */
    public double getKm() {
        return this.km;
    }

    /**
     * Adds all q-v-tau to another set of arrays
     */
    void copyTo(final TDoubleArrayList dstqs, final TIntArrayList dstcounts, final TDoubleArrayList dstvmains, final TDoubleArrayList dsttaus) {
        for (int i = 0; i <= this.qs.size(); i++) {
            dstqs.add(this.qs.getQuick(i));
            dstcounts.add(this.counts.getQuick(i));
            dstvmains.add(this.vmains.getQuick(i));
            dsttaus.add(this.taus.getQuick(i));
        }
    }

    /**
     * Discharge found by the last {@link findQ}
     *
     * @return
     */
    public double getFindQ() {
        return this.findQ;
    }

    /**
     * Velocity found by the last {@link findQ}
     */
    public double getVmainFound() {
        return this.vmainFound;
    }

    /**
     * Shear stress found by the last {@link findQ}
     */
    public double getTauFound() {
        return this.tauFound;
    }

    /**
     * Whether qFound has been interpolated
     */
    public boolean getIsInterpolated() {
        return this.isInterpolated;
    }

    /**
     * Adds a q-v-tau value triple, averaging the last values if q duplicates.
     */
    public void addValues(final double q, final double vmain, final double tau) {
        final int j = this.qs.size() - 1;
        if ((j >= 0) && (q < this.qs.getQuick(j) + 0.001)) {
            this.qs.setQuick(j, (this.qs.getQuick(j) * this.counts.getQuick(j) + q) / (this.counts.getQuick(j) + 1));
            this.vmains.setQuick(j, (this.vmains.getQuick(j) * this.counts.getQuick(j) + vmain) / (this.counts.getQuick(j) + 1));
            this.taus.setQuick(j, (this.taus.getQuick(j) * this.counts.getQuick(j) + tau) / (this.counts.getQuick(j) + 1));
            this.counts.setQuick(j, this.counts.getQuick(j) + 1);
        }
        else {
            this.qs.add(q);
            this.counts.add(1);
            this.vmains.add(vmain);
            this.taus.add(tau);
        }
    }

    /**
     * Searches a discharge value and returns it or the interpolated value
     *
     * @return Found or interpolated discharge, or NaN otherwise
     */
    public double findQ(final double q) {
        if (this.vInterpolator == null) {
            this.vInterpolator = new LinearInterpolator().interpolate(this.qs.toNativeArray(), this.vmains.toNativeArray());
            this.tauInterpolator = new LinearInterpolator().interpolate(this.qs.toNativeArray(), this.taus.toNativeArray());
        }

        this.findQ = q;

        try {
            this.vmainFound = this.vInterpolator.value(q);
            this.tauFound = this.tauInterpolator.value(q);
            return q;
        }
        catch (final Exception e) {
            e.printStackTrace();
            return Double.NaN;
        }
    }
}

http://dive4elements.wald.intevation.org