Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/GaussianProcessRegressionSolutionLineChartView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/GaussianProcessRegressionSolutionLineChartView.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/GaussianProcessRegressionSolutionLineChartView.cs	(revision 8484)
@@ -91,11 +91,17 @@
         // series of remaining points
         int[] allIndices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
-        var estimatedValues = Content.EstimatedValues.ToArray();
-        List<double> allEstimatedValues = allIndices.Select(index => estimatedValues[index]).ToList();
+        mean = Content.EstimatedValues.ToArray();
+        s2 = Content.EstimatedVariance.ToArray();
+        lower = mean.Zip(s2, (m, s) => m - 1.96 * Math.Sqrt(s)).ToArray();
+        upper = mean.Zip(s2, (m, s) => m + 1.96 * Math.Sqrt(s)).ToArray();
+        List<double> allLower = allIndices.Select(index => lower[index]).ToList();
+        List<double> allUpper = allIndices.Select(index => upper[index]).ToList();
         this.chart.Series.Add(ESTIMATEDVALUES_ALL_SERIES_NAME);
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].LegendText = ESTIMATEDVALUES_ALL_SERIES_NAME;
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].ChartType = SeriesChartType.Range;
-        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndices, allEstimatedValues);
-        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+        if (allIndices.Count() > 0) {
+          this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndices, allLower, allUpper);
+          this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+        }
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Tag = Content;
 
@@ -127,5 +133,6 @@
         if ((int)p2.XValue - (int)p1.XValue != 1) {
           // insert an empty point between p1 and p2 so that the line will be invisible (transparent)
-          var p = new DataPoint((int)((p1.XValue + p2.XValue) / 2), 0.0) { IsEmpty = true };
+          var p = new DataPoint((int)((p1.XValue + p2.XValue) / 2), new double[] { 0.0, 0.0 }) { IsEmpty = true };
+          // insert 
           series.Points.Insert(i + 1, p);
         }
@@ -236,5 +243,4 @@
         }
       } else if (Content != null) {
-        string targetVariableName = Content.ProblemData.TargetVariable;
 
         IEnumerable<int> indices = null;
@@ -268,9 +274,11 @@
             break;
         }
-        series.Points.DataBindXY(indices, lower, upper);
-        this.InsertEmptyPoints(series);
-        chart.Legends[series.Legend].ForeColor = Color.Black;
-        UpdateCursorInterval();
-        chart.Refresh();
+        if (indices.Count() > 0) {
+          series.Points.DataBindXY(indices, lower, upper);
+          this.InsertEmptyPoints(series);
+          chart.Legends[series.Legend].ForeColor = Color.Black;
+          UpdateCursorInterval();
+          chart.Refresh();
+        }
       }
     }
@@ -300,8 +308,8 @@
     private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
       if (chart.Series.Count != 4) return;
-      e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-      e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-      e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-      e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceConst.cs	(revision 8484)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -57,22 +58,19 @@
 
     public void SetParameter(double[] hyp) {
+      if (hyp.Length != 1) throw new ArgumentException("CovarianceConst has only one hyperparameter", "k");
       this.sf2 = Math.Exp(2 * hyp[0]);
-    }
-    public void SetData(double[,] x) {
-      // nothing to do
     }
 
 
-    public void SetData(double[,] x, double[,] xt) {
-      // nothing to do
-    }
-
-    public double GetCovariance(int i, int j) {
+    public double GetCovariance(double[,] x, int i, int j) {
       return sf2;
     }
 
-    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 IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+      yield return 2 * sf2;
+    }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+      return sf2;
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinear.cs	(revision 8484)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,12 +30,4 @@
   [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;
@@ -44,15 +37,4 @@
     protected 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()
@@ -66,51 +48,16 @@
     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) {
+      return Util.ScalarProd(Util.GetRow(x, i), Util.GetRow(x, j));
     }
 
-    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) {
+      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) {
+      return Util.ScalarProd(Util.GetRow(x, i), Util.GetRow(xt, j));
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs	(revision 8484)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceLinearArd.cs	(revision 8484)
@@ -0,0 +1,132 @@
+﻿#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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "CovarianceLinearArd",
+    Description = "Linear covariance function with automatic relevance determination for Gaussian processes.")]
+  public class CovarianceLinearArd : Item, ICovarianceFunction {
+    [Storable]
+    private double[,] x;
+    [Storable]
+    private double[,] xt;
+
+    [Storable]
+    private double[] l;
+    public double[] Length {
+      get {
+        double[] res = new double[l.Length];
+        Array.Copy(l, res, res.Length);
+        return res;
+      }
+    }
+
+    private double[,] k;
+    private bool symmetric;
+
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return numberOfVariables;
+    }
+    [StorableConstructor]
+    protected CovarianceLinearArd(bool deserializing) : base(deserializing) { }
+    protected CovarianceLinearArd(CovarianceLinearArd 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.l = new double[original.l.GetLength(0)];
+        Array.Copy(original.l, this.l, l.Length);
+      }
+      this.symmetric = original.symmetric;
+    }
+    public CovarianceLinearArd()
+      : base() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovarianceLinearArd(this, cloner);
+    }
+
+    public void SetParameter(double[] hyp) {
+      l = hyp.Select(Math.Exp).ToArray();
+    }
+
+    public void SetData(double[,] x) {
+      SetData(x, x);
+      this.symmetric = true;
+    }
+
+    public void SetData(double[,] x, double[,] xt) {
+      this.x = x;
+      this.xt = xt;
+      this.symmetric = false;
+
+      k = null;
+    }
+
+    public double GetCovariance(int i, int j) {
+      if (k == null) CalculateInnerProduct();
+      return k[i, j];
+    }
+
+    public double GetGradient(int i, int j, int k) {
+
+    }
+
+
+    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).Select((e, k) => e / l[k]),
+                                      Util.GetRow(x, j).Select((e, k) => e / l[k]));
+            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).Select((e, k) => e / l[k]),
+                                      Util.GetRow(xt, j).Select((e, k) => e / l[k]));
+          }
+        }
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceNoise.cs	(revision 8484)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -59,24 +60,15 @@
       this.sf2 = Math.Exp(2 * hyp[0]);
     }
-    public void SetData(double[,] x) {
-      // nothing to do
+
+    public double GetCovariance(double[,] x, int i, int j) {
+      return sf2;
     }
 
-
-    public void SetData(double[,] x, double[,] xt) {
-      // nothing to do
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+      yield return 2 * sf2;
     }
 
-    public double GetCovariance(int i, int j) {
-      if (i == j) return sf2;
-      else return 0.0;
-    }
-
-    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) {
+      return 0.0;
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs	(revision 8484)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,8 +30,4 @@
   [Item(Name = "CovariancePeriodic", Description = "Periodic covariance function for Gaussian processes.")]
   public class CovariancePeriodic : Item, ICovarianceFunction {
-    [Storable]
-    private double[,] x;
-    [Storable]
-    private double[,] xt;
     [Storable]
     private double sf2;
@@ -43,7 +40,4 @@
     public double Period { get { return p; } }
 
-    private bool symmetric;
-
-    private double[,] sd;
     public int GetNumberOfParameters(int numberOfVariables) {
       return 3;
@@ -53,14 +47,7 @@
     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()
@@ -77,24 +64,8 @@
       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;
     }
 
-    public void SetData(double[,] x, double[,] xt) {
-      this.x = x;
-      this.xt = xt;
-      this.symmetric = false;
-
-      sd = null;
-    }
-
-    public double GetCovariance(int i, int j) {
-      if (sd == null) CalculateSquaredDistances();
-      double k = sd[i, j];
+    public double GetCovariance(double[,] x, int i, int j) {
+      double k = i == j ? 0.0 : GetDistance(x, x, i, j);
       k = Math.PI * k / p;
       k = Math.Sin(k) / l;
@@ -104,48 +75,25 @@
     }
 
-    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) {
+      double v = i == j ? 0.0 : Math.PI * GetDistance(x, x, i, j) / p;
+      double gradient = Math.Sin(v) / l;
+      gradient *= gradient;
+      yield return 4.0 * sf2 * Math.Exp(-2.0 * gradient) * gradient;
+      double r = Math.Sin(v) / l;
+      yield return 4.0 * sf2 / l * Math.Exp(-2 * r * r) * r * Math.Cos(v) * v;
+      yield return 2.0 * sf2 * 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) {
+      double k = GetDistance(x, xt, i, j);
+      k = Math.PI * k / p;
+      k = Math.Sin(k) / l;
+      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 sf2 * Math.Exp(-2.0 * k);
+    }
+
+    private double GetDistance(double[,] x, double[,] xt, int i, int j) {
+      return Math.Sqrt(Util.SqrDist(Util.GetRow(x, i), Util.GetRow(xt, j)));
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProd.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProd.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProd.cs	(revision 8484)
@@ -73,8 +73,9 @@
     public int GetNumberOfParameters(int numberOfVariables) {
       this.numberOfVariables = numberOfVariables;
-      return factors.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();
+      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) {
@@ -84,37 +85,41 @@
       }
     }
-    public void SetData(double[,] x) {
-      SetData(x, x);
+
+    public double GetCovariance(double[,] x, int i, int j) {
+      return factors.Select(f => f.GetCovariance(x, i, j)).Aggregate((a, b) => a * b);
     }
 
-    public void SetData(double[,] x, double[,] xt) {
-      foreach (var t in factors) {
-        t.SetData(x, xt);
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+      //if (cachedParameterMap == null) {
+      //  CalculateParameterMap();
+      //}
+      //int ti = cachedParameterMap[k].Item1;
+      //k = cachedParameterMap[k].Item2;
+      //double gradient = 1.0;
+      //for (int ii = 0; ii < factors.Count; ii++) {
+      //  var f = factors[ii];
+      //  if (ii == ti) {
+      //    gradient *= f.GetGradient(x, i, j, k);
+      //  } else {
+      //    gradient *= f.GetCovariance(x, i, j);
+      //  }
+      //}
+      //return gradient;
+      var covariances = factors.Select(f => f.GetCovariance(x, i, j)).ToArray();
+      for (int ii = 0; ii < factors.Count; ii++) {
+        foreach (var g in factors[ii].GetGradient(x, i, j)) {
+          double res = g;
+          for (int jj = 0; jj < covariances.Length; jj++)
+            if (ii != jj) res *= covariances[jj];
+          yield return res;
+        }
       }
     }
 
-    public double GetCovariance(int i, int j) {
-      return factors.Select(t => t.GetCovariance(i, j)).Aggregate((a, b) => a * b);
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+      return factors.Select(f => f.GetCrossCovariance(x, xt, i, j)).Aggregate((a, b) => a * b);
     }
 
     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;
-      double res = 1.0;
-      for (int ii = 0; ii < factors.Count; ii++) {
-        var f = factors[ii];
-        if (ii == ti) {
-          res *= f.GetGradient(i, j, k);
-        } else {
-          res *= f.GetCovariance(i, j);
-        }
-      }
-      return res;
-    }
-
     private void ClearCache() {
       cachedParameterMap = null;
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQiso.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQiso.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceRQiso.cs	(revision 8484)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
@@ -32,8 +33,4 @@
   public class CovarianceRQiso : Item, ICovarianceFunction {
     [Storable]
-    private double[,] x;
-    [Storable]
-    private double[,] xt;
-    [Storable]
     private double sf2;
     public double Scale { get { return sf2; } }
@@ -44,7 +41,4 @@
     private double alpha;
     public double Shape { get { return alpha; } }
-    [Storable]
-    private bool symmetric;
-    private double[,] d2;
 
     [StorableConstructor]
@@ -55,19 +49,7 @@
     protected CovarianceRQiso(CovarianceRQiso 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.d2 = new double[original.d2.GetLength(0), original.d2.GetLength(1)];
-        Array.Copy(original.d2, this.d2, d2.Length);
-        this.sf2 = original.sf2;
-      }
       this.sf2 = original.sf2;
       this.l = original.l;
       this.alpha = original.alpha;
-      this.symmetric = original.symmetric;
     }
 
@@ -85,60 +67,35 @@
 
     public void SetParameter(double[] hyp) {
+      if (hyp.Length != 3) throw new ArgumentException("CovarianceRQiso has three hyperparameters", "k");
       this.l = Math.Exp(hyp[0]);
       this.sf2 = Math.Exp(2 * hyp[1]);
       this.alpha = Math.Exp(hyp[2]);
-      d2 = null;
-    }
-    public void SetData(double[,] x) {
-      SetData(x, x);
-      this.symmetric = true;
     }
 
 
-    public void SetData(double[,] x, double[,] xt) {
-      this.symmetric = false;
-      this.x = x;
-      this.xt = xt;
-      d2 = null;
+    public double GetCovariance(double[,] x, int i, int j) {
+      double lInv = 1.0 / l;
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(x, j).Select(e => e * lInv));
+      return sf2 * Math.Pow(1 + 0.5 * d / alpha, -alpha);
     }
 
-    public double GetCovariance(int i, int j) {
-      if (d2 == null) CalculateSquaredDistances();
-      return sf2 * Math.Pow(1 + 0.5 * d2[i, j] / alpha, -alpha);
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+      double lInv = 1.0 / l;
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(x, j).Select(e => e * lInv));
+
+      double b = 1 + 0.5 * d / alpha;
+      yield return sf2 * Math.Pow(b, -alpha - 1) * d;
+      yield return 2 * sf2 * Math.Pow(b, -alpha);
+      yield return sf2 * Math.Pow(b, -alpha) * (0.5 * d / b - alpha * Math.Log(b));
     }
 
-    public double GetGradient(int i, int j, int k) {
-      switch (k) {
-        case 0: return sf2 * Math.Pow(1 + 0.5 * d2[i, j] / alpha, -alpha - 1) * d2[i, j];
-        case 1: return 2 * sf2 * Math.Pow((1 + 0.5 * d2[i, j] / alpha), (-alpha));
-        case 2: {
-            double g = (1 + 0.5 * d2[i, j] / alpha);
-            g = sf2 * Math.Pow(g, -alpha) * (0.5 * d2[i, j] / g - alpha * Math.Log(g));
-            return g;
-          }
-        default: throw new ArgumentException("CovarianceRQiso has three hyperparameters", "k");
-      }
-    }
-
-    private void CalculateSquaredDistances() {
-      if (x.GetLength(1) != xt.GetLength(1)) throw new InvalidOperationException();
-      int rows = x.GetLength(0);
-      int cols = xt.GetLength(0);
-      d2 = new double[rows, cols];
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
       double lInv = 1.0 / l;
-      if (symmetric) {
-        for (int i = 0; i < rows; i++) {
-          for (int j = i; j < rows; j++) {
-            d2[i, j] = Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(xt, j).Select(e => e * lInv));
-            d2[j, i] = d2[i, j];
-          }
-        }
-      } else {
-        for (int i = 0; i < rows; i++) {
-          for (int j = 0; j < cols; j++) {
-            d2[i, j] = Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(xt, j).Select(e => e * lInv));
-          }
-        }
-      }
+      double d = Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(xt, j).Select(e => e * lInv));
+      return sf2 * Math.Pow(1 + 0.5 * d / alpha, -alpha);
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEard.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEard.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEard.cs	(revision 8484)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
@@ -30,8 +31,4 @@
   [Item(Name = "CovarianceSEard", Description = "Squared exponential covariance function with automatic relevance determination for Gaussian processes.")]
   public class CovarianceSEard : Item, ICovarianceFunction {
-    [Storable]
-    private double[,] x;
-    [Storable]
-    private double[,] xt;
     [Storable]
     private double sf2;
@@ -49,7 +46,4 @@
     }
 
-    private double[,] sd;
-    private bool symmetric;
-
     public int GetNumberOfParameters(int numberOfVariables) {
       return numberOfVariables + 1;
@@ -59,19 +53,9 @@
     protected CovarianceSEard(CovarianceSEard 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.sd = new double[original.sd.GetLength(0), original.sd.GetLength(1)];
-        Array.Copy(original.sd, this.sd, sd.Length);
-
+      if (original.l != null) {
         this.l = new double[original.l.Length];
         Array.Copy(original.l, this.l, l.Length);
       }
       this.sf2 = original.sf2;
-      this.symmetric = original.symmetric;
     }
     public CovarianceSEard()
@@ -86,60 +70,30 @@
       this.l = hyp.Take(hyp.Length - 1).Select(Math.Exp).ToArray();
       this.sf2 = Math.Exp(2 * hyp[hyp.Length - 1]);
-      // sf2 = Math.Min(10E6, sf2); // upper limit for the scale
-
-      sd = null;
     }
 
-    public void SetData(double[,] x) {
-      SetData(x, x);
-      this.symmetric = true;
+    public double GetCovariance(double[,] x, int i, int j) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(Util.GetRow(x, i).Select((e, k) => e / l[k]),
+                                  Util.GetRow(x, j).Select((e, k) => e / l[k]));
+      return sf2 * Math.Exp(-d / 2.0);
     }
 
-    public void SetData(double[,] x, double[,] xt) {
-      this.x = x;
-      this.xt = xt;
-      this.symmetric = false;
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(Util.GetRow(x, i).Select((e, ii) => e / l[ii]),
+                                  Util.GetRow(x, j).Select((e, ii) => e / l[ii]));
 
-      sd = null;
+      for (int ii = 0; ii < l.Length; ii++) {
+        double sqrDist = Util.SqrDist(x[i, ii] / l[ii], x[j, ii] / l[ii]);
+        yield return sf2 * Math.Exp(d / 2.0) * sqrDist;
+      }
+      yield return 2.0 * sf2 * Math.Exp(d / 2.0);
     }
 
-    public double GetCovariance(int i, int j) {
-      if (sd == null) CalculateSquaredDistances();
-      return sf2 * Math.Exp(-sd[i, j] / 2.0);
-    }
-
-    public double GetGradient(int i, int j, int k) {
-      if (k < l.Length) {
-        double sqrDist = Util.SqrDist(x[i, k] / l[k], xt[j, k] / l[k]);
-        return sf2 * Math.Exp(-sd[i, j] / 2.0) * sqrDist;
-      } else if (k == l.Length) {
-        return 2.0 * sf2 * Math.Exp(-sd[i, j] / 2.0);
-      } else {
-        throw new ArgumentException("CovarianceSEard has dimension+1 hyperparameters.", "k");
-      }
-    }
-
-
-    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];
-      if (symmetric) {
-        for (int i = 0; i < rows; i++) {
-          for (int j = i; j < cols; j++) {
-            sd[i, j] = Util.SqrDist(Util.GetRow(x, i).Select((e, k) => e / l[k]),
-                                    Util.GetRow(xt, j).Select((e, k) => e / l[k]));
-            sd[j, i] = sd[i, j];
-          }
-        }
-      } else {
-        for (int i = 0; i < rows; i++) {
-          for (int j = 0; j < cols; j++) {
-            sd[i, j] = Util.SqrDist(Util.GetRow(x, i).Select((e, k) => e / l[k]),
-                                    Util.GetRow(xt, j).Select((e, k) => e / l[k]));
-          }
-        }
-      }
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+      double d = Util.SqrDist(Util.GetRow(x, i).Select((e, k) => e / l[k]), Util.GetRow(xt, j).Select((e, k) => e / l[k]));
+      return sf2 * Math.Exp(-d / 2.0);
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEiso.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEiso.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEiso.cs	(revision 8484)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
@@ -32,8 +33,4 @@
   public class CovarianceSEiso : Item, ICovarianceFunction {
     [Storable]
-    private double[,] x;
-    [Storable]
-    private double[,] xt;
-    [Storable]
     private double sf2;
     public double Scale { get { return sf2; } }
@@ -41,7 +38,4 @@
     private double l;
     public double Length { get { return l; } }
-    [Storable]
-    private bool symmetric;
-    private double[,] sd;
 
     [StorableConstructor]
@@ -52,18 +46,6 @@
     protected CovarianceSEiso(CovarianceSEiso 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.sd = new double[original.sd.GetLength(0), original.sd.GetLength(1)];
-        Array.Copy(original.sd, this.sd, sd.Length);
-        this.sf2 = original.sf2;
-      }
       this.sf2 = original.sf2;
       this.l = original.l;
-      this.symmetric = original.symmetric;
     }
 
@@ -81,54 +63,32 @@
 
     public void SetParameter(double[] hyp) {
+      if (hyp.Length != 2) throw new ArgumentException("CovarianceSEiso has two hyperparameters", "k");
       this.l = Math.Exp(hyp[0]);
       this.sf2 = Math.Exp(2 * hyp[1]);
-      sd = null;
-    }
-    public void SetData(double[,] x) {
-      SetData(x, x);
-      this.symmetric = true;
     }
 
 
-    public void SetData(double[,] x, double[,] xt) {
-      this.symmetric = false;
-      this.x = x;
-      this.xt = xt;
-      sd = null;
+    public double GetCovariance(double[,] x, int i, int j) {
+      double lInv = 1.0 / l;
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(x, j).Select(e => e * lInv));
+      return sf2 * Math.Exp(-d / 2.0);
     }
 
-    public double GetCovariance(int i, int j) {
-      if (sd == null) CalculateSquaredDistances();
-      return sf2 * Math.Exp(-sd[i, j] / 2.0);
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+      double lInv = 1.0 / l;
+      double d = i == j
+                   ? 0.0
+                   : Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(x, j).Select(e => e * lInv));
+      double g = Math.Exp(-d / 2.0);
+      yield return sf2 * g * d;
+      yield return 2.0 * sf2 * g;
     }
 
-    public double GetGradient(int i, int j, int k) {
-      switch (k) {
-        case 0: return sf2 * Math.Exp(-sd[i, j] / 2.0) * sd[i, j];
-        case 1: return 2.0 * sf2 * Math.Exp(-sd[i, j] / 2.0);
-        default: throw new ArgumentException("CovarianceSEiso has two hyperparameters", "k");
-      }
-    }
-
-    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) {
       double lInv = 1.0 / l;
-      if (symmetric) {
-        for (int i = 0; i < rows; i++) {
-          for (int j = i; j < rows; j++) {
-            sd[i, j] = Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(xt, j).Select(e => e * lInv));
-            sd[j, i] = sd[i, j];
-          }
-        }
-      } else {
-        for (int i = 0; i < rows; i++) {
-          for (int j = 0; j < cols; j++) {
-            sd[i, j] = Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(xt, j).Select(e => e * lInv));
-          }
-        }
-      }
+      double d = Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(xt, j).Select(e => e * lInv));
+      return sf2 * Math.Exp(-d / 2.0);
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs	(revision 8484)
@@ -77,4 +77,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,40 +85,37 @@
       }
     }
-    public void SetData(double[,] x) {
-      SetData(x, x);
-    }
 
-    public void SetData(double[,] x, double[,] xt) {
-      foreach (var t in terms) {
-        t.SetData(x, xt);
-      }
-    }
-
-    public double GetCovariance(int i, int j) {
-      return terms.Select(t => t.GetCovariance(i, j)).Sum();
+    public double GetCovariance(double[,] x, int i, int j) {
+      return terms.Select(t => t.GetCovariance(x, 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);
+    public IEnumerable<double> GetGradient(double[,] x, int i, int j) {
+      //if (cachedParameterMap == null) {
+      //  CalculateParameterMap();
+      //}
+      //int ti = cachedParameterMap[k].Item1;
+      //k = cachedParameterMap[k].Item2;
+      //return terms[ti].GetGradient(x, i, j, k);
+      return terms.Select(t => t.GetGradient(x, i, j)).Aggregate(Enumerable.Concat);
     }
+
+    public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {
+      return terms.Select(t => t.GetCrossCovariance(x, xt, i, j)).Sum();
+    }
+
     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);
-        }
-      }
-    }
+    //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);
+    //    }
+    //  }
+    //}
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 8484)
@@ -39,4 +39,14 @@
     public double NegativeLogLikelihood {
       get { return negativeLogLikelihood; }
+    }
+
+    [Storable]
+    private double[] hyperparameterGradients;
+    public double[] HyperparameterGradients {
+      get {
+        var copy = new double[hyperparameterGradients.Length];
+        Array.Copy(hyperparameterGradients, copy, copy.Length);
+        return copy;
+      }
     }
 
@@ -125,5 +135,4 @@
 
       meanFunction.SetData(x);
-      covarianceFunction.SetData(x);
 
       // calculate means and covariances
@@ -131,5 +140,5 @@
       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 +162,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 +188,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();
+
     }
 
@@ -219,40 +231,15 @@
       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 +253,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: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionModelCreator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionModelCreator.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionModelCreator.cs	(revision 8484)
@@ -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: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/ICovarianceFunction.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/ICovarianceFunction.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/ICovarianceFunction.cs	(revision 8484)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using HeuristicLab.Core;
 
@@ -26,9 +27,12 @@
     int GetNumberOfParameters(int numberOfVariables);
     void SetParameter(double[] hyp);
-    void SetData(double[,] x);
-    void SetData(double[,] x, double[,] xt);
+    double GetCovariance(double[,] x, int i, int j);
+    IEnumerable<double> GetGradient(double[,] x, int i, int j);
+    double GetCrossCovariance(double[,] x, double[,] xt, int i, int j);
+    //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(int i, int j);
+    //double GetGradient(int i, int j, int k);
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IGaussianProcessModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IGaussianProcessModel.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IGaussianProcessModel.cs	(revision 8484)
@@ -31,5 +31,5 @@
     IMeanFunction MeanFunction { get; }
     ICovarianceFunction CovarianceFunction { get; }
-    double[] GetHyperparameterGradients();
+    double[] HyperparameterGradients { get; }
 
     IEnumerable<double> GetEstimatedVariance(Dataset ds, IEnumerable<int> rows);
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessFunctionsTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessFunctionsTest.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessFunctionsTest.cs	(revision 8484)
@@ -904,5 +904,4 @@
       var hyp = Enumerable.Repeat(hypValue, nHyp).ToArray();
       cf.SetParameter(hyp);
-      cf.SetData(x, xt);
 
       int rows0 = x.GetLength(0);
@@ -911,5 +910,5 @@
       for (int i = 0; i < rows0; i++)
         for (int j = 0; j < rows1; j++)
-          actualCov[i, j] = cf.GetCovariance(i, j);
+          actualCov[i, j] = cf.GetCrossCovariance(x, xt, i, j);
 
       AssertEqual(expectedCov, actualCov, delta);
@@ -917,6 +916,7 @@
       for (int i = 0; i < rows0; i++)
         for (int j = 0; j < rows1; j++) {
+          var g = cf.GetGradient(x, i, j).ToArray();
           for (int k = 0; k < nHyp; k++)
-            Assert.AreEqual(expectedGradients[k][i, j], cf.GetGradient(i, j, k), delta);
+            Assert.AreEqual(expectedGradients[k][i, j], g[k], delta);
         }
     }
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessModelTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessModelTest.cs	(revision 8483)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab.Algorithms.DataAnalysis-3.4/GaussianProcessModelTest.cs	(revision 8484)
@@ -55,5 +55,5 @@
         Assert.AreEqual(4.3170e+004, model.NegativeLogLikelihood, 1);
 
-        var dHyp = model.GetHyperparameterGradients();
+        var dHyp = model.HyperparameterGradients;
         Assert.AreEqual(-248.7932, dHyp[0], 1E-2);
         var dHypCovExpected = new double[] { -0.5550e4, -5.5533e4, -0.2511e4, -2.7625e4, -1.3033e4, 0.0289e4, -2.7625e4 };
@@ -76,5 +76,5 @@
         Assert.AreEqual(872.8448, model.NegativeLogLikelihood, 1e-3);
 
-        var dHyp = model.GetHyperparameterGradients();
+        var dHyp = model.HyperparameterGradients;
         Assert.AreEqual(-0.0046, dHyp[0], 1e-3);
         var dHypCovExpected = new double[] { 0.2652, -0.2386, 0.1706, -0.1744, 0.0000, 0.0000, -0.1744 };
