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

http://dive4elements.wald.intevation.org