Improve the way in which histogram bin ranges are chosen 20120323030502/pspp
authorJohn Darrington <john@darrington.wattle.id.au>
Thu, 22 Mar 2012 21:00:01 +0000 (22:00 +0100)
committerJohn Darrington <john@darrington.wattle.id.au>
Thu, 22 Mar 2012 21:00:01 +0000 (22:00 +0100)
src/math/histogram.c
tests/language/stats/examine.at

index 89619bcca54555bf2c7358bb677d7fdf30f9d179..0b2369f63c7b6ecad3329d6c728e2ed5eebf7dcf 100644 (file)
@@ -60,22 +60,31 @@ histogram_create (double bin_width, double min, double max)
   int bins;
   struct histogram *h = xmalloc (sizeof *h);
   struct statistic *stat = &h->parent;
-  const short max_sign = max >= 0;
-  const short min_sign = min >= 0;
 
   double upper_limit, lower_limit;
 
   assert (max >= min);
 
-  lower_limit = trunc (2 * abs (min) / bin_width) - 1;
-  lower_limit *= bin_width / 2;
-  lower_limit *= min_sign;
+  if (max == min)
+     bin_width = 1;
 
-  upper_limit = trunc (2 * abs(max) / bin_width) + 1;
-  upper_limit *= bin_width / 2;
-  upper_limit *= max_sign;
+  lower_limit = floor (2 * min / bin_width) - 1;
+  upper_limit = floor (2 * max / bin_width) + 1;
   
-  bins = (upper_limit - lower_limit) / bin_width;
+  /* The range must be an even number of half bin_widths */
+  if ( (int)(upper_limit - lower_limit) % 2)
+    {
+      /* Extend the range at the end which gives the least unused space */
+      if (remainder (min, bin_width / 2.0) > remainder (max, bin_width / 2.0))
+       lower_limit --;
+      else
+       upper_limit ++;
+    }
+
+  bins = (upper_limit - lower_limit) / 2.0;
+
+  upper_limit *= bin_width / 2;
+  lower_limit *= bin_width / 2;  
 
   h->gsl_hist = gsl_histogram_alloc (bins);
 
index 64f6d7c573f84ae9c6aafb29517d461e1ea4e343..24005a0675b734abebc7e0e0bd03b9e373dc30fd 100644 (file)
@@ -519,6 +519,7 @@ END DATA
 EXAMINE
        quality 
        /STATISTICS descriptives 
+        /PLOT = histogram
        .
 ])
 AT_CHECK([pspp -o pspp.csv examine.sps])
@@ -639,4 +640,4 @@ x,Highest,1,threehundred,300.00
 ,,5,five        ,5.00
 ])
 
-AT_CLEANUP 
\ No newline at end of file
+AT_CLEANUP