# HG changeset patch # User Sascha L. Teichmann # Date 1376065495 -7200 # Node ID 978ab716a15e913d7e1ac2a2dded3bc1141b3cba # Parent 0747ca95ad6e01a71dbc89e4bebad10235e8f6a9 flys/issue1347: Added missing calcutions. TODO: Bring them into the generated outs. diff -r 0747ca95ad6e -r 978ab716a15e artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQRelationCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQRelationCalculation.java Fri Aug 09 12:20:32 2013 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQRelationCalculation.java Fri Aug 09 18:24:55 2013 +0200 @@ -38,6 +38,15 @@ public static final String SQ_POW_FUNCTION_NAME = "sq-pow"; public static final String SQ_LIN_FUNCTION_NAME = "linear"; + public static final String [] EXTRA_PARAMETERS = { + "chi_sqr", + "std_dev", + "max_q", + "c_perguson", + "c_duan", + "r2" + }; + protected String river; protected double location; protected DateRange period; @@ -149,7 +158,6 @@ SQ.Factory sqFactory; ParameterCreator pc; - if (NON_LINEAR_FITTING) { log.debug("Use non linear fitting."); sqView = SQ.SQ_VIEW; @@ -157,7 +165,9 @@ function = powFunction; pc = new ParameterCreator( powFunction.getParameterNames(), - powFunction.getParameterNames()); + powFunction.getParameterNames(), + powFunction, + sqView); } else { log.debug("Use linear fitting."); @@ -174,7 +184,9 @@ } pc = new LinearParameterCreator( powFunction.getParameterNames(), - function.getParameterNames()); + function.getParameterNames(), + function, + sqView); } Measurements measurements = @@ -236,7 +248,8 @@ Parameters parameters = pc.createParameters( coeffs, standardDeviation, - chiSqr); + chiSqr, + measurements); iterations.add(new SQFractionResult.Iteration( parameters, measurements, @@ -252,29 +265,129 @@ protected String [] origNames; protected String [] proxyNames; - public ParameterCreator(String [] origNames, String [] proxyNames) { + protected Function function; + protected SQ.View view; + + public ParameterCreator( + String [] origNames, + String [] proxyNames, + Function function, + SQ.View view + ) { this.origNames = origNames; this.proxyNames = proxyNames; + this.view = view; } protected double [] transformCoeffs(double [] coeffs) { return coeffs; } + private static double maxQ(SQ [] sqs) { + double max = -Double.MAX_VALUE; + for (SQ sq: sqs) { + double q = sq.getQ(); // Don't use view here! + if (q > max) { + max = q; + } + } + return Math.max(0d, max); + } + + private double cPerguson( + org.dive4elements.river.artifacts.math.Function instance, + SQ [] sqs + ) { + double sqrSum = 0d; + + for (SQ sq: sqs) { + double s = view.getS(sq); + double q = view.getQ(sq); + double diffS = s - instance.value(q); + sqrSum += diffS*diffS; + } + + return Math.exp(0.5d * sqrSum/(sqs.length-2)); + } + + private double cDuan( + org.dive4elements.river.artifacts.math.Function instance, + SQ [] sqs + ) { + double sum = 0d; + + for (SQ sq: sqs) { + double s = view.getS(sq); + double q = view.getQ(sq); + double diffS = s - instance.value(q); + sum += Math.exp(diffS); + } + return sum / sqs.length; + } + + private double r2( + org.dive4elements.river.artifacts.math.Function instance, + SQ [] sqs + ) { + double xm = 0; + double ym = 0; + for (SQ sq: sqs) { + double s = view.getS(sq); + double q = view.getQ(sq); + double fs = instance.value(q); + xm += s; + ym += fs; + } + xm /= sqs.length; + ym /= sqs.length; + + double mixXY = 0d; + double sumX = 0d; + double sumY = 0d; + + for (SQ sq: sqs) { + double s = view.getS(sq); + double q = view.getQ(sq); + double fs = instance.value(q); + + double xDiff = xm - s; + double yDiff = ym - fs; + + mixXY += xDiff*yDiff; + + sumX += xDiff*xDiff; + sumY *= yDiff*yDiff; + } + + double r = mixXY/Math.sqrt(sumX*sumY); + return r*r; + } + + public Parameters createParameters( double [] coeffs, double standardDeviation, - double chiSqr + double chiSqr, + SQ [] measurements ) { - String [] columns = new String[origNames.length + 2]; - columns[0] = "chi_sqr"; - columns[1] = "std_dev"; - System.arraycopy(origNames, 0, columns, 2, origNames.length); + String [] columns = StringUtils.join(EXTRA_PARAMETERS, origNames); + Parameters parameters = new Parameters(columns); int row = parameters.newRow(); parameters.set(row, origNames, transformCoeffs(coeffs)); parameters.set(row, "chi_sqr", chiSqr); parameters.set(row, "std_dev", standardDeviation); + parameters.set(row, "max_q", maxQ(measurements)); + + // We need to instantiate the function to calculate + // the remaining values. + org.dive4elements.river.artifacts.math.Function f = + function.instantiate(coeffs); + + parameters.set(row, "c_perguson", cPerguson(f, measurements)); + parameters.set(row, "c_duan", cDuan(f, measurements)); + parameters.set(row, "r2", r2(f, measurements)); + return parameters; } } @@ -284,9 +397,11 @@ public LinearParameterCreator( String [] origNames, - String [] proxyNames + String [] proxyNames, + Function function, + SQ.View view ) { - super(origNames, proxyNames); + super(origNames, proxyNames, function, view); } @Override