changeset 4806:d3bd9c04147f

[project @ 2004-03-02 05:12:32 by jwe]
author jwe
date Tue, 02 Mar 2004 05:12:33 +0000
parents b0d6da24caeb
children 15e923b54eff
files liboctave/Array-C.cc liboctave/Array-ch.cc liboctave/Array-d.cc liboctave/Array.cc liboctave/Array.h liboctave/CNDArray.cc liboctave/CNDArray.h liboctave/ChangeLog liboctave/chNDArray.cc liboctave/chNDArray.h liboctave/dNDArray.cc liboctave/dNDArray.h liboctave/mx-inlines.cc scripts/ChangeLog scripts/miscellaneous/horzcat.m scripts/miscellaneous/vertcat.m src/Cell.cc src/Cell.h src/ChangeLog src/TEMPLATE-INST/Array-tc.cc src/data.cc src/oct-map.cc src/oct-map.h
diffstat 23 files changed, 358 insertions(+), 303 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/Array-C.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/Array-C.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -33,7 +33,7 @@
 
 INSTANTIATE_ARRAY_AND_ASSIGN (Complex);
 
-INSTANTIATE_CAT (Complex);
+INSTANTIATE_ARRAY_CAT (Complex);
 
 INSTANTIATE_ARRAY_ASSIGN (Complex, double);
 INSTANTIATE_ARRAY_ASSIGN (Complex, int);
--- a/liboctave/Array-ch.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/Array-ch.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -31,7 +31,7 @@
 
 INSTANTIATE_ARRAY_AND_ASSIGN (char);
 
-INSTANTIATE_CAT (char);
+INSTANTIATE_ARRAY_CAT (char);
 
 #include "Array2.h"
 
--- a/liboctave/Array-d.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/Array-d.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -31,7 +31,7 @@
 
 INSTANTIATE_ARRAY_AND_ASSIGN (double);
 
-INSTANTIATE_CAT (double);
+INSTANTIATE_ARRAY_CAT (double);
 
 INSTANTIATE_ARRAY_ASSIGN (double, int);
 INSTANTIATE_ARRAY_ASSIGN (double, short);
--- a/liboctave/Array.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/Array.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -966,6 +966,8 @@
 Array<T>&
 Array<T>::insertN (const Array<T>& a, int r, int c)
 {
+  dim_vector dv = dims ();
+
   dim_vector a_dv = a.dims ();
 
   int n = a_dv.length ();
@@ -979,7 +981,7 @@
 
       for (int i = 0; i < n; i++)
 	{
-	  if (a_ra_idx (i) < 0 || (a_ra_idx (i) + a_dv (i)) > dimensions (i))
+	  if (a_ra_idx(i) < 0 || (a_ra_idx(i) + a_dv(i)) > dv(i))
 	    {
 	      (*current_liboctave_error_handler)
 		("Array<T>::insert: range error for insert");
@@ -987,21 +989,29 @@
 	    }
 	}
 
-      a_ra_idx.elem (0) = 0;
-      a_ra_idx.elem (1) = 0;
-
       int n_elt = a.numel ();
-
+      
+      const T *a_data = a.data ();   
+   
+      int iidx = 0;
+	  
+      int a_rows = a_dv(0);
+
+      int this_rows = dv(0);
+	  
+      int numel_page = a_dv(0) * a_dv(1);	  
+
+      int count_pages = 0;
+	  
       for (int i = 0; i < n_elt; i++)
 	{
-	  Array<int> ra_idx = a_ra_idx;
-
-	  ra_idx.elem (0) = a_ra_idx (0) + r;
-	  ra_idx.elem (1) = a_ra_idx (1) + c;
-
-	  elem (ra_idx) = a.elem (a_ra_idx);
-
-	  increment_index (a_ra_idx, a_dv);
+	  if (i != 0 && i % a_rows == 0)
+	    iidx += (this_rows - a_rows);	      
+	  
+	  if (i % numel_page == 0)
+	    iidx = c * dv(0) + r + dv(0) * dv(1) * count_pages++;
+
+	  elem (iidx++) = a_data[i];
 	}
     }
   else
@@ -3066,35 +3076,26 @@
 }
 
 template <class T>
-bool
-cat_ra (Array<T>& ra_cat, const Array<T>& ra_arg, int dim, int add_dim)
+int
+cat_ra (Array<T>& ra, const Array<T>& ra_arg, int dim, int idx, int move)
 {
-  bool retval = false;
-
-  dim_vector dv = ra_arg.dims ();
-
-  Array<int> ra_idx (dv.length (), 0);
-
-  for (int i = 0; i < ra_arg.length (); i++)
-    {
-      if (i != 0)
-	increment_index (ra_idx, dv);
-
-      Array<int> ra_idx2 = ra_idx;
-
-      if (dim >= ra_idx2.length ())
-	{
-	  ra_idx2.resize_and_fill (dim + 1, 0);
-
-	  retval = true;
-	}
-
-      ra_idx2(dim) = ra_idx2(dim) + add_dim;
-
-      ra_cat(ra_idx2) = ra_arg(ra_idx);
-    }
-
-  return retval;
+  dim_vector dv_arg = ra_arg.dims (); 
+  
+  const T *arg_data = ra_arg.data ();
+  
+  int numel_to_move = dv_arg(0);
+
+  int numel_arg = dv_arg.length ();
+
+  int ii_limit = dim+1 > numel_arg ? numel_arg : dim + 1;
+  
+  for (int ii = 1; ii < ii_limit; ii++)
+    numel_to_move *= dv_arg(ii);
+
+  for (int j = 0; j < numel_to_move; j++)
+    ra.elem (idx++) = arg_data[numel_to_move * move + j];
+  
+  return idx;
 }
 
 template <class T>
--- a/liboctave/Array.h	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/Array.h	Tue Mar 02 05:12:33 2004 +0000
@@ -526,8 +526,8 @@
 // do that because of bugs in gcc prior to 3.3.
 
 template <class T>
-bool 
-cat_ra (Array<T>& ra_cat, const Array<T>& ra_arg, int dim, int add_dim);
+int 
+cat_ra (Array<T>& ra, const Array<T>& ra_arg, int dim, int idx, int move);
 
 template <class LT, class RT>
 /* friend */ int
@@ -564,9 +564,9 @@
   template class Array<T>; \
   template T resize_fill_value (const T&); \
 
-#define INSTANTIATE_CAT(T) \
-  template bool cat_ra (Array<T>& ra_cat, const Array<T>& ra_arg, \
-                        int dim, int add_dim)
+#define INSTANTIATE_ARRAY_CAT(T) \
+  template int cat_ra (Array<T>& ra, const Array<T>& ra_arg, \
+                       int dim, int idx, int move)
 
 #define INSTANTIATE_ARRAY_AND_ASSIGN(T) \
   INSTANTIATE_ARRAY (T); \
--- a/liboctave/CNDArray.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/CNDArray.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -677,10 +677,10 @@
   MX_ND_COMPLEX_OP_REDUCTION (+= elem (iter_idx), Complex (0, 0));
 }
 
-bool
-ComplexNDArray::cat (const ComplexNDArray& ra_arg, int dim, int add_dim)
+int
+ComplexNDArray::cat (const ComplexNDArray& ra_arg, int dim, int iidx, int move)
 {
-  MX_ND_CAT;
+  return ::cat_ra(*this, ra_arg, dim, iidx, move);
 }
 
 NDArray
--- a/liboctave/CNDArray.h	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/CNDArray.h	Tue Mar 02 05:12:33 2004 +0000
@@ -87,7 +87,7 @@
   ComplexNDArray prod (int dim = -1) const;
   ComplexNDArray sum (int dim = -1) const;
   ComplexNDArray sumsq (int dim = -1) const;
-  bool cat (const ComplexNDArray& ra_arg, int dim, int add_dim);
+  int cat (const ComplexNDArray& ra_arg, int dim, int iidx, int move);
 
   ComplexNDArray& insert (const NDArray& a, int r, int c);
   ComplexNDArray& insert (const ComplexNDArray& a, int r, int c);
--- a/liboctave/ChangeLog	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/ChangeLog	Tue Mar 02 05:12:33 2004 +0000
@@ -1,3 +1,17 @@
+2004-03-01  Petter Risholm  <risholm@idi.ntnu.no>
+
+	* Array.cc (Array<T>::insertN): Eliminate N-d indexing.
+
+        * mx-inlines.cc (MX_ND_CAT): Delete macro.
+
+        * dNDArray.h, chNDArray.h, CNDArray.h (cat): Change declaration.
+        * dNDArray.cc (NDArray<T>::cat): Call new form of cat function.
+        * chNDArray.cc (charNDArray<T>::cat): Ditto.
+        * CNDArray.cc (ComplexNDArray<T>::cat): Ditto.
+
+        * Array.h (cat_ra): Return int.  Accept idx and move args, not add_dim.
+        * Array.cc (cat_ra): Speed up implementation by avoiding N-d indexing.
+
 2004-02-24  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* oct-rl-edit.c (octave_rl_set_startup_hook,
--- a/liboctave/chNDArray.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/chNDArray.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -48,10 +48,10 @@
   MX_ND_ANY_ALL_REDUCTION (MX_ND_ANY_EVAL (elem (iter_idx) != ' '), false);
 }
 
-bool
-charNDArray::cat (const charNDArray& ra_arg, int dim, int add_dim)
+int
+charNDArray::cat (const charNDArray& ra_arg, int dim, int iidx, int move)
 {
-  MX_ND_CAT;  
+  return ::cat_ra(*this, ra_arg, dim, iidx, move);  
 }
 
 charMatrix
--- a/liboctave/chNDArray.h	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/chNDArray.h	Tue Mar 02 05:12:33 2004 +0000
@@ -71,7 +71,7 @@
 
   boolNDArray all (int dim = -1) const;
   boolNDArray any (int dim = -1) const;
-  bool cat (const charNDArray& ra_arg, int dim, int add_dim);
+  int cat (const charNDArray& ra_arg, int dim, int iidx, int move);
  
   charMatrix matrix_value (void) const;
 
--- a/liboctave/dNDArray.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/dNDArray.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -656,11 +656,10 @@
   MX_ND_REAL_OP_REDUCTION (+= elem (iter_idx), 0);
 }
 
-bool
-NDArray::cat (const NDArray& ra_arg, int dim, int add_dim)
+int
+NDArray::cat (const NDArray& ra_arg, int dim, int iidx, int move)
 {
-  //  MX_ND_CAT;
-  return ::cat_ra (*this, ra_arg, dim, add_dim);
+  return ::cat_ra (*this, ra_arg, dim, iidx, move);
 }
 
 NDArray
--- a/liboctave/dNDArray.h	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/dNDArray.h	Tue Mar 02 05:12:33 2004 +0000
@@ -86,7 +86,7 @@
   NDArray prod (int dim = -1) const;
   NDArray sum (int dim = -1) const;  
   NDArray sumsq (int dim = -1) const;
-  bool cat (const NDArray& ra_arg, int dim, int add_dim);
+  int cat (const NDArray& ra_arg, int dim, int iidx, int move);
      
   NDArray abs (void) const;
 
--- a/liboctave/mx-inlines.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/liboctave/mx-inlines.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -607,34 +607,6 @@
 \
   return retval
 
-#define MX_ND_CAT \
- bool retval = false;\
- \
-  dim_vector dv = ra_arg.dims (); \
- \
-   Array<int> ra_idx (dv.length (), 0); \
- \
-   for (int i = 0; i < ra_arg.length (); i++) \
-     { \
-       if (i != 0) \
-	 increment_index (ra_idx, dv, 0); \
- \
-       Array<int> ra_idx2 = ra_idx; \
- \
-       if (dim >= ra_idx2.length ()) \
-	 { \
-	   ra_idx2.resize_and_fill (dim + 1, 0); \
- \
-	   retval = true; \
-	 } \
- \
-       ra_idx2.elem (dim) = ra_idx2.elem (dim) + add_dim; \
- \
-       elem (ra_idx2) =  ra_arg.elem (ra_idx); \
-     } \
- \
-   return retval
-
 #endif
 
 /*
--- a/scripts/ChangeLog	Tue Mar 02 03:43:15 2004 +0000
+++ b/scripts/ChangeLog	Tue Mar 02 05:12:33 2004 +0000
@@ -1,3 +1,8 @@
+2004-03-01  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* miscellaneous/horzcat.m: Delete.
+	* miscellaneous/vertcat.m: Delete.
+
 2004-02-19  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* plot/figure.m: Also look for GNUTERM in the environment and use
--- a/scripts/miscellaneous/horzcat.m	Tue Mar 02 03:43:15 2004 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-## Copyright (C) 2003 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, write to the Free
-## Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-## 02111-1307, USA.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {@var{c} =} horzcat (@var{a}, @var{b}, @dots{})
-## Equivalent to @code{c = [a, b, ...]}.
-## @end deftypefn
-
-function c = horzcat (varargin)
-
-  ## This is just a quick fix for compatibility.
-
-  if (nargin > 1)
-    c = [ varargin{:} ];
-  else
-    usage ("horzcat (a, b, ...)");
-  endif
-
-endfunction
--- a/scripts/miscellaneous/vertcat.m	Tue Mar 02 03:43:15 2004 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-## Copyright (C) 2003 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, write to the Free
-## Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-## 02111-1307, USA.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {@var{c} =} vertcat (@var{a}, @var{b}, @dots{})
-## Equivalent to @code{c = [a; b; ...]}.
-## @end deftypefn
-
-function c = vertcat (varargin)
-
-  ## This is just a quick fix for compatibility.
-
-  if (nargin > 1)
-    for i = 1:nargin
-      varargin{i} = varargin{i}.';
-    endfor
-    c = [ varargin{:} ].';
-  else
-    usage ("vertcat (a, b, ...)");
-  endif
-
-endfunction
--- a/src/Cell.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/src/Cell.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -100,6 +100,12 @@
   return *this;
 }
 
+int
+Cell::cat (const Cell& ra_arg, int dim, int iidx, int move)
+{
+  return ::cat_ra (*this, ra_arg, dim, iidx, move);
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/Cell.h	Tue Mar 02 03:43:15 2004 +0000
+++ b/src/Cell.h	Tue Mar 02 05:12:33 2004 +0000
@@ -96,6 +96,8 @@
   // XXX FIXME XXX
   boolMatrix any (int dim = 0) const { return boolMatrix (); }
 
+  int cat (const Cell& ra_arg, int dim, int iidx, int move);
+
   // XXX FIXME XXX
   bool is_true (void) const { return false; }
 
--- a/src/ChangeLog	Tue Mar 02 03:43:15 2004 +0000
+++ b/src/ChangeLog	Tue Mar 02 05:12:33 2004 +0000
@@ -1,3 +1,17 @@
+2004-03-01  Petter Risholm  <risholm@idi.ntnu.no>
+
+        * Cell.cc (Cell::cat): New function.
+        * Cell.h: Provide decl.
+
+        * oct-map.cc (Octave_map::cat): New function.
+        * oct-map.h: Provide decl.
+
+        * data.cc (Fcat): Speedup implementation.
+
+        * data.cc (Fhorzcat, Fvertcat): New functions.
+
+        * Array-tc.cc: Instantiate cat function.
+
 2004-03-01  David Bateman  <dbateman@free.fr>
  
 	* ls-hdf5.cc (save_hdf5_empty, load_hdf5_empty): New functions
--- a/src/TEMPLATE-INST/Array-tc.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/src/TEMPLATE-INST/Array-tc.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -51,6 +51,8 @@
 
 INSTANTIATE_ARRAY_ASSIGN (octave_value, octave_value);
 
+INSTANTIATE_ARRAY_CAT (octave_value);
+
 template class Array2<octave_value>;
 
 template class ArrayN<octave_value>;
--- a/src/data.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/src/data.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -40,6 +40,8 @@
 #include "variables.h"
 #include "oct-obj.h"
 #include "utils.h"
+#include "Cell.h"
+#include "oct-map.h"
 
 #define ANY_ALL(FCN) \
  \
@@ -750,10 +752,248 @@
   return true;
 }
 
+octave_value do_cat (const octave_value_list& args)
+{
+  octave_value retval;
+ 
+  int dim = args(0).int_value () - 1;
+
+  int n_args = args.length ();
+ 
+  if (error_state)
+    {
+      error ("cat: expecting first argument to be a integer");
+      return retval;
+    }
+  
+  if (n_args > 2 && dim >= 0)
+    {      
+      dim_vector  dv = args(1).dims ();
+  
+      for (int i = 2; i < args.length (); i++)
+	{
+	  // add_dims constructs a dimension vector which holds the
+	  // dimensions of the final array after concatenation.
+
+	  if (! cat_add_dims (dv, args(i).dims (), dim))
+	    {
+	      // Dimensions do not match. 
+	      // cat_add_dims printed a error msg
+	      return retval;
+	    }
+	}
+
+      NDArray cat_re;
+      ComplexNDArray cat_cx;
+      charNDArray cat_ch;
+      Cell cat_cell;
+      Octave_map cat_map;
+
+      // The final array can be of three types:
+      //
+      //       re cx ch c
+      // ----------------
+      // re   |re cx ch X
+      // cx   |cx cx X  X
+      // ch   |ch X  ch X
+      // cell |X  X  X  c
+      // (X means incompatible).
+
+      enum types { REAL, COMPLEX, CHAR, CELL, MAP} t;      
+
+      // Initialize t to right value
+      if (args(1).is_cell ())
+	{
+	  t = CELL;
+	  cat_cell = Cell (dv);
+	}
+      else if (args(1).is_map ())
+	{
+	  error ("concatenation of structures is not yet implemented");
+	  return retval;
+	  // t = MAP;
+	  // cat_map = Octave_map (dv);
+	}
+      else 
+	{
+	  t = REAL;
+	  cat_re = NDArray (dv, 0);
+	}
+ 
+      int idx = 0;
+  
+      dim_vector dv_first = args(1).dims ();
+      
+      // n_moves tells us how many times we need to
+      // visit each argument.
+      //
+      // If we are concatenating a 2x2x2 array with a 2x2x2 array
+      // along the second dimensions, we do two iterations
+      // trough the arguments and move 2x2 elements from each
+      // of the arguments into the resulting array on each iteration.
+      int n_moves = 1;
+
+      for (int i = dim + 1; i < dv_first.length (); i++)
+	n_moves *= dv_first(i);
+      
+      for (int move = 0; move < n_moves ; move++)
+	{     
+	  for (int i = 1; i < n_args; i++)
+	    {
+	      octave_value tmp = args (i);
+
+	      if (t == MAP)
+		{
+		  error ("concatenation of structures is not yet implemented");
+		  return retval;
+		}
+	      else if (t == CELL)
+		{
+		  if (! tmp.is_cell ())
+		    {
+		      error ("cannot convert argument to cell");
+		      return retval;
+		    }
+		  else
+		    {
+			Cell ra_tmp = args(i).cell_value ();
+	  
+			if (error_state)
+			  return retval;
+
+			idx = cat_cell.cat (ra_tmp, dim, idx, move);
+		    }
+		}
+	      else if (t == REAL)
+		{
+		  if (tmp.is_complex_type ())
+		    {
+		      cat_cx = ComplexNDArray (cat_re);		  
+		  
+		      ComplexNDArray ra_tmp = tmp.complex_array_value ();
+	  
+		      if (error_state)
+			return retval;
+
+		      idx = cat_cx.cat (ra_tmp, dim, idx, move);
+
+		      t = COMPLEX;
+		    }
+		  else if (tmp.is_string ())
+		    {
+		      // This is a hack to be able to convert a dNDArray
+		      // to a chNDArray.
+
+		      cat_ch = charNDArray (octave_value (cat_re).char_array_value ());	  
+		  
+		      charNDArray ra_tmp = tmp.char_array_value ();
+	  
+		      if (error_state)
+			return retval;
+
+		      idx = cat_ch.cat (ra_tmp, dim, idx, move);
+	
+		      t = CHAR;
+		    }
+		  else //if (tmp.is_real_type ())
+		    { 
+		      NDArray ra_tmp = tmp.array_value ();
+	
+		      if (error_state)
+			return retval;
+		
+		      idx = cat_re.cat (ra_tmp, dim, idx, move);
+		    }  
+		}
+	      else if (t == COMPLEX)
+		{
+		  ComplexNDArray ra_tmp = tmp.complex_array_value ();
+	  
+		  if (error_state)
+		    return retval;
+
+		  idx = cat_cx.cat (ra_tmp, dim, idx, move);
+		}
+	      else if (t == CHAR)
+		{
+		  if (tmp.is_complex_type ())
+		    {
+		      error ("cannot convert complex type to character type");
+		      return retval;
+		    }
+		  else
+		    {
+		      charNDArray ra_tmp = tmp.char_array_value ();
+	  
+		      if (error_state)
+			return retval;
+
+		      cat_ch.cat (ra_tmp, dim, idx, move);
+		    }
+		}
+	    }
+	}
+      
+      if (t == REAL)
+	retval = octave_value (cat_re);
+      else if (t == COMPLEX)
+	retval = octave_value (cat_cx);
+      else if (t == CHAR)
+	retval = octave_value (cat_ch);
+      else if (t == CELL)
+	retval = octave_value (cat_cell);
+      else if (t == MAP)
+	retval = octave_value (cat_map);
+    }
+  else
+    print_usage ("cat");
+ 
+  return retval;
+}
+
+DEFUN (horzcat, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} horzcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})\n\
+Return the horizontal concatenation of N-d array objects, @var{array1},\n\
+@var{array2}, @dots{}, @var{arrayN} along dimension 2.\n\
+@end deftypefn\n\
+@seealso{cat and vertcat}")
+{
+  octave_value_list args_tmp = args;
+  
+  int dim = 2;
+  
+  octave_value d (dim);
+  
+  args_tmp.prepend (d);
+  
+  return do_cat (args_tmp);
+}
+
+DEFUN (vertcat, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} vertcat (@var{array1}, @var{array2}, @dots{}, @var{arrayN})\n\
+Return the vertical concatenation of N-d array objects, @var{array1},\n\
+@var{array2}, @dots{}, @var{arrayN} along dimension 1.\n\
+@end deftypefn\n\
+@seealso{cat and horzcat}")
+{
+  octave_value_list args_tmp = args;
+  
+  int dim = 1;
+  
+  octave_value d (dim);
+  
+  args_tmp.prepend (d);
+  
+  return do_cat (args_tmp);
+}
+
 DEFUN (cat, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} cat (@var{dim}, @var{array1}, @var{array2}, @dots{}, @var{arrayN})\n\
-Return the concatenation of N-d array objects, @var{array1}, @var{array2}, @dots{}, @var{arrayN} along dimension @var{dim}.\n\
+Return the concatenation of N-d array objects, @var{array1},\n\
+@var{array2}, @dots{}, @var{arrayN} along dimension @var{dim}.\n\
 \n\
 @example\n\
 @group\n\
@@ -797,146 +1037,10 @@
 @end group\n\
 @end example\n\
 \n\
-@seealso{horzcat and vertcat}\n\
-@end deftypefn")
+@end deftypefn\n\
+@seealso{horzcat and vertcat}")
 {
-  octave_value retval;
-
-  int dim = args(0).int_value () - 1;
-
-  if (error_state)
-    {
-      error ("cat: expecting first argument to be a integer");
-      return retval;
-    }
-
-  if (args.length () > 2 && (dim >= 0))
-    {      
-      dim_vector  dv = args(1).dims ();
-
-      // I need to look into these conversions.
-
-      for (int i = 2; i < args.length (); i++)
-	{
-	  // add_dims constructs a dimension vector which holds the
-	  // dimensions of the final array after concatenation.
-
-	  if (! cat_add_dims (dv, args(i).dims (), dim))
-	    {
-	      // Dimensions do not match.
-	      return retval;
-	    }
-	}
-
-      NDArray cat_re = NDArray (dv, 0);
-      ComplexNDArray cat_cx;
-      charNDArray cat_ch;
-
-      // The final array can be of three types:
-      //
-      //     re cx ch
-      // --------------
-      // re |re cx ch
-      // cx |cx cx X
-      // ch |ch X  ch
-      //
-      // (X means incompatible).
-
-      enum types { REAL, COMPLEX, CHAR } t = REAL;      
-
-      // Variable which tells us how much we have extended the
-      // variable along the dim dimension.
-
-      int curr_add_dims = 0;
-
-      // Tells us wether the array we concatenated had fewer dimensions
-      // than dim, such that we only add one dimension to
-      // curr_add_dims.
-
-      bool extended_dims = false;
-      
-      // Start filling in values.
-
-      for (int i = 1; i < args.length (); i++)
-	{
-	  octave_value tmp = args (i);
-
-	  dim_vector dv_arg = tmp.dims ();
-
-	  // This variable tells us wether the the new value is has a
-	  // number of dimension less than the final value.
-
-	  extended_dims = false;
-	  
-	  if (t == REAL)
-	    {
-	      if (tmp.is_complex_type ())
-		{
-		  cat_cx = ComplexNDArray (cat_re);
-		  
-		  extended_dims =
-		    cat_cx.cat (tmp.complex_array_value (), dim, curr_add_dims);
-		  
-		  t = COMPLEX;
-		}
-	      else if (tmp.is_string ())
-		{
-		  // This is a hack to be able to convert a dNDArray
-		  // to a chNDArray.
-
-		  cat_ch = charNDArray (octave_value (cat_re).char_array_value ());
-		  
-		  extended_dims =
-		    cat_ch.cat (tmp.char_array_value (), dim, curr_add_dims);
-		  
-		  t = CHAR;
-		}
-	      else
-		extended_dims = 
-		  cat_re.cat (tmp.array_value(), dim, curr_add_dims);
-	    }
-	  else if (t == COMPLEX)
-	    {
-	      extended_dims = 
-		cat_cx.cat (tmp.complex_array_value (), dim, curr_add_dims);
-	    }
-	  else if (t == CHAR)
-	    {
-	      if (tmp.is_complex_type ())
-		{
-		  error ("cannot convert complex type to character type");
-		  return retval;
-		}
-	      else
-		extended_dims =
-		  cat_ch.cat (tmp.char_array_value (), dim, curr_add_dims);
-	    }
-	  
-	  if (error_state)
-	    {
-	      // Wrong conversion in the last if statement.
-	      return retval;
-	    }
-
-	  // Keep track of how many dimensions have been added.
-
-	  if (extended_dims)
-	    curr_add_dims++;
-	  else
-	    curr_add_dims += dv_arg (dim);
-	}
-
-      if (t == REAL)
-	retval = octave_value (cat_re);
-      else if (t == COMPLEX)
-	retval = octave_value (cat_cx);
-      else if (t == CHAR)
-	retval = octave_value (cat_ch);
-    }
-  else
-    print_usage ("cat");
-
-  return retval;
+  return do_cat (args);
 }
 
 static octave_value
--- a/src/oct-map.cc	Tue Mar 02 03:43:15 2004 +0000
+++ b/src/oct-map.cc	Tue Mar 02 05:12:33 2004 +0000
@@ -88,6 +88,13 @@
   return retval;
 }
 
+int
+Octave_map::cat (const Octave_map& ra_arg, int dim, int iidx, int move)
+{
+  //return ::cat_ra (*this, ra_arg, dim, iidx, move);
+  return 0;
+}
+
 static string_vector
 equiv_keys (const Octave_map& a, const Octave_map& b)
 {
--- a/src/oct-map.h	Tue Mar 02 03:43:15 2004 +0000
+++ b/src/oct-map.h	Tue Mar 02 05:12:33 2004 +0000
@@ -118,6 +118,8 @@
 
   int numel (void) const;
 
+  int cat (const Octave_map& ra_arg, int dim, int iidx, int move);
+
   Octave_map& assign (const octave_value_list& idx, const Octave_map& rhs);
 
   Octave_map& assign (const octave_value_list& idx, const std::string& k,