changeset 3091:cec9d4af5f03

Simplified and fixed Nash Sutcliffe calculation.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 23 Apr 2019 10:10:54 +0200
parents 342c7bcb97f1
children 7dc9660df743
files pkg/common/nashsutcliffe.go pkg/controllers/gauges.go
diffstat 2 files changed, 27 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/common/nashsutcliffe.go	Sun Apr 21 19:11:38 2019 +0200
+++ b/pkg/common/nashsutcliffe.go	Tue Apr 23 10:10:54 2019 +0200
@@ -14,6 +14,7 @@
 package common
 
 import (
+	"fmt"
 	"sort"
 	"time"
 )
@@ -78,32 +79,33 @@
 	return 0, false
 }
 
-type NSMeasurement struct {
-	When      time.Time
-	Predicted float64
-	Observed  float64
-}
+func NashSutcliffe(predicted, observed []float64) float64 {
 
-func NashSutcliffe(sample []NSMeasurement, from, to time.Time) (float64, int) {
+	if len(predicted) != len(observed) {
+		panic(fmt.Sprintf(
+			"NashSutcliffe: predicted and observed len differ: %d != %d",
+			len(predicted),
+			len(observed)))
+	}
 
-	if len(sample) == 0 {
-		return 0, 0
+	if len(observed) == 0 {
+		return 0
 	}
 
 	var mo float64
-	for i := range sample {
-		mo += sample[i].Observed
+	for _, v := range observed {
+		mo += v
 	}
 
-	mo /= float64(len(sample))
+	mo /= float64(len(observed))
 
 	var num, denom float64
-	for i := range sample {
-		d1 := sample[i].Predicted - sample[i].Observed
+	for i, o := range observed {
+		d1 := predicted[i] - o
 		num += d1 * d1
-		d2 := sample[i].Observed - mo
+		d2 := o - mo
 		denom += d2 * d2
 	}
 
-	return 1 - num/denom, len(sample)
+	return 1 - num/denom
 }
--- a/pkg/controllers/gauges.go	Sun Apr 21 19:11:38 2019 +0200
+++ b/pkg/controllers/gauges.go	Tue Apr 23 10:10:54 2019 +0200
@@ -558,29 +558,26 @@
 		Coeffs []coeff           `json:"coeffs"`
 	}
 
-	var measurements []common.NSMeasurement
+	var predicted, observed []float64
 
 	cs := make([]coeff, 3)
 	for i := range cs {
 		cs[i].Hours = (i + 1) * 24
-		back := when.Add(time.Duration(-cs[i].Hours) * time.Hour)
+		delta := -time.Duration(-cs[i].Hours) * time.Hour
 
 		for j := range values {
-			if predicted, ok := values[j].predicted.Interpolate(back); ok {
-				measurements = append(measurements, common.NSMeasurement{
-					Observed:  values[j].observed,
-					Predicted: predicted,
-				})
+			when := values[j].when.Add(delta)
+			if p, ok := values[j].predicted.Interpolate(when); ok {
+				predicted = append(predicted, p)
+				observed = append(observed, values[j].observed)
 			}
 		}
 
-		cs[i].Value, cs[i].Samples = common.NashSutcliffe(
-			measurements,
-			when,
-			back,
-		)
+		cs[i].Value = common.NashSutcliffe(predicted, observed)
+		cs[i].Samples = len(predicted)
 
-		measurements = measurements[:0]
+		predicted = predicted[:0]
+		observed = observed[:0]
 	}
 
 	jr = JSONResult{