Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/PolysplineKernel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/PolysplineKernel.cs	(revision 15163)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/PolysplineKernel.cs	(revision 15164)
@@ -57,5 +57,5 @@
 
     protected override double Get(double norm) {
-      if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null");
+      if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null");
       var beta = Beta.Value;
       if (Math.Abs(beta) < double.Epsilon) return double.NaN;
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/ThinPlatePolysplineKernel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/ThinPlatePolysplineKernel.cs	(revision 15163)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/ThinPlatePolysplineKernel.cs	(revision 15164)
@@ -66,5 +66,5 @@
     // (Degree/beta) * (norm/beta)^Degree * log(norm/beta) 
     protected override double GetGradient(double norm) {
-      if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null");
+      if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null");
       var beta = Beta.Value;
       if (Math.Abs(beta) < double.Epsilon) return double.NaN;
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs	(revision 15163)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs	(revision 15164)
@@ -123,5 +123,5 @@
 
     public static IRegressionSolution CreateRadialBasisRegressionSolution(IRegressionProblemData problemData, ICovarianceFunction kernel, double lambda, bool scaleInputs, out double rmsError, out double looCvRMSE) {
-      var model = new KernelRidgeRegressionModel(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel, lambda);
+      var model = KernelRidgeRegressionModel.Create(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel, lambda);
       rmsError = double.NaN;
       if (problemData.TestIndices.Any()) {
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs	(revision 15163)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs	(revision 15164)
@@ -39,5 +39,5 @@
     private readonly string[] allowedInputVariables;
     public string[] AllowedInputVariables {
-      get { return allowedInputVariables; }
+      get { return allowedInputVariables.ToArray(); }
     }
 
@@ -81,6 +81,5 @@
       yOffset = original.yOffset;
       yScale = original.yScale;
-      if (original.kernel != null)
-        kernel = cloner.Clone(original.kernel);
+      kernel = original.kernel;
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -88,34 +87,27 @@
     }
 
-    public KernelRidgeRegressionModel(IDataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, IEnumerable<int> rows,
-      bool scaleInputs, ICovarianceFunction kernel, double lambda = 0.1) : 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();
+    public static KernelRidgeRegressionModel Create(IDataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, IEnumerable<int> rows,
+      bool scaleInputs, ICovarianceFunction kernel, double lambda = 0.1) {
       var trainingRows = rows.ToArray();
-      this.kernel = (ICovarianceFunction)kernel.Clone();
-      this.lambda = lambda;
+      var model = new KernelRidgeRegressionModel(dataset, targetVariable, allowedInputVariables, trainingRows, scaleInputs, kernel, lambda);
+
       try {
-        if (scaleInputs)
-          scaling = CreateScaling(dataset, trainingRows);
-        trainX = ExtractData(dataset, trainingRows, scaling);
+        int info;
+        int n = model.trainX.GetLength(0);
+        alglib.densesolverreport denseSolveRep;
+        var gram = BuildGramMatrix(model.trainX, lambda, kernel);
+        var l = new double[n, n];
+        Array.Copy(gram, l, l.Length);
+
+        double[] alpha = new double[n];
+        double[,] invG;
         var y = dataset.GetDoubleValues(targetVariable, trainingRows).ToArray();
-        yOffset = y.Average();
-        yScale = 1.0 / y.StandardDeviation();
         for (int i = 0; i < y.Length; i++) {
-          y[i] -= yOffset;
-          y[i] *= yScale;
-        }
-        int info;
-        int n = trainX.GetLength(0);
-        alglib.densesolverreport denseSolveRep;
-        var gram = BuildGramMatrix(trainX, lambda);
-        var l = new double[n, n]; Array.Copy(gram, l, l.Length);
-
-        double[,] invG;
+          y[i] -= model.yOffset;
+          y[i] *= model.yScale;
+        }
         // cholesky decomposition
         var res = alglib.trfac.spdmatrixcholesky(ref l, n, false);
-        if (res == false) { //throw new ArgumentException("Could not decompose matrix. Is it quadratic symmetric positive definite?");
+        if (res == false) { //try lua decomposition if cholesky faild
           int[] pivots;
           var lua = new double[n, n];
@@ -127,5 +119,4 @@
           invG = lua;  // rename
           alglib.rmatrixluinverse(ref invG, pivots, n, out info, out rep);
-          if (info != 1) throw new ArgumentException("Could not invert Gram matrix.");
         } else {
           alglib.spdmatrixcholeskysolve(l, n, false, y, out info, out denseSolveRep, out alpha);
@@ -135,6 +126,6 @@
           invG = l;   // rename 
           alglib.spdmatrixcholeskyinverse(ref invG, n, false, out info, out rep);
-          if (info != 1) throw new ArgumentException("Could not invert Gram matrix.");
-        }
+        }
+        if (info != 1) throw new ArgumentException("Could not invert Gram matrix.");
 
         var ssqLooError = 0.0;
@@ -142,12 +133,32 @@
           var pred_i = Util.ScalarProd(Util.GetRow(gram, i).ToArray(), alpha);
           var looPred_i = pred_i - alpha[i] / invG[i, i];
-          var error = (y[i] - looPred_i) / yScale;
+          var error = (y[i] - looPred_i) / model.yScale;
           ssqLooError += error * error;
         }
-        LooCvRMSE = Math.Sqrt(ssqLooError / n);
+
+        Array.Copy(alpha, model.alpha, n);
+        model.LooCvRMSE = Math.Sqrt(ssqLooError / n);
       } 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 kernel ridge regression model", ae);
       }
+      return model;
+    }
+
+    private KernelRidgeRegressionModel(IDataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, int[] rows,
+      bool scaleInputs, ICovarianceFunction kernel, double lambda = 0.1) : base(targetVariable) {
+      this.allowedInputVariables = allowedInputVariables.ToArray();
+      if (kernel.GetNumberOfParameters(this.allowedInputVariables.Length) > 0) throw new ArgumentException("All parameters in the kernel function must be specified.");
+      name = ItemName;
+      description = ItemDescription;
+
+      this.kernel = (ICovarianceFunction)kernel.Clone();
+      this.lambda = lambda;
+      if (scaleInputs) scaling = CreateScaling(dataset, rows, this.allowedInputVariables);
+      trainX = ExtractData(dataset, rows, this.allowedInputVariables, scaling);
+      var y = dataset.GetDoubleValues(targetVariable, rows).ToArray();
+      yOffset = y.Average();
+      yScale = 1.0 / y.StandardDeviation();
+      alpha = new double[trainX.GetLength(0)];
     }
 
@@ -155,5 +166,5 @@
     #region IRegressionModel Members
     public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
-      var newX = ExtractData(dataset, rows, scaling);
+      var newX = ExtractData(dataset, rows, allowedInputVariables, scaling);
       var dim = newX.GetLength(1);
       var cov = kernel.GetParameterizedCovarianceFunction(new double[0], Enumerable.Range(0, dim).ToArray());
@@ -175,5 +186,5 @@
 
     #region helpers
-    private double[,] BuildGramMatrix(double[,] data, double lambda) {
+    private static double[,] BuildGramMatrix(double[,] data, double lambda, ICovarianceFunction kernel) {
       var n = data.GetLength(0);
       var dim = data.GetLength(1);
@@ -190,6 +201,6 @@
     }
 
-    private ITransformation<double>[] CreateScaling(IDataset dataset, int[] rows) {
-      var trans = new ITransformation<double>[allowedInputVariables.Length];
+    private static ITransformation<double>[] CreateScaling(IDataset dataset, int[] rows, IReadOnlyCollection<string> allowedInputVariables) {
+      var trans = new ITransformation<double>[allowedInputVariables.Count];
       int i = 0;
       foreach (var variable in allowedInputVariables) {
@@ -205,5 +216,5 @@
     }
 
-    private double[,] ExtractData(IDataset dataset, IEnumerable<int> rows, ITransformation<double>[] scaling = null) {
+    private static double[,] ExtractData(IDataset dataset, IEnumerable<int> rows, IReadOnlyCollection<string> allowedInputVariables, ITransformation<double>[] scaling = null) {
       double[][] variables;
       if (scaling != null) {
