Mercurial > hg > octave-terminal
changeset 4747:3f28979bbe2c
[project @ 2004-02-06 23:56:46 by jwe]
author | jwe |
---|---|
date | Fri, 06 Feb 2004 23:56:46 +0000 |
parents | c43a0c0b6d44 |
children | 7b145222fea3 |
files | liboctave/Array-util.cc liboctave/Array-util.h liboctave/Array.cc liboctave/ChangeLog |
diffstat | 4 files changed, 270 insertions(+), 280 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/Array-util.cc +++ b/liboctave/Array-util.cc @@ -39,7 +39,7 @@ { for (int i = 0; i < n; i++) { - if (ra_idx(i) < 0 || ra_idx(i) > dimensions(i)) + if (ra_idx(i) < 0 || ra_idx(i) >= dimensions(i)) { retval = false; break; @@ -236,25 +236,6 @@ } bool -equal_arrays (const dim_vector& a, const dim_vector& b) -{ - bool retval = true; - - if (a.length () != b.length ()) - retval = false; - else - { - for (int i = 0; i < a.length (); i++) - { - if (a(i) != b(i)) - retval = false; - } - } - - return retval; -} - -bool all_ok (const Array<idx_vector>& ra_idx) { bool retval = true; @@ -293,25 +274,6 @@ } bool -any_zero_len (const dim_vector& frozen_lengths) -{ - bool retval = false; - - int n = frozen_lengths.length (); - - for (int i = 0; i < n; i++) - { - if (frozen_lengths(i) == 0) - { - retval = true; - break; - } - } - - return retval; -} - -bool all_colon_equiv (const Array<idx_vector>& ra_idx, const dim_vector& frozen_lengths) { @@ -393,22 +355,6 @@ return retval; } -int -number_of_elements (const dim_vector ra_idx) -{ - int retval = 1; - - int n = ra_idx.length (); - - if (n == 0) - retval = 0; - - for (int i = 0; i < n; i++) - retval *= ra_idx(i); - - return retval; -} - Array<int> get_ra_idx (int idx, const dim_vector& dims) { @@ -421,7 +367,7 @@ for (int i = 0; i < n_dims; i++) retval(i) = 0; - assert (idx > 0 || idx < number_of_elements (dims)); + assert (idx > 0 || idx < dims.numel ()); for (int i = 0; i < idx; i++) increment_index (retval, dims);
--- a/liboctave/Array-util.h +++ b/liboctave/Array-util.h @@ -56,17 +56,10 @@ extern bool vector_equivalent (const Array<int>& ra_idx); -extern bool equal_arrays (const dim_vector& a, const dim_vector& b); - extern bool all_ok (const Array<idx_vector>& ra_idx); extern bool any_orig_empty (const Array<idx_vector>& ra_idx); -extern bool any_zero_len (const dim_vector& frozen_lengths); - -extern dim_vector get_zero_len_size (const dim_vector& frozen_lengths, - const dim_vector& dimensions); - extern bool all_colon_equiv (const Array<idx_vector>& ra_idx, const dim_vector& frozen_lengths); @@ -79,8 +72,6 @@ extern Array<int> get_elt_idx (const Array<idx_vector>& ra_idx, const Array<int>& result_idx); -extern int number_of_elements (const dim_vector ra_idx); - extern Array<int> get_ra_idx (int idx, const dim_vector& dims); extern dim_vector short_freeze (Array<idx_vector>& ra_idx,
--- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -475,7 +475,7 @@ dimensions = dim_vector (n); - if (old_data && old_len > 0) + if (n > 0 && old_data && old_len > 0) { int min_len = old_len < n ? old_len : n; @@ -529,18 +529,23 @@ typename Array<T>::ArrayRep *old_rep = rep; const T *old_data = data (); - rep = new typename Array<T>::ArrayRep (get_size (dv)); + int ts = get_size (dv); + + rep = new typename Array<T>::ArrayRep (ts); dimensions = dv; - Array<int> ra_idx (dimensions.length (), 0); - - for (int i = 0; i < old_len; i++) + if (ts > 0) { - if (index_in_bounds (ra_idx, dimensions)) - xelem (ra_idx) = old_data[i]; - - increment_index (ra_idx, dimensions); + Array<int> ra_idx (dimensions.length (), 0); + + for (int i = 0; i < old_len; i++) + { + if (index_in_bounds (ra_idx, dimensions)) + xelem (ra_idx) = old_data[i]; + + increment_index (ra_idx, dimensions); + } } if (--old_rep->count <= 0) @@ -575,11 +580,13 @@ int old_d2 = dim2 (); int old_len = length (); - rep = new typename Array<T>::ArrayRep (get_size (r, c)); + int ts = get_size (r, c); + + rep = new typename Array<T>::ArrayRep (ts); dimensions = dim_vector (r, c); - if (old_data && old_len > 0) + if (ts > 0 && old_data && old_len > 0) { int min_r = old_d1 < r ? old_d1 : r; int min_c = old_d2 < c ? old_d2 : c; @@ -628,7 +635,7 @@ dimensions = dim_vector (r, c, p); - if (old_data && old_len > 0) + if (ts > 0 && old_data && old_len > 0) { int min_r = old_d1 < r ? old_d1 : r; int min_c = old_d2 < c ? old_d2 : c; @@ -666,17 +673,20 @@ dimensions = dim_vector (n); - int min_len = old_len < n ? old_len : n; - - if (old_data && old_len > 0) + if (n > 0) { - for (int i = 0; i < min_len; i++) - xelem (i) = old_data[i]; + int min_len = old_len < n ? old_len : n; + + if (old_data && old_len > 0) + { + for (int i = 0; i < min_len; i++) + xelem (i) = old_data[i]; + } + + for (int i = old_len; i < n; i++) + xelem (i) = val; } - for (int i = old_len; i < n; i++) - xelem (i) = val; - if (--old_rep->count <= 0) delete old_rep; } @@ -707,28 +717,33 @@ int old_d2 = dim2 (); int old_len = length (); - rep = new typename Array<T>::ArrayRep (get_size (r, c)); + int ts = get_size (r, c); + + rep = new typename Array<T>::ArrayRep (ts); dimensions = dim_vector (r, c); - int min_r = old_d1 < r ? old_d1 : r; - int min_c = old_d2 < c ? old_d2 : c; - - if (old_data && old_len > 0) + if (ts > 0) { + int min_r = old_d1 < r ? old_d1 : r; + int min_c = old_d2 < c ? old_d2 : c; + + if (old_data && old_len > 0) + { + for (int j = 0; j < min_c; j++) + for (int i = 0; i < min_r; i++) + xelem (i, j) = old_data[old_d1*j+i]; + } + for (int j = 0; j < min_c; j++) - for (int i = 0; i < min_r; i++) - xelem (i, j) = old_data[old_d1*j+i]; + for (int i = min_r; i < r; i++) + xelem (i, j) = val; + + for (int j = min_c; j < c; j++) + for (int i = 0; i < r; i++) + xelem (i, j) = val; } - for (int j = 0; j < min_c; j++) - for (int i = min_r; i < r; i++) - xelem (i, j) = val; - - for (int j = min_c; j < c; j++) - for (int i = 0; i < r; i++) - xelem (i, j) = val; - if (--old_rep->count <= 0) delete old_rep; } @@ -767,34 +782,37 @@ dimensions = dim_vector (r, c, p); - int min_r = old_d1 < r ? old_d1 : r; - int min_c = old_d2 < c ? old_d2 : c; - int min_p = old_d3 < p ? old_d3 : p; - - if (old_data && old_len > 0) - for (int k = 0; k < min_p; k++) - for (int j = 0; j < min_c; j++) - for (int i = 0; i < min_r; i++) - xelem (i, j, k) = old_data[old_d1*(old_d2*k+j)+i]; - - // XXX FIXME XXX -- if the copy constructor is expensive, this may - // win. Otherwise, it may make more sense to just copy the value - // everywhere when making the new ArrayRep. - - for (int k = 0; k < min_p; k++) - for (int j = min_c; j < c; j++) - for (int i = 0; i < min_r; i++) - xelem (i, j, k) = val; - - for (int k = 0; k < min_p; k++) - for (int j = 0; j < c; j++) - for (int i = min_r; i < r; i++) - xelem (i, j, k) = val; - - for (int k = min_p; k < p; k++) - for (int j = 0; j < c; j++) - for (int i = 0; i < r; i++) - xelem (i, j, k) = val; + if (ts > 0) + { + int min_r = old_d1 < r ? old_d1 : r; + int min_c = old_d2 < c ? old_d2 : c; + int min_p = old_d3 < p ? old_d3 : p; + + if (old_data && old_len > 0) + for (int k = 0; k < min_p; k++) + for (int j = 0; j < min_c; j++) + for (int i = 0; i < min_r; i++) + xelem (i, j, k) = old_data[old_d1*(old_d2*k+j)+i]; + + // XXX FIXME XXX -- if the copy constructor is expensive, this + // may win. Otherwise, it may make more sense to just copy the + // value everywhere when making the new ArrayRep. + + for (int k = 0; k < min_p; k++) + for (int j = min_c; j < c; j++) + for (int i = 0; i < min_r; i++) + xelem (i, j, k) = val; + + for (int k = 0; k < min_p; k++) + for (int j = 0; j < c; j++) + for (int i = min_r; i < r; i++) + xelem (i, j, k) = val; + + for (int k = min_p; k < p; k++) + for (int j = 0; j < c; j++) + for (int i = 0; i < r; i++) + xelem (i, j, k) = val; + } if (--old_rep->count <= 0) delete old_rep; @@ -858,23 +876,26 @@ dimensions = dv; - Array<int> ra_idx (dimensions.length (), 0); - - // XXX FIXME XXX -- it is much simpler to fill the whole array - // first, but probably slower for large arrays, or if the assignment - // operator for the type T is expensive. OTOH, the logic for - // deciding whether an element needs the copied value or the filled - // value might be more expensive. - - for (int i = 0; i < len; i++) - rep->elem (i) = val; - - for (int i = 0; i < old_len; i++) + if (len > 0) { - if (index_in_bounds (ra_idx, dv_old)) - xelem (ra_idx) = old_data[get_scalar_idx (ra_idx, dv_old)]; - - increment_index (ra_idx, dv_old); + Array<int> ra_idx (dimensions.length (), 0); + + // XXX FIXME XXX -- it is much simpler to fill the whole array + // first, but probably slower for large arrays, or if the assignment + // operator for the type T is expensive. OTOH, the logic for + // deciding whether an element needs the copied value or the filled + // value might be more expensive. + + for (int i = 0; i < len; i++) + rep->elem (i) = val; + + for (int i = 0; i < old_len; i++) + { + if (index_in_bounds (ra_idx, dv_old)) + xelem (ra_idx) = old_data[get_scalar_idx (ra_idx, dv_old)]; + + increment_index (ra_idx, dv_old); + } } if (--old_rep->count <= 0) @@ -1840,9 +1861,9 @@ { Array<T> retval; - int n_dims = dims ().length (); - - int orig_len = number_of_elements (dims ()); + int n_dims = dims().length (); + + int orig_len = dims().numel (); dim_vector idx_orig_dims = ra_idx.orig_dimensions (); @@ -1873,7 +1894,7 @@ if (len == 0) { - if (any_zero_len (idx_orig_dims)) + if (idx_orig_dims.any_zero ()) retval = Array<T> (idx_orig_dims); else { @@ -1922,8 +1943,7 @@ { if (liboctave_wfi_flag && ! (ra_idx.is_colon () - || (ra_idx.one_zero_only () - && equal_arrays (idx_orig_dims, dims ())))) + || (ra_idx.one_zero_only () && idx_orig_dims == dims ()))) (*current_liboctave_warning_handler) ("single index used for N-d array"); @@ -1945,7 +1965,7 @@ retval.resize (result_dims); - int n = number_of_elements (result_dims); + int n = result_dims.numel (); int r_dims = result_dims.length (); @@ -2063,7 +2083,7 @@ { if (all_ok (ra_idx)) { - if (any_orig_empty (ra_idx) || any_zero_len (frozen_lengths)) + if (any_orig_empty (ra_idx) || frozen_lengths.any_zero ()) { frozen_lengths.chop_trailing_singletons (); @@ -2644,159 +2664,169 @@ dim_vector final_lhs_dims = lhs_dims; - bool rhs_is_empty = rhs_dims_len == 0 ? true : any_zero_len (rhs_dims); - - Array<int> idx_is_colon (n_idx, 0); - Array<int> idx_is_colon_equiv (n_idx, 0); - dim_vector frozen_len; - if (! rhs_is_empty) + int orig_lhs_dims_len = lhs_dims_len; + + bool orig_empty = lhs_dims.all_zero (); + + if (n_idx < lhs_dims_len) { - int orig_lhs_dims_len = lhs_dims_len; - - if (n_idx < lhs_dims_len) + // Collapse dimensions beyond last index. + + if (liboctave_wfi_flag && ! (idx(n_idx-1).is_colon ())) + (*current_liboctave_warning_handler) + ("fewer indices than dimensions for N-d array"); + + for (int i = n_idx; i < lhs_dims_len; i++) + lhs_dims(n_idx-1) *= lhs_dims(i); + + lhs_dims.resize (n_idx); + + lhs.resize (lhs_dims); + + lhs_dims = lhs.dims (); + + lhs_dims_len = lhs_dims.length (); + } + + // Resize. + + dim_vector new_dims; + new_dims.resize (n_idx); + + for (int i = 0; i < n_idx; i++) + { + if (orig_empty) { - // Collapse dimensions beyond last index. - - if (liboctave_wfi_flag && ! (idx(n_idx-1).is_colon ())) - (*current_liboctave_warning_handler) - ("fewer indices than dimensions for N-d array"); - - for (int i = n_idx; i < lhs_dims_len; i++) - lhs_dims(n_idx-1) *= lhs_dims(i); - - lhs_dims.resize (n_idx); - - lhs.resize (lhs_dims); - - lhs_dims = lhs.dims (); - - lhs_dims_len = lhs_dims.length (); - } - - // Resize. - - dim_vector new_dims; - new_dims.resize (n_idx); - - for (int i = 0; i < n_idx; i++) - { - int tmp = (i < rhs_dims.length () && idx(i).is_colon ()) - ? rhs_dims(i) : idx(i).max () + 1; + // If index is a colon, resizing to RHS dimensions is + // allowed because we started out empty. new_dims(i) - = ((lhs_dims_len == 0 || i >= lhs_dims_len || tmp > lhs_dims(i)) - ? tmp : lhs_dims(i)); + = (i < rhs_dims.length () && idx(i).is_colon ()) + ? rhs_dims(i) : idx(i).max () + 1; } - - if (n_idx < orig_lhs_dims_len && new_dims(n_idx-1) != lhs_dims(n_idx-1)) + else { - // We reshaped and the last dimension changed. This has to - // be an error, because we don't know how to undo that - // later... - - (*current_liboctave_error_handler) - ("array index %d (= %d) for assignment requires invalid resizing operation", - n_idx, new_dims(n_idx-1)); - - retval = 0; - goto done; + // We didn't start out with all zero dimensions, so if + // index is a colon, it refers to the current LHS + // dimension. Otherwise, it is OK to enlarge to a + // dimension given by the largest index. + + new_dims(i) + = (idx(i).is_colon () || idx(i).max () < lhs_dims(i)) + ? lhs_dims(i) : idx(i).max () + 1; } - - if (n_idx > orig_lhs_dims_len) - final_lhs_dims = new_dims; - else + } + + if (! orig_empty + && n_idx < orig_lhs_dims_len + && new_dims(n_idx-1) != lhs_dims(n_idx-1)) + { + // We reshaped and the last dimension changed. This has to + // be an error, because we don't know how to undo that + // later... + + (*current_liboctave_error_handler) + ("array index %d (= %d) for assignment requires invalid resizing operation", + n_idx, new_dims(n_idx-1)); + + retval = 0; + } + else + { + if (n_idx < orig_lhs_dims_len) { for (int i = 0; i < n_idx-1; i++) final_lhs_dims(i) = new_dims(i); } + else + final_lhs_dims = new_dims; lhs.resize_and_fill (new_dims, rfv); lhs_dims = lhs.dims (); lhs_dims_len = lhs_dims.length (); - } - - for (int i = 0; i < n_idx; i++) - { - idx_is_colon_equiv(i) = idx(i).is_colon_equiv (lhs_dims(i), 1); - - idx_is_colon(i) = idx(i).is_colon (); - } - - frozen_len = freeze (idx, lhs_dims, true); - - if (rhs_is_scalar) - { - int n = Array<LT>::get_size (frozen_len); - - Array<int> result_idx (lhs_dims_len, 0); - - RT scalar = rhs.elem (0); - - for (int i = 0; i < n; i++) + + frozen_len = freeze (idx, lhs_dims, true); + + if (rhs_is_scalar) { - Array<int> elt_idx = get_elt_idx (idx, result_idx); - - lhs.checkelem (elt_idx) = scalar; - - increment_index (result_idx, frozen_len); - } - } - else - { - // RHS is matrix or higher dimension. - - // Check that non-singleton RHS dimensions conform to - // non-singleton LHS index dimensions. - - dim_vector t_rhs_dims = rhs_dims.squeeze (); - dim_vector t_frozen_len = frozen_len.squeeze (); - - // If after sqeezing out singleton dimensions, RHS is vector - // and LHS is vector, force them to have the same orientation - // so that operations like - // - // a = zeros (3, 3, 3); - // a(1:3,1,1) = [1,2,3]; - // - // will work. - - if (t_rhs_dims.length () == 2 && t_frozen_len.length () == 2 - && (t_rhs_dims.elem(1) == 1 && t_frozen_len.elem(0) == 1 - || t_rhs_dims.elem(0) == 1 && t_frozen_len.elem(1) == 1)) - { - int t0 = t_rhs_dims.elem(0); - t_rhs_dims.elem(0) = t_rhs_dims.elem(1); - t_rhs_dims.elem(1) = t0; - } - - if (t_rhs_dims != t_frozen_len) - { - (*current_liboctave_error_handler) - ("A(IDX-LIST) = X: X must be a scalar or size of X must equal number of elements indexed by IDX-LIST"); - - retval = 0; + if (! final_lhs_dims.any_zero ()) + { + int n = Array<LT>::get_size (frozen_len); + + Array<int> result_idx (lhs_dims_len, 0); + + RT scalar = rhs.elem (0); + + for (int i = 0; i < n; i++) + { + Array<int> elt_idx = get_elt_idx (idx, result_idx); + + lhs.elem (elt_idx) = scalar; + + increment_index (result_idx, frozen_len); + } + } } else { - int n = Array<LT>::get_size (frozen_len); - - Array<int> result_idx (lhs_dims_len, 0); - - for (int i = 0; i < n; i++) + // RHS is matrix or higher dimension. + + // Check that non-singleton RHS dimensions conform to + // non-singleton LHS index dimensions. + + dim_vector t_rhs_dims = rhs_dims.squeeze (); + dim_vector t_frozen_len = frozen_len.squeeze (); + + // If after sqeezing out singleton dimensions, RHS is + // vector and LHS is vector, force them to have the same + // orientation so that operations like + // + // a = zeros (3, 3, 3); + // a(1:3,1,1) = [1,2,3]; + // + // will work. + + if (t_rhs_dims.length () == 2 && t_frozen_len.length () == 2 + && ((t_rhs_dims.elem(1) == 1 + && t_frozen_len.elem(0) == 1) + || (t_rhs_dims.elem(0) == 1 + && t_frozen_len.elem(1) == 1))) { - Array<int> elt_idx = get_elt_idx (idx, result_idx); - - lhs.elem (elt_idx) = rhs.elem (i); - - increment_index (result_idx, frozen_len); + int t0 = t_rhs_dims.elem(0); + t_rhs_dims.elem(0) = t_rhs_dims.elem(1); + t_rhs_dims.elem(1) = t0; + } + + if (t_rhs_dims != t_frozen_len) + { + (*current_liboctave_error_handler) + ("A(IDX-LIST) = X: X must be a scalar or size of X must equal number of elements indexed by IDX-LIST"); + + retval = 0; + } + else + { + if (! final_lhs_dims.any_zero ()) + { + int n = Array<LT>::get_size (frozen_len); + + Array<int> result_idx (lhs_dims_len, 0); + + for (int i = 0; i < n; i++) + { + Array<int> elt_idx = get_elt_idx (idx, result_idx); + + lhs.elem (elt_idx) = rhs.elem (i); + + increment_index (result_idx, frozen_len); + } + } } } } - done: - lhs.resize (final_lhs_dims); }
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,8 +1,31 @@ 2004-02-06 John W. Eaton <jwe@bevo.che.wisc.edu> + * Array.cc (Array<T>::resize_and_fill): Don't bother to assign any + values unless the length of the new array is greater than 0. + (Array<T>::resize_no_fill): Likewise. + + * Array-util.cc (index_in_bounds): Also return false if ra_idx(i) + is equal to dimensions(i). + + * Array-util.h, Array-util.cc (equal_arrays, any_zero_len, + get_zero_len_size, number_of_elements): + Delete unused functions. + + * Array-util.cc (get_ra_idx): Use dim_vector::numel instead of + number_of_elements function. + * Array.cc (Array<T>::indexN): Likewise. + + * Array.cc (Array<T>::indexN): Use dim_vector::operator == instead + of equal_arrays function. + (Array<T>::index, Array<T>::indexN, Array<T>::assignN) Use + dim_vector::any_zero instead of any_zero_len function. + + * Array.cc (Array<T>::assignN): Eliminate special case for empty index. + Don't skip reshaping and resizing if RHS is empty. + * Array.cc (Array<T>::assignN): Simplify loop for array assignment. Move body of MAYBE_RESIZE_ND_DIMS here since it is only used once. - Eliminate special case for empty index. + Delete unused variables is_colon and is_colon_equiv. Correctly resize for expressions like x(:,:,2) = ones(3,3) when LHS is not yet defined. Error for resizing if number of indices is less than number of LHS