Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationEnsembleModel.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationEnsembleModel.cs	(revision 5722)
+++ 	(revision )
@@ -1,94 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  /// <summary>
-  /// Represents classification solutions that contain an ensemble of multiple classification models
-  /// </summary>
-  [StorableClass]
-  [Item("ClassificationEnsembleModel", "A classification model that contains an ensemble of multiple classification models")]
-  public class ClassificationEnsembleModel : NamedItem, IClassificationEnsembleModel {
-
-    [Storable]
-    private List<IClassificationModel> models;
-    public IEnumerable<IClassificationModel> Models {
-      get { return new List<IClassificationModel>(models); }
-    }
-    [StorableConstructor]
-    protected ClassificationEnsembleModel(bool deserializing) : base(deserializing) { }
-    protected ClassificationEnsembleModel(ClassificationEnsembleModel original, Cloner cloner)
-      : base(original, cloner) {
-      this.models = original.Models.Select(m => cloner.Clone(m)).ToList();
-    }
-    public ClassificationEnsembleModel(IEnumerable<IClassificationModel> models)
-      : base() {
-      this.name = ItemName;
-      this.description = ItemDescription;
-      this.models = new List<IClassificationModel>(models);      
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ClassificationEnsembleModel(this, cloner);
-    }
-
-    #region IClassificationEnsembleModel Members
-
-    public IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows) {
-      var estimatedValuesEnumerators = (from model in models
-                                        select model.GetEstimatedClassValues(dataset, rows).GetEnumerator())
-                                       .ToList();
-
-      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
-        yield return from enumerator in estimatedValuesEnumerators
-                     select enumerator.Current;
-      }
-    }
-
-    #endregion
-
-    #region IClassificationModel Members
-
-    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
-      foreach (var estimatedValuesVector in GetEstimatedClassValueVectors(dataset, rows)) {
-        // return the class which is most often occuring
-        yield return
-          estimatedValuesVector
-          .GroupBy(x => x)
-          .OrderBy(g => -g.Count())
-          .Select(g => g.Key)
-          .First();
-      }
-    }
-
-    #endregion
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationProblem.cs	(revision 5722)
+++ 	(revision )
@@ -1,46 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("ClassificationProblem", "A general classification problem.")]
-  [Creatable("Problems")]
-  public class ClassificationProblem : DataAnalysisProblem<IClassificationProblemData>, IClassificationProblem {
-    [StorableConstructor]
-    protected ClassificationProblem(bool deserializing) : base(deserializing) { }
-    protected ClassificationProblem(ClassificationProblem original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) { return new ClassificationProblem(this, cloner); }
-
-    public ClassificationProblem()
-      : base() {
-      ProblemData = new ClassificationProblemData();
-    }
-
-    public override void ImportProblemDataFromFile(string fileName) {
-      ClassificationProblemData problemData = ClassificationProblemData.ImportFromFile(fileName);
-      ProblemData = problemData;
-    }
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationProblemData.cs	(revision 5722)
+++ 	(revision )
@@ -1,373 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("ClassificationProblemData", "Represents an item containing all data defining a classification problem.")]
-  public class ClassificationProblemData : DataAnalysisProblemData, IClassificationProblemData {
-    private const string TargetVariableParameterName = "TargetVariable";
-    private const string ClassNamesParameterName = "ClassNames";
-    private const string ClassificationPenaltiesParameterName = "ClassificationPenalties";
-
-    #region default data
-    private static string[] defaultVariableNames = new string[] { "sample", "clump thickness", "cell size", "cell shape", "marginal adhesion", "epithelial cell size", "bare nuclei", "chromatin", "nucleoli", "mitoses", "class" };
-    private static double[,] defaultData = new double[,]{
-     {1000025,5,1,1,1,2,1,3,1,1,2      },
-     {1002945,5,4,4,5,7,10,3,2,1,2     },
-     {1015425,3,1,1,1,2,2,3,1,1,2      },
-     {1016277,6,8,8,1,3,4,3,7,1,2      },
-     {1017023,4,1,1,3,2,1,3,1,1,2      },
-     {1017122,8,10,10,8,7,10,9,7,1,4   },
-     {1018099,1,1,1,1,2,10,3,1,1,2     },
-     {1018561,2,1,2,1,2,1,3,1,1,2      },
-     {1033078,2,1,1,1,2,1,1,1,5,2      },
-     {1033078,4,2,1,1,2,1,2,1,1,2      },
-     {1035283,1,1,1,1,1,1,3,1,1,2      },
-     {1036172,2,1,1,1,2,1,2,1,1,2      },
-     {1041801,5,3,3,3,2,3,4,4,1,4      },
-     {1043999,1,1,1,1,2,3,3,1,1,2      },
-     {1044572,8,7,5,10,7,9,5,5,4,4     },
-     {1047630,7,4,6,4,6,1,4,3,1,4      },
-     {1048672,4,1,1,1,2,1,2,1,1,2      },
-     {1049815,4,1,1,1,2,1,3,1,1,2      },
-     {1050670,10,7,7,6,4,10,4,1,2,4    },
-     {1050718,6,1,1,1,2,1,3,1,1,2      },
-     {1054590,7,3,2,10,5,10,5,4,4,4    },
-     {1054593,10,5,5,3,6,7,7,10,1,4    },
-     {1056784,3,1,1,1,2,1,2,1,1,2      },
-     {1057013,8,4,5,1,2,2,7,3,1,4      },
-     {1059552,1,1,1,1,2,1,3,1,1,2      },
-     {1065726,5,2,3,4,2,7,3,6,1,4      },
-     {1066373,3,2,1,1,1,1,2,1,1,2      },
-     {1066979,5,1,1,1,2,1,2,1,1,2      },
-     {1067444,2,1,1,1,2,1,2,1,1,2      },
-     {1070935,1,1,3,1,2,1,1,1,1,2      },
-     {1070935,3,1,1,1,1,1,2,1,1,2      },
-     {1071760,2,1,1,1,2,1,3,1,1,2      },
-     {1072179,10,7,7,3,8,5,7,4,3,4     },
-     {1074610,2,1,1,2,2,1,3,1,1,2      },
-     {1075123,3,1,2,1,2,1,2,1,1,2      },
-     {1079304,2,1,1,1,2,1,2,1,1,2      },
-     {1080185,10,10,10,8,6,1,8,9,1,4   },
-     {1081791,6,2,1,1,1,1,7,1,1,2      },
-     {1084584,5,4,4,9,2,10,5,6,1,4     },
-     {1091262,2,5,3,3,6,7,7,5,1,4      },
-     {1096800,6,6,6,9,6,4,7,8,1,2      },
-     {1099510,10,4,3,1,3,3,6,5,2,4     },
-     {1100524,6,10,10,2,8,10,7,3,3,4   },
-     {1102573,5,6,5,6,10,1,3,1,1,4     },
-     {1103608,10,10,10,4,8,1,8,10,1,4  },
-     {1103722,1,1,1,1,2,1,2,1,2,2      },
-     {1105257,3,7,7,4,4,9,4,8,1,4      },
-     {1105524,1,1,1,1,2,1,2,1,1,2      },
-     {1106095,4,1,1,3,2,1,3,1,1,2      },
-     {1106829,7,8,7,2,4,8,3,8,2,4      },
-     {1108370,9,5,8,1,2,3,2,1,5,4      },
-     {1108449,5,3,3,4,2,4,3,4,1,4      },
-     {1110102,10,3,6,2,3,5,4,10,2,4    },
-     {1110503,5,5,5,8,10,8,7,3,7,4     },
-     {1110524,10,5,5,6,8,8,7,1,1,4     },
-     {1111249,10,6,6,3,4,5,3,6,1,4     },
-     {1112209,8,10,10,1,3,6,3,9,1,4    },
-     {1113038,8,2,4,1,5,1,5,4,4,4      },
-     {1113483,5,2,3,1,6,10,5,1,1,4     },
-     {1113906,9,5,5,2,2,2,5,1,1,4      },
-     {1115282,5,3,5,5,3,3,4,10,1,4     },
-     {1115293,1,1,1,1,2,2,2,1,1,2      },
-     {1116116,9,10,10,1,10,8,3,3,1,4   },
-     {1116132,6,3,4,1,5,2,3,9,1,4      },
-     {1116192,1,1,1,1,2,1,2,1,1,2      },
-     {1116998,10,4,2,1,3,2,4,3,10,4    },
-     {1117152,4,1,1,1,2,1,3,1,1,2      },
-     {1118039,5,3,4,1,8,10,4,9,1,4     },
-     {1120559,8,3,8,3,4,9,8,9,8,4      },
-     {1121732,1,1,1,1,2,1,3,2,1,2      },
-     {1121919,5,1,3,1,2,1,2,1,1,2      },
-     {1123061,6,10,2,8,10,2,7,8,10,4   },
-     {1124651,1,3,3,2,2,1,7,2,1,2      },
-     {1125035,9,4,5,10,6,10,4,8,1,4    },
-     {1126417,10,6,4,1,3,4,3,2,3,4     },
-     {1131294,1,1,2,1,2,2,4,2,1,2      },
-     {1132347,1,1,4,1,2,1,2,1,1,2      },
-     {1133041,5,3,1,2,2,1,2,1,1,2      },
-     {1133136,3,1,1,1,2,3,3,1,1,2      },
-     {1136142,2,1,1,1,3,1,2,1,1,2      },
-     {1137156,2,2,2,1,1,1,7,1,1,2      },
-     {1143978,4,1,1,2,2,1,2,1,1,2      },
-     {1143978,5,2,1,1,2,1,3,1,1,2      },
-     {1147044,3,1,1,1,2,2,7,1,1,2      },
-     {1147699,3,5,7,8,8,9,7,10,7,4     },
-     {1147748,5,10,6,1,10,4,4,10,10,4  },
-     {1148278,3,3,6,4,5,8,4,4,1,4      },
-     {1148873,3,6,6,6,5,10,6,8,3,4     },
-     {1152331,4,1,1,1,2,1,3,1,1,2      },
-     {1155546,2,1,1,2,3,1,2,1,1,2      },
-     {1156272,1,1,1,1,2,1,3,1,1,2      },
-     {1156948,3,1,1,2,2,1,1,1,1,2      },
-     {1157734,4,1,1,1,2,1,3,1,1,2      },
-     {1158247,1,1,1,1,2,1,2,1,1,2      },
-     {1160476,2,1,1,1,2,1,3,1,1,2      },
-     {1164066,1,1,1,1,2,1,3,1,1,2      },
-     {1165297,2,1,1,2,2,1,1,1,1,2      },
-     {1165790,5,1,1,1,2,1,3,1,1,2      },
-     {1165926,9,6,9,2,10,6,2,9,10,4    },
-     {1166630,7,5,6,10,5,10,7,9,4,4    },
-     {1166654,10,3,5,1,10,5,3,10,2,4   },
-     {1167439,2,3,4,4,2,5,2,5,1,4      },
-     {1167471,4,1,2,1,2,1,3,1,1,2      },
-     {1168359,8,2,3,1,6,3,7,1,1,4      },
-     {1168736,10,10,10,10,10,1,8,8,8,4 },
-     {1169049,7,3,4,4,3,3,3,2,7,4      },
-     {1170419,10,10,10,8,2,10,4,1,1,4  },
-     {1170420,1,6,8,10,8,10,5,7,1,4    },
-     {1171710,1,1,1,1,2,1,2,3,1,2      },
-     {1171710,6,5,4,4,3,9,7,8,3,4      },
-     {1171795,1,3,1,2,2,2,5,3,2,2      },
-     {1171845,8,6,4,3,5,9,3,1,1,4      },
-     {1172152,10,3,3,10,2,10,7,3,3,4   },
-     {1173216,10,10,10,3,10,8,8,1,1,4  },
-     {1173235,3,3,2,1,2,3,3,1,1,2      },
-     {1173347,1,1,1,1,2,5,1,1,1,2      },
-     {1173347,8,3,3,1,2,2,3,2,1,2      },
-     {1173509,4,5,5,10,4,10,7,5,8,4    },
-     {1173514,1,1,1,1,4,3,1,1,1,2      },
-     {1173681,3,2,1,1,2,2,3,1,1,2      },
-     {1174057,1,1,2,2,2,1,3,1,1,2      },
-     {1174057,4,2,1,1,2,2,3,1,1,2      },
-     {1174131,10,10,10,2,10,10,5,3,3,4 },
-     {1174428,5,3,5,1,8,10,5,3,1,4     },
-     {1175937,5,4,6,7,9,7,8,10,1,4     },
-     {1176406,1,1,1,1,2,1,2,1,1,2      },
-     {1176881,7,5,3,7,4,10,7,5,5,4        }
-};
-    private static Dataset defaultDataset;
-    private static IEnumerable<string> defaultAllowedInputVariables;
-    private static string defaultTargetVariable;
-    static ClassificationProblemData() {
-      defaultDataset = new Dataset(defaultVariableNames, defaultData);
-      defaultDataset.Name = "Wisconsin classification problem";
-      defaultDataset.Description = "subset from to ..";
-
-      defaultAllowedInputVariables = defaultVariableNames.Except(new List<string>() { "sample", "class" });
-      defaultTargetVariable = "class";
-    }
-    #endregion
-
-    #region parameter properties
-    public IValueParameter<StringValue> TargetVariableParameter {
-      get { return (IValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
-    }
-    public IFixedValueParameter<StringMatrix> ClassNamesParameter {
-      get { return (IFixedValueParameter<StringMatrix>)Parameters[ClassNamesParameterName]; }
-    }
-    public IFixedValueParameter<DoubleMatrix> ClassificationPenaltiesParameter {
-      get { return (IFixedValueParameter<DoubleMatrix>)Parameters[ClassificationPenaltiesParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public string TargetVariable {
-      get { return TargetVariableParameter.Value.Value; }
-    }
-
-    private List<double> classValues;
-    public List<double> ClassValues {
-      get {
-        if (classValues == null) {
-          classValues = Dataset.GetEnumeratedVariableValues(TargetVariableParameter.Value.Value).Distinct().ToList();
-          classValues.Sort();
-        }
-        return classValues;
-      }
-    }
-    IEnumerable<double> IClassificationProblemData.ClassValues {
-      get { return ClassValues; }
-    }
-
-    public int Classes {
-      get { return ClassValues.Count; }
-    }
-
-    private List<string> classNames;
-    public List<string> ClassNames {
-      get {
-        if (classNames == null) {
-          classNames = new List<string>();
-          for (int i = 0; i < ClassNamesParameter.Value.Rows; i++)
-            classNames.Add(ClassNamesParameter.Value[i, 0]);
-        }
-        return classNames;
-      }
-    }
-    IEnumerable<string> IClassificationProblemData.ClassNames {
-      get { return ClassNames; }
-    }
-
-    private Dictionary<Tuple<double, double>, double> classificationPenaltiesCache = new Dictionary<Tuple<double, double>, double>();
-    #endregion
-
-
-    [StorableConstructor]
-    protected ClassificationProblemData(bool deserializing) : base(deserializing) { }
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterParameterEvents();
-    }
-
-    protected ClassificationProblemData(ClassificationProblemData original, Cloner cloner)
-      : base(original, cloner) {
-      RegisterParameterEvents();
-    }
-    public override IDeepCloneable Clone(Cloner cloner) { return new ClassificationProblemData(this, cloner); }
-
-    public ClassificationProblemData() : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) { }
-    public ClassificationProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
-      : base(dataset, allowedInputVariables) {
-      var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
-      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.Where(x => x.Value == targetVariable).First()));
-      Parameters.Add(new FixedValueParameter<StringMatrix>(ClassNamesParameterName, "", new StringMatrix()));
-      Parameters.Add(new FixedValueParameter<DoubleMatrix>(ClassificationPenaltiesParameterName, "", new DoubleMatrix()));
-
-      ResetTargetVariableDependentMembers();
-      RegisterParameterEvents();
-    }
-
-    private void ResetTargetVariableDependentMembers() {
-      DergisterParameterEvents();
-
-      classNames = null;
-      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Columns = 1;
-      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Rows = ClassValues.Count;
-      for (int i = 0; i < Classes; i++)
-        ClassNamesParameter.Value[i, 0] = "Class " + ClassValues[i];
-      ClassNamesParameter.Value.ColumnNames = new List<string>() { "ClassNames" };
-      ClassNamesParameter.Value.RowNames = ClassValues.Select(s => "ClassValue: " + s);
-
-      classificationPenaltiesCache.Clear();
-      ((ValueParameter<DoubleMatrix>)ClassificationPenaltiesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
-      ((IStringConvertibleMatrix)ClassificationPenaltiesParameter.Value).Rows = Classes;
-      ((IStringConvertibleMatrix)ClassificationPenaltiesParameter.Value).Columns = Classes;
-      ClassificationPenaltiesParameter.Value.RowNames = ClassNames.Select(name => "Actual " + name);
-      ClassificationPenaltiesParameter.Value.ColumnNames = ClassNames.Select(name => "Estimated " + name);
-      for (int i = 0; i < Classes; i++) {
-        for (int j = 0; j < Classes; j++) {
-          if (i != j) ClassificationPenaltiesParameter.Value[i, j] = 1;
-          else ClassificationPenaltiesParameter.Value[i, j] = 0;
-        }
-      }
-      ((ValueParameter<DoubleMatrix>)ClassificationPenaltiesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = true;
-      RegisterParameterEvents();
-    }
-
-    public string GetClassName(double classValue) {
-      if (!ClassValues.Contains(classValue)) throw new ArgumentException();
-      int index = ClassValues.IndexOf(classValue);
-      return ClassNames[index];
-    }
-    public double GetClassValue(string className) {
-      if (!ClassNames.Contains(className)) throw new ArgumentException();
-      int index = ClassNames.IndexOf(className);
-      return ClassValues[index];
-    }
-    public void SetClassName(double classValue, string className) {
-      if (!classValues.Contains(classValue)) throw new ArgumentException();
-      int index = ClassValues.IndexOf(classValue);
-      ClassNames[index] = className;
-      ClassNamesParameter.Value[index, 0] = className;
-    }
-
-    public double GetClassificationPenalty(string correctClassName, string estimatedClassName) {
-      return GetClassificationPenalty(GetClassValue(correctClassName), GetClassValue(estimatedClassName));
-    }
-    public double GetClassificationPenalty(double correctClassValue, double estimatedClassValue) {
-      var key = Tuple.Create(correctClassValue, estimatedClassValue);
-      if (!classificationPenaltiesCache.ContainsKey(key)) {
-        int correctClassIndex = ClassValues.IndexOf(correctClassValue);
-        int estimatedClassIndex = ClassValues.IndexOf(estimatedClassValue);
-        classificationPenaltiesCache[key] = ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex];
-      }
-      return classificationPenaltiesCache[key];
-    }
-    public void SetClassificationPenalty(string correctClassName, string estimatedClassName, double penalty) {
-      SetClassificationPenalty(GetClassValue(correctClassName), GetClassValue(estimatedClassName), penalty);
-    }
-    public void SetClassificationPenalty(double correctClassValue, double estimatedClassValue, double penalty) {
-      var key = Tuple.Create(correctClassValue, estimatedClassValue);
-      int correctClassIndex = ClassValues.IndexOf(correctClassValue);
-      int estimatedClassIndex = ClassValues.IndexOf(estimatedClassValue);
-
-      ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex] = penalty;
-    }
-
-    #region events
-    private void RegisterParameterEvents() {
-      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
-      ClassNamesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
-      ClassNamesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
-      ClassificationPenaltiesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
-      ClassificationPenaltiesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
-    }
-    private void DergisterParameterEvents() {
-      TargetVariableParameter.ValueChanged -= new EventHandler(TargetVariableParameter_ValueChanged);
-      ClassNamesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
-      ClassNamesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
-      ClassificationPenaltiesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
-      ClassificationPenaltiesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
-    }
-
-    private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
-      classValues = null;
-      ResetTargetVariableDependentMembers();
-      OnChanged();
-    }
-    private void Parameter_ValueChanged(object sender, EventArgs e) {
-      OnChanged();
-    }
-    private void MatrixParameter_ItemChanged(object sender, EventArgs<int, int> e) {
-      OnChanged();
-    }
-    #endregion
-
-    #region Import from file
-    public static ClassificationProblemData ImportFromFile(string fileName) {
-      TableFileParser csvFileParser = new TableFileParser();
-      csvFileParser.Parse(fileName);
-
-      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
-      dataset.Name = Path.GetFileName(fileName);
-
-      ClassificationProblemData problemData = new ClassificationProblemData(dataset, dataset.VariableNames.Skip(1), dataset.VariableNames.First());
-      problemData.Name = "Data imported from " + Path.GetFileName(fileName);
-      return problemData;
-    }
-    #endregion
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationSolution.cs	(revision 5722)
+++ 	(revision )
@@ -1,119 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  /// <summary>
-  /// Abstract base class for classification data analysis solutions
-  /// </summary>
-  [StorableClass]
-  public abstract class ClassificationSolution : DataAnalysisSolution, IClassificationSolution {
-    private const string TrainingAccuracyResultName = "Accuracy (training)";
-    private const string TestAccuracyResultName = "Accuracy (test)";
-
-    public new IClassificationModel Model {
-      get { return (IClassificationModel)base.Model; }
-      protected set { base.Model = value; }
-    }
-
-    public new IClassificationProblemData ProblemData {
-      get { return (IClassificationProblemData)base.ProblemData; }
-      protected set { base.ProblemData = value; }
-    }
-
-    public double TrainingAccuracy {
-      get { return ((DoubleValue)this[TrainingAccuracyResultName].Value).Value; }
-      private set { ((DoubleValue)this[TrainingAccuracyResultName].Value).Value = value; }
-    }
-
-    public double TestAccuracy {
-      get { return ((DoubleValue)this[TestAccuracyResultName].Value).Value; }
-      private set { ((DoubleValue)this[TestAccuracyResultName].Value).Value = value; }
-    }
-
-    [StorableConstructor]
-    protected ClassificationSolution(bool deserializing) : base(deserializing) { }
-    protected ClassificationSolution(ClassificationSolution original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ClassificationSolution(IClassificationModel model, IClassificationProblemData problemData)
-      : base(model, problemData) {
-      Add(new Result(TrainingAccuracyResultName, "Accuracy of the model on the training partition (percentage of correctly classified instances).", new PercentValue()));
-      Add(new Result(TestAccuracyResultName, "Accuracy of the model on the test partition (percentage of correctly classified instances).", new PercentValue()));
-      RecalculateResults();
-    }
-
-    protected override void OnProblemDataChanged(EventArgs e) {
-      base.OnProblemDataChanged(e);
-      RecalculateResults();
-    }
-
-    protected override void OnModelChanged(EventArgs e) {
-      base.OnModelChanged(e);
-      RecalculateResults();
-    }
-
-    private void RecalculateResults() {
-      double[] estimatedTrainingClassValues = EstimatedTrainingClassValues.ToArray(); // cache values
-      IEnumerable<double> originalTrainingClassValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
-      double[] estimatedTestClassValues = EstimatedTestClassValues.ToArray(); // cache values
-      IEnumerable<double> originalTestClassValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
-
-      double trainingAccuracy = OnlineAccuracyEvaluator.Calculate(estimatedTrainingClassValues, originalTrainingClassValues);
-      double testAccuracy = OnlineAccuracyEvaluator.Calculate(estimatedTestClassValues, originalTestClassValues);
-
-      TrainingAccuracy = trainingAccuracy;
-      TestAccuracy = testAccuracy;
-    }
-
-    public virtual IEnumerable<double> EstimatedClassValues {
-      get {
-        return GetEstimatedClassValues(Enumerable.Range(0, ProblemData.Dataset.Rows));
-      }
-    }
-
-    public virtual IEnumerable<double> EstimatedTrainingClassValues {
-      get {
-        return GetEstimatedClassValues(ProblemData.TrainingIndizes);
-      }
-    }
-
-    public virtual IEnumerable<double> EstimatedTestClassValues {
-      get {
-        return GetEstimatedClassValues(ProblemData.TestIndizes);
-      }
-    }
-
-    public virtual IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows) {
-      return Model.GetEstimatedClassValues(ProblemData.Dataset, rows);
-    }
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClusteringProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClusteringProblem.cs	(revision 5722)
+++ 	(revision )
@@ -1,46 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("ClusteringProblem", "A general clustering problem")]
-  [Creatable("Problems")]
-  public class ClusteringProblem : DataAnalysisProblem<IClusteringProblemData>, IClusteringProblem {
-    [StorableConstructor]
-    protected ClusteringProblem(bool deserializing) : base(deserializing) { }
-    protected ClusteringProblem(ClusteringProblem original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) { return new ClusteringProblem(this, cloner); }
-
-    public ClusteringProblem()
-      : base() {
-      ProblemData = new ClusteringProblemData();
-    }
-
-    public override void ImportProblemDataFromFile(string fileName) {
-      ClusteringProblemData problemData = ClusteringProblemData.ImportFromFile(fileName);
-      ProblemData = problemData;
-    }
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClusteringProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClusteringProblemData.cs	(revision 5722)
+++ 	(revision )
@@ -1,111 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("ClusteringProblemData", "Represents an item containing all data defining a clustering problem.")]
-  public sealed class ClusteringProblemData : DataAnalysisProblemData, IClusteringProblemData {
-
-    #region default data
-    private static double[,] kozaF1 = new double[,] {
-          {2.017885919,	-1.449165046},
-          {1.30060506,	-1.344523885},
-          {1.147134798,	-1.317989331},
-          {0.877182504,	-1.266142284},
-          {0.852562452,	-1.261020794},
-          {0.431095788,	-1.158793317},
-          {0.112586002,	-1.050908405},
-          {0.04594507,	-1.021989402},
-          {0.042572879,	-1.020438113},
-          {-0.074027291,	-0.959859562},
-          {-0.109178553,	-0.938094706},
-          {-0.259721109,	-0.803635355},
-          {-0.272991057,	-0.387519561},
-          {-0.161978191,	-0.193611001},
-          {-0.102489983,	-0.114215349},
-          {-0.01469968,	-0.014918985},
-          {-0.008863365,	-0.008942626},
-          {0.026751057,	0.026054094},
-          {0.166922436,	0.14309643},
-          {0.176953808,	0.1504144},
-          {0.190233418,	0.159916534},
-          {0.199800708,	0.166635331},
-          {0.261502822,	0.207600348},
-          {0.30182879,	0.232370249},
-          {0.83763905,	0.468046718}
-    };
-    private static Dataset defaultDataset;
-    private static IEnumerable<string> defaultAllowedInputVariables;
-
-    static ClusteringProblemData() {
-      defaultDataset = new Dataset(new string[] { "y", "x" }, kozaF1);
-      defaultDataset.Name = "Fourth-order Polynomial Function Benchmark Dataset";
-      defaultDataset.Description = "f(x) = x^4 + x^3 + x^2 + x^1";
-      defaultAllowedInputVariables = new List<string>() { "x", "y" };
-    }
-    #endregion
-
-    [StorableConstructor]
-    private ClusteringProblemData(bool deserializing) : base(deserializing) { }
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-    }
-
-
-    private ClusteringProblemData(ClusteringProblemData original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public override IDeepCloneable Clone(Cloner cloner) { return new ClusteringProblemData(this, cloner); }
-
-    public ClusteringProblemData()
-      : this(defaultDataset, defaultAllowedInputVariables) {
-    }
-
-    public ClusteringProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables)
-      : base(dataset, allowedInputVariables) {
-    }
-
-
-    #region Import from file
-    public static ClusteringProblemData ImportFromFile(string fileName) {
-      TableFileParser csvFileParser = new TableFileParser();
-      csvFileParser.Parse(fileName);
-
-      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
-      dataset.Name = Path.GetFileName(fileName);
-
-      ClusteringProblemData problemData = new ClusteringProblemData(dataset, dataset.VariableNames);
-      problemData.Name = "Data imported from " + Path.GetFileName(fileName);
-      return problemData;
-    }
-    #endregion
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClusteringSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClusteringSolution.cs	(revision 5722)
+++ 	(revision )
@@ -1,84 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  /// <summary>
-  /// Abstract base class for clustering data analysis solutions
-  /// </summary>
-  [StorableClass]
-  public abstract class ClusteringSolution : DataAnalysisSolution, IClusteringSolution {
-
-    [StorableConstructor]
-    protected ClusteringSolution(bool deserializing) : base(deserializing) { }
-    protected ClusteringSolution(ClusteringSolution original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ClusteringSolution(IClusteringModel model, IClusteringProblemData problemData)
-      : base(model, problemData) {
-    }
-
-    #region IClusteringSolution Members
-
-    public new IClusteringModel Model {
-      get { return (IClusteringModel)base.Model; }
-      set { base.Model = value; }
-    }
-
-    public new IClusteringProblemData ProblemData {
-      get { return (IClusteringProblemData)base.ProblemData; }
-      set { base.ProblemData = value; }
-    }
-
-    public virtual IEnumerable<int> ClusterValues {
-      get {
-        return GetClusterValues(Enumerable.Range(0, ProblemData.Dataset.Rows));
-      }
-    }
-
-    public virtual IEnumerable<int> TrainingClusterValues {
-      get {
-        return GetClusterValues(ProblemData.TrainingIndizes);
-      }
-    }
-
-    public virtual IEnumerable<int> TestClusterValues {
-      get {
-        return GetClusterValues(ProblemData.TestIndizes);
-      }
-    }
-
-    public virtual IEnumerable<int> GetClusterValues(IEnumerable<int> rows) {
-      return Model.GetClusterValues(ProblemData.Dataset, rows);
-    }
-    #endregion
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblem.cs	(revision 5722)
+++ 	(revision )
@@ -1,79 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  public abstract class DataAnalysisProblem<T> : Problem,
-    IDataAnalysisProblem<T>
-    where T : class, IDataAnalysisProblemData {
-    private const string ProblemDataParameterName = "ProblemData";
-    private const string ProblemDataParameterDescription = "The data set, target variable and input variables of the data analysis problem.";
-    #region parameter properties
-    IParameter IDataAnalysisProblem.ProblemDataParameter {
-      get { return ProblemDataParameter; }
-    }
-    public IValueParameter<T> ProblemDataParameter {
-      get { return (IValueParameter<T>)Parameters[ProblemDataParameterName]; }
-    }
-    #endregion
-    #region properties
-    IDataAnalysisProblemData IDataAnalysisProblem.ProblemData {
-      get { return ProblemData; }
-    }
-    public T ProblemData {
-      get { return ProblemDataParameter.Value; }
-      protected set { ProblemDataParameter.Value = value; }
-    }
-    #endregion
-    protected DataAnalysisProblem(DataAnalysisProblem<T> original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    [StorableConstructor]
-    protected DataAnalysisProblem(bool deserializing) : base(deserializing) { }
-    public DataAnalysisProblem()
-      : base() {
-      Parameters.Add(new ValueParameter<T>(ProblemDataParameterName, ProblemDataParameterDescription));
-    }
-
-    private void RegisterEventHandlers() {
-      ProblemDataParameter.Value.Changed += new EventHandler(ProblemDataParameter_ValueChanged);
-    }
-    private void ProblemDataParameter_ValueChanged(object sender, EventArgs e) {
-      OnProblemDataChanged();
-      OnReset();
-    }
-
-    public event EventHandler ProblemDataChanged;
-    protected virtual void OnProblemDataChanged() {
-      var handler = ProblemDataChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-
-    public abstract void ImportProblemDataFromFile(string fileName);
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblemData.cs	(revision 5722)
+++ 	(revision )
@@ -1,155 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Collections;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  public abstract class DataAnalysisProblemData : ParameterizedNamedItem, IDataAnalysisProblemData {
-    private const string DatasetParameterName = "Dataset";
-    private const string InputVariablesParameterName = "InputVariables";
-    private const string TrainingPartitionStartParameterName = "TrainingPartitionStart";
-    private const string TrainingPartitionEndParameterName = "TrainingPartitionEnd";
-    private const string TestPartitionStartParameterName = "TestPartitionStart";
-    private const string TestPartitionEndParameterName = "TestPartitionEnd";
-
-    #region parameter properites
-    public IFixedValueParameter<Dataset> DatasetParameter {
-      get { return (IFixedValueParameter<Dataset>)Parameters[DatasetParameterName]; }
-    }
-    public IFixedValueParameter<ICheckedItemList<StringValue>> InputVariablesParameter {
-      get { return (IFixedValueParameter<ICheckedItemList<StringValue>>)Parameters[InputVariablesParameterName]; }
-    }
-    public IFixedValueParameter<IntValue> TrainingPartitionStartParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters[TrainingPartitionStartParameterName]; }
-    }
-    public IFixedValueParameter<IntValue> TrainingPartitionEndParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters[TrainingPartitionEndParameterName]; }
-    }
-    public IFixedValueParameter<IntValue> TestPartitionStartParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters[TestPartitionStartParameterName]; }
-    }
-    public IFixedValueParameter<IntValue> TestPartitionEndParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters[TestPartitionEndParameterName]; }
-    }
-    #endregion
-
-    #region propeties
-    public Dataset Dataset {
-      get { return DatasetParameter.Value; }
-    }
-    public ICheckedItemList<StringValue> InputVariables {
-      get { return InputVariablesParameter.Value; }
-    }
-    public IEnumerable<string> AllowedInputVariables {
-      get { return InputVariables.CheckedItems.Select(x => x.Value.Value); }
-    }
-
-    public IntValue TrainingPartitionStart {
-      get { return TrainingPartitionStartParameter.Value; }
-    }
-    public IntValue TrainingPartitionEnd {
-      get { return TrainingPartitionEndParameter.Value; }
-    }
-    public IntValue TestPartitionStart {
-      get { return TestPartitionStartParameter.Value; }
-    }
-    public IntValue TestPartitionEnd {
-      get { return TestPartitionEndParameter.Value; }
-    }
-
-    public IEnumerable<int> TrainingIndizes {
-      get {
-        return Enumerable.Range(TrainingPartitionStart.Value, TrainingPartitionEnd.Value - TrainingPartitionStart.Value)
-                         .Where(i => i >= 0 && i < Dataset.Rows && (i < TestPartitionStart.Value || TestPartitionEnd.Value <= i));
-      }
-    }
-    public IEnumerable<int> TestIndizes {
-      get {
-        return Enumerable.Range(TestPartitionStart.Value, TestPartitionEnd.Value - TestPartitionStart.Value)
-           .Where(i => i >= 0 && i < Dataset.Rows);
-      }
-    }
-    #endregion
-
-    protected DataAnalysisProblemData(DataAnalysisProblemData original, Cloner cloner) : base(original, cloner) { }
-    [StorableConstructor]
-    protected DataAnalysisProblemData(bool deserializing) : base(deserializing) { }
-
-    protected DataAnalysisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables) {
-      if (dataset == null) throw new ArgumentNullException("The dataset must not be null.");
-      if (allowedInputVariables == null) throw new ArgumentNullException("The allowedInputVariables must not be null.");
-
-      if (allowedInputVariables.Except(dataset.VariableNames).Any())
-        throw new ArgumentException("All allowed input variables must be present in the dataset.");
-
-      var inputVariables = new CheckedItemList<StringValue>(dataset.VariableNames.Select(x => new StringValue(x)));
-      foreach (StringValue x in inputVariables)
-        inputVariables.SetItemCheckedState(x, allowedInputVariables.Contains(x.Value));
-
-      int trainingPartitionStart = 0;
-      int trainingPartitionEnd = dataset.Rows / 2;
-      int testPartitionStart = dataset.Rows / 2;
-      int testPartitionEnd = dataset.Rows;
-
-      Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", dataset));
-      Parameters.Add(new FixedValueParameter<ICheckedItemList<StringValue>>(InputVariablesParameterName, "", inputVariables.AsReadOnly()));
-      Parameters.Add(new FixedValueParameter<IntValue>(TrainingPartitionStartParameterName, "", new IntValue(trainingPartitionStart)));
-      Parameters.Add(new FixedValueParameter<IntValue>(TrainingPartitionEndParameterName, "", new IntValue(trainingPartitionEnd)));
-      Parameters.Add(new FixedValueParameter<IntValue>(TestPartitionStartParameterName, "", new IntValue(testPartitionStart)));
-      Parameters.Add(new FixedValueParameter<IntValue>(TestPartitionEndParameterName, "", new IntValue(testPartitionEnd)));
-
-      ((ValueParameter<Dataset>)DatasetParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
-      RegisterEventHandlers();
-    }
-
-    private void RegisterEventHandlers() {
-      DatasetParameter.ValueChanged += new EventHandler(Parameter_ValueChanged);
-      InputVariables.CheckedItemsChanged += new CollectionItemsChangedEventHandler<IndexedItem<StringValue>>(InputVariables_CheckedItemsChanged);
-      TrainingPartitionStart.ValueChanged += new EventHandler(Parameter_ValueChanged);
-      TrainingPartitionEnd.ValueChanged += new EventHandler(Parameter_ValueChanged);
-      TestPartitionStart.ValueChanged += new EventHandler(Parameter_ValueChanged);
-      TestPartitionEnd.ValueChanged += new EventHandler(Parameter_ValueChanged);
-    }
-
-    private void InputVariables_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<StringValue>> e) {
-      OnChanged();
-    }
-
-    private void Parameter_ValueChanged(object sender, EventArgs e) {
-      OnChanged();
-    }
-
-    public event EventHandler Changed;
-    protected virtual void OnChanged() {
-      var listeners = Changed;
-      if (listeners != null) listeners(this, EventArgs.Empty);
-    }
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisSolution.cs	(revision 5722)
+++ 	(revision )
@@ -1,168 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
-using System.Drawing;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  /// <summary>
-  /// Abstract base class for data analysis solutions
-  /// </summary>
-  [StorableClass]
-  public abstract class DataAnalysisSolution : ResultCollection, IDataAnalysisSolution {
-    private const string ModelResultName = "Model";
-    private const string ProblemDataResultName = "ProblemData";
-
-    public override Image ItemImage {
-      get { return HeuristicLab.Common.Resources.VSImageLibrary.Function; }
-    }
-
-    #region properties
-    public IDataAnalysisModel Model {
-      get { return (IDataAnalysisModel)this[ModelResultName].Value; }
-      protected set {
-        if (this[ModelResultName].Value != value) {
-          if (value != null) {
-            this[ModelResultName].Value = value;
-            OnModelChanged(EventArgs.Empty);
-          }
-        }
-      }
-    }
-
-    public IDataAnalysisProblemData ProblemData {
-      get { return (IDataAnalysisProblemData)this[ProblemDataResultName].Value; }
-      protected set {
-        if (this[ProblemDataResultName].Value != value) {
-          if (value != null) {
-            ProblemData.Changed -= new EventHandler(ProblemData_Changed);
-            this[ProblemDataResultName].Value = value;
-            ProblemData.Changed += new EventHandler(ProblemData_Changed);
-            OnProblemDataChanged(EventArgs.Empty);
-          }
-        }
-      }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected DataAnalysisSolution(bool deserializing) : base(deserializing) { }
-    protected DataAnalysisSolution(DataAnalysisSolution original, Cloner cloner)
-      : base(original, cloner) {
-      name = original.Name;
-      description = original.Description;
-    }
-    public DataAnalysisSolution(IDataAnalysisModel model, IDataAnalysisProblemData problemData)
-      : base() {
-      name = ItemName;
-      description = ItemDescription;
-      Add(new Result(ModelResultName, "The symbolic data analysis model.", model));
-      Add(new Result(ProblemDataResultName, "The symbolic data analysis problem data.", problemData));
-
-      problemData.Changed += new EventHandler(ProblemData_Changed);
-    }
-
-    private void ProblemData_Changed(object sender, EventArgs e) {
-      OnProblemDataChanged(e);
-    }
-
-    public event EventHandler ModelChanged;
-    protected virtual void OnModelChanged(EventArgs e) {
-      var listeners = ModelChanged;
-      if (listeners != null) listeners(this, e);
-    }
-
-    public event EventHandler ProblemDataChanged;
-    protected virtual void OnProblemDataChanged(EventArgs e) {
-      var listeners = ProblemDataChanged;
-      if (listeners != null) listeners(this, e);
-    }
-
-    #region INamedItem Members
-    [Storable]
-    protected string name;
-    public string Name {
-      get { return name; }
-      set {
-        if (!CanChangeName) throw new NotSupportedException("Name cannot be changed.");
-        if (!(name.Equals(value) || (value == null) && (name == string.Empty))) {
-          CancelEventArgs<string> e = value == null ? new CancelEventArgs<string>(string.Empty) : new CancelEventArgs<string>(value);
-          OnNameChanging(e);
-          if (!e.Cancel) {
-            name = value == null ? string.Empty : value;
-            OnNameChanged();
-          }
-        }
-      }
-    }
-    public virtual bool CanChangeName {
-      get { return true; }
-    }
-    [Storable]
-    protected string description;
-    public string Description {
-      get { return description; }
-      set {
-        if (!CanChangeDescription) throw new NotSupportedException("Description cannot be changed.");
-        if (!(description.Equals(value) || (value == null) && (description == string.Empty))) {
-          description = value == null ? string.Empty : value;
-          OnDescriptionChanged();
-        }
-      }
-    }
-    public virtual bool CanChangeDescription {
-      get { return true; }
-    }
-
-    public override string ToString() {
-      return Name;
-    }
-
-    public event EventHandler<CancelEventArgs<string>> NameChanging;
-    protected virtual void OnNameChanging(CancelEventArgs<string> e) {
-      var handler = NameChanging;
-      if (handler != null) handler(this, e);
-    }
-
-    public event EventHandler NameChanged;
-    protected virtual void OnNameChanged() {
-      var handler = NameChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-      OnToStringChanged();
-    }
-
-    public event EventHandler DescriptionChanged;
-    protected virtual void OnDescriptionChanged() {
-      var handler = DescriptionChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-    #endregion
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DiscriminantFunctionClassificationModel.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DiscriminantFunctionClassificationModel.cs	(revision 5722)
+++ 	(revision )
@@ -1,109 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  /// <summary>
-  /// Represents discriminant function classification data analysis models.
-  /// </summary>
-  [StorableClass]
-  [Item("DiscriminantFunctionClassificationModel", "Represents a classification model that uses a discriminant function and classification thresholds.")]
-  public class DiscriminantFunctionClassificationModel : NamedItem, IDiscriminantFunctionClassificationModel {
-    [Storable]
-    private IRegressionModel model;
-    [Storable]
-    private double[] classValues;
-    // class values are not necessarily sorted in ascending order
-    public IEnumerable<double> ClassValues {
-      get { return (double[])classValues.Clone(); }
-      set {
-        if (value == null) throw new ArgumentException();
-        double[] newValue = value.ToArray();
-        if (newValue.Length != classValues.Length) throw new ArgumentException();
-        classValues = newValue;
-      }
-    }
-    [Storable]
-    private double[] thresholds;
-    public IEnumerable<double> Thresholds {
-      get { return (IEnumerable<double>)thresholds.Clone(); }
-      set {
-        thresholds = value.ToArray();
-        OnThresholdsChanged(EventArgs.Empty);
-      }
-    }
-
-
-    [StorableConstructor]
-    protected DiscriminantFunctionClassificationModel(bool deserializing) : base(deserializing) { }
-    protected DiscriminantFunctionClassificationModel(DiscriminantFunctionClassificationModel original, Cloner cloner)
-      : base(original, cloner) {
-      model = cloner.Clone(original.model);
-      classValues = (double[])original.classValues.Clone();
-      thresholds = (double[])original.thresholds.Clone();
-    }
-    public DiscriminantFunctionClassificationModel(IRegressionModel model, IEnumerable<double> classValues, IEnumerable<double> thresholds)
-      : base() {
-      this.name = ItemName;
-      this.description = ItemDescription;
-      this.model = model;
-      this.classValues = classValues.ToArray();
-      this.thresholds = thresholds.ToArray();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new DiscriminantFunctionClassificationModel(this, cloner);
-    }
-
-    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
-      return model.GetEstimatedValues(dataset, rows);
-    }
-
-    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
-      foreach (var x in GetEstimatedValues(dataset, rows)) {
-        int classIndex = 0;
-        // find first threshold value which is larger than x => class index = threshold index + 1
-        for (int i = 0; i < thresholds.Length; i++) {
-          if (x > thresholds[i]) classIndex++;
-          else break;
-        }
-        yield return classValues.ElementAt(classIndex);
-      }
-    }
-    #region events
-    public event EventHandler ThresholdsChanged;
-    protected virtual void OnThresholdsChanged(EventArgs e) {
-      var listener = ThresholdsChanged;
-      if (listener != null) listener(this, e);
-    }
-    #endregion
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DiscriminantFunctionClassificationSolution.cs	(revision 5722)
+++ 	(revision )
@@ -1,73 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  /// <summary>
-  /// Represents a classification solution that uses a discriminant function and classification thresholds.
-  /// </summary>
-  [StorableClass]
-  [Item("DiscriminantFunctionClassificationSolution", "Represents a classification solution that uses a discriminant function and classification thresholds.")]
-  public class DiscriminantFunctionClassificationSolution : ClassificationSolution, IDiscriminantFunctionClassificationSolution {
-    public new IDiscriminantFunctionClassificationModel Model {
-      get { return (IDiscriminantFunctionClassificationModel)base.Model; }
-      protected set { base.Model = value; }
-    }
-
-    [StorableConstructor]
-    protected DiscriminantFunctionClassificationSolution(bool deserializing) : base(deserializing) { }
-    protected DiscriminantFunctionClassificationSolution(DiscriminantFunctionClassificationSolution original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public DiscriminantFunctionClassificationSolution(IRegressionModel model, IClassificationProblemData problemData, IEnumerable<double> classValues, IEnumerable<double> thresholds)
-      : this(new DiscriminantFunctionClassificationModel(model, classValues, thresholds), problemData) {
-    }
-    public DiscriminantFunctionClassificationSolution(IDiscriminantFunctionClassificationModel model, IClassificationProblemData problemData)
-      : base(model, problemData) {
-    }
-
-    public IEnumerable<double> EstimatedValues {
-      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
-    }
-
-    public IEnumerable<double> EstimatedTrainingValues {
-      get { return GetEstimatedValues(ProblemData.TrainingIndizes); }
-    }
-
-    public IEnumerable<double> EstimatedTestValues {
-      get { return GetEstimatedValues(ProblemData.TestIndizes); }
-    }
-
-    public IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
-      return Model.GetEstimatedValues(ProblemData.Dataset, rows);
-    }
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 5722)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 5730)
@@ -108,19 +108,19 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="ClassificationProblemData.cs" />
-    <Compile Include="ClassificationProblem.cs" />
-    <Compile Include="ClassificationSolution.cs" />
+    <Compile Include="Classification\ClassificationProblemData.cs" />
+    <Compile Include="Classification\ClassificationProblem.cs" />
+    <Compile Include="Classification\ClassificationSolution.cs" />
     <Compile Include="ClusteringProblem.cs" />
     <Compile Include="ClusteringProblemData.cs" />
     <Compile Include="ClusteringSolution.cs" />
-    <Compile Include="ClassificationEnsembleModel.cs" />
+    <Compile Include="Classification\ClassificationEnsembleModel.cs" />
     <Compile Include="Interfaces\Classification\IDiscriminantFunctionThresholdCalculator.cs" />
     <Compile Include="Interfaces\Classification\IClassificationEnsembleModel.cs" />
     <Compile Include="Interfaces\Regression\IRegressionEnsembleModel.cs" />
     <Compile Include="OnlineEvaluators\OnlineLinearScalingParameterCalculator.cs" />
-    <Compile Include="RegressionEnsembleModel.cs" />
-    <Compile Include="DiscriminantFunctionClassificationModel.cs" />
-    <Compile Include="DiscriminantFunctionClassificationSolution.cs" />
-    <Compile Include="DataAnalysisSolution.cs" />
+    <Compile Include="Regression\RegressionEnsembleModel.cs" />
+    <Compile Include="Classification\DiscriminantFunctionClassificationModel.cs" />
+    <Compile Include="Classification\DiscriminantFunctionClassificationSolution.cs" />
+    <Compile Include="Base\DataAnalysisSolution.cs" />
     <Compile Include="Interfaces\Classification\IDiscriminantFunctionClassificationModel.cs" />
     <Compile Include="Interfaces\Classification\IDiscriminantFunctionClassificationSolution.cs" />
@@ -130,8 +130,8 @@
     <Compile Include="Interfaces\Clustering\IClusteringSolution.cs" />
     <Compile Include="OnlineEvaluators\OnlineAccuracyEvaluator.cs" />
-    <Compile Include="RegressionProblemData.cs" />
-    <Compile Include="DataAnalysisProblemData.cs" />
-    <Compile Include="RegressionProblem.cs" />
-    <Compile Include="DataAnalysisProblem.cs" />
+    <Compile Include="Regression\RegressionProblemData.cs" />
+    <Compile Include="Base\DataAnalysisProblemData.cs" />
+    <Compile Include="Regression\RegressionProblem.cs" />
+    <Compile Include="Base\DataAnalysisProblem.cs" />
     <Compile Include="Dataset.cs" />
     <Compile Include="Interfaces\Classification\IClassificationModel.cs" />
@@ -152,9 +152,9 @@
     <Compile Include="OnlineEvaluators\OnlineNormalizedMeanSquaredErrorEvaluator.cs" />
     <Compile Include="OnlineEvaluators\OnlinePearsonsRSquaredEvaluator.cs" />
-    <Compile Include="RegressionSolution.cs" />
+    <Compile Include="Regression\RegressionSolution.cs" />
     <Compile Include="TableFileParser.cs" />
-    <Compile Include="ThresholdCalculators\AccuracyMaximizationThresholdCalculator.cs" />
-    <Compile Include="ThresholdCalculators\NormalDistributionCutPointsThresholdCalculator.cs" />
-    <Compile Include="ThresholdCalculators\ThresholdCalculator.cs" />
+    <Compile Include="Classification\ThresholdCalculators\AccuracyMaximizationThresholdCalculator.cs" />
+    <Compile Include="Classification\ThresholdCalculators\NormalDistributionCutPointsThresholdCalculator.cs" />
+    <Compile Include="Classification\ThresholdCalculators\ThresholdCalculator.cs" />
     <None Include="HeuristicLab.snk" />
     <None Include="HeuristicLabProblemsDataAnalysisPlugin.cs.frame" />
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 5730)
@@ -0,0 +1,94 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents classification solutions that contain an ensemble of multiple classification models
+  /// </summary>
+  [StorableClass]
+  [Item("ClassificationEnsembleModel", "A classification model that contains an ensemble of multiple classification models")]
+  public class ClassificationEnsembleModel : NamedItem, IClassificationEnsembleModel {
+
+    [Storable]
+    private List<IClassificationModel> models;
+    public IEnumerable<IClassificationModel> Models {
+      get { return new List<IClassificationModel>(models); }
+    }
+    [StorableConstructor]
+    protected ClassificationEnsembleModel(bool deserializing) : base(deserializing) { }
+    protected ClassificationEnsembleModel(ClassificationEnsembleModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.models = original.Models.Select(m => cloner.Clone(m)).ToList();
+    }
+    public ClassificationEnsembleModel(IEnumerable<IClassificationModel> models)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.models = new List<IClassificationModel>(models);      
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClassificationEnsembleModel(this, cloner);
+    }
+
+    #region IClassificationEnsembleModel Members
+
+    public IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      var estimatedValuesEnumerators = (from model in models
+                                        select model.GetEstimatedClassValues(dataset, rows).GetEnumerator())
+                                       .ToList();
+
+      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
+        yield return from enumerator in estimatedValuesEnumerators
+                     select enumerator.Current;
+      }
+    }
+
+    #endregion
+
+    #region IClassificationModel Members
+
+    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      foreach (var estimatedValuesVector in GetEstimatedClassValueVectors(dataset, rows)) {
+        // return the class which is most often occuring
+        yield return
+          estimatedValuesVector
+          .GroupBy(x => x)
+          .OrderBy(g => -g.Count())
+          .Select(g => g.Key)
+          .First();
+      }
+    }
+
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs	(revision 5730)
@@ -0,0 +1,46 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("ClassificationProblem", "A general classification problem.")]
+  [Creatable("Problems")]
+  public class ClassificationProblem : DataAnalysisProblem<IClassificationProblemData>, IClassificationProblem {
+    [StorableConstructor]
+    protected ClassificationProblem(bool deserializing) : base(deserializing) { }
+    protected ClassificationProblem(ClassificationProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ClassificationProblem(this, cloner); }
+
+    public ClassificationProblem()
+      : base() {
+      ProblemData = new ClassificationProblemData();
+    }
+
+    public override void ImportProblemDataFromFile(string fileName) {
+      ClassificationProblemData problemData = ClassificationProblemData.ImportFromFile(fileName);
+      ProblemData = problemData;
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 5730)
@@ -0,0 +1,373 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("ClassificationProblemData", "Represents an item containing all data defining a classification problem.")]
+  public class ClassificationProblemData : DataAnalysisProblemData, IClassificationProblemData {
+    private const string TargetVariableParameterName = "TargetVariable";
+    private const string ClassNamesParameterName = "ClassNames";
+    private const string ClassificationPenaltiesParameterName = "ClassificationPenalties";
+
+    #region default data
+    private static string[] defaultVariableNames = new string[] { "sample", "clump thickness", "cell size", "cell shape", "marginal adhesion", "epithelial cell size", "bare nuclei", "chromatin", "nucleoli", "mitoses", "class" };
+    private static double[,] defaultData = new double[,]{
+     {1000025,5,1,1,1,2,1,3,1,1,2      },
+     {1002945,5,4,4,5,7,10,3,2,1,2     },
+     {1015425,3,1,1,1,2,2,3,1,1,2      },
+     {1016277,6,8,8,1,3,4,3,7,1,2      },
+     {1017023,4,1,1,3,2,1,3,1,1,2      },
+     {1017122,8,10,10,8,7,10,9,7,1,4   },
+     {1018099,1,1,1,1,2,10,3,1,1,2     },
+     {1018561,2,1,2,1,2,1,3,1,1,2      },
+     {1033078,2,1,1,1,2,1,1,1,5,2      },
+     {1033078,4,2,1,1,2,1,2,1,1,2      },
+     {1035283,1,1,1,1,1,1,3,1,1,2      },
+     {1036172,2,1,1,1,2,1,2,1,1,2      },
+     {1041801,5,3,3,3,2,3,4,4,1,4      },
+     {1043999,1,1,1,1,2,3,3,1,1,2      },
+     {1044572,8,7,5,10,7,9,5,5,4,4     },
+     {1047630,7,4,6,4,6,1,4,3,1,4      },
+     {1048672,4,1,1,1,2,1,2,1,1,2      },
+     {1049815,4,1,1,1,2,1,3,1,1,2      },
+     {1050670,10,7,7,6,4,10,4,1,2,4    },
+     {1050718,6,1,1,1,2,1,3,1,1,2      },
+     {1054590,7,3,2,10,5,10,5,4,4,4    },
+     {1054593,10,5,5,3,6,7,7,10,1,4    },
+     {1056784,3,1,1,1,2,1,2,1,1,2      },
+     {1057013,8,4,5,1,2,2,7,3,1,4      },
+     {1059552,1,1,1,1,2,1,3,1,1,2      },
+     {1065726,5,2,3,4,2,7,3,6,1,4      },
+     {1066373,3,2,1,1,1,1,2,1,1,2      },
+     {1066979,5,1,1,1,2,1,2,1,1,2      },
+     {1067444,2,1,1,1,2,1,2,1,1,2      },
+     {1070935,1,1,3,1,2,1,1,1,1,2      },
+     {1070935,3,1,1,1,1,1,2,1,1,2      },
+     {1071760,2,1,1,1,2,1,3,1,1,2      },
+     {1072179,10,7,7,3,8,5,7,4,3,4     },
+     {1074610,2,1,1,2,2,1,3,1,1,2      },
+     {1075123,3,1,2,1,2,1,2,1,1,2      },
+     {1079304,2,1,1,1,2,1,2,1,1,2      },
+     {1080185,10,10,10,8,6,1,8,9,1,4   },
+     {1081791,6,2,1,1,1,1,7,1,1,2      },
+     {1084584,5,4,4,9,2,10,5,6,1,4     },
+     {1091262,2,5,3,3,6,7,7,5,1,4      },
+     {1096800,6,6,6,9,6,4,7,8,1,2      },
+     {1099510,10,4,3,1,3,3,6,5,2,4     },
+     {1100524,6,10,10,2,8,10,7,3,3,4   },
+     {1102573,5,6,5,6,10,1,3,1,1,4     },
+     {1103608,10,10,10,4,8,1,8,10,1,4  },
+     {1103722,1,1,1,1,2,1,2,1,2,2      },
+     {1105257,3,7,7,4,4,9,4,8,1,4      },
+     {1105524,1,1,1,1,2,1,2,1,1,2      },
+     {1106095,4,1,1,3,2,1,3,1,1,2      },
+     {1106829,7,8,7,2,4,8,3,8,2,4      },
+     {1108370,9,5,8,1,2,3,2,1,5,4      },
+     {1108449,5,3,3,4,2,4,3,4,1,4      },
+     {1110102,10,3,6,2,3,5,4,10,2,4    },
+     {1110503,5,5,5,8,10,8,7,3,7,4     },
+     {1110524,10,5,5,6,8,8,7,1,1,4     },
+     {1111249,10,6,6,3,4,5,3,6,1,4     },
+     {1112209,8,10,10,1,3,6,3,9,1,4    },
+     {1113038,8,2,4,1,5,1,5,4,4,4      },
+     {1113483,5,2,3,1,6,10,5,1,1,4     },
+     {1113906,9,5,5,2,2,2,5,1,1,4      },
+     {1115282,5,3,5,5,3,3,4,10,1,4     },
+     {1115293,1,1,1,1,2,2,2,1,1,2      },
+     {1116116,9,10,10,1,10,8,3,3,1,4   },
+     {1116132,6,3,4,1,5,2,3,9,1,4      },
+     {1116192,1,1,1,1,2,1,2,1,1,2      },
+     {1116998,10,4,2,1,3,2,4,3,10,4    },
+     {1117152,4,1,1,1,2,1,3,1,1,2      },
+     {1118039,5,3,4,1,8,10,4,9,1,4     },
+     {1120559,8,3,8,3,4,9,8,9,8,4      },
+     {1121732,1,1,1,1,2,1,3,2,1,2      },
+     {1121919,5,1,3,1,2,1,2,1,1,2      },
+     {1123061,6,10,2,8,10,2,7,8,10,4   },
+     {1124651,1,3,3,2,2,1,7,2,1,2      },
+     {1125035,9,4,5,10,6,10,4,8,1,4    },
+     {1126417,10,6,4,1,3,4,3,2,3,4     },
+     {1131294,1,1,2,1,2,2,4,2,1,2      },
+     {1132347,1,1,4,1,2,1,2,1,1,2      },
+     {1133041,5,3,1,2,2,1,2,1,1,2      },
+     {1133136,3,1,1,1,2,3,3,1,1,2      },
+     {1136142,2,1,1,1,3,1,2,1,1,2      },
+     {1137156,2,2,2,1,1,1,7,1,1,2      },
+     {1143978,4,1,1,2,2,1,2,1,1,2      },
+     {1143978,5,2,1,1,2,1,3,1,1,2      },
+     {1147044,3,1,1,1,2,2,7,1,1,2      },
+     {1147699,3,5,7,8,8,9,7,10,7,4     },
+     {1147748,5,10,6,1,10,4,4,10,10,4  },
+     {1148278,3,3,6,4,5,8,4,4,1,4      },
+     {1148873,3,6,6,6,5,10,6,8,3,4     },
+     {1152331,4,1,1,1,2,1,3,1,1,2      },
+     {1155546,2,1,1,2,3,1,2,1,1,2      },
+     {1156272,1,1,1,1,2,1,3,1,1,2      },
+     {1156948,3,1,1,2,2,1,1,1,1,2      },
+     {1157734,4,1,1,1,2,1,3,1,1,2      },
+     {1158247,1,1,1,1,2,1,2,1,1,2      },
+     {1160476,2,1,1,1,2,1,3,1,1,2      },
+     {1164066,1,1,1,1,2,1,3,1,1,2      },
+     {1165297,2,1,1,2,2,1,1,1,1,2      },
+     {1165790,5,1,1,1,2,1,3,1,1,2      },
+     {1165926,9,6,9,2,10,6,2,9,10,4    },
+     {1166630,7,5,6,10,5,10,7,9,4,4    },
+     {1166654,10,3,5,1,10,5,3,10,2,4   },
+     {1167439,2,3,4,4,2,5,2,5,1,4      },
+     {1167471,4,1,2,1,2,1,3,1,1,2      },
+     {1168359,8,2,3,1,6,3,7,1,1,4      },
+     {1168736,10,10,10,10,10,1,8,8,8,4 },
+     {1169049,7,3,4,4,3,3,3,2,7,4      },
+     {1170419,10,10,10,8,2,10,4,1,1,4  },
+     {1170420,1,6,8,10,8,10,5,7,1,4    },
+     {1171710,1,1,1,1,2,1,2,3,1,2      },
+     {1171710,6,5,4,4,3,9,7,8,3,4      },
+     {1171795,1,3,1,2,2,2,5,3,2,2      },
+     {1171845,8,6,4,3,5,9,3,1,1,4      },
+     {1172152,10,3,3,10,2,10,7,3,3,4   },
+     {1173216,10,10,10,3,10,8,8,1,1,4  },
+     {1173235,3,3,2,1,2,3,3,1,1,2      },
+     {1173347,1,1,1,1,2,5,1,1,1,2      },
+     {1173347,8,3,3,1,2,2,3,2,1,2      },
+     {1173509,4,5,5,10,4,10,7,5,8,4    },
+     {1173514,1,1,1,1,4,3,1,1,1,2      },
+     {1173681,3,2,1,1,2,2,3,1,1,2      },
+     {1174057,1,1,2,2,2,1,3,1,1,2      },
+     {1174057,4,2,1,1,2,2,3,1,1,2      },
+     {1174131,10,10,10,2,10,10,5,3,3,4 },
+     {1174428,5,3,5,1,8,10,5,3,1,4     },
+     {1175937,5,4,6,7,9,7,8,10,1,4     },
+     {1176406,1,1,1,1,2,1,2,1,1,2      },
+     {1176881,7,5,3,7,4,10,7,5,5,4        }
+};
+    private static Dataset defaultDataset;
+    private static IEnumerable<string> defaultAllowedInputVariables;
+    private static string defaultTargetVariable;
+    static ClassificationProblemData() {
+      defaultDataset = new Dataset(defaultVariableNames, defaultData);
+      defaultDataset.Name = "Wisconsin classification problem";
+      defaultDataset.Description = "subset from to ..";
+
+      defaultAllowedInputVariables = defaultVariableNames.Except(new List<string>() { "sample", "class" });
+      defaultTargetVariable = "class";
+    }
+    #endregion
+
+    #region parameter properties
+    public IValueParameter<StringValue> TargetVariableParameter {
+      get { return (IValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    }
+    public IFixedValueParameter<StringMatrix> ClassNamesParameter {
+      get { return (IFixedValueParameter<StringMatrix>)Parameters[ClassNamesParameterName]; }
+    }
+    public IFixedValueParameter<DoubleMatrix> ClassificationPenaltiesParameter {
+      get { return (IFixedValueParameter<DoubleMatrix>)Parameters[ClassificationPenaltiesParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public string TargetVariable {
+      get { return TargetVariableParameter.Value.Value; }
+    }
+
+    private List<double> classValues;
+    public List<double> ClassValues {
+      get {
+        if (classValues == null) {
+          classValues = Dataset.GetEnumeratedVariableValues(TargetVariableParameter.Value.Value).Distinct().ToList();
+          classValues.Sort();
+        }
+        return classValues;
+      }
+    }
+    IEnumerable<double> IClassificationProblemData.ClassValues {
+      get { return ClassValues; }
+    }
+
+    public int Classes {
+      get { return ClassValues.Count; }
+    }
+
+    private List<string> classNames;
+    public List<string> ClassNames {
+      get {
+        if (classNames == null) {
+          classNames = new List<string>();
+          for (int i = 0; i < ClassNamesParameter.Value.Rows; i++)
+            classNames.Add(ClassNamesParameter.Value[i, 0]);
+        }
+        return classNames;
+      }
+    }
+    IEnumerable<string> IClassificationProblemData.ClassNames {
+      get { return ClassNames; }
+    }
+
+    private Dictionary<Tuple<double, double>, double> classificationPenaltiesCache = new Dictionary<Tuple<double, double>, double>();
+    #endregion
+
+
+    [StorableConstructor]
+    protected ClassificationProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+    }
+
+    protected ClassificationProblemData(ClassificationProblemData original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ClassificationProblemData(this, cloner); }
+
+    public ClassificationProblemData() : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) { }
+    public ClassificationProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables) {
+      var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
+      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.Where(x => x.Value == targetVariable).First()));
+      Parameters.Add(new FixedValueParameter<StringMatrix>(ClassNamesParameterName, "", new StringMatrix()));
+      Parameters.Add(new FixedValueParameter<DoubleMatrix>(ClassificationPenaltiesParameterName, "", new DoubleMatrix()));
+
+      ResetTargetVariableDependentMembers();
+      RegisterParameterEvents();
+    }
+
+    private void ResetTargetVariableDependentMembers() {
+      DergisterParameterEvents();
+
+      classNames = null;
+      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Columns = 1;
+      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Rows = ClassValues.Count;
+      for (int i = 0; i < Classes; i++)
+        ClassNamesParameter.Value[i, 0] = "Class " + ClassValues[i];
+      ClassNamesParameter.Value.ColumnNames = new List<string>() { "ClassNames" };
+      ClassNamesParameter.Value.RowNames = ClassValues.Select(s => "ClassValue: " + s);
+
+      classificationPenaltiesCache.Clear();
+      ((ValueParameter<DoubleMatrix>)ClassificationPenaltiesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
+      ((IStringConvertibleMatrix)ClassificationPenaltiesParameter.Value).Rows = Classes;
+      ((IStringConvertibleMatrix)ClassificationPenaltiesParameter.Value).Columns = Classes;
+      ClassificationPenaltiesParameter.Value.RowNames = ClassNames.Select(name => "Actual " + name);
+      ClassificationPenaltiesParameter.Value.ColumnNames = ClassNames.Select(name => "Estimated " + name);
+      for (int i = 0; i < Classes; i++) {
+        for (int j = 0; j < Classes; j++) {
+          if (i != j) ClassificationPenaltiesParameter.Value[i, j] = 1;
+          else ClassificationPenaltiesParameter.Value[i, j] = 0;
+        }
+      }
+      ((ValueParameter<DoubleMatrix>)ClassificationPenaltiesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = true;
+      RegisterParameterEvents();
+    }
+
+    public string GetClassName(double classValue) {
+      if (!ClassValues.Contains(classValue)) throw new ArgumentException();
+      int index = ClassValues.IndexOf(classValue);
+      return ClassNames[index];
+    }
+    public double GetClassValue(string className) {
+      if (!ClassNames.Contains(className)) throw new ArgumentException();
+      int index = ClassNames.IndexOf(className);
+      return ClassValues[index];
+    }
+    public void SetClassName(double classValue, string className) {
+      if (!classValues.Contains(classValue)) throw new ArgumentException();
+      int index = ClassValues.IndexOf(classValue);
+      ClassNames[index] = className;
+      ClassNamesParameter.Value[index, 0] = className;
+    }
+
+    public double GetClassificationPenalty(string correctClassName, string estimatedClassName) {
+      return GetClassificationPenalty(GetClassValue(correctClassName), GetClassValue(estimatedClassName));
+    }
+    public double GetClassificationPenalty(double correctClassValue, double estimatedClassValue) {
+      var key = Tuple.Create(correctClassValue, estimatedClassValue);
+      if (!classificationPenaltiesCache.ContainsKey(key)) {
+        int correctClassIndex = ClassValues.IndexOf(correctClassValue);
+        int estimatedClassIndex = ClassValues.IndexOf(estimatedClassValue);
+        classificationPenaltiesCache[key] = ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex];
+      }
+      return classificationPenaltiesCache[key];
+    }
+    public void SetClassificationPenalty(string correctClassName, string estimatedClassName, double penalty) {
+      SetClassificationPenalty(GetClassValue(correctClassName), GetClassValue(estimatedClassName), penalty);
+    }
+    public void SetClassificationPenalty(double correctClassValue, double estimatedClassValue, double penalty) {
+      var key = Tuple.Create(correctClassValue, estimatedClassValue);
+      int correctClassIndex = ClassValues.IndexOf(correctClassValue);
+      int estimatedClassIndex = ClassValues.IndexOf(estimatedClassValue);
+
+      ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex] = penalty;
+    }
+
+    #region events
+    private void RegisterParameterEvents() {
+      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
+      ClassNamesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
+      ClassNamesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+      ClassificationPenaltiesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+    }
+    private void DergisterParameterEvents() {
+      TargetVariableParameter.ValueChanged -= new EventHandler(TargetVariableParameter_ValueChanged);
+      ClassNamesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
+      ClassNamesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+      ClassificationPenaltiesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+    }
+
+    private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
+      classValues = null;
+      ResetTargetVariableDependentMembers();
+      OnChanged();
+    }
+    private void Parameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+    private void MatrixParameter_ItemChanged(object sender, EventArgs<int, int> e) {
+      OnChanged();
+    }
+    #endregion
+
+    #region Import from file
+    public static ClassificationProblemData ImportFromFile(string fileName) {
+      TableFileParser csvFileParser = new TableFileParser();
+      csvFileParser.Parse(fileName);
+
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
+      dataset.Name = Path.GetFileName(fileName);
+
+      ClassificationProblemData problemData = new ClassificationProblemData(dataset, dataset.VariableNames.Skip(1), dataset.VariableNames.First());
+      problemData.Name = "Data imported from " + Path.GetFileName(fileName);
+      return problemData;
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 5730)
@@ -0,0 +1,119 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Abstract base class for classification data analysis solutions
+  /// </summary>
+  [StorableClass]
+  public abstract class ClassificationSolution : DataAnalysisSolution, IClassificationSolution {
+    private const string TrainingAccuracyResultName = "Accuracy (training)";
+    private const string TestAccuracyResultName = "Accuracy (test)";
+
+    public new IClassificationModel Model {
+      get { return (IClassificationModel)base.Model; }
+      protected set { base.Model = value; }
+    }
+
+    public new IClassificationProblemData ProblemData {
+      get { return (IClassificationProblemData)base.ProblemData; }
+      protected set { base.ProblemData = value; }
+    }
+
+    public double TrainingAccuracy {
+      get { return ((DoubleValue)this[TrainingAccuracyResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingAccuracyResultName].Value).Value = value; }
+    }
+
+    public double TestAccuracy {
+      get { return ((DoubleValue)this[TestAccuracyResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestAccuracyResultName].Value).Value = value; }
+    }
+
+    [StorableConstructor]
+    protected ClassificationSolution(bool deserializing) : base(deserializing) { }
+    protected ClassificationSolution(ClassificationSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ClassificationSolution(IClassificationModel model, IClassificationProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(TrainingAccuracyResultName, "Accuracy of the model on the training partition (percentage of correctly classified instances).", new PercentValue()));
+      Add(new Result(TestAccuracyResultName, "Accuracy of the model on the test partition (percentage of correctly classified instances).", new PercentValue()));
+      RecalculateResults();
+    }
+
+    protected override void OnProblemDataChanged(EventArgs e) {
+      base.OnProblemDataChanged(e);
+      RecalculateResults();
+    }
+
+    protected override void OnModelChanged(EventArgs e) {
+      base.OnModelChanged(e);
+      RecalculateResults();
+    }
+
+    private void RecalculateResults() {
+      double[] estimatedTrainingClassValues = EstimatedTrainingClassValues.ToArray(); // cache values
+      IEnumerable<double> originalTrainingClassValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+      double[] estimatedTestClassValues = EstimatedTestClassValues.ToArray(); // cache values
+      IEnumerable<double> originalTestClassValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
+
+      double trainingAccuracy = OnlineAccuracyEvaluator.Calculate(estimatedTrainingClassValues, originalTrainingClassValues);
+      double testAccuracy = OnlineAccuracyEvaluator.Calculate(estimatedTestClassValues, originalTestClassValues);
+
+      TrainingAccuracy = trainingAccuracy;
+      TestAccuracy = testAccuracy;
+    }
+
+    public virtual IEnumerable<double> EstimatedClassValues {
+      get {
+        return GetEstimatedClassValues(Enumerable.Range(0, ProblemData.Dataset.Rows));
+      }
+    }
+
+    public virtual IEnumerable<double> EstimatedTrainingClassValues {
+      get {
+        return GetEstimatedClassValues(ProblemData.TrainingIndizes);
+      }
+    }
+
+    public virtual IEnumerable<double> EstimatedTestClassValues {
+      get {
+        return GetEstimatedClassValues(ProblemData.TestIndizes);
+      }
+    }
+
+    public virtual IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows) {
+      return Model.GetEstimatedClassValues(ProblemData.Dataset, rows);
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 5730)
@@ -0,0 +1,109 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents discriminant function classification data analysis models.
+  /// </summary>
+  [StorableClass]
+  [Item("DiscriminantFunctionClassificationModel", "Represents a classification model that uses a discriminant function and classification thresholds.")]
+  public class DiscriminantFunctionClassificationModel : NamedItem, IDiscriminantFunctionClassificationModel {
+    [Storable]
+    private IRegressionModel model;
+    [Storable]
+    private double[] classValues;
+    // class values are not necessarily sorted in ascending order
+    public IEnumerable<double> ClassValues {
+      get { return (double[])classValues.Clone(); }
+      set {
+        if (value == null) throw new ArgumentException();
+        double[] newValue = value.ToArray();
+        if (newValue.Length != classValues.Length) throw new ArgumentException();
+        classValues = newValue;
+      }
+    }
+    [Storable]
+    private double[] thresholds;
+    public IEnumerable<double> Thresholds {
+      get { return (IEnumerable<double>)thresholds.Clone(); }
+      set {
+        thresholds = value.ToArray();
+        OnThresholdsChanged(EventArgs.Empty);
+      }
+    }
+
+
+    [StorableConstructor]
+    protected DiscriminantFunctionClassificationModel(bool deserializing) : base(deserializing) { }
+    protected DiscriminantFunctionClassificationModel(DiscriminantFunctionClassificationModel original, Cloner cloner)
+      : base(original, cloner) {
+      model = cloner.Clone(original.model);
+      classValues = (double[])original.classValues.Clone();
+      thresholds = (double[])original.thresholds.Clone();
+    }
+    public DiscriminantFunctionClassificationModel(IRegressionModel model, IEnumerable<double> classValues, IEnumerable<double> thresholds)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.model = model;
+      this.classValues = classValues.ToArray();
+      this.thresholds = thresholds.ToArray();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DiscriminantFunctionClassificationModel(this, cloner);
+    }
+
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      return model.GetEstimatedValues(dataset, rows);
+    }
+
+    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      foreach (var x in GetEstimatedValues(dataset, rows)) {
+        int classIndex = 0;
+        // find first threshold value which is larger than x => class index = threshold index + 1
+        for (int i = 0; i < thresholds.Length; i++) {
+          if (x > thresholds[i]) classIndex++;
+          else break;
+        }
+        yield return classValues.ElementAt(classIndex);
+      }
+    }
+    #region events
+    public event EventHandler ThresholdsChanged;
+    protected virtual void OnThresholdsChanged(EventArgs e) {
+      var listener = ThresholdsChanged;
+      if (listener != null) listener(this, e);
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 5730)
@@ -0,0 +1,73 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a classification solution that uses a discriminant function and classification thresholds.
+  /// </summary>
+  [StorableClass]
+  [Item("DiscriminantFunctionClassificationSolution", "Represents a classification solution that uses a discriminant function and classification thresholds.")]
+  public class DiscriminantFunctionClassificationSolution : ClassificationSolution, IDiscriminantFunctionClassificationSolution {
+    public new IDiscriminantFunctionClassificationModel Model {
+      get { return (IDiscriminantFunctionClassificationModel)base.Model; }
+      protected set { base.Model = value; }
+    }
+
+    [StorableConstructor]
+    protected DiscriminantFunctionClassificationSolution(bool deserializing) : base(deserializing) { }
+    protected DiscriminantFunctionClassificationSolution(DiscriminantFunctionClassificationSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DiscriminantFunctionClassificationSolution(IRegressionModel model, IClassificationProblemData problemData, IEnumerable<double> classValues, IEnumerable<double> thresholds)
+      : this(new DiscriminantFunctionClassificationModel(model, classValues, thresholds), problemData) {
+    }
+    public DiscriminantFunctionClassificationSolution(IDiscriminantFunctionClassificationModel model, IClassificationProblemData problemData)
+      : base(model, problemData) {
+    }
+
+    public IEnumerable<double> EstimatedValues {
+      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+
+    public IEnumerable<double> EstimatedTrainingValues {
+      get { return GetEstimatedValues(ProblemData.TrainingIndizes); }
+    }
+
+    public IEnumerable<double> EstimatedTestValues {
+      get { return GetEstimatedValues(ProblemData.TestIndizes); }
+    }
+
+    public IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      return Model.GetEstimatedValues(ProblemData.Dataset, rows);
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 5730)
@@ -0,0 +1,132 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a threshold calculator that maximizes the weighted accuracy of the classifcation model.
+  /// </summary>
+  [StorableClass]
+  [Item("AccuracyMaximizationThresholdCalculator", "Represents a threshold calculator that maximizes the weighted accuracy of the classifcation model.")]
+  public class AccuracyMaximizationThresholdCalculator : ThresholdCalculator {
+
+    [StorableConstructor]
+    protected AccuracyMaximizationThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected AccuracyMaximizationThresholdCalculator(AccuracyMaximizationThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public AccuracyMaximizationThresholdCalculator()
+      : base() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AccuracyMaximizationThresholdCalculator(this, cloner);
+    }
+
+    public override void Calculate(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
+      AccuracyMaximizationThresholdCalculator.CalculateThresholds(problemData, estimatedValues, targetClassValues, out classValues, out thresholds);
+    }
+
+    public static void CalculateThresholds(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
+      int slices = 100;
+      List<double> estimatedValuesList = estimatedValues.ToList();
+      double maxEstimatedValue = estimatedValuesList.Max();
+      double minEstimatedValue = estimatedValuesList.Min();
+      double thresholdIncrement = (maxEstimatedValue - minEstimatedValue) / slices;
+      var estimatedAndTargetValuePairs =
+        estimatedValuesList.Zip(targetClassValues, (x, y) => new { EstimatedValue = x, TargetClassValue = y })
+        .OrderBy(x => x.EstimatedValue)
+        .ToList();
+
+      classValues = problemData.ClassValues.OrderBy(x => x).ToArray();
+      int nClasses = classValues.Length;
+      thresholds = new double[nClasses + 1];
+      thresholds[0] = double.NegativeInfinity;
+      thresholds[thresholds.Length - 1] = double.PositiveInfinity;
+
+      // incrementally calculate accuracy of all possible thresholds
+      int[,] confusionMatrix = new int[nClasses, nClasses];
+
+      for (int i = 1; i < thresholds.Length - 1; i++) {
+        double lowerThreshold = thresholds[i - 1];
+        double actualThreshold = Math.Max(lowerThreshold, minEstimatedValue);
+        double lowestBestThreshold = double.NaN;
+        double highestBestThreshold = double.NaN;
+        double bestClassificationScore = double.PositiveInfinity;
+        bool seriesOfEqualClassificationScores = false;
+
+        while (actualThreshold < maxEstimatedValue) {
+          double classificationScore = 0.0;
+
+          foreach (var pair in estimatedAndTargetValuePairs) {
+            //all positives
+            if (pair.TargetClassValue.IsAlmost(classValues[i - 1])) {
+              if (pair.EstimatedValue > lowerThreshold && pair.EstimatedValue < actualThreshold)
+                //true positive
+                classificationScore += problemData.GetClassificationPenalty(classValues[i - 1], classValues[i - 1]);
+              else
+                //false negative
+                classificationScore += problemData.GetClassificationPenalty(classValues[i], classValues[i - 1]);
+            }
+              //all negatives
+            else {
+              if (pair.EstimatedValue > lowerThreshold && pair.EstimatedValue < actualThreshold)
+                //false positive
+                classificationScore += problemData.GetClassificationPenalty(classValues[i - 1], classValues[i]);
+              else
+                //true negative, consider only upper class
+                classificationScore += problemData.GetClassificationPenalty(classValues[i], classValues[i]);
+            }
+          }
+
+          //new best classification score found
+          if (classificationScore < bestClassificationScore) {
+            bestClassificationScore = classificationScore;
+            lowestBestThreshold = actualThreshold;
+            highestBestThreshold = actualThreshold;
+            seriesOfEqualClassificationScores = true;
+          }
+            //equal classification scores => if seriesOfEqualClassifcationScores == true update highest threshold
+          else if (Math.Abs(classificationScore - bestClassificationScore) < double.Epsilon && seriesOfEqualClassificationScores)
+            highestBestThreshold = actualThreshold;
+          //worse classificatoin score found reset seriesOfEqualClassifcationScores
+          else seriesOfEqualClassificationScores = false;
+
+          actualThreshold += thresholdIncrement;
+        }
+        //scale lowest thresholds and highest found optimal threshold according to the misclassification matrix
+        double falseNegativePenalty = problemData.GetClassificationPenalty(classValues[i], classValues[i - 1]);
+        double falsePositivePenalty = problemData.GetClassificationPenalty(classValues[i - 1], classValues[i]);
+        thresholds[i] = (lowestBestThreshold * falsePositivePenalty + highestBestThreshold * falseNegativePenalty) / (falseNegativePenalty + falsePositivePenalty);
+      }
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs	(revision 5730)
@@ -0,0 +1,152 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a threshold calculator that calculates thresholds as the cutting points between the estimated class distributions (assuming normally distributed class values).
+  /// </summary>
+  [StorableClass]
+  [Item("NormalDistributionCutPointsThresholdCalculator", "Represents a threshold calculator that calculates thresholds as the cutting points between the estimated class distributions (assuming normally distributed class values).")]
+  public class NormalDistributionCutPointsThresholdCalculator : ThresholdCalculator {
+
+    [StorableConstructor]
+    protected NormalDistributionCutPointsThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected NormalDistributionCutPointsThresholdCalculator(NormalDistributionCutPointsThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public NormalDistributionCutPointsThresholdCalculator()
+      : base() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NormalDistributionCutPointsThresholdCalculator(this, cloner);
+    }
+
+    public override void Calculate(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
+      NormalDistributionCutPointsThresholdCalculator.CalculateThresholds(problemData, estimatedValues, targetClassValues, out classValues, out thresholds);
+    }
+
+    public static void CalculateThresholds(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
+      double maxEstimatedValue = estimatedValues.Max();
+      double minEstimatedValue = estimatedValues.Min();
+      var estimatedTargetValues = Enumerable.Zip(estimatedValues, targetClassValues, (e, t) => new { EstimatedValue = e, TargetValue = t }).ToList();
+
+      Dictionary<double, double> classMean = new Dictionary<double, double>();
+      Dictionary<double, double> classStdDev = new Dictionary<double, double>();
+      // calculate moments per class
+      foreach (var group in estimatedTargetValues.GroupBy(p => p.TargetValue)) {
+        IEnumerable<double> estimatedClassValues = group.Select(x => x.EstimatedValue);
+        double classValue = group.Key;
+        double mean, variance;
+        OnlineMeanAndVarianceCalculator.Calculate(estimatedClassValues, out mean, out variance);
+        classMean[classValue] = mean;
+        classStdDev[classValue] = Math.Sqrt(variance);
+      }
+      double[] originalClasses = classMean.Keys.OrderBy(x => x).ToArray();
+      int nClasses = originalClasses.Length;
+      List<double> thresholdList = new List<double>();
+      for (int i = 0; i < nClasses - 1; i++) {
+        for (int j = i + 1; j < nClasses; j++) {
+          double x1, x2;
+          double class0 = originalClasses[i];
+          double class1 = originalClasses[j];
+          // calculate all thresholds
+          CalculateCutPoints(classMean[class0], classStdDev[class0], classMean[class1], classStdDev[class1], out x1, out x2);
+          if (!thresholdList.Any(x => x.IsAlmost(x1))) thresholdList.Add(x1);
+          if (!thresholdList.Any(x => x.IsAlmost(x2))) thresholdList.Add(x2);
+        }
+      }
+      thresholdList.Sort();
+      thresholdList.Insert(0, double.NegativeInfinity);
+      thresholdList.Add(double.PositiveInfinity);
+
+      // determine class values for each partition separated by a threshold by calculating the density of all class distributions
+      // all points in the partition are classified as the class with the maximal density in the parition
+      List<double> classValuesList = new List<double>();
+      for (int i = 0; i < thresholdList.Count - 1; i++) {
+        double m;
+        if (double.IsNegativeInfinity(thresholdList[i])) {
+          m = thresholdList[i + 1] - 1.0; // smaller than the smalles non-infinity threshold
+        } else if (double.IsPositiveInfinity(thresholdList[i + 1])) {
+          m = thresholdList[i] + 1.0; // larger than the largest non-infinity threshold
+        } else {
+          m = thresholdList[i] + (thresholdList[i + 1] - thresholdList[i]) / 2.0; // middle of partition
+        }
+
+        // determine class with maximal probability density in m
+        double maxDensity = 0;
+        double maxDensityClassValue = -1;
+        foreach (var classValue in originalClasses) {
+          double density = NormalDensity(m, classMean[classValue], classStdDev[classValue]);
+          if (density > maxDensity) {
+            maxDensity = density;
+            maxDensityClassValue = classValue;
+          }
+        }
+        classValuesList.Add(maxDensityClassValue);
+      }
+
+      // only keep thresholds at which the class changes 
+      // class B overrides threshold s. So only thresholds r and t are relevant and have to be kept
+      // 
+      //      A    B  C
+      //       /\  /\/\        
+      //      / r\/ /\t\       
+      //     /   /\/  \ \      
+      //    /   / /\s  \ \     
+      //  -/---/-/ -\---\-\----
+      List<double> filteredThresholds = new List<double>();
+      List<double> filteredClassValues = new List<double>();
+      filteredThresholds.Add(thresholdList[0]);
+      filteredClassValues.Add(classValuesList[0]);
+      for (int i = 0; i < classValuesList.Count - 1; i++) {
+        if (classValuesList[i] != classValuesList[i + 1]) {
+          filteredThresholds.Add(thresholdList[i + 1]);
+          filteredClassValues.Add(classValuesList[i + 1]);
+        }
+      }
+      filteredThresholds.Add(double.PositiveInfinity);
+      thresholds = filteredThresholds.ToArray();
+      classValues = filteredClassValues.ToArray();
+    }
+
+    private static double NormalDensity(double x, double mu, double sigma) {
+      return (1.0 / Math.Sqrt(2.0 * Math.PI * sigma * sigma)) * Math.Exp(-((x - mu) * (x - mu)) / (2.0 * sigma * sigma));
+    }
+
+    private static void CalculateCutPoints(double m1, double s1, double m2, double s2, out double x1, out double x2) {
+      double a = (s1 * s1 - s2 * s2);
+      x1 = -(-m2 * s1 * s1 + m1 * s2 * s2 + Math.Sqrt(s1 * s1 * s2 * s2 * ((m1 - m2) * (m1 - m2) + 2.0 * (-s1 * s1 + s2 * s2) * Math.Log(s2 / s1)))) / a;
+      x2 = (m2 * s1 * s1 - m1 * s2 * s2 + Math.Sqrt(s1 * s1 * s2 * s2 * ((m1 - m2) * (m1 - m2) + 2.0 * (-s1 * s1 + s2 * s2) * Math.Log(s2 / s1)))) / a;
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs	(revision 5730)
@@ -0,0 +1,53 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Base class for threshold calculators for discriminant function classification models.
+  /// </summary>
+  [StorableClass]
+  public abstract class ThresholdCalculator : NamedItem, IDiscriminantFunctionThresholdCalculator {
+
+    [StorableConstructor]
+    protected ThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected ThresholdCalculator(ThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ThresholdCalculator()
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+    }
+
+    public abstract void Calculate(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds);
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs	(revision 5730)
@@ -0,0 +1,46 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("ClusteringProblem", "A general clustering problem")]
+  [Creatable("Problems")]
+  public class ClusteringProblem : DataAnalysisProblem<IClusteringProblemData>, IClusteringProblem {
+    [StorableConstructor]
+    protected ClusteringProblem(bool deserializing) : base(deserializing) { }
+    protected ClusteringProblem(ClusteringProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ClusteringProblem(this, cloner); }
+
+    public ClusteringProblem()
+      : base() {
+      ProblemData = new ClusteringProblemData();
+    }
+
+    public override void ImportProblemDataFromFile(string fileName) {
+      ClusteringProblemData problemData = ClusteringProblemData.ImportFromFile(fileName);
+      ProblemData = problemData;
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 5730)
@@ -0,0 +1,111 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("ClusteringProblemData", "Represents an item containing all data defining a clustering problem.")]
+  public sealed class ClusteringProblemData : DataAnalysisProblemData, IClusteringProblemData {
+
+    #region default data
+    private static double[,] kozaF1 = new double[,] {
+          {2.017885919,	-1.449165046},
+          {1.30060506,	-1.344523885},
+          {1.147134798,	-1.317989331},
+          {0.877182504,	-1.266142284},
+          {0.852562452,	-1.261020794},
+          {0.431095788,	-1.158793317},
+          {0.112586002,	-1.050908405},
+          {0.04594507,	-1.021989402},
+          {0.042572879,	-1.020438113},
+          {-0.074027291,	-0.959859562},
+          {-0.109178553,	-0.938094706},
+          {-0.259721109,	-0.803635355},
+          {-0.272991057,	-0.387519561},
+          {-0.161978191,	-0.193611001},
+          {-0.102489983,	-0.114215349},
+          {-0.01469968,	-0.014918985},
+          {-0.008863365,	-0.008942626},
+          {0.026751057,	0.026054094},
+          {0.166922436,	0.14309643},
+          {0.176953808,	0.1504144},
+          {0.190233418,	0.159916534},
+          {0.199800708,	0.166635331},
+          {0.261502822,	0.207600348},
+          {0.30182879,	0.232370249},
+          {0.83763905,	0.468046718}
+    };
+    private static Dataset defaultDataset;
+    private static IEnumerable<string> defaultAllowedInputVariables;
+
+    static ClusteringProblemData() {
+      defaultDataset = new Dataset(new string[] { "y", "x" }, kozaF1);
+      defaultDataset.Name = "Fourth-order Polynomial Function Benchmark Dataset";
+      defaultDataset.Description = "f(x) = x^4 + x^3 + x^2 + x^1";
+      defaultAllowedInputVariables = new List<string>() { "x", "y" };
+    }
+    #endregion
+
+    [StorableConstructor]
+    private ClusteringProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+    }
+
+
+    private ClusteringProblemData(ClusteringProblemData original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ClusteringProblemData(this, cloner); }
+
+    public ClusteringProblemData()
+      : this(defaultDataset, defaultAllowedInputVariables) {
+    }
+
+    public ClusteringProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables)
+      : base(dataset, allowedInputVariables) {
+    }
+
+
+    #region Import from file
+    public static ClusteringProblemData ImportFromFile(string fileName) {
+      TableFileParser csvFileParser = new TableFileParser();
+      csvFileParser.Parse(fileName);
+
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
+      dataset.Name = Path.GetFileName(fileName);
+
+      ClusteringProblemData problemData = new ClusteringProblemData(dataset, dataset.VariableNames);
+      problemData.Name = "Data imported from " + Path.GetFileName(fileName);
+      return problemData;
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 5730)
@@ -0,0 +1,84 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Abstract base class for clustering data analysis solutions
+  /// </summary>
+  [StorableClass]
+  public abstract class ClusteringSolution : DataAnalysisSolution, IClusteringSolution {
+
+    [StorableConstructor]
+    protected ClusteringSolution(bool deserializing) : base(deserializing) { }
+    protected ClusteringSolution(ClusteringSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ClusteringSolution(IClusteringModel model, IClusteringProblemData problemData)
+      : base(model, problemData) {
+    }
+
+    #region IClusteringSolution Members
+
+    public new IClusteringModel Model {
+      get { return (IClusteringModel)base.Model; }
+      set { base.Model = value; }
+    }
+
+    public new IClusteringProblemData ProblemData {
+      get { return (IClusteringProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    public virtual IEnumerable<int> ClusterValues {
+      get {
+        return GetClusterValues(Enumerable.Range(0, ProblemData.Dataset.Rows));
+      }
+    }
+
+    public virtual IEnumerable<int> TrainingClusterValues {
+      get {
+        return GetClusterValues(ProblemData.TrainingIndizes);
+      }
+    }
+
+    public virtual IEnumerable<int> TestClusterValues {
+      get {
+        return GetClusterValues(ProblemData.TestIndizes);
+      }
+    }
+
+    public virtual IEnumerable<int> GetClusterValues(IEnumerable<int> rows) {
+      return Model.GetClusterValues(ProblemData.Dataset, rows);
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 5730)
@@ -0,0 +1,79 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  public abstract class DataAnalysisProblem<T> : Problem,
+    IDataAnalysisProblem<T>
+    where T : class, IDataAnalysisProblemData {
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string ProblemDataParameterDescription = "The data set, target variable and input variables of the data analysis problem.";
+    #region parameter properties
+    IParameter IDataAnalysisProblem.ProblemDataParameter {
+      get { return ProblemDataParameter; }
+    }
+    public IValueParameter<T> ProblemDataParameter {
+      get { return (IValueParameter<T>)Parameters[ProblemDataParameterName]; }
+    }
+    #endregion
+    #region properties
+    IDataAnalysisProblemData IDataAnalysisProblem.ProblemData {
+      get { return ProblemData; }
+    }
+    public T ProblemData {
+      get { return ProblemDataParameter.Value; }
+      protected set { ProblemDataParameter.Value = value; }
+    }
+    #endregion
+    protected DataAnalysisProblem(DataAnalysisProblem<T> original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    [StorableConstructor]
+    protected DataAnalysisProblem(bool deserializing) : base(deserializing) { }
+    public DataAnalysisProblem()
+      : base() {
+      Parameters.Add(new ValueParameter<T>(ProblemDataParameterName, ProblemDataParameterDescription));
+    }
+
+    private void RegisterEventHandlers() {
+      ProblemDataParameter.Value.Changed += new EventHandler(ProblemDataParameter_ValueChanged);
+    }
+    private void ProblemDataParameter_ValueChanged(object sender, EventArgs e) {
+      OnProblemDataChanged();
+      OnReset();
+    }
+
+    public event EventHandler ProblemDataChanged;
+    protected virtual void OnProblemDataChanged() {
+      var handler = ProblemDataChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public abstract void ImportProblemDataFromFile(string fileName);
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 5730)
@@ -0,0 +1,155 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  public abstract class DataAnalysisProblemData : ParameterizedNamedItem, IDataAnalysisProblemData {
+    private const string DatasetParameterName = "Dataset";
+    private const string InputVariablesParameterName = "InputVariables";
+    private const string TrainingPartitionStartParameterName = "TrainingPartitionStart";
+    private const string TrainingPartitionEndParameterName = "TrainingPartitionEnd";
+    private const string TestPartitionStartParameterName = "TestPartitionStart";
+    private const string TestPartitionEndParameterName = "TestPartitionEnd";
+
+    #region parameter properites
+    public IFixedValueParameter<Dataset> DatasetParameter {
+      get { return (IFixedValueParameter<Dataset>)Parameters[DatasetParameterName]; }
+    }
+    public IFixedValueParameter<ICheckedItemList<StringValue>> InputVariablesParameter {
+      get { return (IFixedValueParameter<ICheckedItemList<StringValue>>)Parameters[InputVariablesParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> TrainingPartitionStartParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TrainingPartitionStartParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> TrainingPartitionEndParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TrainingPartitionEndParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> TestPartitionStartParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TestPartitionStartParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> TestPartitionEndParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TestPartitionEndParameterName]; }
+    }
+    #endregion
+
+    #region propeties
+    public Dataset Dataset {
+      get { return DatasetParameter.Value; }
+    }
+    public ICheckedItemList<StringValue> InputVariables {
+      get { return InputVariablesParameter.Value; }
+    }
+    public IEnumerable<string> AllowedInputVariables {
+      get { return InputVariables.CheckedItems.Select(x => x.Value.Value); }
+    }
+
+    public IntValue TrainingPartitionStart {
+      get { return TrainingPartitionStartParameter.Value; }
+    }
+    public IntValue TrainingPartitionEnd {
+      get { return TrainingPartitionEndParameter.Value; }
+    }
+    public IntValue TestPartitionStart {
+      get { return TestPartitionStartParameter.Value; }
+    }
+    public IntValue TestPartitionEnd {
+      get { return TestPartitionEndParameter.Value; }
+    }
+
+    public IEnumerable<int> TrainingIndizes {
+      get {
+        return Enumerable.Range(TrainingPartitionStart.Value, TrainingPartitionEnd.Value - TrainingPartitionStart.Value)
+                         .Where(i => i >= 0 && i < Dataset.Rows && (i < TestPartitionStart.Value || TestPartitionEnd.Value <= i));
+      }
+    }
+    public IEnumerable<int> TestIndizes {
+      get {
+        return Enumerable.Range(TestPartitionStart.Value, TestPartitionEnd.Value - TestPartitionStart.Value)
+           .Where(i => i >= 0 && i < Dataset.Rows);
+      }
+    }
+    #endregion
+
+    protected DataAnalysisProblemData(DataAnalysisProblemData original, Cloner cloner) : base(original, cloner) { }
+    [StorableConstructor]
+    protected DataAnalysisProblemData(bool deserializing) : base(deserializing) { }
+
+    protected DataAnalysisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables) {
+      if (dataset == null) throw new ArgumentNullException("The dataset must not be null.");
+      if (allowedInputVariables == null) throw new ArgumentNullException("The allowedInputVariables must not be null.");
+
+      if (allowedInputVariables.Except(dataset.VariableNames).Any())
+        throw new ArgumentException("All allowed input variables must be present in the dataset.");
+
+      var inputVariables = new CheckedItemList<StringValue>(dataset.VariableNames.Select(x => new StringValue(x)));
+      foreach (StringValue x in inputVariables)
+        inputVariables.SetItemCheckedState(x, allowedInputVariables.Contains(x.Value));
+
+      int trainingPartitionStart = 0;
+      int trainingPartitionEnd = dataset.Rows / 2;
+      int testPartitionStart = dataset.Rows / 2;
+      int testPartitionEnd = dataset.Rows;
+
+      Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", dataset));
+      Parameters.Add(new FixedValueParameter<ICheckedItemList<StringValue>>(InputVariablesParameterName, "", inputVariables.AsReadOnly()));
+      Parameters.Add(new FixedValueParameter<IntValue>(TrainingPartitionStartParameterName, "", new IntValue(trainingPartitionStart)));
+      Parameters.Add(new FixedValueParameter<IntValue>(TrainingPartitionEndParameterName, "", new IntValue(trainingPartitionEnd)));
+      Parameters.Add(new FixedValueParameter<IntValue>(TestPartitionStartParameterName, "", new IntValue(testPartitionStart)));
+      Parameters.Add(new FixedValueParameter<IntValue>(TestPartitionEndParameterName, "", new IntValue(testPartitionEnd)));
+
+      ((ValueParameter<Dataset>)DatasetParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      DatasetParameter.ValueChanged += new EventHandler(Parameter_ValueChanged);
+      InputVariables.CheckedItemsChanged += new CollectionItemsChangedEventHandler<IndexedItem<StringValue>>(InputVariables_CheckedItemsChanged);
+      TrainingPartitionStart.ValueChanged += new EventHandler(Parameter_ValueChanged);
+      TrainingPartitionEnd.ValueChanged += new EventHandler(Parameter_ValueChanged);
+      TestPartitionStart.ValueChanged += new EventHandler(Parameter_ValueChanged);
+      TestPartitionEnd.ValueChanged += new EventHandler(Parameter_ValueChanged);
+    }
+
+    private void InputVariables_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<StringValue>> e) {
+      OnChanged();
+    }
+
+    private void Parameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+
+    public event EventHandler Changed;
+    protected virtual void OnChanged() {
+      var listeners = Changed;
+      if (listeners != null) listeners(this, EventArgs.Empty);
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 5730)
@@ -0,0 +1,168 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+using System.Drawing;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Abstract base class for data analysis solutions
+  /// </summary>
+  [StorableClass]
+  public abstract class DataAnalysisSolution : ResultCollection, IDataAnalysisSolution {
+    private const string ModelResultName = "Model";
+    private const string ProblemDataResultName = "ProblemData";
+
+    public override Image ItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Function; }
+    }
+
+    #region properties
+    public IDataAnalysisModel Model {
+      get { return (IDataAnalysisModel)this[ModelResultName].Value; }
+      protected set {
+        if (this[ModelResultName].Value != value) {
+          if (value != null) {
+            this[ModelResultName].Value = value;
+            OnModelChanged(EventArgs.Empty);
+          }
+        }
+      }
+    }
+
+    public IDataAnalysisProblemData ProblemData {
+      get { return (IDataAnalysisProblemData)this[ProblemDataResultName].Value; }
+      protected set {
+        if (this[ProblemDataResultName].Value != value) {
+          if (value != null) {
+            ProblemData.Changed -= new EventHandler(ProblemData_Changed);
+            this[ProblemDataResultName].Value = value;
+            ProblemData.Changed += new EventHandler(ProblemData_Changed);
+            OnProblemDataChanged(EventArgs.Empty);
+          }
+        }
+      }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataAnalysisSolution(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisSolution(DataAnalysisSolution original, Cloner cloner)
+      : base(original, cloner) {
+      name = original.Name;
+      description = original.Description;
+    }
+    public DataAnalysisSolution(IDataAnalysisModel model, IDataAnalysisProblemData problemData)
+      : base() {
+      name = ItemName;
+      description = ItemDescription;
+      Add(new Result(ModelResultName, "The symbolic data analysis model.", model));
+      Add(new Result(ProblemDataResultName, "The symbolic data analysis problem data.", problemData));
+
+      problemData.Changed += new EventHandler(ProblemData_Changed);
+    }
+
+    private void ProblemData_Changed(object sender, EventArgs e) {
+      OnProblemDataChanged(e);
+    }
+
+    public event EventHandler ModelChanged;
+    protected virtual void OnModelChanged(EventArgs e) {
+      var listeners = ModelChanged;
+      if (listeners != null) listeners(this, e);
+    }
+
+    public event EventHandler ProblemDataChanged;
+    protected virtual void OnProblemDataChanged(EventArgs e) {
+      var listeners = ProblemDataChanged;
+      if (listeners != null) listeners(this, e);
+    }
+
+    #region INamedItem Members
+    [Storable]
+    protected string name;
+    public string Name {
+      get { return name; }
+      set {
+        if (!CanChangeName) throw new NotSupportedException("Name cannot be changed.");
+        if (!(name.Equals(value) || (value == null) && (name == string.Empty))) {
+          CancelEventArgs<string> e = value == null ? new CancelEventArgs<string>(string.Empty) : new CancelEventArgs<string>(value);
+          OnNameChanging(e);
+          if (!e.Cancel) {
+            name = value == null ? string.Empty : value;
+            OnNameChanged();
+          }
+        }
+      }
+    }
+    public virtual bool CanChangeName {
+      get { return true; }
+    }
+    [Storable]
+    protected string description;
+    public string Description {
+      get { return description; }
+      set {
+        if (!CanChangeDescription) throw new NotSupportedException("Description cannot be changed.");
+        if (!(description.Equals(value) || (value == null) && (description == string.Empty))) {
+          description = value == null ? string.Empty : value;
+          OnDescriptionChanged();
+        }
+      }
+    }
+    public virtual bool CanChangeDescription {
+      get { return true; }
+    }
+
+    public override string ToString() {
+      return Name;
+    }
+
+    public event EventHandler<CancelEventArgs<string>> NameChanging;
+    protected virtual void OnNameChanging(CancelEventArgs<string> e) {
+      var handler = NameChanging;
+      if (handler != null) handler(this, e);
+    }
+
+    public event EventHandler NameChanged;
+    protected virtual void OnNameChanged() {
+      var handler = NameChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+
+    public event EventHandler DescriptionChanged;
+    protected virtual void OnDescriptionChanged() {
+      var handler = DescriptionChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 5730)
@@ -0,0 +1,88 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents regression solutions that contain an ensemble of multiple regression models
+  /// </summary>
+  [StorableClass]
+  [Item("RegressionEnsembleModel", "A regression model that contains an ensemble of multiple regression models")]
+  public class RegressionEnsembleModel : NamedItem, IRegressionEnsembleModel {
+
+    [Storable]
+    private List<IRegressionModel> models;
+    public IEnumerable<IRegressionModel> Models {
+      get { return new List<IRegressionModel>(models); }
+    }
+    [StorableConstructor]
+    protected RegressionEnsembleModel(bool deserializing) : base(deserializing) { }
+    protected RegressionEnsembleModel(RegressionEnsembleModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.models = original.Models.Select(m => cloner.Clone(m)).ToList();
+    }
+    public RegressionEnsembleModel(IEnumerable<IRegressionModel> models)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.models = new List<IRegressionModel>(models);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegressionEnsembleModel(this, cloner);
+    }
+
+    #region IRegressionEnsembleModel Members
+
+    public IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      var estimatedValuesEnumerators = (from model in models
+                                        select model.GetEstimatedValues(dataset, rows).GetEnumerator())
+                                       .ToList();
+
+      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
+        yield return from enumerator in estimatedValuesEnumerators
+                     select enumerator.Current;
+      }
+    }
+
+    #endregion
+
+    #region IRegressionModel Members
+
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      foreach (var estimatedValuesVector in GetEstimatedValueVectors(dataset, rows)) {
+        yield return estimatedValuesVector.Average();
+      }
+    }
+
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 5730)
@@ -0,0 +1,46 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("RegressionProblem", "A general regression problem")]
+  [Creatable("Problems")]
+  public class RegressionProblem : DataAnalysisProblem<IRegressionProblemData>, IRegressionProblem {
+    [StorableConstructor]
+    protected RegressionProblem(bool deserializing) : base(deserializing) { }
+    protected RegressionProblem(RegressionProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new RegressionProblem(this, cloner); }
+
+    public RegressionProblem()
+      : base() {
+      ProblemData = new RegressionProblemData();
+    }
+
+    public override void ImportProblemDataFromFile(string fileName) {
+      RegressionProblemData problemData = RegressionProblemData.ImportFromFile(fileName);
+      ProblemData = problemData;
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 5730)
@@ -0,0 +1,131 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("RegressionProblemData", "Represents an item containing all data defining a regression problem.")]
+  public sealed class RegressionProblemData : DataAnalysisProblemData, IRegressionProblemData {
+    private const string TargetVariableParameterName = "TargetVariable";
+
+    #region default data
+    private static double[,] kozaF1 = new double[,] {
+          {2.017885919,	-1.449165046},
+          {1.30060506,	-1.344523885},
+          {1.147134798,	-1.317989331},
+          {0.877182504,	-1.266142284},
+          {0.852562452,	-1.261020794},
+          {0.431095788,	-1.158793317},
+          {0.112586002,	-1.050908405},
+          {0.04594507,	-1.021989402},
+          {0.042572879,	-1.020438113},
+          {-0.074027291,	-0.959859562},
+          {-0.109178553,	-0.938094706},
+          {-0.259721109,	-0.803635355},
+          {-0.272991057,	-0.387519561},
+          {-0.161978191,	-0.193611001},
+          {-0.102489983,	-0.114215349},
+          {-0.01469968,	-0.014918985},
+          {-0.008863365,	-0.008942626},
+          {0.026751057,	0.026054094},
+          {0.166922436,	0.14309643},
+          {0.176953808,	0.1504144},
+          {0.190233418,	0.159916534},
+          {0.199800708,	0.166635331},
+          {0.261502822,	0.207600348},
+          {0.30182879,	0.232370249},
+          {0.83763905,	0.468046718}
+    };
+    private static Dataset defaultDataset;
+    private static IEnumerable<string> defaultAllowedInputVariables;
+    private static string defaultTargetVariable;
+
+    static RegressionProblemData() {
+      defaultDataset = new Dataset(new string[] { "y", "x" }, kozaF1);
+      defaultDataset.Name = "Fourth-order Polynomial Function Benchmark Dataset";
+      defaultDataset.Description = "f(x) = x^4 + x^3 + x^2 + x^1";
+      defaultAllowedInputVariables = new List<string>() { "x" };
+      defaultTargetVariable = "y";
+    }
+    #endregion
+
+    public IValueParameter<StringValue> TargetVariableParameter {
+      get { return (IValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    }
+    public string TargetVariable {
+      get { return TargetVariableParameter.Value.Value; }
+    }
+
+    [StorableConstructor]
+    private RegressionProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+    }
+
+
+    private RegressionProblemData(RegressionProblemData original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new RegressionProblemData(this, cloner); }
+
+    public RegressionProblemData()
+      : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
+    }
+
+    public RegressionProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables) {
+      var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
+      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.Where(x => x.Value == targetVariable).First()));
+    }
+
+    private void RegisterParameterEvents() {
+      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
+    }
+    private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+
+    #region Import from file
+    public static RegressionProblemData ImportFromFile(string fileName) {
+      TableFileParser csvFileParser = new TableFileParser();
+      csvFileParser.Parse(fileName);
+
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
+      dataset.Name = Path.GetFileName(fileName);
+
+      RegressionProblemData problemData = new RegressionProblemData(dataset, dataset.VariableNames.Skip(1), dataset.VariableNames.First());
+      problemData.Name = "Data imported from " + Path.GetFileName(fileName);
+      return problemData;
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 5730)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 5730)
@@ -0,0 +1,156 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using System;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Abstract base class for regression data analysis solutions
+  /// </summary>
+  [StorableClass]
+  public abstract class RegressionSolution : DataAnalysisSolution, IRegressionSolution {
+    private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
+    private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
+    private const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
+    private const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
+    private const string TrainingRelativeErrorResultName = "Average relative error (training)";
+    private const string TestRelativeErrorResultName = "Average relative error (test)";
+
+    public new IRegressionModel Model {
+      get { return (IRegressionModel)base.Model; }
+      protected set { base.Model = value; }
+    }
+
+    public new IRegressionProblemData ProblemData {
+      get { return (IRegressionProblemData)base.ProblemData; }
+      protected set { base.ProblemData = value; }
+    }
+
+    public double TrainingMeanSquaredError {
+      get { return ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
+    }
+
+    public double TestMeanSquaredError {
+      get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
+    }
+
+    public double TrainingRSquared {
+      get { return ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value = value; }
+    }
+
+    public double TestRSquared {
+      get { return ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value = value; }
+    }
+
+    public double TrainingRelativeError {
+      get { return ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value = value; }
+    }
+
+    public double TestRelativeError {
+      get { return ((DoubleValue)this[TestRelativeErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestRelativeErrorResultName].Value).Value = value; }
+    }
+
+
+    [StorableConstructor]
+    protected RegressionSolution(bool deserializing) : base(deserializing) { }
+    protected RegressionSolution(RegressionSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public RegressionSolution(IRegressionModel model, IRegressionProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
+      Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
+      Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new PercentValue()));
+      Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new PercentValue()));
+
+      RecalculateResults();
+    }
+
+    protected override void OnProblemDataChanged(EventArgs e) {
+      base.OnProblemDataChanged(e);
+      RecalculateResults();
+    }
+    protected override void OnModelChanged(EventArgs e) {
+      base.OnModelChanged(e);
+      RecalculateResults();
+    }
+
+    private void RecalculateResults() {
+      double[] estimatedTrainingValues = EstimatedTrainingValues.ToArray(); // cache values
+      IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+      double[] estimatedTestValues = EstimatedTestValues.ToArray(); // cache values
+      IEnumerable<double> originalTestValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
+
+      double trainingMSE = OnlineMeanSquaredErrorEvaluator.Calculate(estimatedTrainingValues, originalTrainingValues);
+      double testMSE = OnlineMeanSquaredErrorEvaluator.Calculate(estimatedTestValues, originalTestValues);
+      double trainingR2 = OnlinePearsonsRSquaredEvaluator.Calculate(estimatedTrainingValues, originalTrainingValues);
+      double testR2 = OnlinePearsonsRSquaredEvaluator.Calculate(estimatedTestValues, originalTestValues);
+      double trainingRelError = OnlineMeanAbsolutePercentageErrorEvaluator.Calculate(estimatedTrainingValues, originalTrainingValues);
+      double testRelError = OnlineMeanAbsolutePercentageErrorEvaluator.Calculate(estimatedTestValues, originalTestValues);
+
+      TrainingMeanSquaredError = trainingMSE;
+      TestMeanSquaredError = testMSE;
+      TrainingRSquared = trainingR2;
+      TestRSquared = testR2;
+      TrainingRelativeError = trainingRelError;
+      TestRelativeError = testRelError;
+    }
+
+    public virtual IEnumerable<double> EstimatedValues {
+      get {
+        return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows));
+      }
+    }
+
+    public virtual IEnumerable<double> EstimatedTrainingValues {
+      get {
+        return GetEstimatedValues(ProblemData.TrainingIndizes);
+      }
+    }
+
+    public virtual IEnumerable<double> EstimatedTestValues {
+      get {
+        return GetEstimatedValues(ProblemData.TestIndizes);
+      }
+    }
+
+    public virtual IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      return Model.GetEstimatedValues(ProblemData.Dataset, rows);
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionEnsembleModel.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionEnsembleModel.cs	(revision 5722)
+++ 	(revision )
@@ -1,88 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  /// <summary>
-  /// Represents regression solutions that contain an ensemble of multiple regression models
-  /// </summary>
-  [StorableClass]
-  [Item("RegressionEnsembleModel", "A regression model that contains an ensemble of multiple regression models")]
-  public class RegressionEnsembleModel : NamedItem, IRegressionEnsembleModel {
-
-    [Storable]
-    private List<IRegressionModel> models;
-    public IEnumerable<IRegressionModel> Models {
-      get { return new List<IRegressionModel>(models); }
-    }
-    [StorableConstructor]
-    protected RegressionEnsembleModel(bool deserializing) : base(deserializing) { }
-    protected RegressionEnsembleModel(RegressionEnsembleModel original, Cloner cloner)
-      : base(original, cloner) {
-      this.models = original.Models.Select(m => cloner.Clone(m)).ToList();
-    }
-    public RegressionEnsembleModel(IEnumerable<IRegressionModel> models)
-      : base() {
-      this.name = ItemName;
-      this.description = ItemDescription;
-      this.models = new List<IRegressionModel>(models);
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new RegressionEnsembleModel(this, cloner);
-    }
-
-    #region IRegressionEnsembleModel Members
-
-    public IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows) {
-      var estimatedValuesEnumerators = (from model in models
-                                        select model.GetEstimatedValues(dataset, rows).GetEnumerator())
-                                       .ToList();
-
-      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
-        yield return from enumerator in estimatedValuesEnumerators
-                     select enumerator.Current;
-      }
-    }
-
-    #endregion
-
-    #region IRegressionModel Members
-
-    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
-      foreach (var estimatedValuesVector in GetEstimatedValueVectors(dataset, rows)) {
-        yield return estimatedValuesVector.Average();
-      }
-    }
-
-    #endregion
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionProblem.cs	(revision 5722)
+++ 	(revision )
@@ -1,46 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("RegressionProblem", "A general regression problem")]
-  [Creatable("Problems")]
-  public class RegressionProblem : DataAnalysisProblem<IRegressionProblemData>, IRegressionProblem {
-    [StorableConstructor]
-    protected RegressionProblem(bool deserializing) : base(deserializing) { }
-    protected RegressionProblem(RegressionProblem original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) { return new RegressionProblem(this, cloner); }
-
-    public RegressionProblem()
-      : base() {
-      ProblemData = new RegressionProblemData();
-    }
-
-    public override void ImportProblemDataFromFile(string fileName) {
-      RegressionProblemData problemData = RegressionProblemData.ImportFromFile(fileName);
-      ProblemData = problemData;
-    }
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionProblemData.cs	(revision 5722)
+++ 	(revision )
@@ -1,131 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("RegressionProblemData", "Represents an item containing all data defining a regression problem.")]
-  public sealed class RegressionProblemData : DataAnalysisProblemData, IRegressionProblemData {
-    private const string TargetVariableParameterName = "TargetVariable";
-
-    #region default data
-    private static double[,] kozaF1 = new double[,] {
-          {2.017885919,	-1.449165046},
-          {1.30060506,	-1.344523885},
-          {1.147134798,	-1.317989331},
-          {0.877182504,	-1.266142284},
-          {0.852562452,	-1.261020794},
-          {0.431095788,	-1.158793317},
-          {0.112586002,	-1.050908405},
-          {0.04594507,	-1.021989402},
-          {0.042572879,	-1.020438113},
-          {-0.074027291,	-0.959859562},
-          {-0.109178553,	-0.938094706},
-          {-0.259721109,	-0.803635355},
-          {-0.272991057,	-0.387519561},
-          {-0.161978191,	-0.193611001},
-          {-0.102489983,	-0.114215349},
-          {-0.01469968,	-0.014918985},
-          {-0.008863365,	-0.008942626},
-          {0.026751057,	0.026054094},
-          {0.166922436,	0.14309643},
-          {0.176953808,	0.1504144},
-          {0.190233418,	0.159916534},
-          {0.199800708,	0.166635331},
-          {0.261502822,	0.207600348},
-          {0.30182879,	0.232370249},
-          {0.83763905,	0.468046718}
-    };
-    private static Dataset defaultDataset;
-    private static IEnumerable<string> defaultAllowedInputVariables;
-    private static string defaultTargetVariable;
-
-    static RegressionProblemData() {
-      defaultDataset = new Dataset(new string[] { "y", "x" }, kozaF1);
-      defaultDataset.Name = "Fourth-order Polynomial Function Benchmark Dataset";
-      defaultDataset.Description = "f(x) = x^4 + x^3 + x^2 + x^1";
-      defaultAllowedInputVariables = new List<string>() { "x" };
-      defaultTargetVariable = "y";
-    }
-    #endregion
-
-    public IValueParameter<StringValue> TargetVariableParameter {
-      get { return (IValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
-    }
-    public string TargetVariable {
-      get { return TargetVariableParameter.Value.Value; }
-    }
-
-    [StorableConstructor]
-    private RegressionProblemData(bool deserializing) : base(deserializing) { }
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterParameterEvents();
-    }
-
-
-    private RegressionProblemData(RegressionProblemData original, Cloner cloner)
-      : base(original, cloner) {
-      RegisterParameterEvents();
-    }
-    public override IDeepCloneable Clone(Cloner cloner) { return new RegressionProblemData(this, cloner); }
-
-    public RegressionProblemData()
-      : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
-    }
-
-    public RegressionProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
-      : base(dataset, allowedInputVariables) {
-      var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
-      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.Where(x => x.Value == targetVariable).First()));
-    }
-
-    private void RegisterParameterEvents() {
-      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
-    }
-    private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
-      OnChanged();
-    }
-
-    #region Import from file
-    public static RegressionProblemData ImportFromFile(string fileName) {
-      TableFileParser csvFileParser = new TableFileParser();
-      csvFileParser.Parse(fileName);
-
-      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
-      dataset.Name = Path.GetFileName(fileName);
-
-      RegressionProblemData problemData = new RegressionProblemData(dataset, dataset.VariableNames.Skip(1), dataset.VariableNames.First());
-      problemData.Name = "Data imported from " + Path.GetFileName(fileName);
-      return problemData;
-    }
-    #endregion
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionSolution.cs	(revision 5722)
+++ 	(revision )
@@ -1,156 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  /// <summary>
-  /// Abstract base class for regression data analysis solutions
-  /// </summary>
-  [StorableClass]
-  public abstract class RegressionSolution : DataAnalysisSolution, IRegressionSolution {
-    private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
-    private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
-    private const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
-    private const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
-    private const string TrainingRelativeErrorResultName = "Average relative error (training)";
-    private const string TestRelativeErrorResultName = "Average relative error (test)";
-
-    public new IRegressionModel Model {
-      get { return (IRegressionModel)base.Model; }
-      protected set { base.Model = value; }
-    }
-
-    public new IRegressionProblemData ProblemData {
-      get { return (IRegressionProblemData)base.ProblemData; }
-      protected set { base.ProblemData = value; }
-    }
-
-    public double TrainingMeanSquaredError {
-      get { return ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
-    }
-
-    public double TestMeanSquaredError {
-      get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
-    }
-
-    public double TrainingRSquared {
-      get { return ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value; }
-      private set { ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value = value; }
-    }
-
-    public double TestRSquared {
-      get { return ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value; }
-      private set { ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value = value; }
-    }
-
-    public double TrainingRelativeError {
-      get { return ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value = value; }
-    }
-
-    public double TestRelativeError {
-      get { return ((DoubleValue)this[TestRelativeErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TestRelativeErrorResultName].Value).Value = value; }
-    }
-
-
-    [StorableConstructor]
-    protected RegressionSolution(bool deserializing) : base(deserializing) { }
-    protected RegressionSolution(RegressionSolution original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public RegressionSolution(IRegressionModel model, IRegressionProblemData problemData)
-      : base(model, problemData) {
-      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
-      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
-      Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
-      Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
-      Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new PercentValue()));
-      Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new PercentValue()));
-
-      RecalculateResults();
-    }
-
-    protected override void OnProblemDataChanged(EventArgs e) {
-      base.OnProblemDataChanged(e);
-      RecalculateResults();
-    }
-    protected override void OnModelChanged(EventArgs e) {
-      base.OnModelChanged(e);
-      RecalculateResults();
-    }
-
-    private void RecalculateResults() {
-      double[] estimatedTrainingValues = EstimatedTrainingValues.ToArray(); // cache values
-      IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
-      double[] estimatedTestValues = EstimatedTestValues.ToArray(); // cache values
-      IEnumerable<double> originalTestValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
-
-      double trainingMSE = OnlineMeanSquaredErrorEvaluator.Calculate(estimatedTrainingValues, originalTrainingValues);
-      double testMSE = OnlineMeanSquaredErrorEvaluator.Calculate(estimatedTestValues, originalTestValues);
-      double trainingR2 = OnlinePearsonsRSquaredEvaluator.Calculate(estimatedTrainingValues, originalTrainingValues);
-      double testR2 = OnlinePearsonsRSquaredEvaluator.Calculate(estimatedTestValues, originalTestValues);
-      double trainingRelError = OnlineMeanAbsolutePercentageErrorEvaluator.Calculate(estimatedTrainingValues, originalTrainingValues);
-      double testRelError = OnlineMeanAbsolutePercentageErrorEvaluator.Calculate(estimatedTestValues, originalTestValues);
-
-      TrainingMeanSquaredError = trainingMSE;
-      TestMeanSquaredError = testMSE;
-      TrainingRSquared = trainingR2;
-      TestRSquared = testR2;
-      TrainingRelativeError = trainingRelError;
-      TestRelativeError = testRelError;
-    }
-
-    public virtual IEnumerable<double> EstimatedValues {
-      get {
-        return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows));
-      }
-    }
-
-    public virtual IEnumerable<double> EstimatedTrainingValues {
-      get {
-        return GetEstimatedValues(ProblemData.TrainingIndizes);
-      }
-    }
-
-    public virtual IEnumerable<double> EstimatedTestValues {
-      get {
-        return GetEstimatedValues(ProblemData.TestIndizes);
-      }
-    }
-
-    public virtual IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
-      return Model.GetEstimatedValues(ProblemData.Dataset, rows);
-    }
-  }
-}
