Mercurial > gemma
view pkg/common/nashsutcliffe.go @ 2842:37c2a73ed001
client: diagrams: fixed tooltips in firefox
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Thu, 28 Mar 2019 11:16:32 +0100 |
parents | 87aed4f9b1b8 |
children | 4f66a3ba424b |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2019 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package common import ( "sort" "time" ) type NSMeasurement struct { When time.Time Predicted float64 Observed float64 } func NashSutcliffeSort(measurements []NSMeasurement) { sort.Slice(measurements, func(i, j int) bool { return measurements[i].When.Before(measurements[j].When) }) } func NashSutcliffe(measurements []NSMeasurement, from, to time.Time) (float64, int) { if len(measurements) == 0 { return 0, 0 } if to.Before(from) { from, to = to, from } begin := sort.Search(len(measurements), func(i int) bool { return !measurements[i].When.Before(from) }) if begin >= len(measurements) { return 0, 0 } end := sort.Search(len(measurements), func(i int) bool { return measurements[i].When.After(to) }) if end >= len(measurements) { end = len(measurements) - 1 } if end <= begin { return 0, 0 } sample := measurements[begin:end] if len(sample) == 0 { return 0, 0 } var mo float64 for i := range sample { mo += sample[i].Observed } mo /= float64(len(sample)) var num, denom float64 for i := range sample { d1 := sample[i].Predicted - sample[i].Observed num += d1 * d1 d2 := sample[i].Observed - mo denom += d2 * d2 } return 1 - num/denom, len(sample) }