# HG changeset patch # User jwe # Date 1095190954 0 # Node ID b38ef92e443e440547c87f98b310dacbe1b4c090 # Parent 21b4124e31af6b738af8c6d10c41c96baefee789 [project @ 2004-09-14 19:40:26 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2004-09-14 David Bateman + + * DLD-FUNCTIONS/sort.cc (mx_sort (charNDArray&, bool, int)): + New function to sort character strings. + (Fsort): Handle character strings. + 2004-09-11 John W. Eaton * ov-fcn-handle.cc (octave_fcn_handle::save_ascii): diff --git a/src/DLD-FUNCTIONS/sort.cc b/src/DLD-FUNCTIONS/sort.cc --- a/src/DLD-FUNCTIONS/sort.cc +++ b/src/DLD-FUNCTIONS/sort.cc @@ -80,13 +80,13 @@ bool double_compare (double a, double b) { - return (xisnan(b) || (a < b)); + return (xisnan (b) || (a < b)); } bool double_compare (vec_index *a, vec_index *b) { - return (xisnan(b->vec) || (a->vec < b->vec)); + return (xisnan (b->vec) || (a->vec < b->vec)); } template class octave_sort; @@ -102,7 +102,7 @@ bool complex_compare (complex_vec_index *a, complex_vec_index *b) { - return (xisnan(b->vec) || (abs(a->vec) < abs(b->vec))); + return (xisnan (b->vec) || (abs (a->vec) < abs (b->vec))); } template class octave_sort; @@ -194,7 +194,7 @@ } } - retval (1) = idx; + retval(1) = idx; } else { @@ -348,7 +348,7 @@ } } } - retval (1) = idx; + retval(1) = idx; } else { @@ -485,13 +485,148 @@ } if (return_idx) - retval (1) = idx; + retval(1) = idx; retval(0) = m; return retval; } +struct char_vec_index +{ + char vec; + int indx; +}; + +bool +char_compare (char_vec_index *a, char_vec_index *b) +{ + return (a->vec < b->vec); +} + +template class octave_sort; +template class octave_sort; + +static octave_value_list +mx_sort (charNDArray &m, bool return_idx, int dim) +{ + octave_value_list retval; + + if (m.length () < 1) + return retval; + + dim_vector dv = m.dims (); + unsigned int ns = dv (dim); + unsigned int iter = dv.numel () / ns; + unsigned int stride = 1; + for (unsigned int i = 0; i < static_cast (dim); i++) + stride *= dv(i); + + if (return_idx) + { + char *v = m.fortran_vec (); + octave_sort indexed_char_sort (char_compare); + + OCTAVE_LOCAL_BUFFER (char_vec_index *, vi, ns); + OCTAVE_LOCAL_BUFFER (char_vec_index, vix, ns); + + for (unsigned int i = 0; i < ns; i++) + vi[i] = &vix[i]; + + NDArray idx (dv); + + if (stride == 1) + { + for (unsigned int j = 0; j < iter; j++) + { + unsigned int offset = j * ns; + + for (unsigned int i = 0; i < ns; i++) + { + vi[i]->vec = v[i]; + vi[i]->indx = i + 1; + } + + indexed_char_sort.sort (vi, ns); + + for (unsigned int i = 0; i < ns; i++) + { + v[i] = vi[i]->vec; + idx(i + offset) = vi[i]->indx; + } + v += ns; + } + } + else + { + for (unsigned int j = 0; j < iter; j++) + { + unsigned int offset = j; + unsigned int offset2 = 0; + while (offset >= stride) + { + offset -= stride; + offset2++; + } + offset += offset2 * stride * ns; + + for (unsigned int i = 0; i < ns; i++) + { + vi[i]->vec = v[i*stride + offset]; + vi[i]->indx = i + 1; + } + + indexed_char_sort.sort (vi, ns); + + for (unsigned int i = 0; i < ns; i++) + { + v[i*stride+offset] = vi[i]->vec; + idx(i*stride+offset) = vi[i]->indx; + } + } + } + retval(1) = idx; + } + else + { + char *v = m.fortran_vec (); + octave_sort char_sort; + + if (stride == 1) + for (unsigned int j = 0; j < iter; j++) + { + char_sort.sort (v, ns); + v += ns; + } + else + { + OCTAVE_LOCAL_BUFFER (char, vi, ns); + for (unsigned int j = 0; j < iter; j++) + { + unsigned int offset = j; + unsigned int offset2 = 0; + while (offset >= stride) + { + offset -= stride; + offset2++; + } + offset += offset2 * stride * ns; + + for (unsigned int i = 0; i < ns; i++) + vi[i] = v[i*stride + offset]; + + char_sort.sort (vi, ns); + + for (unsigned int i = 0; i < ns; i++) + v[i*stride + offset] = vi[i]; + } + } + } + + retval(0) = octave_value (m, true); + return retval; +} + DEFUN_DLD (sort, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{s}, @var{i}] =} sort (@var{x})\n\ @@ -594,6 +729,13 @@ if (! error_state) retval = mx_sort (cm, return_idx, dim); } + else if (arg.is_string ()) + { + charNDArray chm = arg.char_array_value (); + + if (! error_state) + retval = mx_sort (chm, return_idx, dim); + } else gripe_wrong_type_arg ("sort", arg);