# HG changeset patch # User Felix Wolfsteller # Date 1321365950 0 # Node ID abf5da3b285c90a96a201920eaf5e6a94b220d9a # Parent d2e217f438bc44afd9a70d23b4af6469fd63e942 Added new (at fixed columns) interpolation mechanism. flys-artifacts/trunk@3248 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r d2e217f438bc -r abf5da3b285c flys-artifacts/ChangeLog --- 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 + + 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 * src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java: diff -r d2e217f438bc -r abf5da3b285c flys-artifacts/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()); }