#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.Globalization;
using System.Linq;
using HEAL.Attic;
namespace HeuristicLab.DataImporter.Data.Model {
[StorableType("1C7B8981-3027-4133-A55F-2B1985568E69")]
public class DoubleColumn : ColumnBase {
[Storable]
private List values;
[StorableConstructor]
protected DoubleColumn(StorableConstructorFlag _) : base(_) { }
public DoubleColumn(string columnName)
: base(columnName) {
this.values = new List();
}
public DoubleColumn(string columnName, int capacity)
: this(columnName) {
this.values.Capacity = capacity;
}
public override Type DataType {
get { return typeof(double?); }
}
public override string ToString() {
return base.ToString() + " ";
}
protected override IList Values {
get { return this.values; }
}
public override void AddValue(IComparable value) {
this.values.Add((double?)value);
}
public override void AddValueOrNull(IComparable value) {
this.values.Add(ConvertToDouble(value));
}
public override void InsertValue(int position, IComparable value) {
this.values.Insert(position, (double?)value);
}
public override void ChangeValue(int position, IComparable value) {
this.values[position] = (double?)value;
}
public override void ChangeValueOrNull(int position, IComparable value) {
this.values[position] = ConvertToDouble(value);
}
public override void ChangeValueOrLeaveOldValue(int position, IComparable value) {
if (value == null)
this.values[position] = null;
else {
double? val = ConvertToDouble(value);
if (val != null)
this.values[position] = val;
}
}
private double? ConvertToDouble(IComparable value) {
double? val = null;
double test;
if (value != null) {
if (value is DateTime)
val = double.Parse(((DateTime)value).ToString("yyyyMMddHHmmss"));
else if (value is string) {
string s = value.ToString();
if (s.StartsWith("."))
s = s.Insert(0, "0");
else if (s.StartsWith("-."))
s = s.Insert(1, "0");
CultureInfo culture = CultureInfo.CurrentCulture;
if (s.Contains('.'))
culture = CultureInfo.InvariantCulture;
if (double.TryParse(s, NumberStyles.Any, culture, out test))
val = test;
} else if (value is double)
val = (double)value;
}
return val;
}
public double? Mean {
get {
double sum = 0;
int cnt = 0;
for (int i = 0; i < this.values.Count; i++) {
if (this.values[i] != null) {
sum += (double)this.values[i];
cnt++;
}
}
if (cnt != 0)
return sum / cnt;
else
return null;
}
}
public double? StandardDeviation {
get {
double? mean = Mean;
double sum = 0;
if (mean == null)
return null;
for (int i = 0; i < this.values.Count; i++) {
if (values[i] == null)
continue;
sum += Math.Pow((double)(values[i] - mean), 2.0);
}
return Math.Sqrt(sum / NonNullValuesCount);
}
}
public double? Median {
get {
return GetMedian(0, this.TotalValuesCount);
}
}
public double? GetMedian(int startIndex, int endIndex) {
List sortedValues = values.GetRange(startIndex, endIndex - startIndex).Where(x => x != null).ToList(); ;
if (sortedValues.Count == 0)
return null;
sortedValues.Sort();
if (sortedValues.Count % 2 == 0)
return (sortedValues[sortedValues.Count / 2] + sortedValues[sortedValues.Count / 2 - 1]) / 2;
else
return sortedValues[sortedValues.Count / 2];
}
public override ColumnBase CreateCopyOfColumnWithoutValues() {
return CreateCopyOfColumnWithoutValues(this.values.Capacity);
}
public override ColumnBase CreateCopyOfColumnWithoutValues(int capacity) {
return new DoubleColumn(this.Name, capacity);
}
}
}