changeset 1888:abf5da3b285c

Added new (at fixed columns) interpolation mechanism. flys-artifacts/trunk@3248 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Tue, 15 Nov 2011 14:05:50 +0000 (2011-11-15)
parents d2e217f438bc
children ad22fc70bdab
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java
diffstat 2 files changed, 81 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Mon Nov 14 10:11:57 2011 +0000
+++ b/flys-artifacts/ChangeLog	Tue Nov 15 14:05:50 2011 +0000
@@ -1,3 +1,13 @@
+2011-11-15  Felix Wolfsteller <felix.wolfsteller@intevation.de>
+
+	Added new interpolation mechanism to WstValueTable to interpolate
+	given columns only.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java
+	  (linearW): New, interpolate a given columns w's between given rows.
+	  (interpolateWQColumnwise): New, interpolate between rows ws at a
+				     given column and km.
+
 2011-11-14  Felix Wolfsteller <felix.wolfsteller@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Mon Nov 14 10:11:57 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Tue Nov 15 14:05:50 2011 +0000
@@ -616,7 +616,7 @@
                 if (errors != null) {
                     errors.addProblem(kms[i], "cannot find km");
                 }
-                ws[i] =  Double.NaN;
+                ws[i] = Double.NaN;
                 continue;
             }
             Row r1 = rows.get(rowIndex-1);
@@ -631,6 +631,76 @@
         return qPosition;
     }
 
+    /**
+     * Linearly interpolate w at a km at a column of two rows.
+     *
+     * @param km   position for which to interpolate.
+     * @param row1 first row.
+     * @param row2 second row.
+     * @param col  column-index at which to look.
+     *
+     * @return Linearly interpolated w, NaN if one of the given rows was null.
+     */
+    public static double linearW(double km, Row row1, Row row2, int col) {
+        if (row1 == null || row2 == null) {
+            return Double.NaN;
+        }
+
+        return Linear.linear(km,
+            row1.km, row2.km,
+            row1.ws[col], row2.ws[col]);
+    }
+
+    /**
+     * Do interpolation/lookup of W and Q within columns (i.e. ignoring values
+     * of other columns).
+     * @param km position (km) at which to interpolate/lookup.
+     * @return [[q0, q1, .. qx] , [w0, w1, .. wx]] (can contain NaNs)
+     */
+    public double [][] interpolateWQColumnwise(double km) {
+        double [] qs = new double[columns.length];
+        double [] ws = new double[columns.length];
+
+        // Find out row from where we will start searching.
+        int rowIndex = Collections.binarySearch(rows, new Row(km));
+
+        if (rowIndex < 0) {
+            rowIndex = -rowIndex -1;
+        }
+
+        Row startRow = rows.get(rowIndex);
+
+        for (int col = 0; col < columns.length; col++) {
+            qs[col] = columns[col].getQRangeTree().findQ(km);
+            if (startRow.km == km && startRow.ws[col] != Double.NaN) {
+                // Great. W is defined at km.
+                ws[col] = startRow.ws[col];
+                continue;
+            }
+
+            // Search neighbouring rows that define w at this col.
+            Row rowBefore = null;
+            Row rowAfter  = null;
+            for (int before = rowIndex; before >= 0; before--) {
+                if (!Double.isNaN(rows.get(before).ws[col])) {
+                    rowBefore = rows.get(before);
+                    break;
+                }
+            }
+            for (int after = rowIndex; after < rows.size(); after++) {
+                if (!Double.isNaN(rows.get(after).ws[col])) {
+                    log.error("rows.get(after).ws[col] " + rows.get(after).ws[col]);
+                    rowAfter = rows.get(after);
+                    break;
+                }
+            }
+
+            ws[col] = linearW(km, rowBefore, rowAfter, col);
+        }
+
+        return new double [][] {qs, ws};
+    }
+
     public QPosition getQPosition(double km, double q) {
         return getQPosition(km, q, new QPosition());
     }

http://dive4elements.wald.intevation.org