Index: /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 5657)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 5658)
@@ -116,9 +116,10 @@
     <Compile Include="kMeans\KMeansClusteringModel.cs" />
     <Compile Include="kMeans\KMeansClusteringSolution.cs" />
-    <Compile Include="kMeans\KMeansClusteringUtil.cs" />
+    <Compile Include="kMeans\KMeansClusteringUtil.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Linear\AlglibUtil.cs" />
+    <Compile Include="Linear\LinearDiscriminantAnalysis.cs" />
     <Compile Include="Linear\LinearRegression.cs">
-      <SubType>Code</SubType>
-    </Compile>
-    <Compile Include="Linear\LinearRegressionUtil.cs">
       <SubType>Code</SubType>
     </Compile>
Index: /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/AlglibUtil.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/AlglibUtil.cs	(revision 5658)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/AlglibUtil.cs	(revision 5658)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 System.Linq;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  public static class AlglibUtil {
+    public static double[,] PrepareInputMatrix(Dataset dataset, IEnumerable<string> variables, IEnumerable<int> rows) {
+      List<int> allowedRows = CalculateAllowedRows(dataset, variables, rows).ToList();
+
+      double[,] matrix = new double[allowedRows.Count, variables.Count()];
+      for (int row = 0; row < allowedRows.Count; row++) {
+        int col = 0;
+        foreach (string column in variables) {
+          matrix[row, col] = dataset[column, row];
+          col++;
+        }
+      }
+      return matrix;
+    }
+
+    private static IEnumerable<int> CalculateAllowedRows(Dataset dataset, IEnumerable<string> variables, IEnumerable<int> rows) {
+      // return only rows that contain no infinity or NaN values
+      return from row in rows
+             where (from variable in variables
+                    let x = dataset[variable, row]
+                    where double.IsInfinity(x) || double.IsNaN(x)
+                    select 1)
+                    .Any() == false
+             select row;
+    }
+  }
+}
Index: /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 5658)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 5658)
@@ -0,0 +1,115 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using System.Collections.Generic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Classification;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  /// <summary>
+  /// Linear discriminant analysis classification algorithm.
+  /// </summary>
+  [Item("Linear Discriminant Analysis", "Linear discriminant analysis classification algorithm.")]
+  [Creatable("Data Analysis")]
+  [StorableClass]
+  public sealed class LinearDiscriminantAnalysis : FixedDataAnalysisAlgorithm<IClassificationProblem> {
+    private const string LinearDiscriminantAnalysisSolutionResultName = "Linear discriminant analysis solution";
+
+    [StorableConstructor]
+    private LinearDiscriminantAnalysis(bool deserializing) : base(deserializing) { }
+    private LinearDiscriminantAnalysis(LinearDiscriminantAnalysis original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public LinearDiscriminantAnalysis()
+      : base() {
+      Problem = new ClassificationProblem();
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearDiscriminantAnalysis(this, cloner);
+    }
+
+    #region Fisher LDA
+    protected override void Run() {
+      var solution = CreateLinearDiscriminantAnalysisSolution(Problem.ProblemData);
+      Results.Add(new Result(LinearDiscriminantAnalysisSolutionResultName, "The linear discriminant analysis.", solution));
+    }
+
+    public static IClassificationSolution CreateLinearDiscriminantAnalysisSolution(IClassificationProblemData problemData) {
+      Dataset dataset = problemData.Dataset;
+      string targetVariable = problemData.TargetVariable;
+      IEnumerable<string> allowedInputVariables = problemData.AllowedInputVariables;
+      int samplesStart = problemData.TrainingPartitionStart.Value;
+      int samplesEnd = problemData.TrainingPartitionEnd.Value;
+      IEnumerable<int> rows = Enumerable.Range(samplesStart, samplesEnd - samplesStart);
+      int nClasses = problemData.ClassNames.Count();
+      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables.Concat(new string[] { targetVariable }), rows);
+
+      // change class values into class index
+      int targetVariableColumn = inputMatrix.GetLength(1) - 1;
+      List<double> classValues = problemData.ClassValues.OrderBy(x=>x).ToList();
+      for (int row = 0; row < inputMatrix.GetLength(0); row++) {
+        inputMatrix[row, targetVariableColumn] = classValues.IndexOf(inputMatrix[row, targetVariableColumn]);
+      }
+      int info;
+      double[] w;
+      alglib.fisherlda(inputMatrix, inputMatrix.GetLength(0), allowedInputVariables.Count(), nClasses, out info, out w);
+      if (info < 1) throw new ArgumentException("Error in calculation of linear discriminant analysis solution");
+
+      ISymbolicExpressionTree tree = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
+      ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();
+      tree.Root.AddSubTree(startNode);
+      ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();
+      startNode.AddSubTree(addition);
+
+      int col = 0;
+      foreach (string column in allowedInputVariables) {
+        VariableTreeNode vNode = (VariableTreeNode)new HeuristicLab.Problems.DataAnalysis.Symbolic.Variable().CreateTreeNode();
+        vNode.VariableName = column;
+        vNode.Weight = w[col];
+        addition.AddSubTree(vNode);
+        col++;
+      }
+
+      ConstantTreeNode cNode = (ConstantTreeNode)new Constant().CreateTreeNode();
+      cNode.Value = w[w.Length - 1];
+      addition.AddSubTree(cNode);
+
+      var model = new SymbolicDiscriminantFunctionClassificationModel(tree, new SymbolicDataAnalysisExpressionTreeInterpreter(), classValues);
+      SymbolicDiscriminantFunctionClassificationSolution solution = new SymbolicDiscriminantFunctionClassificationSolution(model, problemData);
+      return solution;
+    }
+    #endregion
+  }
+}
Index: /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs	(revision 5657)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs	(revision 5658)
@@ -75,6 +75,6 @@
       int samplesStart = problemData.TrainingPartitionStart.Value;
       int samplesEnd = problemData.TrainingPartitionEnd.Value;
-
-      double[,] inputMatrix = LinearRegressionUtil.PrepareInputMatrix(dataset, targetVariable, allowedInputVariables, samplesStart, samplesEnd);
+      IEnumerable<int> rows = Enumerable.Range(samplesStart, samplesEnd - samplesStart);
+      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables.Concat(new string[] { targetVariable }), rows);
 
       alglib.linearmodel lm = new alglib.linearmodel();
Index: anches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegressionUtil.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegressionUtil.cs	(revision 5657)
+++ 	(revision )
@@ -1,64 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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 System.Linq;
-using HeuristicLab.Problems.DataAnalysis;
-
-namespace HeuristicLab.Algorithms.DataAnalysis {
-  public static class LinearRegressionUtil {
-    public static double[,] PrepareInputMatrix(Dataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, int start, int end) {
-      List<int> allowedRows = CalculateAllowedRows(dataset, targetVariable, allowedInputVariables, start, end);
-
-      double[,] matrix = new double[allowedRows.Count, allowedInputVariables.Count() + 1];
-      for (int row = 0; row < allowedRows.Count; row++) {
-        int col = 0;
-        foreach (string column in allowedInputVariables) {
-          matrix[row, col] = dataset[column, row];
-          col++;
-        }
-        matrix[row, allowedInputVariables.Count()] = dataset[targetVariable, row];
-      }
-      return matrix;
-    }
-
-    private static List<int> CalculateAllowedRows(Dataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, int start, int end) {
-      List<int> allowedRows = new List<int>();
-      bool add = false;
-
-      for (int row = start; row < end; row++) {
-        add = true;
-        foreach (string column in allowedInputVariables) {
-          double value = dataset[column, row];
-          if (double.IsInfinity(value) ||
-            double.IsNaN(value))
-            add = false;
-        }
-        if (double.IsNaN(dataset[targetVariable, row]))
-          add = false;
-        if (add)
-          allowedRows.Add(row);
-        add = true;
-      }
-      return allowedRows;
-    }
-  }
-}
Index: /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClustering.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClustering.cs	(revision 5657)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClustering.cs	(revision 5658)
@@ -94,5 +94,5 @@
       double[,] centers;
       int[] xyc;
-      double[,] inputMatrix = KMeansClusteringUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
       alglib.kmeansgenerate(inputMatrix, inputMatrix.GetLength(0), inputMatrix.GetLength(1), k, restarts + 1, out info, out centers, out xyc);
       if (info != 1) throw new ArgumentException("Error in calculation of k-Means clustering solution");
Index: /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringModel.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringModel.cs	(revision 5657)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringModel.cs	(revision 5658)
@@ -64,4 +64,6 @@
     public KMeansClusteringModel(double[,] centers, IEnumerable<string> allowedInputVariables)
       : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
       // disect center matrix into list of double[]
       // centers are given as double matrix where number of rows = dimensions and number of columns = clusters
Index: /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringUtil.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringUtil.cs	(revision 5657)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringUtil.cs	(revision 5658)
@@ -27,29 +27,4 @@
 namespace HeuristicLab.Algorithms.DataAnalysis {
   public static class KMeansClusteringUtil {
-    public static double[,] PrepareInputMatrix(Dataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<int> rows) {
-      List<int> allowedRows = CalculateAllowedRows(dataset, allowedInputVariables, rows).ToList();
-
-      double[,] matrix = new double[allowedRows.Count, allowedInputVariables.Count()];
-      for (int row = 0; row < allowedRows.Count; row++) {
-        int col = 0;
-        foreach (string column in allowedInputVariables) {
-          matrix[row, col] = dataset[column, row];
-          col++;
-        }
-      }
-      return matrix;
-    }
-
-    private static IEnumerable<int> CalculateAllowedRows(Dataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<int> rows) {
-      // return only rows that contain no infinity or NaN values
-      return from row in rows
-             where (from inputVariable in allowedInputVariables
-                    let x = dataset[inputVariable, row]
-                    where double.IsInfinity(x) || double.IsNaN(x)
-                    select 1)
-                    .Any() == false
-             select row;
-    }
-
     public static IEnumerable<int> FindClosestCenters(IEnumerable<double[]> centers, Dataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<int> rows) {
       int nRows = rows.Count();
