1+ 'BlueM.Opt
2+ 'Copyright (C) BlueM Dev Group
3+ 'Website: <https://www.bluemodel.org>
4+ '
5+ 'This program is free software: you can redistribute it and/or modify
6+ 'it under the terms of the GNU General Public License as published by
7+ 'the Free Software Foundation, either version 3 of the License, or
8+ '(at your option) any later version.
9+ '
10+ 'This program is distributed in the hope that it will be useful,
11+ 'but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ 'GNU General Public License for more details.
14+ '
15+ 'You should have received a copy of the GNU General Public License
16+ 'along with this program. If not, see <https://www.gnu.org/licenses/>.
17+ '
18+ Imports Microsoft.VisualStudio.TestTools.UnitTesting
19+ Imports BlueM.Opt.Common
20+ Imports BlueM.Wave
21+
22+ <TestClass>
23+ Public Class TestObjectiveFunctions
24+
25+ Private Function CreateTimeSeries(values As Double (), Optional title As String = "Test" ) As TimeSeries
26+ Dim ts As New TimeSeries()
27+ ts.Title = title
28+ ts.Interpretation = TimeSeries.InterpretationEnum.BlockRight
29+ Dim startdate As New DateTime( 2020 , 1 , 1 )
30+ For i = 0 To values.Length - 1
31+ ts.AddNode(startdate.AddDays(i), values(i))
32+ Next
33+ Return ts
34+ End Function
35+
36+ <TestMethod>
37+ Public Sub CompareSeries_SSE_ReturnsSumOfSquaredErrors()
38+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
39+ Dim ref As TimeSeries = CreateTimeSeries({ 2.0 , 2 . 0 , 2 . 0 })
40+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "SSE" )
41+ Assert.AreEqual( 2.0 , result, 0 . 000001 )
42+ End Sub
43+
44+ <TestMethod>
45+ Public Sub CompareSeries_MSE_ReturnsMeanSquaredError()
46+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
47+ Dim ref As TimeSeries = CreateTimeSeries({ 2.0 , 2 . 0 , 2 . 0 })
48+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "MSE" )
49+ Assert.AreEqual( 2.0 / 3 . 0 , result, 0 . 000001 )
50+ End Sub
51+
52+ <TestMethod>
53+ Public Sub CompareSeries_SAE_ReturnsSumOfAbsoluteErrors()
54+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
55+ Dim ref As TimeSeries = CreateTimeSeries({ 2.0 , 2 . 0 , 2 . 0 })
56+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "SAE" )
57+ Assert.AreEqual( 2.0 , result, 0 . 000001 )
58+ End Sub
59+
60+ <TestMethod>
61+ Public Sub CompareSeries_MAE_ReturnsMeanAbsoluteError()
62+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
63+ Dim ref As TimeSeries = CreateTimeSeries({ 2.0 , 2 . 0 , 2 . 0 })
64+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "MAE" )
65+ Assert.AreEqual( 2.0 / 3 . 0 , result, 0 . 000001 )
66+ End Sub
67+
68+ <TestMethod>
69+ Public Sub CompareSeries_BIAS_ReturnsAbsoluteVolumeError()
70+ Dim sim As TimeSeries = CreateTimeSeries({ 2.0 , 3 . 0 , 4 . 0 })
71+ Dim ref As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
72+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "BIAS" )
73+ Assert.AreEqual(( 9.0 - 6 . 0 ) / 6 . 0 * 100 . 0 , result, 0 . 000001 )
74+ End Sub
75+
76+ <TestMethod>
77+ Public Sub CompareSeries_NLT_ReturnsRelativeNumberOfTimestepsLessThan()
78+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
79+ Dim ref As TimeSeries = CreateTimeSeries({ 2.0 , 2 . 0 , 2 . 0 })
80+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "NLT" )
81+ Assert.AreEqual( 1.0 / 3 . 0 * 100 , result, 0 . 000001 )
82+ End Sub
83+
84+ <TestMethod>
85+ Public Sub CompareSeries_SLT_ReturnsSumOfTimestepsLessThan()
86+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
87+ Dim ref As TimeSeries = CreateTimeSeries({ 2.0 , 2 . 0 , 2 . 0 })
88+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "SLT" )
89+ Assert.AreEqual( 1.0 , result, 0 . 000001 )
90+ End Sub
91+
92+ <TestMethod>
93+ Public Sub CompareSeries_NGT_ReturnsRelativeNumberOfTimestepsGreaterThan()
94+ Dim sim As TimeSeries = CreateTimeSeries({ 3.0 , 2 . 0 , 1 . 0 })
95+ Dim ref As TimeSeries = CreateTimeSeries({ 2.0 , 2 . 0 , 2 . 0 })
96+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "NGT" )
97+ Assert.AreEqual( 1.0 / 3 . 0 * 100 , result, 0 . 000001 )
98+ End Sub
99+
100+ <TestMethod>
101+ Public Sub CompareSeries_SGT_ReturnsSumOfTimestepsGreaterThan()
102+ Dim sim As TimeSeries = CreateTimeSeries({ 3.0 , 2 . 0 , 1 . 0 })
103+ Dim ref As TimeSeries = CreateTimeSeries({ 2.0 , 2 . 0 , 2 . 0 })
104+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "SGT" )
105+ Assert.AreEqual( 1.0 , result, 0 . 000001 )
106+ End Sub
107+
108+ <TestMethod>
109+ Public Sub CompareSeries_APFB_ReturnsAnnualPeakFlowBias()
110+ 'create timeseries with two years of monthly data
111+ Dim sim As New TimeSeries( "sim" )
112+ sim.Interpretation = TimeSeries.InterpretationEnum.BlockRight
113+ For i As Integer = 1 To 12
114+ sim.AddNode( New DateTime( 2020 , i, 1 ), i)
115+ sim.AddNode( New DateTime( 2021 , i, 1 ), i * 2 )
116+ Next
117+ Dim ref As New TimeSeries( "ref" )
118+ ref.Interpretation = TimeSeries.InterpretationEnum.BlockRight
119+ For i As Integer = 1 To 12
120+ ref.AddNode( New DateTime( 2020 , i, 1 ), i * 1 . 1 )
121+ ref.AddNode( New DateTime( 2021 , i, 1 ), i * 0 . 9 * 2 )
122+ Next
123+ Dim peakSim = { 12.0 , 24 . 0 }
124+ Dim peakRef = { 13.2 , 21 . 6 }
125+ Dim expected = Math.Sqrt(Math.Pow((peakSim.Average() / peakRef.Average()) - 1.0 , 2 ))
126+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "APFB" )
127+ Assert.AreEqual(expected, result, 0.000001 )
128+ End Sub
129+
130+ <TestMethod>
131+ Public Sub CompareSeries_NSE_ReturnsNashSutcliffeEfficiency()
132+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
133+ Dim ref As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
134+ ' Identical series, NSE = 1
135+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "NSE" )
136+ Assert.AreEqual( 1.0 , result, 0 . 000001 )
137+ End Sub
138+
139+ <TestMethod>
140+ Public Sub CompareSeries_LNNSE_ReturnsLnNashSutcliffeEfficiency()
141+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
142+ Dim ref As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
143+ ' Identical series, lnNSE = 1
144+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "LNNSE" )
145+ Assert.AreEqual( 1.0 , result, 0 . 000001 )
146+ End Sub
147+
148+ <TestMethod>
149+ Public Sub CompareSeries_DET_ReturnsCoefficientOfDetermination()
150+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
151+ Dim ref As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
152+ ' Identical series, DET = 1
153+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "DET" )
154+ Assert.AreEqual( 1.0 , result, 0 . 000001 )
155+ End Sub
156+
157+ <TestMethod>
158+ Public Sub CompareSeries_KGE_ReturnsKlingGuptaEfficiency()
159+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
160+ Dim ref As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
161+ ' Identical series, KGE = 1
162+ Dim result = ObjectiveFunction.compareSeries(sim, ref, "KGE" )
163+ Assert.AreEqual( 1.0 , result, 0 . 000001 )
164+ End Sub
165+
166+ <TestMethod>
167+ <ExpectedException( GetType (Exception))>
168+ Public Sub CompareSeries_DifferentLength_ThrowsException()
169+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 })
170+ Dim ref As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
171+ ObjectiveFunction.compareSeries(sim, ref, "SSE" )
172+ End Sub
173+
174+ <TestMethod>
175+ <ExpectedException( GetType (Exception))>
176+ Public Sub CompareSeries_UnsupportedFunction_ThrowsException()
177+ Dim sim As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
178+ Dim ref As TimeSeries = CreateTimeSeries({ 1.0 , 2 . 0 , 3 . 0 })
179+ ObjectiveFunction.compareSeries(sim, ref, "UNSUPPORTED" )
180+ End Sub
181+
182+ End Class
0 commit comments