comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java @ 1938:1d991c91285b

Refactored the code of the 'berechnete Abflusskurve' to be reusable in the 'Bezugslinienverfahren'. flys-artifacts/trunk@3319 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 25 Nov 2011 17:27:40 +0000
parents f07d64d5cbe1
children 2730d17df021
comparison
equal deleted inserted replaced
1937:f07d64d5cbe1 1938:1d991c91285b
164 ows[i] = Double.NaN; 164 ows[i] = Double.NaN;
165 } 165 }
166 } 166 }
167 } 167 }
168 168
169 public static final class SplineFunction {
170
171 public PolynomialSplineFunction spline;
172 public double [] splineQs;
173 public double [] splineWs;
174
175 public SplineFunction(
176 PolynomialSplineFunction spline,
177 double [] splineQs,
178 double [] splineWs
179 ) {
180 this.spline = spline;
181 this.splineQs = splineQs;
182 this.splineWs = splineWs;
183 }
184
185 public double [][] sample(
186 int numSamples,
187 double km,
188 Calculation errors
189 ) {
190 double q1 = splineQs[0], qN = splineQs[splineQs.length-1];
191 double minQ = Math.min(q1, qN);
192 double maxQ = Math.max(q1, qN);
193
194 double [] outWs = new double[numSamples];
195 double [] outQs = new double[numSamples];
196
197 Arrays.fill(outWs, Double.NaN);
198 Arrays.fill(outQs, Double.NaN);
199
200 double stepWidth = (maxQ - minQ)/numSamples;
201
202 try {
203 double q = minQ;
204 for (int i = 0; i < outWs.length; ++i, q += stepWidth) {
205 outWs[i] = spline.value(outQs[i] = q);
206 }
207 }
208 catch (ArgumentOutsideDomainException aode) {
209 if (errors != null) {
210 // TODO: I18N
211 errors.addProblem(km, "spline interpolation failed");
212 }
213 log.error("spline interpolation failed.", aode);
214 }
215
216 return new double [][] { outWs, outQs };
217 }
218 } // class SplineFunction
219
220 public SplineFunction createSpline(
221 WstValueTable table,
222 Calculation errors
223 ) {
224 int W = ws.length;
225
226 if (W < 1) {
227 if (errors != null) {
228 // TODO: I18N
229 errors.addProblem(km, "no ws found");
230 }
231 return null;
232 }
233
234 double [] splineQs = new double[W];
235
236 for (int i = 0; i < W; ++i) {
237 double sq = table.getQIndex(i, km);
238 if (Double.isNaN(sq) && errors != null) {
239 // TODO: I18N
240 errors.addProblem(
241 km, "no q found in " + (i+1) + " column");
242 }
243 splineQs[i] = sq;
244 }
245
246 try {
247 SplineInterpolator interpolator = new SplineInterpolator();
248 PolynomialSplineFunction spline =
249 interpolator.interpolate(splineQs, ws);
250
251 return new SplineFunction(spline, splineQs, ws);
252 }
253 catch (MathIllegalArgumentException miae) {
254 if (errors != null) {
255 // TODO: I18N
256 errors.addProblem(km, "spline creation failed");
257 }
258 log.error("spline creation failed", miae);
259 }
260 return null;
261 }
262
263 public SplineFunction createSpline(
264 Row other,
265 double km,
266 WstValueTable table,
267 Calculation errors
268 ) {
269 int W = Math.min(ws.length, other.ws.length);
270
271 if (W < 1) {
272 if (errors != null) {
273 // TODO: I18N
274 errors.addProblem("no ws found");
275 }
276 return null;
277 }
278
279 double factor = Linear.factor(km, this.km, other.km);
280
281 double [] splineQs = new double[W];
282 double [] splineWs = new double[W];
283
284 for (int i = 0; i < W; ++i) {
285 double wws = Linear.weight(factor, ws[i], other.ws[i]);
286 double wqs = Linear.weight(
287 factor,
288 table.getQIndex(i, km),
289 table.getQIndex(i, other.km));
290
291 if (Double.isNaN(wws) || Double.isNaN(wqs)) {
292 if (errors != null) {
293 // TODO: I18N
294 errors.addProblem(km, "cannot find w or q");
295 }
296 }
297
298 splineWs[i] = wws;
299 splineQs[i] = wqs;
300 }
301
302 SplineInterpolator interpolator = new SplineInterpolator();
303
304 try {
305 PolynomialSplineFunction spline =
306 interpolator.interpolate(splineQs, splineWs);
307
308 return new SplineFunction(spline, splineQs, splineWs);
309 }
310 catch (MathIllegalArgumentException miae) {
311 if (errors != null) {
312 // TODO: I18N
313 errors.addProblem(km, "spline creation failed");
314 }
315 log.error("spline creation failed", miae);
316 }
317
318 return null;
319 }
320
169 public double [][] interpolateWQ( 321 public double [][] interpolateWQ(
170 Row other, 322 Row other,
171 double km, 323 double km,
172 int steps, 324 int steps,
173 WstValueTable table, 325 WstValueTable table,
174 Calculation errors 326 Calculation errors
175 ) { 327 ) {
176 int W = Math.min(ws.length, other.ws.length); 328 SplineFunction sf = createSpline(other, km, table, errors);
177 329
178 if (W < 1) { 330 return sf != null
179 if (errors != null) { 331 ? sf.sample(steps, km, errors)
180 // TODO: I18N 332 : new double[2][0];
181 errors.addProblem("no ws found");
182 }
183 return new double[2][0];
184 }
185
186 double factor = Linear.factor(km, this.km, other.km);
187
188 double [] splineQ = new double[W];
189 double [] splineW = new double[W];
190
191 double minQ = Double.MAX_VALUE;
192 double maxQ = -Double.MAX_VALUE;
193
194 for (int i = 0; i < W; ++i) {
195 double wws = Linear.weight(factor, ws[i], other.ws[i]);
196 double wqs = Linear.weight(
197 factor,
198 table.getQIndex(i, km),
199 table.getQIndex(i, other.km));
200
201 if (Double.isNaN(wws) || Double.isNaN(wqs)) {
202 if (errors != null) {
203 // TODO: I18N
204 errors.addProblem(km, "cannot find w or q");
205 }
206 }
207 else {
208 if (wqs < minQ) minQ = wqs;
209 if (wqs > maxQ) maxQ = wqs;
210 }
211
212 splineW[i] = wws;
213 splineQ[i] = wqs;
214 }
215
216 double stepWidth = (maxQ - minQ)/steps;
217
218 SplineInterpolator interpolator = new SplineInterpolator();
219 PolynomialSplineFunction spline;
220
221 try {
222 spline = interpolator.interpolate(splineQ, splineW);
223 }
224 catch (MathIllegalArgumentException miae) {
225 if (errors != null) {
226 // TODO: I18N
227 errors.addProblem(km, "spline creation failed");
228 }
229 log.error("spline creation failed", miae);
230 return new double[2][0];
231 }
232
233 double [] outWs = new double[steps];
234 double [] outQs = new double[steps];
235
236 Arrays.fill(outWs, Double.NaN);
237 Arrays.fill(outQs, Double.NaN);
238
239 try {
240 double q = minQ;
241 for (int i = 0; i < outWs.length; ++i, q += stepWidth) {
242 outWs[i] = spline.value(outQs[i] = q);
243 }
244 }
245 catch (ArgumentOutsideDomainException aode) {
246 if (errors != null) {
247 // TODO: I18N
248 errors.addProblem(km, "spline interpolation failed");
249 }
250 log.error("spline interpolation failed", aode);
251 }
252
253 return new double [][] { outWs, outQs };
254 } 333 }
255 334
256 335
257 public double [][] interpolateWQ( 336 public double [][] interpolateWQ(
258 int steps, 337 int steps,
259 WstValueTable table, 338 WstValueTable table,
260 Calculation errors 339 Calculation errors
261 ) { 340 ) {
262 int W = ws.length; 341 SplineFunction sf = createSpline(table, errors);
263 342
264 if (W < 1) { 343 return sf != null
265 if (errors != null) { 344 ? sf.sample(steps, km, errors)
266 // TODO: I18N 345 : new double[2][0];
267 errors.addProblem(km, "no ws found");
268 }
269 return new double[2][0];
270 }
271
272 double [] splineQ = new double[W];
273
274 double minQ = Double.MAX_VALUE;
275 double maxQ = -Double.MAX_VALUE;
276
277 for (int i = 0; i < W; ++i) {
278 double sq = table.getQIndex(i, km);
279 if (Double.isNaN(sq)) {
280 if (errors != null) {
281 // TODO: I18N
282 errors.addProblem(
283 km, "no q found in " + (i+1) + " column");
284 }
285 }
286 else {
287 if (sq < minQ) minQ = sq;
288 if (sq > maxQ) maxQ = sq;
289 }
290 splineQ[i] = sq;
291 }
292
293 double stepWidth = (maxQ - minQ)/steps;
294
295 SplineInterpolator interpolator = new SplineInterpolator();
296
297 PolynomialSplineFunction spline;
298
299 try {
300 spline = interpolator.interpolate(splineQ, ws);
301 }
302 catch (MathIllegalArgumentException miae) {
303 if (errors != null) {
304 // TODO: I18N
305 errors.addProblem(km, "spline creation failed");
306 }
307 log.error("spline creation failed", miae);
308 return new double[2][0];
309 }
310
311 double [] outWs = new double[steps];
312 double [] outQs = new double[steps];
313
314 Arrays.fill(outWs, Double.NaN);
315 Arrays.fill(outQs, Double.NaN);
316
317 try {
318 double q = minQ;
319 for (int i = 0; i < outWs.length; ++i, q += stepWidth) {
320 outWs[i] = spline.value(outQs[i] = q);
321 }
322 }
323 catch (ArgumentOutsideDomainException aode) {
324 if (errors != null) {
325 // TODO: I18N
326 errors.addProblem(km, "spline interpolation failed");
327 }
328 log.error("spline interpolation failed.", aode);
329 }
330
331 return new double [][] { outWs, outQs };
332 } 346 }
333 347
334 348
335 public double getW(QPosition qPosition) { 349 public double getW(QPosition qPosition) {
336 int index = qPosition.index; 350 int index = qPosition.index;

http://dive4elements.wald.intevation.org