Mercurial > octave-nkf
changeset 17662:0b7f5c56f853
Allow randperm to work with bigger inputs (bug #39378)
* rand.cc (Frandperm): Remove restriction on maximum size of m. Wrap
the allocation of idx in a try-catch block. Allocate a smaller idx
in the catch block. Add a test.
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Tue, 15 Oct 2013 14:48:48 -0400 |
parents | 1978a6c76aa9 |
children | 7975d75f933c |
files | libinterp/corefcn/rand.cc |
diffstat | 1 files changed, 18 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/rand.cc Tue Oct 15 11:09:07 2013 -0700 +++ b/libinterp/corefcn/rand.cc Tue Oct 15 14:48:48 2013 -0400 @@ -1157,7 +1157,7 @@ // Quick and dirty heuristic to decide if we allocate or not the // whole vector for tracking the truncated shuffle. - bool short_shuffle = m < n/5 && m < 1e5; + bool short_shuffle = m < n/5; if (! error_state) { @@ -1166,7 +1166,20 @@ double *rvec = r.fortran_vec (); octave_idx_type idx_len = short_shuffle ? m : n; - Array<octave_idx_type> idx (dim_vector (1, idx_len)); + Array<octave_idx_type> idx; + try + { + idx = Array<octave_idx_type> (dim_vector (1, idx_len)); + } + catch(std::bad_alloc) + { + // Looks like n is too big and short_shuffle is false. + // Let's try again, but this time with the alternative. + idx_len = m; + short_shuffle = true; + idx = Array<octave_idx_type> (dim_vector (1, idx_len)); + } + octave_idx_type *ivec = idx.fortran_vec (); for (octave_idx_type i = 0; i < idx_len; i++) @@ -1231,6 +1244,9 @@ %!assert (sort (randperm (20)), 1:20) %!assert (length (randperm (20,10)), 10) +## Test biggish N (bug #39378) +%!assert (length (randperm(30000^2, 100000)), 100000); + %!test %! rand ("seed", 0); %! for i = 1:100