changeset 24859:00ecff875f8a

Add nnz implementation for Range type (bug #53185). * Range.h (nnz): Declare prototype for new function. * Range.cc (nnz): New function. * ov-range.h (nnz): Declare nnz and rely on implementation in Range.cc. * data.cc (Fnnz): Added some basic BIST tests.
author maorshutman <maorus12@gmail.com>
date Fri, 09 Mar 2018 13:44:08 +0200
parents 8ce66fe46f18
children 6266e321ef22
files libinterp/corefcn/data.cc libinterp/octave-value/ov-range.h liboctave/array/Range.cc liboctave/array/Range.h
diffstat 4 files changed, 53 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/data.cc	Mon Mar 05 22:11:33 2018 -0600
+++ b/libinterp/corefcn/data.cc	Fri Mar 09 13:44:08 2018 +0200
@@ -2759,6 +2759,22 @@
   return ovl (args(0).nnz ());
 }
 
+/*
+%!assert (nnz (1:5), 5)
+%!assert (nnz (-5:-1), 5)
+%!assert (nnz (0:5), 5)
+%!assert (nnz (-5:0), 5)
+%!assert (nnz (-5:5), 10)
+%!assert (nnz (-2:1:2), 4)
+%!assert (nnz (-2+eps(2):1:2), 5)
+%!assert (nnz (-2-eps(2):1:2), 5)
+%!assert (nnz (-2:1+eps(1):2), 5)
+%!assert (nnz (-2:1-eps(1):2), 5)
+%!assert (nnz ([1:5] * 0), 0)
+%!assert (nnz ([-5:-1] * 0), 0)
+%!assert (nnz ([-1:1] * 0), 0)
+*/
+
 DEFUN (nzmax, args, ,
        doc: /* -*- texinfo -*-
 @deftypefn {} {@var{n} =} nzmax (@var{SM})
--- a/libinterp/octave-value/ov-range.h	Mon Mar 05 22:11:33 2018 -0600
+++ b/libinterp/octave-value/ov-range.h	Fri Mar 09 13:44:08 2018 +0200
@@ -111,6 +111,8 @@
     return dim_vector (n > 0, n);
   }
 
+  octave_idx_type nnz (void) const { return range.nnz (); }
+
   octave_value resize (const dim_vector& dv, bool fill = false) const;
 
   size_t byte_size (void) const { return 3 * sizeof (double); }
--- a/liboctave/array/Range.cc	Mon Mar 05 22:11:33 2018 -0600
+++ b/liboctave/array/Range.cc	Fri Mar 09 13:44:08 2018 +0200
@@ -47,6 +47,39 @@
           && (octave::math::nint_big (rng_inc) == rng_inc || rng_numel <= 1));
 }
 
+octave_idx_type
+Range::nnz (void) const
+{
+  octave_idx_type retval = 0;
+
+  if (! isempty ())
+    {
+      if ((rng_base > 0.0 && rng_limit > 0.0)
+          || (rng_base < 0.0 && rng_limit < 0.0))
+        {
+          // All elements have the same sign, hence there are no zeros.
+          retval = rng_numel;
+        }
+      else if (rng_inc != 0.0)
+        {
+          if (rng_base == 0.0 || rng_limit == 0.0)
+            retval = rng_numel - 1;
+          else if ((rng_base / rng_inc) != std::floor (rng_base / rng_inc))
+            retval = rng_numel;
+          else
+            retval = rng_numel - 1;
+        }
+      else
+        {
+          // All elements are equal (rng_inc = 0) but not positive or negative,
+          // therefore all elements are zero.
+          retval = 0;
+        }
+    }
+
+  return retval;
+}
+
 Matrix
 Range::matrix_value (void) const
 {
--- a/liboctave/array/Range.h	Mon Mar 05 22:11:33 2018 -0600
+++ b/liboctave/array/Range.h	Fri Mar 09 13:44:08 2018 +0200
@@ -118,6 +118,8 @@
   sortmode is_sorted (sortmode mode = ASCENDING) const
   { return issorted (mode); }
 
+  octave_idx_type nnz (void) const;
+
   // Support for single-index subscripting, without generating matrix cache.
 
   double checkelem (octave_idx_type i) const;