1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022015 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 System.ComponentModel;


25  using System.Linq;


26  using System.Threading.Tasks;


27  using HeuristicLab.PluginInfrastructure;


28 


29  namespace HeuristicLab.Problems.DataAnalysis.Views {


30  [NonDiscoverableType]


31  public sealed class FeatureCorrelationCalculator : AbstractFeatureCorrelationCalculator {


32  public FeatureCorrelationCalculator() : base() { }


33 


34  public void CalculateElements(IDataAnalysisProblemData problemData, IDependencyCalculator calc, string partition, bool ignoreMissingValues) {


35  var indices = GetRelevantIndices(problemData, partition);


36  var info = new BackgroundWorkerInfo {


37  Dataset = problemData.Dataset, Calculator = calc, Partition = partition, Indices = indices, IgnoreMissingValues = ignoreMissingValues


38  };


39 


40  StartCalculation(info);


41  }


42 


43  protected override void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {


44  BackgroundWorker worker = (BackgroundWorker)sender;


45  BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;


46 


47  var dataset = bwInfo.Dataset;


48  var indices = bwInfo.Indices.ToArray();


49  IDependencyCalculator calc = bwInfo.Calculator;


50 


51  IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();


52  OnlineCalculatorError error = OnlineCalculatorError.None;


53  int length = doubleVariableNames.Count;


54  double[,] elements = new double[length, length];


55 


56  worker.ReportProgress(0);


57 


58  for (int counter = 0; counter < length; counter++) {


59  if (worker.CancellationPending) {


60  worker.ReportProgress(100);


61  e.Cancel = true;


62  return;


63  }


64 


65  var i = counter;


66  Parallel.ForEach(Enumerable.Range(i, length  i), j => {


67  var var1 = dataset.GetDoubleValues(doubleVariableNames[i], indices);


68  var var2 = dataset.GetDoubleValues(doubleVariableNames[j], indices);


69 


70  if (bwInfo.IgnoreMissingValues) {


71  var filtered = FilterNaNValues(var1, var2);


72  elements[i, j] = calc.Calculate(filtered, out error);


73  } else


74  elements[i, j] = calc.Calculate(var1, var2, out error);


75 


76  if (!error.Equals(OnlineCalculatorError.None)) {


77  elements[i, j] = double.NaN;


78  }


79  elements[j, i] = elements[i, j];


80 


81  });


82  worker.ReportProgress((int)(((double)counter) / length * 100));


83  }


84  e.Result = elements;


85  worker.ReportProgress(100);


86  }


87 


88 


89  private static IEnumerable<Tuple<double, double>> FilterNaNValues(IEnumerable<double> first, IEnumerable<double> second) {


90  var firstEnumerator = first.GetEnumerator();


91  var secondEnumerator = second.GetEnumerator();


92 


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


94  var firstValue = firstEnumerator.Current;


95  var secondValue = secondEnumerator.Current;


96 


97  if (double.IsNaN(firstValue)) continue;


98  if (double.IsNaN(secondValue)) continue;


99 


100  yield return Tuple.Create(firstValue, secondValue);


101  }


102 


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


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


105  }


106  }


107  }


108  }

