view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQ.java @ 1666:09c1292cf36d

Bugfix: #351 Modified determination of single values specified by min/max values and an interval. flys-artifacts/trunk@2874 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Fri, 30 Sep 2011 14:29:26 +0000
parents 821aaceb2776
children 03fbf1b30e72
line wrap: on
line source
package de.intevation.flys.artifacts.model;

import gnu.trove.TDoubleArrayList;

import java.util.Random;

import org.apache.log4j.Logger;

public class WQ
extends      NamedObjectImpl
{
    private static Logger logger = Logger.getLogger(WQ.class);

    // TODO: s/w/ws/g
    protected TDoubleArrayList w;

    // TODO: s/q/qs/g
    protected TDoubleArrayList q;

    public WQ() {
        this("");
    }

    public WQ(String name) {
        w = new TDoubleArrayList();
        q = new TDoubleArrayList();
    }

    public WQ(int capacity) {
        this(capacity, "");
    }


    public WQ(int capacity, String name) {
        super(name);
        w = new TDoubleArrayList(capacity);
        q = new TDoubleArrayList(capacity);
    }

    public WQ(double [] qs, double [] ws) {
        this(qs, ws, "");
    }

    public WQ(double [] qs, double [] ws, String name) {
        super(name);
        w = new TDoubleArrayList(ws);
        q = new TDoubleArrayList(qs);
    }

    public void add(double w, double q) {
        this.w.add(w);
        this.q.add(q);
    }

    public int size() {
        return w.size();
    }

    public double getW(int idx) {
        return w.getQuick(idx);
    }

    public double getQ(int idx) {
        return q.getQuick(idx);
    }

    public double [] get(int idx) {
        return get(idx, new double [2]);
    }

    public double [] get(int idx, double [] dst) {
        dst[0] = w.getQuick(idx);
        dst[1] = q.getQuick(idx);
        return dst;
    }

    public double [] getWs() {
        return w.toNativeArray();
    }

    public double [] getQs() {
        return q.toNativeArray();
    }

    public static void removeNaNs(TDoubleArrayList [] arrays) {

        int dest = 0;

        int A = arrays.length;
        int N = arrays[0].size();

        OUTER: for (int i = 0; i < N; ++i) {
            for (int j = 0; j < A; ++j) {
                TDoubleArrayList a = arrays[j];
                double v = a.getQuick(i);
                if (Double.isNaN(v)) {
                    continue OUTER;
                }
                a.setQuick(dest, v);
            }
            ++dest;
        }

        if (dest < N) {
            for (int i = 0; i < A; ++i) {
                arrays[i].remove(dest, N-dest);
            }
        }
    }

    public void removeNaNs() {
        removeNaNs(new TDoubleArrayList [] { w, q });
    }

    public boolean guessWaterIncreasing() {
        return guessWaterIncreasing(0.05f);
    }

    public boolean guessWaterIncreasing(float factor) {

        int N = w.size();
        if (N < 2) return false;

        int samples = (int)(factor*N) + 1;

        int up = 0;

        Random rand = new Random();

        for (int i = 0; i < samples; ++i) {
            int    pos2 = rand.nextInt(N-1) + 1;
            if (pos2 == 0) continue;
            int    pos1 = rand.nextInt(pos2);
            double w1   = w.getQuick(pos1);
            double w2   = w.getQuick(pos2);
            if (w2 > w1) ++up;
        }

        return up > samples/2;
    }

    public int [] longestIncreasingWRangeIndices() {
        return longestIncreasingWRangeIndices(new int[2]);
    }

    public int [] longestIncreasingWRangeIndices(int [] bounds) {

        int N = size();
        int start = 0;
        int stop  = 0;

        double lastW = Double.MAX_VALUE;

        for (int i = 0; i < N; ++i) {
            double v = w.getQuick(i);
            if (v <= lastW) {
                if (stop-start > bounds[1]-bounds[0]) {
                    bounds[0] = start;
                    bounds[1] = stop;
                    if (logger.isDebugEnabled()) {
                        logger.debug("new range: " +
                            bounds[0] + " - " + bounds[1] + " (" +
                            w.getQuick(bounds[0]) + ", " +
                            w.getQuick(bounds[1]) + ")");

                    }
                }
                start = stop = i;
            }
            else {
                stop = i;
            }
            lastW = v;
        }

        if (stop-start > bounds[1]-bounds[0]) {
            bounds[0] = start;
            bounds[1] = stop;
            if (logger.isDebugEnabled()) {
                logger.debug("new range @end: " +
                    bounds[0] + " - " + bounds[1] + " (" +
                    w.getQuick(bounds[0]) + ", " +
                    w.getQuick(bounds[1]) + ")");

            }
        }

        return bounds;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org