changeset 14688:42edbe6f6a8d stable

Fix bad two-arg call of randperm (bug #36535) * rand.cc (Frandperm): Rewrite algorithm for short_shuffle. Add another test.
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Fri, 25 May 2012 11:24:02 -0400
parents 847ed7f603cf
children 551566201318
files src/DLD-FUNCTIONS/rand.cc
diffstat 1 files changed, 18 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/DLD-FUNCTIONS/rand.cc	Thu May 24 15:36:06 2012 -0400
+++ b/src/DLD-FUNCTIONS/rand.cc	Fri May 25 11:24:02 2012 -0400
@@ -1086,14 +1086,19 @@
                   octave_idx_type k = i +
                     gnulib::floor (rvec[i] * (n - i));
 
-                  if (map.find(k) == map.end())
+                  //For shuffling first m entries, no need to use extra
+                  //storage
+                  if (k < m)
                     {
-                      map[k] = ivec[i];
-                      ivec[i] = k;
+                      std::swap (ivec[i], ivec[k]);
                     }
                   else
-                    std::swap (ivec[i], map[k]);
+                    {
+                      if (map.find (k) == map.end ())
+                        map[k] = k;
 
+                      std::swap (ivec[i], map[k]);
+                    }
                 }
             }
           else
@@ -1126,6 +1131,13 @@
 }
 
 /*
-%!assert(sort (randperm (20)),1:20)
-%!assert(length (randperm (20,10)), 10)
+%!assert (sort (randperm (20)), 1:20)
+%!assert (length (randperm (20,10)), 10)
+
+%!test
+%! rand ("seed", 0);
+%! for i = 1:100
+%!   p = randperm (305, 30);
+%!   assert (length (unique (p)), 30);
+%! endfor
 */