changeset 10681:0ba9bd294421

make cat() (hopefully) more matlab compatible
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 04 Jun 2010 15:08:33 +0200
parents e00de2d5263c
children 7b4ffe27bbb4
files liboctave/Array.cc liboctave/ChangeLog liboctave/Makefile.am liboctave/dim-vector.h
diffstat 4 files changed, 25 insertions(+), 223 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array.cc	Thu Jun 03 21:52:11 2010 -0700
+++ b/liboctave/Array.cc	Fri Jun 04 15:08:33 2010 +0200
@@ -2518,9 +2518,11 @@
 
   if (n == 1)
     return array_list[0];
-
-  dim_vector dv;
-  for (octave_idx_type i = 0; i < n; i++)
+  else if (n == 0)
+    return Array<T> ();
+
+  dim_vector dv = array_list[0].dims ();
+  for (octave_idx_type i = 1; i < n; i++)
     if (! dv.concat (array_list[i].dims (), dim))
       (*current_liboctave_error_handler)
         ("cat: dimension mismatch");
--- a/liboctave/ChangeLog	Thu Jun 03 21:52:11 2010 -0700
+++ b/liboctave/ChangeLog	Fri Jun 04 15:08:33 2010 +0200
@@ -1,3 +1,15 @@
+2010-06-04  Jaroslav Hajek  <highegg@gmail.com>
+
+	* dim-vector.cc: New source.
+	* Makefile.am: Add it.
+	* dim-vector.h (dim_vector::chop_all_singletons, 
+	dim_vector::str, dim_vector::num_ones, dim_vector::safe_numel, 
+	dim_vector::squeeze, dim_vector::concat, dim_vector::redim):
+	Move bodies to dim_vector.cc. 
+	(dim_vector::concat): Rewrite.
+	* Array.cc (Array::cat): Fix dim_vector concatenation. Don't use 0x0
+	as neutral element, because it isn't with dim > 1.
+
 2010-06-01  Jaroslav Hajek  <highegg@gmail.com>
 
 	* Array.cc (Array<T>::optimize_dimensions): New method.
--- a/liboctave/Makefile.am	Thu Jun 03 21:52:11 2010 -0700
+++ b/liboctave/Makefile.am	Fri Jun 04 15:08:33 2010 +0200
@@ -352,6 +352,7 @@
   boolSparse.cc \
   chMatrix.cc \
   chNDArray.cc \
+  dim-vector.cc \
   dColVector.cc \
   dDiagMatrix.cc \
   dMatrix.cc \
--- a/liboctave/dim-vector.h	Thu Jun 03 21:52:11 2010 -0700
+++ b/liboctave/dim-vector.h	Fri Jun 04 15:08:33 2010 +0200
@@ -204,24 +204,7 @@
       }
   }
 
-  void chop_all_singletons (void)
-  {
-    make_unique ();
-
-    int j = 0;
-    int l = ndims();
-
-    for (int i = 0; i < l; i++)
-      {
-        if (rep[i] != 1)
-          rep[j++] = rep[i];
-      }
-
-    if (j == 1)
-      rep[1] = 1;
-
-    ndims () = j > 2 ? j : 2;
-  }
+  void chop_all_singletons (void);
 
 private:
   
@@ -286,22 +269,7 @@
       }
   }
 
-  std::string str (char sep = 'x') const
-  {
-    std::ostringstream buf;
-
-    for (int i = 0; i < length (); i++)
-      {
-        buf << elem (i);
-
-        if (i < length () - 1)
-          buf << sep;
-      }
-
-    std::string retval = buf.str ();
-
-    return retval;
-  }
+  std::string str (char sep = 'x') const;
 
   bool all_zero (void) const
   {
@@ -340,16 +308,7 @@
     return retval;
   }
 
-  int num_ones (void) const
-  {
-    int retval = 0;
-
-    for (int i = 0; i < length (); i++)
-      if (elem (i) == 1)
-        retval++;
-
-    return retval;
-  }
+  int num_ones (void) const;
 
   bool all_ones (void) const
   {
@@ -380,23 +339,7 @@
   // function that is iterating over an array using octave_idx_type
   // indices.
 
-  octave_idx_type safe_numel (void) const
-  {
-    octave_idx_type idx_max = std::numeric_limits<octave_idx_type>::max () - 1;
-    octave_idx_type n = 1;
-    int n_dims = length ();
-
-    for (int i = 0; i < n_dims; i++)
-      {
-        n *= rep[i];
-        if (rep[i] != 0)
-          idx_max /= rep[i];
-        if (idx_max <= 0)
-          throw std::bad_alloc ();
-      }
-
-    return n;
-  }
+  octave_idx_type safe_numel (void) const;
 
   bool any_neg (void) const
   {
@@ -410,123 +353,9 @@
     return i < n_dims;
   }
 
-  dim_vector squeeze (void) const
-  {
-    dim_vector new_dims = *this;
-
-    bool dims_changed = 1;
-
-    int k = 0;
-
-    for (int i = 0; i < length (); i++)
-      {
-        if (elem (i) == 1)
-          dims_changed = true;
-        else
-          new_dims(k++) = elem (i);
-      }
-
-    if (dims_changed)
-      {
-        if (k == 0)
-          new_dims = dim_vector (1, 1);
-        else if (k == 1)
-          {
-            // There is one non-singleton dimension, so we need
-            // to decide the correct orientation.
-
-            if (elem (0) == 1)
-              {
-                // The original dimension vector had a leading
-                // singleton dimension.
-
-                octave_idx_type tmp = new_dims(0);
-        
-                new_dims.resize (2);
-
-                new_dims(0) = 1;
-                new_dims(1) = tmp;
-              }
-            else
-              {
-                // The first element of the original dimension vector
-                // was not a singleton dimension.
-
-                new_dims.resize (2);
-
-                new_dims(1) = 1;
-              }
-          }
-        else
-          new_dims.resize(k);
-      }
- 
-    return new_dims;
-  }
-
-  bool concat (const dim_vector& dvb, int dim = 0)
-  {
-    if (dvb.zero_by_zero ())
-      return true;
+  dim_vector squeeze (void) const;
 
-    if (zero_by_zero ())
-      {
-        *this = dvb;
-        return true;
-      }
-
-    int na = length ();
-    int nb = dvb.length ();
-  
-    // Find the max and min value of na and nb
-    int n_max = na > nb ? na : nb;
-    int n_min = na < nb ? na : nb;
-  
-    // The elements of the dimension vectors can only differ
-    // if the dim variable differs from the actual dimension
-    // they differ.
-
-    for (int i = 0; i < n_min; i++)
-      {
-        if (elem(i) != dvb(i) && dim != i)
-            return false;
-      }
-  
-    // Ditto.
-    for (int i = n_min; i < n_max; i++)
-      {
-        if (na > n_min)
-          {
-            if (elem(i) != 1 && dim != i)
-              return false;
-          }
-        else 
-          {
-            if (dvb(i) != 1 && dim != i)
-              return false;
-          }
-      }
-    
-    // If we want to add the dimension vectors at a dimension
-    // larger than both, then we need to set n_max to this number
-    // so that we resize *this to the right dimension.
-    
-    n_max = n_max > (dim + 1) ? n_max : (dim + 1);
-    
-    // Resize *this to the appropriate dimensions.
-    
-    if (n_max > na)
-      resize (n_max, 1);
-  
-    // Larger or equal since dim has been decremented by one.
-
-    if (dim >= nb)
-      elem (dim)++;
-    else
-      elem (dim) += dvb(dim);
-
-    return true;
-  }
+  bool concat (const dim_vector& dvb, int dim = 0);
 
   // Force certain dimensionality, preserving numel ().  Missing
   // dimensions are set to 1, redundant are folded into the trailing
@@ -534,49 +363,7 @@
   // (dim_vectors are always at least 2D).  If the original dimensions
   // were all zero, the padding value is zero.
 
-  dim_vector redim (int n) const
-    {
-      int n_dims = length ();
-
-      if (n_dims == n)
-        return *this;
-      else if (n_dims < n)
-        {
-          dim_vector retval = alloc (n);
-
-          int pad = 0;
-          for (int i = 0; i < n_dims; i++)
-            {
-              retval.rep[i] = rep[i];
-              if (rep[i] != 0)
-                pad = 1;
-            }
-
-          for (int i = n_dims; i < n; i++)
-            retval.rep[i] = pad;
-
-          return retval;
-        }
-      else
-        {
-          if (n < 1) n = 1;
-
-          dim_vector retval = alloc (n);
-
-          retval.rep[1] = 1;
-
-          for (int i = 0; i < n-1; i++)
-            retval.rep[i] = rep[i];
-
-          int k = rep[n-1];
-          for (int i = n; i < n_dims; i++)
-            k *= rep[i];
-
-          retval.rep[n-1] = k;
-
-          return retval;
-        }
-    }
+  dim_vector redim (int n) const;
 
   dim_vector as_column (void) const
     {