CAT speedup
Petter Risholm <[email protected]> Sun, 29 Feb 2004 15:11:15 +0100 (MET)
| Newsgroups | gmane.comp.gnu.octave.sources |
|---|---|
| Message-ID | <[email protected]> |
hi, I've reimplemented the cat function which has resulted in a considerable speedup. As it is now, it should be comparable to matlab's cat function when it comes to speed. The reason for the speedup comes mainly from elimination of all N-d indexing which was the bottleneck in the old version. This patch also provides horzcat and vertcat. They are currently called horzcat2 and vertcat2 since there already are a couple of .m scripts for doing horzcat and vertcat (I'm pretty sure they are quite a bit slower than my version for N-d concatenation, so I would recommend removing those .m files from the distribution). See attachment for patch. ChangeLog: 2004-02-29 Petter Risholm <[email protected]> * mx-inlines.cc (MX_ND_CAT): delete macro. * dNDArray.h, chNDArray.h, CNDArray.h (cat): Change declaration. * dNDArray.cc (NDArray<T>::cat): Change defintion. * chNDArray.cc (charNDArray<T>::cat): Ditto. * CNDArray.cc (ComplexNDArray<T>::cat): Ditto. * Array.h (cat_ra): Change declaration. * Array.cc (cat_ra): Speed up implementation by avoiding N-d indexing. 2004-02-29 Petter Risholm <[email protected]> * Cell.h (cat): New function. * Cell.h (Cell::cat): Provide definition. * oct-map.h (cat): New function. * oct-map.cc (Octave_map::cat): Provide definition. * data.cc (Fcat): Speedup implementation. * data.cc (Fhorzcat): New function. * data.cc (Fvertcat): New function. * Array-tc.cc (INSTANTIATE_CAT): Instantiate cat function. Petter Risholm
ChangeLog
(text/plain, 831 B)
2004-02-29 Petter Risholm <[email protected]> * mx-inlines.cc (MX_ND_CAT): delete macro. * dNDArray.h, chNDArray.h, CNDArray.h (cat): Change declaration. * dNDArray.cc (NDArray<T>::cat): Change defintion. * chNDArray.cc (charNDArray<T>::cat): Ditto. * CNDArray.cc (ComplexNDArray<T>::cat): Ditto. * Array.h (cat_ra): Change declaration. * Array.cc (cat_ra): Speed up implementation by avoiding N-d indexing. 2004-02-29 Petter Risholm <[email protected]> * Cell.h (cat): New function. * Cell.h (Cell::cat): Provide definition. * oct-map.h (cat): New function. * oct-map.cc (Octave_map::cat): Provide definition. * data.cc (Fcat): Speedup implementation. * data.cc (Fhorzcat): New function. * data.cc (Fvertcat): New function. * Array-tc.cc (INSTANTIATE_CAT): Instantiate cat function.
cat.src.patch
(text/plain, 15.3 KB)
Index: TEMPLATE-INST/Array-tc.cc
===================================================================
RCS file: /cvs/octave/src/TEMPLATE-INST/Array-tc.cc,v
retrieving revision 1.16
diff -c -p -r1.16 Array-tc.cc
*** TEMPLATE-INST/Array-tc.cc 2003/11/25 05:41:36 1.16
--- TEMPLATE-INST/Array-tc.cc 2004/02/29 13:50:49
*************** template class Array<octave_value>;
*** 51,56 ****
--- 51,58 ----
INSTANTIATE_ARRAY_ASSIGN (octave_value, octave_value);
+ INSTANTIATE_CAT (octave_value);
+
template class Array2<octave_value>;
template class ArrayN<octave_value>;
Index: Cell.cc
===================================================================
RCS file: /cvs/octave/src/Cell.cc,v
retrieving revision 1.10
diff -c -p -r1.10 Cell.cc
*** Cell.cc 2003/11/15 12:51:20 1.10
--- Cell.cc 2004/02/29 13:50:49
*************** Cell::assign (const octave_value_list& i
*** 100,105 ****
--- 100,111 ----
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++ ***
Index: Cell.h
===================================================================
RCS file: /cvs/octave/src/Cell.h,v
retrieving revision 1.17
diff -c -p -r1.17 Cell.h
*** Cell.h 2004/01/21 19:55:36 1.17
--- Cell.h 2004/02/29 13:50:49
*************** public:
*** 96,101 ****
--- 96,103 ----
// 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; }
Index: oct-map.h
===================================================================
RCS file: /cvs/octave/src/oct-map.h,v
retrieving revision 1.30
diff -c -p -r1.30 oct-map.h
*** oct-map.h 2004/02/06 05:46:22 1.30
--- oct-map.h 2004/02/29 13:50:50
*************** Octave_map
*** 118,123 ****
--- 118,125 ----
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,
Index: oct-map.cc
===================================================================
RCS file: /cvs/octave/src/oct-map.cc,v
retrieving revision 1.31
diff -c -p -r1.31 oct-map.cc
*** oct-map.cc 2004/02/02 18:31:09 1.31
--- oct-map.cc 2004/02/29 13:50:50
*************** Octave_map::numel (void) const
*** 88,93 ****
--- 88,100 ----
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)
{
Index: data.cc
===================================================================
RCS file: /cvs/octave/src/data.cc,v
retrieving revision 1.124
diff -c -p -r1.124 data.cc
*** data.cc 2004/02/16 15:23:22 1.124
--- data.cc 2004/02/29 13:50:53
*************** Software Foundation, 59 Temple Place - S
*** 40,45 ****
--- 40,47 ----
#include "variables.h"
#include "oct-obj.h"
#include "utils.h"
+ #include "Cell.h"
+ #include "oct-map.h"
#define ANY_ALL(FCN) \
\
*************** cat_add_dims (dim_vector& dv_new, const
*** 750,821 ****
return true;
}
! 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\
! \n\
! @example\n\
! @group\n\
! A = ones (2, 2);\n\
! B = zeros (2, 2);\n\
! cat (2, A, B)\n\
! @result{} ans =\n\
! \n\
! 1 1 0 0\n\
! 1 1 0 0\n\
! 1 1 0 0\n\
! 1 1 0 0\n\
! @end group\n\
! @end example\n\
! \n\
! Alternatively, we can concatenate @var{A} and @var{B} along the\n\
! second dimension the following way:\n\
! \n\
! @example\n\
! @group\n\
! [A, B].\n\
! @end group\n\
! @end example\n\
! \n\
! @var{dim} can be larger than the dimensions of the N-d array objects\n\
! and the result will thus have @var{dim} dimensions as the\n\
! following example shows:\n\
! @example\n\
! @group\n\
! cat (4, ones(2, 2), zeros (2, 2))\n\
! @result{} ans =\n\
! \n\
! ans(:,:,1,1) =\n\
! \n\
! 1 1\n\
! 1 1\n\
! \n\
! ans(:,:,1,2) =\n\
! 0 0\n\
! 0 0\n\
! @end group\n\
! @end example\n\
! \n\
! @seealso{horzcat and vertcat}\n\
! @end deftypefn")
{
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
--- 752,775 ----
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
*************** cat (4, ones(2, 2), zeros (2, 2))\n\
*** 823,942 ****
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;
}
static octave_value
--- 777,1045 ----
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 (horzcat2, 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}, @var{array2}, @dots{}, @var{arrayN} along dimension @var{dim}.\n\
+ \n\
+ @seealso{cat and vertcat}\n\
+ @end deftypefn")
+ {
+ octave_value_list args_tmp = args;
+
+ int dim = 2;
+
+ octave_value d (dim);
+
+ args_tmp.prepend (d);
+
+ return do_cat(args_tmp);
+ }
+
+ DEFUN (vertcat2, 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}, @var{array2}, @dots{}, @var{arrayN} along dimension @var{dim}.\n\
+ \n\
+ @seealso{cat and horzcat}\n\
+ @end deftypefn")
+ {
+ 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\
+ \n\
+ @example\n\
+ @group\n\
+ A = ones (2, 2);\n\
+ B = zeros (2, 2);\n\
+ cat (2, A, B)\n\
+ @result{} ans =\n\
+ \n\
+ 1 1 0 0\n\
+ 1 1 0 0\n\
+ 1 1 0 0\n\
+ 1 1 0 0\n\
+ @end group\n\
+ @end example\n\
+ \n\
+ Alternatively, we can concatenate @var{A} and @var{B} along the\n\
+ second dimension the following way:\n\
+ \n\
+ @example\n\
+ @group\n\
+ [A, B].\n\
+ @end group\n\
+ @end example\n\
+ \n\
+ @var{dim} can be larger than the dimensions of the N-d array objects\n\
+ and the result will thus have @var{dim} dimensions as the\n\
+ following example shows:\n\
+ @example\n\
+ @group\n\
+ cat (4, ones(2, 2), zeros (2, 2))\n\
+ @result{} ans =\n\
+ \n\
+ ans(:,:,1,1) =\n\
+ \n\
+ 1 1\n\
+ 1 1\n\
+ \n\
+ ans(:,:,1,2) =\n\
+ 0 0\n\
+ 0 0\n\
+ @end group\n\
+ @end example\n\
+ \n\
+ @seealso{horzcat and vertcat}\n\
+ @end deftypefn")
+ {
+ return do_cat(args);
}
static octave_value
cat.liboctave.patch
(text/plain, 8.9 KB)
Index: mx-inlines.cc
===================================================================
RCS file: /cvs/octave/liboctave/mx-inlines.cc,v
retrieving revision 1.31
diff -c -p -r1.31 mx-inlines.cc
*** mx-inlines.cc 2004/02/16 05:07:23 1.31
--- mx-inlines.cc 2004/02/29 13:39:46
*************** OP_DUP_FCN (conj, mx_inline_conj_dup, Co
*** 607,640 ****
\
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
/*
--- 607,612 ----
Index: dNDArray.cc
===================================================================
RCS file: /cvs/octave/liboctave/dNDArray.cc,v
retrieving revision 1.16
diff -c -p -r1.16 dNDArray.cc
*** dNDArray.cc 2004/02/17 15:32:13 1.16
--- dNDArray.cc 2004/02/29 13:39:47
*************** NDArray::sum (int dim) const
*** 656,666 ****
MX_ND_REAL_OP_REDUCTION (+= elem (iter_idx), 0);
}
! bool
! NDArray::cat (const NDArray& ra_arg, int dim, int add_dim)
{
! // MX_ND_CAT;
! return ::cat_ra (*this, ra_arg, dim, add_dim);
}
NDArray
--- 656,665 ----
MX_ND_REAL_OP_REDUCTION (+= elem (iter_idx), 0);
}
! int
! NDArray::cat (const NDArray& ra_arg, int dim, int iidx, int move)
{
! return ::cat_ra (*this, ra_arg, dim, iidx, move);
}
NDArray
Index: dNDArray.h
===================================================================
RCS file: /cvs/octave/liboctave/dNDArray.h,v
retrieving revision 1.13
diff -c -p -r1.13 dNDArray.h
*** dNDArray.h 2004/02/16 19:02:32 1.13
--- dNDArray.h 2004/02/29 13:39:47
*************** public:
*** 86,92 ****
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);
NDArray abs (void) const;
--- 86,92 ----
NDArray prod (int dim = -1) const;
NDArray sum (int dim = -1) const;
NDArray sumsq (int dim = -1) const;
! int cat (const NDArray& ra_arg, int dim, int iidx, int move);
NDArray abs (void) const;
Index: chNDArray.h
===================================================================
RCS file: /cvs/octave/liboctave/chNDArray.h,v
retrieving revision 1.6
diff -c -p -r1.6 chNDArray.h
*** chNDArray.h 2004/02/16 05:07:23 1.6
--- chNDArray.h 2004/02/29 13:39:47
*************** public:
*** 71,77 ****
boolNDArray all (int dim = -1) const;
boolNDArray any (int dim = -1) const;
! bool cat (const charNDArray& ra_arg, int dim, int add_dim);
charMatrix matrix_value (void) const;
--- 71,77 ----
boolNDArray all (int dim = -1) const;
boolNDArray any (int dim = -1) const;
! int cat (const charNDArray& ra_arg, int dim, int iidx, int move);
charMatrix matrix_value (void) const;
Index: chNDArray.cc
===================================================================
RCS file: /cvs/octave/liboctave/chNDArray.cc,v
retrieving revision 1.9
diff -c -p -r1.9 chNDArray.cc
*** chNDArray.cc 2004/02/16 16:22:43 1.9
--- chNDArray.cc 2004/02/29 13:39:48
*************** charNDArray::any (int dim) const
*** 48,57 ****
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)
{
! MX_ND_CAT;
}
charMatrix
--- 48,57 ----
MX_ND_ANY_ALL_REDUCTION (MX_ND_ANY_EVAL (elem (iter_idx) != ' '), false);
}
! int
! charNDArray::cat (const charNDArray& ra_arg, int dim, int iidx, int move)
{
! return ::cat_ra(*this, ra_arg, dim, iidx, move);
}
charMatrix
Index: CNDArray.cc
===================================================================
RCS file: /cvs/octave/liboctave/CNDArray.cc,v
retrieving revision 1.16
diff -c -p -r1.16 CNDArray.cc
*** CNDArray.cc 2004/02/17 15:32:13 1.16
--- CNDArray.cc 2004/02/29 13:39:49
*************** ComplexNDArray::sum (int dim) const
*** 677,686 ****
MX_ND_COMPLEX_OP_REDUCTION (+= elem (iter_idx), Complex (0, 0));
}
! bool
! ComplexNDArray::cat (const ComplexNDArray& ra_arg, int dim, int add_dim)
{
! MX_ND_CAT;
}
NDArray
--- 677,686 ----
MX_ND_COMPLEX_OP_REDUCTION (+= elem (iter_idx), Complex (0, 0));
}
! int
! ComplexNDArray::cat (const ComplexNDArray& ra_arg, int dim, int iidx, int move)
{
! return ::cat_ra(*this, ra_arg, dim, iidx, move);
}
NDArray
Index: CNDArray.h
===================================================================
RCS file: /cvs/octave/liboctave/CNDArray.h,v
retrieving revision 1.13
diff -c -p -r1.13 CNDArray.h
*** CNDArray.h 2004/02/16 19:02:32 1.13
--- CNDArray.h 2004/02/29 13:39:49
*************** public:
*** 87,93 ****
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);
ComplexNDArray& insert (const NDArray& a, int r, int c);
ComplexNDArray& insert (const ComplexNDArray& a, int r, int c);
--- 87,93 ----
ComplexNDArray prod (int dim = -1) const;
ComplexNDArray sum (int dim = -1) const;
ComplexNDArray sumsq (int dim = -1) const;
! 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);
Index: Array.h
===================================================================
RCS file: /cvs/octave/liboctave/Array.h,v
retrieving revision 1.85
diff -c -p -r1.85 Array.h
*** Array.h 2004/02/18 12:52:20 1.85
--- Array.h 2004/02/29 13:39:50
*************** public:
*** 526,533 ****
// 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);
template <class LT, class RT>
/* friend */ int
--- 526,533 ----
// do that because of bugs in gcc prior to 3.3.
template <class T>
! int
! cat_ra (Array<T>& ra, const Array<T>& ra_arg, int dim, int idx, int move);
template <class LT, class RT>
/* friend */ int
*************** assign (Array<LT>& lhs, const Array<RT>&
*** 565,572 ****
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_AND_ASSIGN(T) \
INSTANTIATE_ARRAY (T); \
--- 565,572 ----
template T resize_fill_value (const T&); \
#define INSTANTIATE_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); \
Index: Array.cc
===================================================================
RCS file: /cvs/octave/liboctave/Array.cc,v
retrieving revision 1.106
diff -c -p -r1.106 Array.cc
*** Array.cc 2004/02/23 15:35:00 1.106
--- Array.cc 2004/02/29 13:39:53
*************** assignN (Array<LT>& lhs, const Array<RT>
*** 3066,3100 ****
}
template <class T>
! bool
! cat_ra (Array<T>& ra_cat, const Array<T>& ra_arg, int dim, int add_dim)
{
! 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;
}
template <class T>
--- 3066,3093 ----
}
template <class T>
! int
! cat_ra (Array<T>& ra, const Array<T>& ra_arg, int dim, int idx, int move)
{
! 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>