diff -rwc liboctave/Array.cc.orig liboctave/Array.cc *** liboctave/Array.cc.orig 2006-09-15 16:29:18.000000000 -0400 --- liboctave/Array.cc 2007-01-21 09:23:09.000000000 -0500 *************** *** 2332,2337 **** --- 2354,2379 ---- { retval = *this; } + else if (idx_i.is_colon_equiv (nr) && m == 1) + { + retval.resize_no_fill (n, m); + retval.copy_strips(*this, + 0, // Dest Offset + dim1 () * idx_j.elem (0), // Source Offset + dim1 () , // Element Count + 1, // Block Count + 0, dim1 ()); // Source/Dest Strides + } + else if (n == 1 && idx_j.is_colon_equiv (nc)) + { + retval.resize_no_fill (n, m); + retval.copy_strips(*this, + 0, // Dest Offset + idx_i.elem (0), // Source Offset + 1, // Element Count + dim2 (), // Block Count + dim1 (),1); // Source/Dest Strides + } else { retval.resize_no_fill (n, m); *************** *** 2434,2439 **** --- 2484,2516 ---- Array elt_idx; + octave_idx_type slice_dim = nearly_colon_equiv(ra_idx,dimensions); + + if (slice_dim >= 0) + { + // The idea here is to reshape the nD array into a 3D array, with + // the first dimension equal to the product of the sizes of all the dimensions + // before the slice dimension, the second dimension equal to the size of the + // the slice dimension, and the third dimension equal to the product of all of + // the dimensions after the slice dimension. + elt_idx = get_elt_idx (ra_idx, result_idx); + + octave_idx_type numelem_elt = get_scalar_idx (elt_idx, new_dims); + octave_idx_type slice_elts = dimensions(slice_dim); + octave_idx_type pre_slice_elts = 1 , post_slice_elts = 1; + + for (octave_idx_type i = 0; i < slice_dim; i++) + pre_slice_elts *= dimensions(i); + + for (octave_idx_type i = slice_dim + 1 ; i < dimensions.length(); i++) + post_slice_elts *= dimensions(i); + retval.copy_strips(*this, + 0,numelem_elt, + pre_slice_elts, post_slice_elts, + pre_slice_elts*slice_elts, pre_slice_elts); + return retval; + } + for (octave_idx_type i = 0; i < n; i++) { elt_idx = get_elt_idx (ra_idx, result_idx); *************** *** 2697,2702 **** --- 2795,2818 ---- { MAYBE_RESIZE_LHS; + if (idx_i_is_colon && m == 1) + { + lhs.copy_strips(xrhs, + lhs_nr*idx_j.elem (0) , 0, // Dest/Source Offset + lhs_nr , // Element Count + 1, // Block Count + 0 , 0 ); // Source/Dest Strides + } + else if (n == 1 && idx_j_is_colon) + { + lhs.copy_strips(xrhs, + idx_i.elem (0) , 0, // Dest/Source Offset + 1 , // Element Count + lhs_nc, // Block Count + 1 , lhs_nr); // Source/Dest Strides + } + else + { for (octave_idx_type j = 0; j < m; j++) { octave_idx_type jj = idx_j.elem (j); *************** *** 2708,2713 **** --- 2827,2833 ---- } } } + } else if (n == 0 && m == 0) { if (! ((rhs_nr == 1 && rhs_nc == 1) *************** *** 3164,3169 **** --- 3288,3319 ---- Array result_idx (lhs_dims_len, 0); + octave_idx_type slice_dim = nearly_colon_equiv(idx,final_lhs_dims); + if (slice_dim >= 0) + { + // The idea here is to reshape the nD array into a 3D array, with + // the first dimension equal to the product of the sizes of all the dimensions + // before the slice dimension, the second dimension equal to the size of the + // the slice dimension, and the third dimension equal to the product of all of + // the dimensions after the slice dimension. + Array elt_idx = get_elt_idx (idx, result_idx); + + octave_idx_type numelem_elt = get_scalar_idx (elt_idx, final_lhs_dims); + octave_idx_type slice_elts = final_lhs_dims(slice_dim); + octave_idx_type pre_slice_elts = 1 , post_slice_elts = 1; + + for (octave_idx_type i = 0; i < slice_dim; i++) + pre_slice_elts *= final_lhs_dims(i); + + for (octave_idx_type i = slice_dim + 1 ; i < final_lhs_dims.length(); i++) + post_slice_elts *= final_lhs_dims(i); + lhs.copy_strips(rhs, + numelem_elt,0, + pre_slice_elts, post_slice_elts, + pre_slice_elts, pre_slice_elts*slice_elts); + } + else + { for (octave_idx_type i = 0; i < n; i++) { Array elt_idx = get_elt_idx (idx, result_idx); *************** *** 3177,3182 **** --- 3340,3346 ---- } } } + } lhs.clear_index (); *************** *** 3194,3199 **** --- 3358,3383 ---- template void + Array::copy_strips (const Array& source, octave_idx_type dest_offset, octave_idx_type source_offset, + octave_idx_type element_count, octave_idx_type block_count, octave_idx_type source_stride, octave_idx_type dest_stride) + { + T *raw_source, *raw_dest; + + // First do one element to force the copy-on-write + elem(dest_offset) = source.elem(source_offset); + raw_source = & ( source.rep->data[source_offset] ); + raw_dest = & ( rep->data[dest_offset] ); + + for (octave_idx_type i = 0 ; i < block_count; ++i) + { + memcpy(raw_dest,raw_source,sizeof(T)*element_count); + raw_source += source_stride; + raw_dest += dest_stride; + } + } + + template + void Array::print_info (std::ostream& os, const std::string& prefix) const { os << prefix << "rep address: " << rep << "\n" diff -rwc liboctave/Array.h.orig liboctave/Array.h *** liboctave/Array.h.orig 2007-01-20 13:34:50.000000000 -0500 --- liboctave/Array.h 2007-01-19 16:07:15.000000000 -0500 *************** *** 425,430 **** --- 425,433 ---- T operator () (const Array& ra_idx) const { return elem (ra_idx); } #endif + void copy_strips (const Array& source, octave_idx_type dest_offset, octave_idx_type source_offset, + octave_idx_type element_count, octave_idx_type block_count, octave_idx_type source_stride, octave_idx_type dest_stride); + Array reshape (const dim_vector& new_dims) const; Array permute (const Array& vec, bool inv = false) const; diff -rwc liboctave/Array-util.cc.orig liboctave/Array-util.cc *** liboctave/Array-util.cc.orig 2006-04-24 15:13:07.000000000 -0400 --- liboctave/Array-util.cc 2007-01-21 06:55:36.000000000 -0500 *************** *** 301,306 **** --- 301,336 ---- return retval; } + // Find a single non-colon equivalent index. + // Returns -1 if there is more than one or there are none + + octave_idx_type + nearly_colon_equiv (const Array& ra_idx, + const dim_vector& frozen_lengths) + { + octave_idx_type idx_n = ra_idx.length (); + + int n = frozen_lengths.length (); + octave_idx_type not_colon_equiv = -123456; + + if (idx_n != n) + return -666; + + for (octave_idx_type i = 0; i < n; i++) + { + int status = ra_idx(i).is_colon_equiv (frozen_lengths(i)); + if ( ! status ) + { + if ( not_colon_equiv < 0 ) + not_colon_equiv = i; + else + return -i; + } + } + + return not_colon_equiv; + } + bool is_in (octave_idx_type num, const idx_vector& idx) { diff -rwc liboctave/Array-util.h.orig liboctave/Array-util.h *** liboctave/Array-util.h.orig 2006-02-08 13:56:54.000000000 -0500 --- liboctave/Array-util.h 2007-01-18 18:20:05.000000000 -0500 *************** *** 64,69 **** --- 64,72 ---- extern bool all_colon_equiv (const Array& ra_idx, const dim_vector& frozen_lengths); + extern octave_idx_type nearly_colon_equiv (const Array& ra_idx, + const dim_vector& frozen_lengths); + extern bool is_in (octave_idx_type num, const idx_vector& idx); extern octave_idx_type how_many_lgt (const octave_idx_type num, idx_vector& idxv); diff -rwc liboctave/idx-vector.cc.orig liboctave/idx-vector.cc *** liboctave/idx-vector.cc.orig 2006-05-02 15:40:20.000000000 -0400 --- liboctave/idx-vector.cc 2007-01-18 18:20:05.000000000 -0500 *************** *** 532,539 **** std::ostream& IDX_VEC_REP::print (std::ostream& os) const { for (octave_idx_type ii = 0; ii < len; ii++) ! os << data[ii] << "\n"; return os; } --- 532,549 ---- std::ostream& IDX_VEC_REP::print (std::ostream& os) const { + if ( len == 0) { + if ( colon ) { + return os << ":\n"; + } + if ( colon_equiv ) { + return os << "1:end\n"; + } + return os << "(?)\n"; + } for (octave_idx_type ii = 0; ii < len; ii++) ! os << data[ii] ; ! os << "\n"; return os; }