Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/FixedDataAnalysisAlgorithm.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/FixedDataAnalysisAlgorithm.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/FixedDataAnalysisAlgorithm.cs	(revision 15470)
@@ -28,5 +28,5 @@
 namespace HeuristicLab.Algorithms.DataAnalysis {
   [StorableClass]
-  public abstract class FixedDataAnalysisAlgorithm<T> : BasicAlgorithm where T : class, IDataAnalysisProblem {
+  public abstract class FixedDataAnalysisAlgorithm<T> : BasicAlgorithm, IDataAnalysisAlgorithm<T> where T : class, IDataAnalysisProblem {
     #region Properties
     public override Type ProblemType {
@@ -34,10 +34,12 @@
     }
     public new T Problem {
-      get { return (T)base.Problem; }
+      get { return (T) base.Problem; }
       set { base.Problem = value; }
     }
     #endregion
 
-    public override bool SupportsPause { get { return false; } }
+    public override bool SupportsPause {
+      get { return false; }
+    }
 
     [StorableConstructor]
@@ -45,5 +47,4 @@
     protected FixedDataAnalysisAlgorithm(FixedDataAnalysisAlgorithm<T> original, Cloner cloner) : base(original, cloner) { }
     public FixedDataAnalysisAlgorithm() : base() { }
-
   }
 }
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 15470)
@@ -361,6 +361,5 @@
     <Compile Include="Linear\MultinomialLogitModel.cs" />
     <Compile Include="Linear\Scaling.cs" />
-    <Compile Include="M5Regression\Interfaces\IImpurityCalculator.cs" />
-    <Compile Include="M5Regression\Interfaces\IImpurityType.cs" />
+    <Compile Include="M5Regression\Interfaces\ISplitType.cs" />
     <Compile Include="M5Regression\Interfaces\IM5MetaModel.cs" />
     <Compile Include="M5Regression\Interfaces\ILeafType.cs" />
@@ -377,5 +376,4 @@
     <Compile Include="M5Regression\M5Utilities\M5CreationParameters.cs" />
     <Compile Include="M5Regression\M5Utilities\M5UpdateParameters.cs" />
-    <Compile Include="M5Regression\M5Utilities\SplitInfo.cs" />
     <Compile Include="M5Regression\MetaModels\ComponentReducedLinearModel.cs" />
     <Compile Include="M5Regression\MetaModels\M5NodeModel.cs" />
@@ -392,5 +390,5 @@
     <Compile Include="M5Regression\Pruning\M5LeafPruning.cs" />
     <Compile Include="M5Regression\Spliting\OrderImpurityCalculator.cs" />
-    <Compile Include="M5Regression\Spliting\OrderImpurityType.cs" />
+    <Compile Include="M5Regression\Spliting\OrderSplitType.cs" />
     <Compile Include="Nca\Initialization\INcaInitializer.cs" />
     <Compile Include="Nca\Initialization\LdaInitializer.cs" />
@@ -423,6 +421,5 @@
     <Compile Include="NeuralNetwork\NeuralNetworkRegressionSolution.cs" />
     <Compile Include="NonlinearRegression\NonlinearRegression.cs" />
-    <Compile Include="PCA\PrincipleComponentAnalysis.cs" />
-    <Compile Include="PCA\PrincipleComponentAnalysisStatic.cs" />
+    <Compile Include="M5Regression\M5Utilities\PrincipleComponentTransformation.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: anches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityCalculator.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityCalculator.cs	(revision 15469)
+++ 	(revision )
@@ -1,30 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-namespace HeuristicLab.Algorithms.DataAnalysis {
-  public interface IImpurityCalculator {
-    double Impurity { get; }
-    void Increment(double value, IncrementType type);
-  }
-  public enum IncrementType {
-    Left, Right, None
-  }
-}
Index: anches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityType.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityType.cs	(revision 15469)
+++ 	(revision )
@@ -1,28 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-using System.Collections.Generic;
-using HeuristicLab.Core;
-
-namespace HeuristicLab.Algorithms.DataAnalysis {
-  public interface IImpurityType : IParameterizedNamedItem {
-    IImpurityCalculator GenerateCalculator(int partition, IReadOnlyCollection<double> data);
-  }
-}
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/ISplitType.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/ISplitType.cs	(revision 15470)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/ISplitType.cs	(revision 15470)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  public interface ISplitType : IParameterizedNamedItem {
+    /// <summary>
+    /// decides wether a node sould be split
+    /// and if so at which attribute and which value
+    /// </summary>
+    /// <param name="splitData"></param>
+    /// <param name="minLeafSize"></param>
+    /// <param name="splitAttr"></param>
+    /// <param name="splitValue"></param>
+    /// <returns></returns>
+    bool Split(IRegressionProblemData splitData, int minLeafSize, out string splitAttr, out double splitValue);
+  }
+}
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComponentReductionLinearLeaf.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComponentReductionLinearLeaf.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComponentReductionLinearLeaf.cs	(revision 15470)
@@ -58,6 +58,6 @@
     public IConfidenceRegressionModel BuildModel(IRegressionProblemData pd, IRandom random,
       CancellationToken cancellation, out int noParameters) {
-      var pca = PrincipleComponentAnalysisStatic.Create(pd.Dataset, pd.TrainingIndices, pd.AllowedInputVariables, true);
-      var pcdata = pca.ProjectProblem(pd);
+      var pca = PrincipleComponentTransformation.CreateProjection(pd.Dataset, pd.TrainingIndices, pd.AllowedInputVariables, true);
+      var pcdata = pca.TransformProblemData(pd);
       ComponentReducedLinearModel bestModel = null;
       var bestCvrmse = double.MaxValue;
@@ -65,5 +65,5 @@
       for (var i = 1; i <= Math.Min(NoComponents, pd.AllowedInputVariables.Count()); i++) {
         var pd2 = (IRegressionProblemData) pcdata.Clone();
-        var inputs = new HashSet<string>(pca.Names.Take(i));
+        var inputs = new HashSet<string>(pca.ComponentNames.Take(i));
         foreach (var v in pd2.InputVariables.CheckedItems.ToArray())
           pd2.InputVariables.SetItemCheckedState(v.Value, inputs.Contains(v.Value.Value));
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Regression.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Regression.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Regression.cs	(revision 15470)
@@ -20,5 +20,5 @@
     #region Parametername
     private const string GenerateRulesParameterName = "GenerateRules";
-    private const string ImpurityParameterName = "Impurity";
+    private const string ImpurityParameterName = "Split";
     private const string MinimalNodeSizeParameterName = "MinimalNodeSize";
     private const string ModelTypeParameterName = "ModelType";
@@ -32,6 +32,6 @@
       get { return Parameters[GenerateRulesParameterName] as IFixedValueParameter<BoolValue>; }
     }
-    public IConstrainedValueParameter<IImpurityType> ImpurityParameter {
-      get { return Parameters[ImpurityParameterName] as IConstrainedValueParameter<IImpurityType>; }
+    public IConstrainedValueParameter<ISplitType> ImpurityParameter {
+      get { return Parameters[ImpurityParameterName] as IConstrainedValueParameter<ISplitType>; }
     }
     public IFixedValueParameter<IntValue> MinimalNodeSizeParameter {
@@ -56,5 +56,5 @@
       get { return GenerateRulesParameter.Value.Value; }
     }
-    public IImpurityType Impurity {
+    public ISplitType Split {
       get { return ImpurityParameter.Value; }
     }
@@ -83,7 +83,7 @@
       var modelSet = new ItemSet<ILeafType<IRegressionModel>>(ApplicationManager.Manager.GetInstances<ILeafType<IRegressionModel>>());
       var pruningSet = new ItemSet<IPruningType>(ApplicationManager.Manager.GetInstances<IPruningType>());
-      var impuritySet = new ItemSet<IImpurityType>(ApplicationManager.Manager.GetInstances<IImpurityType>());
+      var impuritySet = new ItemSet<ISplitType>(ApplicationManager.Manager.GetInstances<ISplitType>());
       Parameters.Add(new FixedValueParameter<BoolValue>(GenerateRulesParameterName, "Whether a set of rules or a decision tree shall be created", new BoolValue(true)));
-      Parameters.Add(new ConstrainedValueParameter<IImpurityType>(ImpurityParameterName, "The type of impurity function used to create node splits", impuritySet, impuritySet.OfType<OrderImpurityType>().First()));
+      Parameters.Add(new ConstrainedValueParameter<ISplitType>(ImpurityParameterName, "The type of split function used to create node splits", impuritySet, impuritySet.OfType<OrderSplitType>().First()));
       Parameters.Add(new FixedValueParameter<IntValue>(MinimalNodeSizeParameterName, "The minimal number of samples in a leaf node", new IntValue(1)));
       Parameters.Add(new ConstrainedValueParameter<ILeafType<IRegressionModel>>(ModelTypeParameterName, "The type of model used for the nodes", modelSet, modelSet.OfType<LinearLeaf>().First()));
@@ -102,5 +102,5 @@
       if (SetSeedRandomly) SeedParameter.Value.Value = new System.Random().Next();
       random.Reset(Seed);
-      var solution = CreateM5RegressionSolution(Problem.ProblemData, random, LeafType, Impurity, PruningType, cancellationToken, MinimalNodeSize, GenerateRules, Results);
+      var solution = CreateM5RegressionSolution(Problem.ProblemData, random, LeafType, Split, PruningType, cancellationToken, MinimalNodeSize, GenerateRules, Results);
       AnalyzeSolution(solution);
     }
@@ -108,9 +108,9 @@
     #region Static Interface
     public static IRegressionSolution CreateM5RegressionSolution(IRegressionProblemData problemData, IRandom random,
-      ILeafType<IRegressionModel> leafType = null, IImpurityType impurityType = null, IPruningType pruningType = null,
+      ILeafType<IRegressionModel> leafType = null, ISplitType splitType = null, IPruningType pruningType = null,
       CancellationToken? cancellationToken = null, int minNumInstances = 4, bool generateRules = false, ResultCollection results = null) {
       //set default values
       if (leafType == null) leafType = new LinearLeaf();
-      if (impurityType == null) impurityType = new OrderImpurityType();
+      if (splitType == null) splitType = new OrderSplitType();
       if (cancellationToken == null) cancellationToken = CancellationToken.None;
       if (pruningType == null) pruningType = new M5LeafPruning();
@@ -130,5 +130,5 @@
 
       //create & build Model
-      var m5Params = new M5CreationParameters(pruningType, minNumInstances, leafType, pd, random, impurityType, results);
+      var m5Params = new M5CreationParameters(pruningType, minNumInstances, leafType, pd, random, splitType, results);
 
       IReadOnlyList<int> t, h;
@@ -148,17 +148,17 @@
 
     public static void UpdateM5Model(M5TreeModel model, IRegressionProblemData problemData, IRandom random,
-      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null, ResultCollection results = null) {
-      UpdateM5Model(model as IM5MetaModel, problemData, random, leafType, cancellationToken, results);
+      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null) {
+      UpdateM5Model(model as IM5MetaModel, problemData, random, leafType, cancellationToken);
     }
 
     public static void UpdateM5Model(M5RuleSetModel model, IRegressionProblemData problemData, IRandom random,
-      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null, ResultCollection results = null) {
-      UpdateM5Model(model as IM5MetaModel, problemData, random, leafType, cancellationToken, results);
+      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null) {
+      UpdateM5Model(model as IM5MetaModel, problemData, random, leafType, cancellationToken);
     }
 
     private static void UpdateM5Model(IM5MetaModel model, IRegressionProblemData problemData, IRandom random,
-      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null, ResultCollection results = null) {
+      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null) {
       if (cancellationToken == null) cancellationToken = CancellationToken.None;
-      var m5Params = new M5UpdateParameters(leafType, problemData, random, results);
+      var m5Params = new M5UpdateParameters(leafType, problemData, random);
       model.UpdateModel(problemData.TrainingIndices.ToList(), m5Params, cancellationToken.Value);
     }
@@ -175,5 +175,5 @@
       }
       else {
-        Results.Add(M5Analyzer.CreateRulesResult((M5RuleSetModel) solution.Model, Problem.ProblemData, "M5TreeResult", 0, true));
+        Results.Add(M5Analyzer.CreateRulesResult((M5RuleSetModel) solution.Model, Problem.ProblemData, "M5TreeResult", true));
         frequencies = M5Analyzer.GetRuleVariableFrequences((M5RuleSetModel) solution.Model);
         Results.Add(M5Analyzer.CreateCoverageDiagram((M5RuleSetModel) solution.Model, Problem.ProblemData));
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5Analyzer.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5Analyzer.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5Analyzer.cs	(revision 15470)
@@ -29,11 +29,7 @@
 namespace HeuristicLab.Algorithms.DataAnalysis {
   internal static class M5Analyzer {
-    private const string LeftResultName = "Left";
-    private const string RightResultName = "Right";
     private const string ConditionResultName = "Condition";
     private const string CoverResultName = "Covered Instances";
     private const string CoverageDiagramResultName = "Coverage";
-    private const string NodeModelResultName = "NodeModel";
-    private const string NodeSizeResultName = "NodeSize";
     private const string RuleModelResultName = "RuleModel";
 
@@ -41,6 +37,6 @@
       var res = ruleSetModel.VariablesUsedForPrediction.ToDictionary(x => x, x => 0);
       foreach (var rule in ruleSetModel.Rules)
-        foreach (var att in rule.SplitAtts)
-          res[att]++;
+      foreach (var att in rule.SplitAtts)
+        res[att]++;
       return res;
     }
@@ -57,6 +53,6 @@
       var list = new List<int>();
       GetLeafDepths(treeModel.Root, 0, list);
-      var row = new DataRow("Depths", "", list.Select(x => (double)x)) {
-        VisualProperties = { ChartType = DataRowVisualProperties.DataRowChartType.Histogram }
+      var row = new DataRow("Depths", "", list.Select(x => (double) x)) {
+        VisualProperties = {ChartType = DataRowVisualProperties.DataRowChartType.Histogram}
       };
       var hist = new DataTable("LeafDepths");
@@ -65,9 +61,9 @@
     }
 
-    public static Result CreateRulesResult(M5RuleSetModel ruleSetModel, IRegressionProblemData pd, string resultName, int maxDepth, bool displayModels) {
+    public static Result CreateRulesResult(M5RuleSetModel ruleSetModel, IRegressionProblemData pd, string resultName, bool displayModels) {
       var res = new ResultCollection();
       var i = 0;
       foreach (var rule in ruleSetModel.Rules)
-        res.Add(new Result("Rule" + i++, CreateRulesResult(rule, pd, maxDepth, displayModels, out pd)));
+        res.Add(new Result("Rule" + i++, CreateRulesResult(rule, pd, displayModels, out pd)));
       return new Result(resultName, res);
     }
@@ -101,21 +97,5 @@
     }
 
-    private static ResultCollection CreateRulesResult(M5NodeModel nodeModel, IRegressionProblemData pd, IList<int> rows, int maxDepth, bool displayModels) {
-      var res = new ResultCollection();
-      if (!nodeModel.IsLeaf) {
-        res.Add(new Result(ConditionResultName, new StringValue(nodeModel.SplitAttr + " <= " + nodeModel.SplitValue)));
-        var assignment = pd.Dataset.GetDoubleValues(nodeModel.SplitAttr, rows).Select(x => x <= nodeModel.SplitValue).ToArray();
-        var leftRows = Enumerable.Range(0, assignment.Length).Where(i => assignment[i]).Select(i => rows[i]).ToList();
-        var rightRows = Enumerable.Range(0, assignment.Length).Where(i => !assignment[i]).Select(i => rows[i]).ToList();
-        if (nodeModel.Left != null && maxDepth > 0) res.Add(new Result(LeftResultName, CreateRulesResult(nodeModel.Left, pd, leftRows, maxDepth - 1, displayModels)));
-        if (nodeModel.Right != null && maxDepth > 0) res.Add(new Result(RightResultName, CreateRulesResult(nodeModel.Right, pd, rightRows, maxDepth - 1, displayModels)));
-      }
-      if (nodeModel.NodeModel != null && displayModels) res.Add(new Result(NodeModelResultName, nodeModel.NodeModel.CreateRegressionSolution(pd)));
-      res.Add(new Result(NodeSizeResultName, new IntValue(rows.Count)));
-      return res;
-    }
-
-    private static ResultCollection CreateRulesResult(M5RuleModel m5RuleModel, IRegressionProblemData pd, int maxDepth, bool displayModels, out IRegressionProblemData notCovered) {
-
+    private static ResultCollection CreateRulesResult(M5RuleModel m5RuleModel, IRegressionProblemData pd, bool displayModels, out IRegressionProblemData notCovered) {
       var training = pd.TrainingIndices.Where(x => !m5RuleModel.Covers(pd.Dataset, x)).ToArray();
       var test = pd.TestIndices.Where(x => !m5RuleModel.Covers(pd.Dataset, x)).ToArray();
@@ -134,16 +114,8 @@
       var res = new ResultCollection {
         new Result(ConditionResultName, new StringValue(m5RuleModel.ToCompactString())),
-        new Result(CoverResultName, new IntValue(pd.TrainingIndices.Count()-training.Length))
+        new Result(CoverResultName, new IntValue(pd.TrainingIndices.Count() - training.Length))
       };
       if (displayModels) res.Add(new Result(RuleModelResultName, m5RuleModel.CreateRegressionSolution(covered)));
       return res;
-    }
-
-    private static IEnumerable<double> Cumulate(this IEnumerable<double> values) {
-      double sum = 0.0;
-      foreach (var value in values) {
-        sum += value;
-        yield return sum;
-      }
     }
 
@@ -161,3 +133,2 @@
   }
 }
-
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5CreationParameters.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5CreationParameters.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5CreationParameters.cs	(revision 15470)
@@ -28,5 +28,5 @@
 namespace HeuristicLab.Algorithms.DataAnalysis {
   internal class M5CreationParameters {
-    private readonly IImpurityType Impurity1;
+    private readonly ISplitType Impurity1;
     private readonly IPruningType Pruningtype1;
     private readonly ILeafType<IRegressionModel> LeafType1;
@@ -35,5 +35,5 @@
     private readonly IRandom Random1;
     private readonly ResultCollection Results1;
-    public IImpurityType Impurity {
+    public ISplitType Split {
       get { return Impurity1; }
     }
@@ -71,6 +71,6 @@
 
     public M5CreationParameters(IPruningType pruning, int minleafSize, ILeafType<IRegressionModel> modeltype,
-      IRegressionProblemData problemData, IRandom random, IImpurityType impurity, ResultCollection results) {
-      Impurity1 = impurity;
+      IRegressionProblemData problemData, IRandom random, ISplitType split, ResultCollection results) {
+      Impurity1 = split;
       Pruningtype1 = pruning;
       ProblemData1 = problemData;
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5UpdateParameters.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5UpdateParameters.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5UpdateParameters.cs	(revision 15470)
@@ -30,5 +30,4 @@
     private readonly IRegressionProblemData ProblemData1;
     private readonly IRandom Random1;
-    private readonly ResultCollection Results1;
     public ILeafType<IRegressionModel> LeafType {
       get { return LeafType1; }
@@ -40,23 +39,12 @@
       get { return Random1; }
     }
-    public ResultCollection Results {
-      get { return Results1; }
-    }
-
-    public IEnumerable<string> AllowedInputVariables {
-      get { return ProblemData.AllowedInputVariables; }
-    }
-    public string TargetVariable {
-      get { return ProblemData.TargetVariable; }
-    }
     public IDataset Data {
       get { return ProblemData.Dataset; }
     }
 
-    public M5UpdateParameters(ILeafType<IRegressionModel> modeltype, IRegressionProblemData problemData, IRandom random, ResultCollection results) {
+    public M5UpdateParameters(ILeafType<IRegressionModel> modeltype, IRegressionProblemData problemData, IRandom random) {
       ProblemData1 = problemData;
       Random1 = random;
       LeafType1 = modeltype;
-      Results1 = results;
     }
   }
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/PrincipleComponentTransformation.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/PrincipleComponentTransformation.cs	(revision 15470)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/PrincipleComponentTransformation.cs	(revision 15470)
@@ -0,0 +1,200 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  public class PrincipleComponentTransformation : IDeepCloneable {
+    #region Properties
+    [Storable]
+    private double[,] Matrix { get; set; }
+    [Storable]
+    public double[] Variances { get; private set; }
+    [Storable]
+    public string[] VariableNames { get; private set; }
+    [Storable]
+    private double[] Deviations { get; set; }
+    [Storable]
+    private double[] Means { get; set; }
+    public string[] ComponentNames {
+      get { return VariableNames.Select((_, x) => "pc" + x).ToArray(); }
+    }
+    #endregion
+
+    #region HLConstructors
+    [StorableConstructor]
+    protected PrincipleComponentTransformation(bool deserializing) { }
+    protected PrincipleComponentTransformation(PrincipleComponentTransformation original, Cloner cloner) {
+      if (original.Variances != null) Variances = original.Variances.ToArray();
+      if (original.VariableNames != null) VariableNames = original.VariableNames.ToArray();
+      if (original.Deviations != null) Deviations = original.Deviations.ToArray();
+      if (original.Means != null) Means = original.Means.ToArray();
+      if (original.Matrix == null) return;
+      Matrix = new double[original.Matrix.GetLength(0), original.Matrix.GetLength(1)];
+      for (var i = 0; i < original.Matrix.GetLength(0); i++)
+      for (var j = 0; j < original.Matrix.GetLength(1); j++)
+        Matrix[i, j] = original.Matrix[i, j];
+    }
+    private PrincipleComponentTransformation() { }
+    public IDeepCloneable Clone(Cloner cloner) {
+      return new PrincipleComponentTransformation(this, cloner);
+    }
+    public object Clone() {
+      return new Cloner().Clone(this);
+    }
+    #endregion
+
+    #region Static Interface
+    public static PrincipleComponentTransformation CreateProjection(IDataset dataset, IEnumerable<int> rows, IEnumerable<string> variables, bool normalize = false) {
+      var res = new PrincipleComponentTransformation();
+      res.BuildPca(dataset, rows, variables, normalize);
+      return res;
+    }
+    #endregion
+
+    #region Projection
+    public IRegressionProblemData TransformProblemData(IRegressionProblemData pd) {
+      return CreateProblemData(pd, TransformDataset(pd.Dataset), ComponentNames);
+    }
+
+    public IDataset TransformDataset(IDataset data) {
+      return CreateDataset(data, TransformData(data, Enumerable.Range(0, data.Rows)));
+    }
+
+    public double[,] TransformData(IDataset dataset, IEnumerable<int> rows) {
+      var instances = rows.ToArray();
+      var result = new double[instances.Length, VariableNames.Length];
+      for (var r = 0; r < instances.Length; r++)
+      for (var i = 0; i < VariableNames.Length; i++) {
+        var val = (dataset.GetDoubleValue(VariableNames[i], instances[r]) - Means[i]) / Deviations[i];
+        for (var j = 0; j < VariableNames.Length; j++)
+          result[r, j] += val * Matrix[i, j];
+      }
+      return result;
+    }
+    #endregion
+
+    #region Reversion
+    public IRegressionProblemData RevertProblemData(IRegressionProblemData pd) {
+      return CreateProblemData(pd, RevertDataset(pd.Dataset), VariableNames);
+    }
+
+    public IDataset RevertDataset(IDataset data) {
+      return CreateRevertedDataset(data, RevertData(data, Enumerable.Range(0, data.Rows)));
+    }
+
+    public double[,] RevertData(IDataset dataset, IEnumerable<int> rows) {
+      var instances = rows.ToArray();
+      var components = ComponentNames;
+      var result = new double[instances.Length, VariableNames.Length];
+      for (var r = 0; r < instances.Length; r++)
+      for (var i = 0; i < components.Length; i++) {
+        var val = dataset.GetDoubleValue(components[i], instances[r]);
+        for (var j = 0; j < VariableNames.Length; j++)
+          result[r, j] += val * Matrix[j, i];
+      }
+      for (var r = 0; r < instances.Length; r++) {
+        for (var j = 0; j < VariableNames.Length; j++) {
+          result[r, j] *= Deviations[j];
+          result[r, j] += Means[j];
+        }
+      }
+
+      return result;
+    }
+    #endregion
+
+    #region Helpers
+    private static IRegressionProblemData CreateProblemData(IRegressionProblemData pd, IDataset data, IReadOnlyList<string> allowedNames) {
+      var res = new RegressionProblemData(data, allowedNames, pd.TargetVariable);
+      res.TestPartition.Start = pd.TestPartition.Start;
+      res.TestPartition.End = pd.TestPartition.End;
+      res.TrainingPartition.Start = pd.TrainingPartition.Start;
+      res.TrainingPartition.End = pd.TrainingPartition.End;
+      res.Name = pd.Name;
+      return res;
+    }
+
+    private IDataset CreateDataset(IDataset data, double[,] pcs) {
+      var n = ComponentNames;
+      var nDouble = data.DoubleVariables.Where(x => !VariableNames.Contains(x)).ToArray();
+      var nDateTime = data.DateTimeVariables.ToArray();
+      var nString = data.StringVariables.ToArray();
+
+      IEnumerable<IList> nData = n.Select((_, x) => Enumerable.Range(0, pcs.GetLength(0)).Select(r => pcs[r, x]).ToList());
+      IEnumerable<IList> nDoubleData = nDouble.Select(x => data.GetDoubleValues(x).ToList());
+      IEnumerable<IList> nDateTimeData = nDateTime.Select(x => data.GetDateTimeValues(x).ToList());
+      IEnumerable<IList> nStringData = nString.Select(x => data.GetStringValues(x).ToList());
+
+      return new Dataset(n.Concat(nDouble).Concat(nDateTime).Concat(nString), nData.Concat(nDoubleData).Concat(nDateTimeData).Concat(nStringData).ToArray());
+    }
+
+    private IDataset CreateRevertedDataset(IDataset data, double[,] pcs) {
+      var n = VariableNames;
+      var nDouble = data.DoubleVariables.Where(x => !ComponentNames.Contains(x)).ToArray();
+      var nDateTime = data.DateTimeVariables.ToArray();
+      var nString = data.StringVariables.ToArray();
+
+      IEnumerable<IList> nData = n.Select((_, x) => Enumerable.Range(0, pcs.GetLength(0)).Select(r => pcs[r, x]).ToList());
+      IEnumerable<IList> nDoubleData = nDouble.Select(x => data.GetDoubleValues(x).ToList());
+      IEnumerable<IList> nDateTimeData = nDateTime.Select(x => data.GetDateTimeValues(x).ToList());
+      IEnumerable<IList> nStringData = nString.Select(x => data.GetStringValues(x).ToList());
+
+      return new Dataset(n.Concat(nDouble).Concat(nDateTime).Concat(nString), nData.Concat(nDoubleData).Concat(nDateTimeData).Concat(nStringData).ToArray());
+    }
+
+    private void BuildPca(IDataset dataset, IEnumerable<int> rows, IEnumerable<string> variables, bool normalize) {
+      var instances = rows.ToArray();
+      var attributes = variables.ToArray();
+      Means = normalize
+        ? attributes.Select(v => dataset.GetDoubleValues(v, instances).Average()).ToArray()
+        : attributes.Select(x => 0.0).ToArray();
+      Deviations = normalize
+        ? attributes.Select(v => dataset.GetDoubleValues(v, instances).StandardDeviationPop()).Select(x => x.IsAlmost(0.0) ? 1 : x).ToArray()
+        : attributes.Select(x => 1.0).ToArray();
+
+      var data = new double[instances.Length, attributes.Length];
+
+      for (var j = 0; j < attributes.Length; j++) {
+        var i = 0;
+        foreach (var v in dataset.GetDoubleValues(attributes[j], instances)) {
+          data[i, j] = (v - Means[j]) / Deviations[j];
+          i++;
+        }
+      }
+
+      int info;
+      double[] variances;
+      double[,] matrix;
+      alglib.pcabuildbasis(data, instances.Length, attributes.Length, out info, out variances, out matrix);
+      Matrix = matrix;
+      Variances = variances;
+      VariableNames = attributes;
+    }
+    #endregion
+  }
+}
Index: anches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/SplitInfo.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/SplitInfo.cs	(revision 15469)
+++ 	(revision )
@@ -1,85 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using HeuristicLab.Common;
-
-namespace HeuristicLab.Algorithms.DataAnalysis {
-  internal sealed class SplitInfo : IDeepCloneable {
-    #region Properties
-    public int Position { get; private set; } // position of maximum impurity reduction
-    public double MaxImpurity { get; private set; } // maximum impurity reduction
-    public string SplitAttr { get; private set; } // spliting attribute
-    public double SplitValue { get; private set; } // splitting value
-    #endregion
-
-    #region HLConstructors
-    private SplitInfo(SplitInfo original) {
-      Position = original.Position;
-      MaxImpurity = original.MaxImpurity;
-      SplitValue = original.SplitValue;
-      SplitAttr = original.SplitAttr;
-    }
-    public SplitInfo() {
-      MaxImpurity = -1E20;
-    }
-    public IDeepCloneable Clone(Cloner cloner) {
-      return new SplitInfo(this);
-    }
-    public object Clone() {
-      return new Cloner().Clone(this);
-    }
-    #endregion
-
-    public void AttributeSplit(string attr, IReadOnlyList<double> attribute, IReadOnlyList<double> targets, M5CreationParameters m5CreationParams) {
-      Position = 0;
-      MaxImpurity = -1E20;
-      SplitAttr = attr;
-      SplitValue = 0.0;
-
-      //minSize and order are fixed to 4 and 5 in weka
-      //var order = Math.Max(0, minSize) + 1;
-      //var len = Math.Max(1, targets.Count / order);
-      //len = Math.Max(len, minSize);
-      //var order = 5;
-
-      if (targets.Count < m5CreationParams.MinLeafSize) return;
-
-      var len = m5CreationParams.MinLeafSize;
-      if (targets.Count <= m5CreationParams.MinLeafSize) return;
-      var imp = m5CreationParams.Impurity.GenerateCalculator(len, targets);
-
-      if (imp.Impurity > MaxImpurity) {
-        MaxImpurity = imp.Impurity;
-        SplitValue = (attribute[len - 1] + attribute[len]) / 2;
-        Position = len;
-      }
-      for (var i = len; i < targets.Count - len; i++) {
-        imp.Increment(targets[i], IncrementType.Left);
-        if (attribute[i + 1].IsAlmost(attribute[i]) || imp.Impurity <= MaxImpurity) continue;
-        MaxImpurity = imp.Impurity;
-        SplitValue = (attribute[i] + attribute[i + 1]) / 2;
-        Position = i + 1;
-      }
-    }
-  }
-}
-
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/ComponentReducedLinearModel.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/ComponentReducedLinearModel.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/ComponentReducedLinearModel.cs	(revision 15470)
@@ -21,4 +21,5 @@
 
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -31,5 +32,5 @@
     private IConfidenceRegressionModel Model;
     [Storable]
-    private PrincipleComponentAnalysisStatic Pca;
+    private PrincipleComponentTransformation Pca;
 
     [StorableConstructor]
@@ -39,5 +40,5 @@
       Pca = cloner.Clone(original.Pca);
     }
-    public ComponentReducedLinearModel(string targetVariable, IConfidenceRegressionModel model, PrincipleComponentAnalysisStatic pca) : base(targetVariable) {
+    public ComponentReducedLinearModel(string targetVariable, IConfidenceRegressionModel model, PrincipleComponentTransformation pca) : base(targetVariable) {
       Model = model;
       Pca = pca;
@@ -51,5 +52,6 @@
     }
     public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
-      return Model.GetEstimatedValues(Pca.ProjectDataset(dataset), rows);
+      var data = ReduceDataset(dataset, rows.ToArray());
+      return Model.GetEstimatedValues(Pca.TransformDataset(data), Enumerable.Range(0, data.Rows));
     }
     public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
@@ -57,5 +59,10 @@
     }
     public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
-      return Model.GetEstimatedVariances(Pca.ProjectDataset(dataset), rows);
+      var data = ReduceDataset(dataset, rows.ToArray());
+      return Model.GetEstimatedVariances(Pca.TransformDataset(data), Enumerable.Range(0, data.Rows));
+    }
+
+    private IDataset ReduceDataset(IDataset data, IReadOnlyList<int> rows) {
+      return new Dataset(data.DoubleVariables, data.DoubleVariables.Select(v => data.GetDoubleValues(v, rows).ToList()));
     }
   }
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5NodeModel.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5NodeModel.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5NodeModel.cs	(revision 15470)
@@ -56,6 +56,4 @@
     [Storable]
     private IReadOnlyList<string> Variables { get; set; }
-
-    private const double DevFraction = 0.05;
     #endregion
 
@@ -110,37 +108,23 @@
       Left = null;
       NodeModel = null;
-      IsLeaf = m5CreationParams.Data.GetDoubleValues(TargetVariable, rows).StandardDeviation() < globalStdDev * DevFraction;
+      SplitAttr = null;
+      SplitValue = double.NaN;
+      string attr;
+      double splitValue;
+      //IsLeaf = m5CreationParams.Data.GetDoubleValues(TargetVariable, rows).StandardDeviation() < globalStdDev * DevFraction;
+      //if (IsLeaf) return;
+      IsLeaf = !m5CreationParams.Split.Split(new RegressionProblemData(ReduceDataset(m5CreationParams.Data, rows), Variables, TargetVariable), m5CreationParams.MinLeafSize, out attr, out splitValue);
       if (IsLeaf) return;
-      //Split(rows, m5Params, globalStdDev);
-      var bestSplit = new SplitInfo();
-      var currentSplit = new SplitInfo();
-
-      //find best Attribute for the Split
-      foreach (var attr in m5CreationParams.AllowedInputVariables) {
-        var sortedData = m5CreationParams.Data.GetDoubleValues(attr, rows).Zip(m5CreationParams.Data.GetDoubleValues(TargetVariable, rows), Tuple.Create).OrderBy(x => x.Item1).ToArray();
-        currentSplit.AttributeSplit(attr, sortedData.Select(x => x.Item1).ToArray(), sortedData.Select(x => x.Item2).ToArray(), m5CreationParams);
-        if (!currentSplit.MaxImpurity.IsAlmost(bestSplit.MaxImpurity) && currentSplit.MaxImpurity > bestSplit.MaxImpurity)
-          bestSplit = (SplitInfo) currentSplit.Clone();
-      }
-
-      //if no suitable split exists => leafNode
-      if (bestSplit.SplitAttr == null || bestSplit.Position < 1 || bestSplit.Position > rows.Count - 1) {
+
+      //split Dataset
+      IReadOnlyList<int> leftRows, rightRows;
+      SplitRows(rows, m5CreationParams.Data, attr, splitValue, out leftRows, out rightRows);
+
+      if (leftRows.Count < m5CreationParams.MinLeafSize || rightRows.Count < m5CreationParams.MinLeafSize) {
         IsLeaf = true;
         return;
       }
-
-      SplitAttr = bestSplit.SplitAttr;
-      SplitValue = bestSplit.SplitValue;
-
-      //split Dataset
-      IReadOnlyList<int> leftRows, rightRows;
-      SplitRows(rows, m5CreationParams.Data, SplitAttr, SplitValue, out leftRows, out rightRows);
-
-      if (leftRows.Count < m5CreationParams.MinLeafSize || rightRows.Count < m5CreationParams.MinLeafSize) {
-        IsLeaf = true;
-        SplitAttr = null;
-        SplitValue = double.NaN;
-        return;
-      }
+      SplitAttr = attr;
+      SplitValue = splitValue;
 
       //create subtrees
@@ -220,5 +204,5 @@
 
     private void BuildModel(IReadOnlyList<int> rows, IDataset data, IRandom random, ILeafType<IRegressionModel> leafType, CancellationToken cancellation) {
-      var reducedData = new Dataset(VariablesUsedForPrediction.Concat(new[] {TargetVariable}), VariablesUsedForPrediction.Concat(new[] {TargetVariable}).Select(x => data.GetDoubleValues(x, rows).ToList()));
+      var reducedData = ReduceDataset(data, rows);
       var pd = new RegressionProblemData(reducedData, VariablesUsedForPrediction, TargetVariable);
       pd.TrainingPartition.Start = 0;
@@ -229,4 +213,8 @@
       NodeModelParams = noparams;
       cancellation.ThrowIfCancellationRequested();
+    }
+
+    private IDataset ReduceDataset(IDataset data, IReadOnlyList<int> rows) {
+      return new Dataset(VariablesUsedForPrediction.Concat(new[] {TargetVariable}), VariablesUsedForPrediction.Concat(new[] {TargetVariable}).Select(x => data.GetDoubleValues(x, rows).ToList()));
     }
 
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/PreconstructedLinearModel.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/PreconstructedLinearModel.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/PreconstructedLinearModel.cs	(revision 15470)
@@ -24,9 +24,6 @@
 using System.Linq;
 using HeuristicLab.Common;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Problems.DataAnalysis.Symbolic;
-using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
@@ -98,5 +95,4 @@
     }
 
-
     public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       return rows.Select(row => GetEstimatedValue(dataset, row));
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLeafPruning.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLeafPruning.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLeafPruning.cs	(revision 15470)
@@ -30,5 +30,5 @@
 namespace HeuristicLab.Algorithms.DataAnalysis {
   [StorableClass]
-  [Item("HoldoutLeafPruning", "Postpruning via a holdout set")]
+  [Item("HoldoutLeafPruning", "Postpruning via a holdout set. Pruning is done using the model type of the leaf models")]
   public class HoldoutLeafPruning : PruningBase {
     private const string HoldoutSizeParameterName = "HoldoutSize";
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LinearPruning.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LinearPruning.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LinearPruning.cs	(revision 15470)
@@ -34,5 +34,5 @@
     private M5LinearPruning(bool deserializing) : base(deserializing) { }
     private M5LinearPruning(M5LinearPruning original, Cloner cloner) : base(original, cloner) { }
-    public M5LinearPruning() : base() { }
+    public M5LinearPruning() { }
     public override IDeepCloneable Clone(Cloner cloner) {
       return new M5LinearPruning(this, cloner);
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/NoPruning.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/NoPruning.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/NoPruning.cs	(revision 15470)
@@ -34,5 +34,7 @@
     private NoPruning(bool deserializing) : base(deserializing) { }
     private NoPruning(NoPruning original, Cloner cloner) : base(original, cloner) { }
-    public NoPruning() : base() { }
+    public NoPruning() {
+      PruningStrengthParameter.Hidden = true;
+    }
     public override IDeepCloneable Clone(Cloner cloner) {
       return new NoPruning(this, cloner);
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/PruningBase.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/PruningBase.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/PruningBase.cs	(revision 15470)
@@ -45,5 +45,5 @@
     protected PruningBase(bool deserializing) : base(deserializing) { }
     protected PruningBase(PruningBase original, Cloner cloner) : base(original, cloner) { }
-    protected PruningBase() : base() {
+    protected PruningBase() {
       Parameters.Add(new FixedValueParameter<DoubleValue>(PruningStrengthParameterName, "The strength of the pruning. Higher values force the algorithm to create simpler models", new DoubleValue(2.0)));
     }
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityCalculator.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityCalculator.cs	(revision 15469)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityCalculator.cs	(revision 15470)
@@ -27,8 +27,14 @@
 namespace HeuristicLab.Algorithms.DataAnalysis {
   /// <summary>
-  /// Helper class for incremental impurity calculation.
+  /// Helper class for incremental split calculation.
   /// Used while moving a potential Split along the ordered training Instances
   /// </summary>
-  internal class OrderImpurityCalculator : IImpurityCalculator {
+  internal class OrderImpurityCalculator {
+    internal enum IncrementType {
+      Left,
+      Right,
+      None
+    }
+
     #region Properties
     private double SqSumLeft { get; set; }
@@ -99,5 +105,5 @@
       VarRight = NoRight <= 0 ? 0 : Math.Abs(NoRight * SqSumRight - SumRight * SumRight) / (NoRight * NoRight);
 
-      if (Order <= 0) throw new ArgumentException("Impurity order must be larger than 0");
+      if (Order <= 0) throw new ArgumentException("Split order must be larger than 0");
       if (Order.IsAlmost(1)) {
         y = VarTotal;
@@ -111,6 +117,6 @@
       }
       var t = NoRight + NoLeft;
-      if (NoLeft <= 0.0 || NoRight <= 0.0) Impurity = double.MinValue; //Impurity = 0;
-      else Impurity = y - NoLeft / t * yl - NoRight / t * yr; //  Impurity = y - NoLeft / NoRight * yl - NoRight / NoLeft * yr
+      if (NoLeft <= 0.0 || NoRight <= 0.0) Impurity = double.MinValue; //Split = 0;
+      else Impurity = y - NoLeft / t * yl - NoRight / t * yr; //  Split = y - NoLeft / NoRight * yl - NoRight / NoLeft * yr
     }
     #endregion
Index: anches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityType.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityType.cs	(revision 15469)
+++ 	(revision )
@@ -1,59 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Algorithms.DataAnalysis {
-  [StorableClass]
-  [Item("OrderImpurityType", "A split selector that uses the ratio between Variances^1/Order to determine good splits")]
-  public class OrderImpurityType : ParameterizedNamedItem, IImpurityType {
-    public const string OrderParameterName = "Order";
-    public IFixedValueParameter<DoubleValue> OrderParameter {
-      get { return Parameters[OrderParameterName] as IFixedValueParameter<DoubleValue>; }
-    }
-    public double Order {
-      get { return OrderParameter.Value.Value; }
-    }
-
-    #region Constructors & Cloning
-    [StorableConstructor]
-    private OrderImpurityType(bool deserializing) { }
-    private OrderImpurityType(OrderImpurityType original, Cloner cloner) : base(original, cloner) { }
-    public OrderImpurityType() {
-      Parameters.Add(new FixedValueParameter<DoubleValue>(OrderParameterName, "The exponent in the impurity calculation sum (x_i - x_avg)^Order.", new DoubleValue(4)));
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new OrderImpurityType(this, cloner);
-    }
-    #endregion
-
-    #region IImpurityType
-    public IImpurityCalculator GenerateCalculator(int partition, IReadOnlyCollection<double> data) {
-      return new OrderImpurityCalculator(partition, data, Order);
-    }
-    #endregion
-  }
-}
Index: /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderSplitType.cs
===================================================================
--- /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderSplitType.cs	(revision 15470)
+++ /branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderSplitType.cs	(revision 15470)
@@ -0,0 +1,105 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("OrderSplitType", "A split selector that uses the ratio between Variances^1/Order to determine good splits")]
+  public class OrderSplitType : ParameterizedNamedItem, ISplitType {
+    public const string OrderParameterName = "Order";
+    public IFixedValueParameter<DoubleValue> OrderParameter {
+      get { return Parameters[OrderParameterName] as IFixedValueParameter<DoubleValue>; }
+    }
+    public double Order {
+      get { return OrderParameter.Value.Value; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private OrderSplitType(bool deserializing) { }
+    private OrderSplitType(OrderSplitType original, Cloner cloner) : base(original, cloner) { }
+    public OrderSplitType() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(OrderParameterName, "The exponent in the split calculation sum (x_i - x_avg)^Order.", new DoubleValue(4)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OrderSplitType(this, cloner);
+    }
+    #endregion
+
+    #region ISplitType
+    public bool Split(IRegressionProblemData splitData, int minLeafSize, out string splitAttr, out double splitValue) {
+      var bestPos = 0;
+      var bestImpurity = double.MinValue;
+      var bestSplitValue = 0.0;
+      var bestSplitAttr = string.Empty;
+      splitAttr = bestSplitAttr;
+      splitValue = bestSplitValue;
+      if (splitData.Dataset.Rows < minLeafSize) return false;
+      //find best Attribute for the Split
+      foreach (var attr in splitData.AllowedInputVariables) {
+        int pos;
+        double impurity, sValue;
+        var sortedData = splitData.Dataset.GetDoubleValues(attr).Zip(splitData.Dataset.GetDoubleValues(splitData.TargetVariable), Tuple.Create).OrderBy(x => x.Item1).ToArray();
+        AttributeSplit(sortedData.Select(x => x.Item1).ToArray(), sortedData.Select(x => x.Item2).ToArray(), minLeafSize, out pos, out impurity, out sValue);
+        if (!(bestImpurity < impurity)) continue;
+        bestImpurity = impurity;
+        bestPos = pos;
+        bestSplitValue = sValue;
+        bestSplitAttr = attr;
+      }
+
+      splitAttr = bestSplitAttr;
+      splitValue = bestSplitValue;
+      //if no suitable split exists => leafNode
+      return bestPos >= minLeafSize && bestPos <= splitData.Dataset.Rows - minLeafSize;
+    }
+
+    private void AttributeSplit(IReadOnlyList<double> attValues, IReadOnlyList<double> targetValues, int minLeafSize, out int position, out double maxImpurity, out double splitValue) {
+      position = 0;
+      maxImpurity = -1E20;
+      splitValue = 0.0;
+      var length = targetValues.Count;
+      var imp = new OrderImpurityCalculator(minLeafSize, targetValues, Order);
+      if (imp.Impurity > maxImpurity) {
+        maxImpurity = imp.Impurity;
+        splitValue = (attValues[minLeafSize - 1] + attValues[minLeafSize]) / 2;
+        position = minLeafSize;
+      }
+      for (var i = minLeafSize; i < length - minLeafSize; i++) {
+        imp.Increment(targetValues[i], OrderImpurityCalculator.IncrementType.Left);
+        if (imp.Impurity < maxImpurity) continue;
+        maxImpurity = imp.Impurity;
+        splitValue = (attValues[i] + attValues[i + 1]) / 2;
+        position = i + 1;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/M5Regression/M5Regression.sln
===================================================================
--- /branches/M5Regression/M5Regression.sln	(revision 15470)
+++ /branches/M5Regression/M5Regression.sln	(revision 15470)
@@ -0,0 +1,37 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.16
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.DataAnalysis-3.4", "HeuristicLab.Algorithms.DataAnalysis\3.4\HeuristicLab.Algorithms.DataAnalysis-3.4.csproj", "{2E782078-FA81-4B70-B56F-74CE38DAC6C8}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Debug|x64.ActiveCfg = Debug|x64
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Debug|x64.Build.0 = Debug|x64
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Debug|x86.ActiveCfg = Debug|x86
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Debug|x86.Build.0 = Debug|x86
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Release|x64.ActiveCfg = Release|x64
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Release|x64.Build.0 = Release|x64
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Release|x86.ActiveCfg = Release|x86
+		{2E782078-FA81-4B70-B56F-74CE38DAC6C8}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {B737E9CF-F5F6-4767-AD86-BCC13B63865F}
+	EndGlobalSection
+EndGlobal
