Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/20/10 20:31:23 (14 years ago)
Author:
gkronber
Message:

Included tracking of best of run solution (based on validation set) and calculation of MSE, R² and rel. Error on training and test sets. #938 (Data types and operators for regression problems)

Location:
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators
Files:
2 edited
5 copied

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleEvaluator.cs

    r3376 r3452  
    3838      get { return (ILookupParameter<DoubleMatrix>)Parameters["Values"]; }
    3939    }
    40     public ILookupParameter<DoubleValue> QualityParameter {
    41       get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
    42     }
    43 
    4440    public SimpleEvaluator()
    4541      : base() {
    4642      Parameters.Add(new LookupParameter<DoubleMatrix>("Values", "Table of original and predicted values for which the quality value should be evaluated."));
    47       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value calculated from the values table."));
    4843    }
    4944
    5045    public override IOperation Apply() {
    5146      DoubleMatrix values = ValuesParameter.ActualValue;
    52       QualityParameter.ActualValue = new DoubleValue(Apply(values));
     47      Apply(values);
    5348      return null;
    5449    }
    5550
    56     protected abstract double Apply(DoubleMatrix values);
     51    protected abstract void Apply(DoubleMatrix values);
    5752  }
    5853}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMSEEvaluator.cs

    r3376 r3452  
    2727using HeuristicLab.Core;
    2828using HeuristicLab.Data;
     29using HeuristicLab.Parameters;
    2930
    3031namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
    3132  public class SimpleMSEEvaluator : SimpleEvaluator {
    3233
    33     public SimpleMSEEvaluator()
    34       : base() {
    35       QualityParameter.ActualName = "MeanSquaredError";
     34    public ILookupParameter<DoubleValue> MeanSquaredErrorParameter {
     35      get { return (ILookupParameter<DoubleValue>)Parameters["MeanSquaredError"]; }
    3636    }
    3737
    38     protected override double Apply(DoubleMatrix values) {
    39       return Calculate(values);
     38    public SimpleMSEEvaluator() {
     39      Parameters.Add(new LookupParameter<DoubleValue>("MeanSquaredError", "The mean squared error of estimated values."));
     40    }
     41
     42    protected override void Apply(DoubleMatrix values) {
     43      MeanSquaredErrorParameter.ActualValue = new DoubleValue(Calculate(values));
    4044    }
    4145
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMeanAbsolutePercentageErrorEvaluator.cs

    r3441 r3452  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    2626using HeuristicLab.Core;
    2727using HeuristicLab.Data;
    28 using HeuristicLab.DataAnalysis;
     28using HeuristicLab.Parameters;
     29using HeuristicLab.Common;
    2930
    30 namespace HeuristicLab.Modeling {
    31   public class SimpleMeanAbsolutePercentageErrorEvaluator : SimpleEvaluatorBase {
    32 
    33     public override string OutputVariableName {
    34       get {
    35         return "MAPE";
    36       }
     31namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
     32  public class SimpleMeanAbsolutePercentageErrorEvaluator : SimpleEvaluator {
     33    public ILookupParameter<PercentValue> AverageRelativeErrorParameter {
     34      get { return (ILookupParameter<PercentValue>)Parameters["AverageRelativeError"]; }
    3735    }
    3836
    39     public override double Evaluate(double[,] values) {
    40       try {
    41         return Calculate(values);
    42       }
    43       catch (ArgumentException) {
    44         return double.PositiveInfinity;
    45       }
     37    public SimpleMeanAbsolutePercentageErrorEvaluator() {
     38      Parameters.Add(new LookupParameter<PercentValue>("AverageRelativeError", "The average relative error of estimated values."));
    4639    }
    4740
    48     public static double Calculate(double[,] values) {
    49       double errorsSum = 0.0;
    50       int n = 0;
    51       for (int i = 0; i < values.GetLength(0); i++) {
    52         double estimated = values[i, ESTIMATION_INDEX];
    53         double original = values[i, ORIGINAL_INDEX];
     41    protected override void Apply(DoubleMatrix values) {
     42      var original = from i in Enumerable.Range(0, values.Rows)
     43                     select values[i, ORIGINAL_INDEX];
     44      var estimated = from i in Enumerable.Range(0, values.Rows)
     45                      select values[i, ESTIMATION_INDEX];
     46      AverageRelativeErrorParameter.ActualValue = new PercentValue(Calculate(original, estimated));
     47    }
    5448
    55         if (!double.IsNaN(estimated) && !double.IsInfinity(estimated) &&
    56           !double.IsNaN(original) && !double.IsInfinity(original) && original != 0.0) {
    57           double percent_error = Math.Abs((estimated - original) / original);
    58           errorsSum += percent_error;
    59           n++;
     49    public static double Calculate(IEnumerable<double> original, IEnumerable<double> estimated) {
     50      double sre = 0;
     51      int cnt = 0;
     52      var originalEnumerator = original.GetEnumerator();
     53      var estimatedEnumerator = estimated.GetEnumerator();
     54      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
     55        double e = estimatedEnumerator.Current;
     56        double o = originalEnumerator.Current;
     57        if (!double.IsNaN(e) && !double.IsInfinity(e) &&
     58            !double.IsNaN(o) && !double.IsInfinity(o) && !o.IsAlmost(0.0)) {
     59          double error = Math.Abs((e - o) / o);
     60          sre += error * error;
     61          cnt++;
    6062        }
    6163      }
    62       if (n > 0) {
    63         return errorsSum / n;
    64       } else throw new ArgumentException("Mean of absolute percentage error is not defined for input vectors of NaN or Inf");
     64      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
     65        throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
     66      } else if (cnt == 0) {
     67        throw new ArgumentException("Average relative error is not defined for input vectors of NaN or Inf");
     68      } else {
     69        return sre / cnt;
     70      }
    6571    }
    6672  }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMeanAbsolutePercentageOfRangeErrorEvaluator.cs

    r3441 r3452  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    2727using HeuristicLab.Common;
    2828using HeuristicLab.Data;
    29 using HeuristicLab.DataAnalysis;
     29using HeuristicLab.Parameters;
    3030
    31 namespace HeuristicLab.Modeling {
    32   public class SimpleMeanAbsolutePercentageOfRangeErrorEvaluator : SimpleEvaluatorBase {
    33     public override string OutputVariableName {
    34       get {
    35         return "MAPRE";
    36       }
     31namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
     32  public class SimpleMeanAbsolutePercentageOfRangeErrorEvaluator : SimpleEvaluator {
     33
     34    public ILookupParameter<PercentValue> AveragePercentageOfRangeErrorParameter {
     35      get { return (ILookupParameter<PercentValue>)Parameters["AveragePercentageOfRangeError"]; }
    3736    }
    3837
    39     public override double Evaluate(double[,] values) {
    40       try {
    41         return Calculate(values);
    42       }
    43       catch (ArgumentException) {
    44         return double.PositiveInfinity;
    45       }
     38    public SimpleMeanAbsolutePercentageOfRangeErrorEvaluator() {
     39      Parameters.Add(new LookupParameter<PercentValue>("AveragePercentageOfRangeError", "The average relative (percentage of range) error of estimated values."));
    4640    }
    4741
    48     public static double Calculate(double[,] values) {
     42    protected override void Apply(DoubleMatrix values) {
     43      var original = from i in Enumerable.Range(0, values.Rows)
     44                     select values[i, ORIGINAL_INDEX];
     45      var estimated = from i in Enumerable.Range(0, values.Rows)
     46                      select values[i, ESTIMATION_INDEX];
     47      AveragePercentageOfRangeErrorParameter.ActualValue = new PercentValue(Calculate(original, estimated));
     48    }
     49
     50    public static double Calculate(IEnumerable<double> original, IEnumerable<double> estimated) {
    4951      double errorsSum = 0.0;
    5052      int n = 0;
    51       // copy to one-dimensional array for range calculation
    52       double[] originalValues = new double[values.GetLength(0)];
    53       for (int i = 0; i < originalValues.Length; i++) originalValues[i] = values[i, ORIGINAL_INDEX];
    54       double range = Statistics.Range(originalValues);
    55       if (double.IsInfinity(range)) throw new ArgumentException("Range of elements in values is infinity");
    56       if (range.IsAlmost(0.0)) throw new ArgumentException("Range of elements in values is zero");
     53      IList<double> originalList = original as IList<double>;
     54      if (originalList == null) originalList = original.ToList();
    5755
    58       for (int i = 0; i < values.GetLength(0); i++) {
    59         double estimated = values[i, ESTIMATION_INDEX];
    60         double original = values[i, ORIGINAL_INDEX];
     56      double range = originalList.Max() - originalList.Min();
     57      if (double.IsInfinity(range)) return double.MaxValue;
     58      if (range.IsAlmost(0.0)) return double.MaxValue;
    6159
    62         if (!double.IsNaN(estimated) && !double.IsInfinity(estimated) &&
    63           !double.IsNaN(original) && !double.IsInfinity(original) && original != 0.0) {
    64           double percent_error = Math.Abs((estimated - original) / range);
     60
     61      var originalEnumerator = original.GetEnumerator();
     62      var estimatedEnumerator = estimated.GetEnumerator();
     63      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
     64        double e = estimatedEnumerator.Current;
     65        double o = originalEnumerator.Current;
     66
     67        if (!double.IsNaN(e) && !double.IsInfinity(e) &&
     68          !double.IsNaN(o) && !double.IsInfinity(o) && !o.IsAlmost(0.0)) {
     69          double percent_error = Math.Abs((e - o) / range);
    6570          errorsSum += percent_error;
    6671          n++;
    6772        }
    6873      }
    69       if (double.IsInfinity(range) || n == 0) {
    70         throw new ArgumentException("Mean of absolute percentage of range error is not defined for input vectors of NaN or Inf");
     74      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
     75        throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
     76      } else if (n == 0) {
     77        return double.MaxValue;
    7178      } else {
    7279        return errorsSum / n;
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleNMSEEvaluator.cs

    r3441 r3452  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2010 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;
    223using System.Collections.Generic;
    324using System.Linq;
     
    526using HeuristicLab.Core;
    627using HeuristicLab.Data;
    7 using HeuristicLab.DataAnalysis;
     28using HeuristicLab.Parameters;
    829
    9 namespace HeuristicLab.Modeling {
    10   public class SimpleNMSEEvaluator : SimpleEvaluatorBase {
     30namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
     31  public class SimpleNMSEEvaluator : SimpleEvaluator {
    1132
    12     public override string OutputVariableName {
    13       get {
    14         return "NMSE";
    15       }
    16     }
    17     public override double Evaluate(double[,] values) {
    18       try {
    19         return Calculate(values);
    20       }
    21       catch (ArgumentException) {
    22         return double.PositiveInfinity;
    23       }
     33    public ILookupParameter<DoubleValue> NormalizedMeanSquaredErrorParameter {
     34      get { return (ILookupParameter<DoubleValue>)Parameters["NormalizedMeanSquaredError"]; }
    2435    }
    2536
    26     public static double Calculate(double[,] values) {
    27       double mse = SimpleMSEEvaluator.Calculate(values);
    28       double mean = Statistics.Mean(Matrix<double>.GetColumn(values, ORIGINAL_INDEX));
    29       double ssd = 0;
    30       int n = 0;
    31       for (int i = 0; i < values.GetLength(0); i++) {
    32         double original = values[i, ORIGINAL_INDEX];
    33         if (!(double.IsNaN(original) || double.IsInfinity(original))) {
    34           double dev = original - mean;
    35           ssd += dev * dev;
    36           n++;
    37         }
    38       }
    39       double variance = ssd / (n - 1);
    40       return mse / variance;
     37    public SimpleNMSEEvaluator() {
     38      Parameters.Add(new LookupParameter<DoubleValue>("NormalizedMeanSquaredError", "The normalized mean squared error (divided by variance) of estimated values."));
     39    }
     40
     41    protected override void Apply(DoubleMatrix values) {
     42      var original = from i in Enumerable.Range(0, values.Rows)
     43                     select values[i, ORIGINAL_INDEX];
     44      var estimated = from i in Enumerable.Range(0, values.Rows)
     45                      select values[i, ESTIMATION_INDEX];
     46
     47      NormalizedMeanSquaredErrorParameter.ActualValue = new DoubleValue(Calculate(original, estimated));
     48    }
     49
     50    public static double Calculate(IEnumerable<double> original, IEnumerable<double> estimated) {
     51      double mse = SimpleMSEEvaluator.Calculate(original, estimated);
     52      return mse / original.Variance();
    4153    }
    4254  }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleRSquaredEvaluator.cs

    r3441 r3452  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2010 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;
    223using System.Collections.Generic;
    324using System.Linq;
    425using System.Text;
    526using HeuristicLab.Core;
     27using HeuristicLab.Common;
    628using HeuristicLab.Data;
    7 using HeuristicLab.DataAnalysis;
     29using HeuristicLab.Parameters;
    830
    9 namespace HeuristicLab.Modeling {
    10   public class SimpleStableCorrelationCoefficientEvaluator : SimpleEvaluatorBase {
    11 
    12     public override string OutputVariableName {
    13       get {
    14         return "R2";
    15       }
     31namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
     32  public class SimpleRSquaredEvaluator : SimpleEvaluator {
     33    public ILookupParameter<DoubleValue> RSquaredParameter {
     34      get { return (ILookupParameter<DoubleValue>)Parameters["RSquared"]; }
    1635    }
    1736
    18     public override double Evaluate(double[,] values) {
    19       try {
    20         return Calculate(values);
    21       }
    22       catch (ArgumentException) {
    23         return double.NegativeInfinity;
    24       }
     37    public SimpleRSquaredEvaluator() {
     38      Parameters.Add(new LookupParameter<DoubleValue>("RSquared", "The squared Pearson's Product Moment Correlation (R²) of estimated values and original values."));
    2539    }
    2640
    27     public static double Calculate(double[,] values) {
     41    protected override void Apply(DoubleMatrix values) {
     42      var original = from i in Enumerable.Range(0, values.Rows)
     43                     select values[i, ORIGINAL_INDEX];
     44      var estimated = from i in Enumerable.Range(0, values.Rows)
     45                      select values[i, ESTIMATION_INDEX];
     46      RSquaredParameter.ActualValue = new DoubleValue(Calculate(original, estimated));
     47    }
     48
     49
     50    public static double Calculate(IEnumerable<double> original, IEnumerable<double> estimated) {
     51      var originalEnumerator = original.GetEnumerator();
     52      var estimatedEnumerator = estimated.GetEnumerator();
     53      originalEnumerator.MoveNext();
     54      estimatedEnumerator.MoveNext();
     55      double e = estimatedEnumerator.Current;
     56      double o = originalEnumerator.Current;
     57
     58      // stable and iterative calculation of R² in one pass over original and estimated
    2859      double sum_sq_x = 0.0;
    2960      double sum_sq_y = 0.0;
    3061      double sum_coproduct = 0.0;
    31       if (IsInvalidValue(values[0, ORIGINAL_INDEX]) || IsInvalidValue(values[0, ESTIMATION_INDEX])) {
    32         throw new ArgumentException("Correlation coefficient is not defined for variables with NaN or infinity values.");
     62      if (IsInvalidValue(o) || IsInvalidValue(e)) {
     63        throw new ArgumentException(" is not defined for variables with NaN or infinity values.");
    3364      }
    34       double mean_x = values[0, ORIGINAL_INDEX];
    35       double mean_y = values[0, ESTIMATION_INDEX];
    36       for (int i = 1; i < values.GetLength(0); i++) {
    37         double sweep = (i - 1.0) / i;
    38         if (IsInvalidValue(values[i, ORIGINAL_INDEX]) || IsInvalidValue(values[i, ESTIMATION_INDEX])) {
     65      double mean_x = o;
     66      double mean_y = e;
     67      int n = 1;
     68      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
     69        e = estimatedEnumerator.Current;
     70        o = originalEnumerator.Current;
     71        double sweep = (n - 1.0) / n;
     72        if (IsInvalidValue(o) || IsInvalidValue(e)) {
    3973          throw new ArgumentException("Correlation coefficient is not defined for variables with NaN or infinity values.");
    4074        }
    41         double delta_x = values[i, ORIGINAL_INDEX] - mean_x;
    42         double delta_y = values[i, ESTIMATION_INDEX] - mean_y;
     75        double delta_x = o - mean_x;
     76        double delta_y = e - mean_y;
    4377        sum_sq_x += delta_x * delta_x * sweep;
    4478        sum_sq_y += delta_y * delta_y * sweep;
    4579        sum_coproduct += delta_x * delta_y * sweep;
    46         mean_x += delta_x / i;
    47         mean_y += delta_y / i;
     80        mean_x += delta_x / n;
     81        mean_y += delta_y / n;
     82        n++;
    4883      }
    49       double pop_sd_x = Math.Sqrt(sum_sq_x / values.GetLength(0));
    50       double pop_sd_y = Math.Sqrt(sum_sq_y / values.GetLength(0));
    51       double cov_x_y = sum_coproduct / values.GetLength(0);
     84      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
     85        throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
     86      } else {
     87        double pop_sd_x = Math.Sqrt(sum_sq_x / n);
     88        double pop_sd_y = Math.Sqrt(sum_sq_y / n);
     89        double cov_x_y = sum_coproduct / n;
    5290
    53       if (pop_sd_x == 0.0 || pop_sd_y == 0.0)
    54         return 0.0;
    55       else {
    56         double r = cov_x_y / (pop_sd_x * pop_sd_y);
    57         return r * r;
     91        if (pop_sd_x.IsAlmost(0.0) || pop_sd_y.IsAlmost(0.0))
     92          return 0.0;
     93        else {
     94          double r = cov_x_y / (pop_sd_x * pop_sd_y);
     95          return r * r;
     96        }
    5897      }
    5998    }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleVarianceAccountedForEvaluator.cs

    r3441 r3452  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    2727using HeuristicLab.Common;
    2828using HeuristicLab.Data;
    29 using HeuristicLab.DataAnalysis;
     29using HeuristicLab.Parameters;
    3030
    31 namespace HeuristicLab.Modeling {
     31namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
    3232  /// <summary>
    3333  /// The Variance Accounted For (VAF) function calculates is computed as
    34   /// VAF(y,y') = ( 1 - var(y-y')/var(y) )
     34  /// VAF(y,y') =  1 - var(y-y')/var(y)
    3535  /// where y' denotes the predicted / modelled values for y and var(x) the variance of a signal x.
    3636  /// </summary>
    37   public class SimpleVarianceAccountedForEvaluator : SimpleEvaluatorBase {
     37  public class SimpleVarianceAccountedForEvaluator : SimpleEvaluator {
    3838
    39     public override string OutputVariableName {
    40       get {
    41         return "VAF";
    42       }
     39    public ILookupParameter<DoubleValue> VarianceAccountedForParameter {
     40      get { return (ILookupParameter<DoubleValue>)Parameters["VarianceAccountedFor"]; }
    4341    }
    4442
    45     public override double Evaluate(double[,] values) {
    46       try {
    47         return Calculate(values);
    48       }
    49       catch (ArgumentException) {
    50         return double.NegativeInfinity;
    51       }
     43    public SimpleVarianceAccountedForEvaluator() {
     44      Parameters.Add(new LookupParameter<DoubleValue>("VarianceAccountedFor", "The variance of the original values accounted for by the estimated values (VAF(y,y') = 1 - var(y-y') / var(y) )."));
    5245    }
    5346
    54     public static double Calculate(double[,] values) {
    55       int n = values.GetLength(0);
    56       double[] errors = new double[n];
    57       double[] originalTargetVariableValues = new double[n];
    58       for (int i = 0; i < n; i++) {
    59         double estimated = values[i, ESTIMATION_INDEX];
    60         double original = values[i, ORIGINAL_INDEX];
    61         if (!double.IsNaN(estimated) && !double.IsInfinity(estimated) &&
    62           !double.IsNaN(original) && !double.IsInfinity(original)) {
    63           errors[i] = original - estimated;
    64           originalTargetVariableValues[i] = original;
    65         } else {
    66           errors[i] = double.NaN;
    67           originalTargetVariableValues[i] = double.NaN;
     47    protected override void Apply(DoubleMatrix values) {
     48      var original = from i in Enumerable.Range(0, values.Rows)
     49                     select values[i, ORIGINAL_INDEX];
     50      var estimated = from i in Enumerable.Range(0, values.Rows)
     51                      select values[i, ESTIMATION_INDEX];
     52      VarianceAccountedForParameter.ActualValue = new DoubleValue(Calculate(original, estimated));
     53    }
     54
     55    public static double Calculate(IEnumerable<double> original, IEnumerable<double> estimated) {
     56      var originalEnumerator = original.GetEnumerator();
     57      var estimatedEnumerator = estimated.GetEnumerator();
     58      var errors = new List<double>();
     59      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
     60        double e = estimatedEnumerator.Current;
     61        double o = originalEnumerator.Current;
     62        if (!double.IsNaN(e) && !double.IsInfinity(e) &&
     63          !double.IsNaN(o) && !double.IsInfinity(o)) {
     64          errors.Add(o - e);
    6865        }
    6966      }
    70       double errorsVariance = Statistics.Variance(errors);
    71       double originalsVariance = Statistics.Variance(originalTargetVariableValues);
     67      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
     68        throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
     69      }
     70
     71      double errorsVariance = errors.Variance();
     72      double originalsVariance = original.Variance();
    7273      if (originalsVariance.IsAlmost(0.0))
    7374        if (errorsVariance.IsAlmost(0.0)) {
    7475          return 1.0;
    7576        } else {
    76           throw new ArgumentException("Variance of original values is zero");
     77          return double.MaxValue;
    7778        } else {
    7879        return 1.0 - errorsVariance / originalsVariance;
Note: See TracChangeset for help on using the changeset viewer.