Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs @ 7160

Last change on this file since 7160 was 7160, checked in by gkronber, 13 years ago

#1081 worked on multi-variate time series prognosis

File size: 24.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Collections.Concurrent;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Data;
27using HeuristicLab.Optimization;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Problems.DataAnalysis {
31  [StorableClass]
32  public abstract class TimeSeriesPrognosisSolutionBase : DataAnalysisSolution, ITimeSeriesPrognosisSolution {
33    private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
34    private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
35    private const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
36    private const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
37    private const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
38    private const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
39    private const string TrainingRelativeErrorResultName = "Average relative error (training)";
40    private const string TestRelativeErrorResultName = "Average relative error (test)";
41    private const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
42    private const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
43    private const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
44    private const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
45    private const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
46    private const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
47    private const string TrainingTheilsUStatisticLastResultName = "Average Theil's U (last) (training)";
48    private const string TestTheilsUStatisticLastResultName = "Average Theil's U (last) (test)";
49    private const string TrainingTheilsUStatisticMeanResultName = "Average Theil's U (mean) (training)";
50    private const string TestTheilsUStatisticMeanResultName = "Average Theil's U (mean) (test)";
51    private const string TrainingTheilsUStatisticMAResultName = "Average Theil's U (moving average) (training)";
52    private const string TestTheilsUStatisticMAResultName = "Average Theil's U (moving average) (test)";
53
54    public new ITimeSeriesPrognosisModel Model {
55      get { return (ITimeSeriesPrognosisModel)base.Model; }
56      protected set { base.Model = value; }
57    }
58
59    public new ITimeSeriesPrognosisProblemData ProblemData {
60      get { return (ITimeSeriesPrognosisProblemData)base.ProblemData; }
61      set { base.ProblemData = value; }
62    }
63
64    [Storable]
65    private int horizon;
66    public int Horizon {
67      get { return horizon; }
68      set {
69        if (horizon != value) {
70          horizon = value;
71          RecalculateResults();
72        }
73      }
74    }
75
76    public abstract IEnumerable<IEnumerable<double>> PrognosedTrainingValues { get; }
77    public abstract IEnumerable<IEnumerable<double>> PrognosedTestValues { get; }
78    public abstract IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(IEnumerable<int> rows, int horizon);
79
80    #region Results
81    public double[] TrainingMeanSquaredError {
82      get { return ((DoubleArray)this[TrainingMeanSquaredErrorResultName].Value).ToArray(); }
83      private set { this[TrainingMeanSquaredErrorResultName].Value = new DoubleArray(value); }
84    }
85    public double[] TestMeanSquaredError {
86      get { return ((DoubleArray)this[TestMeanSquaredErrorResultName].Value).ToArray(); }
87      private set { this[TestMeanSquaredErrorResultName].Value = new DoubleArray(value); }
88    }
89    public double[] TrainingMeanAbsoluteError {
90      get { return ((DoubleArray)this[TrainingMeanAbsoluteErrorResultName].Value).ToArray(); }
91      private set { this[TrainingMeanAbsoluteErrorResultName].Value = new DoubleArray(value); }
92    }
93    public double[] TestMeanAbsoluteError {
94      get { return ((DoubleArray)this[TestMeanAbsoluteErrorResultName].Value).ToArray(); }
95      private set { this[TestMeanAbsoluteErrorResultName].Value = new DoubleArray(value); }
96    }
97    public double[] TrainingRSquared {
98      get { return ((DoubleArray)this[TrainingSquaredCorrelationResultName].Value).ToArray(); }
99      private set { this[TrainingSquaredCorrelationResultName].Value = new DoubleArray(value); }
100    }
101    public double[] TestRSquared {
102      get { return ((DoubleArray)this[TestSquaredCorrelationResultName].Value).ToArray(); }
103      private set { this[TestSquaredCorrelationResultName].Value = new DoubleArray(value); }
104    }
105    public double[] TrainingRelativeError {
106      get { return ((DoubleArray)this[TrainingRelativeErrorResultName].Value).ToArray(); }
107      private set { this[TrainingRelativeErrorResultName].Value = new DoubleArray(value); }
108    }
109    public double[] TestRelativeError {
110      get { return ((DoubleArray)this[TestRelativeErrorResultName].Value).ToArray(); }
111      private set { this[TestRelativeErrorResultName].Value = new DoubleArray(value); }
112    }
113    public double[] TrainingNormalizedMeanSquaredError {
114      get { return ((DoubleArray)this[TrainingNormalizedMeanSquaredErrorResultName].Value).ToArray(); }
115      private set { this[TrainingNormalizedMeanSquaredErrorResultName].Value = new DoubleArray(value); }
116    }
117    public double[] TestNormalizedMeanSquaredError {
118      get { return ((DoubleArray)this[TestNormalizedMeanSquaredErrorResultName].Value).ToArray(); }
119      private set { this[TestNormalizedMeanSquaredErrorResultName].Value = new DoubleArray(value); }
120    }
121    public double[] TrainingDirectionalSymmetry {
122      get { return ((DoubleArray)this[TrainingDirectionalSymmetryResultName].Value).ToArray(); }
123      private set { this[TrainingDirectionalSymmetryResultName].Value = new DoubleArray(value); }
124    }
125    public double[] TestDirectionalSymmetry {
126      get { return ((DoubleArray)this[TestDirectionalSymmetryResultName].Value).ToArray(); }
127      private set { this[TestDirectionalSymmetryResultName].Value = new DoubleArray(value); }
128    }
129    public double[] TrainingWeightedDirectionalSymmetry {
130      get { return ((DoubleArray)this[TrainingWeightedDirectionalSymmetryResultName].Value).ToArray(); }
131      private set { this[TrainingWeightedDirectionalSymmetryResultName].Value = new DoubleArray(value); }
132    }
133    public double[] TestWeightedDirectionalSymmetry {
134      get { return ((DoubleArray)this[TestWeightedDirectionalSymmetryResultName].Value).ToArray(); }
135      private set { this[TestWeightedDirectionalSymmetryResultName].Value = new DoubleArray(value); }
136    }
137    public double[] TrainingTheilsUStatisticLast {
138      get { return ((DoubleArray)this[TrainingTheilsUStatisticLastResultName].Value).ToArray(); }
139      private set { this[TrainingTheilsUStatisticLastResultName].Value = new DoubleArray(value); }
140    }
141    public double[] TestTheilsUStatisticLast {
142      get { return ((DoubleArray)this[TestTheilsUStatisticLastResultName].Value).ToArray(); }
143      private set { this[TestTheilsUStatisticLastResultName].Value = new DoubleArray(value); }
144    }
145    public double[] TrainingTheilsUStatisticMean {
146      get { return ((DoubleArray)this[TrainingTheilsUStatisticMeanResultName].Value).ToArray(); }
147      private set { this[TrainingTheilsUStatisticMeanResultName].Value = new DoubleArray(value); }
148    }
149    public double[] TestTheilsUStatisticMean {
150      get { return ((DoubleArray)this[TestTheilsUStatisticMeanResultName].Value).ToArray(); }
151      private set { this[TestTheilsUStatisticMeanResultName].Value = new DoubleArray(value); }
152    }
153    public double[] TrainingTheilsUStatisticMovingAverage {
154      get { return ((DoubleArray)this[TrainingTheilsUStatisticMAResultName].Value).ToArray(); }
155      private set { this[TrainingTheilsUStatisticMAResultName].Value = new DoubleArray(value); }
156    }
157    public double[] TestTheilsUStatisticMovingAverage {
158      get { return ((DoubleArray)this[TestTheilsUStatisticMAResultName].Value).ToArray(); }
159      private set { this[TestTheilsUStatisticMAResultName].Value = new DoubleArray(value); }
160    }
161    #endregion
162
163    [StorableConstructor]
164    protected TimeSeriesPrognosisSolutionBase(bool deserializing) : base(deserializing) { }
165    protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner)
166      : base(original, cloner) {
167      this.horizon = original.horizon;
168    }
169    protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
170      : base(model, problemData) {
171      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleArray()));
172      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleArray()));
173      Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleArray()));
174      Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleArray()));
175      Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleArray()));
176      Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleArray()));
177      Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new DoubleArray()));
178      Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new DoubleArray()));
179      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleArray()));
180      Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleArray()));
181      Add(new Result(TrainingDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the training partition", new DoubleArray()));
182      Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new DoubleArray()));
183      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleArray()));
184      Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleArray()));
185      Add(new Result(TrainingTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the training partition", new DoubleArray()));
186      Add(new Result(TestTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the test partition", new DoubleArray()));
187      Add(new Result(TrainingTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the training partition", new DoubleArray()));
188      Add(new Result(TestTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition", new DoubleArray()));
189      Add(new Result(TrainingTheilsUStatisticMAResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the training partition", new DoubleArray()));
190      Add(new Result(TestTheilsUStatisticMAResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the test partition", new DoubleArray()));
191      horizon = 1;
192    }
193
194    [StorableHook(HookType.AfterDeserialization)]
195    private void AfterDeserialization() {
196      if (horizon == 0) horizon = 1;
197    }
198
199    protected void CalculateResults() {
200      OnlineCalculatorError errorState;
201      string[] targetVariables = ProblemData.TargetVariables.ToArray();
202      /*
203      double[] estimatedTrainingValues = PrognosedTrainingValues.ToArray(); // cache values
204      double[] originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).ToArray();
205      double[] estimatedTestValues = PrognosedTestValues.ToArray(); // cache values
206      double[] originalTestValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes).ToArray();
207
208      double trainingMse = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
209      TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMse : double.NaN;
210      double testMse = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
211      TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMse : double.NaN;
212
213      double trainingMae = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
214      TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMae : double.NaN;
215      double testMae = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
216      TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMae : double.NaN;
217
218      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
219      TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
220      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
221      TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
222
223      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
224      TrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
225      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
226      TestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
227
228      double trainingNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
229      TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNmse : double.NaN;
230      double testNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
231      TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNmse : double.NaN;
232              */
233
234      //double[] trainingDs = new double[targetVariables.Length];
235      //double[] testDs = new double[targetVariables.Length];
236
237      //double[] trainingWds = new double[targetVariables.Length];
238      //double[] testWds = new double[targetVariables.Length];
239
240      //double[] trainingTheilsU = new double[targetVariables.Length];
241      //double[] testTheilsU = new double[targetVariables.Length];
242
243      var trainingDsCalculators = new OnlineDirectionalSymmetryCalculator[targetVariables.Length];
244      var testDsCalculators = new OnlineDirectionalSymmetryCalculator[targetVariables.Length];
245      var trainingWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator[targetVariables.Length];
246      var testWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator[targetVariables.Length];
247      var trainingTheilsULastCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
248      var testTheilsULastCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
249      var trainingTheilsUMeanCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
250      var testTheilsUMeanCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
251      var trainingTheilsUMovingAverageCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
252      var testTheilsUMovingAverageCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
253      for (int i = 0; i < targetVariables.Length; i++) {
254        trainingDsCalculators[i] = new OnlineDirectionalSymmetryCalculator();
255        testDsCalculators[i] = new OnlineDirectionalSymmetryCalculator();
256        trainingWdsCalculators[i] = new OnlineWeightedDirectionalSymmetryCalculator();
257        testWdsCalculators[i] = new OnlineWeightedDirectionalSymmetryCalculator();
258        trainingTheilsULastCalculators[i] = new OnlineTheilsUStatisticCalculator();
259        testTheilsULastCalculators[i] = new OnlineTheilsUStatisticCalculator();
260        trainingTheilsUMeanCalculators[i] = new OnlineTheilsUStatisticCalculator();
261        testTheilsUMeanCalculators[i] = new OnlineTheilsUStatisticCalculator();
262        trainingTheilsUMovingAverageCalculators[i] = new OnlineTheilsUStatisticCalculator();
263        testTheilsUMovingAverageCalculators[i] = new OnlineTheilsUStatisticCalculator();
264      }
265
266      var allPrognosedTrainingValues = GetPrognosedValues(ProblemData.TrainingIndizes, horizon).GetEnumerator();
267      foreach (var row in ProblemData.TrainingIndizes) {
268        if (row + horizon < ProblemData.Dataset.Rows) {
269          allPrognosedTrainingValues.MoveNext();
270          var prognosedTrainingValues = allPrognosedTrainingValues.Current.SelectMany(x => x).ToArray();
271          for (int t = 0; t < targetVariables.Length; t++) {
272            var actualContinuation = ProblemData.Dataset.GetDoubleValues(targetVariables[t],
273                                                                         Enumerable.Range(row, horizon));
274            int maWindow = 10 * horizon;
275            var movingAverageContinuation = from h in Enumerable.Range(0, horizon)
276                                            select (from r in Enumerable.Range(row + h - maWindow, maWindow - h)
277                                                    where r > 0
278                                                    select ProblemData.Dataset.GetDoubleValue(targetVariables[t], r)
279                                                   ).Average();
280            var mean = ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TrainingIndizes).Median();
281            double startValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], row - 1);
282            var prognosedContinuation = prognosedTrainingValues.Skip(t).TakeEvery(targetVariables.Length);
283            trainingDsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
284            trainingWdsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
285            trainingTheilsULastCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
286            trainingTheilsUMeanCalculators[t].Add(startValue, actualContinuation.Select(x => mean), actualContinuation, prognosedContinuation);
287            trainingTheilsUMovingAverageCalculators[t].Add(startValue, movingAverageContinuation, actualContinuation, prognosedContinuation);
288          }
289        }
290      }
291      var allPrognosedTestValues = GetPrognosedValues(ProblemData.TestIndizes, horizon).GetEnumerator();
292      foreach (var row in ProblemData.TestIndizes) {
293        if (row + horizon < ProblemData.Dataset.Rows) {
294          allPrognosedTestValues.MoveNext();
295          var prognosedTestValues = allPrognosedTestValues.Current.SelectMany(x => x).ToArray();
296          for (int t = 0; t < targetVariables.Length; t++) {
297            var actualContinuation = ProblemData.Dataset.GetDoubleValues(targetVariables[t],
298                                                                         Enumerable.Range(row, horizon));
299            int maWindow = 10 * horizon;
300            var movingAverageContinuation = from h in Enumerable.Range(0, horizon)
301                                            select (from r in Enumerable.Range(row + h - maWindow, maWindow - h)
302                                                    where r > 0
303                                                    select ProblemData.Dataset.GetDoubleValue(targetVariables[t], r)
304                                                   ).Average();
305            // mean must be calculated on the training set!
306            var mean = ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TrainingIndizes).Median();
307            double startValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], row - 1);
308            var prognosedContinuation = prognosedTestValues.Skip(t).TakeEvery(targetVariables.Length);
309            testDsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
310            testWdsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
311            testTheilsULastCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
312            testTheilsUMeanCalculators[t].Add(startValue, actualContinuation.Select(x => mean), actualContinuation, prognosedContinuation);
313            testTheilsUMovingAverageCalculators[t].Add(startValue, movingAverageContinuation, actualContinuation, prognosedContinuation);
314          }
315        }
316      }
317
318      TrainingDirectionalSymmetry = trainingDsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
319        .ToArray();
320      TestDirectionalSymmetry = testDsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
321        .ToArray();
322      TrainingWeightedDirectionalSymmetry = trainingWdsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
323        .ToArray();
324      TestWeightedDirectionalSymmetry = testWdsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
325        .ToArray();
326      TrainingTheilsUStatisticLast = trainingTheilsULastCalculators
327        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
328        .ToArray();
329      TestTheilsUStatisticLast = testTheilsULastCalculators
330        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
331        .ToArray();
332      TrainingTheilsUStatisticMean = trainingTheilsUMeanCalculators
333        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
334        .ToArray();
335      TestTheilsUStatisticMean = testTheilsUMeanCalculators
336        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
337        .ToArray();
338      TrainingTheilsUStatisticMovingAverage = trainingTheilsUMovingAverageCalculators
339        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
340        .ToArray();
341      TestTheilsUStatisticMovingAverage = testTheilsUMovingAverageCalculators
342        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
343        .ToArray();
344    }
345  }
346}
Note: See TracBrowser for help on using the repository browser.