# HG changeset patch # User Jaroslav Hajek # Date 1271606176 -7200 # Node ID 2dd8ea8bfd71439702d820f806e595a40dcbd6b9 # Parent 114376c7cba56e362a3349e93c94a6dd5bd15089 basic cat functionality in liboctave diff --git a/liboctave/Array.cc b/liboctave/Array.cc --- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -2595,6 +2595,40 @@ } template +Array +Array::cat (int dim, octave_idx_type n, const Array *array_list) +{ + if (dim < 0) + (*current_liboctave_error_handler) + ("cat: invalid dimension"); + + dim_vector dv; + for (octave_idx_type i = 0; i < n; i++) + if (! dv.concat (array_list[i].dims (), dim)) + (*current_liboctave_error_handler) + ("cat: dimension mismatch"); + + Array retval (dv); + Array idxa (dv.length (), 1, idx_vector::colon); + octave_idx_type l = 0; + + for (octave_idx_type i = 0; i < n; i++) + { + octave_idx_type u; + if (dim < array_list[i].ndims ()) + u = l + array_list[i].dims ()(dim); + else + u = l + 1; + + idxa(dim) = idx_vector (l, u); + + retval.assign (idxa, array_list[i]); + } + + return retval; +} + +template void Array::print_info (std::ostream& os, const std::string& prefix) const { diff --git a/liboctave/Array.h b/liboctave/Array.h --- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -578,6 +578,9 @@ Array diag (octave_idx_type k = 0) const; + static Array + cat (int dim, octave_idx_type n, const Array *array_list); + template Array map (F fcn) const diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,10 @@ +2010-04-18 Jaroslav Hajek + + * Array.cc (Array::cat): New method. + * Array.h: Declare it. + * Sparse.cc (Sparse::cat): New method. + * Sparse.h: Declare it. + 2010-04-16 David Bateman * Sparse.cc (template Sparse::Sparse (const Array&, diff --git a/liboctave/Sparse.cc b/liboctave/Sparse.cc --- a/liboctave/Sparse.cc +++ b/liboctave/Sparse.cc @@ -2377,6 +2377,73 @@ } template +Sparse +Sparse::cat (int dim, octave_idx_type n, const Sparse *sparse_list) +{ + dim_vector dv; + octave_idx_type total_nz = 0; + if (dim == 0 || dim == 1) + { + for (octave_idx_type i = 0; i < n; i++) + { + if (! dv.concat (sparse_list[i].dims (), dim)) + (*current_liboctave_error_handler) + ("cat: dimension mismatch"); + total_nz += sparse_list[i].nnz (); + } + } + + Sparse retval (dv, total_nz); + + switch (dim) + { + case 0: + { + // sparse vertcat. This is not efficiently handled by assignment, so + // we'll do it directly. + octave_idx_type l = 0; + for (octave_idx_type j = 0; j < n; j++) + { + octave_idx_type rcum = 0; + for (octave_idx_type i = 0; i < n; i++) + { + const Sparse& spi = sparse_list[i]; + octave_idx_type kl = spi.cidx(j), ku = spi.cidx(j+1); + for (octave_idx_type k = kl; k < ku; k++, l++) + { + retval.xridx(l) = spi.ridx(k) + rcum; + retval.xdata(l) = spi.data(k); + } + + rcum += spi.rows (); + } + + retval.xcidx(j+1) = l; + } + + break; + } + case 1: + { + octave_idx_type ccum = 0; + for (octave_idx_type i = 0; i < n; i++) + { + octave_idx_type l = ccum, u = ccum + sparse_list[i].columns (); + retval.assign (idx_vector::colon, idx_vector (l, u), sparse_list[i]); + ccum = u; + } + + break; + } + default: + (*current_liboctave_error_handler) + ("cat: invalid dimension for sparse concatenation"); + } + + return retval; +} + +template Array Sparse::array_value () const { diff --git a/liboctave/Sparse.h b/liboctave/Sparse.h --- a/liboctave/Sparse.h +++ b/liboctave/Sparse.h @@ -509,6 +509,9 @@ Sparse diag (octave_idx_type k = 0) const; + static Sparse + cat (int dim, octave_idx_type n, const Sparse *sparse_list); + Array array_value (void) const; template