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 


25  namespace HeuristicLab.Problems.DataAnalysis {


26  public class OnlineCovarianceEvaluator : IOnlineEvaluator {


27 


28  private double originalMean, estimatedMean, Cn;


29  private int n;


30  public double Covariance {


31  get {


32  return n > 0 ? Cn / n : 0.0;


33  }


34  }


35 


36  public OnlineCovarianceEvaluator() {


37  Reset();


38  }


39 


40  #region IOnlineEvaluator Members


41  public double Value {


42  get { return Covariance; }


43  }


44  public void Reset() {


45  n = 0;


46  Cn = 0.0;


47  originalMean = 0.0;


48  estimatedMean = 0.0;


49  }


50 


51  public void Add(double original, double estimated) {


52  if (double.IsNaN(estimated)  double.IsInfinity(estimated) 


53  double.IsNaN(original)  double.IsInfinity(original)) {


54  throw new ArgumentException("Covariance is not defined for series containing NaN or infinity elements");


55  } else {


56  n++;


57  // online calculation of tMean


58  originalMean = originalMean + (original  originalMean) / n;


59  double delta = estimated  estimatedMean; // delta = (y  yMean(n1))


60  estimatedMean = estimatedMean + delta / n;


61 


62  // online calculation of covariance


63  Cn = Cn + delta * (original  originalMean); // C(n) = C(n1) + (y  yMean(n1)) (t  tMean(n))


64  }


65  }


66  #endregion


67 


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


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


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


71  OnlineCovarianceEvaluator covarianceEvaluator = new OnlineCovarianceEvaluator();


72 


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


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


75  double estimated = secondEnumerator.Current;


76  double original = firstEnumerator.Current;


77  covarianceEvaluator.Add(original, estimated);


78  }


79 


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


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


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


83  } else {


84  return covarianceEvaluator.Covariance;


85  }


86  }


87  }


88  }

