Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs @ 13237

Last change on this file since 13237 was 12009, checked in by ascheibe, 10 years ago

#2212 updated copyright year

File size: 6.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24
25namespace HeuristicLab.Problems.DataAnalysis {
26  public class OnlineTheilsUStatisticCalculator : IOnlineTimeSeriesCalculator {
27    private OnlineMeanAndVarianceCalculator squaredErrorMeanCalculator;
28    private OnlineMeanAndVarianceCalculator unbiasedEstimatorMeanCalculator;
29
30    public double TheilsUStatistic {
31      get {
32        return Math.Sqrt(squaredErrorMeanCalculator.Mean) / Math.Sqrt(unbiasedEstimatorMeanCalculator.Mean);
33      }
34    }
35
36    private OnlineCalculatorError errorState;
37    public OnlineCalculatorError ErrorState {
38      get { return errorState | squaredErrorMeanCalculator.MeanErrorState | unbiasedEstimatorMeanCalculator.MeanErrorState; }
39    }
40
41    public OnlineTheilsUStatisticCalculator() {
42      squaredErrorMeanCalculator = new OnlineMeanAndVarianceCalculator();
43      unbiasedEstimatorMeanCalculator = new OnlineMeanAndVarianceCalculator();
44      Reset();
45    }
46
47    #region IOnlineEvaluator Members
48    public double Value {
49      get { return TheilsUStatistic; }
50    }
51
52    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
53      throw new NotSupportedException();
54    }
55
56    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> referenceContinuation, IEnumerable<double> predictedContinuation) {
57      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
58        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
59      } else {
60        var actualEnumerator = actualContinuation.GetEnumerator();
61        var predictedEnumerator = predictedContinuation.GetEnumerator();
62        var referenceEnumerator = referenceContinuation.GetEnumerator();
63        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & referenceEnumerator.MoveNext()
64          & ErrorState != OnlineCalculatorError.InvalidValueAdded) {
65          double actual = actualEnumerator.Current;
66          double predicted = predictedEnumerator.Current;
67          double reference = referenceEnumerator.Current;
68          if (double.IsNaN(actual) || double.IsNaN(predicted) || double.IsNaN(reference)) {
69            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
70          } else {
71            // error of predicted change
72            double errorPredictedChange = (predicted - startValue) - (actual - startValue);
73            squaredErrorMeanCalculator.Add(errorPredictedChange * errorPredictedChange);
74
75            double errorReference = (reference - startValue) - (actual - startValue);
76            unbiasedEstimatorMeanCalculator.Add(errorReference * errorReference);
77          }
78        }
79        // check if both enumerators are at the end to make sure both enumerations have the same length
80        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext() || referenceEnumerator.MoveNext()) {
81          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
82        } else {
83          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
84        }
85      }
86    }
87
88
89    public void Reset() {
90      squaredErrorMeanCalculator.Reset();
91      unbiasedEstimatorMeanCalculator.Reset();
92      errorState = OnlineCalculatorError.InsufficientElementsAdded;
93    }
94
95    #endregion
96
97    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> referenceContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
98      OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
99      calculator.Add(startValue, actualContinuation, referenceContinuation, predictedContinuation);
100      errorState = calculator.ErrorState;
101      return calculator.TheilsUStatistic;
102    }
103
104    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> referenceContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
105      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
106      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
107      IEnumerator<IEnumerable<double>> referenceContinuationsEnumerator = referenceContinuations.GetEnumerator();
108      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
109
110      OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
111
112      // always move forward all enumerators (do not use short-circuit evaluation!)
113      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & referenceContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
114        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, referenceContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
115        if (calculator.ErrorState != OnlineCalculatorError.None) break;
116      }
117
118      // check if all enumerators are at the end to make sure both enumerations have the same length
119      if (calculator.ErrorState == OnlineCalculatorError.None &&
120          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || referenceContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
121        throw new ArgumentException("Number of elements in startValues, actualContinuations, referenceContinuation and estimatedValues predictedContinuations doesn't match.");
122      } else {
123        errorState = calculator.ErrorState;
124        return calculator.TheilsUStatistic;
125      }
126    }
127  }
128}
Note: See TracBrowser for help on using the repository browser.