Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DiscriminantFunctionClassificationSolution.cs	(revision 5649)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DiscriminantFunctionClassificationSolution.cs	(revision 5657)
@@ -74,5 +74,8 @@
 
     public IEnumerable<double> Thresholds {
-      get { return Model.Thresholds; }
+      get {
+        return Model.Thresholds;
+      }
+      protected set { Model.Thresholds = value; }
     }
 
@@ -88,4 +91,86 @@
     }
     #endregion
+
+    public override IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows) {
+      if (Model.Thresholds == null || Model.Thresholds.Count() == 0) RecalculateClassIntermediates();
+      return base.GetEstimatedClassValues(rows);
+    }
+
+    private void RecalculateClassIntermediates() {
+      int slices = 100;
+      List<double> estimatedValues = EstimatedValues.ToList();
+      List<int> classInstances = (from classValue in ProblemData.Dataset.GetVariableValues(ProblemData.TargetVariable)
+                                  group classValue by classValue into grouping
+                                  select grouping.Count()).ToList();
+      double maxEstimatedValue = estimatedValues.Max();
+      double minEstimatedValue = estimatedValues.Min();
+      List<KeyValuePair<double, double>> estimatedTargetValues =
+         (from row in ProblemData.TrainingIndizes
+          select new KeyValuePair<double, double>(
+            estimatedValues[row],
+            ProblemData.Dataset[ProblemData.TargetVariable, row])).ToList();
+
+      List<double> originalClasses = ProblemData.ClassValues.OrderBy(x => x).ToList();
+      int nClasses = originalClasses.Distinct().Count();
+      double[] thresholds = new double[nClasses + 1];
+      thresholds[0] = double.NegativeInfinity;
+      thresholds[thresholds.Length - 1] = double.PositiveInfinity;
+
+      for (int i = 1; i < thresholds.Length - 1; i++) {
+        double lowerThreshold = thresholds[i - 1];
+        double actualThreshold = minEstimatedValue;
+        double thresholdIncrement = (maxEstimatedValue - minEstimatedValue) / slices;
+
+        double lowestBestThreshold = double.NaN;
+        double highestBestThreshold = double.NaN;
+        double bestClassificationScore = double.PositiveInfinity;
+        bool seriesOfEqualClassificationScores = false;
+
+        while (actualThreshold < maxEstimatedValue) {
+          double classificationScore = 0.0;
+
+          foreach (KeyValuePair<double, double> estimatedTarget in estimatedTargetValues) {
+            //all positives
+            if (estimatedTarget.Value.IsAlmost(originalClasses[i - 1])) {
+              if (estimatedTarget.Key > lowerThreshold && estimatedTarget.Key < actualThreshold)
+                //true positive
+                classificationScore += ProblemData.GetClassificationPenalty(originalClasses[i - 1], originalClasses[i - 1]);
+              else
+                //false negative
+                classificationScore += ProblemData.GetClassificationPenalty(originalClasses[i], originalClasses[i - 1]);
+            }
+              //all negatives
+            else {
+              if (estimatedTarget.Key > lowerThreshold && estimatedTarget.Key < actualThreshold)
+                //false positive
+                classificationScore += ProblemData.GetClassificationPenalty(originalClasses[i - 1], originalClasses[i]);
+              else
+                //true negative, consider only upper class
+                classificationScore += ProblemData.GetClassificationPenalty(originalClasses[i], originalClasses[i]);
+            }
+          }
+
+          //new best classification score found
+          if (classificationScore < bestClassificationScore) {
+            bestClassificationScore = classificationScore;
+            lowestBestThreshold = actualThreshold;
+            highestBestThreshold = actualThreshold;
+            seriesOfEqualClassificationScores = true;
+          }
+            //equal classification scores => if seriesOfEqualClassifcationScores == true update highest threshold
+          else if (Math.Abs(classificationScore - bestClassificationScore) < double.Epsilon && seriesOfEqualClassificationScores)
+            highestBestThreshold = actualThreshold;
+          //worse classificatoin score found reset seriesOfEqualClassifcationScores
+          else seriesOfEqualClassificationScores = false;
+
+          actualThreshold += thresholdIncrement;
+        }
+        //scale lowest thresholds and highest found optimal threshold according to the misclassification matrix
+        double falseNegativePenalty = ProblemData.GetClassificationPenalty(originalClasses[i], originalClasses[i - 1]);
+        double falsePositivePenalty = ProblemData.GetClassificationPenalty(originalClasses[i - 1], originalClasses[i]);
+        thresholds[i] = (lowestBestThreshold * falsePositivePenalty + highestBestThreshold * falseNegativePenalty) / (falseNegativePenalty + falsePositivePenalty);
+      }
+      Thresholds = new List<double>(thresholds);
+    }
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 5649)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 5657)
@@ -24,5 +24,5 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface IDiscriminantFunctionClassificationModel : IClassificationModel {
-    IEnumerable<double> Thresholds { get; }
+    IEnumerable<double> Thresholds { get; set; }
     event EventHandler ThresholdsChanged;
     IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/OnlineEvaluators/OnlineAccuracyEvaluator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/OnlineEvaluators/OnlineAccuracyEvaluator.cs	(revision 5649)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/OnlineEvaluators/OnlineAccuracyEvaluator.cs	(revision 5657)
@@ -34,5 +34,5 @@
           throw new InvalidOperationException("No elements");
         else
-          return correctlyClassified / n;
+          return correctlyClassified / (double)n;
       }
     }
