[PATCH] (issue1787) Sort WQ data locally over Q bevor lookup of Qs for given W
Wald Commits
scm-commit at wald.intevation.org
Thu Apr 23 19:13:47 CEST 2015
# HG changeset patch
# User Tom Gottfried <tom at intevation.de>
# Date 1429809213 -7200
# Node ID 93a31cfb18c04c712adbc514f5f4921664fbd432
# Parent e4f9e2316e92813f819e4761036f8d177ea287b0
(issue1787) Sort WQ data locally over Q bevor lookup of Qs for given W.
diff -r e4f9e2316e92 -r 93a31cfb18c0 artifacts/src/main/java/org/dive4elements/river/artifacts/WINFOArtifact.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/WINFOArtifact.java Thu Apr 23 19:06:41 2015 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/WINFOArtifact.java Thu Apr 23 19:13:33 2015 +0200
@@ -229,7 +229,7 @@
log.debug("Determine Q values based on a set of W values.");
qSel = false;
ws = getWs();
- double [][] qws = getQsForWs(ws);
+ double [][] qws = getQsForWs(ws, report);
if (qws == null || qws.length == 0) {
return error(new WQKms[0], "converting.ws.to.qs.failed");
}
@@ -661,7 +661,7 @@
*
* @return an array of Q values.
*/
- public double [][] getQsForWs(double[] ws) {
+ public double [][] getQsForWs(double[] ws, Calculation report) {
if (ws == null) {
log.error("getQsForWs: ws == null");
@@ -708,8 +708,8 @@
if (debug) {
log.debug("getQsForWs: lookup Q for W: " + w);
}
- // There could bemore than one Q per W.
- double [] qs = wst.findQsForW(km, w);
+ // There could be more than one Q per W.
+ double [] qs = wst.findQsForW(km, w, report);
for (int j = 0; j < qs.length; ++j) {
outWs.add(ws[i]);
outQs.add(qs[j]);
diff -r e4f9e2316e92 -r 93a31cfb18c0 artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java Thu Apr 23 19:06:41 2015 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java Thu Apr 23 19:13:33 2015 +0200
@@ -202,6 +202,134 @@
}
/**
+ * Sort Qs and Ws for this Row over Q.
+ */
+ private double[][] getSortedWQ(
+ WstValueTable table,
+ Calculation errors
+ ) {
+ int W = ws.length;
+
+ if (W < 1) {
+ if (errors != null) {
+ errors.addProblem(km, "no.ws.found");
+ }
+ return new double[][] {{Double.NaN}, {Double.NaN}};
+ }
+
+ double [] sortedWs = ws;
+ double [] sortedQs = new double[W];
+
+ for (int i=0; i < W; ++i) {
+ double q = table.getQIndex(i, km);
+ if (Double.isNaN(q) && errors != null) {
+ errors.addProblem(
+ km, "no.q.found.in.column", i+1);
+ }
+ sortedQs[i] = q;
+ }
+
+ DoubleUtil.sortByFirst(sortedQs, sortedWs);
+
+ return new double[][] { sortedWs, sortedQs };
+ }
+
+ /**
+ * Return an array of Qs and Ws for the given km between
+ * this Row and another, sorted over Q.
+ */
+ private double[][] getSortedWQ(
+ Row other,
+ double km,
+ WstValueTable table,
+ Calculation errors
+ ) {
+ int W = Math.min(ws.length, other.ws.length);
+
+ if (W < 1) {
+ if (errors != null) {
+ errors.addProblem("no.ws.found");
+ }
+ return new double[][] {{Double.NaN}, {Double.NaN}};
+ }
+
+ double factor = Linear.factor(km, this.km, other.km);
+
+ double [] sortedQs = new double[W];
+ double [] sortedWs = new double[W];
+
+ for (int i = 0; i < W; ++i) {
+ double wws = Linear.weight(factor, ws[i], other.ws[i]);
+ double wqs = table.getQIndex(i, km);
+
+ if (Double.isNaN(wws) || Double.isNaN(wqs)) {
+ if (errors != null) {
+ errors.addProblem(km, "cannot.find.w.or.q");
+ }
+ }
+
+ sortedWs[i] = wws;
+ sortedQs[i] = wqs;
+ }
+
+ DoubleUtil.sortByFirst(sortedQs, sortedWs);
+
+ return new double[][] { sortedWs, sortedQs };
+ }
+
+ /**
+ * Find Qs matching w in an array of Qs and Ws sorted over Q.
+ */
+ private double[] findQsForW(double w, double[][] sortedWQ) {
+ int W = sortedWQ[0].length;
+
+ double[] sortedQs = sortedWQ[1];
+ double[] sortedWs = sortedWQ[0];
+
+ TDoubleArrayList qs = new TDoubleArrayList();
+
+ if (W > 0 && Math.abs(sortedWs[0]-w) < W_EPSILON) {
+ double q = sortedQs[0];
+ if (!Double.isNaN(q)) {
+ qs.add(q);
+ }
+ }
+
+ for (int i = 1; i < W; ++i) {
+ double w2 = sortedWs[i];
+ if (Double.isNaN(w2)) {
+ continue;
+ }
+ if (Math.abs(w2-w) < W_EPSILON) {
+ double q = sortedQs[i];
+ if (!Double.isNaN(q)) {
+ qs.add(q);
+ }
+ continue;
+ }
+ double w1 = sortedWs[i-1];
+ if (Double.isNaN(w1)) {
+ continue;
+ }
+
+ if (w < Math.min(w1, w2) || w > Math.max(w1, w2)) {
+ continue;
+ }
+
+ double q1 = sortedQs[i-1];
+ double q2 = sortedQs[i];
+ if (Double.isNaN(q1) || Double.isNaN(q2)) {
+ continue;
+ }
+
+ double q = Linear.linear(w, w1, w2, q1, q2);
+ qs.add(q);
+ }
+
+ return qs.toNativeArray();
+ }
+
+ /**
* Compare according to place of measurement (km).
*/
public int compareTo(Row other) {
@@ -256,36 +384,14 @@
WstValueTable table,
Calculation errors
) {
- int W = ws.length;
-
- if (W < 1) {
- if (errors != null) {
- errors.addProblem(km, "no.ws.found");
- }
- return null;
- }
-
- double [] splineQs = new double[W];
- double [] splineWs = new double[W];
-
- for (int i = 0; i < W; ++i) {
- double sq = table.getQIndex(i, km);
- if (Double.isNaN(sq) && errors != null) {
- errors.addProblem(
- km, "no.q.found.in.column", (i+1));
- }
- splineQs[i] = sq;
- splineWs[i] = ws[i];
- }
-
- DoubleUtil.sortByFirst(splineQs, splineWs);
+ double[][] sortedWQ = getSortedWQ(table, errors);
try {
SplineInterpolator interpolator = new SplineInterpolator();
PolynomialSplineFunction spline =
- interpolator.interpolate(splineQs, splineWs);
+ interpolator.interpolate(sortedWQ[1], sortedWQ[0]);
- return new SplineFunction(spline, splineQs, ws);
+ return new SplineFunction(spline, sortedWQ[1], ws);
}
catch (MathIllegalArgumentException miae) {
if (errors != null) {
@@ -302,46 +408,15 @@
WstValueTable table,
Calculation errors
) {
- int W = Math.min(ws.length, other.ws.length);
-
- if (W < 1) {
- if (errors != null) {
- errors.addProblem("no.ws.found");
- }
- return null;
- }
-
- double factor = Linear.factor(km, this.km, other.km);
-
- double [] splineQs = new double[W];
- double [] splineWs = new double[W];
-
- for (int i = 0; i < W; ++i) {
- double wws = Linear.weight(factor, ws[i], other.ws[i]);
- double wqs = Linear.weight(
- factor,
- table.getQIndex(i, km),
- table.getQIndex(i, other.km));
-
- if (Double.isNaN(wws) || Double.isNaN(wqs)) {
- if (errors != null) {
- errors.addProblem(km, "cannot.find.w.or.q");
- }
- }
-
- splineWs[i] = wws;
- splineQs[i] = wqs;
- }
-
- DoubleUtil.sortByFirst(splineQs, splineWs);
+ double[][] sortedWQ = getSortedWQ(other, km, table, errors);
SplineInterpolator interpolator = new SplineInterpolator();
try {
PolynomialSplineFunction spline =
- interpolator.interpolate(splineQs, splineWs);
+ interpolator.interpolate(sortedWQ[1], sortedWQ[0]);
- return new SplineFunction(spline, splineQs, splineWs);
+ return new SplineFunction(spline, sortedWQ[1], sortedWQ[0]);
}
catch (MathIllegalArgumentException miae) {
if (errors != null) {
@@ -414,104 +489,24 @@
return Linear.weight(kmWeight, tw, ow);
}
- public double [] findQsForW(double w, WstValueTable table) {
-
- TDoubleArrayList qs = new TDoubleArrayList();
-
- if (ws.length > 0 && Math.abs(ws[0]-w) < W_EPSILON) {
- double q = table.getQIndex(0, km);
- if (!Double.isNaN(q)) {
- qs.add(q);
- }
- }
-
- for (int i = 1; i < ws.length; ++i) {
- double w2 = ws[i];
- if (Double.isNaN(w2)) {
- continue;
- }
- if (Math.abs(w2-w) < W_EPSILON) {
- double q = table.getQIndex(i, km);
- if (!Double.isNaN(q)) {
- qs.add(q);
- }
- continue;
- }
- double w1 = ws[i-1];
- if (Double.isNaN(w1)) {
- continue;
- }
-
- if (w < Math.min(w1, w2) || w > Math.max(w1, w2)) {
- continue;
- }
-
- double q1 = table.getQIndex(i-1, km);
- double q2 = table.getQIndex(i, km);
- if (Double.isNaN(q1) || Double.isNaN(q2)) {
- continue;
- }
-
- double q = Linear.linear(w, w1, w2, q1, q2);
- qs.add(q);
- }
-
- return qs.toNativeArray();
+ public double [] findQsForW(
+ double w,
+ WstValueTable table,
+ Calculation errors
+ ) {
+ log.debug("Find Qs for given W at tabulated km " + km);
+ return findQsForW(w, getSortedWQ(table, errors));
}
public double [] findQsForW(
Row other,
double w,
double km,
- WstValueTable table
+ WstValueTable table,
+ Calculation errors
) {
- TDoubleArrayList qs = new TDoubleArrayList();
-
- double factor = Linear.factor(km, this.km, other.km);
-
- if (ws.length > 0) {
- double wt = Linear.weight(factor, ws[0], other.ws[0]);
- if (Math.abs(wt-w) < W_EPSILON) {
- double q = table.getQIndex(0, km);
- if (!Double.isNaN(q)) {
- qs.add(q);
- }
- }
- }
-
- for (int i = 1; i < ws.length; ++i) {
- double w2 = Linear.weight(factor, ws[i], other.ws[i]);
- if (Double.isNaN(w2)) {
- continue;
- }
- if (Math.abs(w2-w) < W_EPSILON) {
- double q = table.getQIndex(i, km);
- if (!Double.isNaN(q)) {
- qs.add(q);
- }
- continue;
- }
-
- double w1 = Linear.weight(factor, ws[i-1], other.ws[i-1]);
- if (Double.isNaN(w1)) {
- continue;
- }
-
- if (w < Math.min(w1, w2) || w > Math.max(w1, w2)) {
- continue;
- }
-
- double q1 = table.getQIndex(i-1, km);
- double q2 = table.getQIndex(i, km);
- if (Double.isNaN(q1) || Double.isNaN(q2)) {
- continue;
- }
-
- double q = Linear.linear(w, w1, w2, q1, q2);
- qs.add(q);
- }
-
- return qs.toNativeArray();
+ log.debug("Find Qs for given W at non-tabulated km " + km);
+ return findQsForW(w, getSortedWQ(other, km, table, errors));
}
public double [] getMinMaxW(double [] result) {
@@ -1008,12 +1003,12 @@
return new double [][] {qs, ws};
}
- public double [] findQsForW(double km, double w) {
+ public double [] findQsForW(double km, double w, Calculation errors) {
int rowIndex = Collections.binarySearch(rows, new Row(km));
if (rowIndex >= 0) {
- return rows.get(rowIndex).findQsForW(w, this);
+ return rows.get(rowIndex).findQsForW(w, this, errors);
}
rowIndex = -rowIndex - 1;
@@ -1027,7 +1022,7 @@
Row r1 = rows.get(rowIndex-1);
Row r2 = rows.get(rowIndex);
- return r1.findQsForW(r2, w, km, this);
+ return r1.findQsForW(r2, w, km, this, errors);
}
protected SplineFunction createSpline(double km, Calculation errors) {
More information about the Dive4Elements-commits
mailing list