changeset 10531:2dd8ea8bfd71

basic cat functionality in liboctave
author Jaroslav Hajek <highegg@gmail.com>
date Sun, 18 Apr 2010 17:56:16 +0200
parents 114376c7cba5
children 568c7c041fac
files liboctave/Array.cc liboctave/Array.h liboctave/ChangeLog liboctave/Sparse.cc liboctave/Sparse.h
diffstat 5 files changed, 114 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array.cc	Sat Apr 17 20:37:51 2010 -0400
+++ b/liboctave/Array.cc	Sun Apr 18 17:56:16 2010 +0200
@@ -2595,6 +2595,40 @@
 }
 
 template <class T>
+Array<T>
+Array<T>::cat (int dim, octave_idx_type n, const Array<T> *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<T> retval (dv);
+  Array<idx_vector> 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 <class T>
 void
 Array<T>::print_info (std::ostream& os, const std::string& prefix) const
 {
--- a/liboctave/Array.h	Sat Apr 17 20:37:51 2010 -0400
+++ b/liboctave/Array.h	Sun Apr 18 17:56:16 2010 +0200
@@ -578,6 +578,9 @@
 
   Array<T> diag (octave_idx_type k = 0) const;
 
+  static Array<T>
+  cat (int dim, octave_idx_type n, const Array<T> *array_list);
+
   template <class U, class F>
   Array<U>
   map (F fcn) const
--- a/liboctave/ChangeLog	Sat Apr 17 20:37:51 2010 -0400
+++ b/liboctave/ChangeLog	Sun Apr 18 17:56:16 2010 +0200
@@ -1,3 +1,10 @@
+2010-04-18  Jaroslav Hajek  <highegg@gmail.com>
+
+	* Array.cc (Array<T>::cat): New method.
+	* Array.h: Declare it.
+	* Sparse.cc (Sparse<T>::cat): New method.
+	* Sparse.h: Declare it.
+
 2010-04-16  David Bateman  <dbateman@free.fr>
 
 	* Sparse.cc (template <class T> Sparse<T>::Sparse (const Array<T>&,
--- a/liboctave/Sparse.cc	Sat Apr 17 20:37:51 2010 -0400
+++ b/liboctave/Sparse.cc	Sun Apr 18 17:56:16 2010 +0200
@@ -2377,6 +2377,73 @@
 }
 
 template <class T>
+Sparse<T>
+Sparse<T>::cat (int dim, octave_idx_type n, const Sparse<T> *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<T> 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<T>& 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 <class T>
 Array<T>
 Sparse<T>::array_value () const
 {
--- a/liboctave/Sparse.h	Sat Apr 17 20:37:51 2010 -0400
+++ b/liboctave/Sparse.h	Sun Apr 18 17:56:16 2010 +0200
@@ -509,6 +509,9 @@
 
   Sparse<T> diag (octave_idx_type k = 0) const;
 
+  static Sparse<T>
+  cat (int dim, octave_idx_type n, const Sparse<T> *sparse_list);
+
   Array<T> array_value (void) const;
 
   template <class U, class F>