# HG changeset patch # User jwe # Date 948690350 0 # Node ID 9c509e1cbf494c373e2bc33562eed6d92f513a63 # Parent a0aef47b4b4d1a78ca0989dafc77c875c7a45ad3 [project @ 2000-01-24 05:05:49 by jwe] diff --git a/liboctave/Array2-idx.h b/liboctave/Array2-idx.h --- a/liboctave/Array2-idx.h +++ b/liboctave/Array2-idx.h @@ -213,6 +213,105 @@ template void +Array2::maybe_delete_elements (idx_vector& idx_i) +{ + int nr = d1; + int nc = d2; + + if (nr == 0 && nc == 0) + return; + + int n; + if (nr == 1) + n = nc; + else if (nc == 1) + n = nr; + else + { + (*current_liboctave_error_handler) + ("A(idx) = []: expecting A to be row or column vector or scalar"); + + return; + } + + if (idx_i.is_colon_equiv (n, 1)) + { + // Either A(:) = [] or A(idx) = [] with idx enumerating all + // elements, so we delete all elements and return [](0x0). To + // preserve the orientation of the vector, you have to use + // A(idx,:) = [] (delete rows) or A(:,idx) (delete columns). + + resize (0, 0); + return; + } + + idx_i.sort (true); + + int num_to_delete = idx_i.length (n); + + if (num_to_delete != 0) + { + int new_n = n; + + int idx = 0; + + for (int i = 0; i < n; i++) + if (i == idx_i.elem (idx)) + { + idx++; + new_n--; + + if (idx == num_to_delete) + break; + } + + if (new_n > 0) + { + T *new_data = new T [new_n]; + + int ii = 0; + idx = 0; + for (int i = 0; i < n; i++) + { + if (idx < num_to_delete && i == idx_i.elem (idx)) + idx++; + else + { + if (nr == 1) + new_data[ii] = elem (0, i); + else + new_data[ii] = elem (i, 0); + + ii++; + } + } + + if (--rep->count <= 0) + delete rep; + + rep = new ArrayRep (new_data, new_n); + + if (nr == 1) + { + d1 = 1; + d2 = new_n; + } + else + { + d1 = new_n; + d2 = 1; + } + + set_max_indices (2); + } + else + (*current_liboctave_error_handler) + ("A(idx) = []: index out of range"); + } +} + +template +void Array2::maybe_delete_elements (idx_vector& idx_i, idx_vector& idx_j) { int nr = d1; @@ -221,6 +320,38 @@ if (nr == 0 && nc == 0) return; + if (idx_i.is_colon ()) + { + if (idx_j.is_colon ()) + { + // A(:,:) -- We are deleting columns and rows, so the result + // is [](0x0). + + resize (0, 0); + return; + } + + if (idx_j.is_colon_equiv (nc, 1)) + { + // A(:,j) -- We are deleting columns by enumerating them, + // If we enumerate all of them, we should have zero columns + // with the same number of rows that we started with. + + resize (nr, 0); + return; + } + } + + if (idx_j.is_colon () && idx_i.is_colon_equiv (nr, 1)) + { + // A(i,:) -- We are deleting rows by enumerating them. If we + // enumerate all of them, we should have zero rows with the + // same number of columns that we started with. + + resize (0, nc); + return; + } + if (idx_i.is_colon_equiv (nr, 1)) { if (idx_j.is_colon_equiv (nc, 1)) @@ -484,10 +615,7 @@ if (rhs_nr == 0 && rhs_nc == 0) { if (n != 0 && (lhs_nr != 0 || lhs_nc != 0)) - { - idx_vector tmp (':'); - lhs.maybe_delete_elements (idx, tmp); - } + lhs.maybe_delete_elements (idx); } else if (! liboctave_dfi_flag && lhs_is_empty && idx.is_colon () @@ -577,10 +705,7 @@ if (idx) { if (rhs_nr == 0 && rhs_nc == 0) - { - idx_vector tmp (':'); - lhs.maybe_delete_elements (tmp, idx); - } + lhs.maybe_delete_elements (idx); else { if (assign ((Array&) lhs, (Array&) rhs)) @@ -602,10 +727,7 @@ if (idx) { if (rhs_nr == 0 && rhs_nc == 0) - { - idx_vector tmp (':'); - lhs.maybe_delete_elements (idx, tmp); - } + lhs.maybe_delete_elements (idx); else { if (assign ((Array&) lhs, (Array&) rhs)) diff --git a/liboctave/Array2.h b/liboctave/Array2.h --- a/liboctave/Array2.h +++ b/liboctave/Array2.h @@ -178,6 +178,8 @@ Array2 transpose (void) const; #ifdef HEAVYWEIGHT_INDEXING + void maybe_delete_elements (idx_vector& i); + void maybe_delete_elements (idx_vector& i, idx_vector& j); Array2 value (void); diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,18 @@ +2000-01-23 John W. Eaton + + * Array2-idx.h (Array2::maybe_delete_elements (idx_vector&)): + New function. + (assign (Array2& lhs, const Array2& rhs)): + Use it when indexing with one arg instead of faking a second one. + (Array2::maybe_delete_elements (idx_vector&, idx_vector&)): + Return empty matrices with the correct dimensions for A(:,:) = [] + and also A(:,idx) = [], and A(idx,:) = [] when idx enumerates all + rows or columns. + + * idx-vector.cc (IDX_VEC_REP::is_colon_equiv): Recognize a bool + vector that is all true values with a length equal to n as colon + equivalent. + 2000-01-22 John W. Eaton * strptime.c: Only include langinfo.h if _LIBC is defined. diff --git a/liboctave/idx-vector.cc b/liboctave/idx-vector.cc --- a/liboctave/idx-vector.cc +++ b/liboctave/idx-vector.cc @@ -507,9 +507,13 @@ { colon_equiv = 1; } - else if (len > 1 && ! one_zero) + else if (len > 1) { - if (sort_uniq) + if (one_zero) + { + colon_equiv = (len == n && ones_count () == n); + } + else if (sort_uniq) { int *tmp_data = copy_data (data, len); diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2000-01-23 John W. Eaton + + * ov-base-mat.h (octave_base_matrix::length): Return 0 for empty + arrays. + 2000-01-20 John W. Eaton * DLD-FUNCTIONS/time.cc (Fstrptime): New function. diff --git a/src/ov-base-mat.h b/src/ov-base-mat.h --- a/src/ov-base-mat.h +++ b/src/ov-base-mat.h @@ -76,7 +76,7 @@ int r = rows (); int c = columns (); - return r > c ? r : c; + return (r == 0 || c == 0) ? 0 : ((r > c) ? r : c); } octave_value all (void) const { return matrix.all (); }