Mercurial > hg > octave-nkf
changeset 16779:8fce0ed4894a
Specialize is_empty and numel methods for sparse matrices (debian bug #706376)
* ov-base.h (virtual bool is_empty (void) const) : Make method virtual
* ov-base-sparse.h (bool is_empty (void) const)) : Declare new method
(octave_idx_type numel (void) const): New method.
* ov-base-sparse.cc (template <class T> bool octave_base_sparse<T>:is_empty
(void) const)) : Define new method
* ov-bool-sparse.h (idx_vector index_vector (void) const): Start specialization
for sparse matrices
* lo-array-gripes.cc (void gripe_index_value (void)): Clarify error message
* data.cc : Add test to isempty
* idx-vector.cc (idx_vector::idx_vector_rep::idx_vector_rep (const
Sparse<bool>&) : Fix sparse indexing bug
* __sprand_impl__.m : Don't use randparm when there are more than sizemax() elements.
* sprand.m, sprandn.m : Add a test for large, low density matrices
author | David Bateman <dbateman@free.fr> |
---|---|
date | Thu, 20 Jun 2013 02:17:25 +0200 |
parents | e205f5ea826a |
children | 781916090eb1 |
files | libinterp/interpfcn/data.cc libinterp/octave-value/ov-base-sparse.cc libinterp/octave-value/ov-base-sparse.h libinterp/octave-value/ov-base.h libinterp/octave-value/ov-bool-sparse.h liboctave/array/idx-vector.cc liboctave/util/lo-array-gripes.cc scripts/sparse/private/__sprand_impl__.m scripts/sparse/sprand.m scripts/sparse/sprandn.m |
diffstat | 10 files changed, 65 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/interpfcn/data.cc +++ b/libinterp/interpfcn/data.cc @@ -3342,6 +3342,11 @@ return retval; } +/* +%% Debian bug #706376 +%!assert (isempty (speye(2^16)), false) +*/ + DEFUN (isnumeric, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} isnumeric (@var{x})\n\
--- a/libinterp/octave-value/ov-base-sparse.cc +++ b/libinterp/octave-value/ov-base-sparse.cc @@ -278,6 +278,15 @@ template <class T> bool +octave_base_sparse<T>::is_empty (void) const +{ + dim_vector dv = dims (); + + return (dv.any_zero ()); +} + +template <class T> +bool octave_base_sparse<T>::print_as_scalar (void) const { dim_vector dv = dims ();
--- a/libinterp/octave-value/ov-base-sparse.h +++ b/libinterp/octave-value/ov-base-sparse.h @@ -72,6 +72,8 @@ ~octave_base_sparse (void) { } + octave_idx_type numel (void) const { return dims ().safe_numel (); } + octave_idx_type nnz (void) const { return matrix.nnz (); } octave_idx_type nzmax (void) const { return matrix.nzmax (); } @@ -137,6 +139,8 @@ bool is_defined (void) const { return true; } + bool is_empty (void) const; + bool is_constant (void) const { return true; } bool is_true (void) const;
--- a/libinterp/octave-value/ov-base.h +++ b/libinterp/octave-value/ov-base.h @@ -331,7 +331,7 @@ virtual bool is_defined (void) const { return false; } - bool is_empty (void) const { return numel () == 0; } + virtual bool is_empty (void) const { return numel () == 0; } virtual bool is_cell (void) const { return false; }
--- a/libinterp/octave-value/ov-bool-sparse.h +++ b/libinterp/octave-value/ov-bool-sparse.h @@ -83,9 +83,9 @@ octave_base_value *try_narrowing_conversion (void); - // FIXME Adapt idx_vector to allow sparse logical indexing!! + // FIXME Adapt idx_vector to allow sparse logical indexing without overflow!! idx_vector index_vector (void) const - { return idx_vector (bool_array_value ()); } + { return idx_vector (matrix); } builtin_type_t builtin_type (void) const { return btyp_bool; }
--- a/liboctave/array/idx-vector.cc +++ b/liboctave/array/idx-vector.cc @@ -423,30 +423,27 @@ } idx_vector::idx_vector_rep::idx_vector_rep (const Sparse<bool>& bnda) - : data (0), len (0), ext (0), aowner (0), orig_dims () + : data (0), len (bnda.nnz ()), ext (0), aowner (0), orig_dims () { - for (octave_idx_type i = 0, l = bnda.nnz (); i < l; i++) - if (bnda.data (i)) len++; + const dim_vector dv = bnda.dims (); - dim_vector dv = bnda.dims (); - - orig_dims = ((dv.length () == 2 && dv(0) == 1) - ? dim_vector (1, len) : orig_dims = dim_vector (len, 1)); + if (! dv.all_zero ()) + orig_dims = ((dv.length () == 2 && dv(0) == 1) + ? dim_vector (1, len) : dim_vector (len, 1)); if (len != 0) { octave_idx_type *d = new octave_idx_type [len]; - octave_idx_type nnz = bnda.nnz (); + octave_idx_type k = 0; + octave_idx_type nc = bnda.cols (); + octave_idx_type nr = bnda.rows (); - octave_idx_type k = 0; - // FIXME: I hope this is OK, i.e. the element iterated this way are correctly ordered. - for (octave_idx_type i = 0; i < nnz; i++) - { + for (octave_idx_type j = 0; j < nc; j++) + for (octave_idx_type i = bnda.cidx(j); i < bnda.cidx(j+1); i++) if (bnda.data (i)) - d[k++] = bnda.cidx (i) + bnda.rows () * bnda.ridx (i); - } - + d[k++] = j * nr + bnda.ridx (i); + data = d; ext = d[k-1] + 1;
--- a/liboctave/util/lo-array-gripes.cc +++ b/liboctave/util/lo-array-gripes.cc @@ -130,7 +130,11 @@ const char *err_id = error_id_invalid_index; (*current_liboctave_error_with_id_handler) - (err_id, "subscript indices must be either positive integers or logicals"); +#ifdef USE_64_BIT_IDX_T + (err_id, "subscript indices must be either positive integers less than 2^63 or logicals"); +#else + (err_id, "subscript indices must be either positive integers less than 2^31 or logicals"); +#endif } // FIXME -- the following is a common error message to resize,
--- a/scripts/sparse/private/__sprand_impl__.m +++ b/scripts/sparse/private/__sprand_impl__.m @@ -55,9 +55,27 @@ mn = m*n; k = round (d*mn); - idx = randperm (mn, k); + if (mn > sizemax ()) + ## randperm will overflow, so use alternative methods + + idx = unique (fix (rand (min (k*1.01, k+10), 1) * mn)) + 1; - [i, j] = ind2sub ([m, n], idx); + ## idx contains random numbers in [1,mn] + ## generate 1% or 10 more random values than necessary in order to + ## reduce the probability that there are less than k distinct + ## values; maybe a better strategy could be used but I don't think + ## it's worth the price + + ## actual number of entries in S + k = min (length (idx), k); + j = floor ((idx(1:k) - 1) / m); + i = idx(1:k) - j * m; + else + idx = randperm (mn, k); + [i, j] = ind2sub ([m, n], idx); + endif + + S = sparse (i, j, randfun (k, 1), m, n); endfunction