diff liboctave/array/Range.cc @ 25812:fc74c8d2a584

Clean up liboctave Range implementation. * Range.h: Cleanup up spacing by removing some unnecessary blank lines. * Range.cc: Wrap comments to 80 characters. Add more comments to code. * Range.cc (matrix_value): Use xelem() for performance. * Range.cc (operator <<): Rename "num_elem" to "nel". * Range.cc (teq): Use std::abs() instead of fabs() (we're C++11 now!). * Range.cc (limit_internal): Rename "tmp_limit" to "new_limit". Don't bother checking if new limit is different from old limit before returning it. * range.tst: Add BIST tests for operators (+, -, *) on Ranges.
author Rik <rik@octave.org>
date Fri, 17 Aug 2018 14:49:10 -0700
parents dc47c9e48801
children 00f796120a6d
line wrap: on
line diff
--- a/liboctave/array/Range.cc	Fri Aug 17 14:12:48 2018 -0700
+++ b/liboctave/array/Range.cc	Fri Aug 17 14:49:10 2018 -0700
@@ -39,9 +39,9 @@
 bool
 Range::all_elements_are_ints (void) const
 {
-  // If the base and increment are ints, the final value in the range
-  // will also be an integer, even if the limit is not.  If there is one
-  // or fewer elements only the base needs to be an integer
+  // If the base and increment are ints, the final value in the range will also
+  // be an integer, even if the limit is not.  If there is one or fewer
+  // elements only the base needs to be an integer.
 
   return (! (octave::math::isnan (rng_base) || octave::math::isnan (rng_inc))
           && (octave::math::nint_big (rng_base) == rng_base || rng_numel < 1)
@@ -64,10 +64,13 @@
       else if (rng_inc != 0.0)
         {
           if (rng_base == 0.0 || rng_limit == 0.0)
+            // Exactly one zero at beginning or end of range.
             retval = rng_numel - 1;
           else if ((rng_base / rng_inc) != std::floor (rng_base / rng_inc))
+            // Range crosses negative/positive without hitting zero.
             retval = rng_numel;
           else
+            // Range crosses negative/positive and hits zero.
             retval = rng_numel - 1;
         }
       else
@@ -95,9 +98,9 @@
       double b = rng_base;
       double increment = rng_inc;
       for (octave_idx_type i = 1; i < rng_numel - 1; i++)
-        cache(i) = b + i * increment;
+        cache.xelem (i) = b + i * increment;
 
-      cache(rng_numel - 1) = rng_limit;
+      cache.xelem (rng_numel - 1) = rng_limit;
     }
 
   return cache;
@@ -106,8 +109,6 @@
 double
 Range::checkelem (octave_idx_type i) const
 {
-  // Ranges are row vectors.
-
   if (i < 0 || i >= rng_numel)
     octave::err_index_out_of_range (2, 2, i+1, rng_numel);
 
@@ -122,6 +123,7 @@
 double
 Range::checkelem (octave_idx_type i, octave_idx_type j) const
 {
+  // Ranges are *always* row vectors.
   if (i != 0)
     octave::err_index_out_of_range (1, 1, i+1, rng_numel);
 
@@ -284,7 +286,6 @@
 
   for (octave_idx_type i = 0; i < nel; i++, tmp += stp)
     psidx[i] = tmp;
-
 }
 
 Matrix
@@ -381,17 +382,17 @@
 {
   double b = a.base ();
   double increment = a.inc ();
-  octave_idx_type num_elem = a.numel ();
+  octave_idx_type nel = a.numel ();
 
-  if (num_elem > 1)
+  if (nel > 1)
     {
-      // First element must be the base *exactly* (-0).
+      // First element must be the base *exactly* (e.g., -0).
       os << b << ' ';
-      for (octave_idx_type i = 1; i < num_elem-1; i++)
+      for (octave_idx_type i = 1; i < nel-1; i++)
         os << b + i * increment << ' ';
     }
 
-  // Print out exactly the last element, rather than a calculated last element.
+  // Print out the last element exactly, rather than a calculated last element.
   os << a.rng_limit << "\n";
 
   return os;
@@ -409,7 +410,7 @@
       if (is)
         is >> a.rng_inc;
 
-      // Clip the rng_limit to the true limit and rebuild numel, clear cache
+      // Clip the rng_limit to the true limit, rebuild numel, clear cache
       a.set_limit (tmp_rng_limit);
     }
 
@@ -425,6 +426,9 @@
 Range operator + (double x, const Range& r)
 {
   Range result (x + r.base (), x + r.limit (), r.inc (), r.numel ());
+  // Check whether new range was constructed properly.  A non-finite
+  // value (Inf or NaN) requires that the output be of the same size
+  // as the original range with all values set to the non-finite value.
   if (result.rng_numel < 0)
     result.cache = x + r.matrix_value ();
 
@@ -542,10 +546,10 @@
 teq (double u, double v,
      double ct = 3.0 * std::numeric_limits<double>::epsilon ())
 {
-  double tu = fabs (u);
-  double tv = fabs (v);
+  double tu = std::abs (u);
+  double tv = std::abs (v);
 
-  return fabs (u - v) < ((tu > tv ? tu : tv) * ct);
+  return std::abs (u - v) < ((tu > tv ? tu : tv) * ct);
 }
 
 octave_idx_type
@@ -568,16 +572,14 @@
       octave_idx_type n_elt = (tmp > 0.0 ? static_cast<octave_idx_type> (tmp)
                                          : 0);
 
-      // If the final element that we would compute for the range is
-      // equal to the limit of the range, or is an adjacent floating
-      // point number, accept it.  Otherwise, try a range with one
-      // fewer element.  If that fails, try again with one more
-      // element.
+      // If the final element that we would compute for the range is equal to
+      // the limit of the range, or is an adjacent floating point number,
+      // accept it.  Otherwise, try a range with one fewer element.  If that
+      // fails, try again with one more element.
       //
-      // I'm not sure this is very good, but it seems to work better than
-      // just using tfloor as above.  For example, without it, the
-      // expression 1.8:0.05:1.9 fails to produce the expected result of
-      // [1.8, 1.85, 1.9].
+      // I'm not sure this is very good, but it seems to work better than just
+      // using tfloor as above.  For example, without it, the expression
+      // 1.8:0.05:1.9 fails to produce the expected result of [1.8, 1.85, 1.9].
 
       if (! teq (rng_base + (n_elt - 1) * rng_inc, rng_limit))
         {
@@ -597,18 +599,18 @@
 double
 Range::limit_internal (void) const
 {
-  double tmp_limit = rng_limit;
+  double new_limit = rng_limit;
 
   if (rng_inc > 0)
-    tmp_limit = max ();
+    new_limit = max ();
   else
-    tmp_limit = min ();
+    new_limit = min ();
 
-  // If result must be an integer then force the limit to be one.
+  // If result must be an integer then force the new_limit to be one.
   if (all_elements_are_ints ())
-    tmp_limit = std::round (tmp_limit);
+    new_limit = std::round (new_limit);
 
-  return (tmp_limit != rng_limit) ? tmp_limit : rng_limit;
+  return new_limit;
 }
 
 void