Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/Distances/ManhattanDistance.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/Distances/ManhattanDistance.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/Distances/ManhattanDistance.cs	(revision 14884)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("ManhattanDistance", "A distance function that uses block distance")]
+  public class ManhattanDistance : DistanceBase<IEnumerable<double>> {
+
+    #region HLConstructors & Boilerplate
+    [StorableConstructor]
+    protected ManhattanDistance(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected ManhattanDistance(ManhattanDistance original, Cloner cloner)
+      : base(original, cloner) { }
+    public ManhattanDistance() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ManhattanDistance(this, cloner);
+    }
+    #endregion
+
+    public static double GetDistance(double[] point1, double[] point2) {
+      if (point1.Length != point2.Length) throw new ArgumentException("Manhattan distance not defined on vectors of different length");
+      return point1.Zip(point2, (a1, b1) => Math.Abs(a1 - b1)).Sum();
+    }
+
+    public static double GetDistance(IEnumerable<double> a, IEnumerable<double> b, double threshold) {
+      double sum = 0;
+      var it1 = a.GetEnumerator();
+      var it2 = b.GetEnumerator();
+      while (sum > threshold && it1.MoveNext() && it2.MoveNext()) {
+        sum += Math.Abs(it1.Current - it2.Current);
+      }
+      it1.Dispose();
+      it2.Dispose();
+      return sum;
+    }
+
+    public override double Get(IEnumerable<double> a, IEnumerable<double> b) {
+      return GetDistance(a.ToArray(), b.ToArray());
+    }
+
+    public override double Get(IEnumerable<double> a, IEnumerable<double> b, double threshold) {
+      return GetDistance(a, b, threshold);
+    }
+
+
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/CicularKernel.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/CicularKernel.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/CicularKernel.cs	(revision 14884)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("CircularKernel", "A circular kernel function")]
+  public class CircularKernel : KernelBase {
+
+    #region HLConstructors & Boilerplate
+    [StorableConstructor]
+    protected CircularKernel(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected CircularKernel(CircularKernel original, Cloner cloner) : base(original, cloner) { }
+    public CircularKernel() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The beta in the kernel function 2*pi*(acos(-d)-d*(1-n²)^(0.5)) where n = ||x-c|| and d = n/beta", new DoubleValue(2)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CircularKernel(this, cloner);
+    }
+    #endregion
+
+    protected override double Get(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      if (norm >= Beta) return 0;
+      var d = norm / Beta;
+      return Math.Acos(-d) - d * Math.Sqrt(1 - d * d) - Math.PI / 2;
+    }
+
+    protected override double GetGradient(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      if (Beta < norm) return 0;
+      return -2*Math.Pow(norm,3)/(Math.Pow(Beta,4)*Math.Sqrt(1-norm*norm/(Beta*Beta)));
+    }
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/GaussianKernel.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/GaussianKernel.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/GaussianKernel.cs	(revision 14884)
@@ -0,0 +1,58 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("GaussianKernel", "A kernel function that uses Gaussian function")]
+  public class GaussianKernel : KernelBase {
+
+    #region HLConstructors & Boilerplate
+    [StorableConstructor]
+    protected GaussianKernel(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected GaussianKernel(GaussianKernel original, Cloner cloner) : base(original, cloner) { }
+    public GaussianKernel() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The beta in the kernelfunction exp(-||x-c||/beta²)", new DoubleValue(2)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GaussianKernel(this, cloner);
+    }
+    #endregion
+
+    protected override double Get(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      return Math.Exp(-norm * norm / (Beta * Beta));
+    }
+
+    protected override double GetGradient(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      return 2 * norm * norm / Math.Pow(Beta, 3) * Math.Exp(-norm * norm / (Beta * Beta));
+    }
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/InverseMultiquadraticKernel.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/InverseMultiquadraticKernel.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/InverseMultiquadraticKernel.cs	(revision 14884)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("InverseMultiquadraticKernel", "A kernel function that uses the inverse multiquadratic function")]
+  public class InverseMultiquadraticKernel : KernelBase {
+    #region HLConstructors & Boilerplate
+    [StorableConstructor]
+    protected InverseMultiquadraticKernel(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected InverseMultiquadraticKernel(InverseMultiquadraticKernel original, Cloner cloner) : base(original, cloner) { }
+    public InverseMultiquadraticKernel() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The beta in the kernel function 1 / sqrt(1+||x-c||^2/beta)", new DoubleValue(2)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InverseMultiquadraticKernel(this, cloner);
+    }
+    #endregion
+
+    protected override double Get(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      return 1 / Math.Sqrt(1 + norm * norm / Beta);
+    }
+
+    protected override double GetGradient(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      return norm * norm / (2 * Beta * Beta * Math.Pow((norm * norm + Beta) / Beta, 1.5));
+    }
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/KernelBase.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/KernelBase.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/KernelBase.cs	(revision 14884)
@@ -0,0 +1,159 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  public abstract class KernelBase : ParameterizedNamedItem, ICovarianceFunction {
+
+    #region Parameternames
+    private const string DistanceParameterName = "Distance";
+    protected const string BetaParameterName = "Beta";
+    #endregion
+    #region Parameterproperties
+    public ValueParameter<IDistance> DistanceParameter {
+      get { return Parameters[DistanceParameterName] as ValueParameter<IDistance>; }
+    }
+
+    public IFixedValueParameter<DoubleValue> BetaParameter {
+      get { return Parameters[BetaParameterName] as FixedValueParameter<DoubleValue>; }
+    }
+
+    #endregion
+    #region Properties
+    public IDistance Distance {
+      get { return DistanceParameter.Value; }
+    }
+
+    public double Beta {
+      get { return BetaParameter.Value.Value; }
+    }
+
+    #endregion
+
+    [StorableConstructor]
+    protected KernelBase(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    protected KernelBase(KernelBase original, Cloner cloner)
+      : base(original, cloner) { }
+
+    protected KernelBase() {
+      Parameters.Add(new ValueParameter<IDistance>(DistanceParameterName, "The distance function used for kernel calculation"));
+      DistanceParameter.Value = new EuclideanDistance();
+    }
+
+    public double Get(object a, object b) {
+      return Get(Distance.Get(a, b));
+    }
+
+    protected abstract double Get(double norm);
+
+    public int GetNumberOfParameters(int numberOfVariables) {
+      return 1;
+    }
+
+    public void SetParameter(double[] p) {
+      if (p != null && p.Length == 1) BetaParameter.Value.Value = p[0];
+    }
+
+    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, int[] columnIndices) {
+      if (p == null || p.Length != 1) throw new ArgumentException("Illegal parametrization");
+      var myClone = (KernelBase)Clone(new Cloner());
+      myClone.BetaParameter.Value.Value = p[0];
+      var cov = new ParameterizedCovarianceFunction {
+        Covariance = (x, i, j) => myClone.Get(GetNorm(x, x, i, j, columnIndices)),
+        CrossCovariance = (x, xt, i, j) => myClone.Get(GetNorm(x, xt, i, j, columnIndices)),
+        CovarianceGradient = (x, i, j) => new List<double> { myClone.GetGradient(GetNorm(x, x, i, j, columnIndices)) }
+      };
+      return cov;
+    }
+
+    protected abstract double GetGradient(double norm);
+
+    protected double GetNorm(double[,] x, double[,] xt, int i, int j, int[] columnIndices) {
+      var dist = Distance as IDistance<IEnumerable<double>>;
+      if (dist == null) throw new ArgumentException("The distance needs to apply to double vectors");
+      var r1 = new IndexedEnumerable(x, i, columnIndices);
+      var r2 = new IndexedEnumerable(xt, j, columnIndices);
+      return dist.Get(r1, r2);
+    }
+    internal class IndexedEnumerable : IEnumerable<double> {
+      private readonly double[,] data;
+      private readonly int row;
+      private readonly int[] columnIndices;
+
+      public IndexedEnumerable(double[,] data, int row, int[] columnIndices) {
+        this.data = data;
+        this.row = row;
+        this.columnIndices = columnIndices;
+      }
+
+      public IEnumerator<double> GetEnumerator() {
+        return new IndexedEnumerator(data, row, columnIndices);
+      }
+
+      IEnumerator IEnumerable.GetEnumerator() {
+        return new IndexedEnumerator(data, row, columnIndices);
+      }
+    }
+    internal class IndexedEnumerator : IEnumerator<double> {
+      private readonly IEnumerator<int> column;
+      private readonly double[,] data;
+      private readonly int row;
+
+      public IndexedEnumerator(double[,] data, int row, int[] columnIndices) {
+        this.data = data;
+        this.row = row;
+        column = ((IEnumerable<int>)columnIndices).GetEnumerator();
+      }
+
+      public double Current {
+        get { return data[row, column.Current]; }
+      }
+
+      object IEnumerator.Current {
+        get {
+          return data[row, column.Current];
+        }
+      }
+
+      public void Dispose() { }
+
+      public bool MoveNext() {
+        return column.MoveNext();
+      }
+
+      public void Reset() {
+        column.Reset();
+      }
+    }
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/LaplacianKernel.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/LaplacianKernel.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/LaplacianKernel.cs	(revision 14884)
@@ -0,0 +1,55 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("LaplacianKernel", "A kernel function that uses an exponential function.\nIt is equvalent to the Gaussian kernel but less susceptible to improper values of beta")]
+  public class LaplacianKernel : KernelBase {
+    [StorableConstructor]
+    protected LaplacianKernel(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected LaplacianKernel(LaplacianKernel original, Cloner cloner) : base(original, cloner) { }
+    public LaplacianKernel() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The beta in the kernel function exp(-||x-c||/beta)", new DoubleValue(2)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LaplacianKernel(this, cloner);
+    }
+
+    protected override double Get(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      return Math.Exp(-norm / Beta);
+    }
+
+    protected override double GetGradient(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      return norm * Math.Exp(-norm / Beta) / (Beta * Beta);
+    }
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/MultiquadraticKernel.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/MultiquadraticKernel.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/MultiquadraticKernel.cs	(revision 14884)
@@ -0,0 +1,60 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("MultiquadraticKernel", "A kernel function that uses the multiquadratic function")]
+  public class MultiquadraticKernel : KernelBase {
+
+    #region HLConstructors & Boilerplate
+    [StorableConstructor]
+    protected MultiquadraticKernel(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected MultiquadraticKernel(MultiquadraticKernel original, Cloner cloner)
+                : base(original, cloner) { }
+
+    public MultiquadraticKernel() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The beta in the kernel function sqrt(1+||x-c||²/beta)", new DoubleValue(2)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiquadraticKernel(this, cloner);
+    }
+    #endregion
+    protected override double Get(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      return Math.Sqrt(1 + norm * norm / Beta);
+    }
+
+    protected override double GetGradient(double norm) {
+      if (Math.Abs(Beta) < double.Epsilon) return double.NaN;
+      var dividend = 2 * Beta * Beta * Math.Sqrt((Beta + norm * norm) / Beta);
+      return -norm * norm / dividend;
+    }
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/PolysplineKernel.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/PolysplineKernel.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/PolysplineKernel.cs	(revision 14884)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("PolysplineKernel", "A kernel function that uses the multiquadratic function")]
+  public class PolysplineKernel : KernelBase {
+
+    #region HLConstructors & Boilerplate
+    [StorableConstructor]
+    protected PolysplineKernel(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected PolysplineKernel(PolysplineKernel original, Cloner cloner)
+                : base(original, cloner) { }
+    public PolysplineKernel() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The Beta in the kernelfunction ||x-c||^Beta", new DoubleValue(1.5)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PolysplineKernel(this, cloner);
+    }
+    #endregion
+
+    protected override double Get(double norm) {
+      return Math.Pow(norm, Beta);
+    }
+
+    protected override double GetGradient(double norm) {
+      return Math.Pow(norm, Beta) * Math.Log(norm);
+    }
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/ThinPlatePolysplineKernel.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/ThinPlatePolysplineKernel.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/ThinPlatePolysplineKernel.cs	(revision 14884)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("ThinPlatePolysplineKernel", "A kernel function that uses the ThinPlatePolyspline function")]
+  public class ThinPlatePolysplineKernel : KernelBase {
+    #region HLConstructors & Boilerplate
+    [StorableConstructor]
+    protected ThinPlatePolysplineKernel(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected ThinPlatePolysplineKernel(ThinPlatePolysplineKernel original, Cloner cloner) : base(original, cloner) { }
+    public ThinPlatePolysplineKernel() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The Beta in the kernelfunction ||x-c||^(2*Beta)*log(||x-c||^Beta)", new DoubleValue(1)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ThinPlatePolysplineKernel(this, cloner);
+    }
+    #endregion
+
+    protected override double Get(double norm) {
+      if (Math.Pow(norm, Beta) <= 0) return double.NaN;
+      return Math.Pow(norm, 2 * Beta) * Math.Log(1 + Math.Pow(norm, Beta));
+    }
+
+    protected override double GetGradient(double norm) {
+      if (Math.Pow(norm, Beta) <= 0) return double.NaN;
+      return 2 * Math.Log(norm) * Math.Pow(norm, 2 * Beta) * Math.Log(1 + Math.Pow(norm, Beta)) + Math.Pow(norm, 3 * Beta) * Math.Log(norm) / (Math.Pow(norm, Beta) + 1);
+    }
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/RadialBasisFunctionModel.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/RadialBasisFunctionModel.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/RadialBasisFunctionModel.cs	(revision 14884)
@@ -0,0 +1,238 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  /// <summary>
+  /// Represents an RBF regression model.
+  /// </summary>
+  [StorableClass]
+  [Item("RBFModel", "An RBF regression model")]
+  public sealed class RadialBasisFunctionModel : RegressionModel, IConfidenceRegressionModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
+    }
+
+    [Storable]
+    private readonly string[] allowedInputVariables;
+    public string[] AllowedInputVariables {
+      get { return allowedInputVariables; }
+    }
+
+    [Storable]
+    private readonly double[] alpha;
+
+    [Storable]
+    private readonly double[,] trainX; // it is better to store the original training dataset completely because this is more efficient in persistence
+
+    [Storable]
+    private readonly ITransformation<double>[] scaling;
+
+    [Storable]
+    private readonly ICovarianceFunction kernel;
+
+    private double[,] gramInvert; // not storable as it can be large (recreate after deserialization as required)
+
+    [Storable]
+    private readonly double meanOffset; // implementation works for zero-mean target variables
+
+    [StorableConstructor]
+    private RadialBasisFunctionModel(bool deserializing) : base(deserializing) { }
+    private RadialBasisFunctionModel(RadialBasisFunctionModel original, Cloner cloner)
+      : base(original, cloner) {
+      // shallow copies of arrays because they cannot be modified
+      allowedInputVariables = original.allowedInputVariables;
+      alpha = original.alpha;
+      trainX = original.trainX;
+      gramInvert = original.gramInvert;
+      scaling = original.scaling;
+
+      meanOffset = original.meanOffset;
+      if (original.kernel != null)
+        kernel = cloner.Clone(original.kernel);
+    }
+    public RadialBasisFunctionModel(IDataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, IEnumerable<int> rows,
+      bool scaleInputs, ICovarianceFunction kernel)
+      : base(targetVariable) {
+      if (kernel.GetNumberOfParameters(allowedInputVariables.Count()) > 0) throw new ArgumentException("All parameters in the kernel function must be specified.");
+      name = ItemName;
+      description = ItemDescription;
+      this.allowedInputVariables = allowedInputVariables.ToArray();
+      var trainingRows = rows.ToArray();
+      this.kernel = (ICovarianceFunction)kernel.Clone();
+      try {
+        if (scaleInputs)
+          scaling = CreateScaling(dataset, trainingRows);
+        trainX = ExtractData(dataset, trainingRows, scaling);
+        var y = dataset.GetDoubleValues(targetVariable, trainingRows).ToArray();
+        meanOffset = y.Average();
+        for (int i = 0; i < y.Length; i++) y[i] -= meanOffset;
+        int info;
+        // TODO: improve efficiency by decomposing matrix once instead of solving the system and then inverting the matrix
+        alglib.densesolverlsreport denseSolveRep;
+        gramInvert = BuildGramMatrix(trainX);
+        int n = trainX.GetLength(0);
+        alglib.rmatrixsolvels(gramInvert, n, n, y, 0.0, out info, out denseSolveRep, out alpha);
+        if (info != 1) throw new ArgumentException("Could not create model.");
+
+        alglib.matinvreport report;
+        alglib.rmatrixinverse(ref gramInvert, out info, out report);
+        if (info != 1) throw new ArgumentException("Could not invert matrix. Is it quadratic symmetric positive definite?");
+
+      } catch (alglib.alglibexception ae) {
+        // wrap exception so that calling code doesn't have to know about alglib implementation
+        throw new ArgumentException("There was a problem in the calculation of the RBF model", ae);
+      }
+    }
+
+    private ITransformation<double>[] CreateScaling(IDataset dataset, int[] rows) {
+      var trans = new ITransformation<double>[allowedInputVariables.Length];
+      int i = 0;
+      foreach (var variable in allowedInputVariables) {
+        var lin = new LinearTransformation(allowedInputVariables);
+        var max = dataset.GetDoubleValues(variable, rows).Max();
+        var min = dataset.GetDoubleValues(variable, rows).Min();
+        lin.Multiplier = 1.0 / (max - min);
+        lin.Addend = -min / (max - min);
+        trans[i] = lin;
+        i++;
+      }
+      return trans;
+    }
+
+    private double[,] ExtractData(IDataset dataset, IEnumerable<int> rows, ITransformation<double>[] scaling = null) {
+      double[][] variables;
+      if (scaling != null) {
+        variables =
+          allowedInputVariables.Select((var, i) => scaling[i].Apply(dataset.GetDoubleValues(var, rows)).ToArray())
+            .ToArray();
+      } else {
+        variables =
+        allowedInputVariables.Select(var => dataset.GetDoubleValues(var, rows).ToArray()).ToArray();
+      }
+      int n = variables.First().Length;
+      var res = new double[n, variables.Length];
+      for (int r = 0; r < n; r++)
+        for (int c = 0; c < variables.Length; c++) {
+          res[r, c] = variables[c][r];
+        }
+      return res;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RadialBasisFunctionModel(this, cloner);
+    }
+
+    #region IRegressionModel Members
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      var newX = ExtractData(dataset, rows, scaling);
+      var dim = newX.GetLength(1);
+      var cov = kernel.GetParameterizedCovarianceFunction(new double[0], Enumerable.Range(0, dim).ToArray());
+
+      var pred = new double[newX.GetLength(0)];
+      for (int i = 0; i < pred.Length; i++) {
+        double sum = meanOffset;
+        for (int j = 0; j < alpha.Length; j++) {
+          sum += alpha[j] * cov.CrossCovariance(trainX, newX, j, i);
+        }
+        pred[i] = sum;
+      }
+      return pred;
+    }
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new ConfidenceRegressionSolution(this, new RegressionProblemData(problemData));
+    }
+    #endregion
+
+    public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
+      if (gramInvert == null) CreateAndInvertGramMatrix();
+      int n = gramInvert.GetLength(0);
+      var newData = ExtractData(dataset, rows, scaling);
+      var dim = newData.GetLength(1);
+      var cov = kernel.GetParameterizedCovarianceFunction(new double[0], Enumerable.Range(0, dim).ToArray());
+
+      // TODO perf (matrix matrix multiplication)
+      for (int i = 0; i < newData.GetLength(0); i++) {
+        double[] p = new double[n];
+
+        for (int j = 0; j < trainX.GetLength(0); j++) {
+          p[j] = cov.CrossCovariance(trainX, newData, j, i);
+        }
+
+        var Ap = new double[n];
+        alglib.ablas.rmatrixmv(n, n, gramInvert, 0, 0, 0, p, 0, ref Ap, 0);
+        var res = 0.0;
+        // dot product
+        for (int j = 0; j < p.Length; j++) res += p[j] * Ap[j];
+        yield return res > 0 ? res : 0;
+      }
+    }
+    public double LeaveOneOutCrossValidationRootMeanSquaredError() {
+      if (gramInvert == null) CreateAndInvertGramMatrix();
+      var n = gramInvert.GetLength(0);
+      var s = 1.0 / n;
+
+      var sum = 0.0;
+      for (int i = 0; i < alpha.Length; i++) {
+        var x = alpha[i] / gramInvert[i, i];
+        sum += x * x;
+      }
+      sum *= s;
+      return Math.Sqrt(sum);
+    }
+
+    private void CreateAndInvertGramMatrix() {
+      try {
+        gramInvert = BuildGramMatrix(trainX);
+        int info = 0;
+        alglib.matinvreport report;
+        alglib.rmatrixinverse(ref gramInvert, out info, out report);
+        if (info != 1)
+          throw new ArgumentException("Could not invert matrix. Is it quadratic symmetric positive definite?");
+      } catch (alglib.alglibexception) {
+        // wrap exception so that calling code doesn't have to know about alglib implementation
+        throw new ArgumentException("Could not invert matrix. Is it quadratic symmetric positive definite?");
+      }
+    }
+    #region helpers
+    private double[,] BuildGramMatrix(double[,] data) {
+      var n = data.GetLength(0);
+      var dim = data.GetLength(1);
+      var cov = kernel.GetParameterizedCovarianceFunction(new double[0], Enumerable.Range(0, dim).ToArray());
+      var gram = new double[n, n];
+      for (var i = 0; i < n; i++)
+        for (var j = i; j < n; j++) {
+          gram[j, i] = gram[i, j] = cov.Covariance(data, i, j); // symmetric matrix --> half of the work
+        }
+      return gram;
+    }
+
+    #endregion
+  }
+}
Index: /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/RadialBasisRegression.cs
===================================================================
--- /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/RadialBasisRegression.cs	(revision 14884)
+++ /branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/RadialBasisRegression.cs	(revision 14884)
@@ -0,0 +1,120 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  /// <summary>
+  /// Linear regression data analysis algorithm.
+  /// </summary>
+  [Item("Radial Basis Function Regression (RBF-R)", "Radial basis function regression data analysis algorithm.")]
+  [Creatable(CreatableAttribute.Categories.DataAnalysisRegression, Priority = 100)]
+  [StorableClass]
+  public sealed class RadialBasisRegression : BasicAlgorithm {
+    private const string RBFRegressionSolutionResultName = "RBF regression solution";
+
+    public override bool SupportsPause {
+      get { return false; }
+    }
+    public override Type ProblemType {
+      get { return typeof(IRegressionProblem); }
+    }
+    public new IRegressionProblem Problem {
+      get { return (IRegressionProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    #region parameter names
+    private const string KernelParameterName = "Kernel";
+    private const string ScaleInputVariablesParameterName = "ScaleInputVariables";
+    #endregion
+
+    #region parameter properties
+    public ValueParameter<ICovarianceFunction> KernelParameter {
+      get { return (ValueParameter<ICovarianceFunction>)Parameters[KernelParameterName]; }
+    }
+
+    public IFixedValueParameter<BoolValue> ScaleInputVariablesParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[ScaleInputVariablesParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public ICovarianceFunction Kernel {
+      get { return KernelParameter.Value; }
+    }
+
+    public bool ScaleInputVariables {
+      get { return ScaleInputVariablesParameter.Value.Value; }
+      set { ScaleInputVariablesParameter.Value.Value = value; }
+    }
+
+    #endregion
+
+    [StorableConstructor]
+    private RadialBasisRegression(bool deserializing) : base(deserializing) { }
+    private RadialBasisRegression(RadialBasisRegression original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public RadialBasisRegression() {
+      Problem = new RegressionProblem();
+      Parameters.Add(new ValueParameter<ICovarianceFunction>(KernelParameterName, "The radial basis function"));
+      Parameters.Add(new FixedValueParameter<BoolValue>(ScaleInputVariablesParameterName, "Set to true if the input variables should be scaled to the interval [0..1]", new BoolValue(true)));
+      var kernel = new GaussianKernel();
+      KernelParameter.Value = kernel;
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RadialBasisRegression(this, cloner);
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      double loocvrmse, rmsError;
+      var solution = CreateRadialBasisRegressionSolution(Problem.ProblemData, Kernel, ScaleInputVariables, out loocvrmse, out rmsError);
+      Results.Add(new Result(RBFRegressionSolutionResultName, "The RBF regression solution.", solution));
+      Results.Add(new Result("LOOCVRMSE", "The root mean squared error of a leave-one-out-cross-validation on the training set", new DoubleValue(loocvrmse)));
+      Results.Add(new Result("RMSE (test)", "The root mean squared error of the solution on the test set.", new DoubleValue(rmsError)));
+    }
+
+    public static IRegressionSolution CreateRadialBasisRegressionSolution(IRegressionProblemData problemData, ICovarianceFunction kernel, bool scaleInputs, out double loocvRmsError, out double rmsError) {
+      var model = new RadialBasisFunctionModel(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel);
+      loocvRmsError = model.LeaveOneOutCrossValidationRootMeanSquaredError();
+      rmsError = Math.Sqrt(model.GetEstimatedValues(problemData.Dataset, problemData.TestIndices)
+        .Zip(problemData.TargetVariableTestValues, (a, b) => (a - b) * (a - b))
+        .Average());
+      var solution = model.CreateRegressionSolution((IRegressionProblemData)problemData.Clone());
+      solution.Model.Name = "RBF Regression Model";
+      solution.Name = "RBF Regression Solution";
+      return solution;
+    }
+  }
+}
