Mercurial > dive4elements > river
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; |