Index: /trunk/sources/HeuristicLab.Analysis.Views/3.3/HistogramControl.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis.Views/3.3/HistogramControl.Designer.cs	(revision 12138)
+++ /trunk/sources/HeuristicLab.Analysis.Views/3.3/HistogramControl.Designer.cs	(revision 12139)
@@ -48,32 +48,35 @@
     private void InitializeComponent() {
       this.components = new System.ComponentModel.Container();
-      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
-      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
-      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
       this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
       this.binsNumericUpDown = new System.Windows.Forms.NumericUpDown();
       this.label1 = new System.Windows.Forms.Label();
       this.exactCheckBox = new System.Windows.Forms.CheckBox();
+      this.label2 = new System.Windows.Forms.Label();
+      this.BandwidthNumericUpDown = new System.Windows.Forms.NumericUpDown();
       ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
       ((System.ComponentModel.ISupportInitialize)(this.binsNumericUpDown)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.BandwidthNumericUpDown)).BeginInit();
       this.SuspendLayout();
       // 
       // chart
       // 
-      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-      chartArea1.Name = "ChartArea1";
-      this.chart.ChartAreas.Add(chartArea1);
-      legend1.Alignment = System.Drawing.StringAlignment.Center;
-      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
-      legend1.Name = "Default";
-      this.chart.Legends.Add(legend1);
+      chartArea2.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea2);
+      legend2.Alignment = System.Drawing.StringAlignment.Center;
+      legend2.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend2.Name = "Default";
+      this.chart.Legends.Add(legend2);
       this.chart.Location = new System.Drawing.Point(0, 27);
       this.chart.Name = "chart";
-      series1.ChartArea = "ChartArea1";
-      series1.Legend = "Default";
-      series1.Name = "Series1";
-      this.chart.Series.Add(series1);
+      series2.ChartArea = "ChartArea1";
+      series2.Legend = "Default";
+      series2.Name = "Series1";
+      this.chart.Series.Add(series2);
       this.chart.Size = new System.Drawing.Size(465, 336);
       this.chart.TabIndex = 0;
@@ -88,5 +91,5 @@
             0});
       this.binsNumericUpDown.Minimum = new decimal(new int[] {
-            1,
+            2,
             0,
             0,
@@ -115,5 +118,5 @@
       this.exactCheckBox.AutoSize = true;
       this.exactCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
-      this.exactCheckBox.Location = new System.Drawing.Point(158, 4);
+      this.exactCheckBox.Location = new System.Drawing.Point(291, 4);
       this.exactCheckBox.Name = "exactCheckBox";
       this.exactCheckBox.Size = new System.Drawing.Size(56, 17);
@@ -123,7 +126,42 @@
       this.exactCheckBox.CheckedChanged += new System.EventHandler(this.exactCheckBox_CheckedChanged);
       // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(158, 5);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(60, 13);
+      this.label2.TabIndex = 5;
+      this.label2.Text = "Bandwidth:";
+      // 
+      // BandwidthNumericUpDown
+      // 
+      this.BandwidthNumericUpDown.DecimalPlaces = 2;
+      this.BandwidthNumericUpDown.Location = new System.Drawing.Point(224, 3);
+      this.BandwidthNumericUpDown.Maximum = new decimal(new int[] {
+            100000000,
+            0,
+            0,
+            0});
+      this.BandwidthNumericUpDown.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            65536});
+      this.BandwidthNumericUpDown.Name = "BandwidthNumericUpDown";
+      this.BandwidthNumericUpDown.Size = new System.Drawing.Size(61, 20);
+      this.BandwidthNumericUpDown.TabIndex = 4;
+      this.BandwidthNumericUpDown.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.BandwidthNumericUpDown.ValueChanged += new System.EventHandler(this.BandwidthNumericUpDown_ValueChanged);
+      // 
       // HistogramControl
       // 
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.BandwidthNumericUpDown);
       this.Controls.Add(this.exactCheckBox);
       this.Controls.Add(this.label1);
@@ -134,4 +172,5 @@
       ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
       ((System.ComponentModel.ISupportInitialize)(this.binsNumericUpDown)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.BandwidthNumericUpDown)).EndInit();
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -145,4 +184,6 @@
     private System.Windows.Forms.Label label1;
     private System.Windows.Forms.CheckBox exactCheckBox;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.NumericUpDown BandwidthNumericUpDown;
   }
 }
Index: /trunk/sources/HeuristicLab.Analysis.Views/3.3/HistogramControl.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis.Views/3.3/HistogramControl.cs	(revision 12138)
+++ /trunk/sources/HeuristicLab.Analysis.Views/3.3/HistogramControl.cs	(revision 12139)
@@ -33,4 +33,6 @@
 
     protected Dictionary<string, List<double>> points;
+    private bool suppressUpdate;
+
     public int NumberOfBins {
       get { return (int)binsNumericUpDown.Value; }
@@ -123,7 +125,7 @@
     }
 
-    protected void UpdateHistogram() {
+    protected void UpdateHistogram(double bandwith = double.NaN) {
       if (InvokeRequired) {
-        Invoke((Action)UpdateHistogram, null);
+        Invoke((Action<double>)UpdateHistogram, bandwith);
         return;
       }
@@ -164,5 +166,5 @@
         histogramSeries["PointWidth"] = "1";
 
-        CalculateDensity(histogramSeries, point.Value);
+        CalculateDensity(histogramSeries, point.Value, bandwith);
 
         overallMax = Math.Max(overallMax, maxValue);
@@ -184,7 +186,8 @@
     }
 
-    protected void CalculateDensity(Series series, List<double> row) {
+    protected void CalculateDensity(Series series, List<double> row, double bandwidth = double.NaN) {
       string densitySeriesName = "Density " + series.Name;
       double stepWidth = series.Points[1].XValue - series.Points[0].XValue;
+      var rowArray = row.ToArray();
 
       if (chart.Series.Any(x => x.Name == densitySeriesName)) {
@@ -193,5 +196,10 @@
       }
 
-      var density = NormalDistribution.Density(row.ToArray(), row.Count, stepWidth);
+      if (double.IsNaN(bandwidth)) {
+        bandwidth = KernelDensityEstimator.EstimateBandwidth(rowArray);
+        suppressUpdate = true;
+        BandwidthNumericUpDown.Value = (decimal)bandwidth;
+      }
+      var density = KernelDensityEstimator.Density(rowArray, rowArray.Length, stepWidth, bandwidth);
 
       Series newSeries = new Series(densitySeriesName);
@@ -225,4 +233,11 @@
       UpdateHistogram();
     }
+
+    private void BandwidthNumericUpDown_ValueChanged(object sender, EventArgs e) {
+      if (!suppressUpdate) {
+        UpdateHistogram(decimal.ToDouble(BandwidthNumericUpDown.Value));
+      }
+      suppressUpdate = false;
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 12138)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 12139)
@@ -167,5 +167,5 @@
     <Compile Include="Statistics\Fitting\LinearLeastSquaresFitting.cs" />
     <Compile Include="Statistics\Fitting\LogFitting.cs" />
-    <Compile Include="Statistics\NormalDistribution.cs" />
+    <Compile Include="Statistics\KernelDensityEstimator.cs" />
     <Compile Include="Statistics\PairwiseTest.cs" />
     <Compile Include="Statistics\SampleSizeDetermination.cs" />
Index: /trunk/sources/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs	(revision 12139)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs	(revision 12139)
@@ -0,0 +1,69 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class KernelDensityEstimator {
+    public static double[] Density(double[] x, double mean, double stdDev) {
+      return x.Select(xi => Density(xi, mean, stdDev)).ToArray();
+    }
+
+    public static double Density(double x, double mean, double stdDev) {
+      return (1.0 / (stdDev * Math.Sqrt(2.0 * Math.PI))) *
+                  Math.Exp(-((Math.Pow(x - mean, 2.0)) /
+                             (2.0 * Math.Pow(stdDev, 2.0))));
+    }
+
+    // the scale (sigma) of the kernel is a parameter
+    public static List<Tuple<double, double>> Density(double[] x, int nrOfPoints, double stepWidth, double sigma = 1.0) {
+      // calculate grid for which to estimate the density
+      double[] newX = new double[nrOfPoints];
+      double margin = stepWidth * 2;
+
+      double dataMin = x.Min() - margin;
+      double dataMax = x.Max() + margin;
+      double diff = (dataMax - dataMin) / nrOfPoints;
+      double cur = dataMin;
+      newX[0] = cur;
+      for (int i = 1; i < nrOfPoints; i++) {
+        cur += diff;
+        newX[i] = cur;
+      }
+
+      // for each of the points for which we want to calculate the density
+      // we sum up all the densities of the observed points assuming they are at the center of a normal distribution
+      var y = from xi in newX
+              select (from obsX in x
+                      select Density(xi, obsX, sigma)).Sum();
+
+      return newX.Zip(y, Tuple.Create).ToList();
+    }
+
+    //Silverman's rule of thumb for bandwidth estimation (sigma)
+    public static double EstimateBandwidth(double[] x) {
+      return 1.06 * x.StandardDeviation() * Math.Pow(x.Length, -0.2);
+    }
+  }
+}
Index: unk/sources/HeuristicLab.Analysis/3.3/Statistics/NormalDistribution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/Statistics/NormalDistribution.cs	(revision 12138)
+++ 	(revision )
@@ -1,65 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 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;
-
-namespace HeuristicLab.Analysis.Statistics {
-  public static class NormalDistribution {
-    public static double[] Density(double[] x, double mean, double stdDev) {
-      return x.Select(xi => Density(xi, mean, stdDev)).ToArray();
-    }
-
-    public static double Density(double x, double mean, double stdDev) {
-      return (1.0 / (stdDev * Math.Sqrt(2.0 * Math.PI))) *
-                  Math.Exp(-((Math.Pow(x - mean, 2.0)) /
-                             (2.0 * Math.Pow(stdDev, 2.0))));
-    }
-
-
-    // the scale (sigma) of the kernel is a parameter
-    public static List<Tuple<double, double>> Density(double[] x, int nrOfPoints, double stepWidth, double sigma = 1.0) {
-      // calculate grid for which to estimate the density
-      double[] newX = new double[nrOfPoints];
-      double margin = stepWidth * 2;
-
-      double dataMin = x.Min() - margin;
-      double dataMax = x.Max() + margin;
-      double diff = (dataMax - dataMin) / nrOfPoints;
-      double cur = dataMin;
-      newX[0] = cur;
-      for (int i = 1; i < nrOfPoints; i++) {
-        cur += diff;
-        newX[i] = cur;
-      }
-
-      // for each of the points for which we want to calculate the density
-      // we sum up all the densities of the observed points assuming they are at the center of a normal distribution
-      var y = from xi in newX
-              select (from obsX in x
-                      select Density(xi, obsX, sigma)).Sum();
-
-      return newX.Zip(y, Tuple.Create).ToList();
-    }
-  }
-}
