# HG changeset patch # User Jaroslav Hajek # Date 1274361034 -7200 # Node ID 8645b7087859e741eb3ef9dd0a69ae49ddc82cb1 # Parent 45b72e631cb52231a73a6a12583b3f50360b7587 abstract scalar index checking off Array (prep for struct optimizations) diff -r 45b72e631cb5 -r 8645b7087859 liboctave/Array-util.cc --- a/liboctave/Array-util.cc Thu May 20 07:27:45 2010 +0200 +++ b/liboctave/Array-util.cc Thu May 20 15:10:34 2010 +0200 @@ -174,29 +174,60 @@ return retval; } -octave_idx_type +octave_idx_type +compute_index (octave_idx_type n, const dim_vector& dims) +{ + if (n < 0) + gripe_invalid_index (); + if (n >= dims.numel ()) + gripe_index_out_of_range (1, 1, n+1, dims.numel ()); + + return n; +} + +octave_idx_type +compute_index (octave_idx_type i, octave_idx_type j, const dim_vector& dims) +{ + if (i < 0 || j < 0) + gripe_invalid_index (); + if (i >= dims(0)) + gripe_index_out_of_range (2, 1, i+1, dims(0)); + if (j >= dims.numel (1)) + gripe_index_out_of_range (2, 2, j+1, dims.numel (1)); + + return j*dims(0) + i; +} + +octave_idx_type +compute_index (octave_idx_type i, octave_idx_type j, octave_idx_type k, + const dim_vector& dims) +{ + if (i < 0 || j < 0 || k < 0) + gripe_invalid_index (); + if (i >= dims(0)) + gripe_index_out_of_range (3, 1, i+1, dims(0)); + if (j >= dims(1)) + gripe_index_out_of_range (3, 2, j+1, dims(1)); + if (k >= dims.numel (2)) + gripe_index_out_of_range (3, 3, k+1, dims.numel (2)); + + return (k*dims(1) + j)*dims(0) + i; +} + +octave_idx_type compute_index (const Array& ra_idx, const dim_vector& dims) { - octave_idx_type retval = -1; - - int n = dims.length (); - - if (n > 0 && n == ra_idx.length ()) + int nd = ra_idx.length (); + const dim_vector dv = dims.redim (nd); + for (int d = 0; d < nd; d++) { - retval = ra_idx(--n); + if (ra_idx(d) < 0) + gripe_invalid_index (); + if (ra_idx(d) >= dv(d)) + gripe_index_out_of_range (nd, d+1, ra_idx(d)+1, dv(d)); + } - while (--n >= 0) - { - retval *= dims(n); - - retval += ra_idx(n); - } - } - else - (*current_liboctave_error_handler) - ("ArrayN::compute_index: invalid ra_idxing operation"); - - return retval; + return dv.compute_index (ra_idx.data ()); } Array diff -r 45b72e631cb5 -r 8645b7087859 liboctave/Array-util.h --- a/liboctave/Array-util.h Thu May 20 07:27:45 2010 +0200 +++ b/liboctave/Array-util.h Thu May 20 15:10:34 2010 +0200 @@ -47,7 +47,20 @@ extern OCTAVE_API bool any_ones (const Array& arr); -extern OCTAVE_API octave_idx_type compute_index (const Array& ra_idx, const dim_vector& dims); +// These four compute a linear index for given dimensions, throwing +// exceptions on invalid indices. +extern OCTAVE_API octave_idx_type +compute_index (octave_idx_type n, const dim_vector& dims); + +extern OCTAVE_API octave_idx_type +compute_index (octave_idx_type i, octave_idx_type j, const dim_vector& dims); + +extern OCTAVE_API octave_idx_type +compute_index (octave_idx_type i, octave_idx_type j, octave_idx_type k, + const dim_vector& dims); + +extern OCTAVE_API octave_idx_type +compute_index (const Array& ra_idx, const dim_vector& dims); extern OCTAVE_API Array conv_to_int_array (const Array& a); diff -r 45b72e631cb5 -r 8645b7087859 liboctave/Array.cc --- a/liboctave/Array.cc Thu May 20 07:27:45 2010 +0200 +++ b/liboctave/Array.cc Thu May 20 15:10:34 2010 +0200 @@ -187,28 +187,30 @@ template octave_idx_type +Array::compute_index (octave_idx_type i, octave_idx_type j) const +{ + return ::compute_index (i, j, dimensions); +} + +template +octave_idx_type +Array::compute_index (octave_idx_type i, octave_idx_type j, octave_idx_type k) const +{ + return ::compute_index (i, j, k, dimensions); +} + +template +octave_idx_type Array::compute_index (const Array& ra_idx) const { - octave_idx_type retval = 0; - - int n = dimensions.length (), ni = ra_idx.length (); - - while (ni > n) - retval += ra_idx(--ni); - - while (ni > 0) - { - retval *= dimensions(--ni); - retval += ra_idx(ni); - } - - return retval; + return ::compute_index (ra_idx, dimensions); } template T& Array::checkelem (octave_idx_type n) { + // Do checks directly to avoid recomputing slice_len. if (n < 0) gripe_invalid_index (); if (n >= slice_len) @@ -221,53 +223,28 @@ T& Array::checkelem (octave_idx_type i, octave_idx_type j) { - if (i < 0 || j < 0) - gripe_invalid_index (); - if (i >= dim1 ()) - gripe_index_out_of_range (2, 1, i+1, dim1 ()); - if (j >= dimensions.numel (1)) - gripe_index_out_of_range (2, 2, j+1, dimensions.numel (1)); - - return elem (i, j); + return elem (compute_index (i, j)); } template T& Array::checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) { - if (i < 0 || j < 0 || k < 0) - gripe_invalid_index (); - if (i >= dim1 ()) - gripe_index_out_of_range (3, 1, i+1, dim1 ()); - if (j >= dim2 ()) - gripe_index_out_of_range (3, 2, j+1, dim2 ()); - if (k >= dimensions.numel (2)) - gripe_index_out_of_range (3, 3, k+1, dimensions.numel (2)); - - return elem (i, j, k); + return elem (compute_index (i, j, k)); } template T& Array::checkelem (const Array& ra_idx) { - int nd = ra_idx.length (); - const dim_vector dv = dimensions.redim (nd); - for (int d = 0; d < nd; d++) - { - if (ra_idx(d) < 0) - gripe_invalid_index (); - if (ra_idx(d) >= dv(d)) - gripe_index_out_of_range (nd, d+1, ra_idx(d)+1, dv(d)); - } - - return elem (ra_idx); + return elem (compute_index (ra_idx)); } template typename Array::crefT Array::checkelem (octave_idx_type n) const { + // Do checks directly to avoid recomputing slice_len. if (n < 0) gripe_invalid_index (); if (n >= slice_len) @@ -280,47 +257,21 @@ typename Array::crefT Array::checkelem (octave_idx_type i, octave_idx_type j) const { - if (i < 0 || j < 0) - gripe_invalid_index (); - if (i >= dim1 ()) - gripe_index_out_of_range (2, 1, i+1, dim1 ()); - if (j >= dimensions.numel (1)) - gripe_index_out_of_range (2, 2, j+1, dimensions.numel (1)); - - return elem (i, j); + return elem (compute_index (i, j)); } template typename Array::crefT Array::checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { - if (i < 0 || j < 0 || k < 0) - gripe_invalid_index (); - if (i >= dim1 ()) - gripe_index_out_of_range (3, 1, i+1, dim1 ()); - if (j >= dim2 ()) - gripe_index_out_of_range (3, 2, j+1, dim2 ()); - if (k >= dimensions.numel (2)) - gripe_index_out_of_range (3, 3, k+1, dimensions.numel (2)); - - return elem (i, j, k); + return elem (compute_index (i, j, k)); } template typename Array::crefT Array::checkelem (const Array& ra_idx) const { - int nd = ra_idx.length (); - const dim_vector dv = dimensions.redim (nd); - for (int d = 0; d < nd; d++) - { - if (ra_idx(d) < 0) - gripe_invalid_index (); - if (ra_idx(d) >= dv(d)) - gripe_index_out_of_range (nd, d+1, ra_idx(d)+1, dv(d)); - } - - return elem (ra_idx); + return elem (compute_index (ra_idx)); } template diff -r 45b72e631cb5 -r 8645b7087859 liboctave/Array.h --- a/liboctave/Array.h Thu May 20 07:27:45 2010 +0200 +++ b/liboctave/Array.h Thu May 20 15:10:34 2010 +0200 @@ -336,6 +336,9 @@ octave_idx_type compute_index (octave_idx_type i, octave_idx_type j, octave_idx_type k) const; octave_idx_type compute_index (const Array& ra_idx) const; + octave_idx_type compute_index_unchecked (const Array& ra_idx) const + { return dimensions.compute_index (ra_idx.data (), ra_idx.length ()); } + // No checking, even for multiple references, ever. T& xelem (octave_idx_type n) { return slice_data [n]; } @@ -350,10 +353,10 @@ { return xelem (i, dim2()*k+j); } T& xelem (const Array& ra_idx) - { return xelem (compute_index (ra_idx)); } + { return xelem (compute_index_unchecked (ra_idx)); } crefT xelem (const Array& ra_idx) const - { return xelem (compute_index (ra_idx)); } + { return xelem (compute_index_unchecked (ra_idx)); } // FIXME -- would be nice to fix this so that we don't // unnecessarily force a copy, but that is not so easy, and I see no @@ -375,7 +378,7 @@ T& elem (octave_idx_type i, octave_idx_type j, octave_idx_type k) { return elem (i, dim2()*k+j); } T& elem (const Array& ra_idx) - { return Array::elem (compute_index (ra_idx)); } + { return Array::elem (compute_index_unchecked (ra_idx)); } #if defined (BOUNDS_CHECKING) T& operator () (octave_idx_type n) { return checkelem (n); } @@ -401,7 +404,7 @@ crefT elem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const { return xelem (i, j, k); } crefT elem (const Array& ra_idx) const - { return Array::xelem (compute_index (ra_idx)); } + { return Array::xelem (compute_index_unchecked (ra_idx)); } #if defined (BOUNDS_CHECKING) crefT operator () (octave_idx_type n) const { return checkelem (n); } diff -r 45b72e631cb5 -r 8645b7087859 liboctave/ChangeLog --- a/liboctave/ChangeLog Thu May 20 07:27:45 2010 +0200 +++ b/liboctave/ChangeLog Thu May 20 15:10:34 2010 +0200 @@ -1,3 +1,19 @@ +2010-05-20 Jaroslav Hajek + + * dim-vector.h (dim_vector::compute_index (const octave_idx_type *, + int)): New method overload. + (dim_vector::compute_index, dim_vector::cum_compute_index, + dim_vector::increment_index): Add missing const qualifiers. + + * Array-util.cc (compute_index (..., const dim_vector&)): Rewrite, + add new overloads. Move code from Array::checkelem here. + * Array-util.h: Update decls. + * Array.h (Array::compute_index): Forward to the above. + (Array::compute_index_unchecked): New method. + (Array::elem, Array::xelem): Call it here. + + * Array.cc (Array::checkelem): Use compute_index where suitable. + 2010-05-19 Jaroslav Hajek * mx-inlines.cc (mx_inline_cumcount): Fix 2D version instantiation. diff -r 45b72e631cb5 -r 8645b7087859 liboctave/dim-vector.h --- a/liboctave/dim-vector.h Thu May 20 07:27:45 2010 +0200 +++ b/liboctave/dim-vector.h Thu May 20 15:10:34 2010 +0200 @@ -612,7 +612,7 @@ // Compute a linear index from an index tuple. - octave_idx_type compute_index (const octave_idx_type *idx) + octave_idx_type compute_index (const octave_idx_type *idx) const { octave_idx_type k = 0; for (int i = length () - 1; i >= 0; i--) @@ -621,11 +621,22 @@ return k; } + // Ditto, but the tuple may be incomplete (nidx < length ()). + + octave_idx_type compute_index (const octave_idx_type *idx, int nidx) const + { + octave_idx_type k = 0; + for (int i = nidx - 1; i >= 0; i--) + k = k * rep[i] + idx[i]; + + return k; + } + // Increment a multi-dimensional index tuple, optionally starting // from an offset position and return the index of the last index // position that was changed, or length () if just cycled over. - int increment_index (octave_idx_type *idx, int start = 0) + int increment_index (octave_idx_type *idx, int start = 0) const { int i; for (i = start; i < length (); i++) @@ -655,7 +666,7 @@ // Compute a linear index from an index tuple. Dimensions are // required to be cumulative. - octave_idx_type cum_compute_index (const octave_idx_type *idx) + octave_idx_type cum_compute_index (const octave_idx_type *idx) const { octave_idx_type k = idx[0];