sascha@726: package de.intevation.flys.artifacts.model;
sascha@726: 
ingo@2087: import java.util.regex.Matcher;
ingo@2087: import java.util.regex.Pattern;
ingo@2087: 
sascha@1678: import de.intevation.flys.utils.DataUtil;
sascha@1678: 
sascha@726: import gnu.trove.TDoubleArrayList;
sascha@726: 
sascha@1033: import org.apache.log4j.Logger;
sascha@1033: 
sascha@726: public class WQ
sascha@925: extends      NamedObjectImpl
sascha@726: {
ingo@2087:     public static final Pattern NUMBERS_PATTERN =
ingo@2087:         Pattern.compile("\\D*(\\d++.\\d*)\\D*");
ingo@2087: 
ingo@2087: 
sascha@1033:     private static Logger logger = Logger.getLogger(WQ.class);
sascha@1033: 
sascha@925:     // TODO: s/w/ws/g
sascha@726:     protected TDoubleArrayList w;
sascha@726: 
sascha@925:     // TODO: s/q/qs/g
sascha@726:     protected TDoubleArrayList q;
sascha@726: 
sascha@726:     public WQ() {
sascha@726:         this("");
sascha@726:     }
sascha@726: 
sascha@726:     public WQ(String name) {
sascha@726:         w = new TDoubleArrayList();
sascha@726:         q = new TDoubleArrayList();
sascha@726:     }
sascha@726: 
sascha@726:     public WQ(int capacity) {
sascha@726:         this(capacity, "");
sascha@726:     }
sascha@726: 
sascha@726: 
sascha@726:     public WQ(int capacity, String name) {
sascha@726:         super(name);
sascha@726:         w = new TDoubleArrayList(capacity);
sascha@726:         q = new TDoubleArrayList(capacity);
sascha@726:     }
sascha@726: 
sascha@726:     public WQ(double [] qs, double [] ws) {
sascha@726:         this(qs, ws, "");
sascha@726:     }
sascha@726: 
sascha@726:     public WQ(double [] qs, double [] ws, String name) {
sascha@726:         super(name);
sascha@726:         w = new TDoubleArrayList(ws);
sascha@726:         q = new TDoubleArrayList(qs);
sascha@726:     }
sascha@726: 
ingo@2087: 
ingo@2087:     public Double getRawValue() {
ingo@2087:         if (name == null || name.length() == 0) {
ingo@2087:             // this should never happen
ingo@2087:             return null;
ingo@2087:         }
ingo@2087: 
ingo@2087:         Matcher m = NUMBERS_PATTERN.matcher(name);
ingo@2087: 
ingo@2087:         if (m.matches()) {
ingo@2087:             String raw = m.group(1);
ingo@2087: 
ingo@2087:             try {
ingo@2087:                 return Double.valueOf(raw);
ingo@2087:             }
ingo@2087:             catch (NumberFormatException nfe) {
ingo@2087:                 // do nothing
ingo@2087:             }
ingo@2087:         }
ingo@2087: 
ingo@2087:         return null;
ingo@2087:     }
ingo@2087: 
ingo@2087: 
sascha@726:     public void add(double w, double q) {
sascha@726:         this.w.add(w);
sascha@726:         this.q.add(q);
sascha@726:     }
sascha@726: 
sascha@726:     public int size() {
sascha@726:         return w.size();
sascha@726:     }
sascha@726: 
sascha@726:     public double getW(int idx) {
sascha@726:         return w.getQuick(idx);
sascha@726:     }
sascha@726: 
sascha@726:     public double getQ(int idx) {
sascha@726:         return q.getQuick(idx);
sascha@726:     }
sascha@726: 
sascha@726:     public double [] get(int idx) {
sascha@726:         return get(idx, new double [2]);
sascha@726:     }
sascha@726: 
sascha@726:     public double [] get(int idx, double [] dst) {
sascha@726:         dst[0] = w.getQuick(idx);
sascha@726:         dst[1] = q.getQuick(idx);
sascha@726:         return dst;
sascha@726:     }
sascha@726: 
sascha@726:     public double [] getWs() {
sascha@726:         return w.toNativeArray();
sascha@726:     }
sascha@726: 
sascha@726:     public double [] getQs() {
sascha@726:         return q.toNativeArray();
sascha@726:     }
sascha@726: 
sascha@726:     public static void removeNaNs(TDoubleArrayList [] arrays) {
sascha@726: 
sascha@726:         int dest = 0;
sascha@726: 
sascha@726:         int A = arrays.length;
sascha@726:         int N = arrays[0].size();
sascha@726: 
sascha@726:         OUTER: for (int i = 0; i < N; ++i) {
sascha@726:             for (int j = 0; j < A; ++j) {
sascha@726:                 TDoubleArrayList a = arrays[j];
sascha@726:                 double v = a.getQuick(i);
sascha@726:                 if (Double.isNaN(v)) {
sascha@726:                     continue OUTER;
sascha@726:                 }
sascha@726:                 a.setQuick(dest, v);
sascha@726:             }
sascha@726:             ++dest;
sascha@726:         }
sascha@726: 
sascha@726:         if (dest < N) {
sascha@726:             for (int i = 0; i < A; ++i) {
sascha@726:                 arrays[i].remove(dest, N-dest);
sascha@726:             }
sascha@726:         }
sascha@726:     }
sascha@726: 
sascha@726:     public void removeNaNs() {
sascha@726:         removeNaNs(new TDoubleArrayList [] { w, q });
sascha@726:     }
sascha@744: 
sascha@744:     public boolean guessWaterIncreasing() {
sascha@744:         return guessWaterIncreasing(0.05f);
sascha@744:     }
sascha@744: 
sascha@744:     public boolean guessWaterIncreasing(float factor) {
sascha@1678:         return DataUtil.guessWaterIncreasing(w, factor);
sascha@744:     }
sascha@744: 
sascha@1033:     public int [] longestIncreasingWRangeIndices() {
sascha@1033:         return longestIncreasingWRangeIndices(new int[2]);
sascha@1033:     }
sascha@1033: 
sascha@1033:     public int [] longestIncreasingWRangeIndices(int [] bounds) {
sascha@1033: 
sascha@1033:         int N = size();
sascha@1033:         int start = 0;
sascha@1033:         int stop  = 0;
sascha@1033: 
sascha@1033:         double lastW = Double.MAX_VALUE;
sascha@1033: 
sascha@1033:         for (int i = 0; i < N; ++i) {
sascha@1033:             double v = w.getQuick(i);
sascha@1033:             if (v <= lastW) {
sascha@1033:                 if (stop-start > bounds[1]-bounds[0]) {
sascha@1033:                     bounds[0] = start;
sascha@1033:                     bounds[1] = stop;
sascha@1033:                     if (logger.isDebugEnabled()) {
sascha@1033:                         logger.debug("new range: " +
sascha@1033:                             bounds[0] + " - " + bounds[1] + " (" +
sascha@1033:                             w.getQuick(bounds[0]) + ", " +
sascha@1033:                             w.getQuick(bounds[1]) + ")");
sascha@1033: 
sascha@1033:                     }
sascha@1033:                 }
sascha@1033:                 start = stop = i;
sascha@1033:             }
sascha@1033:             else {
sascha@1033:                 stop = i;
sascha@1033:             }
sascha@1033:             lastW = v;
sascha@1033:         }
sascha@1033: 
sascha@1033:         if (stop-start > bounds[1]-bounds[0]) {
sascha@1033:             bounds[0] = start;
sascha@1033:             bounds[1] = stop;
sascha@1033:             if (logger.isDebugEnabled()) {
sascha@1033:                 logger.debug("new range @end: " +
sascha@1033:                     bounds[0] + " - " + bounds[1] + " (" +
sascha@1033:                     w.getQuick(bounds[0]) + ", " +
sascha@1033:                     w.getQuick(bounds[1]) + ")");
sascha@1033: 
sascha@1033:             }
sascha@1033:         }
sascha@1033: 
sascha@1033:         return bounds;
sascha@1033:     }
sascha@726: }
sascha@726: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :