Mercurial > octave
changeset 33555:a8346c5f6997
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.
author | Arun Giridhar <arungiridhar@gmail.com> |
---|---|
date | Thu, 09 May 2024 18:13:54 -0400 |
parents | 4495e4a23aa6 |
children | 4b0987b80bb7 |
files | libinterp/corefcn/data.cc liboctave/array/Array-base.cc |
diffstat | 2 files changed, 22 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- 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 <Invalid call> sort () %!error <Invalid call> sort (1, 2, 3, 4) %!error <MODE must be either "ascend" or "descend"> sort (1, "foobar") %!error <DIM must be a positive scalar integer> sort (1, [1 2 3]) +%!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], -inf) +%!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], 0) +%!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], 1+i) %!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], 1.234) %!error <DIM must be a positive scalar integer> sort ([1 2; 3 4], nan) %!error <DIM argument must precede MODE argument> sort (1, "ascend", 1)
--- 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<T, Alloc>::sort (Array<octave_idx_type>& 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<octave_idx_type> (dv); + + if (numel () < 1 || dim >= ndims ()) + return *this; + Array<T, Alloc> m (dims ()); - const dim_vector& dv = m.dims (); - - if (m.numel () < 1) - { - sidx = Array<octave_idx_type> (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<T> lsort; - sidx = Array<octave_idx_type> (dv); octave_idx_type *vi = sidx.rwdata (); if (mode != UNSORTED)