Mercurial > hg > octave-nkf
diff src/data.cc @ 7433:402168152bb9
[project @ 2008-01-31 18:59:09 by dbateman]
author | dbateman |
---|---|
date | Thu, 31 Jan 2008 18:59:11 +0000 |
parents | 3fade00a6ac7 |
children | bd2bd04e68ca |
line wrap: on
line diff
--- a/src/data.cc +++ b/src/data.cc @@ -3305,6 +3305,300 @@ return retval; } +DEFUN (sort, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x})\n\ +@deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim})\n\ +@deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{mode})\n\ +@deftypefnx {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x}, @var{dim}, @var{mode})\n\ +Return a copy of @var{x} with the elements arranged in increasing\n\ +order. For matrices, @code{sort} orders the elements in each column.\n\ +\n\ +For example,\n\ +\n\ +@example\n\ +@group\n\ +sort ([1, 2; 2, 3; 3, 1])\n\ + @result{} 1 1\n\ + 2 2\n\ + 3 3\n\ +@end group\n\ +@end example\n\ +\n\ +The @code{sort} function may also be used to produce a matrix\n\ +containing the original row indices of the elements in the sorted\n\ +matrix. For example,\n\ +\n\ +@example\n\ +@group\n\ +[s, i] = sort ([1, 2; 2, 3; 3, 1])\n\ + @result{} s = 1 1\n\ + 2 2\n\ + 3 3\n\ + @result{} i = 1 3\n\ + 2 1\n\ + 3 2\n\ +@end group\n\ +@end example\n\ +\n\ +If the optional argument @var{dim} is given, then the matrix is sorted\n\ +along the dimension defined by @var{dim}. The optional argument @code{mode}\n\ +defines the order in which the values will be sorted. Valid values of\n\ +@code{mode} are `ascend' or `descend'.\n\ +\n\ +For equal elements, the indices are such that the equal elements are listed\n\ +in the order that appeared in the original list.\n\ +\n\ +The @code{sort} function may also be used to sort strings and cell arrays\n\ +of strings, in which case the dictionary order of the strings is used.\n\ +\n\ +The algorithm used in @code{sort} is optimized for the sorting of partially\n\ +ordered lists.\n\ +@end deftypefn") +{ + octave_value_list retval; + + int nargin = args.length (); + sortmode smode = ASCENDING; + + if (nargin < 1 || nargin > 3) + { + print_usage (); + return retval; + } + + bool return_idx = nargout > 1; + + octave_value arg = args(0); + + int dim = 0; + if (nargin > 1) + { + if (args(1).is_string ()) + { + std::string mode = args(1).string_value(); + if (mode == "ascend") + smode = ASCENDING; + else if (mode == "descend") + smode = DESCENDING; + else + { + error ("sort: mode must be either \"ascend\" or \"descend\""); + return retval; + } + } + else + dim = args(1).nint_value () - 1; + } + + if (nargin > 2) + { + if (args(1).is_string ()) + { + print_usage (); + return retval; + } + + if (! args(2).is_string ()) + { + error ("sort: mode must be a string"); + return retval; + } + std::string mode = args(2).string_value(); + if (mode == "ascend") + smode = ASCENDING; + else if (mode == "descend") + smode = DESCENDING; + else + { + error ("sort: mode must be either \"ascend\" or \"descend\""); + return retval; + } + } + + dim_vector dv = arg.dims (); + if (error_state) + { + gripe_wrong_type_arg ("sort", arg); + return retval; + } + if (nargin == 1 || args(1).is_string ()) + { + // Find first non singleton dimension + for (int i = 0; i < dv.length (); i++) + if (dv(i) > 1) + { + dim = i; + break; + } + } + else + { + if (dim < 0 || dim > dv.length () - 1) + { + error ("sort: dim must be a valid dimension"); + return retval; + } + } + + if (return_idx) + { + Array<octave_idx_type> sidx; + + retval (0) = arg.sort (sidx, dim, smode); + + octave_idx_type *ps = sidx.fortran_vec (); + NDArray midx (sidx.dims ()); + double *pm = midx.fortran_vec (); + + for (octave_idx_type i = 0; i < sidx.numel (); i++) + pm [i] = static_cast<double> + (ps [i] + static_cast<octave_idx_type> (1)); + + retval (1) = midx; + } + else + retval(0) = arg.sort (dim, smode); + + return retval; +} + +/* + +%% Double +%!assert (sort ([NaN, 1, -1, 2, Inf]), [-1, 1, 2, Inf, NaN]) +%!assert (sort ([NaN, 1, -1, 2, Inf], 1), [NaN, 1, -1, 2, Inf]) +%!assert (sort ([NaN, 1, -1, 2, Inf], 2), [-1, 1, 2, Inf, NaN]) +%!error (sort ([NaN, 1, -1, 2, Inf], 3)) +%!assert (sort ([NaN, 1, -1, 2, Inf], "ascend"), [-1, 1, 2, Inf, NaN]) +%!assert (sort ([NaN, 1, -1, 2, Inf], 2, "ascend"), [-1, 1, 2, Inf, NaN]) +%!assert (sort ([NaN, 1, -1, 2, Inf], "descend"), [NaN, Inf, 2, 1, -1]) +%!assert (sort ([NaN, 1, -1, 2, Inf], 2, "descend"), [NaN, Inf, 2, 1, -1]) +%!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4]), [3, 1, 6, 4; 8, 2, 7, 5]) +%!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4], 1), [3, 1, 6, 4; 8, 2, 7, 5]) +%!assert (sort ([3, 1, 7, 5; 8, 2, 6, 4], 2), [1, 3, 5, 7; 2, 4, 6, 8]) +%!assert (sort (1), 1) + +%!test +%! [v, i] = sort ([NaN, 1, -1, Inf, 1]); +%! assert (v, [-1, 1, 1, Inf, NaN]) +%! assert (i, [3, 2, 5, 4, 1]) + +%% Complex +%!assert (sort ([NaN, 1i, -1, 2, Inf]), [1i, -1, 2, Inf, NaN]) +%!assert (sort ([NaN, 1i, -1, 2, Inf], 1), [NaN, 1i, -1, 2, Inf]) +%!assert (sort ([NaN, 1i, -1, 2, Inf], 2), [1i, -1, 2, Inf, NaN]) +%!error (sort ([NaN, 1i, -1, 2, Inf], 3)) +%!assert (sort ([NaN, 1i, -1, 2, Inf], "ascend"), [1i, -1, 2, Inf, NaN]) +%!assert (sort ([NaN, 1i, -1, 2, Inf], 2, "ascend"), [1i, -1, 2, Inf, NaN]) +%!assert (sort ([NaN, 1i, -1, 2, Inf], "descend"), [NaN, Inf, 2, -1, 1i]) +%!assert (sort ([NaN, 1i, -1, 2, Inf], 2, "descend"), [NaN, Inf, 2, -1, 1i]) +%!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4]), [3, 1i, 6, 4; 8, 2, 7, 5]) +%!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4], 1), [3, 1i, 6, 4; 8, 2, 7, 5]) +%!assert (sort ([3, 1i, 7, 5; 8, 2, 6, 4], 2), [1i, 3, 5, 7; 2, 4, 6, 8]) +%!assert (sort (1i), 1i) + +%!test +%! [v, i] = sort ([NaN, 1i, -1, Inf, 1, 1i]); +%! assert (v, [1, 1i, 1i, -1, Inf, NaN]) +%! assert (i, [5, 2, 6, 3, 4, 1]) + +%% Bool +%!assert (sort ([true, false, true, false]), [false, false, true, true]) +%!assert (sort ([true, false, true, false], 1), [true, false, true, false]) +%!assert (sort ([true, false, true, false], 2), [false, false, true, true]) +%!error (sort ([true, false, true, false], 3)) +%!assert (sort ([true, false, true, false], "ascend"), [false, false, true, true]) +%!assert (sort ([true, false, true, false], 2, "ascend"), [false, false, true, true]) +%!assert (sort ([true, false, true, false], "descend"), [true, true, false, false]) +%!assert (sort ([true, false, true, false], 2, "descend"), [true, true, false, false]) +%!assert (sort (true), true) + +%!test +%! [v, i] = sort ([true, false, true, false]); +%! assert (v, [false, false, true, true]) +%! assert (i, [2, 4, 1, 3]) + +%% Sparse Double +%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf])), sparse ([-1, 0, 0, 1, 2, Inf, NaN])) +%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 1), sparse ([0, NaN, 1, 0, -1, 2, Inf])) +%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2), sparse ([-1, 0, 0, 1, 2, Inf, NaN])) +%!error (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 3)) +%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), "ascend"), sparse ([-1, 0, 0, 1, 2, Inf, NaN])) +%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2, "ascend"), sparse ([-1, 0, 0, 1, 2, Inf, NaN])) +%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), "descend"), sparse ([NaN, Inf, 2, 1, 0, 0, -1])) +%!assert (sort (sparse ([0, NaN, 1, 0, -1, 2, Inf]), 2, "descend"), sparse ([NaN, Inf, 2, 1, 0, 0, -1])) + +%!shared a +%! a = randn (10, 10); +%! a (a < 0) = 0; +%!assert (sort (sparse (a)), sparse (sort (a))) +%!assert (sort (sparse (a), 1), sparse (sort (a, 1))) +%!assert (sort (sparse (a), 2), sparse (sort (a, 2))) +%!test +%! [v, i] = sort (a); +%! [vs, is] = sort (sparse (a)); +%! assert (vs, sparse (v)) +%! assert (is, i) + +%% Sparse Complex +%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf])), sparse ([0, 0, 1i, -1, 2, Inf, NaN])) +%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 1), sparse ([0, NaN, 1i, 0, -1, 2, Inf])) +%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2), sparse ([0, 0, 1i, -1, 2, Inf, NaN])) +%!error (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 3)) +%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), "ascend"), sparse ([0, 0, 1i, -1, 2, Inf, NaN])) +%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2, "ascend"), sparse ([0, 0, 1i, -1, 2, Inf, NaN])) +%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), "descend"), sparse ([NaN, Inf, 2, -1, 1i, 0, 0])) +%!assert (sort (sparse ([0, NaN, 1i, 0, -1, 2, Inf]), 2, "descend"), sparse ([NaN, Inf, 2, -1, 1i, 0, 0])) + +%!shared a +%! a = randn (10, 10); +%! a (a < 0) = 0; +%! a = 1i * a; +%!assert (sort (sparse (a)), sparse (sort (a))) +%!assert (sort (sparse (a), 1), sparse (sort (a, 1))) +%!assert (sort (sparse (a), 2), sparse (sort (a, 2))) +%!test +%! [v, i] = sort (a); +%! [vs, is] = sort (sparse (a)); +%! assert (vs, sparse (v)) +%! assert (is, i) + +%% Sparse Bool +%!assert (sort (sparse ([true, false, true, false])), sparse ([false, false, true, true])) +%!assert (sort (sparse([true, false, true, false]), 1), sparse ([true, false, true, false])) +%!assert (sort (sparse ([true, false, true, false]), 2), sparse ([false, false, true, true])) +%!error (sort (sparse ([true, false, true, false], 3))) +%!assert (sort (sparse ([true, false, true, false]), "ascend"), sparse([false, false, true, true])) +%!assert (sort (sparse ([true, false, true, false]), 2, "ascend"), sparse([false, false, true, true])) +%!assert (sort (sparse ([true, false, true, false]), "descend"), sparse ([true, true, false, false])) +%!assert (sort (sparse ([true, false, true, false]), 2, "descend"), sparse([true, true, false, false])) + +%!test +%! [v, i] = sort (sparse([true, false, true, false])); +%! assert (v, sparse([false, false, true, true])) +%! assert (i, [2, 4, 1, 3]) + +%% Cell string array +%!shared a, b, c +%! a = {"Alice", "Cecile", "Eric", "Barry", "David"}; +%! b = {"Alice", "Barry", "Cecile", "David", "Eric"}; +%! c = {"Eric", "David", "Cecile", "Barry", "Alice"}; +%!assert (sort (a), b); +%!assert (sort (a, 1), a) +%!assert (sort (a, 2), b) +%!error (sort (a, 3)) +%!assert (sort (a, "ascend"), b) +%!assert (sort (a, 2, "ascend"), b) +%!assert (sort (a, "descend"), c) +%!assert (sort (a, 2, "descend"), c) + +%!test +%! [v, i] = sort (a); +%! assert (i, [1, 4, 2, 5, 3]) + +*/ + /* ;;; Local Variables: *** ;;; mode: C++ ***