Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceConst.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceConst.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceConst.cs	(revision 8982)
@@ -25,4 +25,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -32,11 +33,6 @@
     Description = "Constant covariance function for Gaussian processes.")]
   public sealed class CovarianceConst : ParameterizedNamedItem, ICovarianceFunction {
-
-    [Storable]
-    private double scale;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> scaleParameter;
     public IValueParameter<DoubleValue> ScaleParameter {
-      get { return scaleParameter; }
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     }
 
@@ -48,8 +44,4 @@
     private CovarianceConst(CovarianceConst original, Cloner cloner)
       : base(original, cloner) {
-      this.scaleParameter = cloner.Clone(original.scaleParameter);
-      this.scale = original.scale;
-
-      RegisterEvents();
     }
 
@@ -59,19 +51,6 @@
       Description = ItemDescription;
 
-      scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of the constant covariance function.");
-      Parameters.Add(scaleParameter);
-      RegisterEvents();
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale of the constant covariance function."));
     }
-
-    [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) {
@@ -80,25 +59,38 @@
 
     public int GetNumberOfParameters(int numberOfVariables) {
-      return scaleParameter.Fixed ? 0 : 1;
+      return ScaleParameter.Value != null ? 0 : 1;
     }
 
-    public void SetParameter(double[] hyp) {
-      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 SetParameter(double[] p) {
+      double scale;
+      GetParameterValues(p, out scale);
+      ScaleParameter.Value = new DoubleValue(scale);
     }
 
-    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      return scale;
+    private void GetParameterValues(double[] p, out double scale) {
+      int c = 0;
+      // gather parameter values
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[c]);
+        c++;
+      }
+      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceConst", "p");
     }
 
-    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      yield return 2.0 * scale;
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double scale;
+      GetParameterValues(p, out scale);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => scale;
+      cov.CrossCovariance = (x, xt, i, j) => scale;
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, scale, columnIndices);
+      return cov;
     }
 
-    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
-      return scale;
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double scale, IEnumerable<int> columnIndices) {
+      yield return 2.0 * scale;
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinear.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinear.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinear.cs	(revision 8982)
@@ -48,18 +48,16 @@
     }
 
-    public void SetParameter(double[] hyp) {
-      if (hyp.Length > 0) throw new ArgumentException("No hyperparameters are allowed for the linear covariance function.");
+    public void SetParameter(double[] p) {
+      if (p.Length > 0) throw new ArgumentException("No parameters are allowed for the linear covariance function.");
     }
 
-    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      return Util.ScalarProd(x, i, j, 1, columnIndices);
-    }
-
-    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      yield break;
-    }
-
-    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
-      return Util.ScalarProd(x, i, xt, j, 1.0 , columnIndices);
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      if (p.Length > 0) throw new ArgumentException("No parameters are allowed for the linear covariance function.");
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => Util.ScalarProd(x, i, j, 1, columnIndices);
+      cov.CrossCovariance = (x, xt, i, j) =>  Util.ScalarProd(x, i, xt, j, 1.0 , columnIndices);
+      cov.CovarianceGradient = (x, i, j) => Enumerable.Empty<double>();
+      return cov;
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinearArd.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinearArd.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinearArd.cs	(revision 8982)
@@ -26,4 +26,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -33,10 +34,6 @@
     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; }
+      get { return (IValueParameter<DoubleArray>)Parameters["InverseLength"]; }
     }
 
@@ -45,11 +42,4 @@
     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()
@@ -58,13 +48,6 @@
       Description = ItemDescription;
 
-      inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength",
-                                                               "The inverse length parameter for ARD.");
-      Parameters.Add(inverseLengthParameter);
-      RegisterEvents();
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEvents();
+      Parameters.Add(new OptionalValueParameter<DoubleArray>("InverseLength",
+                                                             "The inverse length parameter for ARD."));
     }
 
@@ -73,12 +56,6 @@
     }
 
-    // caching
-    private void RegisterEvents() {
-      Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.ToArray(); });
-    }
-
-
     public int GetNumberOfParameters(int numberOfVariables) {
-      if (!inverseLengthParameter.Fixed)
+      if (InverseLengthParameter.Value == null)
         return numberOfVariables;
       else
@@ -86,15 +63,31 @@
     }
 
-    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 void SetParameter(double[] p) {
+      double[] inverseLength;
+      GetParameterValues(p, out inverseLength);
+      InverseLengthParameter.Value = new DoubleArray(inverseLength);
     }
 
-    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      return Util.ScalarProd(x, i, j, inverseLength, columnIndices);
+    private void GetParameterValues(double[] p, out double[] inverseLength) {
+      // gather parameter values
+      if (InverseLengthParameter.Value != null) {
+        inverseLength = InverseLengthParameter.Value.ToArray();
+      } else {
+        inverseLength = p.Select(e => 1.0 / Math.Exp(e)).ToArray();
+      }
     }
 
-    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double[] inverseLength;
+      GetParameterValues(p, out inverseLength);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => Util.ScalarProd(x, i, j, inverseLength, columnIndices);
+      cov.CrossCovariance = (x, xt, i, j) => Util.ScalarProd(x, i, xt, j, inverseLength, columnIndices);
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, inverseLength, columnIndices);
+      return cov;
+    }
+
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double[] inverseLength, IEnumerable<int> columnIndices) {
       if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
 
@@ -105,8 +98,4 @@
       }
     }
-
-    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
-      return Util.ScalarProd(x, i, xt, j, inverseLength, columnIndices);
-    }
   }
 }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMask.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMask.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMask.cs	(revision 8982)
@@ -23,4 +23,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using System.Linq.Expressions;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -34,18 +35,9 @@
     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; }
+      get { return (IValueParameter<IntArray>)Parameters["SelectedDimensions"]; }
     }
-
-    [Storable]
-    private ICovarianceFunction cov;
-    [Storable]
-    private readonly ValueParameter<ICovarianceFunction> covParameter;
     public IValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
-      get { return covParameter; }
+      get { return (IValueParameter<ICovarianceFunction>)Parameters["CovarianceFunction"]; }
     }
 
@@ -57,12 +49,4 @@
     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();
     }
 
@@ -72,12 +56,6 @@
       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();
+      Parameters.Add(new OptionalValueParameter<IntArray>("SelectedDimensions", "The dimensions on which the specified covariance function should be applied to."));
+      Parameters.Add(new ValueParameter<ICovarianceFunction>("CovarianceFunction", "The covariance function that should be scaled.", new CovarianceSquaredExponentialIso()));
     }
 
@@ -86,50 +64,20 @@
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEvents();
+    public int GetNumberOfParameters(int numberOfVariables) {
+      if (SelectedDimensionsParameter.Value == null) return CovarianceFunctionParameter.Value.GetNumberOfParameters(numberOfVariables);
+      else return CovarianceFunctionParameter.Value.GetNumberOfParameters(SelectedDimensionsParameter.Value.Length);
     }
 
-    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 void SetParameter(double[] p) {
+      CovarianceFunctionParameter.Value.SetParameter(p);
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      if (selectedDimensions == null) return cov.GetNumberOfParameters(numberOfVariables);
-      else return cov.GetNumberOfParameters(selectedDimensions.Length);
-    }
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      if (columnIndices != null)
+        throw new InvalidOperationException("Stacking of masking covariance functions is not supported.");
+      var cov = CovarianceFunctionParameter.Value;
+      var selectedDimensions = SelectedDimensionsParameter.Value;
 
-    public void SetParameter(double[] hyp) {
-      cov.SetParameter(hyp);
-    }
-
-    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      // cov mask overwrites the previously selected columnIndices 
-      // -> stacking of CovarianceMask is not supported
-      if (columnIndices != null && columnIndices.Count() != x.GetLength(1))
-        throw new InvalidOperationException("Stacking of masking covariance functions is not supported.");
-
-      return cov.GetCovariance(x, i, j, selectedDimensions);
-    }
-
-    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      if (columnIndices != null && columnIndices.Count() != x.GetLength(1))
-        throw new InvalidOperationException("Stacking of masking covariance functions is not supported.");
-
-      return cov.GetGradient(x, i, j, selectedDimensions);
-    }
-
-    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
-      if (columnIndices != null && columnIndices.Count() != x.GetLength(1))
-        throw new InvalidOperationException("Stacking of masking covariance functions is not supported.");
-
-      return cov.GetCrossCovariance(x, xt, i, j, selectedDimensions);
+      return cov.GetParameterizedCovarianceFunction(p, selectedDimensions);
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMaternIso.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMaternIso.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMaternIso.cs	(revision 8982)
@@ -34,26 +34,14 @@
     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; }
+      get { return (IValueParameter<DoubleValue>)Parameters["InverseLength"]; }
     }
 
-    [Storable]
-    private double sf2;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> scaleParameter;
     public IValueParameter<DoubleValue> ScaleParameter {
-      get { return scaleParameter; }
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     }
 
-    [Storable]
-    private int d;
-    [Storable]
-    private readonly ConstrainedValueParameter<IntValue> dParameter;
     public IConstrainedValueParameter<IntValue> DParameter {
-      get { return dParameter; }
+      get { return (IConstrainedValueParameter<IntValue>)Parameters["D"]; }
     }
 
@@ -66,11 +54,4 @@
     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();
     }
 
@@ -80,23 +61,11 @@
       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.");
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric Matern covariance function."));
+      Parameters.Add(new OptionalValueParameter<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();
+      Parameters.Add(new ConstrainedValueParameter<IntValue>("D", "The d parameter (allowed values: 1, 3, or 5) of the isometric Matern covariance function.", validDValues, validDValues.First()));
     }
 
@@ -105,32 +74,57 @@
     }
 
-    // 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.Value != null ? 0 : 1) +
+        (ScaleParameter.Value != null ? 0 : 1);
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return
-        (inverseLengthParameter.Fixed ? 0 : 1) +
-        (scaleParameter.Fixed ? 0 : 1);
+    public void SetParameter(double[] p) {
+      double inverseLength, scale;
+      GetParameterValues(p, out scale, out inverseLength);
+      InverseLengthParameter.Value = new DoubleValue(inverseLength);
+      ScaleParameter.Value = new DoubleValue(scale);
     }
 
-    public void SetParameter(double[] hyp) {
-      int i = 0;
-      if (!inverseLengthParameter.Fixed) {
-        inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
-        i++;
+    private void GetParameterValues(double[] p, out double scale, out double inverseLength) {
+      // gather parameter values
+      int c = 0;
+      if (InverseLengthParameter.Value != null) {
+        inverseLength = InverseLengthParameter.Value.Value;
+      } else {
+        inverseLength = 1.0 / Math.Exp(p[c]);
+        c++;
       }
-      if (!scaleParameter.Fixed) {
-        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
-        i++;
+
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[c]);
+        c++;
       }
-      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceMaternIso", "hyp");
+      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceMaternIso", "p");
     }
 
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double inverseLength, scale;
+      int d = DParameter.Value.Value;
+      GetParameterValues(p, out scale, out inverseLength);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => {
+        double dist = i == j
+                       ? 0.0
+                       : Math.Sqrt(Util.SqrDist(x, i, j, Math.Sqrt(d) * inverseLength, columnIndices));
+        return scale * m(d, dist);
+      };
+      cov.CrossCovariance = (x, xt, i, j) => {
+        double dist = Math.Sqrt(Util.SqrDist(x, i, xt, j, Math.Sqrt(d) * inverseLength, columnIndices));
+        return scale * m(d, dist);
+      };
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, d, scale, inverseLength, columnIndices);
+      return cov;
+    }
 
-    private double m(double t) {
+    private static double m(int d, double t) {
       double f;
       switch (d) {
@@ -143,5 +137,5 @@
     }
 
-    private double dm(double t) {
+    private static double dm(int d, double t) {
       double df;
       switch (d) {
@@ -154,23 +148,12 @@
     }
 
-    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) {
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int d, double scale, double inverseLength, 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);
+      yield return scale * dm(d, dist);
+      yield return 2 * scale * m(d, dist);
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceNoise.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceNoise.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceNoise.cs	(revision 8982)
@@ -22,7 +22,9 @@
 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;
 
@@ -32,12 +34,6 @@
     Description = "Noise covariance function for Gaussian processes.")]
   public sealed class CovarianceNoise : ParameterizedNamedItem, ICovarianceFunction {
-
-
-    [Storable]
-    private double sf2;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> scaleParameter;
     public IValueParameter<DoubleValue> ScaleParameter {
-      get { return scaleParameter; }
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     }
 
@@ -49,7 +45,4 @@
     private CovarianceNoise(CovarianceNoise original, Cloner cloner)
       : base(original, cloner) {
-      this.scaleParameter = cloner.Clone(original.scaleParameter);
-      this.sf2 = original.sf2;
-      RegisterEvents();
     }
 
@@ -59,8 +52,5 @@
       Description = ItemDescription;
 
-      this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of noise.");
-      Parameters.Add(this.scaleParameter);
-
-      RegisterEvents();
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale of noise."));
     }
 
@@ -69,35 +59,35 @@
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEvents();
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return ScaleParameter.Value != null ? 0 : 1;
     }
 
-    private void RegisterEvents() {
-      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
+    public void SetParameter(double[] p) {
+      double scale;
+      GetParameterValues(p, out scale);
+      ScaleParameter.Value = new DoubleValue(scale);
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return scaleParameter.Fixed ? 0 : 1;
+    private void GetParameterValues(double[] p, out double scale) {
+      int c = 0;
+      // gather parameter values
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[c]);
+        c++;
+      }
+      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceNoise", "p");
     }
 
-    public void SetParameter(double[] hyp) {
-      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 double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      return i == j ? sf2 : 0.0;
-    }
-
-    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      yield return i == j ? 2 * sf2 : 0.0;
-    }
-
-    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
-      return 0.0;
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double scale;
+      GetParameterValues(p, out scale);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => i == j ? scale : 0.0;
+      cov.CrossCovariance = (x, xt, i, j) => 0.0;
+      cov.CovarianceGradient = (x, i, j) => Enumerable.Repeat(i == j ? 2.0 * scale : 0.0, 1);
+      return cov;
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovariancePeriodic.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovariancePeriodic.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovariancePeriodic.cs	(revision 8982)
@@ -26,4 +26,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -33,26 +34,14 @@
   public sealed class CovariancePeriodic : ParameterizedNamedItem, ICovarianceFunction {
 
-    [Storable]
-    private double scale;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> scaleParameter;
     public IValueParameter<DoubleValue> ScaleParameter {
-      get { return scaleParameter; }
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     }
 
-    [Storable]
-    private double inverseLength;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
     public IValueParameter<DoubleValue> InverseLengthParameter {
-      get { return inverseLengthParameter; }
+      get { return (IValueParameter<DoubleValue>)Parameters["InverseLength"]; }
     }
 
-    [Storable]
-    private double period;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> periodParameter;
     public IValueParameter<DoubleValue> PeriodParameter {
-      get { return periodParameter; }
+      get { return (IValueParameter<DoubleValue>)Parameters["Period"]; }
     }
 
@@ -62,12 +51,4 @@
     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();
     }
 
@@ -77,17 +58,7 @@
       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();
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale of the periodic covariance function."));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("InverseLength", "The inverse length parameter for the periodic covariance function."));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Period", "The period parameter for the periodic covariance function."));
     }
 
@@ -96,43 +67,70 @@
     }
 
-    // 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 int GetNumberOfParameters(int numberOfVariables) {
+      return (ScaleParameter.Value != null ? 0 : 1) +
+       (PeriodParameter.Value != null ? 0 : 1) +
+       (InverseLengthParameter.Value != null ? 0 : 1);
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return
-        (new[] { scaleParameter, inverseLengthParameter, periodParameter }).Count(p => !p.Fixed);
+    public void SetParameter(double[] p) {
+      double scale, inverseLength, period;
+      GetParameterValues(p, out scale, out period, out inverseLength);
+      ScaleParameter.Value = new DoubleValue(scale);
+      PeriodParameter.Value = new DoubleValue(period);
+      InverseLengthParameter.Value = new DoubleValue(inverseLength);
     }
 
-    public void SetParameter(double[] hyp) {
-      int i = 0;
-      if (!inverseLengthParameter.Fixed) {
-        inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
-        i++;
+
+    private void GetParameterValues(double[] p, out double scale, out double period, out double inverseLength) {
+      // gather parameter values
+      int c = 0;
+      if (InverseLengthParameter.Value != null) {
+        inverseLength = InverseLengthParameter.Value.Value;
+      } else {
+        inverseLength = 1.0 / Math.Exp(p[c]);
+        c++;
       }
-      if (!periodParameter.Fixed) {
-        periodParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));
-        i++;
+      if (PeriodParameter.Value != null) {
+        period = PeriodParameter.Value.Value;
+      } else {
+        period = Math.Exp(p[c]);
+        c++;
       }
-      if (!scaleParameter.Fixed) {
-        scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
-        i++;
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[c]);
+        c++;
       }
-      if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovariancePeriod", "hyp");
+      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovariancePeriodic", "p");
     }
 
-    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;
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double inverseLength, period, scale;
+      GetParameterValues(p, out scale, out period, out inverseLength);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => {
+        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 scale * Math.Exp(-2.0 * k);
+        return scale * Math.Exp(-2.0 * k);
+      };
+      cov.CrossCovariance = (x, xt, i, j) => {
+        double k = GetDistance(x, xt, i, j, columnIndices);
+        k = Math.PI * k / period;
+        k = Math.Sin(k) * inverseLength;
+        k = k * k;
+
+        return scale * Math.Exp(-2.0 * k);
+      };
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, period, inverseLength);
+      return cov;
     }
 
-    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, double period, double inverseLength) {
       double v = i == j ? 0.0 : Math.PI * GetDistance(x, x, i, j, columnIndices) / period;
       double gradient = Math.Sin(v) * inverseLength;
@@ -144,14 +142,5 @@
     }
 
-    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;
-
-      return scale * Math.Exp(-2.0 * k);
-    }
-
-    private double GetDistance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
+    private static 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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceProduct.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceProduct.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceProduct.cs	(revision 8982)
@@ -23,4 +23,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using System.Linq.Expressions;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -66,22 +67,34 @@
     }
 
-    public void SetParameter(double[] hyp) {
-      if (factors.Count == 0) throw new ArgumentException("at least one factor is necessary for the product covariance function.");
+    public void SetParameter(double[] p) {
       int offset = 0;
-      foreach (var t in factors) {
-        var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);
-        t.SetParameter(hyp.Skip(offset).Take(numberOfParameters).ToArray());
+      foreach (var f in factors) {
+        var numberOfParameters = f.GetNumberOfParameters(numberOfVariables);
+        f.SetParameter(p.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 ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      if (factors.Count == 0) throw new ArgumentException("at least one factor is necessary for the product covariance function.");
+      var functions = new List<ParameterizedCovarianceFunction>();
+      foreach (var f in factors) {
+        int numberOfParameters = f.GetNumberOfParameters(numberOfVariables);
+        functions.Add(f.GetParameterizedCovarianceFunction(p.Take(numberOfParameters).ToArray(), columnIndices));
+        p = p.Skip(numberOfParameters).ToArray();
+      }
+
+
+      var product = new ParameterizedCovarianceFunction();
+      product.Covariance = (x, i, j) => functions.Select(e => e.Covariance(x, i, j)).Aggregate((a, b) => a * b);
+      product.CrossCovariance = (x, xt, i, j) => functions.Select(e => e.CrossCovariance(x, xt, i, j)).Aggregate((a, b) => a * b);
+      product.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, functions);
+      return product;
     }
 
-    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)) {
+    public static IEnumerable<double> GetGradient(double[,] x, int i, int j, List<ParameterizedCovarianceFunction> factorFunctions) {
+      var covariances = factorFunctions.Select(f => f.Covariance(x, i, j)).ToArray();
+      for (int ii = 0; ii < factorFunctions.Count; ii++) {
+        foreach (var g in factorFunctions[ii].CovarianceGradient(x, i, j)) {
           double res = g;
           for (int jj = 0; jj < covariances.Length; jj++)
@@ -91,8 +104,4 @@
       }
     }
-
-    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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticArd.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticArd.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticArd.cs	(revision 8982)
@@ -26,4 +26,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -33,26 +34,14 @@
     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; }
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     }
 
-    [Storable]
-    private double[] inverseLength;
-    [Storable]
-    private readonly HyperParameter<DoubleArray> inverseLengthParameter;
     public IValueParameter<DoubleArray> InverseLengthParameter {
-      get { return inverseLengthParameter; }
+      get { return (IValueParameter<DoubleArray>)Parameters["InverseLength"]; }
     }
 
-    [Storable]
-    private double shape;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> shapeParameter;
     public IValueParameter<DoubleValue> ShapeParameter {
-      get { return shapeParameter; }
+      get { return (IValueParameter<DoubleValue>)Parameters["Shape"]; }
     }
 
@@ -64,17 +53,4 @@
     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();
     }
 
@@ -84,13 +60,7 @@
       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();
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the rational quadratic covariance function with ARD."));
+      Parameters.Add(new OptionalValueParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination."));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the rational quadratic covariance function with ARD."));
     }
 
@@ -99,48 +69,65 @@
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEvents();
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (ScaleParameter.Value != null ? 0 : 1) +
+        (ShapeParameter.Value != null ? 0 : 1) +
+        (InverseLengthParameter.Value != null ? 0 : numberOfVariables);
     }
 
-    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 void SetParameter(double[] p) {
+      double scale, shape;
+      double[] inverseLength;
+      GetParameterValues(p, out scale, out shape, out inverseLength);
+      ScaleParameter.Value = new DoubleValue(scale);
+      ShapeParameter.Value = new DoubleValue(shape);
+      InverseLengthParameter.Value = new DoubleArray(inverseLength);
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return
-        (scaleParameter.Fixed ? 0 : 1) +
-        (shapeParameter.Fixed ? 0 : 1) +
-        (inverseLengthParameter.Fixed ? 0 : numberOfVariables);
+    private void GetParameterValues(double[] p, out double scale, out double shape, out double[] inverseLength) {
+      int c = 0;
+      // gather parameter values
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[c]);
+        c++;
+      }
+      if (ShapeParameter.Value != null) {
+        shape = ShapeParameter.Value.Value;
+      } else {
+        shape = Math.Exp(p[c]);
+        c++;
+      }
+      if (InverseLengthParameter.Value != null) {
+        inverseLength = InverseLengthParameter.Value.ToArray();
+      } else {
+        inverseLength = p.Skip(2).Select(e => 1.0 / Math.Exp(e)).ToArray();
+        c += inverseLength.Length;
+      }
+      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRationalQuadraticArd", "p");
     }
 
-    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 ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double scale, shape;
+      double[] inverseLength;
+      GetParameterValues(p, out scale, out shape, out inverseLength);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => {
+        double d = i == j
+                    ? 0.0
+                    : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+        return scale * Math.Pow(1 + 0.5 * d / shape, -shape);
+      };
+      cov.CrossCovariance = (x, xt, i, j) => {
+        double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
+        return scale * Math.Pow(1 + 0.5 * d / shape, -shape);
+      };
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, shape, inverseLength);
+      return cov;
     }
 
-
-    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) {
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, double shape, double[] inverseLength) {
       if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
       double d = i == j
@@ -150,14 +137,9 @@
       int k = 0;
       foreach (var columnIndex in columnIndices) {
-        yield return sf2 * Math.Pow(b, -shape - 1) * Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]);
+        yield return scale * Math.Pow(b, -shape - 1) * Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]);
         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);
+      yield return 2 * scale * Math.Pow(b, -shape);
+      yield return scale * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticIso.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticIso.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticIso.cs	(revision 8982)
@@ -25,4 +25,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -32,22 +33,15 @@
     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; } }
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
+    }
 
-    [Storable]
-    private double inverseLength;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
-    public IValueParameter<DoubleValue> InverseLengthParameter { get { return inverseLengthParameter; } }
+    public IValueParameter<DoubleValue> InverseLengthParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["InverseLength"]; }
+    }
 
-    [Storable]
-    private double shape;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> shapeParameter;
-    public IValueParameter<DoubleValue> ShapeParameter { get { return shapeParameter; } }
-
+    public IValueParameter<DoubleValue> ShapeParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["Shape"]; }
+    }
     [StorableConstructor]
     private CovarianceRationalQuadraticIso(bool deserializing)
@@ -57,14 +51,4 @@
     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();
     }
 
@@ -74,13 +58,7 @@
       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();
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the isometric rational quadratic covariance function."));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric rational quadratic covariance function."));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the isometric rational quadratic covariance function."));
     }
 
@@ -89,48 +67,62 @@
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEvents();
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return (ScaleParameter.Value != null ? 0 : 1) +
+        (ShapeParameter.Value != null ? 0 : 1) +
+        (InverseLengthParameter.Value != null ? 0 : 1);
     }
 
-    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 void SetParameter(double[] p) {
+      double scale, shape, inverseLength;
+      GetParameterValues(p, out scale, out shape, out inverseLength);
+      ScaleParameter.Value = new DoubleValue(scale);
+      ShapeParameter.Value = new DoubleValue(shape);
+      InverseLengthParameter.Value = new DoubleValue(inverseLength);
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return
-        (scaleParameter.Fixed ? 0 : 1) +
-        (inverseLengthParameter.Fixed ? 0 : 1) +
-        (shapeParameter.Fixed ? 0 : 1);
+    private void GetParameterValues(double[] p, out double scale, out double shape, out double inverseLength) {
+      int c = 0;
+      // gather parameter values
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[c]);
+        c++;
+      }
+      if (ShapeParameter.Value != null) {
+        shape = ShapeParameter.Value.Value;
+      } else {
+        shape = Math.Exp(p[c]);
+        c++;
+      }
+      if (InverseLengthParameter.Value != null) {
+        inverseLength = InverseLengthParameter.Value.Value;
+      } else {
+        inverseLength = 1.0 / Math.Exp(p[c]);
+        c++;
+      }
+      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRationalQuadraticIso", "p");
     }
 
-    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 ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double scale, shape, inverseLength;
+      GetParameterValues(p, out scale, out shape, out inverseLength);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => {
+        double d = i == j
+                    ? 0.0
+                    : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+        return shape * Math.Pow(1 + 0.5 * d / shape, -shape);
+      };
+      cov.CrossCovariance = (x, xt, i, j) => {
+        double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
+        return scale * Math.Pow(1 + 0.5 * d / shape, -shape);
+      };
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, shape, inverseLength);
+      return cov;
     }
 
-
-    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) {
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, double shape, double inverseLength) {
       double d = i == j
                    ? 0.0
@@ -138,12 +130,7 @@
 
       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);
+      yield return scale * Math.Pow(b, -shape - 1) * d;
+      yield return 2 * scale * Math.Pow(b, -shape);
+      yield return scale * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceScale.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceScale.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceScale.cs	(revision 8982)
@@ -34,18 +34,10 @@
     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; }
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     }
 
-    [Storable]
-    private ICovarianceFunction cov;
-    [Storable]
-    private readonly ValueParameter<ICovarianceFunction> covParameter;
     public IValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
-      get { return covParameter; }
+      get { return (IValueParameter<ICovarianceFunction>)Parameters["CovarianceFunction"]; }
     }
 
@@ -57,10 +49,4 @@
     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();
     }
 
@@ -70,12 +56,6 @@
       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();
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter."));
+      Parameters.Add(new ValueParameter<ICovarianceFunction>("CovarianceFunction", "The covariance function that should be scaled.", new CovarianceSquaredExponentialIso()));
     }
 
@@ -84,39 +64,40 @@
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEvents();
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return (ScaleParameter.Value != null ? 0 : 1) + CovarianceFunctionParameter.Value.GetNumberOfParameters(numberOfVariables);
     }
 
-    private void RegisterEvents() {
-      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
-      covParameter.ValueChanged += (sender, args) => { cov = covParameter.Value; };
+    public void SetParameter(double[] p) {
+      double scale;
+      GetParameterValues(p, out scale);
+      ScaleParameter.Value = new DoubleValue(scale);
+      CovarianceFunctionParameter.Value.SetParameter(p.Skip(1).ToArray());
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return (scaleParameter.Fixed ? 0 : 1) + cov.GetNumberOfParameters(numberOfVariables);
+    private void GetParameterValues(double[] p, out double scale) {
+      // gather parameter values
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[0]);
+      }
     }
 
-    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 ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double scale;
+      GetParameterValues(p, out scale);
+      var subCov = CovarianceFunctionParameter.Value.GetParameterizedCovarianceFunction(p.Skip(1).ToArray(), columnIndices);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => scale * subCov.Covariance(x, i, j);
+      cov.CrossCovariance = (x, xt, i, j) => scale * subCov.CrossCovariance(x, xt, i, j);
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, subCov);
+      return cov;
     }
 
-    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);
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, ParameterizedCovarianceFunction cov) {
+      yield return 2 * scale * cov.Covariance(x, i, j);
+      foreach (var g in cov.CovarianceGradient(x, i, j))
+        yield return scale * g;
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialArd.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialArd.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialArd.cs	(revision 8982)
@@ -26,4 +26,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -32,15 +33,11 @@
   [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; } }
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
+    }
 
-    [Storable]
-    private double[] inverseLength;
-    [Storable]
-    private readonly HyperParameter<DoubleArray> inverseLengthParameter;
-    public IValueParameter<DoubleArray> InverseLengthParameter { get { return inverseLengthParameter; } }
+    public IValueParameter<DoubleArray> InverseLengthParameter {
+      get { return (IValueParameter<DoubleArray>)Parameters["InverseLength"]; }
+    }
 
     [StorableConstructor]
@@ -48,14 +45,4 @@
     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()
@@ -64,11 +51,6 @@
       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();
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the squared exponential covariance function with ARD."));
+      Parameters.Add(new OptionalValueParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination."));
     }
 
@@ -77,45 +59,58 @@
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEvents();
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (ScaleParameter.Value != null ? 0 : 1) +
+        (InverseLengthParameter.Value != null ? 0 : numberOfVariables);
     }
 
-    private void RegisterEvents() {
-      Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
-      Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => {
-        inverseLength =
-          inverseLengthParameter.Value.ToArray();
-      });
+    public void SetParameter(double[] p) {
+      double scale;
+      double[] inverseLength;
+      GetParameterValues(p, out scale, out inverseLength);
+      ScaleParameter.Value = new DoubleValue(scale);
+      InverseLengthParameter.Value = new DoubleArray(inverseLength);
     }
 
-    public int GetNumberOfParameters(int numberOfVariables) {
-      return
-        (scaleParameter.Fixed ? 0 : 1) +
-        (inverseLengthParameter.Fixed ? 0 : numberOfVariables);
+    private void GetParameterValues(double[] p, out double scale, out double[] inverseLength) {
+      int c = 0;
+      // gather parameter values
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[c]);
+        c++;
+      }
+      if (InverseLengthParameter.Value != null) {
+        inverseLength = InverseLengthParameter.Value.ToArray();
+      } else {
+        inverseLength = p.Skip(1).Select(e => 1.0 / Math.Exp(e)).ToArray();
+        c += inverseLength.Length;
+      }
+      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceSquaredExponentialArd", "p");
+    }
+
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double scale;
+      double[] inverseLength;
+      GetParameterValues(p, out scale, out inverseLength);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => {
+        double d = i == j
+                 ? 0.0
+                 : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+        return scale * Math.Exp(-d / 2.0);
+      };
+      cov.CrossCovariance = (x, xt, i, j) => {
+        double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
+        return scale * Math.Exp(-d / 2.0);
+      };
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, inverseLength);
+      return cov;
     }
 
 
-    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) {
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, double[] inverseLength) {
       if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
       double d = i == j
@@ -125,14 +120,9 @@
       foreach (var columnIndex in columnIndices) {
         double sqrDist = Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]);
-        yield return sf2 * Math.Exp(-d / 2.0) * sqrDist;
+        yield return scale * Math.Exp(-d / 2.0) * sqrDist;
         k++;
       }
 
-      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);
+      yield return 2.0 * scale * Math.Exp(-d / 2.0);
     }
   }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialIso.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialIso.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialIso.cs	(revision 8982)
@@ -22,7 +22,9 @@
 using System;
 using System.Collections.Generic;
+using System.Linq.Expressions;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -32,15 +34,11 @@
     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; } }
+    public IValueParameter<DoubleValue> ScaleParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
+    }
 
-    [Storable]
-    private double inverseLength;
-    [Storable]
-    private readonly HyperParameter<DoubleValue> inverseLengthParameter;
-    public IValueParameter<DoubleValue> InverseLengthParameter { get { return inverseLengthParameter; } }
+    public IValueParameter<DoubleValue> InverseLengthParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["InverseLength"]; }
+    }
 
     [StorableConstructor]
@@ -51,11 +49,4 @@
     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();
     }
 
@@ -65,11 +56,6 @@
       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();
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the isometric squared exponential covariance function."));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric squared exponential covariance function."));
     }
 
@@ -78,42 +64,57 @@
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterEvents();
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return
+        (ScaleParameter.Value != null ? 0 : 1) +
+        (InverseLengthParameter.Value != null ? 0 : 1);
     }
 
-    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 void SetParameter(double[] p) {
+      double scale, inverseLength;
+      GetParameterValues(p, out scale, out inverseLength);
+      ScaleParameter.Value = new DoubleValue(scale);
+      InverseLengthParameter.Value = new DoubleValue(inverseLength);
     }
 
 
-    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);
+    private void GetParameterValues(double[] p, out double scale, out double inverseLength) {
+      // gather parameter values
+      int c = 0;
+      if (InverseLengthParameter.Value != null) {
+        inverseLength = InverseLengthParameter.Value.Value;
+      } else {
+        inverseLength = 1.0 / Math.Exp(p[c]);
+        c++;
+      }
+
+      if (ScaleParameter.Value != null) {
+        scale = ScaleParameter.Value.Value;
+      } else {
+        scale = Math.Exp(2 * p[c]);
+        c++;
+      }
+      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceSquaredExponentialIso", "p");
     }
 
-    public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      double inverseLength, scale;
+      GetParameterValues(p, out scale, out inverseLength);
+      // create functions
+      var cov = new ParameterizedCovarianceFunction();
+      cov.Covariance = (x, i, j) => {
+        double d = i == j
+                ? 0.0
+                : Util.SqrDist(x, i, j, inverseLength, columnIndices);
+        return scale * Math.Exp(-d / 2.0);
+      };
+      cov.CrossCovariance = (x, xt, i, j) => {
+        double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
+        return scale * Math.Exp(-d / 2.0);
+      };
+      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, scale, inverseLength, columnIndices);
+      return cov;
+    }
+
+    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double sf2, double inverseLength, IEnumerable<int> columnIndices) {
       double d = i == j
                    ? 0.0
@@ -123,9 +124,4 @@
       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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSum.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSum.cs	(revision 8933)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSum.cs	(revision 8982)
@@ -23,4 +23,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using System.Linq.Expressions;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -66,24 +67,27 @@
     }
 
-    public void SetParameter(double[] hyp) {
-      if (terms.Count == 0) throw new ArgumentException("At least one term is needed for sum covariance function.");
+    public void SetParameter(double[] p) {
       int offset = 0;
       foreach (var t in terms) {
         var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);
-        t.SetParameter(hyp.Skip(offset).Take(numberOfParameters).ToArray());
+        t.SetParameter(p.Skip(offset).Take(numberOfParameters).ToArray());
         offset += numberOfParameters;
       }
     }
 
-    public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
-      return terms.Select(t => t.GetCovariance(x, i, j, columnIndices)).Sum();
-    }
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
+      if (terms.Count == 0) throw new ArgumentException("at least one term is necessary for the product covariance function.");
+      var functions = new List<ParameterizedCovarianceFunction>();
+      foreach (var t in terms) {
+        var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);
+        functions.Add(t.GetParameterizedCovarianceFunction(p.Take(numberOfParameters).ToArray(), columnIndices));
+        p = p.Skip(numberOfParameters).ToArray();
+      }
 
-    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 GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
-      return terms.Select(t => t.GetCrossCovariance(x, xt, i, j, columnIndices)).Sum();
+      var sum = new ParameterizedCovarianceFunction();
+      sum.Covariance = (x, i, j) => functions.Select(e => e.Covariance(x, i, j)).Sum();
+      sum.CrossCovariance = (x, xt, i, j) => functions.Select(e => e.CrossCovariance(x, xt, i, j)).Sum();
+      sum.CovarianceGradient = (x, i, j) => functions.Select(e => e.CovarianceGradient(x, i, j)).Aggregate(Enumerable.Concat);
+      return sum;
     }
   }
