changeset 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 0747ca95ad6e
children e237a83fd87d
files artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQRelationCalculation.java
diffstat 1 files changed, 127 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- 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

http://dive4elements.wald.intevation.org