Mercurial > hg > octave-lyh
diff src/pt-mat.cc @ 10535:3f973f6c841c
improve sparse concatenation operator
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Tue, 20 Apr 2010 08:42:03 +0200 |
parents | 12884915a8e4 |
children | 53253f796351 |
line wrap: on
line diff
--- a/src/pt-mat.cc +++ b/src/pt-mat.cc @@ -724,9 +724,9 @@ "concatenation of different character string types may have unintended consequences"); } -template<class TYPE> +template<class TYPE, class T> static void -single_type_concat (TYPE& result, +single_type_concat (Array<T>& result, tm_const& tmp) { octave_idx_type r = 0, c = 0; @@ -761,14 +761,79 @@ } } +template<class TYPE, class T> +static void +single_type_concat (Array<T>& result, + const dim_vector& dv, + tm_const& tmp) +{ + if (tmp.length () == 1) + { + // If possible, forward the operation to liboctave. + // Single row. + tm_row_const& row = tmp.front (); + octave_idx_type ncols = row.length (), i = 0; + OCTAVE_LOCAL_BUFFER (Array<T>, array_list, ncols); + + for (tm_row_const::iterator q = row.begin (); + q != row.end () && ! error_state; + q++) + { + octave_quit (); + + array_list[i++] = octave_value_extract<TYPE> (*q); + } + + if (! error_state) + result = Array<T>::cat (1, ncols, array_list); + } + else + { + result = Array<T> (dv); + single_type_concat<TYPE> (result, tmp); + } +} + +template<class TYPE, class T> +static void +single_type_concat (Sparse<T>& result, + const dim_vector&, + tm_const& tmp) +{ + // Sparse matrices require preallocation for efficient indexing; besides, + // only horizontal concatenation can be efficiently handled by indexing. + // So we just cat all rows through liboctave, then cat the final column. + octave_idx_type nrows = tmp.length (), j = 0; + OCTAVE_LOCAL_BUFFER (Sparse<T>, sparse_row_list, nrows); + for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++) + { + tm_row_const row = *p; + octave_idx_type ncols = row.length (), i = 0; + OCTAVE_LOCAL_BUFFER (Sparse<T>, sparse_list, ncols); + + for (tm_row_const::iterator q = row.begin (); + q != row.end () && ! error_state; + q++) + { + octave_quit (); + + sparse_list[i++] = octave_value_extract<TYPE> (*q); + } + + sparse_row_list[j++] = Sparse<T>::cat (1, ncols, sparse_list); + } + + result = Sparse<T>::cat (0, nrows, sparse_row_list); +} + template<class TYPE> static octave_value do_single_type_concat (const dim_vector& dv, tm_const& tmp) { - TYPE result (dv); + TYPE result; - single_type_concat (result, tmp); + single_type_concat<TYPE> (result, dv, tmp); return result; } @@ -778,9 +843,9 @@ do_single_type_concat_no_mutate (const dim_vector& dv, tm_const& tmp) { - TYPE result (dv); + TYPE result; - single_type_concat (result, tmp); + single_type_concat<TYPE> (result, dv, tmp); return new OV_TYPE (result); } @@ -915,7 +980,7 @@ charNDArray result (dv, Vstring_fill_char); - single_type_concat (result, tmp); + single_type_concat<charNDArray> (result, tmp); retval = octave_value (result, type); }