changeset 3641:1dc904370a64

Fixed issue687: Rewrote AT export in FixA flys-artifacts/trunk@5361 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 04 Sep 2012 17:32:37 +0000
parents 1d2856de489d
children 83c0735092a3
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java
diffstat 2 files changed, 82 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Tue Sep 04 07:16:21 2012 +0000
+++ b/flys-artifacts/ChangeLog	Tue Sep 04 17:32:37 2012 +0000
@@ -1,3 +1,10 @@
+2012-09-04	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Fix for issue687
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java:
+	  Rewrote AT export to fix it.
+
 2012-09-03	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
 
 	Fix for issue820.
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java	Tue Sep 04 07:16:21 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java	Tue Sep 04 17:32:37 2012 +0000
@@ -14,8 +14,6 @@
 import java.io.PrintWriter;
 import java.io.Writer;
 
-import java.util.ArrayDeque;
-import java.util.Collection;
 import java.util.Locale;
 
 import org.apache.log4j.Logger;
@@ -32,19 +30,8 @@
 
     public static final String [] Q_MAX_COLUMN = new String [] { "max_q" };
 
-    public static class WQ {
-
-        protected double w;
-        protected double q;
-
-        public WQ() {
-        }
-
-        public WQ(double w, double q) {
-            this.w = w;
-            this.q = q;
-        }
-    } // class WQ
+    private static final int    MAX_ITERATIONS = 10000;
+    private static final double EPSILON        = 1e-8;
 
     protected Function   function;
     protected Parameters parameters;
@@ -94,73 +81,61 @@
         de.intevation.flys.artifacts.math.Function invInst =
             inverse.instantiate(coeffs);
 
-        /* TODO: Do some fancy root finding stuff with the
-         * first derivative of the inverse function to find
-         * the minimum of function and directly export
-         * the longest strict monotonous ascending run of
-         * ws of the inverse in range [0, wMax].
-         *
-         * To simplify the situation we iterate in steps
-         * of 10cm over the range and export the longest
-         * run.
-         */
-
-        ArrayDeque<WQ> longest = new ArrayDeque<WQ>();
-        ArrayDeque<WQ> current = new ArrayDeque<WQ>();
+        double wMin = minW(invInst, wMax, qMax[0]);
 
-        for (double w = 0d; w <= wMax; w += 0.1d) {
-            double q = invInst.value(w);
-
-            if (Double.isNaN(q)) {
-                log.debug("Eval of inverse for " + w + " failed.");
-                continue;
-            }
+        double wMinCM = wMin * 100d;
+        double wMaxCM = wMax * 100d;
 
-            WQ wq = new WQ(w, q);
+        int wRow = ((int)wMinCM / 10) * 10;
 
-            if (current.isEmpty() || current.getLast().q < q) {
-                current.add(wq);
-            }
-            else {
-                if (current.size() >= longest.size()) {
-                    longest = current;
-                }
-                current = new ArrayDeque<WQ>();
-                current.add(wq);
+        if ((wMinCM - (int)wMinCM) > 0d) {
+            wMinCM = (int)wMinCM + 1d;
+        }
+
+        double w = wMinCM / 100.0;
+
+        int wcm = ((int)wMinCM) % 10;
+
+        if (log.isDebugEnabled()) {
+            log.debug("wMinCM: " + wMinCM);
+            log.debug("wMaxCM: " + wMaxCM);
+            log.debug("wcm: " + wcm);
+        }
+
+        out.printf(Locale.US, "%8d", wRow);
+
+        if (wcm > 0) {
+            int rest = 10 - wcm;
+            while (rest-- > 0) {
+                out.print(ATWriter.EMPTY);
             }
         }
 
-        if (current.size() >= longest.size()) {
-            longest = current;
+        for (;;) {
+            while (wcm++ < 10) {
+                if (w > wMax) {
+                    break;
+                }
+                double q = invInst.value(w);
+                if (Double.isNaN(w)) {
+                    out.print(ATWriter.EMPTY);
+                }
+                else {
+                    ATWriter.printQ(out, q);
+                }
+                w += 0.01d;
+            }
+            out.println();
+            if (w > wMax) {
+                break;
+            }
+            out.printf(Locale.US, "%8d", wRow += 10);
+            wcm = 0;
         }
 
-        printWQs(out, longest);
         out.flush();
     }
 
-    protected void printWQs(PrintWriter out, Collection<WQ> wqs) {
-        int lastColumn = 10;
-        for (WQ wq: wqs) {
-            int column = (int)(wq.w * 10d) % 10;
-
-            if (lastColumn > column) {
-                for (; lastColumn < 10; ++lastColumn) {
-                    out.print(ATWriter.EMPTY);
-                }
-                out.println();
-                out.printf(Locale.US, "%8d", (int)Math.round(wq.w*100.0));
-                lastColumn = 0;
-            }
-            for (;lastColumn < column-1; ++lastColumn) {
-                out.print(ATWriter.EMPTY);
-            }
-            ATWriter.printQ(out, wq.q);
-
-            lastColumn = column;
-        }
-        out.println();
-    }
-
     protected void printHeader(
         PrintWriter out,
         CallMeta    meta,
@@ -173,5 +148,34 @@
             I18N_HEADER_DEFAULT,
             river, km));
     }
+
+    private static double minW(
+        de.intevation.flys.artifacts.math.Function function,
+        double maxW,
+        double maxQ
+    ) {
+        double stepWidth = 10d;
+
+        double lastW = maxW;
+        double lastQ = maxQ;
+
+        for (int i = 0; i < MAX_ITERATIONS; ++i) {
+            double w = lastW - stepWidth;
+            double q = function.value(w);
+
+            if (Double.isNaN(q) || q > lastQ || q < 0d) {
+                if (stepWidth < EPSILON) {
+                    break;
+                }
+                stepWidth *= 0.5d;
+                continue;
+            }
+
+            lastW = w;
+            lastQ = q;
+        }
+
+        return lastW;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org