#region License Information
/* HeuristicLab
* Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
namespace HeuristicLab.DataPreprocessing {
public class SearchLogic {
private readonly ITransactionalPreprocessingData preprocessingData;
private readonly FilterLogic filterLogic;
private Dictionary> MissingValueIndicies { get; set; }
private Dictionary ValuesWithoutNaN { get; set; }
public IEnumerable VariableNames {
get { return preprocessingData.VariableNames; }
}
public int Columns {
get { return preprocessingData.Columns; }
}
public int Rows {
get { return preprocessingData.Rows; }
}
public SearchLogic(ITransactionalPreprocessingData thePreprocessingData, FilterLogic theFilterLogic) {
preprocessingData = thePreprocessingData;
filterLogic = theFilterLogic;
MissingValueIndicies = new Dictionary>();
ValuesWithoutNaN = new Dictionary();
preprocessingData.Changed += PreprocessingData_Changed;
filterLogic.FilterChanged += FilterLogic_FilterChanged;
}
void FilterLogic_FilterChanged(object sender, EventArgs e) {
//recalculate
for (int i = 0; i < Columns; i++) {
MissingValueIndicies.Remove(i);
ValuesWithoutNaN.Remove(i);
}
}
void PreprocessingData_Changed(object sender, DataPreprocessingChangedEventArgs e) {
switch (e.Type) {
case DataPreprocessingChangedEventType.DeleteColumn:
case DataPreprocessingChangedEventType.ChangeColumn:
MissingValueIndicies.Remove(e.Column);
ValuesWithoutNaN.Remove(e.Column);
break;
case DataPreprocessingChangedEventType.AddColumn:
//cache does not need to be updated, will be calculated the first time it is requested
break;
case DataPreprocessingChangedEventType.DeleteRow:
case DataPreprocessingChangedEventType.AddRow:
case DataPreprocessingChangedEventType.ChangeItem:
case DataPreprocessingChangedEventType.Any:
case DataPreprocessingChangedEventType.Transformation:
default:
MissingValueIndicies = new Dictionary>();
ValuesWithoutNaN = new Dictionary();
break;
}
}
public IDictionary> GetMissingValueIndices() {
var dic = new Dictionary>();
for (int i = 0; i < preprocessingData.Columns; ++i) {
dic.Add(i, GetMissingValueIndices(i));
}
return dic;
}
public IList GetMissingValueIndices(int columnIndex) {
int index = 0;
var indices = new List();
if (MissingValueIndicies.ContainsKey(columnIndex)) {
return MissingValueIndicies[columnIndex];
}
if (preprocessingData.VariableHasType(columnIndex)) {
foreach (var v in preprocessingData.GetValues(columnIndex)) {
if (double.IsNaN(v)) indices.Add(index);
index++;
}
} else if (preprocessingData.VariableHasType(columnIndex)) {
foreach (var v in preprocessingData.GetValues(columnIndex)) {
if (string.IsNullOrEmpty(v)) indices.Add(index);
index++;
}
} else if (preprocessingData.VariableHasType(columnIndex)) {
foreach (var v in preprocessingData.GetValues(columnIndex)) {
if (DateTime.MinValue.Equals(v)) indices.Add(index);
index++;
}
} else {
throw new ArgumentException("column " + columnIndex + " contains a non supported type.");
}
MissingValueIndicies[columnIndex] = indices;
return MissingValueIndicies[columnIndex];
}
public bool IsMissingValue(int columnIndex, int rowIndex) {
if (preprocessingData.VariableHasType(columnIndex)) {
return double.IsNaN(preprocessingData.GetCell(columnIndex, rowIndex));
} else if (preprocessingData.VariableHasType(columnIndex)) {
return string.IsNullOrEmpty(preprocessingData.GetCell(columnIndex, rowIndex));
} else if (preprocessingData.VariableHasType(columnIndex)) {
return preprocessingData.GetCell(columnIndex, rowIndex).Equals(DateTime.MinValue);
} else {
throw new ArgumentException("cell in column " + columnIndex + " and row index " + rowIndex + " contains a non supported type.");
}
}
public IEnumerable GetValuesWithoutNaN(int columnIndex, bool considerSelection) {
if (considerSelection) {
var selectedRows = preprocessingData.Selection[columnIndex];
List values = new List();
foreach (var rowIdx in selectedRows) {
if (!IsMissingValue(columnIndex, rowIdx)) {
values.Add(preprocessingData.GetCell(columnIndex, rowIdx));
}
}
return values;
} else {
if (!ValuesWithoutNaN.ContainsKey(columnIndex)) {
List values = new List();
for (int row = 0; row < preprocessingData.Rows; ++row) {
if (!IsMissingValue(columnIndex, row)) {
values.Add(preprocessingData.GetCell(columnIndex, row));
}
}
ValuesWithoutNaN[columnIndex] = values;
}
return (IEnumerable)ValuesWithoutNaN[columnIndex];
}
}
}
}