1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022011 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 


22  using System;


23  using System.Collections.Generic;


24  using HeuristicLab.Common;


25 


26  namespace HeuristicLab.Problems.DataAnalysis {


27  public class OnlinePearsonsRSquaredEvaluator : IOnlineEvaluator {


28  private OnlineCovarianceEvaluator covEvaluator = new OnlineCovarianceEvaluator();


29  private OnlineMeanAndVarianceCalculator sxEvaluator = new OnlineMeanAndVarianceCalculator();


30  private OnlineMeanAndVarianceCalculator syEvaluator = new OnlineMeanAndVarianceCalculator();


31 


32  public double RSquared {


33  get {


34  double xVar = sxEvaluator.PopulationVariance;


35  double yVar = syEvaluator.PopulationVariance;


36  if (xVar.IsAlmost(0.0)  yVar.IsAlmost(0.0)) {


37  return 0.0;


38  } else {


39  double r = covEvaluator.Covariance / (Math.Sqrt(xVar) * Math.Sqrt(yVar));


40  return r * r;


41  }


42  }


43  }


44 


45  public OnlinePearsonsRSquaredEvaluator() { }


46 


47  #region IOnlineEvaluator Members


48  public double Value {


49  get { return RSquared; }


50  }


51  public void Reset() {


52  covEvaluator.Reset();


53  sxEvaluator.Reset();


54  syEvaluator.Reset();


55  }


56 


57  public void Add(double x, double y) {


58  if (IsInvalidValue(x)  IsInvalidValue(y)) {


59  throw new ArgumentException("R² is not defined for variables with NaN or infinity values.");


60  }


61  covEvaluator.Add(x, y);


62  sxEvaluator.Add(x);


63  syEvaluator.Add(y);


64  }


65 


66  #endregion


67 


68  private bool IsInvalidValue(double x) {


69  return double.IsNaN(x)  double.IsInfinity(x);


70  }


71 


72  public static double Calculate(IEnumerable<double> first, IEnumerable<double> second) {


73  IEnumerator<double> firstEnumerator = first.GetEnumerator();


74  IEnumerator<double> secondEnumerator = second.GetEnumerator();


75  OnlinePearsonsRSquaredEvaluator rSquaredEvaluator = new OnlinePearsonsRSquaredEvaluator();


76 


77  // always move forward both enumerators (do not use shortcircuit evaluation!)


78  while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {


79  double estimated = secondEnumerator.Current;


80  double original = firstEnumerator.Current;


81  rSquaredEvaluator.Add(original, estimated);


82  }


83 


84  // check if both enumerators are at the end to make sure both enumerations have the same length


85  if (secondEnumerator.MoveNext()  firstEnumerator.MoveNext()) {


86  throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");


87  } else {


88  return rSquaredEvaluator.RSquared;


89  }


90  }


91  }


92  }

