Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQRelationCalculation.java @ 6796:978ab716a15e
flys/issue1347: Added missing calcutions. TODO: Bring them into the generated outs.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Fri, 09 Aug 2013 18:24:55 +0200 |
parents | 51eb6491c537 |
children | e237a83fd87d |
comparison
equal
deleted
inserted
replaced
6795:0747ca95ad6e | 6796:978ab716a15e |
---|---|
35 public static final boolean NON_LINEAR_FITTING = | 35 public static final boolean NON_LINEAR_FITTING = |
36 Boolean.getBoolean("minfo.sq.calcution.non.linear.fitting"); | 36 Boolean.getBoolean("minfo.sq.calcution.non.linear.fitting"); |
37 | 37 |
38 public static final String SQ_POW_FUNCTION_NAME = "sq-pow"; | 38 public static final String SQ_POW_FUNCTION_NAME = "sq-pow"; |
39 public static final String SQ_LIN_FUNCTION_NAME = "linear"; | 39 public static final String SQ_LIN_FUNCTION_NAME = "linear"; |
40 | |
41 public static final String [] EXTRA_PARAMETERS = { | |
42 "chi_sqr", | |
43 "std_dev", | |
44 "max_q", | |
45 "c_perguson", | |
46 "c_duan", | |
47 "r2" | |
48 }; | |
40 | 49 |
41 protected String river; | 50 protected String river; |
42 protected double location; | 51 protected double location; |
43 protected DateRange period; | 52 protected DateRange period; |
44 protected double outliers; | 53 protected double outliers; |
147 Function function; | 156 Function function; |
148 SQ.View sqView; | 157 SQ.View sqView; |
149 SQ.Factory sqFactory; | 158 SQ.Factory sqFactory; |
150 ParameterCreator pc; | 159 ParameterCreator pc; |
151 | 160 |
152 | |
153 if (NON_LINEAR_FITTING) { | 161 if (NON_LINEAR_FITTING) { |
154 log.debug("Use non linear fitting."); | 162 log.debug("Use non linear fitting."); |
155 sqView = SQ.SQ_VIEW; | 163 sqView = SQ.SQ_VIEW; |
156 sqFactory = SQ.SQ_FACTORY; | 164 sqFactory = SQ.SQ_FACTORY; |
157 function = powFunction; | 165 function = powFunction; |
158 pc = new ParameterCreator( | 166 pc = new ParameterCreator( |
159 powFunction.getParameterNames(), | 167 powFunction.getParameterNames(), |
160 powFunction.getParameterNames()); | 168 powFunction.getParameterNames(), |
169 powFunction, | |
170 sqView); | |
161 } | 171 } |
162 else { | 172 else { |
163 log.debug("Use linear fitting."); | 173 log.debug("Use linear fitting."); |
164 sqView = LogSQ.LOG_SQ_VIEW; | 174 sqView = LogSQ.LOG_SQ_VIEW; |
165 sqFactory = LogSQ.LOG_SQ_FACTORY; | 175 sqFactory = LogSQ.LOG_SQ_FACTORY; |
172 addProblem("sq.missing.sq.function"); | 182 addProblem("sq.missing.sq.function"); |
173 return new CalculationResult(new SQResult[0], this); | 183 return new CalculationResult(new SQResult[0], this); |
174 } | 184 } |
175 pc = new LinearParameterCreator( | 185 pc = new LinearParameterCreator( |
176 powFunction.getParameterNames(), | 186 powFunction.getParameterNames(), |
177 function.getParameterNames()); | 187 function.getParameterNames(), |
188 function, | |
189 sqView); | |
178 } | 190 } |
179 | 191 |
180 Measurements measurements = | 192 Measurements measurements = |
181 MeasurementFactory.getMeasurements( | 193 MeasurementFactory.getMeasurements( |
182 river, location, period, sqFactory); | 194 river, location, period, sqFactory); |
234 double chiSqr | 246 double chiSqr |
235 ) { | 247 ) { |
236 Parameters parameters = pc.createParameters( | 248 Parameters parameters = pc.createParameters( |
237 coeffs, | 249 coeffs, |
238 standardDeviation, | 250 standardDeviation, |
239 chiSqr); | 251 chiSqr, |
252 measurements); | |
240 iterations.add(new SQFractionResult.Iteration( | 253 iterations.add(new SQFractionResult.Iteration( |
241 parameters, | 254 parameters, |
242 measurements, | 255 measurements, |
243 outliers)); | 256 outliers)); |
244 } | 257 } |
250 public static class ParameterCreator { | 263 public static class ParameterCreator { |
251 | 264 |
252 protected String [] origNames; | 265 protected String [] origNames; |
253 protected String [] proxyNames; | 266 protected String [] proxyNames; |
254 | 267 |
255 public ParameterCreator(String [] origNames, String [] proxyNames) { | 268 protected Function function; |
269 protected SQ.View view; | |
270 | |
271 public ParameterCreator( | |
272 String [] origNames, | |
273 String [] proxyNames, | |
274 Function function, | |
275 SQ.View view | |
276 ) { | |
256 this.origNames = origNames; | 277 this.origNames = origNames; |
257 this.proxyNames = proxyNames; | 278 this.proxyNames = proxyNames; |
279 this.view = view; | |
258 } | 280 } |
259 | 281 |
260 protected double [] transformCoeffs(double [] coeffs) { | 282 protected double [] transformCoeffs(double [] coeffs) { |
261 return coeffs; | 283 return coeffs; |
262 } | 284 } |
285 | |
286 private static double maxQ(SQ [] sqs) { | |
287 double max = -Double.MAX_VALUE; | |
288 for (SQ sq: sqs) { | |
289 double q = sq.getQ(); // Don't use view here! | |
290 if (q > max) { | |
291 max = q; | |
292 } | |
293 } | |
294 return Math.max(0d, max); | |
295 } | |
296 | |
297 private double cPerguson( | |
298 org.dive4elements.river.artifacts.math.Function instance, | |
299 SQ [] sqs | |
300 ) { | |
301 double sqrSum = 0d; | |
302 | |
303 for (SQ sq: sqs) { | |
304 double s = view.getS(sq); | |
305 double q = view.getQ(sq); | |
306 double diffS = s - instance.value(q); | |
307 sqrSum += diffS*diffS; | |
308 } | |
309 | |
310 return Math.exp(0.5d * sqrSum/(sqs.length-2)); | |
311 } | |
312 | |
313 private double cDuan( | |
314 org.dive4elements.river.artifacts.math.Function instance, | |
315 SQ [] sqs | |
316 ) { | |
317 double sum = 0d; | |
318 | |
319 for (SQ sq: sqs) { | |
320 double s = view.getS(sq); | |
321 double q = view.getQ(sq); | |
322 double diffS = s - instance.value(q); | |
323 sum += Math.exp(diffS); | |
324 } | |
325 return sum / sqs.length; | |
326 } | |
327 | |
328 private double r2( | |
329 org.dive4elements.river.artifacts.math.Function instance, | |
330 SQ [] sqs | |
331 ) { | |
332 double xm = 0; | |
333 double ym = 0; | |
334 for (SQ sq: sqs) { | |
335 double s = view.getS(sq); | |
336 double q = view.getQ(sq); | |
337 double fs = instance.value(q); | |
338 xm += s; | |
339 ym += fs; | |
340 } | |
341 xm /= sqs.length; | |
342 ym /= sqs.length; | |
343 | |
344 double mixXY = 0d; | |
345 double sumX = 0d; | |
346 double sumY = 0d; | |
347 | |
348 for (SQ sq: sqs) { | |
349 double s = view.getS(sq); | |
350 double q = view.getQ(sq); | |
351 double fs = instance.value(q); | |
352 | |
353 double xDiff = xm - s; | |
354 double yDiff = ym - fs; | |
355 | |
356 mixXY += xDiff*yDiff; | |
357 | |
358 sumX += xDiff*xDiff; | |
359 sumY *= yDiff*yDiff; | |
360 } | |
361 | |
362 double r = mixXY/Math.sqrt(sumX*sumY); | |
363 return r*r; | |
364 } | |
365 | |
263 | 366 |
264 public Parameters createParameters( | 367 public Parameters createParameters( |
265 double [] coeffs, | 368 double [] coeffs, |
266 double standardDeviation, | 369 double standardDeviation, |
267 double chiSqr | 370 double chiSqr, |
268 ) { | 371 SQ [] measurements |
269 String [] columns = new String[origNames.length + 2]; | 372 ) { |
270 columns[0] = "chi_sqr"; | 373 String [] columns = StringUtils.join(EXTRA_PARAMETERS, origNames); |
271 columns[1] = "std_dev"; | 374 |
272 System.arraycopy(origNames, 0, columns, 2, origNames.length); | |
273 Parameters parameters = new Parameters(columns); | 375 Parameters parameters = new Parameters(columns); |
274 int row = parameters.newRow(); | 376 int row = parameters.newRow(); |
275 parameters.set(row, origNames, transformCoeffs(coeffs)); | 377 parameters.set(row, origNames, transformCoeffs(coeffs)); |
276 parameters.set(row, "chi_sqr", chiSqr); | 378 parameters.set(row, "chi_sqr", chiSqr); |
277 parameters.set(row, "std_dev", standardDeviation); | 379 parameters.set(row, "std_dev", standardDeviation); |
380 parameters.set(row, "max_q", maxQ(measurements)); | |
381 | |
382 // We need to instantiate the function to calculate | |
383 // the remaining values. | |
384 org.dive4elements.river.artifacts.math.Function f = | |
385 function.instantiate(coeffs); | |
386 | |
387 parameters.set(row, "c_perguson", cPerguson(f, measurements)); | |
388 parameters.set(row, "c_duan", cDuan(f, measurements)); | |
389 parameters.set(row, "r2", r2(f, measurements)); | |
390 | |
278 return parameters; | 391 return parameters; |
279 } | 392 } |
280 } | 393 } |
281 | 394 |
282 /** We need to transform the coeffs back to the original function. */ | 395 /** We need to transform the coeffs back to the original function. */ |
283 public static class LinearParameterCreator extends ParameterCreator { | 396 public static class LinearParameterCreator extends ParameterCreator { |
284 | 397 |
285 public LinearParameterCreator( | 398 public LinearParameterCreator( |
286 String [] origNames, | 399 String [] origNames, |
287 String [] proxyNames | 400 String [] proxyNames, |
288 ) { | 401 Function function, |
289 super(origNames, proxyNames); | 402 SQ.View view |
403 ) { | |
404 super(origNames, proxyNames, function, view); | |
290 } | 405 } |
291 | 406 |
292 @Override | 407 @Override |
293 protected double [] transformCoeffs(double [] coeffs) { | 408 protected double [] transformCoeffs(double [] coeffs) { |
294 | 409 |