changeset 8971:967a692ddfe2

fix range arithmetics
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 13 Mar 2009 12:18:50 +0100
parents b37a6c27c23f
children 5fa53d1b6247
files liboctave/ChangeLog liboctave/Range.cc liboctave/Range.h src/ChangeLog src/ov-range.cc src/ov-range.h
diffstat 6 files changed, 70 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Fri Mar 13 12:18:45 2009 +0100
+++ b/liboctave/ChangeLog	Fri Mar 13 12:18:50 2009 +0100
@@ -1,3 +1,10 @@
+2009-03-13  Jaroslav Hajek  <highegg@gmail.com>
+
+	* Range.h (Range::Range (double, double, octave_idx_type)): Remove
+	constructor body.
+	* Range.cc: Move it here. Check for invalid range op results.
+	(all operators): Validate cache for invalid range op results.
+
 2009-03-10  Jason Riedy  <jason@acm.org>
 
 	* sparse-base-lu.cc (Pr_mat): New member function.  Return the row
--- a/liboctave/Range.cc	Fri Mar 13 12:18:45 2009 +0100
+++ b/liboctave/Range.cc	Fri Mar 13 12:18:50 2009 +0100
@@ -36,6 +36,14 @@
 #include "lo-math.h"
 #include "lo-utils.h"
 
+Range::Range (double b, double i, octave_idx_type n)
+  : rng_base (b), rng_limit (b + n * i), rng_inc (i), 
+  rng_nelem (n), cache ()
+{
+  if (! xfinite (b) || ! xfinite (i))
+    rng_nelem = -2;
+}
+
 bool
 Range::all_elements_are_ints (void) const
 {
@@ -51,7 +59,7 @@
 Matrix
 Range::matrix_value (void) const
 {
-  if (rng_nelem > 0 && cache.rows () == 0)
+  if (rng_nelem > 0 && cache.nelem () == 0)
     {
       cache.resize (1, rng_nelem);
       double b = rng_base;
@@ -181,35 +189,7 @@
 Matrix 
 Range::diag (octave_idx_type k) const
 {
-  octave_idx_type nnr = 1;
-  octave_idx_type nnc = nelem ();
-  Matrix d;
-
-  if  (nnr != 0)
-    {
-      octave_idx_type roff = 0;
-      octave_idx_type coff = 0;
-      if (k > 0)
-	{
-	  roff = 0;
-	  coff = k;
-	}
-      else if (k < 0)
-	{
-	  roff = -k;
-	  coff = 0;
-	}
-
-      // Force cached matrix to be created
-      matrix_value ();
-
-      octave_idx_type n = nnc + std::abs (k);
-      d = Matrix (n, n, Matrix::resize_fill_value ());
-      for (octave_idx_type i = 0; i < nnc; i++)
-	d.xelem (i+roff, i+coff) = cache.xelem (i);
-    }
-
-  return d;
+  return matrix_value ().diag (k);
 }
 
 Range
@@ -305,32 +285,56 @@
 
 Range operator + (double x, const Range& r)
 {
-  return Range (x + r.base (), r.inc (), r.nelem ());
+  Range result (x + r.base (), r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = x + r.matrix_value ();
+
+  return result;
 }
 
 Range operator + (const Range& r, double x)
 {
-  return Range (r.base () + x, r.inc (), r.nelem ());
+  Range result (r.base () + x, r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = r.matrix_value () + x;
+
+  return result;
 }
 
 Range operator - (double x, const Range& r)
 {
-  return Range (x - r.base (), -r.inc (), r.nelem ());
+  Range result (x - r.base (), -r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = x - r.matrix_value ();
+
+  return result;
 }
 
 Range operator - (const Range& r, double x)
 {
-  return Range (r.base () - x, r.inc (), r.nelem ());
+  Range result (r.base () - x, r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = r.matrix_value () - x;
+
+  return result;
 }
 
 Range operator * (double x, const Range& r)
 {
-  return Range (x * r.base (), x * r.inc (), r.nelem ());
+  Range result (x * r.base (), x * r.inc (), r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = x * r.matrix_value ();
+
+  return result;
 }
 
 Range operator * (const Range& r, double x)
 {
-  return Range (r.base () * x, r.inc () * x, r.nelem ());
+  Range result (r.base () * x, r.inc () * x, r.nelem ());
+  if (result.rng_nelem < 0)
+    result.cache = r.matrix_value () * x;
+
+  return result;
 }
 
 
--- a/liboctave/Range.h	Fri Mar 13 12:18:45 2009 +0100
+++ b/liboctave/Range.h	Fri Mar 13 12:18:50 2009 +0100
@@ -40,7 +40,7 @@
 
   Range (const Range& r)
     : rng_base (r.rng_base), rng_limit (r.rng_limit), rng_inc (r.rng_inc),
-      rng_nelem (r.rng_nelem), cache () { }
+      rng_nelem (r.rng_nelem), cache (r.cache) { }
 
   Range (double b, double l)
     : rng_base (b), rng_limit (l), rng_inc (1),
@@ -51,9 +51,7 @@
       rng_nelem (nelem_internal ()), cache () { }
 
   // For operators' usage (to preserve element count).
-  Range (double b, double i, octave_idx_type n)
-    : rng_base (b), rng_limit (b + n * i), rng_inc (i), 
-      rng_nelem (n), cache () { }
+  Range (double b, double i, octave_idx_type n);
 
   double base (void) const { return rng_base; }
   double limit (void) const { return rng_limit; }
@@ -109,6 +107,14 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const Range& r);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, Range& r);
 
+  friend OCTAVE_API Range operator - (const Range& r);
+  friend OCTAVE_API Range operator + (double x, const Range& r);
+  friend OCTAVE_API Range operator + (const Range& r, double x);
+  friend OCTAVE_API Range operator - (double x, const Range& r);
+  friend OCTAVE_API Range operator - (const Range& r, double x);
+  friend OCTAVE_API Range operator * (double x, const Range& r);
+  friend OCTAVE_API Range operator * (const Range& r, double x);
+
   void print_range (void);
 
  private:
@@ -124,6 +130,7 @@
   octave_idx_type nelem_internal (void) const;
 
   void clear_cache (void) const { cache.resize (0, 0); }
+
 };
 
 extern OCTAVE_API Range operator - (const Range& r);
--- a/src/ChangeLog	Fri Mar 13 12:18:45 2009 +0100
+++ b/src/ChangeLog	Fri Mar 13 12:18:50 2009 +0100
@@ -1,3 +1,10 @@
+2009-03-13  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-range.h (octave_range::octave_range (const Range&)): Allow
+	constructing from invalid range op result.
+	* ov-range.cc (octave_range::try_narrowing_conversion): Validate
+	invalid range op results.
+
 2009-03-10  Jason Riedy  <jason@acm.org>
 
 	* DLD-FUNCTIONS/lu.cc (lu): Call fact.Pr_mat () and fact.Pc_mat ()
--- a/src/ov-range.cc	Fri Mar 13 12:18:45 2009 +0100
+++ b/src/ov-range.cc	Fri Mar 13 12:18:50 2009 +0100
@@ -77,6 +77,10 @@
       retval = new octave_matrix (Matrix (1, 0));
       break;
 
+    case -2:
+      retval = new octave_matrix (range.matrix_value ());
+      break;
+
     default:
       break;
     }
--- a/src/ov-range.h	Fri Mar 13 12:18:45 2009 +0100
+++ b/src/ov-range.h	Fri Mar 13 12:18:50 2009 +0100
@@ -68,7 +68,7 @@
   octave_range (const Range& r)
     : octave_base_value (), range (r)
       {
-	if (range.nelem () < 0)
+	if (range.nelem () < 0 && range.nelem () != -2)
 	  ::error ("invalid range");
       }