# HG changeset patch # User Sascha L. Teichmann # Date 1346779957 0 # Node ID 1dc904370a6476de42d9c44bf670494d3f37bcd3 # Parent 1d2856de489dc1e598b1af592b74100e981257c2 Fixed issue687: Rewrote AT export in FixA flys-artifacts/trunk@5361 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 1d2856de489d -r 1dc904370a64 flys-artifacts/ChangeLog --- 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 + + Fix for issue687 + + * src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java: + Rewrote AT export to fix it. + 2012-09-03 Felix Wolfsteller Fix for issue820. diff -r 1d2856de489d -r 1dc904370a64 flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java --- 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 longest = new ArrayDeque(); - ArrayDeque current = new ArrayDeque(); + 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(); - 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 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 :