# HG changeset patch # User Jaroslav Hajek # Date 1236943130 -3600 # Node ID 967a692ddfe249db30f5ec6ff430795dbcfe9a57 # Parent b37a6c27c23f9d6185e853195bbda9226b4e1d34 fix range arithmetics diff -r b37a6c27c23f -r 967a692ddfe2 liboctave/ChangeLog --- 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 + + * 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 * sparse-base-lu.cc (Pr_mat): New member function. Return the row diff -r b37a6c27c23f -r 967a692ddfe2 liboctave/Range.cc --- 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; } diff -r b37a6c27c23f -r 967a692ddfe2 liboctave/Range.h --- 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); diff -r b37a6c27c23f -r 967a692ddfe2 src/ChangeLog --- 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 + + * 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 * DLD-FUNCTIONS/lu.cc (lu): Call fact.Pr_mat () and fact.Pc_mat () diff -r b37a6c27c23f -r 967a692ddfe2 src/ov-range.cc --- 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; } diff -r b37a6c27c23f -r 967a692ddfe2 src/ov-range.h --- 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"); }