# HG changeset patch # User Arun Giridhar # Date 1715292834 14400 # Node ID a8346c5f699738597778933813cf4c71fe1eef91 # Parent 4495e4a23aa6cae879acd7d39c00e98cd97b5f1a Fix 2-output form of sort() for dim > ndims() (bug #65712) Following fixes to allow `sort (A, dim)` for dim exceeding `ndims (A)`, including the case of dim = inf, this patch does the same for the 2-output calling form of sort(). * Array-base.cc: Create `sidx` early, rework early return conditions. * data.cc: Adapt the value of `dv(dim)` when dim exceeds the size of dv. Tweak input validation conditions to trap more conditions. Add BISTs. diff -r 4495e4a23aa6 -r a8346c5f6997 libinterp/corefcn/data.cc --- a/libinterp/corefcn/data.cc Wed May 08 14:58:32 2024 -0400 +++ b/libinterp/corefcn/data.cc Thu May 09 18:13:54 2024 -0400 @@ -7120,15 +7120,13 @@ } else { - // Forbid vector or array input - if (! args(1).is_scalar_type ()) + // Require dim to be positive real scalar. + if (! args(1).is_scalar_type () || args(1).iscomplex () + || args(1).double_value () <= 0) error ("sort: DIM must be a positive scalar integer"); // Forbid fractional value input, also nan input. dim = args(1).strict_int_value ("sort: DIM must be a positive scalar integer") - 1; - - if (dim < 0) - error ("sort: DIM must be a positive scalar integer"); } } @@ -7162,7 +7160,8 @@ // NOTE: Can not change this to ovl() call because arg.sort changes sidx // and objects are declared const in ovl prototype. retval(0) = arg.sort (sidx, dim, smode); - retval(1) = idx_vector (sidx, dv(dim)); // No checking, extent is known. + // Check for index dimension extent. Set to 1 for dimension >= ndims () + retval(1) = idx_vector (sidx, (dim < arg.ndims ()) ? dv(dim) : 1); } else retval = ovl (arg.sort (dim, smode)); @@ -7394,11 +7393,20 @@ %! A = [1 2; 3 4]; %! assert (sort (A, 100), A) %! assert (sort (A, inf), A) +%! [B, idx] = sort (A, 100); +%! assert (B, A); +%! assert (idx, ones (2)) +%! [B, idx] = sort (A, inf); +%! assert (B, A); +%! assert (idx, ones (2)) %!error sort () %!error sort (1, 2, 3, 4) %!error sort (1, "foobar") %!error sort (1, [1 2 3]) +%!error sort ([1 2; 3 4], -inf) +%!error sort ([1 2; 3 4], 0) +%!error sort ([1 2; 3 4], 1+i) %!error sort ([1 2; 3 4], 1.234) %!error sort ([1 2; 3 4], nan) %!error sort (1, "ascend", 1) diff -r 4495e4a23aa6 -r a8346c5f6997 liboctave/array/Array-base.cc --- a/liboctave/array/Array-base.cc Wed May 08 14:58:32 2024 -0400 +++ b/liboctave/array/Array-base.cc Thu May 09 18:13:54 2024 -0400 @@ -1922,19 +1922,18 @@ Array::sort (Array& sidx, int dim, sortmode mode) const { - if (dim < 0 || dim >= ndims ()) + if (dim < 0) (*current_liboctave_error_handler) ("sort: invalid dimension"); + const dim_vector& dv = dims (); + + sidx = Array (dv); + + if (numel () < 1 || dim >= ndims ()) + return *this; + Array m (dims ()); - const dim_vector& dv = m.dims (); - - if (m.numel () < 1) - { - sidx = Array (dv); - return m; - } - octave_idx_type ns = dv(dim); octave_idx_type iter = dv.numel () / ns; octave_idx_type stride = 1; @@ -1947,7 +1946,6 @@ octave_sort lsort; - sidx = Array (dv); octave_idx_type *vi = sidx.rwdata (); if (mode != UNSORTED)