Mercurial > hg > octave-lyh
changeset 10535:3f973f6c841c
improve sparse concatenation operator
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Tue, 20 Apr 2010 08:42:03 +0200 |
parents | eb55e736060e |
children | 74cb77f0a163 |
files | liboctave/Array.cc liboctave/ChangeLog liboctave/Sparse.cc src/ChangeLog src/pt-mat.cc |
diffstat | 5 files changed, 95 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -2602,6 +2602,9 @@ (*current_liboctave_error_handler) ("cat: invalid dimension"); + if (n == 1) + return array_list[0]; + dim_vector dv; for (octave_idx_type i = 0; i < n; i++) if (! dv.concat (array_list[i].dims (), dim))
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,8 @@ +2010-04-19 Jaroslav Hajek <highegg@gmail.com> + + * Array.cc (Array<T>::cat): Fast return for single array case. + * Sparse.cc (Sparse<T>::cat): Ditto. + 2010-04-19 Jaroslav Hajek <highegg@gmail.com> * Array.cc (Array<T>::cat): Miscellaneous fixes.
--- a/liboctave/Sparse.cc +++ b/liboctave/Sparse.cc @@ -2384,6 +2384,9 @@ octave_idx_type total_nz = 0; if (dim == 0 || dim == 1) { + if (n == 1) + return sparse_list[0]; + for (octave_idx_type i = 0; i < n; i++) { if (! dv.concat (sparse_list[i].dims (), dim)) @@ -2392,6 +2395,9 @@ total_nz += sparse_list[i].nnz (); } } + else + (*current_liboctave_error_handler) + ("cat: invalid dimension for sparse concatenation"); Sparse<T> retval (dv, total_nz); @@ -2443,8 +2449,7 @@ break; } default: - (*current_liboctave_error_handler) - ("cat: invalid dimension for sparse concatenation"); + assert (false); } return retval;
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2010-04-20 Jaroslav Hajek <highegg@gmail.com> + + * pt-mat.cc (single_type_concat): New overloads. Make TYPE an explicit + template parameter. Try to forward some cases to Array<T>::cat and + Sparse<T>::cat. + (do_single_type_concat, do_single_type_concat_no_mutate): Don't + allocate the array here, let single_type_concat do it. + 2010-04-19 Jaroslav Hajek <highegg@gmail.com> * data.cc (single_type_concat, do_single_type_concat): Rewrite using
--- 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); }