changeset 33595:e8e951bcf701

hist.m: Avoid error when Y value range is very small (bug #65714). * hist.m: Add check for the distance between max and min Y value when calculating the bin locations. If distance is less than 20*eps, use calculation for distance = 0 to avoid error where X value separation is smaller than eps and appear non-unique. Add BISTs to check for no error with small Y values with and without a specified number of bins. * NEWS.9.md: Addd note about fix to hist.m line under Improvements and Fixes.
author Nicholas R. Jankowski <jankowski.nicholas@gmail.com>
date Fri, 17 May 2024 16:49:20 -0400
parents 2104a33b7e83
children 96a203bc7e17 1a479e04f2a6
files etc/NEWS.9.md scripts/plot/draw/hist.m
diffstat 2 files changed, 20 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS.9.md	Fri May 17 13:44:02 2024 -0700
+++ b/etc/NEWS.9.md	Fri May 17 16:49:20 2024 -0400
@@ -6,7 +6,7 @@
 ### Improvements and fixes
 
 - `hist.m`: Add input validation for `Y` restricting it to 2-D array
-  (bug #65478).
+  (bug #65478).  Avoid error when `Y` value range is very small (bug #65714).
 - `cross.m`: Add input validation for `dim` restricting it to a numeric
   integer valued scalar (bug #65544, bug #65527).
 - `getframe.m`: Respect pixel ratio (high DPI) of screen with figure
--- a/scripts/plot/draw/hist.m	Fri May 17 13:44:02 2024 -0700
+++ b/scripts/plot/draw/hist.m	Fri May 17 16:49:20 2024 -0400
@@ -127,8 +127,9 @@
   if (nargin == 1 || ischar (varargin{iarg}))
     n = 10;
     ## Use integer range values and perform division last to preserve
-    ## accuracy.
-    if (min_val != max_val)
+    ## accuracy.  If max - min is less than 20*eps, treat as if min = max to
+    ## avoid bug #65714 error.
+    if (min_val != max_val && diff ([min_val, max_val]) > 20 * eps)
       x = 1:2:2*n;
       x = ((max_val - min_val) * x + 2*n*min_val) / (2*n);
     else
@@ -153,8 +154,9 @@
         error ("hist: number of bins NBINS must be positive");
       endif
       ## Use integer range values and perform division last to preserve
-      ## accuracy.
-      if (min_val != max_val)
+      ## accuracy.  If max - min is less than 20*eps, treat as if min = max
+      ## to avoid bug #65714 error.
+      if (min_val != max_val && diff ([min_val, max_val]) > 20 * eps)
         x = 1:2:2*n;
         x = ((max_val - min_val) * x + 2*n*min_val) / (2*n);
       else
@@ -429,6 +431,19 @@
 %! [nb, xb] = hist (b, 30);
 %! assert ({na, xa}, {nb, xb});
 
+%!test <*65714> # Avoid error if diff(y) is very small.
+%! a = [1, 1+eps, 1+ 15*eps];
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   hax = axes ("parent", hf);
+%!   hist (hax, a);
+%!   hp = get (hax, "children");
+%!   assert (max (get (hp, "ydata")(:)), 3);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+
 ## Test input validation
 %!error <Invalid call> hist ()
 %!error <Y must be real-valued> hist (2+i)