Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 8742)
@@ -44,5 +44,5 @@
 
       executionState = ExecutionState.Stopped;
-      runs = new RunCollection();
+      runs = new RunCollection { AlgorithmName = name };
       runsCounter = 0;
 
@@ -246,4 +246,9 @@
     #endregion
 
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+      Runs.AlgorithmName = Name;
+    }
+
     public void Prepare() {
       if (ExecutionState == ExecutionState.Started)
@@ -447,9 +452,6 @@
         problemDataClone.TestPartition.Start = SamplesStart.Value; problemDataClone.TestPartition.End = SamplesEnd.Value;
         // clone models
-        var ensembleSolution = new ClassificationEnsembleSolution(
-          solutions.Value.Select(x => cloner.Clone(x.Model)),
-          problemDataClone,
-          solutions.Value.Select(x => cloner.Clone(x.ProblemData.TrainingPartition)),
-          solutions.Value.Select(x => cloner.Clone(x.ProblemData.TestPartition)));
+        var ensembleSolution = new ClassificationEnsembleSolution(problemDataClone);
+        ensembleSolution.AddClassificationSolutions(solutions.Value);
 
         aggregatedResults.Add(new Result(solutions.Key + " (ensemble)", ensembleSolution));
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs	(revision 8742)
@@ -21,6 +21,8 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -29,22 +31,47 @@
   [Item(Name = "CovarianceConst",
     Description = "Constant covariance function for Gaussian processes.")]
-  public class CovarianceConst : Item, ICovarianceFunction {
+  public sealed class CovarianceConst : ParameterizedNamedItem, ICovarianceFunction {
+
     [Storable]
-    private double sf2;
-    public double Scale { get { return sf2; } }
+    private double scale;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return scaleParameter; }
+    }
 
     [StorableConstructor]
-    protected CovarianceConst(bool deserializing)
+    private CovarianceConst(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceConst(CovarianceConst original, Cloner cloner)
+    private CovarianceConst(CovarianceConst original, Cloner cloner)
       : base(original, cloner) {
-      this.sf2 = original.sf2;
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+      this.scale = original.scale;
+
+      RegisterEvents();
     }
 
     public CovarianceConst()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of the constant covariance function.");
+      Parameters.Add(scaleParameter);
+      RegisterEvents();
     }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    // caching
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { scale = scaleParameter.Value.Value; });
+    }
+
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -53,26 +80,25 @@
 
     public int GetNumberOfParameters(int numberOfVariables) {
-      return 1;
+      return scaleParameter.Fixed ? 0 : 1;
     }
 
     public void SetParameter(double[] hyp) {
-      this.sf2 = Math.Exp(2 * hyp[0]);
-    }
-    public void SetData(double[,] x) {
-      // nothing to do
+      if (!scaleParameter.Fixed && hyp.Length == 1) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[0])));
+      } else {
+        throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceConst", "hyp");
+      }
     }
 
-
-    public void SetData(double[,] x, double[,] xt) {
-      // nothing to do
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return scale;
     }
 
-    public double GetCovariance(int i, int j) {
-      return sf2;
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      yield return 2.0 * scale;
     }
 
-    public double GetGradient(int i, int j, int k) {
-      if (k != 0) throw new ArgumentException("CovarianceConst has only one hyperparameters", "k");
-      return 2 * sf2;
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return scale;
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs	(revision 8742)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -28,31 +29,9 @@
   [StorableClass]
   [Item(Name = "CovarianceLinear", Description = "Linear covariance function for Gaussian processes.")]
-  public class CovarianceLinear : Item, ICovarianceFunction {
-    [Storable]
-    private double[,] x;
-    [Storable]
-    private double[,] xt;
-
-    private double[,] k;
-    private bool symmetric;
-
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return 0;
-    }
+  public sealed class CovarianceLinear : Item, ICovarianceFunction {
     [StorableConstructor]
-    protected CovarianceLinear(bool deserializing) : base(deserializing) { }
-    protected CovarianceLinear(CovarianceLinear original, Cloner cloner)
+    private CovarianceLinear(bool deserializing) : base(deserializing) { }
+    private CovarianceLinear(CovarianceLinear original, Cloner cloner)
       : base(original, cloner) {
-      if (original.x != null) {
-        this.x = new double[original.x.GetLength(0), original.x.GetLength(1)];
-        Array.Copy(original.x, this.x, x.Length);
-
-        this.xt = new double[original.xt.GetLength(0), original.xt.GetLength(1)];
-        Array.Copy(original.xt, this.xt, xt.Length);
-
-        this.k = new double[original.k.GetLength(0), original.k.GetLength(1)];
-        Array.Copy(original.k, this.k, k.Length);
-      }
-      this.symmetric = original.symmetric;
     }
     public CovarianceLinear()
@@ -64,53 +43,22 @@
     }
 
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return 0;
+    }
+
     public void SetParameter(double[] hyp) {
       if (hyp.Length > 0) throw new ArgumentException("No hyperparameters are allowed for the linear covariance function.");
-      k = null;
     }
 
-    public void SetData(double[,] x) {
-      SetData(x, x);
-      this.symmetric = true;
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return Util.ScalarProd(x, i, j, 1, columnIndices);
     }
 
-    public void SetData(double[,] x, double[,] xt) {
-      this.x = x;
-      this.xt = xt;
-      this.symmetric = false;
-
-      k = null;
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      yield break;
     }
 
-    public double GetCovariance(int i, int j) {
-      if (k == null) CalculateInnerProduct();
-      return k[i, j];
-    }
-
-    public double GetGradient(int i, int j, int k) {
-      throw new NotSupportedException("CovarianceLinear does not have hyperparameters.");
-    }
-
-
-    private void CalculateInnerProduct() {
-      if (x.GetLength(1) != xt.GetLength(1)) throw new InvalidOperationException();
-      int rows = x.GetLength(0);
-      int cols = xt.GetLength(0);
-      k = new double[rows, cols];
-      if (symmetric) {
-        for (int i = 0; i < rows; i++) {
-          for (int j = i; j < cols; j++) {
-            k[i, j] = Util.ScalarProd(Util.GetRow(x, i),
-                                      Util.GetRow(x, j));
-            k[j, i] = k[i, j];
-          }
-        }
-      } else {
-        for (int i = 0; i < rows; i++) {
-          for (int j = 0; j < cols; j++) {
-            k[i, j] = Util.ScalarProd(Util.GetRow(x, i),
-                                      Util.GetRow(xt, j));
-          }
-        }
-      }
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return Util.ScalarProd(x, i, xt, j);
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs	(revision 8742)
@@ -0,0 +1,110 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceLinearArd",
+    Description = "Linear covariance function with automatic relevance determination for Gaussian processes.")]
+  public sealed class CovarianceLinearArd : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double[] inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleArray> inverseLengthParameter;
+    public IValueParameter<DoubleArray> InverseLengthParameter {
+      get { return inverseLengthParameter; }
+    }
+
+    [StorableConstructor]
+    private CovarianceLinearArd(bool deserializing) : base(deserializing) { }
+    private CovarianceLinearArd(CovarianceLinearArd original, Cloner cloner)
+      : base(original, cloner) {
+      inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+      if (original.inverseLength != null) {
+        this.inverseLength = new double[original.inverseLength.Length];
+        Array.Copy(original.inverseLength, inverseLength, inverseLength.Length);
+      }
+
+      RegisterEvents();
+    }
+    public CovarianceLinearArd()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength",
+                                                               "The inverse length parameter for ARD.");
+      Parameters.Add(inverseLengthParameter);
+      RegisterEvents();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceLinearArd(this, cloner);
+    }
+
+    // caching
+    private void RegisterEvents() {
+      Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.ToArray(); });
+    }
+
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      if (!inverseLengthParameter.Fixed)
+        return numberOfVariables;
+      else
+        return 0;
+    }
+
+    public void SetParameter(double[] hyp) {
+      if (!inverseLengthParameter.Fixed && hyp.Length > 0) {
+        inverseLengthParameter.SetValue(new DoubleArray(hyp.Select(e => 1.0 / Math.Exp(e)).ToArray()));
+      } else throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceLinearArd", "hyp");
+    }
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return Util.ScalarProd(x, i, j, inverseLength, columnIndices);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
+
+      foreach (int k in columnIndices) {
+        yield return -2.0 * x[i, k] * x[j, k] * inverseLength[k] * inverseLength[k];
+      }
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return Util.ScalarProd(x, i, xt, j, inverseLength, columnIndices);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMask.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMask.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMask.cs	(revision 8742)
@@ -0,0 +1,124 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceMask",
+    Description = "Masking covariance function for dimension selection can be used to apply a covariance function only on certain input dimensions.")]
+  public sealed class CovarianceMask : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private int[] selectedDimensions;
+    [Storable]
+    private readonly ValueParameter<IntArray> selectedDimensionsParameter;
+    public IValueParameter<IntArray> SelectedDimensionsParameter {
+      get { return selectedDimensionsParameter; }
+    }
+
+    [Storable]
+    private ICovarianceFunction cov;
+    [Storable]
+    private readonly ValueParameter<ICovarianceFunction> covParameter;
+    public IValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
+      get { return covParameter; }
+    }
+
+    [StorableConstructor]
+    private CovarianceMask(bool deserializing)
+      : base(deserializing) {
+    }
+
+    private CovarianceMask(CovarianceMask original, Cloner cloner)
+      : base(original, cloner) {
+      this.selectedDimensionsParameter = cloner.Clone(original.selectedDimensionsParameter);
+      if (original.selectedDimensions != null) {
+        this.selectedDimensions = (int[])original.selectedDimensions.Clone();
+      }
+
+      this.covParameter = cloner.Clone(original.covParameter);
+      this.cov = cloner.Clone(original.cov);
+      RegisterEvents();
+    }
+
+    public CovarianceMask()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.selectedDimensionsParameter = new ValueParameter<IntArray>("SelectedDimensions", "The dimensions on which the specified covariance function should be applied to.");
+      this.covParameter = new ValueParameter<ICovarianceFunction>("CovarianceFunction", "The covariance function that should be scaled.", new CovarianceSquaredExponentialIso());
+      cov = covParameter.Value;
+
+      Parameters.Add(selectedDimensionsParameter);
+      Parameters.Add(covParameter);
+
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceMask(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachArrayChangeHandler<IntArray, int>(selectedDimensionsParameter, () => {
+        selectedDimensions = selectedDimensionsParameter.Value
+          .OrderBy(x => x)
+          .Distinct()
+          .ToArray();
+        if (selectedDimensions.Length == 0) selectedDimensions = null;
+      });
+      covParameter.ValueChanged += (sender, args) => { cov = covParameter.Value; };
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      if (selectedDimensions == null) return cov.GetNumberOfParameters(numberOfVariables);
+      else return cov.GetNumberOfParameters(selectedDimensions.Length);
+    }
+
+    public void SetParameter(double[] hyp) {
+      cov.SetParameter(hyp);
+    }
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return cov.GetCovariance(x, i, j, selectedDimensions);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return cov.GetGradient(x, i, j, selectedDimensions);
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return cov.GetCrossCovariance(x, xt, i, j, selectedDimensions);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMaternIso.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMaternIso.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceMaternIso.cs	(revision 8742)
@@ -0,0 +1,177 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceMaternIso",
+    Description = "Matern covariance function for Gaussian processes.")]
+  public sealed class CovarianceMaternIso : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
+    public IValueParameter<DoubleValue> InverseLengthParameter {
+      get { return inverseLengthParameter; }
+    }
+
+    [Storable]
+    private double sf2;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return scaleParameter; }
+    }
+
+    [Storable]
+    private int d;
+    [Storable]
+    private readonly ConstrainedValueParameter<IntValue> dParameter;
+    public IConstrainedValueParameter<IntValue> DParameter {
+      get { return dParameter; }
+    }
+
+
+    [StorableConstructor]
+    private CovarianceMaternIso(bool deserializing)
+      : base(deserializing) {
+    }
+
+    private CovarianceMaternIso(CovarianceMaternIso original, Cloner cloner)
+      : base(original, cloner) {
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+      this.sf2 = original.sf2;
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+      this.inverseLength = original.inverseLength;
+      this.dParameter = cloner.Clone(original.dParameter);
+      this.d = original.d;
+      RegisterEvents();
+    }
+
+    public CovarianceMaternIso()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric Matern covariance function.");
+      scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric Matern covariance function.");
+      var validDValues = new ItemSet<IntValue>();
+      validDValues.Add((IntValue)new IntValue(1).AsReadOnly());
+      validDValues.Add((IntValue)new IntValue(3).AsReadOnly());
+      validDValues.Add((IntValue)new IntValue(5).AsReadOnly());
+      dParameter = new ConstrainedValueParameter<IntValue>("D", "The d parameter (allowed values: 1, 3, or 5) of the isometric Matern covariance function.", validDValues, validDValues.First());
+      d = dParameter.Value.Value;
+
+      Parameters.Add(inverseLengthParameter);
+      Parameters.Add(scaleParameter);
+      Parameters.Add(dParameter);
+
+      RegisterEvents();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceMaternIso(this, cloner);
+    }
+
+    // caching
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<IntValue, int>(dParameter, () => { d = dParameter.Value.Value; });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (inverseLengthParameter.Fixed ? 0 : 1) +
+        (scaleParameter.Fixed ? 0 : 1);
+    }
+
+    public void SetParameter(double[] hyp) {
+      int i = 0;
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceMaternIso", "hyp");
+    }
+
+
+    private double m(double t) {
+      double f;
+      switch (d) {
+        case 1: { f = 1; break; }
+        case 3: { f = 1 + t; break; }
+        case 5: { f = 1 + t * (1 + t / 3.0); break; }
+        default: throw new InvalidOperationException();
+      }
+      return f * Math.Exp(-t);
+    }
+
+    private double dm(double t) {
+      double df;
+      switch (d) {
+        case 1: { df = 1; break; }
+        case 3: { df = t; break; }
+        case 5: { df = t * (1 + t) / 3.0; break; }
+        default: throw new InvalidOperationException();
+      }
+      return df * t * Math.Exp(-t);
+    }
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double dist = i == j
+                   ? 0.0
+                   : Math.Sqrt(Util.SqrDist(x, i, j, Math.Sqrt(d) * inverseLength, columnIndices));
+      return sf2 * m(dist);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double dist = i == j
+                   ? 0.0
+                   : Math.Sqrt(Util.SqrDist(x, i, j, Math.Sqrt(d) * inverseLength, columnIndices));
+
+      yield return sf2 * dm(dist);
+      yield return 2 * sf2 * m(dist);
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      double dist = Math.Sqrt(Util.SqrDist(x, i, xt, j, Math.Sqrt(d) * inverseLength, columnIndices));
+      return sf2 * m(dist);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs	(revision 8742)
@@ -21,6 +21,8 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -29,21 +31,36 @@
   [Item(Name = "CovarianceNoise",
     Description = "Noise covariance function for Gaussian processes.")]
-  public class CovarianceNoise : Item, ICovarianceFunction {
+  public sealed class CovarianceNoise : ParameterizedNamedItem, ICovarianceFunction {
+
+
     [Storable]
     private double sf2;
-    public double Scale { get { return sf2; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return scaleParameter; }
+    }
 
     [StorableConstructor]
-    protected CovarianceNoise(bool deserializing)
+    private CovarianceNoise(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceNoise(CovarianceNoise original, Cloner cloner)
+    private CovarianceNoise(CovarianceNoise original, Cloner cloner)
       : base(original, cloner) {
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
       this.sf2 = original.sf2;
+      RegisterEvents();
     }
 
     public CovarianceNoise()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of noise.");
+      Parameters.Add(this.scaleParameter);
+
+      RegisterEvents();
     }
 
@@ -52,31 +69,35 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+    }
+
     public int GetNumberOfParameters(int numberOfVariables) {
-      return 1;
+      return scaleParameter.Fixed ? 0 : 1;
     }
 
     public void SetParameter(double[] hyp) {
-      this.sf2 = Math.Exp(2 * hyp[0]);
-    }
-    public void SetData(double[,] x) {
-      // nothing to do
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[0])));
+      } else {
+        if (hyp.Length > 0) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceNoise", "hyp");
+      }
     }
 
-
-    public void SetData(double[,] x, double[,] xt) {
-      // nothing to do
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return sf2;
     }
 
-    public double GetCovariance(int i, int j) {
-      if (i == j) return sf2;
-      else return 0.0;
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      yield return 2 * sf2;
     }
 
-    public double GetGradient(int i, int j, int k) {
-      if (k != 0) throw new ArgumentException("CovarianceConst has only one hyperparameters", "k");
-      if (i == j)
-        return 2 * sf2;
-      else
-        return 0.0;
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return 0.0;
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs	(revision 8742)
@@ -21,6 +21,9 @@
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -28,42 +31,63 @@
   [StorableClass]
   [Item(Name = "CovariancePeriodic", Description = "Periodic covariance function for Gaussian processes.")]
-  public class CovariancePeriodic : Item, ICovarianceFunction {
+  public sealed class CovariancePeriodic : ParameterizedNamedItem, ICovarianceFunction {
+
     [Storable]
-    private double[,] x;
+    private double scale;
     [Storable]
-    private double[,] xt;
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return scaleParameter; }
+    }
+
     [Storable]
-    private double sf2;
-    public double Scale { get { return sf2; } }
+    private double inverseLength;
     [Storable]
-    private double l;
-    public double Length { get { return l; } }
+    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
+    public IValueParameter<DoubleValue> InverseLengthParameter {
+      get { return inverseLengthParameter; }
+    }
+
     [Storable]
-    private double p;
-    public double Period { get { return p; } }
+    private double period;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> periodParameter;
+    public IValueParameter<DoubleValue> PeriodParameter {
+      get { return periodParameter; }
+    }
 
-    private bool symmetric;
 
-    private double[,] sd;
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return 3;
+    [StorableConstructor]
+    private CovariancePeriodic(bool deserializing) : base(deserializing) { }
+    private CovariancePeriodic(CovariancePeriodic original, Cloner cloner)
+      : base(original, cloner) {
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+      this.periodParameter = cloner.Clone(original.periodParameter);
+      this.scale = original.scale;
+      this.inverseLength = original.inverseLength;
+      this.period = original.period;
+
+      RegisterEvents();
     }
-    [StorableConstructor]
-    protected CovariancePeriodic(bool deserializing) : base(deserializing) { }
-    protected CovariancePeriodic(CovariancePeriodic original, Cloner cloner)
-      : base(original, cloner) {
-      if (original.x != null) {
-        x = new double[original.x.GetLength(0), original.x.GetLength(1)];
-        Array.Copy(original.x, x, x.Length);
-        xt = new double[original.xt.GetLength(0), original.xt.GetLength(1)];
-        Array.Copy(original.xt, xt, xt.Length);
-      }
-      sf2 = original.sf2;
-      l = original.l;
-      p = original.p;
-      symmetric = original.symmetric;
-    }
+
     public CovariancePeriodic()
       : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of the periodic covariance function.");
+      inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter for the periodic covariance function.");
+      periodParameter = new HyperParameter<DoubleValue>("Period", "The period parameter for the periodic covariance function.");
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+      Parameters.Add(periodParameter);
+
+      RegisterEvents();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
     }
 
@@ -72,80 +96,63 @@
     }
 
-    public void SetParameter(double[] hyp) {
-      if (hyp.Length != 3) throw new ArgumentException();
-      this.l = Math.Exp(hyp[0]);
-      this.p = Math.Exp(hyp[1]);
-      this.sf2 = Math.Exp(2 * hyp[2]);
-      // sf2 = Math.Min(10E6, sf2); // upper limit for the scale
-
-      sd = null;
-    }
-    public void SetData(double[,] x) {
-      SetData(x, x);
-      this.symmetric = true;
+    // caching
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { scale = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(periodParameter, () => { period = periodParameter.Value.Value; });
     }
 
-    public void SetData(double[,] x, double[,] xt) {
-      this.x = x;
-      this.xt = xt;
-      this.symmetric = false;
-
-      sd = null;
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (new[] { scaleParameter, inverseLengthParameter, periodParameter }).Count(p => !p.Fixed);
     }
 
-    public double GetCovariance(int i, int j) {
-      if (sd == null) CalculateSquaredDistances();
-      double k = sd[i, j];
-      k = Math.PI * k / p;
-      k = Math.Sin(k) / l;
+    public void SetParameter(double[] hyp) {
+      int i = 0;
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!periodParameter.Fixed) {
+        periodParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovariancePeriod", "hyp");
+    }
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double k = i == j ? 0.0 : GetDistance(x, x, i, j, columnIndices);
+      k = Math.PI * k / period;
+      k = Math.Sin(k) * inverseLength;
       k = k * k;
 
-      return sf2 * Math.Exp(-2.0 * k);
+      return scale * Math.Exp(-2.0 * k);
     }
 
-    public double GetGradient(int i, int j, int k) {
-      double v = Math.PI * sd[i, j] / p;
-      switch (k) {
-        case 0: {
-            double newK = Math.Sin(v) / l;
-            newK = newK * newK;
-            return 4 * sf2 * Math.Exp(-2 * newK) * newK;
-          }
-        case 1: {
-            double r = Math.Sin(v) / l;
-            return 4 * sf2 / l * Math.Exp(-2 * r * r) * r * Math.Cos(v) * v;
-          }
-        case 2: {
-            double newK = Math.Sin(v) / l;
-            newK = newK * newK;
-            return 2 * sf2 * Math.Exp(-2 * newK);
-
-          }
-        default: {
-            throw new ArgumentException("CovariancePeriodic only has three hyperparameters.", "k");
-          }
-      }
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double v = i == j ? 0.0 : Math.PI * GetDistance(x, x, i, j, columnIndices) / period;
+      double gradient = Math.Sin(v) * inverseLength;
+      gradient *= gradient;
+      yield return 4.0 * scale * Math.Exp(-2.0 * gradient) * gradient;
+      double r = Math.Sin(v) * inverseLength;
+      yield return 4.0 * scale * inverseLength * Math.Exp(-2 * r * r) * r * Math.Cos(v) * v;
+      yield return 2.0 * scale * Math.Exp(-2 * gradient);
     }
 
-    private void CalculateSquaredDistances() {
-      if (x.GetLength(1) != xt.GetLength(1)) throw new InvalidOperationException();
-      int rows = x.GetLength(0);
-      int cols = xt.GetLength(0);
-      sd = new double[rows, cols];
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      double k = GetDistance(x, xt, i, j, columnIndices);
+      k = Math.PI * k / period;
+      k = Math.Sin(k) * inverseLength;
+      k = k * k;
 
-      if (symmetric) {
-        for (int i = 0; i < rows; i++) {
-          for (int j = i; j < cols; j++) {
-            sd[i, j] = Math.Sqrt(Util.SqrDist(Util.GetRow(x, i), Util.GetRow(x, j)));
-            sd[j, i] = sd[i, j];
-          }
-        }
-      } else {
-        for (int i = 0; i < rows; i++) {
-          for (int j = 0; j < cols; j++) {
-            sd[i, j] = Math.Sqrt(Util.SqrDist(Util.GetRow(x, i), Util.GetRow(xt, j)));
-          }
-        }
-      }
+      return scale * Math.Exp(-2.0 * k);
+    }
+
+    private double GetDistance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return Math.Sqrt(Util.SqrDist(x, i, xt, j, 1, columnIndices));
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProduct.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProduct.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProduct.cs	(revision 8742)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceProduct",
+    Description = "Product covariance function for Gaussian processes.")]
+  public sealed class CovarianceProduct : Item, ICovarianceFunction {
+    [Storable]
+    private ItemList<ICovarianceFunction> factors;
+
+    [Storable]
+    private int numberOfVariables;
+    public ItemList<ICovarianceFunction> Factors {
+      get { return factors; }
+    }
+
+    [StorableConstructor]
+    private CovarianceProduct(bool deserializing)
+      : base(deserializing) {
+    }
+
+    private CovarianceProduct(CovarianceProduct original, Cloner cloner)
+      : base(original, cloner) {
+      this.factors = cloner.Clone(original.factors);
+      this.numberOfVariables = original.numberOfVariables;
+    }
+
+    public CovarianceProduct()
+      : base() {
+      this.factors = new ItemList<ICovarianceFunction>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceProduct(this, cloner);
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      this.numberOfVariables = numberOfVariables;
+      return factors.Select(f => f.GetNumberOfParameters(numberOfVariables)).Sum();
+    }
+
+    public void SetParameter(double[] hyp) {
+      if (factors.Count == 0) throw new ArgumentException("at least one factor is necessary for the product covariance function.");
+      int offset = 0;
+      foreach (var t in factors) {
+        var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);
+        t.SetParameter(hyp.Skip(offset).Take(numberOfParameters).ToArray());
+        offset += numberOfParameters;
+      }
+    }
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return factors.Select(f => f.GetCovariance(x, i, j, columnIndices)).Aggregate((a, b) => a * b);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      var covariances = factors.Select(f => f.GetCovariance(x, i, j, columnIndices)).ToArray();
+      for (int ii = 0; ii < factors.Count; ii++) {
+        foreach (var g in factors[ii].GetGradient(x, i, j, columnIndices)) {
+          double res = g;
+          for (int jj = 0; jj < covariances.Length; jj++)
+            if (ii != jj) res *= covariances[jj];
+          yield return res;
+        }
+      }
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return factors.Select(f => f.GetCrossCovariance(x, xt, i, j, columnIndices)).Aggregate((a, b) => a * b);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRationalQuadraticArd.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRationalQuadraticArd.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRationalQuadraticArd.cs	(revision 8742)
@@ -0,0 +1,161 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceRationalQuadraticArd",
+    Description = "Rational quadratic covariance function with automatic relevance determination for Gaussian processes.")]
+  public sealed class CovarianceRationalQuadraticArd : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double sf2;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return scaleParameter; }
+    }
+
+    [Storable]
+    private double[] inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleArray> inverseLengthParameter;
+    public IValueParameter<DoubleArray> InverseLengthParameter {
+      get { return inverseLengthParameter; }
+    }
+
+    [Storable]
+    private double shape;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> shapeParameter;
+    public IValueParameter<DoubleValue> ShapeParameter {
+      get { return shapeParameter; }
+    }
+
+    [StorableConstructor]
+    private CovarianceRationalQuadraticArd(bool deserializing)
+      : base(deserializing) {
+    }
+
+    private CovarianceRationalQuadraticArd(CovarianceRationalQuadraticArd original, Cloner cloner)
+      : base(original, cloner) {
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+      this.sf2 = original.sf2;
+
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+      if (original.inverseLength != null) {
+        this.inverseLength = new double[original.inverseLength.Length];
+        Array.Copy(original.inverseLength, inverseLength, inverseLength.Length);
+      }
+
+      this.shapeParameter = cloner.Clone(original.shapeParameter);
+      this.shape = original.shape;
+
+      RegisterEvents();
+    }
+
+    public CovarianceRationalQuadraticArd()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the rational quadratic covariance function with ARD.");
+      this.inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination.");
+      this.shapeParameter = new HyperParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the rational quadratic covariance function with ARD.");
+
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+      Parameters.Add(shapeParameter);
+
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceRationalQuadraticArd(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(shapeParameter, () => { shape = shapeParameter.Value.Value; });
+      Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.ToArray(); });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (scaleParameter.Fixed ? 0 : 1) +
+        (shapeParameter.Fixed ? 0 : 1) +
+        (inverseLengthParameter.Fixed ? 0 : numberOfVariables);
+    }
+
+    public void SetParameter(double[] hyp) {
+      int i = 0;
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (!shapeParameter.Fixed) {
+        shapeParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleArray(hyp.Skip(i).Select(e => 1.0 / Math.Exp(e)).ToArray()));
+        i += hyp.Skip(i).Count();
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRationalQuadraticArd", "hyp");
+    }
+
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+      return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+      double b = 1 + 0.5 * d / shape;
+      for (int k = 0; k < inverseLength.Length; k++) {
+        yield return sf2 * Math.Pow(b, -shape - 1) * Util.SqrDist(x[i, k] * inverseLength[k], x[j, k] * inverseLength[k]);
+      }
+      yield return 2 * sf2 * Math.Pow(b, -shape);
+      yield return sf2 * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
+      return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRationalQuadraticIso.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRationalQuadraticIso.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRationalQuadraticIso.cs	(revision 8742)
@@ -0,0 +1,150 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceRationalQuadraticIso",
+    Description = "Isotropic rational quadratic covariance function for Gaussian processes.")]
+  public sealed class CovarianceRationalQuadraticIso : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double sf2;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
+
+    [Storable]
+    private double inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
+    public IValueParameter<DoubleValue> InverseLengthParameter { get { return inverseLengthParameter; } }
+
+    [Storable]
+    private double shape;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> shapeParameter;
+    public IValueParameter<DoubleValue> ShapeParameter { get { return shapeParameter; } }
+
+    [StorableConstructor]
+    private CovarianceRationalQuadraticIso(bool deserializing)
+      : base(deserializing) {
+    }
+
+    private CovarianceRationalQuadraticIso(CovarianceRationalQuadraticIso original, Cloner cloner)
+      : base(original, cloner) {
+      this.sf2 = original.sf2;
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+
+      this.inverseLength = original.inverseLength;
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+
+      this.shape = original.shape;
+      this.shapeParameter = cloner.Clone(original.shapeParameter);
+
+      RegisterEvents();
+    }
+
+    public CovarianceRationalQuadraticIso()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric rational quadratic covariance function.");
+      this.inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric rational quadratic covariance function.");
+      this.shapeParameter = new HyperParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the isometric rational quadratic covariance function.");
+
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+      Parameters.Add(shapeParameter);
+
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceRationalQuadraticIso(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(shapeParameter, () => { shape = shapeParameter.Value.Value; });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (scaleParameter.Fixed ? 0 : 1) +
+        (inverseLengthParameter.Fixed ? 0 : 1) +
+        (shapeParameter.Fixed ? 0 : 1);
+    }
+
+    public void SetParameter(double[] hyp) {
+      int i = 0;
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (!shapeParameter.Fixed) {
+        shapeParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
+        i++;
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRationalQuadraticIso", "hyp");
+    }
+
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+      return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+
+      double b = 1 + 0.5 * d / shape;
+      yield return sf2 * Math.Pow(b, -shape - 1) * d;
+      yield return 2 * sf2 * Math.Pow(b, -shape);
+      yield return sf2 * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
+      return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceScale.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceScale.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceScale.cs	(revision 8742)
@@ -0,0 +1,123 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceScale",
+    Description = "Scale covariance function for Gaussian processes.")]
+  public sealed class CovarianceScale : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double sf2;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return scaleParameter; }
+    }
+
+    [Storable]
+    private ICovarianceFunction cov;
+    [Storable]
+    private readonly ValueParameter<ICovarianceFunction> covParameter;
+    public IValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
+      get { return covParameter; }
+    }
+
+    [StorableConstructor]
+    private CovarianceScale(bool deserializing)
+      : base(deserializing) {
+    }
+
+    private CovarianceScale(CovarianceScale original, Cloner cloner)
+      : base(original, cloner) {
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+      this.sf2 = original.sf2;
+
+      this.covParameter = cloner.Clone(original.covParameter);
+      this.cov = cloner.Clone(original.cov);
+      RegisterEvents();
+    }
+
+    public CovarianceScale()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter.");
+      this.covParameter = new ValueParameter<ICovarianceFunction>("CovarianceFunction", "The covariance function that should be scaled.", new CovarianceSquaredExponentialIso());
+      cov = covParameter.Value;
+
+      Parameters.Add(this.scaleParameter);
+      Parameters.Add(covParameter);
+
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceScale(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      covParameter.ValueChanged += (sender, args) => { cov = covParameter.Value; };
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return (scaleParameter.Fixed ? 0 : 1) + cov.GetNumberOfParameters(numberOfVariables);
+    }
+
+    public void SetParameter(double[] hyp) {
+      int i = 0;
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      cov.SetParameter(hyp.Skip(i).ToArray());
+    }
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return sf2 * cov.GetCovariance(x, i, j, columnIndices);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      yield return 2 * sf2 * cov.GetCovariance(x, i, j, columnIndices);
+      foreach (var g in cov.GetGradient(x, i, j, columnIndices))
+        yield return sf2 * g;
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return sf2 * cov.GetCrossCovariance(x, xt, i, j, columnIndices);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSquaredExponentialArd.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSquaredExponentialArd.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSquaredExponentialArd.cs	(revision 8742)
@@ -0,0 +1,136 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceSquaredExponentialArd", Description = "Squared exponential covariance function with automatic relevance determination for Gaussian processes.")]
+  public sealed class CovarianceSquaredExponentialArd : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double sf2;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
+
+    [Storable]
+    private double[] inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleArray> inverseLengthParameter;
+    public IValueParameter<DoubleArray> InverseLengthParameter { get { return inverseLengthParameter; } }
+
+    [StorableConstructor]
+    private CovarianceSquaredExponentialArd(bool deserializing) : base(deserializing) { }
+    private CovarianceSquaredExponentialArd(CovarianceSquaredExponentialArd original, Cloner cloner)
+      : base(original, cloner) {
+      this.sf2 = original.sf2;
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+
+      if (original.inverseLength != null) {
+        this.inverseLength = new double[original.inverseLength.Length];
+        Array.Copy(original.inverseLength, this.inverseLength, this.inverseLength.Length);
+      }
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+
+      RegisterEvents();
+    }
+    public CovarianceSquaredExponentialArd()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the squared exponential covariance function with ARD.");
+      this.inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination.");
+
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceSquaredExponentialArd(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => {
+        inverseLength =
+          inverseLengthParameter.Value.ToArray();
+      });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (scaleParameter.Fixed ? 0 : 1) +
+        (inverseLengthParameter.Fixed ? 0 : numberOfVariables);
+    }
+
+
+    public void SetParameter(double[] hyp) {
+      int i = 0;
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleArray(hyp.Skip(i).Select(e => 1.0 / Math.Exp(e)).ToArray()));
+        i += hyp.Skip(i).Count();
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceSquaredExponentialArd", "hyp");
+    }
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+      return sf2 * Math.Exp(-d / 2.0);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+
+      for (int ii = 0; ii < inverseLength.Length; ii++) {
+        double sqrDist = Util.SqrDist(x[i, ii] * inverseLength[ii], x[j, ii] * inverseLength[ii]);
+        yield return sf2 * Math.Exp(-d / 2.0) * sqrDist;
+      }
+      yield return 2.0 * sf2 * Math.Exp(-d / 2.0);
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
+      return sf2 * Math.Exp(-d / 2.0);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSquaredExponentialIso.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSquaredExponentialIso.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSquaredExponentialIso.cs	(revision 8742)
@@ -0,0 +1,131 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceSquaredExponentialIso",
+    Description = "Isotropic squared exponential covariance function for Gaussian processes.")]
+  public sealed class CovarianceSquaredExponentialIso : ParameterizedNamedItem, ICovarianceFunction {
+    [Storable]
+    private double sf2;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> scaleParameter;
+    public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
+
+    [Storable]
+    private double inverseLength;
+    [Storable]
+    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
+    public IValueParameter<DoubleValue> InverseLengthParameter { get { return inverseLengthParameter; } }
+
+    [StorableConstructor]
+    private CovarianceSquaredExponentialIso(bool deserializing)
+      : base(deserializing) {
+    }
+
+    private CovarianceSquaredExponentialIso(CovarianceSquaredExponentialIso original, Cloner cloner)
+      : base(original, cloner) {
+      this.sf2 = original.sf2;
+      this.scaleParameter = cloner.Clone(original.scaleParameter);
+
+      this.inverseLength = original.inverseLength;
+      this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
+
+      RegisterEvents();
+    }
+
+    public CovarianceSquaredExponentialIso()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+
+      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric squared exponential covariance function.");
+      this.inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric squared exponential covariance function.");
+
+      Parameters.Add(scaleParameter);
+      Parameters.Add(inverseLengthParameter);
+
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceSquaredExponentialIso(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+      Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (scaleParameter.Fixed ? 0 : 1) +
+        (inverseLengthParameter.Fixed ? 0 : 1);
+    }
+
+    public void SetParameter(double[] hyp) {
+      int i = 0;
+      if (!inverseLengthParameter.Fixed) {
+        inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
+        i++;
+      }
+      if (!scaleParameter.Fixed) {
+        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
+        i++;
+      }
+      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceSquaredExponentialIso", "hyp");
+    }
+
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+      return sf2 * Math.Exp(-d / 2.0);
+    }
+
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+      double g = Math.Exp(-d / 2.0);
+      yield return sf2 * g * d;
+      yield return 2.0 * sf2 * g;
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
+      return sf2 * Math.Exp(-d / 2.0);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs	(revision 8742)
@@ -31,5 +31,5 @@
   [Item(Name = "CovarianceSum",
     Description = "Sum covariance function for Gaussian processes.")]
-  public class CovarianceSum : Item, ICovarianceFunction {
+  public sealed class CovarianceSum : Item, ICovarianceFunction {
     [Storable]
     private ItemList<ICovarianceFunction> terms;
@@ -42,13 +42,12 @@
 
     [StorableConstructor]
-    protected CovarianceSum(bool deserializing)
+    private CovarianceSum(bool deserializing)
       : base(deserializing) {
     }
 
-    protected CovarianceSum(CovarianceSum original, Cloner cloner)
+    private CovarianceSum(CovarianceSum original, Cloner cloner)
       : base(original, cloner) {
       this.terms = cloner.Clone(original.terms);
       this.numberOfVariables = original.numberOfVariables;
-      AttachEventHandlers();
     }
 
@@ -56,13 +55,4 @@
       : base() {
       this.terms = new ItemList<ICovarianceFunction>();
-      AttachEventHandlers();
-    }
-
-    private void AttachEventHandlers() {
-      this.terms.CollectionReset += (sender, args) => ClearCache();
-      this.terms.ItemsAdded += (sender, args) => ClearCache();
-      this.terms.ItemsRemoved += (sender, args) => ClearCache();
-      this.terms.ItemsReplaced += (sender, args) => ClearCache();
-      this.terms.ItemsMoved += (sender, args) => ClearCache();
     }
 
@@ -77,4 +67,5 @@
 
     public void SetParameter(double[] hyp) {
+      if (terms.Count == 0) throw new ArgumentException("At least one term is needed for sum covariance function.");
       int offset = 0;
       foreach (var t in terms) {
@@ -84,39 +75,15 @@
       }
     }
-    public void SetData(double[,] x) {
-      SetData(x, x);
+
+    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return terms.Select(t => t.GetCovariance(x, i, j, columnIndices)).Sum();
     }
 
-    public void SetData(double[,] x, double[,] xt) {
-      foreach (var t in terms) {
-        t.SetData(x, xt);
-      }
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+      return terms.Select(t => t.GetGradient(x, i, j, columnIndices)).Aggregate(Enumerable.Concat);
     }
 
-    public double GetCovariance(int i, int j) {
-      return terms.Select(t => t.GetCovariance(i, j)).Sum();
-    }
-
-    private Dictionary<int, Tuple<int, int>> cachedParameterMap;
-    public double GetGradient(int i, int j, int k) {
-      if (cachedParameterMap == null) {
-        CalculateParameterMap();
-      }
-      int ti = cachedParameterMap[k].Item1;
-      k = cachedParameterMap[k].Item2;
-      return terms[ti].GetGradient(i, j, k);
-    }
-    private void ClearCache() {
-      cachedParameterMap = null;
-    }
-
-    private void CalculateParameterMap() {
-      cachedParameterMap = new Dictionary<int, Tuple<int, int>>();
-      int k = 0;
-      for (int ti = 0; ti < terms.Count; ti++) {
-        for (int ti_k = 0; ti_k < terms[ti].GetNumberOfParameters(numberOfVariables); ti_k++) {
-          cachedParameterMap[k++] = Tuple.Create(ti, ti_k);
-        }
-      }
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+      return terms.Select(t => t.GetCrossCovariance(x, xt, i, j, columnIndices)).Sum();
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassification.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassification.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassification.cs	(revision 8742)
@@ -0,0 +1,196 @@
+
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Algorithms.GradientDescent;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  /// <summary>
+  /// Gaussian process least-squares classification data analysis algorithm.
+  /// </summary>
+  [Item("Gaussian Process Least-Squares Classification", "Gaussian process least-squares classification data analysis algorithm.")]
+  [Creatable("Data Analysis")]
+  [StorableClass]
+  public sealed class GaussianProcessClassification : EngineAlgorithm, IStorableContent {
+    public string Filename { get; set; }
+
+    public override Type ProblemType { get { return typeof(IClassificationProblem); } }
+    public new IClassificationProblem Problem {
+      get { return (IClassificationProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    private const string MeanFunctionParameterName = "MeanFunction";
+    private const string CovarianceFunctionParameterName = "CovarianceFunction";
+    private const string MinimizationIterationsParameterName = "Iterations";
+    private const string ApproximateGradientsParameterName = "ApproximateGradients";
+    private const string SeedParameterName = "Seed";
+    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
+
+    #region parameter properties
+    public IValueParameter<IMeanFunction> MeanFunctionParameter {
+      get { return (IValueParameter<IMeanFunction>)Parameters[MeanFunctionParameterName]; }
+    }
+    public IValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
+      get { return (IValueParameter<ICovarianceFunction>)Parameters[CovarianceFunctionParameterName]; }
+    }
+    public IValueParameter<IntValue> MinimizationIterationsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MinimizationIterationsParameterName]; }
+    }
+    public IValueParameter<IntValue> SeedParameter {
+      get { return (IValueParameter<IntValue>)Parameters[SeedParameterName]; }
+    }
+    public IValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (IValueParameter<BoolValue>)Parameters[SetSeedRandomlyParameterName]; }
+    }
+    #endregion
+    #region properties
+    public IMeanFunction MeanFunction {
+      set { MeanFunctionParameter.Value = value; }
+      get { return MeanFunctionParameter.Value; }
+    }
+    public ICovarianceFunction CovarianceFunction {
+      set { CovarianceFunctionParameter.Value = value; }
+      get { return CovarianceFunctionParameter.Value; }
+    }
+    public int MinimizationIterations {
+      set { MinimizationIterationsParameter.Value.Value = value; }
+      get { return MinimizationIterationsParameter.Value.Value; }
+    }
+    public int Seed { get { return SeedParameter.Value.Value; } set { SeedParameter.Value.Value = value; } }
+    public bool SetSeedRandomly { get { return SetSeedRandomlyParameter.Value.Value; } set { SetSeedRandomlyParameter.Value.Value = value; } }
+    #endregion
+
+    [StorableConstructor]
+    private GaussianProcessClassification(bool deserializing) : base(deserializing) { }
+    private GaussianProcessClassification(GaussianProcessClassification original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public GaussianProcessClassification()
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+
+      Problem = new ClassificationProblem();
+
+      Parameters.Add(new ValueParameter<IMeanFunction>(MeanFunctionParameterName, "The mean function to use.", new MeanConst()));
+      Parameters.Add(new ValueParameter<ICovarianceFunction>(CovarianceFunctionParameterName, "The covariance function to use.", new CovarianceSquaredExponentialIso()));
+      Parameters.Add(new ValueParameter<IntValue>(MinimizationIterationsParameterName, "The number of iterations for likelihood optimization with LM-BFGS.", new IntValue(20)));
+      Parameters.Add(new ValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new ValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+
+      Parameters.Add(new ValueParameter<BoolValue>(ApproximateGradientsParameterName, "Indicates that gradients should not be approximated (necessary for LM-BFGS).", new BoolValue(false)));
+      Parameters[ApproximateGradientsParameterName].Hidden = true; // should not be changed
+
+      var randomCreator = new HeuristicLab.Random.RandomCreator();
+      var gpInitializer = new GaussianProcessHyperparameterInitializer();
+      var bfgsInitializer = new LbfgsInitializer();
+      var makeStep = new LbfgsMakeStep();
+      var branch = new ConditionalBranch();
+      var modelCreator = new GaussianProcessClassificationModelCreator();
+      var updateResults = new LbfgsUpdateResults();
+      var analyzer = new LbfgsAnalyzer();
+      var finalModelCreator = new GaussianProcessClassificationModelCreator();
+      var finalAnalyzer = new LbfgsAnalyzer();
+      var solutionCreator = new GaussianProcessClassificationSolutionCreator();
+
+      OperatorGraph.InitialOperator = randomCreator;
+      randomCreator.SeedParameter.ActualName = SeedParameterName;
+      randomCreator.SeedParameter.Value = null;
+      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameterName;
+      randomCreator.SetSeedRandomlyParameter.Value = null;
+      randomCreator.Successor = gpInitializer;
+
+      gpInitializer.CovarianceFunctionParameter.ActualName = CovarianceFunctionParameterName;
+      gpInitializer.MeanFunctionParameter.ActualName = MeanFunctionParameterName;
+      gpInitializer.ProblemDataParameter.ActualName = Problem.ProblemDataParameter.Name;
+      gpInitializer.HyperparameterParameter.ActualName = modelCreator.HyperparameterParameter.Name;
+      gpInitializer.RandomParameter.ActualName = randomCreator.RandomParameter.Name;
+      gpInitializer.Successor = bfgsInitializer;
+
+      bfgsInitializer.IterationsParameter.ActualName = MinimizationIterationsParameterName;
+      bfgsInitializer.PointParameter.ActualName = modelCreator.HyperparameterParameter.Name;
+      bfgsInitializer.ApproximateGradientsParameter.ActualName = ApproximateGradientsParameterName;
+      bfgsInitializer.Successor = makeStep;
+
+      makeStep.StateParameter.ActualName = bfgsInitializer.StateParameter.Name;
+      makeStep.PointParameter.ActualName = modelCreator.HyperparameterParameter.Name;
+      makeStep.Successor = branch;
+
+      branch.ConditionParameter.ActualName = makeStep.TerminationCriterionParameter.Name;
+      branch.FalseBranch = modelCreator;
+      branch.TrueBranch = finalModelCreator;
+
+      modelCreator.ProblemDataParameter.ActualName = Problem.ProblemDataParameter.Name;
+      modelCreator.MeanFunctionParameter.ActualName = MeanFunctionParameterName;
+      modelCreator.CovarianceFunctionParameter.ActualName = CovarianceFunctionParameterName;
+      modelCreator.Successor = updateResults;
+
+      updateResults.StateParameter.ActualName = bfgsInitializer.StateParameter.Name;
+      updateResults.QualityParameter.ActualName = modelCreator.NegativeLogLikelihoodParameter.Name;
+      updateResults.QualityGradientsParameter.ActualName = modelCreator.HyperparameterGradientsParameter.Name;
+      updateResults.ApproximateGradientsParameter.ActualName = ApproximateGradientsParameterName;
+      updateResults.Successor = analyzer;
+
+      analyzer.QualityParameter.ActualName = modelCreator.NegativeLogLikelihoodParameter.Name;
+      analyzer.PointParameter.ActualName = modelCreator.HyperparameterParameter.Name;
+      analyzer.QualityGradientsParameter.ActualName = modelCreator.HyperparameterGradientsParameter.Name;
+      analyzer.StateParameter.ActualName = bfgsInitializer.StateParameter.Name;
+      analyzer.PointsTableParameter.ActualName = "Hyperparameter table";
+      analyzer.QualityGradientsTableParameter.ActualName = "Gradients table";
+      analyzer.QualitiesTableParameter.ActualName = "Negative log likelihood table";
+      analyzer.Successor = makeStep;
+
+      finalModelCreator.ProblemDataParameter.ActualName = Problem.ProblemDataParameter.Name;
+      finalModelCreator.MeanFunctionParameter.ActualName = MeanFunctionParameterName;
+      finalModelCreator.CovarianceFunctionParameter.ActualName = CovarianceFunctionParameterName;
+      finalModelCreator.HyperparameterParameter.ActualName = bfgsInitializer.PointParameter.ActualName;
+      finalModelCreator.Successor = finalAnalyzer;
+
+      finalAnalyzer.QualityParameter.ActualName = modelCreator.NegativeLogLikelihoodParameter.Name;
+      finalAnalyzer.PointParameter.ActualName = modelCreator.HyperparameterParameter.Name;
+      finalAnalyzer.QualityGradientsParameter.ActualName = modelCreator.HyperparameterGradientsParameter.Name;
+      finalAnalyzer.PointsTableParameter.ActualName = analyzer.PointsTableParameter.ActualName;
+      finalAnalyzer.QualityGradientsTableParameter.ActualName = analyzer.QualityGradientsTableParameter.ActualName;
+      finalAnalyzer.QualitiesTableParameter.ActualName = analyzer.QualitiesTableParameter.ActualName;
+      finalAnalyzer.Successor = solutionCreator;
+
+      solutionCreator.ModelParameter.ActualName = finalModelCreator.ModelParameter.Name;
+      solutionCreator.ProblemDataParameter.ActualName = Problem.ProblemDataParameter.Name;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GaussianProcessClassification(this, cloner);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassificationModelCreator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassificationModelCreator.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassificationModelCreator.cs	(revision 8742)
@@ -0,0 +1,81 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "GaussianProcessClassificationModelCreator",
+    Description = "Creates a Gaussian process model for least-squares classification given the data, the hyperparameters, a mean function, and a covariance function.")]
+  public sealed class GaussianProcessClassificationModelCreator : GaussianProcessModelCreator {
+    private const string ProblemDataParameterName = "ProblemData";
+
+    #region Parameter Properties
+    public ILookupParameter<IClassificationProblemData> ProblemDataParameter {
+      get { return (ILookupParameter<IClassificationProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+    private IClassificationProblemData ProblemData {
+      get { return ProblemDataParameter.ActualValue; }
+    }
+    #endregion
+    [StorableConstructor]
+    private GaussianProcessClassificationModelCreator(bool deserializing) : base(deserializing) { }
+    private GaussianProcessClassificationModelCreator(GaussianProcessClassificationModelCreator original, Cloner cloner) : base(original, cloner) { }
+    public GaussianProcessClassificationModelCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<IClassificationProblemData>(ProblemDataParameterName, "The classification problem data for the Gaussian process model."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GaussianProcessClassificationModelCreator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      try {
+        var model = Create(ProblemData, Hyperparameter.ToArray(), MeanFunction, CovarianceFunction);
+        ModelParameter.ActualValue = model;
+        NegativeLogLikelihoodParameter.ActualValue = new DoubleValue(model.NegativeLogLikelihood);
+        HyperparameterGradientsParameter.ActualValue = new RealVector(model.HyperparameterGradients);
+        return base.Apply();
+      }
+      catch (ArgumentException) { }
+      catch (alglib.alglibexception) { }
+      NegativeLogLikelihoodParameter.ActualValue = new DoubleValue(1E300);
+      HyperparameterGradientsParameter.ActualValue = new RealVector(Hyperparameter.Count());
+      return base.Apply();
+    }
+
+    public static IGaussianProcessModel Create(IClassificationProblemData problemData, double[] hyperparameter, IMeanFunction meanFunction, ICovarianceFunction covarianceFunction) {
+      return new GaussianProcessModel(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, hyperparameter, meanFunction, covarianceFunction);
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassificationSolutionCreator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassificationSolutionCreator.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassificationSolutionCreator.cs	(revision 8742)
@@ -0,0 +1,103 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "GaussianProcessClassificationSolutionCreator",
+    Description = "Creates a Gaussian process solution from a trained model.")]
+  public sealed class GaussianProcessClassificationSolutionCreator : SingleSuccessorOperator {
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string ModelParameterName = "GaussianProcessClassificationModel";
+    private const string SolutionParameterName = "Solution";
+    private const string ResultsParameterName = "Results";
+    private const string TrainingAccuracyResultName = "Accuracy (training)";
+    private const string TestAccuracyResultName = "Accuracy (test)";
+
+    #region Parameter Properties
+    public ILookupParameter<IClassificationProblemData> ProblemDataParameter {
+      get { return (ILookupParameter<IClassificationProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    public ILookupParameter<IDiscriminantFunctionClassificationSolution> SolutionParameter {
+      get { return (ILookupParameter<IDiscriminantFunctionClassificationSolution>)Parameters[SolutionParameterName]; }
+    }
+    public ILookupParameter<IGaussianProcessModel> ModelParameter {
+      get { return (ILookupParameter<IGaussianProcessModel>)Parameters[ModelParameterName]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private GaussianProcessClassificationSolutionCreator(bool deserializing) : base(deserializing) { }
+    private GaussianProcessClassificationSolutionCreator(GaussianProcessClassificationSolutionCreator original, Cloner cloner) : base(original, cloner) { }
+    public GaussianProcessClassificationSolutionCreator()
+      : base() {
+      // in
+      Parameters.Add(new LookupParameter<IClassificationProblemData>(ProblemDataParameterName, "The classification problem data for the Gaussian process solution."));
+      Parameters.Add(new LookupParameter<IGaussianProcessModel>(ModelParameterName, "The Gaussian process classification model to use for the solution."));
+      // in & out
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The result collection of the algorithm."));
+      // out
+      Parameters.Add(new LookupParameter<IDiscriminantFunctionClassificationSolution>(SolutionParameterName, "The produced Gaussian process solution."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GaussianProcessClassificationSolutionCreator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      if (ModelParameter.ActualValue != null) {
+        var m = (IGaussianProcessModel)ModelParameter.ActualValue.Clone();
+        var data = (IClassificationProblemData)ProblemDataParameter.ActualValue.Clone();
+        var model = new DiscriminantFunctionClassificationModel(m, new NormalDistributionCutPointsThresholdCalculator());
+        model.RecalculateModelParameters(data, data.TrainingIndices);
+        var s = model.CreateDiscriminantFunctionClassificationSolution(data);
+
+        SolutionParameter.ActualValue = s;
+        var results = ResultsParameter.ActualValue;
+        if (!results.ContainsKey(SolutionParameterName)) {
+          results.Add(new Result(SolutionParameterName, "The Gaussian process classification solution", s));
+          results.Add(new Result(TrainingAccuracyResultName,
+                                 "The accuracy of the Gaussian process solution on the training partition.",
+                                 new DoubleValue(s.TrainingAccuracy)));
+          results.Add(new Result(TestAccuracyResultName,
+                                 "The accuracy of the Gaussian process solution on the test partition.",
+                                 new DoubleValue(s.TestAccuracy)));
+        } else {
+          results[SolutionParameterName].Value = s;
+          results[TrainingAccuracyResultName].Value = new DoubleValue(s.TrainingAccuracy);
+          results[TestAccuracyResultName].Value = new DoubleValue(s.TestAccuracy);
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessHyperparameterInitializer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessHyperparameterInitializer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessHyperparameterInitializer.cs	(revision 8742)
@@ -91,5 +91,5 @@
       var rand = RandomParameter.ActualValue;
       for (int i = 0; i < r.Length; i++)
-        r[i] = rand.NextDouble() * 2 - 1;
+        r[i] = rand.NextDouble() * 10 - 5;
 
       HyperparameterParameter.ActualValue = r;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 8742)
@@ -42,4 +42,14 @@
 
     [Storable]
+    private double[] hyperparameterGradients;
+    public double[] HyperparameterGradients {
+      get {
+        var copy = new double[hyperparameterGradients.Length];
+        Array.Copy(hyperparameterGradients, copy, copy.Length);
+        return copy;
+      }
+    }
+
+    [Storable]
     private ICovarianceFunction covarianceFunction;
     public ICovarianceFunction CovarianceFunction {
@@ -66,4 +76,7 @@
     [Storable]
     private double sqrSigmaNoise;
+    public double SigmaNoise {
+      get { return Math.Sqrt(sqrSigmaNoise); }
+    }
 
     [Storable]
@@ -124,12 +137,9 @@
       l = new double[n, n];
 
-      meanFunction.SetData(x);
-      covarianceFunction.SetData(x);
-
       // calculate means and covariances
       double[] m = meanFunction.GetMean(x);
       for (int i = 0; i < n; i++) {
         for (int j = i; j < n; j++) {
-          l[j, i] = covarianceFunction.GetCovariance(i, j) / sqrSigmaNoise;
+          l[j, i] = covarianceFunction.GetCovariance(x, i, j) / sqrSigmaNoise;
           if (j == i) l[j, i] += 1.0;
         }
@@ -153,12 +163,8 @@
         alpha[i] = alpha[i] / sqrSigmaNoise;
       negativeLogLikelihood = 0.5 * Util.ScalarProd(ym, alpha) + diagSum + (n / 2.0) * Math.Log(2.0 * Math.PI * sqrSigmaNoise);
-    }
-
-    public double[] GetHyperparameterGradients() {
+
       // derivatives
-      int n = x.GetLength(0);
       int nAllowedVariables = x.GetLength(1);
 
-      int info;
       alglib.matinvreport matInvRep;
       double[,] lCopy = new double[l.GetLength(0), l.GetLength(1)];
@@ -183,17 +189,24 @@
       if (covGradients.Length > 0) {
         for (int i = 0; i < n; i++) {
+          for (int j = 0; j < i; j++) {
+            var g = covarianceFunction.GetGradient(x, i, j).ToArray();
+            for (int k = 0; k < covGradients.Length; k++) {
+              covGradients[k] += lCopy[i, j] * g[k];
+            }
+          }
+
+          var gDiag = covarianceFunction.GetGradient(x, i, i).ToArray();
           for (int k = 0; k < covGradients.Length; k++) {
-            for (int j = 0; j < i; j++) {
-              covGradients[k] += lCopy[i, j] * covarianceFunction.GetGradient(i, j, k);
-            }
-            covGradients[k] += 0.5 * lCopy[i, i] * covarianceFunction.GetGradient(i, i, k);
+            // diag
+            covGradients[k] += 0.5 * lCopy[i, i] * gDiag[k];
           }
         }
       }
 
-      return
+      hyperparameterGradients =
         meanGradients
         .Concat(covGradients)
         .Concat(new double[] { noiseGradient }).ToArray();
+
     }
 
@@ -208,5 +221,5 @@
     }
     public GaussianProcessRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new GaussianProcessRegressionSolution(this, problemData);
+      return new GaussianProcessRegressionSolution(this, new RegressionProblemData(problemData));
     }
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
@@ -214,4 +227,5 @@
     }
     #endregion
+
 
     private IEnumerable<double> GetEstimatedValuesHelper(Dataset dataset, IEnumerable<int> rows) {
@@ -219,40 +233,14 @@
       int newN = newX.GetLength(0);
       int n = x.GetLength(0);
-      // var predMean = new double[newN];
-      // predVar = new double[newN];
-
-
-
-      // var kss = new double[newN];
       var Ks = new double[newN, n];
-      //double[,] sWKs = new double[n, newN];
-      // double[,] v;
-
-
-      // for stddev 
-      //covarianceFunction.SetParameter(covHyp, newX);
-      //kss = covarianceFunction.GetDiagonalCovariances();
-
-      covarianceFunction.SetData(x, newX);
-      meanFunction.SetData(newX);
       var ms = meanFunction.GetMean(newX);
       for (int i = 0; i < newN; i++) {
         for (int j = 0; j < n; j++) {
-          Ks[i, j] = covarianceFunction.GetCovariance(j, i);
-          //sWKs[j, i] = Ks[i, j] / Math.Sqrt(sqrSigmaNoise);
-        }
-      }
-
-      // for stddev 
-      // alglib.rmatrixsolvem(l, n, sWKs, newN, true, out info, out denseSolveRep, out v);
+          Ks[i, j] = covarianceFunction.GetCrossCovariance(x, newX, j, i);
+        }
+      }
 
       return Enumerable.Range(0, newN)
         .Select(i => ms[i] + Util.ScalarProd(Util.GetRow(Ks, i), alpha));
-      //for (int i = 0; i < newN; i++) {
-      //  // predMean[i] = ms[i] + prod(GetRow(Ks, i), alpha);
-      //  // var sumV2 = prod(GetCol(v, i), GetCol(v, i));
-      //  // predVar[i] = kss[i] - sumV2;
-      //}
-
     }
 
@@ -266,24 +254,18 @@
 
       // for stddev 
-      covarianceFunction.SetData(newX);
       for (int i = 0; i < newN; i++)
-        kss[i] = covarianceFunction.GetCovariance(i, i);
-
-      covarianceFunction.SetData(x, newX);
+        kss[i] = covarianceFunction.GetCovariance(newX, i, i);
+
       for (int i = 0; i < newN; i++) {
         for (int j = 0; j < n; j++) {
-          sWKs[j, i] = covarianceFunction.GetCovariance(j, i) / Math.Sqrt(sqrSigmaNoise);
+          sWKs[j, i] = covarianceFunction.GetCrossCovariance(x, newX, j, i) / Math.Sqrt(sqrSigmaNoise);
         }
       }
 
       // for stddev 
-      int info;
-      alglib.densesolverreport denseSolveRep;
-      double[,] v;
-
-      alglib.rmatrixsolvem(l, n, sWKs, newN, false, out info, out denseSolveRep, out v);
+      alglib.ablas.rmatrixlefttrsm(n, newN, l, 0, 0, false, false, 0, ref sWKs, 0, 0);
 
       for (int i = 0; i < newN; i++) {
-        var sumV = Util.ScalarProd(Util.GetCol(v, i), Util.GetCol(v, i));
+        var sumV = Util.ScalarProd(Util.GetCol(sWKs, i), Util.GetCol(sWKs, i));
         kss[i] -= sumV;
         if (kss[i] < 0) kss[i] = 0;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegression.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegression.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegression.cs	(revision 8742)
@@ -22,6 +22,4 @@
 
 using System;
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Algorithms.GradientDescent;
 using HeuristicLab.Common;
@@ -32,5 +30,4 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.PluginInfrastructure;
 using HeuristicLab.Problems.DataAnalysis;
 
@@ -59,9 +56,9 @@
 
     #region parameter properties
-    public IConstrainedValueParameter<IMeanFunction> MeanFunctionParameter {
-      get { return (IConstrainedValueParameter<IMeanFunction>)Parameters[MeanFunctionParameterName]; }
+    public IValueParameter<IMeanFunction> MeanFunctionParameter {
+      get { return (IValueParameter<IMeanFunction>)Parameters[MeanFunctionParameterName]; }
     }
-    public IConstrainedValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
-      get { return (IConstrainedValueParameter<ICovarianceFunction>)Parameters[CovarianceFunctionParameterName]; }
+    public IValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
+      get { return (IValueParameter<ICovarianceFunction>)Parameters[CovarianceFunctionParameterName]; }
     }
     public IValueParameter<IntValue> MinimizationIterationsParameter {
@@ -104,11 +101,6 @@
       Problem = new RegressionProblem();
 
-      List<IMeanFunction> meanFunctions = ApplicationManager.Manager.GetInstances<IMeanFunction>().ToList();
-      List<ICovarianceFunction> covFunctions = ApplicationManager.Manager.GetInstances<ICovarianceFunction>().ToList();
-
-      Parameters.Add(new ConstrainedValueParameter<IMeanFunction>(MeanFunctionParameterName, "The mean function to use.",
-        new ItemSet<IMeanFunction>(meanFunctions), meanFunctions.OfType<MeanConst>().First()));
-      Parameters.Add(new ConstrainedValueParameter<ICovarianceFunction>(CovarianceFunctionParameterName, "The covariance function to use.",
-        new ItemSet<ICovarianceFunction>(covFunctions), covFunctions.OfType<CovarianceSEiso>().First()));
+      Parameters.Add(new ValueParameter<IMeanFunction>(MeanFunctionParameterName, "The mean function to use.", new MeanConst()));
+      Parameters.Add(new ValueParameter<ICovarianceFunction>(CovarianceFunctionParameterName, "The covariance function to use.", new CovarianceSquaredExponentialIso()));
       Parameters.Add(new ValueParameter<IntValue>(MinimizationIterationsParameterName, "The number of iterations for likelihood optimization with LM-BFGS.", new IntValue(20)));
       Parameters.Add(new ValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionModelCreator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionModelCreator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionModelCreator.cs	(revision 8742)
@@ -65,5 +65,5 @@
         ModelParameter.ActualValue = model;
         NegativeLogLikelihoodParameter.ActualValue = new DoubleValue(model.NegativeLogLikelihood);
-        HyperparameterGradientsParameter.ActualValue = new RealVector(model.GetHyperparameterGradients());
+        HyperparameterGradientsParameter.ActualValue = new RealVector(model.HyperparameterGradients);
         return base.Apply();
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionSolution.cs	(revision 8742)
@@ -34,4 +34,5 @@
   [StorableClass]
   public sealed class GaussianProcessRegressionSolution : RegressionSolution, IGaussianProcessSolution {
+    private new readonly Dictionary<int, double> evaluationCache;
 
     public new IGaussianProcessModel Model {
@@ -41,10 +42,17 @@
 
     [StorableConstructor]
-    private GaussianProcessRegressionSolution(bool deserializing) : base(deserializing) { }
+    private GaussianProcessRegressionSolution(bool deserializing)
+      : base(deserializing) {
+      evaluationCache = new Dictionary<int, double>();
+
+    }
     private GaussianProcessRegressionSolution(GaussianProcessRegressionSolution original, Cloner cloner)
       : base(original, cloner) {
+      evaluationCache = new Dictionary<int, double>(original.evaluationCache);
     }
     public GaussianProcessRegressionSolution(IGaussianProcessModel model, IRegressionProblemData problemData)
       : base(model, problemData) {
+
+      evaluationCache = new Dictionary<int, double>(problemData.Dataset.Rows);
       RecalculateResults();
     }
@@ -65,5 +73,22 @@
 
     public IEnumerable<double> GetEstimatedVariance(IEnumerable<int> rows) {
-      return Model.GetEstimatedVariance(ProblemData.Dataset, rows);
+      var rowsToEvaluate = rows.Except(evaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = Model.GetEstimatedVariance(ProblemData.Dataset, rowsToEvaluate).GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        evaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => evaluationCache[row]);
+    }
+
+    protected override void OnModelChanged() {
+      evaluationCache.Clear();
+      base.OnModelChanged();
+    }
+    protected override void OnProblemDataChanged() {
+      evaluationCache.Clear();
+      base.OnProblemDataChanged();
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionSolutionCreator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionSolutionCreator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionSolutionCreator.cs	(revision 8742)
@@ -75,19 +75,25 @@
 
     public override IOperation Apply() {
-      var m = (IGaussianProcessModel)ModelParameter.ActualValue.Clone();
-      var data = (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone();
-      var s = new GaussianProcessRegressionSolution(m, data);
+      if (ModelParameter.ActualValue != null) {
+        var m = (IGaussianProcessModel)ModelParameter.ActualValue.Clone();
+        var data = (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone();
+        var s = new GaussianProcessRegressionSolution(m, data);
 
 
-      SolutionParameter.ActualValue = s;
-      var results = ResultsParameter.ActualValue;
-      if (!results.ContainsKey(SolutionParameterName)) {
-        results.Add(new Result(SolutionParameterName, "The Gaussian process regression solution", s));
-        results.Add(new Result(TrainingRSquaredResultName, "The Pearson's R² of the Gaussian process solution on the training partition.", new DoubleValue(s.TrainingRSquared)));
-        results.Add(new Result(TestRSquaredResultName, "The Pearson's R² of the Gaussian process solution on the test partition.", new DoubleValue(s.TestRSquared)));
-      } else {
-        results[SolutionParameterName].Value = s;
-        results[TrainingRSquaredResultName].Value = new DoubleValue(s.TrainingRSquared);
-        results[TestRSquaredResultName].Value = new DoubleValue(s.TestRSquared);
+        SolutionParameter.ActualValue = s;
+        var results = ResultsParameter.ActualValue;
+        if (!results.ContainsKey(SolutionParameterName)) {
+          results.Add(new Result(SolutionParameterName, "The Gaussian process regression solution", s));
+          results.Add(new Result(TrainingRSquaredResultName,
+                                 "The Pearson's R² of the Gaussian process solution on the training partition.",
+                                 new DoubleValue(s.TrainingRSquared)));
+          results.Add(new Result(TestRSquaredResultName,
+                                 "The Pearson's R² of the Gaussian process solution on the test partition.",
+                                 new DoubleValue(s.TestRSquared)));
+        } else {
+          results[SolutionParameterName].Value = s;
+          results[TrainingRSquaredResultName].Value = new DoubleValue(s.TrainingRSquared);
+          results[TestRSquaredResultName].Value = new DoubleValue(s.TestRSquared);
+        }
       }
       return base.Apply();
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/HyperParameter.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/HyperParameter.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/HyperParameter.cs	(revision 8742)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "HyperParameter", Description = "Represents a hyperparameter for Gaussian processes.")]
+  internal class HyperParameter<T> : OptionalValueParameter<T>, IValueParameter<T> where T : class, IItem {
+
+    [Storable]
+    private bool @fixed = false;
+
+    public bool Fixed {
+      get { return @fixed; }
+    }
+
+    [StorableConstructor]
+    protected HyperParameter(bool deserializing)
+      : base(deserializing) {
+    }
+
+    protected HyperParameter(HyperParameter<T> original, Cloner cloner)
+      : base(original, cloner) {
+      this.@fixed = original.@fixed;
+    }
+
+    public HyperParameter() : base("HyperParameter", "Represents a hyperparameter for Gaussian processes.") { }
+
+    public HyperParameter(string name, string description)
+      : base(name, description) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HyperParameter<T>(this, cloner);
+    }
+
+    // if a value is set through this property then we fix the value of the hyperparameter 
+    public override T Value {
+      get {
+        return base.Value;
+      }
+      set {
+        base.Value = value;
+        @fixed = value != null;
+      }
+    }
+
+    // in the optimization we are allowed to set the value of non-fixed parameters
+    public void SetValue(T value) {
+      if (@fixed) throw new InvalidOperationException("Can't set the value of a fixed hyperparameter");
+      base.Value = value;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/ICovarianceFunction.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/ICovarianceFunction.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/ICovarianceFunction.cs	(revision 8742)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using HeuristicLab.Core;
 
@@ -26,9 +27,7 @@
     int GetNumberOfParameters(int numberOfVariables);
     void SetParameter(double[] hyp);
-    void SetData(double[,] x);
-    void SetData(double[,] x, double[,] xt);
-
-    double GetCovariance(int i, int j);
-    double GetGradient(int i, int j, int k);
+    double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices = null);
+    IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices = null);
+    double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices = null);
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/IMeanFunction.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/IMeanFunction.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/IMeanFunction.cs	(revision 8742)
@@ -25,5 +25,4 @@
     int GetNumberOfParameters(int numberOfVariables);
     void SetParameter(double[] hyp);
-    void SetData(double[,] x);
     double[] GetMean(double[,] x);
     double[] GetGradients(int k, double[,] x);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanConst.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanConst.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanConst.cs	(revision 8742)
@@ -24,4 +24,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -29,28 +30,51 @@
   [StorableClass]
   [Item(Name = "MeanConst", Description = "Constant mean function for Gaussian processes.")]
-  public class MeanConst : Item, IMeanFunction {
+  public sealed class MeanConst : ParameterizedNamedItem, IMeanFunction {
     [Storable]
     private double c;
-    public double Value { get { return c; } }
+    [Storable]
+    private readonly HyperParameter<DoubleValue> valueParameter;
+    public IValueParameter<DoubleValue> ValueParameter { get { return valueParameter; } }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return 1;
-    }
     [StorableConstructor]
-    protected MeanConst(bool deserializing) : base(deserializing) { }
-    protected MeanConst(MeanConst original, Cloner cloner)
+    private MeanConst(bool deserializing) : base(deserializing) { }
+    private MeanConst(MeanConst original, Cloner cloner)
       : base(original, cloner) {
       this.c = original.c;
+      this.valueParameter = cloner.Clone(original.valueParameter);
+      RegisterEvents();
     }
     public MeanConst()
       : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+
+      this.valueParameter = new HyperParameter<DoubleValue>("Value", "The constant value for the constant mean function.");
+      Parameters.Add(valueParameter);
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanConst(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachValueChangeHandler<DoubleValue, double>(valueParameter, () => { c = valueParameter.Value.Value; });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return valueParameter.Fixed ? 0 : 1;
     }
 
     public void SetParameter(double[] hyp) {
-      if (hyp.Length != 1) throw new ArgumentException("Only one hyper-parameter allowed for constant mean function.", "hyp");
-      this.c = hyp[0];
-    }
-    public void SetData(double[,] x) {
-      // nothing to do
+      if (!valueParameter.Fixed) {
+        valueParameter.SetValue(new DoubleValue(hyp[0]));
+      } else if (hyp.Length > 0)
+        throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for the constant mean function.", "hyp");
     }
 
@@ -63,8 +87,4 @@
       return Enumerable.Repeat(1.0, x.GetLength(0)).ToArray();
     }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanConst(this, cloner);
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanLinear.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanLinear.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanLinear.cs	(revision 8742)
@@ -19,8 +19,10 @@
  */
 #endregion
+
 using System;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -28,48 +30,62 @@
   [StorableClass]
   [Item(Name = "MeanLinear", Description = "Linear mean function for Gaussian processes.")]
-  public class MeanLinear : Item, IMeanFunction {
+  public sealed class MeanLinear : ParameterizedNamedItem, IMeanFunction {
     [Storable]
-    private double[] alpha;
-    public double[] Weights {
-      get {
-        if (alpha == null) return new double[0];
-        var copy = new double[alpha.Length];
-        Array.Copy(alpha, copy, copy.Length);
-        return copy;
+    private double[] weights;
+    [Storable]
+    private readonly HyperParameter<DoubleArray> weightsParameter;
+    public IValueParameter<DoubleArray> WeightsParameter { get { return weightsParameter; } }
+
+    [StorableConstructor]
+    private MeanLinear(bool deserializing) : base(deserializing) { }
+    private MeanLinear(MeanLinear original, Cloner cloner)
+      : base(original, cloner) {
+      if (original.weights != null) {
+        this.weights = new double[original.weights.Length];
+        Array.Copy(original.weights, weights, original.weights.Length);
       }
-    }
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return numberOfVariables;
-    }
-    [StorableConstructor]
-    protected MeanLinear(bool deserializing) : base(deserializing) { }
-    protected MeanLinear(MeanLinear original, Cloner cloner)
-      : base(original, cloner) {
-      if (original.alpha != null) {
-        this.alpha = new double[original.alpha.Length];
-        Array.Copy(original.alpha, alpha, original.alpha.Length);
-      }
+      weightsParameter = cloner.Clone(original.weightsParameter);
+      RegisterEvents();
     }
     public MeanLinear()
       : base() {
+      this.weightsParameter = new HyperParameter<DoubleArray>("Weights", "The weights parameter for the linear mean function.");
+      Parameters.Add(weightsParameter);
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanLinear(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      Util.AttachArrayChangeHandler<DoubleArray, double>(weightsParameter, () => {
+        weights = weightsParameter.Value.ToArray();
+      });
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return weightsParameter.Fixed ? 0 : numberOfVariables;
     }
 
     public void SetParameter(double[] hyp) {
-      this.alpha = new double[hyp.Length];
-      Array.Copy(hyp, alpha, hyp.Length);
-    }
-    public void SetData(double[,] x) {
-      // nothing to do
+      if (!weightsParameter.Fixed) {
+        weightsParameter.SetValue(new DoubleArray(hyp));
+      } else if (hyp.Length != 0) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for the linear mean function.", "hyp");
     }
 
     public double[] GetMean(double[,] x) {
       // sanity check
-      if (alpha.Length != x.GetLength(1)) throw new ArgumentException("The number of hyperparameters must match the number of variables for the linear mean function.");
+      if (weights.Length != x.GetLength(1)) throw new ArgumentException("The number of hyperparameters must match the number of variables for the linear mean function.");
       int cols = x.GetLength(1);
       int n = x.GetLength(0);
       return (from i in Enumerable.Range(0, n)
-              let rowVector = from j in Enumerable.Range(0, cols)
-                              select x[i, j]
-              select Util.ScalarProd(alpha, rowVector))
+              let rowVector = Enumerable.Range(0, cols).Select(j => x[i, j])
+              select Util.ScalarProd(weights, rowVector))
         .ToArray();
     }
@@ -79,10 +95,5 @@
       int n = x.GetLength(0);
       if (k > cols) throw new ArgumentException();
-      return (from r in Enumerable.Range(0, n)
-              select x[r, k]).ToArray();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanLinear(this, cloner);
+      return (Enumerable.Range(0, n).Select(r => x[r, k])).ToArray();
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanProduct.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanProduct.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanProduct.cs	(revision 8742)
@@ -0,0 +1,104 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "MeanProduct", Description = "Product of mean functions for Gaussian processes.")]
+  public sealed class MeanProduct : Item, IMeanFunction {
+    [Storable]
+    private ItemList<IMeanFunction> factors;
+
+    [Storable]
+    private int numberOfVariables;
+
+    public ItemList<IMeanFunction> Factors {
+      get { return factors; }
+    }
+
+    [StorableConstructor]
+    private MeanProduct(bool deserializing)
+      : base(deserializing) {
+    }
+
+    private MeanProduct(MeanProduct original, Cloner cloner)
+      : base(original, cloner) {
+      this.factors = cloner.Clone(original.factors);
+      this.numberOfVariables = original.numberOfVariables;
+    }
+
+    public MeanProduct() {
+      this.factors = new ItemList<IMeanFunction>();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanProduct(this, cloner);
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      this.numberOfVariables = numberOfVariables;
+      return factors.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();
+    }
+
+    public void SetParameter(double[] hyp) {
+      int offset = 0;
+      foreach (var t in factors) {
+        var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);
+        t.SetParameter(hyp.Skip(offset).Take(numberOfParameters).ToArray());
+        offset += numberOfParameters;
+      }
+    }
+
+    public double[] GetMean(double[,] x) {
+      var res = factors.First().GetMean(x);
+      foreach (var t in factors.Skip(1)) {
+        var a = t.GetMean(x);
+        for (int i = 0; i < res.Length; i++) res[i] *= a[i];
+      }
+      return res;
+    }
+
+    public double[] GetGradients(int k, double[,] x) {
+      double[] res = Enumerable.Repeat(1.0, x.GetLength(0)).ToArray();
+      // find index of factor for the given k
+      int j = 0;
+      while (k >= factors[j].GetNumberOfParameters(numberOfVariables)) {
+        k -= factors[j].GetNumberOfParameters(numberOfVariables);
+        j++;
+      }
+      for (int i = 0; i < factors.Count; i++) {
+        var f = factors[i];
+        if (i == j) {
+          // multiply gradient
+          var g = f.GetGradients(k, x);
+          for (int ii = 0; ii < res.Length; ii++) res[ii] *= g[ii];
+        } else {
+          // multiply mean
+          var m = f.GetMean(x);
+          for (int ii = 0; ii < res.Length; ii++) res[ii] *= m[ii];
+        }
+      }
+      return res;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanSum.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanSum.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanSum.cs	(revision 8742)
@@ -27,5 +27,5 @@
   [StorableClass]
   [Item(Name = "MeanSum", Description = "Sum of mean functions for Gaussian processes.")]
-  public class MeanSum : Item, IMeanFunction {
+  public sealed class MeanSum : Item, IMeanFunction {
     [Storable]
     private ItemList<IMeanFunction> terms;
@@ -37,11 +37,7 @@
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      this.numberOfVariables = numberOfVariables;
-      return terms.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();
-    }
     [StorableConstructor]
-    protected MeanSum(bool deserializing) : base(deserializing) { }
-    protected MeanSum(MeanSum original, Cloner cloner)
+    private MeanSum(bool deserializing) : base(deserializing) { }
+    private MeanSum(MeanSum original, Cloner cloner)
       : base(original, cloner) {
       this.terms = cloner.Clone(original.terms);
@@ -50,4 +46,13 @@
     public MeanSum() {
       this.terms = new ItemList<IMeanFunction>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanSum(this, cloner);
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      this.numberOfVariables = numberOfVariables;
+      return terms.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();
     }
 
@@ -59,8 +64,4 @@
         offset += numberOfParameters;
       }
-    }
-
-    public void SetData(double[,] x) {
-      foreach (var t in terms) t.SetData(x);
     }
 
@@ -82,8 +83,4 @@
       return terms[i].GetGradients(k, x);
     }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanSum(this, cloner);
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanZero.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanZero.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanZero.cs	(revision 8742)
@@ -28,11 +28,8 @@
   [StorableClass]
   [Item(Name = "MeanZero", Description = "Constant zero mean function for Gaussian processes.")]
-  public class MeanZero : Item, IMeanFunction {
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return 0;
-    }
+  public sealed class MeanZero : Item, IMeanFunction {
     [StorableConstructor]
-    protected MeanZero(bool deserializing) : base(deserializing) { }
-    protected MeanZero(MeanZero original, Cloner cloner)
+    private MeanZero(bool deserializing) : base(deserializing) { }
+    private MeanZero(MeanZero original, Cloner cloner)
       : base(original, cloner) {
     }
@@ -40,10 +37,14 @@
     }
 
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MeanZero(this, cloner);
+    }
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return 0;
+    }
+
     public void SetParameter(double[] hyp) {
       if (hyp.Length > 0) throw new ArgumentException("No hyper-parameters allowed for zero mean function.", "hyp");
-    }
-
-    public void SetData(double[,] x) {
-      // do nothing
     }
 
@@ -56,7 +57,4 @@
       return Enumerable.Repeat(0.0, x.GetLength(0)).ToArray();
     }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new MeanZero(this, cloner);
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/Util.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/Util.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/Util.cs	(revision 8742)
@@ -20,11 +20,18 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
-  public static class Util {
+  internal static class Util {
     public static double ScalarProd(IEnumerable<double> v, IEnumerable<double> u) {
       return v.Zip(u, (vi, ui) => vi * ui).Sum();
+    }
+
+    public static double SqrDist(IEnumerable<double> x, IEnumerable<double> y) {
+      return x.Zip(y, (a, b) => (a - b) * (a - b)).Sum();
     }
 
@@ -34,6 +41,54 @@
     }
 
-    public static double SqrDist(IEnumerable<double> x, IEnumerable<double> y) {
-      return x.Zip(y, (a, b) => (a - b) * (a - b)).Sum();
+    public static double SqrDist(double[,] x, int i, int j, double scale = 1.0, IEnumerable<int> columnIndices = null) {
+      return SqrDist(x, i, x, j, scale, columnIndices);
+    }
+
+    public static double SqrDist(double[,] x, int i, double[,] xt, int j, double scale = 1.0, IEnumerable<int> columnIndices = null) {
+      double ss = 0.0;
+      if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
+      foreach (int k in columnIndices) {
+        double d = x[i, k] - xt[j, k];
+        ss += d * d;
+      }
+      return scale * scale * ss;
+    }
+
+    public static double SqrDist(double[,] x, int i, int j, double[] scale, IEnumerable<int> columnIndices = null) {
+      return SqrDist(x, i, x, j, scale);
+    }
+
+    public static double SqrDist(double[,] x, int i, double[,] xt, int j, double[] scale, IEnumerable<int> columnIndices = null) {
+      double ss = 0.0;
+      if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
+      foreach (int k in columnIndices) {
+        double d = x[i, k] - xt[j, k];
+        ss += d * d * scale[k] * scale[k];
+      }
+      return ss;
+    }
+    public static double ScalarProd(double[,] x, int i, int j, double scale = 1.0, IEnumerable<int> columnIndices = null) {
+      return ScalarProd(x, i, x, j, scale, columnIndices);
+    }
+
+    public static double ScalarProd(double[,] x, int i, double[,] xt, int j, double scale = 1.0, IEnumerable<int> columnIndices = null) {
+      double sum = 0.0;
+      if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
+      foreach (int k in columnIndices) {
+        sum += x[i, k] * xt[j, k];
+      }
+      return scale * scale * sum;
+    }
+    public static double ScalarProd(double[,] x, int i, int j, double[] scale, IEnumerable<int> columnIndices = null) {
+      return ScalarProd(x, i, x, j, scale, columnIndices);
+    }
+
+    public static double ScalarProd(double[,] x, int i, double[,] xt, int j, double[] scale, IEnumerable<int> columnIndices = null) {
+      double sum = 0.0;
+      if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
+      foreach (int k in columnIndices) {
+        sum += x[i, k] * scale[k] * xt[j, k] * scale[k];
+      }
+      return sum;
     }
 
@@ -46,4 +101,35 @@
       return Enumerable.Range(0, rows).Select(r => x[r, c]);
     }
+
+
+    public static void AttachValueChangeHandler<T, U>(IValueParameter<T> parameter, Action action)
+      where T : ValueTypeValue<U>
+      where U : struct {
+      parameter.ValueChanged += (sender, args) => {
+        if (parameter.Value != null) {
+          parameter.Value.ValueChanged += (s, a) => action();
+          action();
+        }
+      };
+      if (parameter.Value != null) {
+        parameter.Value.ValueChanged += (s, a) => action();
+      }
+    }
+
+    public static void AttachArrayChangeHandler<T, U>(IValueParameter<T> parameter, Action action)
+      where T : ValueTypeArray<U>
+      where U : struct {
+      parameter.ValueChanged += (sender, args) => {
+        if (parameter.Value != null) {
+          parameter.Value.ItemChanged += (s, a) => action();
+          parameter.Value.Reset += (s, a) => action();
+          action();
+        }
+      };
+      if (parameter.Value != null) {
+        parameter.Value.ItemChanged += (s, a) => action();
+        parameter.Value.Reset += (s, a) => action();
+      }
+    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 8742)
@@ -105,60 +105,23 @@
       <Private>False</Private>
     </Reference>
-    <Reference Include="HeuristicLab.Algorithms.Benchmarks-3.3">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.Benchmarks-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Algorithms.GradientDescent-3.3">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.GradientDescent-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Analysis-3.3">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.RealVectorEncoding-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="LibSVM-1.6.3, Version=1.6.3.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\LibSVM-1.6.3.dll</HintPath>
+    <Reference Include="HeuristicLab.Algorithms.GradientDescent-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="LibSVM-3.12, Version=3.12.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\..\..\trunk\sources\bin\LibSVM-3.12.dll</HintPath>
       <Private>False</Private>
     </Reference>
@@ -174,10 +137,21 @@
     </Compile>
     <Compile Include="FixedDataAnalysisAlgorithm.cs" />
-    <Compile Include="GaussianProcess\CovarianceRQiso.cs" />
+    <Compile Include="GaussianProcess\CovarianceMask.cs" />
+    <Compile Include="GaussianProcess\GaussianProcessClassificationSolutionCreator.cs" />
+    <Compile Include="GaussianProcess\GaussianProcessClassificationModelCreator.cs" />
+    <Compile Include="GaussianProcess\GaussianProcessClassification.cs" />
+    <Compile Include="GaussianProcess\CovarianceProduct.cs" />
+    <Compile Include="GaussianProcess\CovarianceScale.cs" />
+    <Compile Include="GaussianProcess\CovarianceRationalQuadraticArd.cs" />
+    <Compile Include="GaussianProcess\CovarianceRationalQuadraticIso.cs" />
+    <Compile Include="GaussianProcess\CovarianceSquaredExponentialArd.cs" />
+    <Compile Include="GaussianProcess\CovarianceSquaredExponentialIso.cs" />
+    <Compile Include="GaussianProcess\HyperParameter.cs" />
+    <Compile Include="GaussianProcess\CovarianceMaternIso.cs" />
+    <Compile Include="GaussianProcess\CovarianceLinearArd.cs" />
     <Compile Include="GaussianProcess\CovarianceNoise.cs" />
     <Compile Include="GaussianProcess\CovarianceConst.cs" />
-    <Compile Include="GaussianProcess\MeanProd.cs" />
+    <Compile Include="GaussianProcess\MeanProduct.cs" />
     <Compile Include="GaussianProcess\MeanSum.cs" />
-    <Compile Include="GaussianProcess\CovarianceProd.cs" />
     <Compile Include="GaussianProcess\CovarianceSum.cs" />
     <Compile Include="GaussianProcess\CovariancePeriodic.cs" />
@@ -194,6 +168,4 @@
     <Compile Include="GaussianProcess\MeanConst.cs" />
     <Compile Include="GaussianProcess\IMeanFunction.cs" />
-    <Compile Include="GaussianProcess\CovarianceSEard.cs" />
-    <Compile Include="GaussianProcess\CovarianceSEiso.cs" />
     <Compile Include="GaussianProcess\GaussianProcessModel.cs" />
     <Compile Include="GaussianProcess\GaussianProcessRegression.cs" />
@@ -295,9 +267,4 @@
       <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
-      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
-      <Name>HeuristicLab.Random-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
@@ -332,5 +299,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -339,4 +306,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IGaussianProcessModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IGaussianProcessModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IGaussianProcessModel.cs	(revision 8742)
@@ -29,7 +29,8 @@
   public interface IGaussianProcessModel : IRegressionModel {
     double NegativeLogLikelihood { get; }
+    double SigmaNoise { get; }
     IMeanFunction MeanFunction { get; }
     ICovarianceFunction CovarianceFunction { get; }
-    double[] GetHyperparameterGradients();
+    double[] HyperparameterGradients { get; }
 
     IEnumerable<double> GetEstimatedVariance(Dataset ds, IEnumerable<int> rows);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/ISupportVectorMachineModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/ISupportVectorMachineModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/ISupportVectorMachineModel.cs	(revision 8742)
@@ -20,8 +20,6 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
-using System.Collections.Generic;
+using LibSVM;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
@@ -30,6 +28,6 @@
   /// </summary>
   public interface ISupportVectorMachineModel : IDataAnalysisModel, IRegressionModel, IClassificationModel {
-    SVM.Model Model { get; }
-    SVM.RangeTransform RangeTransform { get; }
+    svm_model Model { get; }
+    RangeTransform RangeTransform { get; }
     Dataset SupportVectors { get; }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 8742)
@@ -111,5 +111,7 @@
       IClassificationProblemData problemData,
       IEnumerable<int> rows) {
-      return new SymbolicDiscriminantFunctionClassificationModel(tree, interpreter);
+      var model = new SymbolicDiscriminantFunctionClassificationModel(tree, interpreter, new AccuracyMaximizationThresholdCalculator());
+      model.RecalculateModelParameters(problemData, rows);
+      return model;
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs	(revision 8742)
@@ -45,5 +45,4 @@
     public MultinomialLogitClassificationSolution(IClassificationProblemData problemData, MultinomialLogitModel logitModel)
       : base(logitModel, problemData) {
-      RecalculateResults();
     }
 
@@ -51,8 +50,4 @@
       return new MultinomialLogitClassificationSolution(this, cloner);
     }
-
-    protected override void RecalculateResults() {
-      CalculateResults();
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 8742)
@@ -109,5 +109,5 @@
 
     public MultinomialLogitClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new MultinomialLogitClassificationSolution(problemData, this);
+      return new MultinomialLogitClassificationSolution(new ClassificationProblemData(problemData), this);
     }
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Matrix.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Matrix.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Matrix.cs	(revision 8742)
@@ -70,6 +70,5 @@
 
     public Matrix Transpose() {
-      var result = new Matrix(Transpose(values, Columns, Rows), Columns, Rows);
-      return result;
+      return new Matrix(Transpose(values, Columns, Rows), Columns, Rows);
     }
 
@@ -125,10 +124,9 @@
     }
 
-    public double VectorLength() {
-      return Math.Sqrt(SquaredVectorLength());
-    }
-
-    public double SquaredVectorLength() {
-      if (Rows != 1) throw new ArgumentException("Length only works on vectors.");
+    public double EuclideanNorm() {
+      return Math.Sqrt(SumOfSquares());
+    }
+
+    public double SumOfSquares() {
       return values.Sum(x => x * x);
     }
@@ -137,4 +135,22 @@
       if (Rows != 1 || other.Rows != 1) throw new ArgumentException("OuterProduct can only be applied to vectors.");
       return Transpose().Multiply(other);
+    }
+
+    public IEnumerable<double> ColumnSums() {
+      return Transpose().RowSums();
+    }
+
+    public IEnumerable<double> RowSums() {
+      var sum = 0.0;
+      int counter = 0;
+      foreach (var v in values) {
+        sum += v;
+        counter++;
+        if (counter == Rows) {
+          yield return sum;
+          sum = 0.0;
+          counter = 0;
+        }
+      }
     }
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaAlgorithm.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaAlgorithm.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaAlgorithm.cs	(revision 8742)
@@ -35,9 +35,13 @@
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
-  internal delegate void Reporter(double quality, double[] coefficients);
+  internal delegate void Reporter(double quality, double[] coefficients, double[] gradients);
   /// <summary>
   /// Neighborhood Components Analysis
   /// </summary>
-  [Item("Neighborhood Components Analysis (NCA)", "Implementation of Neighborhood Components Analysis based on the description of J. Goldberger, S. Roweis, G. Hinton, R. Salakhutdinov. 2005. Neighbourhood Component Analysis. Advances in Neural Information Processing Systems, 17. pp. 513-520.")]
+  [Item("Neighborhood Components Analysis (NCA)", @"Implementation of Neighborhood Components Analysis
+based on the description of J. Goldberger, S. Roweis, G. Hinton, R. Salakhutdinov. 2005.
+Neighbourhood Component Analysis. Advances in Neural Information Processing Systems, 17. pp. 513-520
+with additional regularizations described in Z. Yang, J. Laaksonen. 2007.
+Regularized Neighborhood Component Analysis. Lecture Notes in Computer Science, 4522. pp. 253-262.")]
   [Creatable("Data Analysis")]
   [StorableClass]
@@ -59,22 +63,29 @@
       get { return (IFixedValueParameter<IntValue>)Parameters["Iterations"]; }
     }
+    public IFixedValueParameter<DoubleValue> RegularizationParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters["Regularization"]; }
+    }
     #endregion
 
     #region Properties
-    private int K {
+    public int K {
       get { return KParameter.Value.Value; }
       set { KParameter.Value.Value = value; }
     }
-    private int Dimensions {
+    public int Dimensions {
       get { return DimensionsParameter.Value.Value; }
       set { DimensionsParameter.Value.Value = value; }
     }
-    private int NeighborSamples {
+    public int NeighborSamples {
       get { return NeighborSamplesParameter.Value.Value; }
       set { NeighborSamplesParameter.Value.Value = value; }
     }
-    private int Iterations {
+    public int Iterations {
       get { return IterationsParameter.Value.Value; }
       set { IterationsParameter.Value.Value = value; }
+    }
+    public double Regularization {
+      get { return RegularizationParameter.Value.Value; }
+      set { RegularizationParameter.Value.Value = value; }
     }
     #endregion
@@ -85,9 +96,10 @@
     public NcaAlgorithm()
       : base() {
-      Parameters.Add(new FixedValueParameter<IntValue>("K", "The K for the nearest neighbor.", new IntValue(1)));
+      Parameters.Add(new FixedValueParameter<IntValue>("K", "The K for the nearest neighbor.", new IntValue(3)));
       Parameters.Add(new FixedValueParameter<IntValue>("Dimensions", "The number of dimensions that NCA should reduce the data to.", new IntValue(2)));
       Parameters.Add(new ConstrainedValueParameter<INCAInitializer>("Initialization", "Which method should be used to initialize the matrix. Typically LDA (linear discriminant analysis) should provide a good estimate."));
-      Parameters.Add(new FixedValueParameter<IntValue>("NeighborSamples", "How many of the neighbors should be sampled in order to speed up the calculation. This should be at least the value of k and at most the number of training instances minus one.", new IntValue(50)));
-      Parameters.Add(new FixedValueParameter<IntValue>("Iterations", "How many iterations the conjugate gradient (CG) method should be allowed to perform. The method might still terminate earlier if a local optima has already been reached.", new IntValue(20)));
+      Parameters.Add(new FixedValueParameter<IntValue>("NeighborSamples", "How many of the neighbors should be sampled in order to speed up the calculation. This should be at least the value of k and at most the number of training instances minus one.", new IntValue(60)));
+      Parameters.Add(new FixedValueParameter<IntValue>("Iterations", "How many iterations the conjugate gradient (CG) method should be allowed to perform. The method might still terminate earlier if a local optima has already been reached.", new IntValue(50)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Regularization", "A non-negative paramter which can be set to increase generalization and avoid overfitting. If set to 0 the algorithm is similar to NCA as proposed by Goldberger et al.", new DoubleValue(0)));
 
       INCAInitializer defaultInitializer = null;
@@ -105,4 +117,11 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey("Regularization")) {
+        Parameters.Add(new FixedValueParameter<DoubleValue>("Regularization", "A non-negative paramter which can be set to increase generalization and avoid overfitting. If set to 0 the algorithm is similar to NCA as proposed by Goldberger et al.", new DoubleValue(0)));
+      }
+    }
+
     public override void Prepare() {
       if (Problem != null) base.Prepare();
@@ -113,27 +132,30 @@
 
       var clonedProblem = (IClassificationProblemData)Problem.ProblemData.Clone();
-      var model = Train(clonedProblem, K, Dimensions, NeighborSamples, Iterations, initializer.Initialize(clonedProblem, Dimensions), ReportQuality, CancellationToken.None);
-      Results.Add(new Result("ClassificationSolution", "The classification solution.", model.CreateClassificationSolution(clonedProblem)));
-    }
-
-    public static INcaClassificationSolution CreateClassificationSolution(IClassificationProblemData data, int k, int dimensions, int neighborSamples, int iterations, INCAInitializer initializer) {
+      var model = Train(clonedProblem, K, Dimensions, NeighborSamples, Regularization, Iterations, initializer.Initialize(clonedProblem, Dimensions), ReportQuality, CancellationToken.None);
+      var solution = model.CreateClassificationSolution(clonedProblem);
+      if (!Results.ContainsKey("ClassificationSolution"))
+        Results.Add(new Result("ClassificationSolution", "The classification solution.", solution));
+      else Results["ClassificationSolution"].Value = solution;
+    }
+
+    public static INcaClassificationSolution CreateClassificationSolution(IClassificationProblemData data, int k, int dimensions, int neighborSamples, double regularization, int iterations, INCAInitializer initializer) {
       var clonedProblem = (IClassificationProblemData)data.Clone();
-      var model = Train(clonedProblem, k, dimensions, neighborSamples, iterations, initializer);
+      var model = Train(clonedProblem, k, dimensions, neighborSamples, regularization, iterations, initializer);
       return model.CreateClassificationSolution(clonedProblem);
     }
 
-    public static INcaModel Train(IClassificationProblemData problemData, int k, int dimensions, int neighborSamples, int iterations, INCAInitializer initializer) {
-      return Train(problemData, k, dimensions, neighborSamples, iterations, initializer.Initialize(problemData, dimensions), null, CancellationToken.None);
-    }
-
-    public static INcaModel Train(IClassificationProblemData problemData, int k, int neighborSamples, int iterations, double[,] initalMatrix) {
+    public static INcaModel Train(IClassificationProblemData problemData, int k, int dimensions, int neighborSamples, double regularization, int iterations, INCAInitializer initializer) {
+      return Train(problemData, k, dimensions, neighborSamples, regularization, iterations, initializer.Initialize(problemData, dimensions), null, CancellationToken.None);
+    }
+
+    public static INcaModel Train(IClassificationProblemData problemData, int k, int neighborSamples, double regularization, int iterations, double[,] initalMatrix) {
       var matrix = new double[initalMatrix.Length];
       for (int i = 0; i < initalMatrix.GetLength(0); i++)
         for (int j = 0; j < initalMatrix.GetLength(1); j++)
           matrix[i * initalMatrix.GetLength(1) + j] = initalMatrix[i, j];
-      return Train(problemData, k, initalMatrix.GetLength(1), neighborSamples, iterations, matrix, null, CancellationToken.None);
-    }
-
-    private static INcaModel Train(IClassificationProblemData data, int k, int dimensions, int neighborSamples, int iterations, double[] matrix, Reporter reporter, CancellationToken cancellation) {
+      return Train(problemData, k, initalMatrix.GetLength(1), neighborSamples, regularization, iterations, matrix, null, CancellationToken.None);
+    }
+
+    private static INcaModel Train(IClassificationProblemData data, int k, int dimensions, int neighborSamples, double regularization, int iterations, double[] matrix, Reporter reporter, CancellationToken cancellation) {
       var scaling = new Scaling(data.Dataset, data.AllowedInputVariables, data.TrainingIndices);
       var scaledData = AlglibUtil.PrepareAndScaleInputMatrix(data.Dataset, data.AllowedInputVariables, data.TrainingIndices, scaling);
@@ -146,7 +168,9 @@
       alglib.mincgsetcond(state, 0, 0, 0, iterations);
       alglib.mincgsetxrep(state, true);
+      //alglib.mincgsetgradientcheck(state, 0.01);
       int neighborSampleSize = neighborSamples;
-      Optimize(state, scaledData, classes, dimensions, neighborSampleSize, cancellation, reporter);
+      Optimize(state, scaledData, classes, dimensions, neighborSampleSize, regularization, cancellation, reporter);
       alglib.mincgresults(state, out matrix, out rep);
+      if (rep.terminationtype == -7) throw new InvalidOperationException("Gradient verification failed.");
 
       var transformationMatrix = new double[attributes, dimensions];
@@ -159,14 +183,14 @@
     }
 
-    private static void Optimize(alglib.mincgstate state, double[,] data, double[] classes, int dimensions, int neighborSampleSize, CancellationToken cancellation, Reporter reporter) {
+    private static void Optimize(alglib.mincgstate state, double[,] data, double[] classes, int dimensions, int neighborSampleSize, double lambda, CancellationToken cancellation, Reporter reporter) {
       while (alglib.mincgiteration(state)) {
         if (cancellation.IsCancellationRequested) break;
         if (state.needfg) {
-          Gradient(state.x, ref state.innerobj.f, state.innerobj.g, data, classes, dimensions, neighborSampleSize);
+          Gradient(state.x, ref state.innerobj.f, state.innerobj.g, data, classes, dimensions, neighborSampleSize, lambda);
           continue;
         }
         if (state.innerobj.xupdated) {
           if (reporter != null)
-            reporter(state.innerobj.f, state.innerobj.x);
+            reporter(state.innerobj.f, state.innerobj.x, state.innerobj.g);
           continue;
         }
@@ -175,5 +199,5 @@
     }
 
-    private static void Gradient(double[] A, ref double func, double[] grad, double[,] data, double[] classes, int dimensions, int neighborSampleSize) {
+    private static void Gradient(double[] A, ref double func, double[] grad, double[,] data, double[] classes, int dimensions, int neighborSampleSize, double lambda) {
       var instances = data.GetLength(0);
       var attributes = data.GetLength(1);
@@ -192,13 +216,10 @@
           }
           var kVector = new Matrix(GetRow(data, k));
-          transformedDistances[k] = Math.Exp(-iVector.Multiply(AMatrix).Subtract(kVector.Multiply(AMatrix)).SquaredVectorLength());
-        }
-        var sample = transformedDistances.OrderByDescending(x => x.Value).Take(neighborSampleSize).ToArray();
-        var normalization = sample.Sum(x => x.Value);
-        if (normalization > 0) {
-          foreach (var s in sample) {
-            if (s.Value <= 0) break;
-            alglib.sparseset(probabilities, i, s.Key, s.Value / normalization);
-          }
+          transformedDistances[k] = Math.Exp(-iVector.Multiply(AMatrix).Subtract(kVector.Multiply(AMatrix)).SumOfSquares());
+        }
+        var normalization = transformedDistances.Sum(x => x.Value);
+        if (normalization <= 0) continue;
+        foreach (var s in transformedDistances.Where(x => x.Value > 0).OrderByDescending(x => x.Value).Take(neighborSampleSize)) {
+          alglib.sparseset(probabilities, i, s.Key, s.Value / normalization);
         }
       }
@@ -224,14 +245,15 @@
       }
 
-      func = -pi.Sum();
+      func = -pi.Sum() + lambda * AMatrix.SumOfSquares();
 
       r = 0;
       var newGrad = AMatrix.Multiply(-2.0).Transpose().Multiply(new Matrix(innerSum)).Transpose();
       foreach (var g in newGrad) {
-        grad[r++] = g;
-      }
-    }
-
-    private void ReportQuality(double func, double[] coefficients) {
+        grad[r] = g + lambda * 2 * A[r];
+        r++;
+      }
+    }
+
+    private void ReportQuality(double func, double[] coefficients, double[] gradients) {
       var instances = Problem.ProblemData.TrainingIndices.Count();
       DataTable qualities;
@@ -243,7 +265,37 @@
       qualities.Rows["Quality"].Values.Add(-func / instances);
 
+      string[] attributNames = Problem.ProblemData.AllowedInputVariables.ToArray();
+      if (gradients != null) {
+        DataTable grads;
+        if (!Results.ContainsKey("Gradients")) {
+          grads = new DataTable("Gradients");
+          for (int i = 0; i < gradients.Length; i++)
+            grads.Rows.Add(new DataRow(attributNames[i / Dimensions] + "-" + (i % Dimensions), string.Empty));
+          Results.Add(new Result("Gradients", grads));
+        } else grads = (DataTable)Results["Gradients"].Value;
+        for (int i = 0; i < gradients.Length; i++)
+          grads.Rows[attributNames[i / Dimensions] + "-" + (i % Dimensions)].Values.Add(gradients[i]);
+      }
+
       if (!Results.ContainsKey("Quality")) {
         Results.Add(new Result("Quality", new DoubleValue(-func / instances)));
       } else ((DoubleValue)Results["Quality"].Value).Value = -func / instances;
+
+      var attributes = attributNames.Length;
+      var transformationMatrix = new double[attributes, Dimensions];
+      var counter = 0;
+      for (var i = 0; i < attributes; i++)
+        for (var j = 0; j < Dimensions; j++)
+          transformationMatrix[i, j] = coefficients[counter++];
+
+      var scaling = new Scaling(Problem.ProblemData.Dataset, attributNames, Problem.ProblemData.TrainingIndices);
+      var model = new NcaModel(K, transformationMatrix, Problem.ProblemData.Dataset, Problem.ProblemData.TrainingIndices, Problem.ProblemData.TargetVariable, attributNames, scaling, Problem.ProblemData.ClassValues.ToArray());
+
+      IClassificationSolution solution = model.CreateClassificationSolution(Problem.ProblemData);
+      if (!Results.ContainsKey("ClassificationSolution")) {
+        Results.Add(new Result("ClassificationSolution", solution));
+      } else {
+        Results["ClassificationSolution"].Value = solution;
+      }
     }
 
@@ -252,4 +304,5 @@
         yield return data[row, i];
     }
+
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs	(revision 8742)
@@ -42,5 +42,4 @@
     public NcaClassificationSolution(IClassificationProblemData problemData, INcaModel ncaModel)
       : base(ncaModel, problemData) {
-      RecalculateResults();
     }
 
@@ -48,8 +47,4 @@
       return new NcaClassificationSolution(this, cloner);
     }
-
-    protected override void RecalculateResults() {
-      CalculateResults();
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs	(revision 8742)
@@ -82,5 +82,5 @@
 
     public INcaClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new NcaClassificationSolution(problemData, this);
+      return new NcaClassificationSolution(new ClassificationProblemData(problemData), this);
     }
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs	(revision 8742)
@@ -45,5 +45,4 @@
     public NearestNeighbourClassificationSolution(IClassificationProblemData problemData, INearestNeighbourModel nnModel)
       : base(nnModel, problemData) {
-      RecalculateResults();
     }
 
@@ -51,8 +50,4 @@
       return new NearestNeighbourClassificationSolution(this, cloner);
     }
-
-    protected override void RecalculateResults() {
-      CalculateResults();
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 8742)
@@ -202,5 +202,5 @@
 
     public INearestNeighbourRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new NearestNeighbourRegressionSolution(problemData, this);
+      return new NearestNeighbourRegressionSolution(new RegressionProblemData(problemData), this);
     }
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
@@ -208,5 +208,5 @@
     }
     public INearestNeighbourClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new NearestNeighbourClassificationSolution(problemData, this);
+      return new NearestNeighbourClassificationSolution(new ClassificationProblemData(problemData), this);
     }
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs	(revision 8742)
@@ -45,5 +45,4 @@
     public NeuralNetworkClassificationSolution(IClassificationProblemData problemData, INeuralNetworkModel nnModel)
       : base(nnModel, problemData) {
-      RecalculateResults();
     }
 
@@ -51,7 +50,5 @@
       return new NeuralNetworkClassificationSolution(this, cloner);
     }
-    protected override void RecalculateResults() {
-      CalculateResults();
-    }
+
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs	(revision 8742)
@@ -45,5 +45,4 @@
     public NeuralNetworkEnsembleClassificationSolution(IClassificationProblemData problemData, INeuralNetworkEnsembleModel nnModel)
       : base(nnModel, problemData) {
-      RecalculateResults();
     }
 
@@ -51,8 +50,4 @@
       return new NeuralNetworkEnsembleClassificationSolution(this, cloner);
     }
-
-    protected override void RecalculateResults() {
-      CalculateResults();
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 8742)
@@ -130,5 +130,5 @@
 
     public INeuralNetworkEnsembleRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new NeuralNetworkEnsembleRegressionSolution(problemData, this);
+      return new NeuralNetworkEnsembleRegressionSolution(new RegressionEnsembleProblemData(problemData), this);
     }
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
@@ -136,5 +136,5 @@
     }
     public INeuralNetworkEnsembleClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new NeuralNetworkEnsembleClassificationSolution(problemData, this);
+      return new NeuralNetworkEnsembleClassificationSolution(new ClassificationEnsembleProblemData(problemData), this);
     }
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 8742)
@@ -138,5 +138,5 @@
 
     public INeuralNetworkRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new NeuralNetworkRegressionSolution(problemData, this);
+      return new NeuralNetworkRegressionSolution(new RegressionProblemData(problemData), this);
     }
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
@@ -144,5 +144,5 @@
     }
     public INeuralNetworkClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new NeuralNetworkClassificationSolution(problemData, this);
+      return new NeuralNetworkClassificationSolution(new ClassificationProblemData(problemData), this);
     }
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Plugin.cs.frame	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Plugin.cs.frame	(revision 8742)
@@ -46,5 +46,5 @@
   [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Classification", "3.4")]
   [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression", "3.4")]
-  [PluginDependency("HeuristicLab.LibSVM", "1.6.3")]
+  [PluginDependency("HeuristicLab.LibSVM", "3.12")]
   [PluginDependency("HeuristicLab.Random", "3.3")]
   public class HeuristicLabAlgorithmsDataAnalysisPlugin : PluginBase {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs	(revision 8742)
@@ -45,5 +45,4 @@
     public RandomForestClassificationSolution(IClassificationProblemData problemData, IRandomForestModel randomForestModel)
       : base(randomForestModel, problemData) {
-      RecalculateResults();
     }
 
@@ -51,8 +50,4 @@
       return new RandomForestClassificationSolution(this, cloner);
     }
-
-    protected override void RecalculateResults() {
-      CalculateResults();
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 8742)
@@ -132,5 +132,5 @@
 
     public IRandomForestRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new RandomForestRegressionSolution(problemData, this);
+      return new RandomForestRegressionSolution(new RegressionProblemData(problemData), this);
     }
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
@@ -138,5 +138,5 @@
     }
     public IRandomForestClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new RandomForestClassificationSolution(problemData, this);
+      return new RandomForestClassificationSolution(new ClassificationProblemData(problemData), this);
     }
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorClassification.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorClassification.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorClassification.cs	(revision 8742)
@@ -30,4 +30,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis;
+using LibSVM;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
@@ -44,4 +45,5 @@
     private const string NuParameterName = "Nu";
     private const string GammaParameterName = "Gamma";
+    private const string DegreeParameterName = "Degree";
 
     #region parameter properties
@@ -60,4 +62,7 @@
     public IValueParameter<DoubleValue> GammaParameter {
       get { return (IValueParameter<DoubleValue>)Parameters[GammaParameterName]; }
+    }
+    public IValueParameter<IntValue> DegreeParameter {
+      get { return (IValueParameter<IntValue>)Parameters[DegreeParameterName]; }
     }
     #endregion
@@ -79,4 +84,7 @@
     public DoubleValue Gamma {
       get { return GammaParameter.Value; }
+    }
+    public IntValue Degree {
+      get { return DegreeParameter.Value; }
     }
     #endregion
@@ -103,7 +111,13 @@
       Parameters.Add(new ValueParameter<DoubleValue>(CostParameterName, "The value of the C (cost) parameter of C-SVC.", new DoubleValue(1.0)));
       Parameters.Add(new ValueParameter<DoubleValue>(GammaParameterName, "The value of the gamma parameter in the kernel function.", new DoubleValue(1.0)));
+      Parameters.Add(new ValueParameter<IntValue>(DegreeParameterName, "The degree parameter for the polynomial kernel function.", new IntValue(3)));
     }
     [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() { }
+    private void AfterDeserialization() {
+      #region backwards compatibility (change with 3.4)
+      if (!Parameters.ContainsKey(DegreeParameterName))
+        Parameters.Add(new ValueParameter<IntValue>(DegreeParameterName, "The degree parameter for the polynomial kernel function.", new IntValue(3)));
+      #endregion
+    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -118,15 +132,15 @@
       int nSv;
       var solution = CreateSupportVectorClassificationSolution(problemData, selectedInputVariables,
-        SvmType.Value, KernelType.Value, Cost.Value, Nu.Value, Gamma.Value,
+        SvmType.Value, KernelType.Value, Cost.Value, Nu.Value, Gamma.Value, Degree.Value,
         out trainingAccuracy, out testAccuracy, out nSv);
 
       Results.Add(new Result("Support vector classification solution", "The support vector classification solution.", solution));
       Results.Add(new Result("Training accuracy", "The accuracy of the SVR solution on the training partition.", new DoubleValue(trainingAccuracy)));
-      Results.Add(new Result("Test R²", "The accuracy of the SVR solution on the test partition.", new DoubleValue(testAccuracy)));
+      Results.Add(new Result("Test accuracy", "The accuracy of the SVR solution on the test partition.", new DoubleValue(testAccuracy)));
       Results.Add(new Result("Number of support vectors", "The number of support vectors of the SVR solution.", new IntValue(nSv)));
     }
 
     public static SupportVectorClassificationSolution CreateSupportVectorClassificationSolution(IClassificationProblemData problemData, IEnumerable<string> allowedInputVariables,
-      string svmType, string kernelType, double cost, double nu, double gamma,
+      string svmType, string kernelType, double cost, double nu, double gamma, int degree,
       out double trainingAccuracy, out double testAccuracy, out int nSv) {
       Dataset dataset = problemData.Dataset;
@@ -135,13 +149,20 @@
 
       //extract SVM parameters from scope and set them
-      SVM.Parameter parameter = new SVM.Parameter();
-      parameter.SvmType = (SVM.SvmType)Enum.Parse(typeof(SVM.SvmType), svmType, true);
-      parameter.KernelType = (SVM.KernelType)Enum.Parse(typeof(SVM.KernelType), kernelType, true);
+      svm_parameter parameter = new svm_parameter();
+      parameter.svm_type = GetSvmType(svmType);
+      parameter.kernel_type = GetKernelType(kernelType);
       parameter.C = cost;
-      parameter.Nu = nu;
-      parameter.Gamma = gamma;
-      parameter.CacheSize = 500;
-      parameter.Probability = false;
-
+      parameter.nu = nu;
+      parameter.gamma = gamma;
+      parameter.cache_size = 500;
+      parameter.probability = 0;
+      parameter.eps = 0.001;
+      parameter.degree = degree;
+      parameter.shrinking = 1;
+      parameter.coef0 = 0;
+
+
+      var weightLabels = new List<int>();
+      var weights = new List<double>();
       foreach (double c in problemData.ClassValues) {
         double wSum = 0.0;
@@ -151,20 +172,37 @@
           }
         }
-        parameter.Weights.Add((int)c, wSum);
+        weightLabels.Add((int)c);
+        weights.Add(wSum);
       }
-
-
-      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, targetVariable, allowedInputVariables, rows);
-      SVM.RangeTransform rangeTransform = SVM.RangeTransform.Compute(problem);
-      SVM.Problem scaledProblem = SVM.Scaling.Scale(rangeTransform, problem);
-      var svmModel = SVM.Training.Train(scaledProblem, parameter);
+      parameter.weight_label = weightLabels.ToArray();
+      parameter.weight = weights.ToArray();
+
+
+      svm_problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, targetVariable, allowedInputVariables, rows);
+      RangeTransform rangeTransform = RangeTransform.Compute(problem);
+      svm_problem scaledProblem = rangeTransform.Scale(problem);
+      var svmModel = svm.svm_train(scaledProblem, parameter);
       var model = new SupportVectorMachineModel(svmModel, rangeTransform, targetVariable, allowedInputVariables, problemData.ClassValues);
       var solution = new SupportVectorClassificationSolution(model, (IClassificationProblemData)problemData.Clone());
 
-      nSv = svmModel.SupportVectorCount;
+      nSv = svmModel.SV.Length;
       trainingAccuracy = solution.TrainingAccuracy;
       testAccuracy = solution.TestAccuracy;
 
       return solution;
+    }
+
+    private static int GetSvmType(string svmType) {
+      if (svmType == "NU_SVC") return svm_parameter.NU_SVC;
+      if (svmType == "C_SVC") return svm_parameter.C_SVC;
+      throw new ArgumentException("Unknown SVM type");
+    }
+
+    private static int GetKernelType(string kernelType) {
+      if (kernelType == "LINEAR") return svm_parameter.LINEAR;
+      if (kernelType == "POLY") return svm_parameter.POLY;
+      if (kernelType == "SIGMOID") return svm_parameter.SIGMOID;
+      if (kernelType == "RBF") return svm_parameter.RBF;
+      throw new ArgumentException("Unknown kernel type");
     }
     #endregion
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorClassificationSolution.cs	(revision 8742)
@@ -45,5 +45,4 @@
     public SupportVectorClassificationSolution(SupportVectorMachineModel model, IClassificationProblemData problemData)
       : base(model, problemData) {
-      RecalculateResults();
     }
 
@@ -51,8 +50,4 @@
       return new SupportVectorClassificationSolution(this, cloner);
     }
-
-    protected override void RecalculateResults() {
-      CalculateResults();
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs	(revision 8742)
@@ -29,5 +29,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis;
-using SVM;
+using LibSVM;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
@@ -39,9 +39,9 @@
   public sealed class SupportVectorMachineModel : NamedItem, ISupportVectorMachineModel {
 
-    private SVM.Model model;
+    private svm_model model;
     /// <summary>
     /// Gets or sets the SVM model.
     /// </summary>
-    public SVM.Model Model {
+    public svm_model Model {
       get { return model; }
       set {
@@ -57,6 +57,6 @@
     /// Gets or sets the range transformation for the model.
     /// </summary>
-    private SVM.RangeTransform rangeTransform;
-    public SVM.RangeTransform RangeTransform {
+    private RangeTransform rangeTransform;
+    public RangeTransform RangeTransform {
       get { return rangeTransform; }
       set {
@@ -71,9 +71,9 @@
     public Dataset SupportVectors {
       get {
-        var data = new double[Model.SupportVectorCount, allowedInputVariables.Count()];
-        for (int i = 0; i < Model.SupportVectorCount; i++) {
-          var sv = Model.SupportVectors[i];
+        var data = new double[Model.sv_coef.Length, allowedInputVariables.Count()];
+        for (int i = 0; i < Model.sv_coef.Length; i++) {
+          var sv = Model.SV[i];
           for (int j = 0; j < sv.Length; j++) {
-            data[i, j] = sv[j].Value;
+            data[i, j] = sv[j].value;
           }
         }
@@ -101,9 +101,9 @@
         this.classValues = (double[])original.classValues.Clone();
     }
-    public SupportVectorMachineModel(SVM.Model model, SVM.RangeTransform rangeTransform, string targetVariable, IEnumerable<string> allowedInputVariables, IEnumerable<double> classValues)
+    public SupportVectorMachineModel(svm_model model, RangeTransform rangeTransform, string targetVariable, IEnumerable<string> allowedInputVariables, IEnumerable<double> classValues)
       : this(model, rangeTransform, targetVariable, allowedInputVariables) {
       this.classValues = classValues.ToArray();
     }
-    public SupportVectorMachineModel(SVM.Model model, SVM.RangeTransform rangeTransform, string targetVariable, IEnumerable<string> allowedInputVariables)
+    public SupportVectorMachineModel(svm_model model, RangeTransform rangeTransform, string targetVariable, IEnumerable<string> allowedInputVariables)
       : base() {
       this.name = ItemName;
@@ -124,5 +124,5 @@
     }
     public SupportVectorRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new SupportVectorRegressionSolution(this, problemData);
+      return new SupportVectorRegressionSolution(this, new RegressionProblemData(problemData));
     }
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
@@ -153,5 +153,5 @@
 
     public SupportVectorClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new SupportVectorClassificationSolution(this, problemData);
+      return new SupportVectorClassificationSolution(this, new ClassificationProblemData(problemData));
     }
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
@@ -161,9 +161,9 @@
     private IEnumerable<double> GetEstimatedValuesHelper(Dataset dataset, IEnumerable<int> rows) {
       // calculate predictions for the currently requested rows
-      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, targetVariable, allowedInputVariables, rows);
-      SVM.Problem scaledProblem = SVM.Scaling.Scale(RangeTransform, problem);
-
-      for (int i = 0; i < scaledProblem.Count; i++) {
-        yield return SVM.Prediction.Predict(Model, scaledProblem.X[i]);
+      svm_problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, targetVariable, allowedInputVariables, rows);
+      svm_problem scaledProblem = rangeTransform.Scale(problem);
+
+      for (int i = 0; i < problem.l; i++) {
+        yield return svm.svm_predict(Model, scaledProblem.x[i]);
       }
     }
@@ -183,5 +183,5 @@
       get {
         using (MemoryStream stream = new MemoryStream()) {
-          SVM.Model.Write(stream, Model);
+          svm.svm_save_model(new StreamWriter(stream), Model);
           stream.Seek(0, System.IO.SeekOrigin.Begin);
           StreamReader reader = new StreamReader(stream);
@@ -191,5 +191,5 @@
       set {
         using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(value))) {
-          model = SVM.Model.Read(stream);
+          model = svm.svm_load_model(new StreamReader(stream));
         }
       }
@@ -199,5 +199,5 @@
       get {
         using (MemoryStream stream = new MemoryStream()) {
-          SVM.RangeTransform.Write(stream, RangeTransform);
+          RangeTransform.Write(stream, RangeTransform);
           stream.Seek(0, System.IO.SeekOrigin.Begin);
           StreamReader reader = new StreamReader(stream);
@@ -207,5 +207,5 @@
       set {
         using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(value))) {
-          RangeTransform = SVM.RangeTransform.Read(stream);
+          RangeTransform = RangeTransform.Read(stream);
         }
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineUtil.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineUtil.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineUtil.cs	(revision 8742)
@@ -23,4 +23,5 @@
 using System.Linq;
 using HeuristicLab.Problems.DataAnalysis;
+using LibSVM;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
@@ -32,15 +33,15 @@
     /// <param name="rowIndices">The rows of the dataset that should be contained in the resulting SVM-problem</param>
     /// <returns>A problem data type that can be used to train a support vector machine.</returns>
-    public static SVM.Problem CreateSvmProblem(Dataset dataset, string targetVariable, IEnumerable<string> inputVariables, IEnumerable<int> rowIndices) {
+    public static svm_problem CreateSvmProblem(Dataset dataset, string targetVariable, IEnumerable<string> inputVariables, IEnumerable<int> rowIndices) {
       double[] targetVector =
         dataset.GetDoubleValues(targetVariable, rowIndices).ToArray();
 
-      SVM.Node[][] nodes = new SVM.Node[targetVector.Length][];
-      List<SVM.Node> tempRow;
+      svm_node[][] nodes = new svm_node[targetVector.Length][];
+      List<svm_node> tempRow;
       int maxNodeIndex = 0;
       int svmProblemRowIndex = 0;
       List<string> inputVariablesList = inputVariables.ToList();
       foreach (int row in rowIndices) {
-        tempRow = new List<SVM.Node>();
+        tempRow = new List<svm_node>();
         int colIndex = 1; // make sure the smallest node index for SVM = 1
         foreach (var inputVariable in inputVariablesList) {
@@ -49,5 +50,5 @@
           // => don't add NaN values in the dataset to the sparse SVM matrix representation
           if (!double.IsNaN(value)) {
-            tempRow.Add(new SVM.Node(colIndex, value)); // nodes must be sorted in ascending ordered by column index
+            tempRow.Add(new svm_node() { index = colIndex, value = value }); // nodes must be sorted in ascending ordered by column index
             if (colIndex > maxNodeIndex) maxNodeIndex = colIndex;
           }
@@ -57,5 +58,5 @@
       }
 
-      return new SVM.Problem(targetVector.Length, targetVector, nodes, maxNodeIndex);
+      return new svm_problem() { l = targetVector.Length, y = targetVector, x = nodes };
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorRegression.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorRegression.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorRegression.cs	(revision 8742)
@@ -30,4 +30,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis;
+using LibSVM;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
@@ -45,4 +46,5 @@
     private const string GammaParameterName = "Gamma";
     private const string EpsilonParameterName = "Epsilon";
+    private const string DegreeParameterName = "Degree";
 
     #region parameter properties
@@ -64,4 +66,7 @@
     public IValueParameter<DoubleValue> EpsilonParameter {
       get { return (IValueParameter<DoubleValue>)Parameters[EpsilonParameterName]; }
+    }
+    public IValueParameter<IntValue> DegreeParameter {
+      get { return (IValueParameter<IntValue>)Parameters[DegreeParameterName]; }
     }
     #endregion
@@ -86,4 +91,7 @@
     public DoubleValue Epsilon {
       get { return EpsilonParameter.Value; }
+    }
+    public IntValue Degree {
+      get { return DegreeParameter.Value; }
     }
     #endregion
@@ -111,7 +119,13 @@
       Parameters.Add(new ValueParameter<DoubleValue>(GammaParameterName, "The value of the gamma parameter in the kernel function.", new DoubleValue(1.0)));
       Parameters.Add(new ValueParameter<DoubleValue>(EpsilonParameterName, "The value of the epsilon parameter for epsilon-SVR.", new DoubleValue(0.1)));
+      Parameters.Add(new ValueParameter<IntValue>(DegreeParameterName, "The degree parameter for the polynomial kernel function.", new IntValue(3)));
     }
     [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() { }
+    private void AfterDeserialization() {
+      #region backwards compatibility (change with 3.4)
+      if (!Parameters.ContainsKey(DegreeParameterName))
+        Parameters.Add(new ValueParameter<IntValue>(DegreeParameterName, "The degree parameter for the polynomial kernel function.", new IntValue(3)));
+      #endregion
+    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -126,5 +140,5 @@
       int nSv;
       var solution = CreateSupportVectorRegressionSolution(problemData, selectedInputVariables, SvmType.Value,
-        KernelType.Value, Cost.Value, Nu.Value, Gamma.Value, Epsilon.Value,
+        KernelType.Value, Cost.Value, Nu.Value, Gamma.Value, Epsilon.Value, Degree.Value,
         out trainR2, out testR2, out nSv);
 
@@ -136,5 +150,5 @@
 
     public static SupportVectorRegressionSolution CreateSupportVectorRegressionSolution(IRegressionProblemData problemData, IEnumerable<string> allowedInputVariables,
-      string svmType, string kernelType, double cost, double nu, double gamma, double epsilon,
+      string svmType, string kernelType, double cost, double nu, double gamma, double epsilon, int degree,
       out double trainingR2, out double testR2, out int nSv) {
       Dataset dataset = problemData.Dataset;
@@ -143,20 +157,25 @@
 
       //extract SVM parameters from scope and set them
-      SVM.Parameter parameter = new SVM.Parameter();
-      parameter.SvmType = (SVM.SvmType)Enum.Parse(typeof(SVM.SvmType), svmType, true);
-      parameter.KernelType = (SVM.KernelType)Enum.Parse(typeof(SVM.KernelType), kernelType, true);
+      svm_parameter parameter = new svm_parameter();
+      parameter.svm_type = GetSvmType(svmType);
+      parameter.kernel_type = GetKernelType(kernelType);
       parameter.C = cost;
-      parameter.Nu = nu;
-      parameter.Gamma = gamma;
-      parameter.P = epsilon;
-      parameter.CacheSize = 500;
-      parameter.Probability = false;
-
-
-      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, targetVariable, allowedInputVariables, rows);
-      SVM.RangeTransform rangeTransform = SVM.RangeTransform.Compute(problem);
-      SVM.Problem scaledProblem = SVM.Scaling.Scale(rangeTransform, problem);
-      var svmModel = SVM.Training.Train(scaledProblem, parameter);
-      nSv = svmModel.SupportVectorCount;
+      parameter.nu = nu;
+      parameter.gamma = gamma;
+      parameter.p = epsilon;
+      parameter.cache_size = 500;
+      parameter.probability = 0;
+      parameter.eps = 0.001;
+      parameter.degree = degree;
+      parameter.shrinking = 1;
+      parameter.coef0 = 0;
+
+
+
+      svm_problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, targetVariable, allowedInputVariables, rows);
+      RangeTransform rangeTransform = RangeTransform.Compute(problem);
+      svm_problem scaledProblem = rangeTransform.Scale(problem);
+      var svmModel = svm.svm_train(scaledProblem, parameter);
+      nSv = svmModel.SV.Length;
       var model = new SupportVectorMachineModel(svmModel, rangeTransform, targetVariable, allowedInputVariables);
       var solution = new SupportVectorRegressionSolution(model, (IRegressionProblemData)problemData.Clone());
@@ -165,4 +184,18 @@
       return solution;
     }
+
+    private static int GetSvmType(string svmType) {
+      if (svmType == "NU_SVR") return svm_parameter.NU_SVR;
+      if (svmType == "EPSILON_SVR") return svm_parameter.EPSILON_SVR;
+      throw new ArgumentException("Unknown SVM type");
+    }
+
+    private static int GetKernelType(string kernelType) {
+      if (kernelType == "LINEAR") return svm_parameter.LINEAR;
+      if (kernelType == "POLY") return svm_parameter.POLY;
+      if (kernelType == "SIGMOID") return svm_parameter.SIGMOID;
+      if (kernelType == "RBF") return svm_parameter.RBF;
+      throw new ArgumentException("Unknown kernel type");
+    }
     #endregion
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionTreeLengthAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionTreeLengthAnalyzer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionTreeLengthAnalyzer.cs	(revision 8742)
@@ -88,5 +88,5 @@
 
     [StorableConstructor]
-    private SymbolicExpressionTreeLengthAnalyzer(bool deserializing) : base() { }
+    private SymbolicExpressionTreeLengthAnalyzer(bool deserializing) : base(deserializing) { }
     private SymbolicExpressionTreeLengthAnalyzer(SymbolicExpressionTreeLengthAnalyzer original, Cloner cloner)
       : base(original, cloner) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 8742)
@@ -227,5 +227,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+   <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -234,4 +234,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+<PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 8742)
@@ -51,5 +51,5 @@
     protected override void UpdateModel(ISymbolicExpressionTree tree) {
       var model = new SymbolicTimeSeriesPrognosisModel(tree, Content.Model.Interpreter);
-      SymbolicTimeSeriesPrognosisModel.Scale(model, Content.ProblemData);
+      SymbolicTimeSeriesPrognosisModel.Scale(model, Content.ProblemData, Content.ProblemData.TargetVariable);
       Content.Model = model;
     }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj	(revision 8742)
@@ -93,6 +93,6 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.5.0, Version=3.5.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
-    <Reference Include="HeuristicLab.ALGLIB-3.5.0, Version=3.5.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Plugin.cs.frame	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Plugin.cs.frame	(revision 8742)
@@ -28,5 +28,5 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis","Provides classes to perform symbolic time-series prognosis.", "3.4.1.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.ALGLIB", "3.4")]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6")]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 8742)
@@ -21,7 +21,4 @@
 
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -33,13 +30,4 @@
   public abstract class SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator : SymbolicDataAnalysisSingleObjectiveEvaluator<ITimeSeriesPrognosisProblemData>, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator {
     private const string HorizonParameterName = "Horizon";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
-
-    public IFixedValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    public bool ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value.Value; }
-      set { ApplyLinearScalingParameter.Value.Value = value; }
-    }
     public IValueLookupParameter<IntValue> HorizonParameter {
       get { return (IValueLookupParameter<IntValue>)Parameters[HorizonParameterName]; }
@@ -54,45 +42,7 @@
     protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator()
       : base() {
-      Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating.", new BoolValue(true)));
       Parameters.Add(new ValueLookupParameter<IntValue>(HorizonParameterName, "The time interval for which the prognosis should be calculated.", new IntValue(1)));
       ApplyLinearScalingParameter.Hidden = true;
     }
-
-
-    [ThreadStatic]
-    private static double[] cache;
-    protected static void CalculateWithScaling(IEnumerable<double> targetValues, IEnumerable<double> estimatedValues,
-      double lowerEstimationLimit, double upperEstimationLimit,
-      IOnlineCalculator calculator, int maxRows) {
-      if (cache == null || cache.GetLength(0) < maxRows) {
-        cache = new double[maxRows];
-      }
-
-      //calculate linear scaling
-      //the static methods of the calculator could not be used as it performs a check if the enumerators have an equal amount of elements
-      //this is not true if the cache is used
-      int i = 0;
-      var linearScalingCalculator = new OnlineLinearScalingParameterCalculator();
-      var targetValuesEnumerator = targetValues.GetEnumerator();
-      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
-      while (targetValuesEnumerator.MoveNext() && estimatedValuesEnumerator.MoveNext()) {
-        double target = targetValuesEnumerator.Current;
-        double estimated = estimatedValuesEnumerator.Current;
-        cache[i] = estimated;
-        linearScalingCalculator.Add(estimated, target);
-        i++;
-      }
-      double alpha = linearScalingCalculator.Alpha;
-      double beta = linearScalingCalculator.Beta;
-
-      //calculate the quality by using the passed online calculator
-      targetValuesEnumerator = targetValues.GetEnumerator();
-      var scaledBoundedEstimatedValuesEnumerator = Enumerable.Range(0, i).Select(x => cache[x] * beta + alpha)
-        .LimitToRange(lowerEstimationLimit, upperEstimationLimit).GetEnumerator();
-
-      while (targetValuesEnumerator.MoveNext() & scaledBoundedEstimatedValuesEnumerator.MoveNext()) {
-        calculator.Add(targetValuesEnumerator.Current, scaledBoundedEstimatedValuesEnumerator.Current);
-      }
-    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 8742)
@@ -53,5 +53,5 @@
         EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
         ProblemDataParameter.ActualValue, rows, EvaluationPartitionParameter.ActualValue,
-        HorizonParameter.ActualValue.Value, ApplyLinearScaling);
+        HorizonParameter.ActualValue.Value, ApplyLinearScalingParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -73,5 +73,5 @@
       } else if (applyLinearScaling) { //first create model to perform linear scaling and afterwards calculate fitness for the scaled model
         var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)solution.Clone(), interpreter, lowerEstimationLimit, upperEstimationLimit);
-        SymbolicTimeSeriesPrognosisModel.Scale(model, problemData);
+        SymbolicTimeSeriesPrognosisModel.Scale(model, problemData, problemData.TargetVariable);
         var scaledSolution = model.SymbolicExpressionTree;
         estimatedValues = interpreter.GetSymbolicExpressionTreeValues(scaledSolution, problemData.Dataset, rows, horizions).SelectMany(x => x);
@@ -94,5 +94,5 @@
       EvaluationPartitionParameter.ExecutionContext = context;
 
-      double mse = Calculate((ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter)SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, EvaluationPartitionParameter.ActualValue, HorizonParameter.ActualValue.Value, ApplyLinearScaling);
+      double mse = Calculate((ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter)SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, EvaluationPartitionParameter.ActualValue, HorizonParameter.ActualValue.Value, ApplyLinearScalingParameter.ActualValue.Value);
 
       HorizonParameter.ExecutionContext = null;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8742)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -38,5 +37,4 @@
     private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     #region parameter properties
     public ILookupParameter<ITimeSeriesPrognosisProblemData> ProblemDataParameter {
@@ -49,14 +47,6 @@
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
     }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
     #endregion
 
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
-    }
-    #endregion
 
     [StorableConstructor]
@@ -68,5 +58,4 @@
       Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic time series prognosis interpreter for the symbolic expression tree."));
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -76,5 +65,5 @@
     protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
       var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value) SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
       return new SymbolicTimeSeriesPrognosisSolution(model, (ITimeSeriesPrognosisProblemData)ProblemDataParameter.ActualValue.Clone());
     }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 8742)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -35,17 +34,7 @@
   public sealed class SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer<ISymbolicTimeSeriesPrognosisSolution, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator, ITimeSeriesPrognosisProblemData>, ISymbolicDataAnalysisBoundedOperator {
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     #region parameter properties
     public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
-    }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
     }
     #endregion
@@ -57,5 +46,4 @@
       : base() {
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -65,5 +53,5 @@
     protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
       var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value) SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
 
       return new SymbolicTimeSeriesPrognosisSolution(model, (ITimeSeriesPrognosisProblemData)ProblemDataParameter.ActualValue.Clone());
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisSolution.cs	(revision 8742)
@@ -25,5 +25,4 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
@@ -63,5 +62,5 @@
       Add(new Result(ModelLengthResultName, "Length of the symbolic regression model.", new IntValue()));
       Add(new Result(ModelDepthResultName, "Depth of the symbolic regression model.", new IntValue()));
-      RecalculateResults();
+      CalculateResults();
     }
 
@@ -72,4 +71,7 @@
     protected override void RecalculateResults() {
       base.RecalculateResults();
+      CalculateResults();
+    }
+    private void CalculateResults() {
       ModelLength = Model.SymbolicExpressionTree.Length;
       ModelDepth = Model.SymbolicExpressionTree.Depth;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj	(revision 8742)
@@ -236,5 +236,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+   <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -243,4 +243,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+<PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs	(revision 8742)
@@ -20,14 +20,9 @@
 #endregion
 
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -39,4 +34,5 @@
     private const string QualitiesParameterName = "Qualities";
     private const string MaximizationParameterName = "Maximization";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     #region parameter properties
     public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
@@ -45,4 +41,7 @@
     public ILookupParameter<BoolArray> MaximizationParameter {
       get { return (ILookupParameter<BoolArray>)Parameters[MaximizationParameterName]; }
+    }
+    public ILookupParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
     }
     #endregion
@@ -64,4 +63,13 @@
       Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>(QualitiesParameterName, "The qualities of the trees that should be analyzed."));
       Parameters.Add(new LookupParameter<BoolArray>(MaximizationParameterName, "The directions of optimization for each dimension."));
+      Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (Parameters.ContainsKey(ApplyLinearScalingParameterName) && Parameters[ApplyLinearScalingParameterName] is LookupParameter<BoolValue>)
+        Parameters.Remove(ApplyLinearScalingParameterName);
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
+        Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs	(revision 8742)
@@ -20,14 +20,9 @@
 #endregion
 
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -39,4 +34,6 @@
     private const string QualityParameterName = "Quality";
     private const string MaximizationParameterName = "Maximization";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+
     #region parameter properties
     public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
@@ -45,4 +42,7 @@
     public ILookupParameter<BoolValue> MaximizationParameter {
       get { return (ILookupParameter<BoolValue>)Parameters[MaximizationParameterName]; }
+    }
+    public ILookupParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
     }
     #endregion
@@ -64,4 +64,13 @@
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName, "The qualities of the trees that should be analyzed."));
       Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName, "The direction of optimization."));
+      Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (Parameters.ContainsKey(ApplyLinearScalingParameterName) && !(Parameters[ApplyLinearScalingParameterName] is LookupParameter<BoolValue>))
+        Parameters.Remove(ApplyLinearScalingParameterName);
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
+        Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisVariableFrequencyAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisVariableFrequencyAnalyzer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisVariableFrequencyAnalyzer.cs	(revision 8742)
@@ -109,5 +109,5 @@
       // update variable impacts matrix
       var orderedImpacts = (from row in datatable.Rows
-                            select new { Name = row.Name, Impact = datatable.Rows[row.Name].Values.Average() })
+                            select new { Name = row.Name, Impact = Math.Round(datatable.Rows[row.Name].Values.Average(), 3) })
                            .OrderByDescending(p => p.Impact)
                            .ToList();
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs	(revision 8742)
@@ -44,4 +44,5 @@
     private const string EvaluationPartitionParameterName = "EvaluationPartition";
     private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     private const string ValidRowIndicatorParameterName = "ValidRowIndicator";
 
@@ -71,4 +72,7 @@
       get { return (IValueLookupParameter<PercentValue>)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
     }
+    public ILookupParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
     public IValueLookupParameter<StringValue> ValidRowIndicatorParameter {
       get { return (IValueLookupParameter<StringValue>)Parameters[ValidRowIndicatorParameterName]; }
@@ -91,4 +95,5 @@
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The upper and lower limit that should be used as cut off value for the output values of symbolic data analysis trees."));
       Parameters.Add(new ValueLookupParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index."));
+      Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
       Parameters.Add(new ValueLookupParameter<StringValue>(ValidRowIndicatorParameterName, "An indicator variable in the data set that specifies which rows should be evaluated (those for which the indicator <> 0) (optional)."));
     }
@@ -96,4 +101,8 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
+      if (Parameters.ContainsKey(ApplyLinearScalingParameterName) && !(Parameters[ApplyLinearScalingParameterName] is LookupParameter<BoolValue>))
+        Parameters.Remove(ApplyLinearScalingParameterName);
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
+        Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
       if (!Parameters.ContainsKey(ValidRowIndicatorParameterName))
         Parameters.Add(new ValueLookupParameter<StringValue>(ValidRowIndicatorParameterName, "An indicator variable in the data set that specifies which rows should be evaluated (those for which the indicator <> 0) (optional)."));
@@ -105,5 +114,4 @@
 
     protected IEnumerable<int> GenerateRowsToEvaluate(double percentageOfRows) {
-
       IEnumerable<int> rows;
       int samplesStart = EvaluationPartitionParameter.ActualValue.Start;
@@ -131,4 +139,48 @@
       return rows;
     }
+
+    [ThreadStatic]
+    private static double[] cache;
+    protected static void CalculateWithScaling(IEnumerable<double> targetValues, IEnumerable<double> estimatedValues,
+      double lowerEstimationLimit, double upperEstimationLimit,
+      IOnlineCalculator calculator, int maxRows) {
+      if (cache == null || cache.GetLength(0) < maxRows) {
+        cache = new double[maxRows];
+      }
+
+      //calculate linear scaling
+      //the static methods of the calculator could not be used as it performs a check if the enumerators have an equal amount of elements
+      //this is not true if the cache is used
+      int i = 0;
+      var linearScalingCalculator = new OnlineLinearScalingParameterCalculator();
+      var targetValuesEnumerator = targetValues.GetEnumerator();
+      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
+      while (targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) {
+        double target = targetValuesEnumerator.Current;
+        double estimated = estimatedValuesEnumerator.Current;
+        cache[i] = estimated;
+        if (!double.IsNaN(estimated) && !double.IsInfinity(estimated))
+          linearScalingCalculator.Add(estimated, target);
+        i++;
+      }
+      if (linearScalingCalculator.ErrorState == OnlineCalculatorError.None && (targetValuesEnumerator.MoveNext() || estimatedValuesEnumerator.MoveNext()))
+        throw new ArgumentException("Number of elements in target and estimated values enumeration do not match.");
+
+      double alpha = linearScalingCalculator.Alpha;
+      double beta = linearScalingCalculator.Beta;
+      if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) {
+        alpha = 0.0;
+        beta = 1.0;
+      }
+
+      //calculate the quality by using the passed online calculator
+      targetValuesEnumerator = targetValues.GetEnumerator();
+      var scaledBoundedEstimatedValuesEnumerator = Enumerable.Range(0, i).Select(x => cache[x] * beta + alpha)
+        .LimitToRange(lowerEstimationLimit, upperEstimationLimit).GetEnumerator();
+
+      while (targetValuesEnumerator.MoveNext() & scaledBoundedEstimatedValuesEnumerator.MoveNext()) {
+        calculator.Add(targetValuesEnumerator.Current, scaledBoundedEstimatedValuesEnumerator.Current);
+      }
+    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 8742)
@@ -93,9 +93,8 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.5.0, Version=3.5.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\bin\ALGLIB-3.5.0.dll</HintPath>
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.6.0.dll</HintPath>
       <Private>False</Private>
     </Reference>
-    <Reference Include="HeuristicLab.ALGLIB-3.5.0, Version=3.5.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
@@ -280,5 +279,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -287,4 +286,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisEvaluator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisEvaluator.cs	(revision 8742)
@@ -29,4 +29,5 @@
     IValueLookupParameter<IntRange> EvaluationPartitionParameter { get; }
     IValueLookupParameter<PercentValue> RelativeNumberOfEvaluatedSamplesParameter { get; }
+    ILookupParameter<BoolValue> ApplyLinearScalingParameter { get; }
 
     IValueLookupParameter<T> ProblemDataParameter { get; }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisMultiObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisMultiObjectiveAnalyzer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisMultiObjectiveAnalyzer.cs	(revision 8742)
@@ -21,11 +21,9 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   public interface ISymbolicDataAnalysisMultiObjectiveAnalyzer : ISymbolicDataAnalysisAnalyzer {
     IScopeTreeLookupParameter<DoubleArray> QualitiesParameter { get; }
     ILookupParameter<BoolArray> MaximizationParameter { get; }
+    ILookupParameter<BoolValue> ApplyLinearScalingParameter { get; }
 
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisSingleObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisSingleObjectiveAnalyzer.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisSingleObjectiveAnalyzer.cs	(revision 8742)
@@ -28,4 +28,5 @@
     IScopeTreeLookupParameter<DoubleValue> QualityParameter { get; }
     ILookupParameter<BoolValue> MaximizationParameter { get; }
+    ILookupParameter<BoolValue> ApplyLinearScalingParameter { get; }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 8742)
@@ -28,5 +28,5 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic","Provides base classes for symbolic data analysis tasks.", "3.4.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.ALGLIB", "3.5.0")]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6.0")]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModel.cs	(revision 8742)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Drawing;
 using HeuristicLab.Common;
@@ -66,4 +67,87 @@
       this.interpreter = interpreter;
     }
+
+    #region Scaling
+    public static void Scale(ISymbolicDataAnalysisModel model, IDataAnalysisProblemData problemData, string targetVariable) {
+      var dataset = problemData.Dataset;
+      var rows = problemData.TrainingIndices;
+      var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, rows);
+      var targetValues = dataset.GetDoubleValues(targetVariable, rows);
+
+      var linearScalingCalculator = new OnlineLinearScalingParameterCalculator();
+      var targetValuesEnumerator = targetValues.GetEnumerator();
+      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
+      while (targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) {
+        double target = targetValuesEnumerator.Current;
+        double estimated = estimatedValuesEnumerator.Current;
+        if (!double.IsNaN(estimated) && !double.IsInfinity(estimated))
+          linearScalingCalculator.Add(estimated, target);
+      }
+      if (linearScalingCalculator.ErrorState == OnlineCalculatorError.None && (targetValuesEnumerator.MoveNext() || estimatedValuesEnumerator.MoveNext()))
+        throw new ArgumentException("Number of elements in target and estimated values enumeration do not match.");
+
+      double alpha = linearScalingCalculator.Alpha;
+      double beta = linearScalingCalculator.Beta;
+      if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) return;
+
+      ConstantTreeNode alphaTreeNode = null;
+      ConstantTreeNode betaTreeNode = null;
+      // check if model has been scaled previously by analyzing the structure of the tree
+      var startNode = model.SymbolicExpressionTree.Root.GetSubtree(0);
+      if (startNode.GetSubtree(0).Symbol is Addition) {
+        var addNode = startNode.GetSubtree(0);
+        if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) {
+          alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode;
+          var mulNode = addNode.GetSubtree(0);
+          if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) {
+            betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode;
+          }
+        }
+      }
+      // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes
+      if (alphaTreeNode != null && betaTreeNode != null) {
+        betaTreeNode.Value *= beta;
+        alphaTreeNode.Value *= beta;
+        alphaTreeNode.Value += alpha;
+      } else {
+        var mainBranch = startNode.GetSubtree(0);
+        startNode.RemoveSubtree(0);
+        var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha);
+        startNode.AddSubtree(scaledMainBranch);
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode treeNode, double alpha) {
+      if (alpha.IsAlmost(0.0)) {
+        return treeNode;
+      } else {
+        var addition = new Addition();
+        var node = addition.CreateTreeNode();
+        var alphaConst = MakeConstant(alpha);
+        node.AddSubtree(treeNode);
+        node.AddSubtree(alphaConst);
+        return node;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode treeNode, double beta) {
+      if (beta.IsAlmost(1.0)) {
+        return treeNode;
+      } else {
+        var multipliciation = new Multiplication();
+        var node = multipliciation.CreateTreeNode();
+        var betaConst = MakeConstant(beta);
+        node.AddSubtree(treeNode);
+        node.AddSubtree(betaConst);
+        return node;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeConstant(double c) {
+      var node = (ConstantTreeNode)(new Constant()).CreateTreeNode();
+      node.Value = c;
+      return node;
+    }
+    #endregion
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 8742)
@@ -53,4 +53,5 @@
     private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition";
     private const string ValidationPartitionParameterName = "ValidationPartition";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
 
     private const string ProblemDataParameterDescription = "";
@@ -64,4 +65,5 @@
     private const string FitnessCalculationPartitionParameterDescription = "The partition of the problem data training partition, that should be used to calculate the fitness of an individual.";
     private const string ValidationPartitionParameterDescription = "The partition of the problem data training partition, that should be used to select the best model from (optional).";
+    private const string ApplyLinearScalingParameterDescription = "Flag that indicates if the individual should be linearly scaled before evaluating.";
     #endregion
 
@@ -100,4 +102,7 @@
       get { return (IFixedValueParameter<IntRange>)Parameters[ValidationPartitionParameterName]; }
     }
+    public IFixedValueParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
     #endregion
 
@@ -144,4 +149,7 @@
     public IntRange ValidationPartition {
       get { return ValidationPartitionParameter.Value; }
+    }
+    public BoolValue ApplyLinearScaling {
+      get { return ApplyLinearScalingParameter.Value; }
     }
     #endregion
@@ -151,4 +159,14 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, ApplyLinearScalingParameterDescription, new BoolValue(false)));
+        ApplyLinearScalingParameter.Hidden = true;
+
+        //it is assumed that for all symbolic regression algorithms linear scaling was set to true
+        //there is no possibility to determine the previous value of the parameter as it was stored in the evaluator
+        if (GetType().Name.Contains("SymbolicRegression"))
+          ApplyLinearScaling.Value = true;
+      }
+
       RegisterEventHandlers();
     }
@@ -170,8 +188,10 @@
       Parameters.Add(new FixedValueParameter<IntRange>(ValidationPartitionParameterName, ValidationPartitionParameterDescription));
       Parameters.Add(new FixedValueParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, RelativeNumberOfEvaluatedSamplesParameterDescription, new PercentValue(1)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, ApplyLinearScalingParameterDescription, new BoolValue(false)));
 
       SymbolicExpressionTreeInterpreterParameter.Hidden = true;
       MaximumFunctionArgumentsParameter.Hidden = true;
       MaximumFunctionDefinitionsParameter.Hidden = true;
+      ApplyLinearScalingParameter.Hidden = true;
 
       SymbolicExpressionTreeGrammar = new TypeCoherentExpressionGrammar();
@@ -274,13 +294,13 @@
 
       foreach (var op in operators.OfType<ISymbolicExpressionTreeGrammarBasedOperator>()) {
-        op.SymbolicExpressionTreeGrammarParameter.ActualName = SymbolicExpressionTreeGrammarParameterName;
+        op.SymbolicExpressionTreeGrammarParameter.ActualName = SymbolicExpressionTreeGrammarParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicExpressionTreeSizeConstraintOperator>()) {
-        op.MaximumSymbolicExpressionTreeDepthParameter.ActualName = MaximumSymbolicExpressionTreeDepthParameterName;
-        op.MaximumSymbolicExpressionTreeLengthParameter.ActualName = MaximumSymbolicExpressionTreeLengthParameterName;
+        op.MaximumSymbolicExpressionTreeDepthParameter.ActualName = MaximumSymbolicExpressionTreeDepthParameter.Name;
+        op.MaximumSymbolicExpressionTreeLengthParameter.ActualName = MaximumSymbolicExpressionTreeLengthParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicExpressionTreeArchitectureAlteringOperator>()) {
-        op.MaximumFunctionArgumentsParameter.ActualName = MaximumFunctionArgumentsParameterName;
-        op.MaximumFunctionDefinitionsParameter.ActualName = MaximumFunctionDefinitionsParameterName;
+        op.MaximumFunctionArgumentsParameter.ActualName = MaximumFunctionArgumentsParameter.Name;
+        op.MaximumFunctionDefinitionsParameter.ActualName = MaximumFunctionDefinitionsParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicDataAnalysisEvaluator<T>>()) {
@@ -289,4 +309,5 @@
         op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameter.Name;
         op.RelativeNumberOfEvaluatedSamplesParameter.ActualName = RelativeNumberOfEvaluatedSamplesParameter.Name;
+        op.ApplyLinearScalingParameter.ActualName = ApplyLinearScalingParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicExpressionTreeCrossover>()) {
@@ -300,4 +321,10 @@
         op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
       }
+      foreach (var op in operators.OfType<ISymbolicDataAnalysisSingleObjectiveAnalyzer>()) {
+        op.ApplyLinearScalingParameter.ActualName = ApplyLinearScalingParameter.Name;
+      }
+      foreach (var op in operators.OfType<ISymbolicDataAnalysisMultiObjectiveAnalyzer>()) {
+        op.ApplyLinearScalingParameter.ActualName = ApplyLinearScalingParameter.Name;
+      }
       foreach (var op in operators.OfType<ISymbolicDataAnalysisAnalyzer>()) {
         op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
@@ -308,8 +335,8 @@
       }
       foreach (var op in operators.OfType<ISymbolicDataAnalysisInterpreterOperator>()) {
-        op.SymbolicDataAnalysisTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameterName;
+        op.SymbolicDataAnalysisTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicDataAnalysisExpressionCrossover<T>>()) {
-        op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameterName;
+        op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameter.Name;
         op.ProblemDataParameter.ActualName = ProblemDataParameter.Name;
         op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameter.Name;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs	(revision 8742)
@@ -96,5 +96,5 @@
       }
 
-      int classValuesCount = Content.ProblemData.ClassValues.Count;
+      int classValuesCount = Content.ProblemData.Classes;
       int solutionsCount = Content.ClassificationSolutions.Count();
       string[,] values = new string[indices.Length, 5 + classValuesCount + solutionsCount];
@@ -114,8 +114,7 @@
             estimatedValuesVector[i].GroupBy(x => x).Select(g => new { Key = g.Key, Count = g.Count() }).ToList();
           var estimationCount = groups.Where(g => g.Key != null).Select(g => g.Count).Sum();
-          values[i, 4] =
-            (((double)groups.Where(g => g.Key == estimatedClassValues[i]).Single().Count) / estimationCount).ToString();
-          for (int classIndex = 0; classIndex < Content.ProblemData.ClassValues.Count; classIndex++) {
-            var group = groups.Where(g => g.Key == Content.ProblemData.ClassValues[classIndex]).SingleOrDefault();
+          values[i, 4] = (((double)groups.Where(g => g.Key == estimatedClassValues[i]).Single().Count) / estimationCount).ToString();
+          for (int classIndex = 0; classIndex < Content.ProblemData.Classes; classIndex++) {
+            var group = groups.Where(g => g.Key == Content.ProblemData.ClassValues.ElementAt(classIndex)).SingleOrDefault();
             if (group == null) values[i, 5 + classIndex] = 0.ToString();
             else values[i, 5 + classIndex] = group.Count.ToString();
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs	(revision 8742)
@@ -20,7 +20,9 @@
 #endregion
 
+using System;
 using System.Linq;
 using System.Windows.Forms;
 using HeuristicLab.Common;
+using HeuristicLab.Core;
 using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
@@ -83,6 +85,30 @@
             solutions = solutions.Select(s => cloner.Clone(s));
           }
-          foreach (var solution in solutions)
-            Content.Add(solution);
+          var solutionCollection = Content as ItemCollection<IClassificationSolution>;
+          if (solutionCollection != null) {
+            solutionCollection.AddRange(solutions);
+          } else {
+            foreach (var solution in solutions)
+              Content.Add(solution);
+          }
+        }
+      }
+      protected override void itemsListView_KeyDown(object sender, KeyEventArgs e) {
+        var solutionCollection = Content as ItemCollection<IClassificationSolution>;
+        if (e.KeyCode == Keys.Delete && solutionCollection != null) {
+          if ((itemsListView.SelectedItems.Count > 0) && !Content.IsReadOnly && !ReadOnly) {
+            solutionCollection.RemoveRange(itemsListView.SelectedItems.Cast<ListViewItem>().Select(x => (IClassificationSolution)x.Tag));
+          }
+        } else {
+          base.itemsListView_KeyDown(sender, e);
+        }
+      }
+      protected override void removeButton_Click(object sender, EventArgs e) {
+        var solutionCollection = Content as ItemCollection<IClassificationSolution>;
+        if (itemsListView.SelectedItems.Count > 0 && solutionCollection != null) {
+          solutionCollection.RemoveRange(itemsListView.SelectedItems.Cast<ListViewItem>().Select(x => (IClassificationSolution)x.Tag));
+          itemsListView.SelectedItems.Clear();
+        } else {
+          base.removeButton_Click(sender, e);
         }
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.Designer.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.Designer.cs	(revision 8742)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationFeatureCorrelationView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.cs	(revision 8742)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Classification Feature Correlation View")]
+  [Content(typeof(ClassificationProblemData), false)]
+  public partial class ClassificationFeatureCorrelationView : FeatureCorrelationView {
+
+    public new ClassificationProblemData Content {
+      get { return (ClassificationProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ClassificationFeatureCorrelationView() {
+      InitializeComponent();
+    }
+
+    protected override bool[] SetInitialVisibilityOfColumns() {
+      int i = Content.Dataset.DoubleVariables.ToList().FindIndex(x => x == Content.TargetVariable);
+      var initialVisibility = base.SetInitialVisibilityOfColumns();
+      initialVisibility[i] = true;
+      return initialVisibility;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.Designer.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.Designer.cs	(revision 8742)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationTimeframeFeatureCorrelationView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.cs	(revision 8742)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Classification Timeframe Feature Correlation View")]
+  [Content(typeof(ClassificationProblemData), false)]
+  public partial class ClassificationTimeframeFeatureCorrelationView : TimeframeFeatureCorrelationView {
+
+    public new ClassificationProblemData Content {
+      get { return (ClassificationProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ClassificationTimeframeFeatureCorrelationView() {
+      InitializeComponent();
+    }
+
+    protected override bool[] SetInitialVisibilityOfColumns() {
+      int i = Content.Dataset.DoubleVariables.ToList().FindIndex(x => x == Content.TargetVariable);
+      var initialVisibility = base.SetInitialVisibilityOfColumns();
+      initialVisibility[i] = true;
+      return initialVisibility;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.Designer.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.Designer.cs	(revision 8742)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DiscriminantFunctionClassificationModelView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.SuspendLayout();
+
+      // 
+      // RegressionSolutionEnsembleModelView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "DiscriminantFunctionClassificationModelView";
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.cs	(revision 8742)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Discriminant Function Classification Model")]
+  [Content(typeof(DiscriminantFunctionClassificationModel), true)]
+  internal sealed partial class DiscriminantFunctionClassificationModelView : AsynchronousContentView {
+    private ViewHost view;
+
+    public DiscriminantFunctionClassificationModelView() {
+      InitializeComponent();
+      view = new ViewHost();
+      view.Dock = DockStyle.Fill;
+      Controls.Add(view);
+    }
+
+    public new DiscriminantFunctionClassificationModel Content {
+      get { return (DiscriminantFunctionClassificationModel)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        view.Content = Content.Model;
+      } else
+        view.Content = null;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 8742)
@@ -114,5 +114,5 @@
         maxThreshold += thresholdIncrement;
 
-        List<double> classValues = Content.ProblemData.ClassValues.OrderBy(x => x).ToList();
+        List<double> classValues = Content.Model.ClassValues.ToList();
 
         foreach (double classValue in classValues) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 8742)
@@ -238,4 +238,5 @@
       double[] thresholds = Content.Model.Thresholds.ToArray();
       thresholds[classIndex] = e.NewLocationY;
+      Array.Sort(thresholds);
       Content.Model.SetThresholdsAndClassValues(thresholds, Content.Model.ClassValues);
     }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.Designer.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.Designer.cs	(revision 8742)
@@ -0,0 +1,116 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClusteringSolutionVisualizationView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.rangeComboBox = new System.Windows.Forms.ComboBox();
+      this.rangeLabel = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.IsSplitterFixed = true;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.rangeComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.rangeLabel);
+      this.splitContainer.Size = new System.Drawing.Size(438, 198);
+      this.splitContainer.SplitterDistance = 27;
+      this.splitContainer.TabIndex = 1;
+      // 
+      // rangeComboBox
+      // 
+      this.rangeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.rangeComboBox.FormattingEnabled = true;
+      this.rangeComboBox.Items.AddRange(new object[] {
+            "Training samples",
+            "Test samples",
+            "All samples"});
+      this.rangeComboBox.Location = new System.Drawing.Point(56, 3);
+      this.rangeComboBox.Name = "rangeComboBox";
+      this.rangeComboBox.Size = new System.Drawing.Size(146, 21);
+      this.rangeComboBox.TabIndex = 1;
+      this.rangeComboBox.SelectedIndexChanged += new System.EventHandler(this.rangeComboBox_SelectedIndexChanged);
+      // 
+      // rangeLabel
+      // 
+      this.rangeLabel.AutoSize = true;
+      this.rangeLabel.Location = new System.Drawing.Point(3, 6);
+      this.rangeLabel.Name = "rangeLabel";
+      this.rangeLabel.Size = new System.Drawing.Size(47, 13);
+      this.rangeLabel.TabIndex = 0;
+      this.rangeLabel.Text = "Samples";
+      // 
+      // ClusteringSolutionVisualizationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "ClusteringSolutionVisualizationView";
+      this.Size = new System.Drawing.Size(438, 198);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.ComboBox rangeComboBox;
+    private System.Windows.Forms.Label rangeLabel;
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.cs	(revision 8742)
@@ -0,0 +1,133 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 System.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Cluster Visualization")]
+  [Content(typeof(IClusteringSolution), IsDefaultView = false)]
+  public partial class ClusteringSolutionVisualizationView : DataAnalysisSolutionEvaluationView {
+    private ViewHost viewHost = new ViewHost();
+    private ScatterPlot scatterPlot = new ScatterPlot();
+
+    public new IClusteringSolution Content {
+      get { return (IClusteringSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ClusteringSolutionVisualizationView() {
+      InitializeComponent();
+      viewHost.Dock = DockStyle.Fill;
+      splitContainer.Panel2.Controls.Add(viewHost);
+      rangeComboBox.SelectedIndex = 0;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        viewHost.Content = null;
+        scatterPlot.Rows.Clear();
+      } else {
+        UpdateScatterPlot();
+        viewHost.Content = scatterPlot;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      rangeComboBox.Enabled = Content != null;
+    }
+
+    private void UpdateScatterPlot() {
+      scatterPlot.Rows.Clear();
+
+      IEnumerable<int> range = null;
+      if (rangeComboBox.SelectedIndex == 0) range = Content.ProblemData.TrainingIndices;
+      else if (rangeComboBox.SelectedIndex == 1) range = Content.ProblemData.TestIndices;
+      else range = Enumerable.Range(0, Content.ProblemData.Dataset.Rows);
+
+      IDictionary<int, Tuple<double, string>> classes = Content.Model.GetClusterValues(Content.ProblemData.Dataset, Enumerable.Range(0, Content.ProblemData.Dataset.Rows))
+          .Select((v, i) => new { Row = i, Cluster = (double)v })
+          .ToDictionary(x => x.Row, y => Tuple.Create(y.Cluster, "Cluster " + y.Cluster));
+
+      var rows = classes.Values.Select(x => x.Item2).Distinct().ToDictionary(c => c, c => new ScatterPlotDataRow(c, string.Empty, Enumerable.Empty<Point2D<double>>()));
+
+      var reduced = PCAReduce(Content.ProblemData.Dataset, range, Content.ProblemData.AllowedInputVariables, Content.Model);
+
+      int idx = 0;
+      foreach (var r in range) {
+        rows[classes[r].Item2].Points.Add(new Point2D<double>(reduced[idx, 0], reduced[idx, 1]));
+        idx++;
+      }
+
+      scatterPlot.Rows.AddRange(rows.Values);
+    }
+
+    private static double[,] PCAReduce(Dataset dataset, IEnumerable<int> rows, IEnumerable<string> variables, IDataAnalysisModel model) {
+      var clusteringModel = model as IClusteringModel;
+      if (clusteringModel == null) return new double[0, 0];
+
+      var instances = rows.ToArray();
+      var attributes = variables.ToArray();
+      var data = new double[instances.Length, attributes.Length + 1];
+
+      for (int j = 0; j < attributes.Length; j++) {
+        int i = 0;
+        var values = dataset.GetDoubleValues(attributes[j], instances);
+        foreach (var v in values) {
+          data[i++, j] = v;
+        }
+      }
+      int info;
+      double[] variances;
+      var matrix = new double[0, 0];
+      alglib.pcabuildbasis(data, instances.Length, attributes.Length, out info, out variances, out matrix);
+
+      var result = new double[instances.Length, 2];
+      int r = 0;
+      foreach (var inst in instances) {
+        int i = 0;
+        foreach (var attrib in attributes) {
+          double val = dataset.GetDoubleValue(attrib, inst);
+          for (int j = 0; j < result.GetLength(1); j++)
+            result[r, j] += val * matrix[i, j];
+          i++;
+        }
+        r++;
+      }
+
+      return result;
+    }
+
+    #region Event Handlers
+    private void rangeComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
+      if (Content != null) UpdateScatterPlot();
+    }
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 8742)
@@ -93,5 +93,10 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="HeuristicLab.ALGLIB-3.4.0, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\bin\ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Analysis.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
@@ -137,4 +142,34 @@
       <DependentUpon>ClassificationEnsembleSolutionModelView.cs</DependentUpon>
     </Compile>
+    <Compile Include="Classification\ClassificationFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationFeatureCorrelationView.Designer.cs">
+      <DependentUpon>ClassificationFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\ClassificationTimeframeFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationTimeframeFeatureCorrelationView.Designer.cs">
+      <DependentUpon>ClassificationTimeframeFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationModelView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationModelView.Designer.cs">
+      <DependentUpon>DiscriminantFunctionClassificationModelView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Clustering\ClusteringSolutionVisualizationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Clustering\ClusteringSolutionVisualizationView.Designer.cs">
+      <DependentUpon>ClusteringSolutionVisualizationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FeatureCorrelation\AbstractFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FeatureCorrelation\AbstractFeatureCorrelationView.Designer.cs">
+      <DependentUpon>AbstractFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
     <Compile Include="DataAnalysisSolutionEvaluationView.cs">
       <SubType>UserControl</SubType>
@@ -143,5 +178,39 @@
       <DependentUpon>DataAnalysisSolutionEvaluationView.cs</DependentUpon>
     </Compile>
+    <Compile Include="FeatureCorrelation\FeatureCorrelationCalculator.cs" />
+    <Compile Include="FeatureCorrelation\FeatureCorrelationEnums.cs" />
+    <Compile Include="FeatureCorrelation\VariableVisibilityDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="FeatureCorrelation\VariableVisibilityDialog.Designer.cs">
+      <DependentUpon>VariableVisibilityDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FeatureCorrelation\FeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FeatureCorrelation\FeatureCorrelationView.Designer.cs">
+      <DependentUpon>FeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FeatureCorrelation\FeatureCorrelationCache.cs" />
+    <Compile Include="FeatureCorrelation\FeatureCorrelationTimeframeCache.cs" />
     <Compile Include="Plugin.cs" />
+    <Compile Include="ProblemDataView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ProblemDataView.Designer.cs">
+      <DependentUpon>ProblemDataView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionFeatureCorrelationView.Designer.cs">
+      <DependentUpon>RegressionFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionTimeframeFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionTimeframeFeatureCorrelationView.Designer.cs">
+      <DependentUpon>RegressionTimeframeFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Regression\RegressionEnsembleSolutionModelView.cs">
       <SubType>UserControl</SubType>
@@ -278,9 +347,9 @@
       <DependentUpon>RegressionSolutionView.cs</DependentUpon>
     </Compile>
-    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs">
-      <DependentUpon>TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
+    <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationView.Designer.cs">
+      <DependentUpon>TimeframeFeatureCorrelationView.cs</DependentUpon>
     </Compile>
     <None Include="HeuristicLab.snk" />
@@ -288,4 +357,15 @@
     <None Include="Properties\AssemblyInfo.cs.frame" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Algorithms.DataAnalysis\3.4\HeuristicLab.Algorithms.DataAnalysis-3.4.csproj">
+      <Project>{2E782078-FA81-4B70-B56F-74CE38DAC6C8}</Project>
+      <Name>HeuristicLab.Algorithms.DataAnalysis-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
+      <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+      <Private>False</Private>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
@@ -308,8 +388,7 @@
   <ItemGroup />
   <ItemGroup>
-    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
-      <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
-      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
-    </ProjectReference>
+    <EmbeddedResource Include="FeatureCorrelation\AbstractFeatureCorrelationView.resx">
+      <DependentUpon>AbstractFeatureCorrelationView.cs</DependentUpon>
+    </EmbeddedResource>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
@@ -322,5 +401,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -329,4 +408,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame	(revision 8742)
@@ -28,4 +28,7 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Views", "Provides views for base classes for data analysis tasks.", "3.4.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Views-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6.0")]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
   [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs	(revision 8742)
@@ -0,0 +1,74 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ProblemDataView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.FeatureCorrelationButton = new System.Windows.Forms.Button();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.AllowDrop = true;
+      this.parameterCollectionView.DragDrop += new System.Windows.Forms.DragEventHandler(this.parameterCollectionView_DragDrop);
+      this.parameterCollectionView.DragEnter += new System.Windows.Forms.DragEventHandler(this.parameterCollectionView_DragEnterOver);
+      this.parameterCollectionView.DragOver += new System.Windows.Forms.DragEventHandler(this.parameterCollectionView_DragEnterOver);
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      // 
+      // FeatureCorrelationButton
+      // 
+      this.FeatureCorrelationButton.Location = new System.Drawing.Point(184, 45);
+      this.FeatureCorrelationButton.Name = "FeatureCorrelationButton";
+      this.FeatureCorrelationButton.Size = new System.Drawing.Size(121, 24);
+      this.FeatureCorrelationButton.TabIndex = 4;
+      this.FeatureCorrelationButton.Text = "Feature Correlation";
+      this.FeatureCorrelationButton.UseVisualStyleBackColor = true;
+      this.FeatureCorrelationButton.Click += new System.EventHandler(this.FeatureCorrelationButton_Click);
+      // 
+      // ProblemDataView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.FeatureCorrelationButton);
+      this.Name = "ProblemDataView";
+      this.Controls.SetChildIndex(this.parameterCollectionView, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.FeatureCorrelationButton, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.Button FeatureCorrelationButton;
+
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs	(revision 8742)
@@ -0,0 +1,103 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Problem Data View")]
+  [Content(typeof(DataAnalysisProblemData), true)]
+  public partial class ProblemDataView : ParameterizedNamedItemView {
+
+    public new DataAnalysisProblemData Content {
+      get { return (DataAnalysisProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ProblemDataView() {
+      InitializeComponent();
+    }
+
+    protected void FeatureCorrelationButton_Click(object sender, System.EventArgs e) {
+      Type viewType = MainFormManager.GetViewTypes(this.Content.GetType(), true).FirstOrDefault(t => typeof(AbstractFeatureCorrelationView).IsAssignableFrom(t));
+      MainFormManager.MainForm.ShowContent(Content, viewType);
+    }
+
+    protected void parameterCollectionView_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        var stringValueList = (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IFixedValueParameter).Value as ICheckedItemList<StringValue>;
+        SetInputVariables(stringValueList);
+      }
+    }
+
+    private void SetInputVariables(ICheckedItemList<StringValue> stringValueList) {
+      var inputVariables = Content.InputVariables;
+      var stringValues = stringValueList.Select(x => x.Value);
+      var notContainedVariables = inputVariables.Where(x => !stringValues.Contains(x.Value));
+
+      if (notContainedVariables.Count() != 0) {
+        StringBuilder strBuilder = new StringBuilder();
+        foreach (var variable in notContainedVariables) {
+          strBuilder.Append(variable.Value + ", ");
+        }
+        strBuilder.Remove(strBuilder.Length - 2, 2);
+        MessageBox.Show(String.Format("There was an error while changing the input variables. The following input " +
+          "variables have not been contained {0}", strBuilder.ToString()), "Error while changing the input variables",
+          MessageBoxButtons.OK, MessageBoxIcon.Warning);
+      } else {
+        var checkedItems = stringValueList.CheckedItems.Select(x => x.Value.Value);
+        var setChecked = inputVariables.Where(x => checkedItems.Contains(x.Value));
+        foreach (var variable in inputVariables) {
+          if (setChecked.Contains(variable) && !inputVariables.ItemChecked(variable)) {
+            inputVariables.SetItemCheckedState(variable, true);
+          } else if (!setChecked.Contains(variable) && inputVariables.ItemChecked(variable)) {
+            inputVariables.SetItemCheckedState(variable, false);
+          }
+        }
+      }
+    }
+
+    protected void parameterCollectionView_DragEnterOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (ReadOnly)
+        return;
+      if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) == null)
+        return;
+
+      var parameter = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IFixedValueParameter;
+      if (parameter == null)
+        return;
+
+      var stringValueList = parameter.Value as ICheckedItemList<StringValue>;
+      if (stringValueList == null)
+        return;
+
+      e.Effect = e.AllowedEffect;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 8742)
@@ -20,7 +20,9 @@
 #endregion
 
+using System;
 using System.Linq;
 using System.Windows.Forms;
 using HeuristicLab.Common;
+using HeuristicLab.Core;
 using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
@@ -83,6 +85,30 @@
             solutions = solutions.Select(s => cloner.Clone(s));
           }
-          foreach (var solution in solutions)
-            Content.Add(solution);
+          var solutionCollection = Content as ItemCollection<IRegressionSolution>;
+          if (solutionCollection != null) {
+            solutionCollection.AddRange(solutions);
+          } else {
+            foreach (var solution in solutions)
+              Content.Add(solution);
+          }
+        }
+      }
+      protected override void itemsListView_KeyDown(object sender, KeyEventArgs e) {
+        var solutionCollection = Content as ItemCollection<IRegressionSolution>;
+        if (e.KeyCode == Keys.Delete && solutionCollection != null) {
+          if ((itemsListView.SelectedItems.Count > 0) && !Content.IsReadOnly && !ReadOnly) {
+            solutionCollection.RemoveRange(itemsListView.SelectedItems.Cast<ListViewItem>().Select(x => (IRegressionSolution)x.Tag));
+          }
+        } else {
+          base.itemsListView_KeyDown(sender, e);
+        }
+      }
+      protected override void removeButton_Click(object sender, EventArgs e) {
+        var solutionCollection = Content as ItemCollection<IRegressionSolution>;
+        if (itemsListView.SelectedItems.Count > 0 && solutionCollection != null) {
+          solutionCollection.RemoveRange(itemsListView.SelectedItems.Cast<ListViewItem>().Select(x => (IRegressionSolution)x.Tag));
+          itemsListView.SelectedItems.Clear();
+        } else {
+          base.removeButton_Click(sender, e);
         }
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.Designer.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.Designer.cs	(revision 8742)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionFeatureCorrelationView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.cs	(revision 8742)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Regression Feature Correlation View")]
+  [Content(typeof(RegressionProblemData), false)]
+  public partial class RegressionFeatureCorrelationView : FeatureCorrelationView {
+
+    public new RegressionProblemData Content {
+      get { return (RegressionProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionFeatureCorrelationView() {
+      InitializeComponent();
+    }
+
+    protected override bool[] SetInitialVisibilityOfColumns() {
+      int i = Content.Dataset.DoubleVariables.ToList().FindIndex(x => x == Content.TargetVariable);
+      var initialVisibility = base.SetInitialVisibilityOfColumns();
+      initialVisibility[i] = true;
+      return initialVisibility;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 8742)
@@ -89,6 +89,8 @@
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].LegendText = ESTIMATEDVALUES_ALL_SERIES_NAME;
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].ChartType = SeriesChartType.FastLine;
-        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndices, allEstimatedValues);
-        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+        if (allEstimatedValues.Count > 0) {
+          this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndices, allEstimatedValues);
+          this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+        }
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Tag = Content;
         this.ToggleSeriesData(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
@@ -224,10 +226,10 @@
 
         IEnumerable<int> indices = null;
-        IEnumerable<double> predictedValues = null;
+        double[] predictedValues = null;
         switch (series.Name) {
           case ESTIMATEDVALUES_ALL_SERIES_NAME:
             indices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
             var estimatedValues = Content.EstimatedValues.ToArray();
-            predictedValues = indices.Select(index => estimatedValues[index]).ToList();
+            predictedValues = indices.Select(index => estimatedValues[index]).ToArray();
             break;
           case ESTIMATEDVALUES_TRAINING_SERIES_NAME:
@@ -240,6 +242,8 @@
             break;
         }
-        series.Points.DataBindXY(indices, predictedValues);
-        this.InsertEmptyPoints(series);
+        if (predictedValues.Length > 0) {
+          series.Points.DataBindXY(indices, predictedValues);
+          this.InsertEmptyPoints(series);
+        }
         chart.Legends[series.Legend].ForeColor = Color.Black;
         UpdateCursorInterval();
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.Designer.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.Designer.cs	(revision 8742)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionTimeframeFeatureCorrelationView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.cs	(revision 8742)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Regression Timeframe Feature Correlation View")]
+  [Content(typeof(RegressionProblemData), false)]
+  public partial class RegressionTimeframeFeatureCorrelationView : TimeframeFeatureCorrelationView {
+
+    public new RegressionProblemData Content {
+      get { return (RegressionProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionTimeframeFeatureCorrelationView() {
+      InitializeComponent();
+    }
+
+    protected override bool[] SetInitialVisibilityOfColumns() {
+      int i = Content.Dataset.DoubleVariables.ToList().FindIndex(x => x == Content.TargetVariable);
+      var initialVisibility = base.SetInitialVisibilityOfColumns();
+      initialVisibility[i] = true;
+      return initialVisibility;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8742)
@@ -93,6 +93,12 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.5.0, Version=3.5.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
-    <Reference Include="HeuristicLab.ALGLIB-3.5.0, Version=3.5.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
@@ -161,5 +167,5 @@
     <Compile Include="Interfaces\Regression\IRegressionEnsembleSolution.cs" />
     <Compile Include="Implementation\Regression\RegressionSolutionBase.cs" />
-    <Compile Include="OnlineCalculators\AutoCorrelationCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineBoundedMeanSquaredErrorCalculator.cs" />
     <Compile Include="OnlineCalculators\HoeffdingsDependenceCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineMaxAbsoluteErrorCalculator.cs" />
@@ -207,4 +213,5 @@
     <Compile Include="OnlineCalculators\OnlinePearsonsRSquaredCalculator.cs" />
     <Compile Include="Implementation\Regression\RegressionSolution.cs" />
+    <Compile Include="OnlineCalculators\SpearmansRankCorrelationCoefficientCalculator.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="OnlineCalculators\OnlineTheilsUStatisticCalculator.cs" />
@@ -237,4 +244,5 @@
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
@@ -246,5 +254,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -253,4 +261,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 8742)
@@ -95,5 +95,5 @@
 
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new ClassificationEnsembleSolution(models, problemData);
+      return new ClassificationEnsembleSolution(models, new ClassificationEnsembleProblemData(problemData));
     }
     #endregion
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 8742)
@@ -36,7 +36,8 @@
   [Item("Classification Ensemble Solution", "A classification solution that contains an ensemble of multiple classification models")]
   [Creatable("Data Analysis - Ensembles")]
-  public sealed class ClassificationEnsembleSolution : ClassificationSolution, IClassificationEnsembleSolution {
+  public sealed class ClassificationEnsembleSolution : ClassificationSolutionBase, IClassificationEnsembleSolution {
     private readonly Dictionary<int, double> trainingEvaluationCache = new Dictionary<int, double>();
     private readonly Dictionary<int, double> testEvaluationCache = new Dictionary<int, double>();
+    private readonly Dictionary<int, double> evaluationCache = new Dictionary<int, double>();
 
     public new IClassificationEnsembleModel Model {
@@ -104,4 +105,7 @@
     }
 
+    public ClassificationEnsembleSolution(IClassificationProblemData problemData) :
+      this(Enumerable.Empty<IClassificationModel>(), problemData) { }
+
     public ClassificationEnsembleSolution(IEnumerable<IClassificationModel> models, IClassificationProblemData problemData)
       : this(models, problemData,
@@ -150,9 +154,10 @@
     }
 
-    protected override void RecalculateResults() {
-      CalculateResults();
-    }
 
     #region Evaluation
+    public override IEnumerable<double> EstimatedClassValues {
+      get { return GetEstimatedClassValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+
     public override IEnumerable<double> EstimatedTrainingClassValues {
       get {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 8742)
@@ -223,38 +223,34 @@
     }
 
-    private List<double> classValues;
-    public List<double> ClassValues {
+    private List<double> classValuesCache;
+    private List<double> ClassValuesCache {
       get {
-        if (classValues == null) {
-          classValues = Dataset.GetDoubleValues(TargetVariableParameter.Value.Value).Distinct().ToList();
-          classValues.Sort();
+        if (classValuesCache == null) {
+          classValuesCache = Dataset.GetDoubleValues(TargetVariableParameter.Value.Value).Distinct().OrderBy(x => x).ToList();
         }
-        return classValues;
+        return classValuesCache;
       }
     }
-    IEnumerable<double> IClassificationProblemData.ClassValues {
-      get { return ClassValues; }
-    }
-
+    public IEnumerable<double> ClassValues {
+      get { return ClassValuesCache; }
+    }
     public int Classes {
-      get { return ClassValues.Count; }
-    }
-
-    private List<string> classNames;
-    public List<string> ClassNames {
+      get { return ClassValuesCache.Count; }
+    }
+
+    private List<string> classNamesCache;
+    private List<string> ClassNamesCache {
       get {
-        if (classNames == null) {
-          classNames = new List<string>();
+        if (classNamesCache == null) {
+          classNamesCache = new List<string>();
           for (int i = 0; i < ClassNamesParameter.Value.Rows; i++)
-            classNames.Add(ClassNamesParameter.Value[i, 0]);
+            classNamesCache.Add(ClassNamesParameter.Value[i, 0]);
         }
-        return classNames;
+        return classNamesCache;
       }
     }
-    IEnumerable<string> IClassificationProblemData.ClassNames {
-      get { return ClassNames; }
-    }
-
-    private Dictionary<Tuple<double, double>, double> classificationPenaltiesCache = new Dictionary<Tuple<double, double>, double>();
+    public IEnumerable<string> ClassNames {
+      get { return ClassNamesCache; }
+    }
     #endregion
 
@@ -277,4 +273,22 @@
 
     public ClassificationProblemData() : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) { }
+
+    public ClassificationProblemData(IClassificationProblemData classificationProblemData)
+      : this(classificationProblemData.Dataset, classificationProblemData.AllowedInputVariables, classificationProblemData.TargetVariable) {
+      TrainingPartition.Start = classificationProblemData.TrainingPartition.Start;
+      TrainingPartition.End = classificationProblemData.TrainingPartition.End;
+      TestPartition.Start = classificationProblemData.TestPartition.Start;
+      TestPartition.End = classificationProblemData.TestPartition.End;
+
+      for (int i = 0; i < classificationProblemData.ClassNames.Count(); i++)
+        ClassNamesParameter.Value[i, 0] = classificationProblemData.ClassNames.ElementAt(i);
+
+      for (int i = 0; i < Classes; i++) {
+        for (int j = 0; j < Classes; j++) {
+          ClassificationPenaltiesParameter.Value[i, j] = classificationProblemData.GetClassificationPenalty(i, j);
+        }
+      }
+    }
+
     public ClassificationProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
       : base(dataset, allowedInputVariables) {
@@ -310,14 +324,11 @@
       DeregisterParameterEvents();
 
-      classNames = null;
       ((IStringConvertibleMatrix)ClassNamesParameter.Value).Columns = 1;
-      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Rows = ClassValues.Count;
+      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Rows = ClassValuesCache.Count;
       for (int i = 0; i < Classes; i++)
-        ClassNamesParameter.Value[i, 0] = "Class " + ClassValues[i];
+        ClassNamesParameter.Value[i, 0] = "Class " + ClassValuesCache[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;
@@ -330,23 +341,22 @@
         }
       }
-      ((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];
+      if (!ClassValuesCache.Contains(classValue)) throw new ArgumentException();
+      int index = ClassValuesCache.IndexOf(classValue);
+      return ClassNamesCache[index];
     }
     public double GetClassValue(string className) {
-      if (!ClassNames.Contains(className)) throw new ArgumentException();
-      int index = ClassNames.IndexOf(className);
-      return ClassValues[index];
+      if (!ClassNamesCache.Contains(className)) throw new ArgumentException();
+      int index = ClassNamesCache.IndexOf(className);
+      return ClassValuesCache[index];
     }
     public void SetClassName(double classValue, string className) {
-      if (!classValues.Contains(classValue)) throw new ArgumentException();
-      int index = ClassValues.IndexOf(classValue);
-      ClassNames[index] = className;
+      if (!ClassValuesCache.Contains(classValue)) throw new ArgumentException();
+      int index = ClassValuesCache.IndexOf(classValue);
       ClassNamesParameter.Value[index, 0] = className;
+      // updating of class names cache is not necessary here as the parameter value fires a changed event which updates the cache
     }
 
@@ -355,11 +365,7 @@
     }
     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];
+      int correctClassIndex = ClassValuesCache.IndexOf(correctClassValue);
+      int estimatedClassIndex = ClassValuesCache.IndexOf(estimatedClassValue);
+      return ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex];
     }
     public void SetClassificationPenalty(string correctClassName, string estimatedClassName, double penalty) {
@@ -367,7 +373,6 @@
     }
     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);
+      int correctClassIndex = ClassValuesCache.IndexOf(correctClassValue);
+      int estimatedClassIndex = ClassValuesCache.IndexOf(estimatedClassValue);
 
       ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex] = penalty;
@@ -378,25 +383,26 @@
       TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
       ClassNamesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
-      ClassNamesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+      ClassNamesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(Parameter_ValueChanged);
       ClassificationPenaltiesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
-      ClassificationPenaltiesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
     }
     private void DeregisterParameterEvents() {
       TargetVariableParameter.ValueChanged -= new EventHandler(TargetVariableParameter_ValueChanged);
       ClassNamesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
-      ClassNamesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+      ClassNamesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(Parameter_ValueChanged);
       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;
+      classValuesCache = null;
+      classNamesCache = null;
       ResetTargetVariableDependentMembers();
       OnChanged();
     }
     private void Parameter_ValueChanged(object sender, EventArgs e) {
-      OnChanged();
-    }
-    private void MatrixParameter_ItemChanged(object sender, EventArgs<int, int> e) {
+      classNamesCache = null;
+      ClassificationPenaltiesParameter.Value.RowNames = ClassNames.Select(name => "Actual " + name);
+      ClassificationPenaltiesParameter.Value.ColumnNames = ClassNames.Select(name => "Estimated " + name);
       OnChanged();
     }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 8742)
@@ -45,4 +45,5 @@
       : base(model, problemData) {
       evaluationCache = new Dictionary<int, double>(problemData.Dataset.Rows);
+      CalculateClassificationResults();
     }
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 8742)
@@ -85,5 +85,5 @@
     }
 
-    protected void CalculateResults() {
+    protected void CalculateClassificationResults() {
       double[] estimatedTrainingClassValues = EstimatedTrainingClassValues.ToArray(); // cache values
       double[] originalTrainingClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToArray();
@@ -114,4 +114,8 @@
 
     public abstract IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows);
+
+    protected override void RecalculateResults() {
+      CalculateClassificationResults();
+    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 8742)
@@ -33,7 +33,11 @@
   [StorableClass]
   [Item("DiscriminantFunctionClassificationModel", "Represents a classification model that uses a discriminant function and classification thresholds.")]
-  public abstract class DiscriminantFunctionClassificationModel : NamedItem, IDiscriminantFunctionClassificationModel {
+  public class DiscriminantFunctionClassificationModel : NamedItem, IDiscriminantFunctionClassificationModel {
     [Storable]
     private IRegressionModel model;
+    public IRegressionModel Model {
+      get { return model; }
+      private set { model = value; }
+    }
 
     [Storable]
@@ -51,4 +55,11 @@
     }
 
+    private IDiscriminantFunctionThresholdCalculator thresholdCalculator;
+    [Storable]
+    public IDiscriminantFunctionThresholdCalculator ThresholdCalculator {
+      get { return thresholdCalculator; }
+      private set { thresholdCalculator = value; }
+    }
+
 
     [StorableConstructor]
@@ -61,11 +72,21 @@
     }
 
-    public DiscriminantFunctionClassificationModel(IRegressionModel model)
+    public DiscriminantFunctionClassificationModel(IRegressionModel model, IDiscriminantFunctionThresholdCalculator thresholdCalculator)
       : base() {
       this.name = ItemName;
       this.description = ItemDescription;
       this.model = model;
-      this.classValues = new double[] { 0.0 };
-      this.thresholds = new double[] { double.NegativeInfinity };
+      this.classValues = new double[0];
+      this.thresholds = new double[0];
+      this.thresholdCalculator = thresholdCalculator;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (ThresholdCalculator == null) ThresholdCalculator = new AccuracyMaximizationThresholdCalculator();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DiscriminantFunctionClassificationModel(this, cloner);
     }
 
@@ -80,4 +101,14 @@
     }
 
+    public virtual void RecalculateModelParameters(IClassificationProblemData problemData, IEnumerable<int> rows) {
+      double[] classValues;
+      double[] thresholds;
+      var targetClassValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var estimatedTrainingValues = GetEstimatedValues(problemData.Dataset, rows);
+      thresholdCalculator.Calculate(problemData, estimatedTrainingValues, targetClassValues, out classValues, out thresholds);
+      SetThresholdsAndClassValues(thresholds, classValues);
+    }
+
+
     public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
       return model.GetEstimatedValues(dataset, rows);
@@ -85,4 +116,5 @@
 
     public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      if (!Thresholds.Any() && !ClassValues.Any()) throw new ArgumentException("No thresholds and class values were set for the current classification model.");
       foreach (var x in GetEstimatedValues(dataset, rows)) {
         int classIndex = 0;
@@ -103,6 +135,11 @@
     #endregion
 
-    public abstract IDiscriminantFunctionClassificationSolution CreateDiscriminantFunctionClassificationSolution(IClassificationProblemData problemData);
-    public abstract IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData);
+    public virtual IDiscriminantFunctionClassificationSolution CreateDiscriminantFunctionClassificationSolution(IClassificationProblemData problemData) {
+      return new DiscriminantFunctionClassificationSolution(this, problemData);
+    }
+
+    public virtual IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return CreateDiscriminantFunctionClassificationSolution(problemData);
+    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 8742)
@@ -32,5 +32,5 @@
   [StorableClass]
   [Item("DiscriminantFunctionClassificationSolution", "Represents a classification solution that uses a discriminant function and classification thresholds.")]
-  public abstract class DiscriminantFunctionClassificationSolution : DiscriminantFunctionClassificationSolutionBase {
+  public class DiscriminantFunctionClassificationSolution : DiscriminantFunctionClassificationSolutionBase {
     protected readonly Dictionary<int, double> valueEvaluationCache;
     protected readonly Dictionary<int, double> classValueEvaluationCache;
@@ -47,10 +47,14 @@
       classValueEvaluationCache = new Dictionary<int, double>(original.classValueEvaluationCache);
     }
-    protected DiscriminantFunctionClassificationSolution(IDiscriminantFunctionClassificationModel model, IClassificationProblemData problemData)
+    public DiscriminantFunctionClassificationSolution(IDiscriminantFunctionClassificationModel model, IClassificationProblemData problemData)
       : base(model, problemData) {
       valueEvaluationCache = new Dictionary<int, double>();
       classValueEvaluationCache = new Dictionary<int, double>();
+      CalculateRegressionResults();
+      CalculateClassificationResults();
+    }
 
-      SetAccuracyMaximizingThresholds();
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DiscriminantFunctionClassificationSolution(this, cloner);
     }
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 8742)
@@ -85,5 +85,4 @@
       Add(new Result(TrainingRSquaredResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
       Add(new Result(TestRSquaredResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
-
       RegisterEventHandler();
     }
@@ -92,11 +91,4 @@
     private void AfterDeserialization() {
       RegisterEventHandler();
-    }
-
-    protected override void OnModelChanged() {
-      DeregisterEventHandler();
-      SetAccuracyMaximizingThresholds();
-      RegisterEventHandler();
-      base.OnModelChanged();
     }
 
@@ -137,25 +129,6 @@
     }
 
-    public void SetAccuracyMaximizingThresholds() {
-      double[] classValues;
-      double[] thresholds;
-      var targetClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
-      AccuracyMaximizationThresholdCalculator.CalculateThresholds(ProblemData, EstimatedTrainingValues, targetClassValues, out classValues, out thresholds);
-
-      Model.SetThresholdsAndClassValues(thresholds, classValues);
-    }
-
-    public void SetClassDistibutionCutPointThresholds() {
-      double[] classValues;
-      double[] thresholds;
-      var targetClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
-      NormalDistributionCutPointsThresholdCalculator.CalculateThresholds(ProblemData, EstimatedTrainingValues, targetClassValues, out classValues, out thresholds);
-
-      Model.SetThresholdsAndClassValues(thresholds, classValues);
-    }
-
     protected virtual void OnModelThresholdsChanged(EventArgs e) {
-      CalculateResults();
-      CalculateRegressionResults();
+      OnModelChanged();
     }
 
@@ -165,4 +138,9 @@
 
     public abstract IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows);
+
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateRegressionResults();
+    }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 8742)
@@ -53,6 +53,6 @@
 
     public static void CalculateThresholds(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
-      int slices = 100;
-      double minThresholdInc = 10e-5; // necessary to prevent infinite loop when maxEstimated - minEstimated is effectively zero (constant model)
+      const int slices = 100;
+      const double minThresholdInc = 10e-5; // necessary to prevent infinite loop when maxEstimated - minEstimated is effectively zero (constant model)
       List<double> estimatedValuesList = estimatedValues.ToList();
       double maxEstimatedValue = estimatedValuesList.Max();
@@ -61,12 +61,13 @@
       var estimatedAndTargetValuePairs =
         estimatedValuesList.Zip(targetClassValues, (x, y) => new { EstimatedValue = x, TargetClassValue = y })
-        .OrderBy(x => x.EstimatedValue)
-        .ToList();
+        .OrderBy(x => x.EstimatedValue).ToList();
 
-      classValues = problemData.ClassValues.OrderBy(x => x).ToArray();
+      classValues = estimatedAndTargetValuePairs.GroupBy(x => x.TargetClassValue)
+        .Select(x => new { Median = x.Select(y => y.EstimatedValue).Median(), Class = x.Key })
+        .OrderBy(x => x.Median).Select(x => x.Class).ToArray();
+
       int nClasses = classValues.Length;
       thresholds = new double[nClasses];
       thresholds[0] = double.NegativeInfinity;
-      // thresholds[thresholds.Length - 1] = double.PositiveInfinity;
 
       // incrementally calculate accuracy of all possible thresholds
@@ -85,19 +86,24 @@
             //all positives
             if (pair.TargetClassValue.IsAlmost(classValues[i - 1])) {
-              if (pair.EstimatedValue > lowerThreshold && pair.EstimatedValue < actualThreshold)
+              if (pair.EstimatedValue > lowerThreshold && pair.EstimatedValue <= actualThreshold)
                 //true positive
-                classificationScore += problemData.GetClassificationPenalty(classValues[i - 1], classValues[i - 1]);
+                classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, pair.TargetClassValue);
               else
                 //false negative
-                classificationScore += problemData.GetClassificationPenalty(classValues[i], classValues[i - 1]);
+                classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, classValues[i]);
             }
               //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]);
+              //false positive
+              if (pair.EstimatedValue > lowerThreshold && pair.EstimatedValue <= actualThreshold)
+                classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, classValues[i - 1]);
+              else if (pair.EstimatedValue <= lowerThreshold)
+                classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, classValues[i - 2]);
+              else if (pair.EstimatedValue > actualThreshold) {
+                if (pair.TargetClassValue < classValues[i - 1]) //negative in wrong class, consider upper class
+                  classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, classValues[i]);
+                else //true negative, must be optimized by the other thresholds
+                  classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, pair.TargetClassValue);
+              }
             }
           }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs	(revision 8742)
@@ -53,7 +53,6 @@
 
     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();
+      double estimatedValuesRange = estimatedValues.Range();
 
       Dictionary<double, double> classMean = new Dictionary<double, double>();
@@ -82,36 +81,45 @@
           // 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);
+
+          // if the two cut points are too close (for instance because the stdDev=0)
+          // then move them by 0.1% of the range of estimated values
+          if (x1.IsAlmost(x2)) {
+            x1 -= 0.001 * estimatedValuesRange;
+            x2 += 0.001 * estimatedValuesRange;
+          }
+          if (!double.IsInfinity(x1) && !thresholdList.Any(x => x.IsAlmost(x1))) thresholdList.Add(x1);
+          if (!double.IsInfinity(x2) && !thresholdList.Any(x => x.IsAlmost(x2))) thresholdList.Add(x2);
         }
       }
       thresholdList.Sort();
-      thresholdList.Insert(0, double.NegativeInfinity);
+
+      // add small value and large value for the calculation of most influential class in each thresholded section
+      thresholdList.Insert(0, estimatedValues.Min() - 1);
+      thresholdList.Add(estimatedValues.Max() + 1);
 
       // 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; i++) {
-        double m;
-        if (double.IsNegativeInfinity(thresholdList[i])) {
-          m = thresholdList[i + 1] - 1.0; // smaller than the smalles non-infinity threshold
-        } else if (i == thresholdList.Count - 1) {
-          // last threshold
-          m = thresholdList[i] + 1.0; // larger than the last threshold
-        } else {
-          m = thresholdList[i] + (thresholdList[i + 1] - thresholdList[i]) / 2.0; // middle of partition
+      if (thresholdList.Count == 2) {
+        // this happens if there are no thresholds (distributions for all classes are exactly the same)
+        // -> all samples should be classified as the first class
+        classValuesList.Add(originalClasses[0]);
+      } else {
+        // at least one reasonable threshold ...
+        // find the most likely class for the points between thresholds m
+        for (int i = 0; i < thresholdList.Count - 1; i++) {
+
+          // determine class with maximal density mass between the thresholds
+          double maxDensity = LogNormalDensityMass(thresholdList[i], thresholdList[i + 1], classMean[originalClasses[0]], classStdDev[originalClasses[0]]);
+          double maxDensityClassValue = originalClasses[0];
+          foreach (var classValue in originalClasses.Skip(1)) {
+            double density = LogNormalDensityMass(thresholdList[i], thresholdList[i + 1], classMean[classValue], classStdDev[classValue]);
+            if (density > maxDensity) {
+              maxDensity = density;
+              maxDensityClassValue = classValue;
+            }
+          }
+          classValuesList.Add(maxDensityClassValue);
         }
-
-        // determine class with maximal probability density in m
-        double maxDensity = double.MinValue;
-        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);
       }
 
@@ -125,10 +133,12 @@
       //    /   / /\s  \ \     
       //  -/---/-/ -\---\-\----
+
       List<double> filteredThresholds = new List<double>();
       List<double> filteredClassValues = new List<double>();
-      filteredThresholds.Add(thresholdList[0]);
+      filteredThresholds.Add(double.NegativeInfinity); // the smallest possible threshold for the first class
       filteredClassValues.Add(classValuesList[0]);
+      // do not include the last threshold which was just needed for the previous step
       for (int i = 0; i < classValuesList.Count - 1; i++) {
-        if (classValuesList[i] != classValuesList[i + 1]) {
+        if (!classValuesList[i].IsAlmost(classValuesList[i + 1])) {
           filteredThresholds.Add(thresholdList[i + 1]);
           filteredClassValues.Add(classValuesList[i + 1]);
@@ -139,16 +149,45 @@
     }
 
-    private static double NormalDensity(double x, double mu, double sigma) {
+    private static double LogNormalDensityMass(double lower, double upper, double mu, double sigma) {
       if (sigma.IsAlmost(0.0)) {
-        if (x.IsAlmost(mu)) return 1.0; else return 0.0;
-      } else {
-        return (1.0 / Math.Sqrt(2.0 * Math.PI * sigma * sigma)) * Math.Exp(-((x - mu) * (x - mu)) / (2.0 * sigma * sigma));
+        if (lower < mu && mu < upper) return double.PositiveInfinity; // log(1)
+        else return double.NegativeInfinity; // log(0)
       }
+
+      Func<double, double> f = (x) =>
+        x * -0.5 * Math.Log(2.0 * Math.PI * sigma * sigma) - Math.Pow(x - mu, 3) / (3 * 2.0 * sigma * sigma);
+
+      if (double.IsNegativeInfinity(lower)) return f(upper);
+      else return f(upper) - f(lower);
     }
 
     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;
+      if (s1.IsAlmost(s2)) {
+        if (m1.IsAlmost(m2)) {
+          x1 = double.NegativeInfinity;
+          x2 = double.NegativeInfinity;
+        } else {
+          x1 = (m1 + m2) / 2;
+          x2 = double.NegativeInfinity;
+        }
+      } else if (s1.IsAlmost(0.0)) {
+        x1 = m1;
+        x2 = m1;
+      } else if (s2.IsAlmost(0.0)) {
+        x1 = m2;
+        x2 = m2;
+      } else {
+        if (s2 < s1) {
+          // make sure s2 is the larger std.dev.
+          CalculateCutPoints(m2, s2, m1, s1, out x1, out x2);
+        } else {
+          double a = (s1 + s2) * (s1 - s2);
+          double g = Math.Sqrt(s1 * s1 * s2 * s2 * ((m1 - m2) * (m1 - m2) + 2.0 * (s1 * s1 + s2 * s2) * Math.Log(s2 / s1)));
+          double m1s2 = m1 * s2 * s2;
+          double m2s1 = m2 * s1 * s1;
+          x1 = -(-m2s1 + m1s2 + g) / a;
+          x2 = (m2s1 - m1s2 + g) / a;
+        }
+      }
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 8742)
@@ -107,4 +107,5 @@
     [StorableConstructor]
     protected DataAnalysisProblemData(bool deserializing) : base(deserializing) { }
+
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 8742)
@@ -55,5 +55,5 @@
 
     public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new ConstantRegressionSolution(this, problemData);
+      return new ConstantRegressionSolution(this, new RegressionProblemData(problemData));
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 8742)
@@ -102,5 +102,5 @@
 
     public RegressionEnsembleSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new RegressionEnsembleSolution(this.Models, problemData);
+      return new RegressionEnsembleSolution(this.Models, new RegressionEnsembleProblemData(problemData));
     }
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 8742)
@@ -36,7 +36,8 @@
   [Item("Regression Ensemble Solution", "A regression solution that contains an ensemble of multiple regression models")]
   [Creatable("Data Analysis - Ensembles")]
-  public sealed class RegressionEnsembleSolution : RegressionSolution, IRegressionEnsembleSolution {
+  public sealed class RegressionEnsembleSolution : RegressionSolutionBase, IRegressionEnsembleSolution {
     private readonly Dictionary<int, double> trainingEvaluationCache = new Dictionary<int, double>();
     private readonly Dictionary<int, double> testEvaluationCache = new Dictionary<int, double>();
+    private readonly Dictionary<int, double> evaluationCache = new Dictionary<int, double>();
 
     public new IRegressionEnsembleModel Model {
@@ -156,4 +157,8 @@
 
     #region Evaluation
+    public override IEnumerable<double> EstimatedValues {
+      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+
     public override IEnumerable<double> EstimatedTrainingValues {
       get {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 8742)
@@ -121,4 +121,11 @@
       : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
     }
+    public RegressionProblemData(IRegressionProblemData regressionProblemData)
+      : this(regressionProblemData.Dataset, regressionProblemData.AllowedInputVariables, regressionProblemData.TargetVariable) {
+      TrainingPartition.Start = regressionProblemData.TrainingPartition.Start;
+      TrainingPartition.End = regressionProblemData.TrainingPartition.End;
+      TestPartition.Start = regressionProblemData.TestPartition.Start;
+      TestPartition.End = regressionProblemData.TestPartition.End;
+    }
 
     public RegressionProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 8742)
@@ -45,5 +45,7 @@
       : base(model, problemData) {
       evaluationCache = new Dictionary<int, double>(problemData.Dataset.Rows);
+      CalculateRegressionResults();
     }
+
 
     public override IEnumerable<double> EstimatedValues {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 8742)
@@ -178,8 +178,8 @@
 
     protected override void RecalculateResults() {
-      CalculateResults();
-    }
-
-    private void CalculateResults() {
+      CalculateRegressionResults();
+    }
+
+    protected void CalculateRegressionResults() {
       IEnumerable<double> estimatedTrainingValues = EstimatedTrainingValues; // cache values
       IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 8742)
@@ -33,5 +33,10 @@
     protected TimeSeriesPrognosisSolution(bool deserializing) : base(deserializing) { }
     protected TimeSeriesPrognosisSolution(TimeSeriesPrognosisSolution original, Cloner cloner) : base(original, cloner) { }
-    protected internal TimeSeriesPrognosisSolution(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData) : base(model, problemData) { }
+    protected internal TimeSeriesPrognosisSolution(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
+      : base(model, problemData) {
+      CalculateRegressionResults();
+      CalculateTimeSeriesResults();
+      CalculateTimeSeriesResults(ProblemData.TrainingHorizon, ProblemData.TestHorizon);
+    }
 
     public override IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizons) {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 8742)
@@ -431,5 +431,5 @@
     }
 
-    private void CalculateTimeSeriesResults() {
+    protected void CalculateTimeSeriesResults() {
       OnlineCalculatorError errorState;
       double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
@@ -484,5 +484,5 @@
     }
 
-    private void CalculateTimeSeriesResults(int trainingHorizon, int testHorizon) {
+    protected void CalculateTimeSeriesResults(int trainingHorizon, int testHorizon) {
       OnlineCalculatorError errorState;
       //mean model
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 8742)
@@ -26,4 +26,6 @@
     IEnumerable<double> Thresholds { get; }
     IEnumerable<double> ClassValues { get; }
+    IDiscriminantFunctionThresholdCalculator ThresholdCalculator { get; }
+    void RecalculateModelParameters(IClassificationProblemData problemData, IEnumerable<int> rows);
     // class values and thresholds can only be assigned simultanously
     void SetThresholdsAndClassValues(IEnumerable<double> thresholds, IEnumerable<double> classValues);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs	(revision 8742)
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis {
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs	(revision 8742)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineBoundedMeanSquaredErrorCalculator : IOnlineCalculator {
+
+    private double errorSum;
+    private int n;
+    public double BoundedMeanSquaredError {
+      get {
+        return n > 0 ? errorSum / n : 0.0;
+      }
+    }
+
+    public double LowerBound { get; private set; }
+    public double UpperBound { get; private set; }
+
+
+    public OnlineBoundedMeanSquaredErrorCalculator(double lowerBound, double upperbound) {
+      LowerBound = lowerBound;
+      UpperBound = upperbound;
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return BoundedMeanSquaredError; }
+    }
+    public void Reset() {
+      n = 0;
+      errorSum = 0.0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        double error = estimated - original;
+        if (estimated < LowerBound || estimated > UpperBound)
+          errorSum += Math.Abs(error);
+        else
+          errorSum += error * error;
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, double lowerBound, double upperBound, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineBoundedMeanSquaredErrorCalculator boundedMseCalculator = new OnlineBoundedMeanSquaredErrorCalculator(lowerBound, upperBound);
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        boundedMseCalculator.Add(original, estimated);
+        if (boundedMseCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (boundedMseCalculator.ErrorState == OnlineCalculatorError.None &&
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      } else {
+        errorState = boundedMseCalculator.ErrorState;
+        return boundedMseCalculator.BoundedMeanSquaredError;
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/SpearmansRankCorrelationCoefficientCalculator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 8742)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class SpearmansRankCorrelationCoefficientCalculator {
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      double rs = double.NaN;
+      try {
+        var original = originalValues.ToArray();
+        var estimated = estimatedValues.ToArray();
+        rs = alglib.basestat.spearmancorr2(original, estimated, original.Length);
+        errorState = OnlineCalculatorError.None;
+      }
+      catch (alglib.alglibexception) {
+        errorState = OnlineCalculatorError.InvalidValueAdded;
+      }
+
+      return rs;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 8742)
@@ -28,5 +28,5 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis","Provides base classes for data analysis tasks.", "3.4.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.ALGLIB","3.5")]
+  [PluginDependency("HeuristicLab.ALGLIB","3.6")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/CSV/ClassifiactionCSVInstanceProvider.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/CSV/ClassifiactionCSVInstanceProvider.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/CSV/ClassifiactionCSVInstanceProvider.cs	(revision 8742)
@@ -21,8 +21,11 @@
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
+using System.Globalization;
 using System.IO;
 using System.Linq;
 using System.Text;
+using HeuristicLab.Common;
 using HeuristicLab.Problems.DataAnalysis;
 
@@ -61,23 +64,64 @@
 
       Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
-      string targetVar = csvFileParser.VariableNames.Where(x => dataset.DoubleVariables.Contains(x)).Last();
-      IEnumerable<string> allowedInputVars = dataset.DoubleVariables.Where(x => !x.Equals(targetVar));
+      string targetVar = dataset.DoubleVariables.Last();
 
-      ClassificationProblemData claData = new ClassificationProblemData(dataset, allowedInputVars, targetVar);
-
-      int trainingPartEnd = csvFileParser.Rows * 2 / 3;
-      claData.TrainingPartition.Start = 0;
-      claData.TrainingPartition.End = trainingPartEnd;
-      claData.TestPartition.Start = trainingPartEnd;
-      claData.TestPartition.End = csvFileParser.Rows;
-      int pos = path.LastIndexOf('\\');
-      if (pos < 0)
-        claData.Name = path;
-      else {
-        pos++;
-        claData.Name = path.Substring(pos, path.Length - pos);
+      // turn of input variables that are constant in the training partition
+      var allowedInputVars = new List<string>();
+      var trainingIndizes = Enumerable.Range(0, (csvFileParser.Rows * 2) / 3);
+      if (trainingIndizes.Count() >= 2) {
+        foreach (var variableName in dataset.DoubleVariables) {
+          if (dataset.GetDoubleValues(variableName, trainingIndizes).Range() > 0 &&
+            variableName != targetVar)
+            allowedInputVars.Add(variableName);
+        }
+      } else {
+        allowedInputVars.AddRange(dataset.DoubleVariables.Where(x => x.Equals(targetVar)));
       }
 
-      return claData;
+      ClassificationProblemData classificationData = new ClassificationProblemData(dataset, allowedInputVars, targetVar);
+
+      int trainingPartEnd = trainingIndizes.Last();
+      classificationData.TrainingPartition.Start = trainingIndizes.First();
+      classificationData.TrainingPartition.End = trainingPartEnd;
+      classificationData.TestPartition.Start = trainingPartEnd;
+      classificationData.TestPartition.End = csvFileParser.Rows;
+
+      classificationData.Name = Path.GetFileName(path);
+
+      return classificationData;
+    }
+
+    public override IClassificationProblemData ImportData(string path, DataAnalysisImportType type) {
+      TableFileParser csvFileParser = new TableFileParser();
+      csvFileParser.Parse(path);
+
+      int trainingPartEnd = (csvFileParser.Rows * type.Training) / 100;
+      List<IList> values = csvFileParser.Values;
+      if (type.Shuffle) {
+        values = Shuffle(values);
+      }
+
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, values);
+      string targetVar = dataset.DoubleVariables.Last();
+
+      // turn of input variables that are constant in the training partition
+      var allowedInputVars = new List<string>();
+      var trainingIndizes = Enumerable.Range(0, trainingPartEnd);
+      foreach (var variableName in dataset.DoubleVariables) {
+        if (trainingIndizes.Count() >= 2 && dataset.GetDoubleValues(variableName, trainingIndizes).Range() > 0 &&
+          variableName != targetVar)
+          allowedInputVars.Add(variableName);
+      }
+
+      ClassificationProblemData classificationData = new ClassificationProblemData(dataset, allowedInputVars, targetVar);
+
+      classificationData.TrainingPartition.Start = 0;
+      classificationData.TrainingPartition.End = trainingPartEnd;
+      classificationData.TestPartition.Start = trainingPartEnd;
+      classificationData.TestPartition.End = csvFileParser.Rows;
+
+      classificationData.Name = Path.GetFileName(path);
+
+      return classificationData;
     }
 
@@ -86,23 +130,23 @@
     }
     public override void ExportData(IClassificationProblemData instance, string path) {
-      StringBuilder strBuilder = new StringBuilder();
-
-      foreach (var variable in instance.InputVariables) {
-        strBuilder.Append(variable + ";");
+      var strBuilder = new StringBuilder();
+      var colSep = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
+      foreach (var variable in instance.Dataset.VariableNames) {
+        strBuilder.Append(variable.Replace(colSep, String.Empty) + colSep);
       }
-      strBuilder.Remove(strBuilder.Length - 1, 1);
+      strBuilder.Remove(strBuilder.Length - colSep.Length, colSep.Length);
       strBuilder.AppendLine();
 
-      Dataset dataset = instance.Dataset;
+      var dataset = instance.Dataset;
 
       for (int i = 0; i < dataset.Rows; i++) {
         for (int j = 0; j < dataset.Columns; j++) {
-          strBuilder.Append(dataset.GetValue(i, j) + ";");
+          if (j > 0) strBuilder.Append(colSep);
+          strBuilder.Append(dataset.GetValue(i, j));
         }
-        strBuilder.Remove(strBuilder.Length - 1, 1);
         strBuilder.AppendLine();
       }
 
-      using (StreamWriter writer = new StreamWriter(path)) {
+      using (var writer = new StreamWriter(path)) {
         writer.Write(strBuilder);
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/ClassificationInstanceProvider.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/ClassificationInstanceProvider.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/ClassificationInstanceProvider.cs	(revision 8742)
@@ -23,5 +23,5 @@
 
 namespace HeuristicLab.Problems.Instances.DataAnalysis {
-  public abstract class ClassificationInstanceProvider : ProblemInstanceProvider<IClassificationProblemData> {
+  public abstract class ClassificationInstanceProvider : DataAnalysisInstanceProvider<IClassificationProblemData> {
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Clustering/CSV/ClusteringCSVInstanceProvider.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Clustering/CSV/ClusteringCSVInstanceProvider.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Clustering/CSV/ClusteringCSVInstanceProvider.cs	(revision 8742)
@@ -21,7 +21,11 @@
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
+using System.Globalization;
 using System.IO;
+using System.Linq;
 using System.Text;
+using HeuristicLab.Common;
 using HeuristicLab.Problems.DataAnalysis;
 
@@ -56,24 +60,67 @@
     public override IClusteringProblemData ImportData(string path) {
       var csvFileParser = new TableFileParser();
-
       csvFileParser.Parse(path);
 
-      var dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
-      var claData = new ClusteringProblemData(dataset, dataset.DoubleVariables);
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
+      string targetVar = dataset.DoubleVariables.Last();
 
-      int trainingPartEnd = csvFileParser.Rows * 2 / 3;
-      claData.TrainingPartition.Start = 0;
-      claData.TrainingPartition.End = trainingPartEnd;
-      claData.TestPartition.Start = trainingPartEnd;
-      claData.TestPartition.End = csvFileParser.Rows;
-      int pos = path.LastIndexOf('\\');
-      if (pos < 0)
-        claData.Name = path;
-      else {
-        pos++;
-        claData.Name = path.Substring(pos, path.Length - pos);
+      // turn of input variables that are constant in the training partition
+      var allowedInputVars = new List<string>();
+      var trainingIndizes = Enumerable.Range(0, (csvFileParser.Rows * 2) / 3);
+      if (trainingIndizes.Count() >= 2) {
+        foreach (var variableName in dataset.DoubleVariables) {
+          if (dataset.GetDoubleValues(variableName, trainingIndizes).Range() > 0 &&
+            variableName != targetVar)
+            allowedInputVars.Add(variableName);
+        }
+      } else {
+        allowedInputVars.AddRange(dataset.DoubleVariables.Where(x => x.Equals(targetVar)));
       }
 
-      return claData;
+      ClusteringProblemData clusteringData = new ClusteringProblemData(dataset, allowedInputVars);
+
+      int trainingPartEnd = trainingIndizes.Last();
+      clusteringData.TrainingPartition.Start = trainingIndizes.First();
+      clusteringData.TrainingPartition.End = trainingPartEnd;
+      clusteringData.TestPartition.Start = trainingPartEnd;
+      clusteringData.TestPartition.End = csvFileParser.Rows;
+
+      clusteringData.Name = Path.GetFileName(path);
+
+      return clusteringData;
+    }
+
+    public override IClusteringProblemData ImportData(string path, DataAnalysisImportType type) {
+      TableFileParser csvFileParser = new TableFileParser();
+      csvFileParser.Parse(path);
+
+      List<IList> values = csvFileParser.Values;
+      if (type.Shuffle) {
+        values = Shuffle(values);
+      }
+
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, values);
+      string targetVar = dataset.DoubleVariables.Last();
+
+      // turn of input variables that are constant in the training partition
+      var allowedInputVars = new List<string>();
+      int trainingPartEnd = (csvFileParser.Rows * type.Training) / 100;
+      var trainingIndizes = Enumerable.Range(0, trainingPartEnd);
+      foreach (var variableName in dataset.DoubleVariables) {
+        if (trainingIndizes.Count() >= 2 && dataset.GetDoubleValues(variableName, trainingIndizes).Range() > 0 &&
+          variableName != targetVar)
+          allowedInputVars.Add(variableName);
+      }
+
+      ClusteringProblemData clusteringData = new ClusteringProblemData(dataset, allowedInputVars);
+
+      clusteringData.TrainingPartition.Start = 0;
+      clusteringData.TrainingPartition.End = trainingPartEnd;
+      clusteringData.TestPartition.Start = trainingPartEnd;
+      clusteringData.TestPartition.End = csvFileParser.Rows;
+
+      clusteringData.Name = Path.GetFileName(path);
+
+      return clusteringData;
     }
 
@@ -83,9 +130,9 @@
     public override void ExportData(IClusteringProblemData instance, string path) {
       var strBuilder = new StringBuilder();
-
-      foreach (var variable in instance.InputVariables) {
-        strBuilder.Append(variable + ";");
+      var colSep = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
+      foreach (var variable in instance.Dataset.VariableNames) {
+        strBuilder.Append(variable.Replace(colSep, String.Empty) + colSep);
       }
-      strBuilder.Remove(strBuilder.Length - 1, 1);
+      strBuilder.Remove(strBuilder.Length - colSep.Length, colSep.Length);
       strBuilder.AppendLine();
 
@@ -94,7 +141,7 @@
       for (int i = 0; i < dataset.Rows; i++) {
         for (int j = 0; j < dataset.Columns; j++) {
-          strBuilder.Append(dataset.GetValue(i, j) + ";");
+          if (j > 0) strBuilder.Append(colSep);
+          strBuilder.Append(dataset.GetValue(i, j));
         }
-        strBuilder.Remove(strBuilder.Length - 1, 1);
         strBuilder.AppendLine();
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Clustering/ClusteringInstanceProvider.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Clustering/ClusteringInstanceProvider.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Clustering/ClusteringInstanceProvider.cs	(revision 8742)
@@ -23,5 +23,5 @@
 
 namespace HeuristicLab.Problems.Instances.DataAnalysis {
-  public abstract class ClusteringInstanceProvider : ProblemInstanceProvider<IClusteringProblemData> {
+  public abstract class ClusteringInstanceProvider : DataAnalysisInstanceProvider<IClusteringProblemData> {
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/DataAnalysisImportType.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/DataAnalysisImportType.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/DataAnalysisImportType.cs	(revision 8742)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+
+namespace HeuristicLab.Problems.Instances.DataAnalysis {
+  public class DataAnalysisImportType {
+    public bool Shuffle { get; set; }
+    public int Training { get; set; }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/DataAnalysisInstanceProvider.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/DataAnalysisInstanceProvider.cs	(revision 8742)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/DataAnalysisInstanceProvider.cs	(revision 8742)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Problems.Instances.DataAnalysis {
+  public abstract class DataAnalysisInstanceProvider<TData> : ProblemInstanceProvider<TData>
+    where TData : class, IDataAnalysisProblemData {
+
+    // has to be implemented, if CanImportData is true
+    public virtual TData ImportData(string path, DataAnalysisImportType type) {
+      throw new NotSupportedException();
+    }
+
+    protected List<IList> Shuffle(List<IList> values) {
+      int count = values.First().Count;
+      int[] indices = GetRandomIndices(count);
+      List<IList> shuffeledValues = new List<IList>(values.Count);
+      for (int col = 0; col < values.Count; col++) {
+
+        if (values[col] is List<double>)
+          shuffeledValues.Add(new List<double>());
+        else if (values[col] is List<DateTime>)
+          shuffeledValues.Add(new List<DateTime>());
+        else if (values[col] is List<string>)
+          shuffeledValues.Add(new List<string>());
+        else
+          throw new InvalidOperationException();
+
+        for (int i = 0; i < count; i++) {
+          shuffeledValues[col].Add(values[col][indices[i]]);
+        }
+      }
+      return shuffeledValues;
+    }
+
+    //Fisher–Yates shuffle
+    private int[] GetRandomIndices(int amount) {
+      int[] randomIndices = Enumerable.Range(0, amount).ToArray();
+      System.Random rand = new System.Random();
+      int n = amount;
+      while (n > 1) {
+        n--;
+        int k = rand.Next(n + 1);
+        int value = randomIndices[k];
+        randomIndices[k] = randomIndices[n];
+        randomIndices[n] = value;
+      }
+      return randomIndices;
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj	(revision 8742)
@@ -98,26 +98,13 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.Instances-3.3">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="ICSharpCode.SharpZipLib, Version=0.85.4.369, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="ICSharpCode.SharpZipLib">
+      <HintPath>..\..\HeuristicLab.PluginInfrastructure\3.3\ICSharpCode.SharpZipLib.dll</HintPath>
       <Private>False</Private>
     </Reference>
@@ -137,11 +124,13 @@
     <Compile Include="Classification\ClassificationInstanceProvider.cs" />
     <Compile Include="Classification\CSV\ClassifiactionCSVInstanceProvider.cs" />
-    <Compile Include="Classification\RealWorld\Iris.cs" />
-    <Compile Include="Classification\RealWorld\Mammography.cs" />
-    <Compile Include="Classification\RealWorld\ClassificationRealWorldInstanceProvider.cs" />
     <Compile Include="Classification\ResourceClassificationDataDescriptor.cs" />
     <Compile Include="Classification\ResourceClassificationInstanceProvider.cs" />
+    <Compile Include="Classification\UCI\Mammography.cs" />
+    <Compile Include="Classification\UCI\UCIInstanceProvider.cs" />
+    <Compile Include="Classification\UCI\Wine.cs" />
     <Compile Include="Clustering\ClusteringInstanceProvider.cs" />
     <Compile Include="Clustering\CSV\ClusteringCSVInstanceProvider.cs" />
+    <Compile Include="DataAnalysisImportType.cs" />
+    <Compile Include="DataAnalysisInstanceProvider.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -219,5 +208,5 @@
   </ItemGroup>
   <ItemGroup>
-    <EmbeddedResource Include="Classification\Data\ClassificationRealWorld.zip" />
+    <EmbeddedResource Include="Classification\Data\UCI.zip" />
     <None Include="HeuristicLab.snk" />
     <None Include="Plugin.cs.frame" />
@@ -234,5 +223,5 @@
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -240,4 +229,10 @@
 
 call PreBuildEvent.cmd</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Plugin.cs.frame	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Plugin.cs.frame	(revision 8742)
@@ -25,4 +25,5 @@
   [Plugin("HeuristicLab.Problems.Instances.DataAnalysis", "3.3.7.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.Instances.DataAnalysis-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
   [PluginDependency("HeuristicLab.Core", "3.3")]
   [PluginDependency("HeuristicLab.Data", "3.3")]
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/CSV/RegressionCSVInstanceProvider.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/CSV/RegressionCSVInstanceProvider.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/CSV/RegressionCSVInstanceProvider.cs	(revision 8742)
@@ -21,8 +21,11 @@
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
+using System.Globalization;
 using System.IO;
 using System.Linq;
 using System.Text;
+using HeuristicLab.Common;
 using HeuristicLab.Problems.DataAnalysis;
 
@@ -59,24 +62,64 @@
 
       Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
-      string targetVar = csvFileParser.VariableNames.Where(x => dataset.DoubleVariables.Contains(x)).Last();
+      string targetVar = dataset.DoubleVariables.Last();
 
-      IEnumerable<string> allowedInputVars = dataset.DoubleVariables.Where(x => !x.Equals(targetVar));
+      // turn of input variables that are constant in the training partition
+      var allowedInputVars = new List<string>();
+      var trainingIndizes = Enumerable.Range(0, (csvFileParser.Rows * 2) / 3);
+      foreach (var variableName in dataset.DoubleVariables) {
+        if (trainingIndizes.Count() >= 2 && dataset.GetDoubleValues(variableName, trainingIndizes).Range() > 0 &&
+          variableName != targetVar)
+          allowedInputVars.Add(variableName);
+      }
 
-      IRegressionProblemData regData = new RegressionProblemData(dataset, allowedInputVars, targetVar);
+      IRegressionProblemData regressionData = new RegressionProblemData(dataset, allowedInputVars, targetVar);
 
-      int trainingPartEnd = csvFileParser.Rows * 2 / 3;
-      regData.TrainingPartition.Start = 0;
-      regData.TrainingPartition.End = trainingPartEnd;
-      regData.TestPartition.Start = trainingPartEnd;
-      regData.TestPartition.End = csvFileParser.Rows;
+      var trainingPartEnd = trainingIndizes.Last();
+      regressionData.TrainingPartition.Start = trainingIndizes.First();
+      regressionData.TrainingPartition.End = trainingPartEnd;
+      regressionData.TestPartition.Start = trainingPartEnd;
+      regressionData.TestPartition.End = csvFileParser.Rows;
 
-      int pos = path.LastIndexOf('\\');
-      if (pos < 0)
-        regData.Name = path;
-      else {
-        pos++;
-        regData.Name = path.Substring(pos, path.Length - pos);
+      regressionData.Name = Path.GetFileName(path);
+
+      return regressionData;
+    }
+
+    public override IRegressionProblemData ImportData(string path, DataAnalysisImportType type) {
+      TableFileParser csvFileParser = new TableFileParser();
+      csvFileParser.Parse(path);
+
+      List<IList> values = csvFileParser.Values;
+      if (type.Shuffle) {
+        values = Shuffle(values);
       }
-      return regData;
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, values);
+      string targetVar = dataset.DoubleVariables.Last();
+
+      // turn of input variables that are constant in the training partition
+      var allowedInputVars = new List<string>();
+      int trainingPartEnd = (csvFileParser.Rows * type.Training) / 100;
+      trainingPartEnd = trainingPartEnd > 0 ? trainingPartEnd : 1;
+      var trainingIndizes = Enumerable.Range(0, trainingPartEnd);
+      if (trainingIndizes.Count() >= 2) {
+        foreach (var variableName in dataset.DoubleVariables) {
+          if (dataset.GetDoubleValues(variableName, trainingIndizes).Range() > 0 &&
+            variableName != targetVar)
+            allowedInputVars.Add(variableName);
+        }
+      } else {
+        allowedInputVars.AddRange(dataset.DoubleVariables.Where(x => x.Equals(targetVar)));
+      }
+
+      RegressionProblemData regressionData = new RegressionProblemData(dataset, allowedInputVars, targetVar);
+
+      regressionData.TrainingPartition.Start = 0;
+      regressionData.TrainingPartition.End = trainingPartEnd;
+      regressionData.TestPartition.Start = trainingPartEnd;
+      regressionData.TestPartition.End = csvFileParser.Rows;
+
+      regressionData.Name = Path.GetFileName(path);
+
+      return regressionData;
     }
 
@@ -85,23 +128,23 @@
     }
     public override void ExportData(IRegressionProblemData instance, string path) {
-      StringBuilder strBuilder = new StringBuilder();
-
-      foreach (var variable in instance.InputVariables) {
-        strBuilder.Append(variable + ";");
+      var strBuilder = new StringBuilder();
+      var colSep = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
+      foreach (var variable in instance.Dataset.VariableNames) {
+        strBuilder.Append(variable.Replace(colSep, String.Empty) + colSep);
       }
-      strBuilder.Remove(strBuilder.Length - 1, 1);
+      strBuilder.Remove(strBuilder.Length - colSep.Length, colSep.Length);
       strBuilder.AppendLine();
 
-      Dataset dataset = instance.Dataset;
+      var dataset = instance.Dataset;
 
       for (int i = 0; i < dataset.Rows; i++) {
         for (int j = 0; j < dataset.Columns; j++) {
-          strBuilder.Append(dataset.GetValue(i, j) + ";");
+          if (j > 0) strBuilder.Append(colSep);
+          strBuilder.Append(dataset.GetValue(i, j));
         }
-        strBuilder.Remove(strBuilder.Length - 1, 1);
         strBuilder.AppendLine();
       }
 
-      using (StreamWriter writer = new StreamWriter(path)) {
+      using (var writer = new StreamWriter(path)) {
         writer.Write(strBuilder);
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/RegressionInstanceProvider.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/RegressionInstanceProvider.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/RegressionInstanceProvider.cs	(revision 8742)
@@ -23,5 +23,5 @@
 
 namespace HeuristicLab.Problems.Instances.DataAnalysis {
-  public abstract class RegressionInstanceProvider : ProblemInstanceProvider<IRegressionProblemData> {
+  public abstract class RegressionInstanceProvider : DataAnalysisInstanceProvider<IRegressionProblemData> {
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/ValueGenerator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/ValueGenerator.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/ValueGenerator.cs	(revision 8742)
@@ -23,4 +23,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Random;
 
@@ -40,5 +41,6 @@
       if (stepWidth <= 0) throw new ArgumentException("stepwith must be larger than zero.", "stepWidth");
       double x = start;
-      while (x <= end) {
+      // x<=end could skip the last value because of numerical problems
+      while (x < end || x.IsAlmost(end)) {
         yield return x;
         x += stepWidth;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/Various/FriedmanTwo.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/Various/FriedmanTwo.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Regression/Various/FriedmanTwo.cs	(revision 8742)
@@ -36,6 +36,6 @@
     }
     protected override string TargetVariable { get { return "Y"; } }
-    protected override string[] InputVariables { get { return new string[] { "X1", "X2", "X3", "X4", "X5", "Y" }; } }
-    protected override string[] AllowedInputVariables { get { return new string[] { "X1", "X2", "X3", "X4", "X5" }; } }
+    protected override string[] InputVariables { get { return new string[] { "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "Y" }; } }
+    protected override string[] AllowedInputVariables { get { return new string[] { "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10" }; } }
     protected override int TrainingPartitionStart { get { return 0; } }
     protected override int TrainingPartitionEnd { get { return 5000; } }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TableFileParser.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TableFileParser.cs	(revision 8741)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TableFileParser.cs	(revision 8742)
@@ -32,5 +32,5 @@
 namespace HeuristicLab.Problems.Instances.DataAnalysis {
   public class TableFileParser {
-    private const int BUFFER_SIZE = 1024;
+    private const int BUFFER_SIZE = 65536;
     private static readonly char[] POSSIBLE_SEPARATORS = new char[] { ',', ';', '\t' };
     private Tokenizer tokenizer;
