#region License Information
/* HeuristicLab
* Copyright (C) 2002-2013 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;
using System.Linq;
namespace HeuristicLab.DataPreprocessing {
public class SearchLogic : ISearchLogic {
private readonly ITransactionalPreprocessingData preprocessingData;
private Dictionary> MissingValueIndicies { get; set; }
private Dictionary ValuesWithoutNaN { get; set; }
public SearchLogic(ITransactionalPreprocessingData thePreprocessingData) {
preprocessingData = thePreprocessingData;
MissingValueIndicies = new Dictionary>();
ValuesWithoutNaN = new Dictionary();
preprocessingData.Changed += preprocessingData_Changed;
}
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:
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 bool IsMissingValue(int columnIndex, int rowIndex) {
if (preprocessingData.IsType(columnIndex)) {
return double.IsNaN(preprocessingData.GetCell(columnIndex, rowIndex));
} else if (preprocessingData.IsType(columnIndex)) {
return string.IsNullOrEmpty(preprocessingData.GetCell(columnIndex, rowIndex));
} else if (preprocessingData.IsType(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 IList GetMissingValueIndices(int columnIndex) {
if (!MissingValueIndicies.ContainsKey(columnIndex)){
if (preprocessingData.IsType(columnIndex)) {
MissingValueIndicies[columnIndex] = GetMissingValueIndices(columnIndex);
} else if (preprocessingData.IsType(columnIndex)) {
MissingValueIndicies[columnIndex] = GetMissingValueIndices(columnIndex);
} else if (preprocessingData.IsType(columnIndex)) {
MissingValueIndicies[columnIndex] = GetMissingValueIndices(columnIndex);
} else {
throw new ArgumentException("column " + columnIndex + " contains a non supported type.");
}
}
return MissingValueIndicies[columnIndex];
}
private IList GetMissingValueIndices(int columnIndex) {
List missingIndices = new List();
for(int row = 0; row < preprocessingData.Rows; ++row) {
if (IsMissingValue(columnIndex, row)) {
missingIndices.Add(row);
}
}
return missingIndices;
}
public IEnumerable GetValuesWithoutNaN(int columnIndex, bool considerSelection)
{
if (considerSelection) {
var selectedRows = preprocessingData.GetSelection()[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];
}
}
}
}