annotate pkg/common/nashsutcliffe.go @ 5736:55892008ec96 default tip

Fixed a bunch of corner cases in WG import.
author Sascha Wilde <wilde@sha-bang.de>
date Wed, 29 May 2024 19:02:42 +0200
parents 6270951dda28
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
1 // This is Free Software under GNU Affero General Public License v >= 3.0
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
2 // without warranty, see README.md and license for details.
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
3 //
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
4 // SPDX-License-Identifier: AGPL-3.0-or-later
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
5 // License-Filename: LICENSES/AGPL-3.0.txt
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
6 //
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
7 // Copyright (C) 2019 by via donau
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
8 // – Österreichische Wasserstraßen-Gesellschaft mbH
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
9 // Software engineering by Intevation GmbH
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
10 //
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
11 // Author(s):
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
12 // * Sascha L. Teichmann <sascha.teichmann@intevation.de>
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
13
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
14 package common
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
15
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
16 import (
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
17 "fmt"
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
18 "time"
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
19 )
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
20
4162
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
21 type (
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
22 // TimedValue is a tuple of a point in time and an associated value.
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
23 TimedValue struct {
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
24 When time.Time
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
25 Value float64
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
26 }
3087
014be2194bd1 Prepare new Nash-Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 2878
diff changeset
27
4162
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
28 // TimedValues is a slice of TimedValue tuples.
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
29 TimedValues []TimedValue
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
30 )
3087
014be2194bd1 Prepare new Nash-Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 2878
diff changeset
31
3099
f516ac26f4db "Sharp" match for predicted and measured values in nash sutcliffe.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3098
diff changeset
32 func epsEquals(a, b time.Time) bool {
f516ac26f4db "Sharp" match for predicted and measured values in nash sutcliffe.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3098
diff changeset
33 d := a.Sub(b)
f516ac26f4db "Sharp" match for predicted and measured values in nash sutcliffe.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3098
diff changeset
34 return -10*time.Millisecond < d && d < 10*time.Millisecond
f516ac26f4db "Sharp" match for predicted and measured values in nash sutcliffe.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3098
diff changeset
35 }
3087
014be2194bd1 Prepare new Nash-Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 2878
diff changeset
36
4162
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
37 // Find scans to the tuples and compares the time with an
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
38 // epsilon of ten micro seconds. If they are equals the associated
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
39 // value is returned. The return bool flags indicated if the
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
40 // search was successful.
3099
f516ac26f4db "Sharp" match for predicted and measured values in nash sutcliffe.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3098
diff changeset
41 func (mvs TimedValues) Find(when time.Time) (float64, bool) {
f516ac26f4db "Sharp" match for predicted and measured values in nash sutcliffe.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3098
diff changeset
42 for i := range mvs {
f516ac26f4db "Sharp" match for predicted and measured values in nash sutcliffe.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3098
diff changeset
43 if epsEquals(when, mvs[i].When) {
f516ac26f4db "Sharp" match for predicted and measured values in nash sutcliffe.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3098
diff changeset
44 return mvs[i].Value, true
3097
e6ba32b060df Nash Sutcliffe: Treat last prediction date as valid afterwards. Small optimizsations.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3096
diff changeset
45 }
3087
014be2194bd1 Prepare new Nash-Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 2878
diff changeset
46 }
014be2194bd1 Prepare new Nash-Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 2878
diff changeset
47 return 0, false
014be2194bd1 Prepare new Nash-Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 2878
diff changeset
48 }
014be2194bd1 Prepare new Nash-Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 2878
diff changeset
49
4162
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
50 // NashSutcliffe calculates the Nash-Sutcliffe coefficent for
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
51 // given predicted and observed values.
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
52 // See
5712
6270951dda28 /interface{}/any/
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4162
diff changeset
53 //
6270951dda28 /interface{}/any/
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4162
diff changeset
54 // https://en.wikipedia.org/wiki/Nash%E2%80%93Sutcliffe_model_efficiency_coefficient
6270951dda28 /interface{}/any/
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4162
diff changeset
55 //
4162
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
56 // for details.
8c5df0f3562e Made 'golint' and 'staticcheck' happy with common package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3103
diff changeset
57 // The function panics if predicted and observed are of different lengths.
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
58 func NashSutcliffe(predicted, observed []float64) float64 {
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
59
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
60 if len(predicted) != len(observed) {
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
61 panic(fmt.Sprintf(
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
62 "NashSutcliffe: predicted and observed len differ: %d != %d",
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
63 len(predicted),
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
64 len(observed)))
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
65 }
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
66
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
67 if len(observed) == 0 {
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
68 return 0
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
69 }
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
70
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
71 var mo float64
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
72 for _, v := range observed {
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
73 mo += v
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
74 }
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
75
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
76 mo /= float64(len(observed))
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
77
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
78 var num, denom float64
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
79 for i, o := range observed {
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
80 d1 := predicted[i] - o
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
81 num += d1 * d1
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
82 d2 := o - mo
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
83 denom += d2 * d2
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
84 }
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
85
3091
cec9d4af5f03 Simplified and fixed Nash Sutcliffe calculation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3088
diff changeset
86 return 1 - num/denom
2741
87aed4f9b1b8 Added calculation of Nash Sutcliffe efficiency coefficents.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
87 }