Mercurial > hg > octave-thorsten
changeset 4915:c638c144d4da
[project @ 2004-07-23 19:01:22 by jwe]
line wrap: on
line diff
--- a/liboctave/Array-C.cc +++ b/liboctave/Array-C.cc @@ -33,8 +33,6 @@ INSTANTIATE_ARRAY_AND_ASSIGN (Complex); -INSTANTIATE_ARRAY_CAT (Complex); - INSTANTIATE_ARRAY_ASSIGN (Complex, double); INSTANTIATE_ARRAY_ASSIGN (Complex, int); INSTANTIATE_ARRAY_ASSIGN (Complex, short);
--- a/liboctave/Array-ch.cc +++ b/liboctave/Array-ch.cc @@ -31,8 +31,6 @@ INSTANTIATE_ARRAY_AND_ASSIGN (char); -INSTANTIATE_ARRAY_CAT (char); - #include "Array2.h" template class Array2<char>;
--- a/liboctave/Array-d.cc +++ b/liboctave/Array-d.cc @@ -31,8 +31,6 @@ INSTANTIATE_ARRAY_AND_ASSIGN (double); -INSTANTIATE_ARRAY_CAT (double); - INSTANTIATE_ARRAY_ASSIGN (double, int); INSTANTIATE_ARRAY_ASSIGN (double, short); INSTANTIATE_ARRAY_ASSIGN (double, char);
--- a/liboctave/Array-i.cc +++ b/liboctave/Array-i.cc @@ -46,16 +46,6 @@ INSTANTIATE_ARRAY_AND_ASSIGN (octave_uint32); INSTANTIATE_ARRAY_AND_ASSIGN (octave_uint64); -INSTANTIATE_ARRAY_CAT (octave_int8); -INSTANTIATE_ARRAY_CAT (octave_int16); -INSTANTIATE_ARRAY_CAT (octave_int32); -INSTANTIATE_ARRAY_CAT (octave_int64); - -INSTANTIATE_ARRAY_CAT (octave_uint8); -INSTANTIATE_ARRAY_CAT (octave_uint16); -INSTANTIATE_ARRAY_CAT (octave_uint32); -INSTANTIATE_ARRAY_CAT (octave_uint64); - #include "Array2.h" template class Array2<int>;
--- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -570,8 +570,9 @@ dim_vector dv_old = dimensions; int dv_old_orig_len = dv_old.length (); dimensions = dv; - - if (ts > 0 && dv_old_orig_len > 0) + int ts_old = get_size (dv_old); + + if (ts > 0 && ts_old > 0 && dv_old_orig_len > 0) { Array<int> ra_idx (dimensions.length (), 0); @@ -1040,11 +1041,14 @@ if (n == dimensions.length ()) { - dim_vector a_dims = a.dims (); + dim_vector dva = a.dims (); + dim_vector dv = dims (); + int len_a = dva.length (); for (int i = 0; i < n; i++) { - if (ra_idx(i) < 0 || ra_idx(i) + a_dims(i) > dimensions(i)) + if (ra_idx(i) < 0 || (ra_idx(i) + + (i < len_a ? dva(i) : 1)) > dimensions(i)) { (*current_liboctave_error_handler) ("Array<T>::insert: range error for insert"); @@ -1052,15 +1056,39 @@ } } - -#if 0 - // XXX FIXME XXX -- need to copy elements - - for (int j = 0; j < a_cols; j++) - for (int i = 0; i < a_rows; i++) - elem (r+i, c+j) = a.elem (i, j); -#endif - + if (dva.numel ()) + { + const T *a_data = a.data (); + int numel_to_move = dva (0); + int skip = dv (0); + for (int i = 0; i < len_a - 1; i++) + if (ra_idx(i) == 0 && dva(i) == dv(i)) + { + numel_to_move *= dva(i+1); + skip *= dv(i+1); + } + else + { + skip -= dva(i); + break; + } + + int jidx = ra_idx (n - 1); + for (int i = n-2; i >= 0; i--) + { + jidx *= dv (i); + jidx += ra_idx (i); + } + + int iidx = 0; + int moves = dva.numel () / numel_to_move; + for (int i = 0; i < moves; i++) + { + for (int j = 0; j < numel_to_move; j++) + elem (jidx++) = a_data[iidx++]; + jidx += skip; + } + } } else (*current_liboctave_error_handler) @@ -3081,29 +3109,6 @@ } 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> void Array<T>::print_info (std::ostream& os, const std::string& prefix) const {
--- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -543,10 +543,6 @@ // Array<T>::dimensions should be protected, not public, but we can't // 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>& rhs, const LT& rfv); @@ -582,10 +578,6 @@ template class Array<T>; \ template T resize_fill_value (const T&); \ -#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); \ INSTANTIATE_ARRAY_ASSIGN (T, T)
--- a/liboctave/CNDArray.cc +++ b/liboctave/CNDArray.cc @@ -653,10 +653,33 @@ MX_ND_COMPLEX_OP_REDUCTION (+= elem (iter_idx), Complex (0, 0)); } -int -ComplexNDArray::cat (const ComplexNDArray& ra_arg, int dim, int iidx, int move) +ComplexNDArray +concat (const ComplexNDArray& ra, const ComplexNDArray& rb, + const Array<int>& ra_idx) +{ + ComplexNDArray retval (ra); + if (ra.numel () > 0) + retval.insert (rb, ra_idx); + return retval; +} + +ComplexNDArray +concat (const ComplexNDArray& ra, const NDArray& rb, const Array<int>& ra_idx) { - return ::cat_ra(*this, ra_arg, dim, iidx, move); + ComplexNDArray retval (ra); + ComplexNDArray tmp (rb); + if (ra.numel () > 0) + retval.insert (tmp, ra_idx); + return retval; +} + +ComplexNDArray +concat (const NDArray& ra, const ComplexNDArray& rb, const Array<int>& ra_idx) +{ + ComplexNDArray retval (ra); + if (ra.numel () > 0) + retval.insert (rb, ra_idx); + return retval; } static const Complex Complex_NaN_result (octave_NaN, octave_NaN); @@ -915,6 +938,13 @@ return *this; } +ComplexNDArray& +ComplexNDArray::insert (const ComplexNDArray& a, const Array<int>& ra_idx) +{ + Array<Complex>::insert (a, ra_idx); + return *this; +} + ComplexMatrix ComplexNDArray::matrix_value (void) const {
--- a/liboctave/CNDArray.h +++ b/liboctave/CNDArray.h @@ -79,7 +79,13 @@ 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); + friend ComplexNDArray concat (const ComplexNDArray& ra, + const ComplexNDArray& rb, + const Array<int>& ra_idx); + friend ComplexNDArray concat (const ComplexNDArray& ra, const NDArray& rb, + const Array<int>& ra_idx); + friend ComplexNDArray concat (const NDArray& ra, const ComplexNDArray& rb, + const Array<int>& ra_idx); ComplexNDArray max (int dim = 0) const; ComplexNDArray max (ArrayN<int>& index, int dim = 0) const; @@ -88,6 +94,7 @@ ComplexNDArray& insert (const NDArray& a, int r, int c); ComplexNDArray& insert (const ComplexNDArray& a, int r, int c); + ComplexNDArray& insert (const ComplexNDArray& a, const Array<int>& ra_idx); NDArray abs (void) const;
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,36 @@ +2004-07-23 David Bateman <dbateman@free.fr> + + * Array.cc, Array.h (cat_ra): Delete. + * Array.h, Array-C.cc, Array-d.cc, Array-ch.cc, Array-i.cc + (INSTANTIATE_ARRAY_CAT): Delete. + + * dNDArray.cc, dNDArray.h, CNDArray.cc, CNDArray.h, chNDArray.cc, + chNDArray.h, intNDArray.cc, intNDArray.h (cat): Delete. + + * Array.cc (Array<T>::insert): Copy data in NDArray version. + + * dNDArray.cc, dNDArray.h, CNDArray.cc, CNDArray.h, chNDArray.cc, + chNDArray.h (concat): New function used for concatenation that does + an indexed copy of one array into another. + + * dim-vector.h (concat): New function to concatenate dim_vectors. + + * dNDArray.cc, dNDArray.h, CNDArray.cc, CNDArray.h, chNDArray.cc, + chNDArray.h, intNDArray.cc, intNDArray.h (insert): New function for + insertion of one NDArray into another. + + * oct-inttype.cc (OCTAVE_INT_CONCAT_FN, OCTAVE_INT_CONCAT_DECL): New + macros to define the int/uint concatenation functions. + + * uint8NDArray.cc, uint16NDArray.cc, uint32NDArray.cc, uint64NDArray.cc + int8NDArray.cc, int16NDArray.cc, int32NDArray.cc, int64NDArray.cc + (OCTAVE_INT_CONCAT_FN): Instantiate the concatenation function . + + * uint8NDArray.h, uint16NDArray.h, uint32NDArray.h, uint64NDArray.h + int8NDArray.h, int16NDArray.h, int32NDArray.h, int64NDArray.h + (OCTAVE_INT_CONCAT_DECL): Declare the int/uint concatentaion + functions. + 2004-07-22 David Bateman <dbateman@free.fr> * oct-sort.h: Don't include oct-obj.h.
--- a/liboctave/chNDArray.cc +++ b/liboctave/chNDArray.cc @@ -33,6 +33,7 @@ #include "chNDArray.h" #include "mx-base.h" #include "lo-ieee.h" +#include "lo-mappers.h" // XXX FIXME XXX -- this is not quite the right thing. @@ -48,10 +49,97 @@ 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) +charNDArray +concat (const charNDArray& ra, const charNDArray& rb, const Array<int>& ra_idx) +{ + charNDArray retval (ra); + if (ra.numel () > 0) + retval.insert (rb, ra_idx); + return retval; +} + +charNDArray +concat (const charNDArray& ra, const NDArray& rb, const Array<int>& ra_idx) { - return ::cat_ra(*this, ra_arg, dim, iidx, move); + charNDArray retval (ra); + charNDArray tmp (rb.dims ()); + int nel = rb.numel (); + + if (ra.numel () == 0) + return retval; + + for (int i = 0; i < nel; i++) + { + double d = rb.elem (i); + + if (xisnan (d)) + { + (*current_liboctave_error_handler) + ("invalid conversion from NaN to character"); + return retval; + } + else + { + int ival = NINT (d); + + if (ival < 0 || ival > UCHAR_MAX) + // XXX FIXME XXX -- is there something + // better we could do? Should we warn the user? + ival = 0; + + tmp.elem (i) = static_cast<char>(ival); + } + } + + retval.insert (tmp, ra_idx); + return retval; +} + +charNDArray +concat (const NDArray& ra, const charNDArray& rb, const Array<int>& ra_idx) +{ + charNDArray retval (ra.dims ()); + int nel = ra.numel (); + + for (int i = 0; i < nel; i++) + { + double d = ra.elem (i); + + if (xisnan (d)) + { + (*current_liboctave_error_handler) + ("invalid conversion from NaN to character"); + return retval; + } + else + { + int ival = NINT (d); + + if (ival < 0 || ival > UCHAR_MAX) + // XXX FIXME XXX -- is there something + // better we could do? Should we warn the user? + ival = 0; + + retval.elem (i) = static_cast<char>(ival); + } + } + + retval.insert (rb, ra_idx); + return retval; +} + +charNDArray& +charNDArray::insert (const charNDArray& a, int r, int c) +{ + Array<char>::insert (a, r, c); + return *this; +} + +charNDArray& +charNDArray::insert (const charNDArray& a, const Array<int>& ra_idx) +{ + Array<char>::insert (a, ra_idx); + return *this; } charMatrix
--- a/liboctave/chNDArray.h +++ b/liboctave/chNDArray.h @@ -71,8 +71,16 @@ boolNDArray all (int dim = -1) const; boolNDArray any (int dim = -1) const; - int cat (const charNDArray& ra_arg, int dim, int iidx, int move); - + friend charNDArray concat (const charNDArray& ra, const charNDArray& rb, + const Array<int>& ra_idx); + friend charNDArray concat (const charNDArray& ra, const NDArray& rb, + const Array<int>& ra_idx); + friend charNDArray concat (const NDArray& ra, const charNDArray& rb, + const Array<int>& ra_idx); + + charNDArray& insert (const charNDArray& a, int r, int c); + charNDArray& insert (const charNDArray& a, const Array<int>& ra_idx); + charMatrix matrix_value (void) const; charNDArray squeeze (void) const { return ArrayN<char>::squeeze (); }
--- a/liboctave/dNDArray.cc +++ b/liboctave/dNDArray.cc @@ -792,10 +792,13 @@ return result; } -int -NDArray::cat (const NDArray& ra_arg, int dim, int iidx, int move) +NDArray +concat (const NDArray& ra, const NDArray& rb, const Array<int>& ra_idx) { - return ::cat_ra (*this, ra_arg, dim, iidx, move); + NDArray retval (ra); + if (ra.numel () > 0) + retval.insert (rb, ra_idx); + return retval; } NDArray @@ -818,6 +821,20 @@ return retval; } +NDArray& +NDArray::insert (const NDArray& a, int r, int c) +{ + Array<double>::insert (a, r, c); + return *this; +} + +NDArray& +NDArray::insert (const NDArray& a, const Array<int>& ra_idx) +{ + Array<double>::insert (a, ra_idx); + return *this; +} + NDArray NDArray::abs (void) const {
--- a/liboctave/dNDArray.h +++ b/liboctave/dNDArray.h @@ -84,13 +84,17 @@ 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); + friend NDArray concat (const NDArray& ra, const NDArray& rb, + const Array<int>& ra_idx); NDArray max (int dim = 0) const; NDArray max (ArrayN<int>& index, int dim = 0) const; NDArray min (int dim = 0) const; NDArray min (ArrayN<int>& index, int dim = 0) const; + NDArray& insert (const NDArray& a, int r, int c); + NDArray& insert (const NDArray& a, const Array<int>& ra_idx); + NDArray abs (void) const; ComplexNDArray fourier (int dim = 1) const;
--- a/liboctave/dim-vector.h +++ b/liboctave/dim-vector.h @@ -357,6 +357,77 @@ return new_dims; } + + bool concat (const dim_vector& dvb, int dim = 0) + { + if (all_zero ()) + { + *this = dvb; + return true; + } + + if (dvb.all_zero ()) + 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) + { + dim_vector_rep *old_rep = rep; + + rep = new dim_vector_rep (n_max, old_rep, 1); + + if (--old_rep->count <= 0) + delete old_rep; + } + + // Larger or equal since dim has been decremented by one. + + if (dim >= nb) + elem (dim) = elem (dim)++; + else + elem (dim) += dvb(dim); + + return true; + } }; static inline bool
--- a/liboctave/int16NDArray.cc +++ b/liboctave/int16NDArray.cc @@ -43,6 +43,8 @@ std::istream& operator >> (std::istream& is, intNDArray<octave_int16>& a); +OCTAVE_INT_CONCAT_FN (octave_int16) + NDS_CMP_OPS (int16NDArray, , octave_int16, ) NDS_BOOL_OPS (int16NDArray, octave_int16, octave_int16 (0))
--- a/liboctave/int16NDArray.h +++ b/liboctave/int16NDArray.h @@ -33,6 +33,8 @@ typedef intNDArray<octave_int16> int16NDArray; +OCTAVE_INT_CONCAT_DECL (octave_int16) + NDS_CMP_OP_DECLS (int16NDArray, octave_int16) NDS_BOOL_OP_DECLS (int16NDArray, octave_int16)
--- a/liboctave/int32NDArray.cc +++ b/liboctave/int32NDArray.cc @@ -43,6 +43,8 @@ std::istream& operator >> (std::istream& is, intNDArray<octave_int32>& a); +OCTAVE_INT_CONCAT_FN (octave_int32) + NDS_CMP_OPS (int32NDArray, , octave_int32, ) NDS_BOOL_OPS (int32NDArray, octave_int32, octave_int32 (0))
--- a/liboctave/int32NDArray.h +++ b/liboctave/int32NDArray.h @@ -33,6 +33,8 @@ typedef intNDArray<octave_int32> int32NDArray; +OCTAVE_INT_CONCAT_DECL (octave_int32) + NDS_CMP_OP_DECLS (int32NDArray, octave_int32) NDS_BOOL_OP_DECLS (int32NDArray, octave_int32)
--- a/liboctave/int64NDArray.cc +++ b/liboctave/int64NDArray.cc @@ -43,6 +43,8 @@ std::istream& operator >> (std::istream& is, intNDArray<octave_int64>& a); +OCTAVE_INT_CONCAT_FN (octave_int64) + NDS_CMP_OPS (int64NDArray, , octave_int64, ) NDS_BOOL_OPS (int64NDArray, octave_int64, octave_int64 (0))
--- a/liboctave/int64NDArray.h +++ b/liboctave/int64NDArray.h @@ -33,6 +33,8 @@ typedef intNDArray<octave_int64> int64NDArray; +OCTAVE_INT_CONCAT_DECL (octave_int64) + NDS_CMP_OP_DECLS (int64NDArray, octave_int64) NDS_BOOL_OP_DECLS (int64NDArray, octave_int64)
--- a/liboctave/int8NDArray.cc +++ b/liboctave/int8NDArray.cc @@ -43,6 +43,8 @@ std::istream& operator >> (std::istream& is, intNDArray<octave_int8>& a); +OCTAVE_INT_CONCAT_FN (octave_int8) + NDS_CMP_OPS (int8NDArray, , octave_int8, ) NDS_BOOL_OPS (int8NDArray, octave_int8, octave_int8 (0))
--- a/liboctave/int8NDArray.h +++ b/liboctave/int8NDArray.h @@ -33,6 +33,8 @@ typedef intNDArray<octave_int8> int8NDArray; +OCTAVE_INT_CONCAT_DECL (octave_int8) + NDS_CMP_OP_DECLS (int8NDArray, octave_int8) NDS_BOOL_OP_DECLS (int8NDArray, octave_int8)
--- a/liboctave/intNDArray.cc +++ b/liboctave/intNDArray.cc @@ -64,13 +64,6 @@ } template <class T> -int -intNDArray<T>::cat (const intNDArray<T>& ra_arg, int dim, int iidx, int move) -{ - return ::cat_ra (*this, ra_arg, dim, iidx, move); -} - -template <class T> void intNDArray<T>::increment_index (Array<int>& ra_idx, const dim_vector& dimensions, @@ -87,6 +80,22 @@ return ::compute_index (ra_idx, dimensions); } +template <class T> +intNDArray<T>& +intNDArray<T>::insert (const intNDArray<T>& a, int r, int c) +{ + Array<T>::insert (a, r, c); + return *this; +} + +template <class T> +intNDArray<T>& +intNDArray<T>::insert (const intNDArray<T>& a, const Array<int>& ra_idx) +{ + Array<T>::insert (a, ra_idx); + return *this; +} + // This contains no information on the array structure !!! template <class T>
--- a/liboctave/intNDArray.h +++ b/liboctave/intNDArray.h @@ -69,7 +69,6 @@ boolNDArray all (int dim = -1) const; boolNDArray any (int dim = -1) const; - int cat (const intNDArray<T>& ra_arg, int dim, int iidx, int move); intNDArray squeeze (void) const { return intNDArray<T> (MArrayN<T>::squeeze ()); } @@ -77,6 +76,9 @@ intNDArray transpose (void) const { return intNDArray<T> (MArrayN<T>::transpose ()); } + intNDArray& insert (const intNDArray<T>& a, int r, int c); + intNDArray& insert (const intNDArray<T>& a, const Array<int>& ra_idx); + static void increment_index (Array<int>& ra_idx, const dim_vector& dimensions, int start_dimension = 0);
--- a/liboctave/oct-inttypes.h +++ b/liboctave/oct-inttypes.h @@ -313,6 +313,21 @@ OCTAVE_INT_CMP_OP (==) OCTAVE_INT_CMP_OP (!=) +#define OCTAVE_INT_CONCAT_FN(TYPE) \ +intNDArray< TYPE > \ +concat (const intNDArray< TYPE >& ra, const intNDArray< TYPE >& rb, \ + const Array<int>& ra_idx) \ +{ \ + intNDArray< TYPE > retval (ra); \ + retval.insert (rb, ra_idx); \ + return retval; \ +} + +#define OCTAVE_INT_CONCAT_DECL(TYPE) \ +intNDArray< TYPE > \ +concat (const intNDArray< TYPE >& ra, const intNDArray< TYPE >& rb, \ + const Array<int>& ra_idx); + #undef OCTAVE_INT_TRAIT #undef OCTAVE_INT_BINOP_TRAIT #undef OCTAVE_INT_MIN_VAL
--- a/liboctave/uint16NDArray.cc +++ b/liboctave/uint16NDArray.cc @@ -43,6 +43,8 @@ std::istream& operator >> (std::istream& is, intNDArray<octave_uint16>& a); +OCTAVE_INT_CONCAT_FN (octave_uint16) + NDS_CMP_OPS (uint16NDArray, , octave_uint16, ) NDS_BOOL_OPS (uint16NDArray, octave_uint16, octave_uint16 (0))
--- a/liboctave/uint16NDArray.h +++ b/liboctave/uint16NDArray.h @@ -33,6 +33,8 @@ typedef intNDArray<octave_uint16> uint16NDArray; +OCTAVE_INT_CONCAT_DECL (octave_uint16) + NDS_CMP_OP_DECLS (uint16NDArray, octave_uint16) NDS_BOOL_OP_DECLS (uint16NDArray, octave_uint16)
--- a/liboctave/uint32NDArray.cc +++ b/liboctave/uint32NDArray.cc @@ -43,6 +43,8 @@ std::istream& operator >> (std::istream& is, intNDArray<octave_uint32>& a); +OCTAVE_INT_CONCAT_FN (octave_uint32) + NDS_CMP_OPS (uint32NDArray, , octave_uint32, ) NDS_BOOL_OPS (uint32NDArray, octave_uint32, octave_uint32 (0))
--- a/liboctave/uint32NDArray.h +++ b/liboctave/uint32NDArray.h @@ -33,6 +33,8 @@ typedef intNDArray<octave_uint32> uint32NDArray; +OCTAVE_INT_CONCAT_DECL (octave_uint32) + NDS_CMP_OP_DECLS (uint32NDArray, octave_uint32) NDS_BOOL_OP_DECLS (uint32NDArray, octave_uint32)
--- a/liboctave/uint64NDArray.cc +++ b/liboctave/uint64NDArray.cc @@ -43,6 +43,8 @@ std::istream& operator >> (std::istream& is, intNDArray<octave_uint64>& a); +OCTAVE_INT_CONCAT_FN (octave_uint64) + NDS_CMP_OPS (uint64NDArray, , octave_uint64, ) NDS_BOOL_OPS (uint64NDArray, octave_uint64, octave_uint64 (0))
--- a/liboctave/uint64NDArray.h +++ b/liboctave/uint64NDArray.h @@ -33,6 +33,8 @@ typedef intNDArray<octave_uint64> uint64NDArray; +OCTAVE_INT_CONCAT_DECL (octave_uint64) + NDS_CMP_OP_DECLS (uint64NDArray, octave_uint64) NDS_BOOL_OP_DECLS (uint64NDArray, octave_uint64)
--- a/liboctave/uint8NDArray.cc +++ b/liboctave/uint8NDArray.cc @@ -43,6 +43,8 @@ std::istream& operator >> (std::istream& is, intNDArray<octave_uint8>& a); +OCTAVE_INT_CONCAT_FN (octave_uint8) + NDS_CMP_OPS (uint8NDArray, , octave_uint8, ) NDS_BOOL_OPS (uint8NDArray, octave_uint8, octave_uint8 (0))
--- a/liboctave/uint8NDArray.h +++ b/liboctave/uint8NDArray.h @@ -33,6 +33,8 @@ typedef intNDArray<octave_uint8> uint8NDArray; +OCTAVE_INT_CONCAT_DECL (octave_uint8) + NDS_CMP_OP_DECLS (uint8NDArray, octave_uint8) NDS_BOOL_OP_DECLS (uint8NDArray, octave_uint8)
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,7 @@ +2004-07-23 David Bateman <dbateman@free.fr> + + * general/bitcmp.m, general/bitget.m, general/bitset.m: New functions. + 2004-07-22 Etienne Grossmann <etienne@cs.uky.edu> * general/sub2ind.m: Make reshaping index list unnecessary.
--- a/src/Cell.cc +++ b/src/Cell.cc @@ -100,10 +100,26 @@ return *this; } -int -Cell::cat (const Cell& ra_arg, int dim, int iidx, int move) +Cell +concat (const Cell& ra, const Cell& rb, const Array<int>& ra_idx) { - return ::cat_ra (*this, ra_arg, dim, iidx, move); + Cell retval (ra); + retval.insert (rb, ra_idx); + return retval; +} + +Cell& +Cell::insert (const Cell& a, int r, int c) +{ + Array<octave_value>::insert (a, r, c); + return *this; +} + +Cell& +Cell::insert (const Cell& a, const Array<int>& ra_idx) +{ + Array<octave_value>::insert (a, ra_idx); + return *this; } /*
--- a/src/Cell.h +++ b/src/Cell.h @@ -99,7 +99,10 @@ // XXX FIXME XXX boolMatrix any (int dim = 0) const { return boolMatrix (); } - int cat (const Cell& ra_arg, int dim, int iidx, int move); + friend Cell concat (const Cell& ra, const Cell& rb, const Array<int>& ra_idx); + + Cell& insert (const Cell& a, int r, int c); + Cell& insert (const Cell& a, const Array<int>& ra_idx); // XXX FIXME XXX bool is_true (void) const { return false; }
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,76 @@ +2004-07-23 David Bateman <dbateman@free.fr> + + * ov-intx.h (OCTAVE_VALUE_INT_MATRIX_T::array_value, + OCTAVE_VALUE_INT_SCALAR_T::array_value): new methods to extract array + value from integer types. + + * bitfcns.cc (BITOPX): New Macro renamed from BITOP. + (BITOP): Alter to allow different types and call BITOP appropriately. + (DO_SBITSHIFT, DO_UBITSHIFT): New macros for signed, unsigned + bitshifts. + + (DO_BITSHIFT): Test for shift of more bits than in type, which is + undefined. Generalize to allow double args as well. + (Fbitshift): Add int and double types. + (Fbitmax): Return 53 bit value which conforms to IEEE754 double + mantissa. + (Fintmax, Fintmin): New functions. + (Fbitget, Fbitset, Fbitcmp): Delete. + + * OPERATORS/op-int.h: Add sm_el_pow function + + * ops.h (CATOPDECL, DEFCATOPX, DEFCATOP, DEFCATOP_FB, DEFNDCATOP_FN, + CATOP_NONCONFORMANT, INSTALL_CATOP): New macros. + + * OPERATORS/op-b-b.cc, OPERATORS/op-b-bm.cc, OPERATORS/op-bm-b.cc, + OPERATORS/op-bm-bm.cc, OPERATORS/op-cell.cc, OPERATORS/op-chm.cc, + OPERATORS/op-cm-cm.cc, OPERATORS/op-cm-cs.cc, OPERATORS/op-cm-m.cc, + OPERATORS/op-cm-s.cc, OPERATORS/op-cs-cm.cc, OPERATORS/op-cs-cs.cc, + OPERATORS/op-cs-m.cc, OPERATORS/op-cs-s.cc, OPERATORS/op-m-cm.cc, + OPERATORS/op-m-cs.cc, OPERATORS/op-m-m.cc, OPERATORS/op-m-s.cc, + OPERATORS/op-range.cc, OPERATORS/op-s-cm.cc, OPERATORS/op-s-cs.cc, + OPERATORS/op-s-m.cc, OPERATORS/op-s-s.cc, OPERATORS/op-str-str.cc, + OPERATORS/op-str-m.cc, OPERATORS/op-str-s.cc (CATOPDECL, DEFCATOPX, + DEFCATOP, DEFCATOP_FB, DEFNDCATOP_FN, CATOP_NONCONFORMANT, + INSTALL_CATOP): Use them to define concatenation functions. + + * OPERATORS/op-int.h (OCTAVE_CONCAT_FN, OCTAVE_INSTALL_CONCAT_FN): + New macros to define and install concatentaion functions for int/uint + types. + + * TEMPLATE-INST/Array-tc.cc (INSTANTIATE_ARRAY_CAT): Delete. + + * pt-mat.cc (tm_row_const::tm_row_const_rep::do_init_element): + Also append empty elements to the list of elements to be parsed. + (tree_matrix::rvalue): Use new concatenation binary operators. + + * data.cc (cat_add_dims): Delete (now dim_vector::concat). + (do_cat): Use new concatenation binary operators. + + * ov-typeinfo.cc (cat_op_fcn): Instantiate the array of cat functions. + (register_cat_op, do_register_cat_op, do_lookup_cat_op): New functions. + (cat_ops): Lookup table of binary concatentaion operators. + + * ov-typeinfo.h (lookup_cat_op): New function. + + * ov.cc (gripe_cat_op, gripe_cat_op_conv, do_cat_op): New functions. + + * ov.h (cat_op_fcn): Definition. + (resize, do_cat_op): New functions. + + * ov-intx.h (resize): New_function + + * version.h (OCTAVE_API_VERSION): Bump version to api-v9. + + * Cell.cc, Cell.h, oct-map.cc, oct-map.h (cat): Delete. + (concat): New function. + + * Cell.cc, Cell.h (insert): New function + + * ov-base.cc, ov-base.h, ov-scalar.h, ov-complex.h, ov-bool.h, + ov-range.h, ov-base-mat.h, (resize): New function. + + 2004-07-23 John W. Eaton <jwe@octave.org> * symtab.cc (whos_parameter): Move decl here, from symtab.h.
--- a/src/OPERATORS/op-b-b.cc +++ b/src/OPERATORS/op-b-b.cc @@ -32,6 +32,8 @@ #include "oct-obj.h" #include "ov.h" #include "ov-bool.h" +#include "ov-scalar.h" +#include "ov-re-mat.h" #include "ov-typeinfo.h" #include "ops.h" #include "xdiv.h" @@ -52,6 +54,10 @@ DEFBINOP_OP (el_and, bool, bool, &&) DEFBINOP_OP (el_or, bool, bool, ||) +DEFNDCATOP_FN (b_b, bool, bool, array, array, concat) +DEFNDCATOP_FN (b_s, bool, scalar, array, array, concat) +DEFNDCATOP_FN (s_b, scalar, bool, array, array, concat) + void install_b_b_ops (void) { @@ -63,6 +69,10 @@ INSTALL_BINOP (op_ne, octave_bool, octave_bool, ne); INSTALL_BINOP (op_el_and, octave_bool, octave_bool, el_and); INSTALL_BINOP (op_el_or, octave_bool, octave_bool, el_or); + + INSTALL_CATOP (octave_bool, octave_bool, b_b); + INSTALL_CATOP (octave_bool, octave_scalar, b_s); + INSTALL_CATOP (octave_scalar, octave_bool, s_b); } /*
--- a/src/OPERATORS/op-b-bm.cc +++ b/src/OPERATORS/op-b-bm.cc @@ -33,6 +33,8 @@ #include "ov.h" #include "ov-bool.h" #include "ov-bool-mat.h" +#include "ov-scalar.h" +#include "ov-re-mat.h" #include "ov-typeinfo.h" #include "ops.h" #include "xdiv.h" @@ -43,11 +45,19 @@ DEFNDBINOP_FN (el_and, bool, bool_matrix, bool, bool_array, mx_el_and) DEFNDBINOP_FN (el_or, bool, bool_matrix, bool, bool_array, mx_el_or) +DEFNDCATOP_FN (b_bm, bool, bool_matrix, array, array, concat) +DEFNDCATOP_FN (b_m, bool, matrix, array, array, concat) +DEFNDCATOP_FN (s_bm, scalar, bool_matrix, array, array, concat) + void install_b_bm_ops (void) { INSTALL_BINOP (op_el_and, octave_bool, octave_bool_matrix, el_and); INSTALL_BINOP (op_el_or, octave_bool, octave_bool_matrix, el_or); + + INSTALL_CATOP (octave_bool, octave_bool_matrix, b_bm); + INSTALL_CATOP (octave_bool, octave_matrix, b_m); + INSTALL_CATOP (octave_scalar, octave_bool_matrix, s_bm); } /*
--- a/src/OPERATORS/op-bm-b.cc +++ b/src/OPERATORS/op-bm-b.cc @@ -33,6 +33,8 @@ #include "ov.h" #include "ov-bool.h" #include "ov-bool-mat.h" +#include "ov-scalar.h" +#include "ov-re-mat.h" #include "ov-typeinfo.h" #include "ops.h" #include "xdiv.h" @@ -43,6 +45,10 @@ DEFNDBINOP_FN (el_and, bool_matrix, bool, bool_array, bool, mx_el_and) DEFNDBINOP_FN (el_or, bool_matrix, bool, bool_array, bool, mx_el_or) +DEFNDCATOP_FN (bm_b, bool_matrix, bool, array, array, concat) +DEFNDCATOP_FN (bm_s, bool_matrix, scalar, array, array, concat) +DEFNDCATOP_FN (m_b, matrix, bool, array, array, concat) + DEFNDASSIGNOP_FN (assign, bool_matrix, bool, bool_array, assign) void @@ -51,6 +57,10 @@ INSTALL_BINOP (op_el_and, octave_bool_matrix, octave_bool, el_and); INSTALL_BINOP (op_el_or, octave_bool_matrix, octave_bool, el_or); + INSTALL_CATOP (octave_bool_matrix, octave_bool, bm_b); + INSTALL_CATOP (octave_bool_matrix, octave_scalar, bm_s); + INSTALL_CATOP (octave_matrix, octave_bool, m_b); + INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_bool, assign); }
--- a/src/OPERATORS/op-bm-bm.cc +++ b/src/OPERATORS/op-bm-bm.cc @@ -32,6 +32,7 @@ #include "oct-obj.h" #include "ov.h" #include "ov-bool-mat.h" +#include "ov-re-mat.h" #include "ov-typeinfo.h" #include "ops.h" #include "xdiv.h" @@ -65,6 +66,10 @@ DEFNDBINOP_FN (el_or, bool_matrix, bool_matrix, bool_array, bool_array, mx_el_or) +DEFNDCATOP_FN (bm_bm, bool_matrix, bool_matrix, array, array, concat) +DEFNDCATOP_FN (bm_m, bool_matrix, matrix, array, array, concat) +DEFNDCATOP_FN (m_bm, matrix, bool_matrix, array, array, concat) + DEFNDASSIGNOP_FN (assign, bool_matrix, bool_matrix, bool_array, assign) void @@ -80,6 +85,10 @@ INSTALL_BINOP (op_el_and, octave_bool_matrix, octave_bool_matrix, el_and); INSTALL_BINOP (op_el_or, octave_bool_matrix, octave_bool_matrix, el_or); + INSTALL_CATOP (octave_bool_matrix, octave_bool_matrix, bm_bm); + INSTALL_CATOP (octave_bool_matrix, octave_matrix, bm_m); + INSTALL_CATOP (octave_matrix, octave_bool_matrix, m_bm); + INSTALL_ASSIGNOP (op_asn_eq, octave_bool_matrix, octave_bool_matrix, assign); }
--- a/src/OPERATORS/op-cell.cc +++ b/src/OPERATORS/op-cell.cc @@ -52,6 +52,8 @@ return octave_value (Cell (v.cell_value().transpose ())); } +DEFCATOP_FN (c_c, cell, cell, concat) + DEFASSIGNANYOP_FN (assign, cell, assign); void @@ -60,6 +62,8 @@ INSTALL_UNOP (op_transpose, octave_cell, transpose); INSTALL_UNOP (op_hermitian, octave_cell, transpose); + INSTALL_CATOP (octave_cell, octave_cell, c_c); + INSTALL_ASSIGNANYOP (op_asn_eq, octave_cell, assign); }
--- a/src/OPERATORS/op-chm.cc +++ b/src/OPERATORS/op-chm.cc @@ -32,6 +32,10 @@ #include "oct-obj.h" #include "ov.h" #include "ov-ch-mat.h" +#include "ov-scalar.h" +#include "ov-re-mat.h" +#include "ov-bool.h" +#include "ov-bool-mat.h" #include "ov-typeinfo.h" #include "ops.h" @@ -44,11 +48,63 @@ return octave_value (v.matrix_value().transpose ()); } +DEFNDCATOP_FN (chm_chm, char_matrix, char_matrix, char_array, char_array, concat) + +DEFCATOP (chm_s, char_matrix, scalar) +{ + CAST_BINOP_ARGS (const octave_char_matrix&, const octave_scalar&); + + if (Vwarn_num_to_str) + gripe_implicit_conversion (v2.type_name (), v1.type_name ()); + + return octave_value (concat (v1.char_array_value (), v2.array_value (), + ra_idx)); +} + +DEFCATOP (chm_m, char_matrix, matrix) +{ + CAST_BINOP_ARGS (const octave_char_matrix&, const octave_matrix&); + + if (Vwarn_num_to_str) + gripe_implicit_conversion (v2.type_name (), v1.type_name ()); + + return octave_value (concat (v1.char_array_value (), v2.array_value (), + ra_idx)); +} + +DEFCATOP (s_chm, scalar, char_matrix) +{ + CAST_BINOP_ARGS (const octave_scalar&, const octave_char_matrix&); + + if (Vwarn_num_to_str) + gripe_implicit_conversion (v1.type_name (), v2.type_name ()); + + return octave_value (concat (v1.array_value (), v2.char_array_value (), + ra_idx)); +} + +DEFCATOP (m_chm, matrix, char_matrix) +{ + CAST_BINOP_ARGS (const octave_matrix&, const octave_char_matrix&); + + if (Vwarn_num_to_str) + gripe_implicit_conversion (v1.type_name (), v2.type_name ()); + + return octave_value (concat (v1.array_value (), v2.char_array_value (), + ra_idx)); +} + void install_chm_ops (void) { INSTALL_UNOP (op_transpose, octave_char_matrix, transpose); INSTALL_UNOP (op_hermitian, octave_char_matrix, transpose); + + INSTALL_CATOP (octave_char_matrix, octave_char_matrix, chm_chm); + INSTALL_CATOP (octave_char_matrix, octave_scalar, chm_s); + INSTALL_CATOP (octave_char_matrix, octave_matrix, chm_m); + INSTALL_CATOP (octave_scalar, octave_char_matrix, s_chm); + INSTALL_CATOP (octave_matrix, octave_char_matrix, m_chm); } /*
--- a/src/OPERATORS/op-cm-cm.cc +++ b/src/OPERATORS/op-cm-cm.cc @@ -108,6 +108,8 @@ DEFNDBINOP_FN (el_and, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_and) DEFNDBINOP_FN (el_or, complex_matrix, complex_matrix, complex_array, complex_array, mx_el_or) +DEFNDCATOP_FN (cm_cm, complex_matrix, complex_matrix, complex_array, complex_array, concat) + DEFNDASSIGNOP_FN (assign, complex_matrix, complex_matrix, complex_array, assign) void @@ -140,6 +142,8 @@ INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_complex_matrix, el_and); INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_complex_matrix, el_or); + INSTALL_CATOP (octave_complex_matrix, octave_complex_matrix, cm_cm); + INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_complex_matrix, assign); }
--- a/src/OPERATORS/op-cm-cs.cc +++ b/src/OPERATORS/op-cm-cs.cc @@ -101,6 +101,8 @@ DEFNDBINOP_FN (el_and, complex_matrix, complex, complex_array, complex, mx_el_and) DEFNDBINOP_FN (el_or, complex_matrix, complex, complex_array, complex, mx_el_or) +DEFNDCATOP_FN (cm_cs, complex_matrix, complex, complex_array, complex_array, concat) + DEFNDASSIGNOP_FN (assign, complex_matrix, complex, complex_array, assign) void @@ -125,6 +127,8 @@ INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_complex, el_and); INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_complex, el_or); + INSTALL_CATOP (octave_complex_matrix, octave_complex, cm_cs); + INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_complex, assign); }
--- a/src/OPERATORS/op-cm-m.cc +++ b/src/OPERATORS/op-cm-m.cc @@ -80,6 +80,8 @@ DEFNDBINOP_FN (el_and, complex_matrix, matrix, complex_array, array, mx_el_and) DEFNDBINOP_FN (el_or, complex_matrix, matrix, complex_array, array, mx_el_or) +DEFNDCATOP_FN (cm_m, complex_matrix, matrix, complex_array, array, concat) + DEFNDASSIGNOP_FN (assign, complex_matrix, matrix, complex_array, assign) void @@ -104,6 +106,8 @@ INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_matrix, el_and); INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_matrix, el_or); + INSTALL_CATOP (octave_complex_matrix, octave_matrix, cm_m); + INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_matrix, assign); }
--- a/src/OPERATORS/op-cm-s.cc +++ b/src/OPERATORS/op-cm-s.cc @@ -105,6 +105,8 @@ DEFNDBINOP_FN (el_and, complex_matrix, scalar, complex_array, scalar, mx_el_and) DEFNDBINOP_FN (el_or, complex_matrix, scalar, complex_array, scalar, mx_el_or) +DEFNDCATOP_FN (cm_s, complex_matrix, scalar, complex_array, array, concat) + DEFNDASSIGNOP_FN (assign, complex_matrix, scalar, complex_array, assign) void @@ -129,6 +131,8 @@ INSTALL_BINOP (op_el_and, octave_complex_matrix, octave_scalar, el_and); INSTALL_BINOP (op_el_or, octave_complex_matrix, octave_scalar, el_or); + INSTALL_CATOP (octave_complex_matrix, octave_scalar, cm_s); + INSTALL_ASSIGNOP (op_asn_eq, octave_complex_matrix, octave_scalar, assign); }
--- a/src/OPERATORS/op-cs-cm.cc +++ b/src/OPERATORS/op-cs-cm.cc @@ -94,6 +94,8 @@ DEFNDBINOP_FN (el_and, complex, complex_matrix, complex, complex_array, mx_el_and) DEFNDBINOP_FN (el_or, complex, complex_matrix, complex, complex_array, mx_el_or) +DEFNDCATOP_FN (cs_cm, complex, complex_matrix, complex_array, complex_array, concat) + DEFCONV (complex_matrix_conv, complex, complex_matrix) { CAST_CONV_ARG (const octave_complex&); @@ -123,6 +125,8 @@ INSTALL_BINOP (op_el_and, octave_complex, octave_complex_matrix, el_and); INSTALL_BINOP (op_el_or, octave_complex, octave_complex_matrix, el_or); + INSTALL_CATOP (octave_complex, octave_complex_matrix, cs_cm); + INSTALL_ASSIGNCONV (octave_complex, octave_complex_matrix, octave_complex_matrix); INSTALL_WIDENOP (octave_complex, octave_complex_matrix, complex_matrix_conv);
--- a/src/OPERATORS/op-cs-cs.cc +++ b/src/OPERATORS/op-cs-cs.cc @@ -176,6 +176,8 @@ return v1.complex_value () != 0.0 || v2.complex_value () != 0.0; } +DEFNDCATOP_FN (cs_cs, complex, complex, complex_array, complex_array, concat) + void install_cs_cs_ops (void) { @@ -206,6 +208,8 @@ INSTALL_BINOP (op_el_and, octave_complex, octave_complex, el_and); INSTALL_BINOP (op_el_or, octave_complex, octave_complex, el_or); + INSTALL_CATOP (octave_complex, octave_complex, cs_cs); + INSTALL_ASSIGNCONV (octave_complex, octave_complex, octave_complex_matrix); }
--- a/src/OPERATORS/op-cs-m.cc +++ b/src/OPERATORS/op-cs-m.cc @@ -100,6 +100,8 @@ DEFNDBINOP_FN (el_and, complex, matrix, complex, array, mx_el_and) DEFNDBINOP_FN (el_or, complex, matrix, complex, array, mx_el_or) +DEFNDCATOP_FN (cs_m, complex, matrix, complex_array, array, concat) + void install_cs_m_ops (void) { @@ -122,6 +124,8 @@ INSTALL_BINOP (op_el_and, octave_complex, octave_matrix, el_and); INSTALL_BINOP (op_el_or, octave_complex, octave_matrix, el_or); + INSTALL_CATOP (octave_complex, octave_matrix, cs_m); + INSTALL_ASSIGNCONV (octave_complex, octave_matrix, octave_complex_matrix); }
--- a/src/OPERATORS/op-cs-s.cc +++ b/src/OPERATORS/op-cs-s.cc @@ -155,6 +155,8 @@ return v1.complex_value () != 0.0 || v2.double_value (); } +DEFNDCATOP_FN (cs_s, complex, scalar, complex_array, array, concat) + void install_cs_s_ops (void) { @@ -177,6 +179,8 @@ INSTALL_BINOP (op_el_and, octave_complex, octave_scalar, el_and); INSTALL_BINOP (op_el_or, octave_complex, octave_scalar, el_or); + INSTALL_CATOP (octave_complex, octave_scalar, cs_s); + INSTALL_ASSIGNCONV (octave_complex, octave_scalar, octave_complex_matrix); }
--- a/src/OPERATORS/op-int.h +++ b/src/OPERATORS/op-int.h @@ -20,6 +20,18 @@ */ +#define OCTAVE_CONCAT_FN(TYPE) \ + DEFNDCATOP_FN (TYPE ## _s_s, TYPE ## _scalar, TYPE ## _scalar, TYPE ## _array, TYPE ## _array, concat) \ + DEFNDCATOP_FN (TYPE ## _s_m, TYPE ## _scalar, TYPE ## _matrix, TYPE ## _array, TYPE ## _array, concat) \ + DEFNDCATOP_FN (TYPE ## _m_s, TYPE ## _matrix, TYPE ## _scalar, TYPE ## _array, TYPE ## _array, concat) \ + DEFNDCATOP_FN (TYPE ## _m_m, TYPE ## _matrix, TYPE ## _matrix, TYPE ## _array, TYPE ## _array, concat) + +#define OCTAVE_INSTALL_CONCAT_FN(TYPE) \ + INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_ ## TYPE ## _scalar, TYPE ## _s_s) \ + INSTALL_CATOP (octave_ ## TYPE ## _scalar, octave_ ## TYPE ## _matrix, TYPE ## _s_m) \ + INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_ ## TYPE ## _scalar, TYPE ## _m_s) \ + INSTALL_CATOP (octave_ ## TYPE ## _matrix, octave_ ## TYPE ## _matrix, TYPE ## _m_m) + #define OCTAVE_S_INT_UNOPS(TYPE) \ /* scalar unary ops. */ \ \ @@ -148,7 +160,15 @@ \ DEFNDBINOP_OP (sm_el_mul, TS ## _scalar, TM ## _matrix, TS ## _scalar, TM ## _array, *) \ /* DEFNDBINOP_FN (sm_el_div, TS ## _scalar, TM ## _matrix, TS ## _scalar, TM ## _array, x_el_div) */ \ - /* DEFNDBINOP_FN (sm_el_pow, TS ## _scalar, TM ## _matrix, TS ## _scalar, TM ## _array, elem_xpow) */ \ + DEFBINOP (sm_el_pow, TS ## _scalar, TM ## _matrix) \ + { \ + CAST_BINOP_ARGS (const octave_ ## TS ## _scalar&, const octave_ ## TM ## _matrix&); \ + \ + double d = v1.TS ## _scalar_value (); \ + \ + /* XXX FIXME XXX Return type wrong */ \ + return octave_value (elem_xpow (d, v2.array_value())); \ + } \ \ /* DEFBINOP (sm_el_ldiv, TS ## _scalar, TM ## _matrix) */ \ /* { */ \ @@ -350,7 +370,8 @@ OCTAVE_SS_INT_OPS (TYPE) \ OCTAVE_SM_INT_OPS (TYPE) \ OCTAVE_MS_INT_OPS (TYPE) \ - OCTAVE_MM_INT_OPS (TYPE) + OCTAVE_MM_INT_OPS (TYPE) \ + OCTAVE_CONCAT_FN (TYPE) #define OCTAVE_INSTALL_S_INT_UNOPS(TYPE) \ INSTALL_UNOP (op_not, octave_ ## TYPE ## _scalar, s_not); \ @@ -406,7 +427,7 @@ /* INSTALL_BINOP (op_ldiv, octave_ ## T1 ## _scalar, octave_ ## T2 ## _matrix, sm_ldiv); */ \ INSTALL_BINOP (op_el_mul, octave_ ## T1 ## _scalar, octave_ ## T2 ## _matrix, sm_el_mul); \ /* INSTALL_BINOP (op_el_div, octave_ ## T1 ## _scalar, octave_ ## T2 ## _matrix, sm_el_div); */ \ - /* INSTALL_BINOP (op_el_pow, octave_ ## T1 ## _scalar, octave_ ## T2 ## _matrix, sm_el_pow); */ \ + INSTALL_BINOP (op_el_pow, octave_ ## T1 ## _scalar, octave_ ## T2 ## _matrix, sm_el_pow); \ /* INSTALL_BINOP (op_el_ldiv, octave_ ## T1 ## _scalar, octave_ ## T2 ## _matrix, sm_el_ldiv); */ #define OCTAVE_INSTALL_SM_INT_CMP_OPS(T1, T2) \ @@ -526,7 +547,8 @@ OCTAVE_INSTALL_SS_INT_OPS (TYPE) \ OCTAVE_INSTALL_SM_INT_OPS (TYPE) \ OCTAVE_INSTALL_MS_INT_OPS (TYPE) \ - OCTAVE_INSTALL_MM_INT_OPS (TYPE) + OCTAVE_INSTALL_MM_INT_OPS (TYPE) \ + OCTAVE_INSTALL_CONCAT_FN (TYPE) /* ;;; Local Variables: ***
--- a/src/OPERATORS/op-m-cm.cc +++ b/src/OPERATORS/op-m-cm.cc @@ -80,6 +80,8 @@ DEFNDBINOP_FN (el_and, matrix, complex_matrix, array, complex_array, mx_el_and) DEFNDBINOP_FN (el_or, matrix, complex_matrix, array, complex_array, mx_el_or) +DEFNDCATOP_FN (m_cm, matrix, complex_matrix, array, complex_array, concat) + DEFCONV (complex_matrix_conv, matrix, complex_matrix) { CAST_CONV_ARG (const octave_matrix&); @@ -109,6 +111,8 @@ INSTALL_BINOP (op_el_and, octave_matrix, octave_complex_matrix, el_and); INSTALL_BINOP (op_el_or, octave_matrix, octave_complex_matrix, el_or); + INSTALL_CATOP (octave_matrix, octave_complex_matrix, m_cm); + INSTALL_ASSIGNCONV (octave_matrix, octave_complex_matrix, octave_complex_matrix); INSTALL_WIDENOP (octave_matrix, octave_complex_matrix, complex_matrix_conv);
--- a/src/OPERATORS/op-m-cs.cc +++ b/src/OPERATORS/op-m-cs.cc @@ -107,6 +107,8 @@ DEFNDBINOP_FN (el_and, matrix, complex, array, complex, mx_el_and) DEFNDBINOP_FN (el_or, matrix, complex, array, complex, mx_el_or) +DEFNDCATOP_FN (m_cs, matrix, complex, array, complex_array, concat) + void install_m_cs_ops (void) { @@ -129,6 +131,8 @@ INSTALL_BINOP (op_el_and, octave_matrix, octave_complex, el_and); INSTALL_BINOP (op_el_or, octave_matrix, octave_complex, el_or); + INSTALL_CATOP (octave_matrix, octave_complex, m_cs); + INSTALL_ASSIGNCONV (octave_matrix, octave_complex, octave_complex_matrix); }
--- a/src/OPERATORS/op-m-m.cc +++ b/src/OPERATORS/op-m-m.cc @@ -95,6 +95,8 @@ DEFNDBINOP_FN (el_and, matrix, matrix, array, array, mx_el_and) DEFNDBINOP_FN (el_or, matrix, matrix, array, array, mx_el_or) +DEFNDCATOP_FN (m_m, matrix, matrix, array, array, concat) + DEFNDASSIGNOP_FN (assign, matrix, matrix, array, assign) void @@ -127,6 +129,8 @@ INSTALL_BINOP (op_el_and, octave_matrix, octave_matrix, el_and); INSTALL_BINOP (op_el_or, octave_matrix, octave_matrix, el_or); + INSTALL_CATOP (octave_matrix, octave_matrix, m_m); + INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_matrix, assign); }
--- a/src/OPERATORS/op-m-s.cc +++ b/src/OPERATORS/op-m-s.cc @@ -101,6 +101,8 @@ DEFNDBINOP_FN (el_and, matrix, scalar, array, scalar, mx_el_and) DEFNDBINOP_FN (el_or, matrix, scalar, array, scalar, mx_el_or) +DEFNDCATOP_FN (m_s, matrix, scalar, array, array, concat) + DEFNDASSIGNOP_FN (assign, matrix, scalar, array, assign) void @@ -131,6 +133,8 @@ INSTALL_BINOP (op_el_and, octave_matrix, octave_scalar, el_and); INSTALL_BINOP (op_el_or, octave_matrix, octave_scalar, el_or); + INSTALL_CATOP (octave_matrix, octave_scalar, m_s); + INSTALL_ASSIGNOP (op_asn_eq, octave_matrix, octave_scalar, assign); }
--- a/src/OPERATORS/op-range.cc +++ b/src/OPERATORS/op-range.cc @@ -32,6 +32,13 @@ #include "oct-obj.h" #include "ov.h" #include "ov-range.h" +#include "ov-ch-mat.h" +#include "ov-scalar.h" +#include "ov-re-mat.h" +#include "ov-complex.h" +#include "ov-cx-mat.h" +#include "ov-bool.h" +#include "ov-bool-mat.h" #include "ov-typeinfo.h" #include "ops.h" @@ -53,6 +60,22 @@ return octave_value (v.matrix_value().transpose ()); } +DEFNDCATOP_FN (r_r, range, range, array, array, concat) +DEFNDCATOP_FN (r_s, range, scalar, array, array, concat) +DEFNDCATOP_FN (r_m, range, matrix, array, array, concat) +DEFNDCATOP_FN (r_cs, range, complex, array, complex_array, concat) +DEFNDCATOP_FN (r_cm, range, complex_matrix, array, complex_array, concat) +DEFNDCATOP_FN (r_b, range, bool, array, array, concat) +DEFNDCATOP_FN (r_bm, range, bool_matrix, array, array, concat) +DEFNDCATOP_FN (r_chm, range, char_matrix, array, char_array, concat) +DEFNDCATOP_FN (s_r, scalar, range, array, array, concat) +DEFNDCATOP_FN (m_r, matrix, range, array, array, concat) +DEFNDCATOP_FN (cs_r, complex, range, complex_array, array, concat) +DEFNDCATOP_FN (cm_r, complex_matrix, range, complex_array, array, concat) +DEFNDCATOP_FN (b_r, bool, range, array, array, concat) +DEFNDCATOP_FN (bm_r, bool_matrix, range, array, array, concat) +DEFNDCATOP_FN (chm_r, char_matrix, range, char_array, array, concat) + void install_range_ops (void) { @@ -60,6 +83,22 @@ INSTALL_UNOP (op_uminus, octave_range, uminus); INSTALL_UNOP (op_transpose, octave_range, transpose); INSTALL_UNOP (op_hermitian, octave_range, transpose); + + INSTALL_CATOP (octave_range, octave_range, r_r); + INSTALL_CATOP (octave_range, octave_scalar, r_s); + INSTALL_CATOP (octave_range, octave_matrix, r_m); + INSTALL_CATOP (octave_range, octave_complex, r_cs); + INSTALL_CATOP (octave_range, octave_complex_matrix, r_cm); + INSTALL_CATOP (octave_range, octave_bool, r_b); + INSTALL_CATOP (octave_range, octave_bool_matrix, r_bm); + INSTALL_CATOP (octave_range, octave_char_matrix, r_chm); + INSTALL_CATOP (octave_scalar, octave_range, s_r); + INSTALL_CATOP (octave_matrix, octave_range, m_r); + INSTALL_CATOP (octave_complex, octave_range, cs_r); + INSTALL_CATOP (octave_complex_matrix, octave_range, cm_r); + INSTALL_CATOP (octave_bool, octave_range, b_r); + INSTALL_CATOP (octave_bool_matrix, octave_range, bm_r); + INSTALL_CATOP (octave_char_matrix, octave_range, chm_r); } /*
--- a/src/OPERATORS/op-s-cm.cc +++ b/src/OPERATORS/op-s-cm.cc @@ -111,6 +111,8 @@ return mx_el_or (v1.double_value (), v2.complex_array_value ()); } +DEFNDCATOP_FN (s_cm, scalar, complex_matrix, array, complex_array, concat) + DEFCONV (complex_matrix_conv, scalar, complex_matrix) { CAST_CONV_ARG (const octave_scalar&); @@ -140,6 +142,8 @@ INSTALL_BINOP (op_el_and, octave_scalar, octave_complex_matrix, el_and); INSTALL_BINOP (op_el_or, octave_scalar, octave_complex_matrix, el_or); + INSTALL_CATOP (octave_scalar, octave_complex_matrix, s_cm); + INSTALL_ASSIGNCONV (octave_scalar, octave_complex_matrix, octave_complex_matrix); INSTALL_WIDENOP (octave_scalar, octave_complex_matrix, complex_matrix_conv);
--- a/src/OPERATORS/op-s-cs.cc +++ b/src/OPERATORS/op-s-cs.cc @@ -155,6 +155,8 @@ return octave_value (v1.double_value () || (v2.complex_value () != 0.0)); } +DEFNDCATOP_FN (s_cs, scalar, complex, array, complex_array, concat) + void install_s_cs_ops (void) { @@ -177,6 +179,8 @@ INSTALL_BINOP (op_el_and, octave_scalar, octave_complex, el_and); INSTALL_BINOP (op_el_or, octave_scalar, octave_complex, el_or); + INSTALL_CATOP (octave_scalar, octave_complex, s_cs); + INSTALL_ASSIGNCONV (octave_scalar, octave_complex, octave_complex_matrix); }
--- a/src/OPERATORS/op-s-m.cc +++ b/src/OPERATORS/op-s-m.cc @@ -94,6 +94,8 @@ DEFNDBINOP_FN (el_and, scalar, matrix, scalar, array, mx_el_and) DEFNDBINOP_FN (el_or, scalar, matrix, scalar, array, mx_el_or) +DEFNDCATOP_FN (s_m, scalar, matrix, array, array, concat) + DEFCONV (matrix_conv, scalar, matrix) { CAST_CONV_ARG (const octave_scalar&); @@ -123,6 +125,8 @@ INSTALL_BINOP (op_el_and, octave_scalar, octave_matrix, el_and); INSTALL_BINOP (op_el_or, octave_scalar, octave_matrix, el_or); + INSTALL_CATOP (octave_scalar, octave_matrix, s_m); + INSTALL_ASSIGNCONV (octave_scalar, octave_matrix, octave_matrix); INSTALL_WIDENOP (octave_scalar, octave_matrix, matrix_conv);
--- a/src/OPERATORS/op-s-s.cc +++ b/src/OPERATORS/op-s-s.cc @@ -118,6 +118,8 @@ DEFBINOP_OP (el_and, scalar, scalar, &&) DEFBINOP_OP (el_or, scalar, scalar, ||) +DEFNDCATOP_FN (s_s, scalar, scalar, array, array, concat) + void install_s_s_ops (void) { @@ -148,6 +150,8 @@ INSTALL_BINOP (op_el_and, octave_scalar, octave_scalar, el_and); INSTALL_BINOP (op_el_or, octave_scalar, octave_scalar, el_or); + INSTALL_CATOP (octave_scalar, octave_scalar, s_s); + INSTALL_ASSIGNCONV (octave_scalar, octave_scalar, octave_matrix); }
--- a/src/OPERATORS/op-str-m.cc +++ b/src/OPERATORS/op-str-m.cc @@ -48,10 +48,37 @@ return octave_value (); } +DEFCATOP (str_m, char_matrix_str, matrix) +{ + CAST_BINOP_ARGS (const octave_char_matrix_str&, + const octave_matrix&); + + if (Vwarn_num_to_str) + gripe_implicit_conversion (v2.type_name (), v1.type_name ()); + + return octave_value (concat (v1.char_array_value (), v2.array_value (), + ra_idx), true); +} + +DEFCATOP (m_str, matrix, char_matrix_str) +{ + CAST_BINOP_ARGS (const octave_matrix&, + const octave_char_matrix_str&); + + if (Vwarn_num_to_str) + gripe_implicit_conversion (v1.type_name (), v2.type_name ()); + + return octave_value (concat (v1.array_value (), v2.char_array_value (), + ra_idx), true); +} + void install_str_m_ops (void) { INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_matrix, assign); + + INSTALL_CATOP (octave_char_matrix_str, octave_matrix, str_m); + INSTALL_CATOP (octave_matrix, octave_char_matrix_str, m_str); } /*
--- a/src/OPERATORS/op-str-s.cc +++ b/src/OPERATORS/op-str-s.cc @@ -48,10 +48,37 @@ return octave_value (); } +DEFCATOP (str_s, char_matrix_str, scalar) +{ + CAST_BINOP_ARGS (const octave_char_matrix_str&, + const octave_scalar&); + + if (Vwarn_num_to_str) + gripe_implicit_conversion (v2.type_name (), v1.type_name ()); + + return octave_value (concat (v1.char_array_value (), v2.array_value (), + ra_idx), true); +} + +DEFCATOP (s_str, scalar, char_matrix_str) +{ + CAST_BINOP_ARGS (const octave_scalar&, + const octave_char_matrix_str&); + + if (Vwarn_num_to_str) + gripe_implicit_conversion (v1.type_name (), v2.type_name ()); + + return octave_value (concat (v1.array_value (), v2.char_array_value (), + ra_idx), true); +} + void install_str_s_ops (void) { INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_scalar, assign); + + INSTALL_CATOP (octave_char_matrix_str, octave_scalar, str_s); + INSTALL_CATOP (octave_scalar, octave_char_matrix_str, s_str); } /*
--- a/src/OPERATORS/op-str-str.cc +++ b/src/OPERATORS/op-str-str.cc @@ -117,6 +117,14 @@ return octave_value (); } +DEFCATOP (str_str, char_matrix_str, char_matrix_str) +{ + CAST_BINOP_ARGS (const octave_char_matrix_str&, + const octave_char_matrix_str&); + return octave_value (concat (v1.char_array_value (), v2.char_array_value (), + ra_idx), true); +} + void install_str_str_ops (void) { @@ -126,6 +134,8 @@ INSTALL_BINOP (op_eq, octave_char_matrix_str, octave_char_matrix_str, eq); INSTALL_BINOP (op_ne, octave_char_matrix_str, octave_char_matrix_str, ne); + INSTALL_CATOP (octave_char_matrix_str, octave_char_matrix_str, str_str); + INSTALL_ASSIGNOP (op_asn_eq, octave_char_matrix_str, octave_char_matrix_str, assign); }
--- a/src/TEMPLATE-INST/Array-tc.cc +++ b/src/TEMPLATE-INST/Array-tc.cc @@ -51,8 +51,6 @@ INSTANTIATE_ARRAY_ASSIGN (octave_value, octave_value); -INSTANTIATE_ARRAY_CAT (octave_value); - template class Array2<octave_value>; template class ArrayN<octave_value>;
--- a/src/bitfcns.cc +++ b/src/bitfcns.cc @@ -31,11 +31,53 @@ #include "error.h" #include "ov.h" #include "ov-uint64.h" - +#include "ov-uint32.h" +#include "ov-uint16.h" +#include "ov-uint8.h" +#include "ov-int64.h" +#include "ov-int32.h" +#include "ov-int16.h" +#include "ov-int8.h" +#include "ov-scalar.h" +#include "ov-re-mat.h" // XXX FIXME XXX -- could probably eliminate some code duplication by // clever use of templates. +#define BITOPX(OP, FNAME, RET) \ + { \ + int nelx = x.numel (); \ + int nely = y.numel (); \ + \ + bool is_scalar_op = (nelx == 1 || nely == 1); \ + \ + dim_vector dvx = x.dims (); \ + dim_vector dvy = y.dims (); \ + \ + bool is_array_op = (dvx == dvy); \ + \ + if (is_array_op || is_scalar_op) \ + { \ + RET result; \ + \ + if (nelx != 1) \ + result.resize (dvx); \ + else \ + result.resize (dvy); \ + \ + for (int i = 0; i < nelx; i++) \ + if (is_scalar_op) \ + for (int k = 0; k < nely; k++) \ + result(i+k) = x(i) OP y(k); \ + else \ + result(i) = x(i) OP y(i); \ + \ + retval = result; \ + } \ + else \ + error ("%s: size of x and y must match, or one operand must be a scalar", FNAME); \ + } + #define BITOP(OP, FNAME) \ \ octave_value retval; \ @@ -44,44 +86,175 @@ \ if (nargin == 2) \ { \ - uint64NDArray x = args(0).uint64_array_value (); \ - uint64NDArray y = args(1).uint64_array_value (); \ - \ - if (! error_state) \ + if (args(0).type_id () == octave_matrix::static_type_id () || \ + args(0).type_id () == octave_scalar::static_type_id () || \ + args(1).type_id () == octave_matrix::static_type_id () || \ + args(1).type_id () == octave_scalar::static_type_id ()) \ { \ - int nelx = x.numel (); \ - int nely = y.numel (); \ - \ - bool is_scalar_op = (nelx == 1 || nely == 1); \ + bool arg0_is_int = true; \ + bool arg1_is_int = true; \ \ - dim_vector dvx = x.dims (); \ - dim_vector dvy = y.dims (); \ - \ - bool is_array_op = (dvx == dvy); \ + if (args(0).type_id () == octave_matrix::static_type_id () || \ + args(0).type_id () == octave_scalar::static_type_id ()) \ + arg0_is_int = false; \ \ - if (is_array_op || is_scalar_op) \ - { \ - uint64NDArray result; \ - \ - if (nelx != 1) \ - result.resize (dvx); \ - else \ - result.resize (dvy); \ + if (args(1).type_id () == octave_matrix::static_type_id () || \ + args(1).type_id () == octave_scalar::static_type_id ()) \ + arg1_is_int = false; \ \ - for (int i = 0; i < nelx; i++) \ - if (is_scalar_op) \ - for (int k = 0; k < nely; k++) \ - result(i+k) = x(i) OP y(k); \ - else \ - result(i) = x(i) OP y(i); \ - \ - retval = result; \ + if (!arg0_is_int && !arg1_is_int) \ + { \ + uint64NDArray x (args(0).array_value ()); \ + uint64NDArray y (args(1).array_value ()); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint64NDArray); \ + retval = retval.array_value (); \ } \ else \ - error ("%s: size of x and y must match, or one operand must be a scalar", FNAME); \ - } \ + { \ + int p = (arg0_is_int ? 1 : 0); \ + int q = (arg0_is_int ? 0 : 1); \ + NDArray dx = args(p).array_value (); \ + \ + if (args(q).type_id () == octave_uint64_matrix::static_type_id () || \ + args(q).type_id () == octave_uint64_scalar::static_type_id ()) \ + { \ + uint64NDArray x (dx); \ + uint64NDArray y = args(q).uint64_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint64NDArray); \ + } \ + else if (args(q).type_id () == octave_uint32_matrix::static_type_id () || \ + args(q).type_id () == octave_uint32_scalar::static_type_id ()) \ + { \ + uint32NDArray x (dx); \ + uint32NDArray y = args(q).uint32_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint32NDArray); \ + } \ + else if (args(q).type_id () == octave_uint16_matrix::static_type_id () || \ + args(q).type_id () == octave_uint16_scalar::static_type_id ()) \ + { \ + uint16NDArray x (dx); \ + uint16NDArray y = args(q).uint16_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint16NDArray); \ + } \ + else if (args(q).type_id () == octave_uint8_matrix::static_type_id () || \ + args(q).type_id () == octave_uint8_scalar::static_type_id ()) \ + { \ + uint8NDArray x (dx); \ + uint8NDArray y = args(q).uint8_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint8NDArray); \ + } \ + else if (args(q).type_id () == octave_int64_matrix::static_type_id () || \ + args(q).type_id () == octave_int64_scalar::static_type_id ()) \ + { \ + int64NDArray x (dx); \ + int64NDArray y = args(q).int64_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, int64NDArray); \ + } \ + else if (args(q).type_id () == octave_int32_matrix::static_type_id () || \ + args(q).type_id () == octave_int32_scalar::static_type_id ()) \ + { \ + int32NDArray x (dx); \ + int32NDArray y = args(q).int32_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, int32NDArray); \ + } \ + else if (args(q).type_id () == octave_int16_matrix::static_type_id () || \ + args(q).type_id () == octave_int16_scalar::static_type_id ()) \ + { \ + int16NDArray x (dx); \ + int16NDArray y = args(q).int16_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, int16NDArray); \ + } \ + else if (args(q).type_id () == octave_int8_matrix::static_type_id () || \ + args(q).type_id () == octave_int8_scalar::static_type_id ()) \ + { \ + int8NDArray x (dx); \ + int8NDArray y = args(q).int8_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, int8NDArray); \ + } \ + else \ + error ("%s: illegal operand type", FNAME); \ + } \ + } \ + else if (args(0).type_id () == args(1).type_id ()) \ + { \ + if (args(0).type_id () == octave_uint64_matrix::static_type_id () || \ + args(0).type_id () == octave_uint64_scalar::static_type_id ()) \ + { \ + uint64NDArray x = args(0).uint64_array_value (); \ + uint64NDArray y = args(1).uint64_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint64NDArray); \ + } \ + else if (args(0).type_id () == octave_uint32_matrix::static_type_id () || \ + args(0).type_id () == octave_uint32_scalar::static_type_id ()) \ + { \ + uint32NDArray x = args(0).uint32_array_value (); \ + uint32NDArray y = args(1).uint32_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint32NDArray); \ + } \ + else if (args(0).type_id () == octave_uint16_matrix::static_type_id () || \ + args(0).type_id () == octave_uint16_scalar::static_type_id ()) \ + { \ + uint16NDArray x = args(0).uint16_array_value (); \ + uint16NDArray y = args(1).uint16_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint16NDArray); \ + } \ + else if (args(0).type_id () == octave_uint8_matrix::static_type_id () || \ + args(0).type_id () == octave_uint8_scalar::static_type_id ()) \ + { \ + uint8NDArray x = args(0).uint8_array_value (); \ + uint8NDArray y = args(1).uint8_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, uint8NDArray); \ + } \ + else if (args(0).type_id () == octave_int64_matrix::static_type_id () || \ + args(0).type_id () == octave_int64_scalar::static_type_id ()) \ + { \ + int64NDArray x = args(0).int64_array_value (); \ + int64NDArray y = args(1).int64_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, int64NDArray); \ + } \ + else if (args(0).type_id () == octave_int32_matrix::static_type_id () || \ + args(0).type_id () == octave_int32_scalar::static_type_id ()) \ + { \ + int32NDArray x = args(0).int32_array_value (); \ + int32NDArray y = args(1).int32_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, int32NDArray); \ + } \ + else if (args(0).type_id () == octave_int16_matrix::static_type_id () || \ + args(0).type_id () == octave_int16_scalar::static_type_id ()) \ + { \ + int16NDArray x = args(0).int16_array_value (); \ + int16NDArray y = args(1).int16_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, int16NDArray); \ + } \ + else if (args(0).type_id () == octave_int8_matrix::static_type_id () || \ + args(0).type_id () == octave_int8_scalar::static_type_id ()) \ + { \ + int8NDArray x = args(0).int8_array_value (); \ + int8NDArray y = args(1).int8_array_value (); \ + if (! error_state) \ + BITOPX (OP, FNAME, int8NDArray); \ + } \ + else \ + error ("%s: illegal operand type", FNAME); \ + } \ else \ - error ("%s: expecting uint64 arguments", FNAME); \ + error ("%s: must have matching operand types", FNAME); \ } \ else \ print_usage (FNAME); \ @@ -121,73 +294,20 @@ BITOP (^, "bitxor"); } -DEFUN (bitcmp, args, , - "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} bitcmp (@var{a}, @var{k})\n\ -returns the @var{k}-bit complement of integers in @var{a}. If\n\ -@var{k} is omitted k = log2(bitmax) is assumed.\n\ -\n\ -@example\n\ -bitcmp (7, 4)\n\ -@result{} 8\n\ -dec2bin (11)\n\ -@result{} 1011\n\ -dec2bin (bitcmp (11))\n\ -@result{} 11111111111111111111111111110100\n\ -@end example\n\ -\n\ -@end deftypefn\n\ -@seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}") +static EIGHT_BYTE_INT +bitshift (const double& a, int n) { - octave_value retval; - error ("not implemented"); - return retval; + if (n > 0) + return static_cast<EIGHT_BYTE_INT> (a) << n; + else if (n < 0) + return static_cast<EIGHT_BYTE_INT> (a) >> -n; + else + return static_cast<EIGHT_BYTE_INT> (a); } -DEFUN (bitget, args, , - "-*- texinfo -*-\n\ -@deftypefn {Function File} {} bitget (@var{a}, @var{n})\n\ -returns the status of bit(s) @var{n} of unsigned integers in @var{a}\n\ -the lowest significant bit is @var{n} = 1.\n\ -\n\ -@example\n\ -bitget (100,8:-1:1)\n\ -@result{} 0 1 1 0 0 1 0 0\n\ -@end example\n\ -@end deftypefn\n\ -@seealso{bitand, bitor, bitxor, bitset, bitcmp, bitshift, bitmax}") -{ - octave_value retval; - error ("not implemented"); - return retval; -} - -DEFUN (bitset, args, , - "-*- texinfo -*-\n\ -@deftypefn {Function File} {} bitset (@var{a}, @var{n})\n\ -@deftypefnx {Function File} {} bitset (@var{a}, @var{n}, @var{v})\n\ -sets or resets bit(s) @var{n} of unsigned integers in @var{a}.\n\ -@var{v} = 0 resets and @var{v} = 1 sets the bits.\n\ -The lowest significant bit is: @var{n} = 1\n\ -\n\ -@example\n\ -dec2bin (bitset (10, 1))\n\ -@result{} 1011\n\ -@end example\n\ -\n\ -@end deftypefn\n\ -@seealso{bitand, bitor, bitxor, bitget, bitcmp, bitshift, bitmax}") -{ - octave_value retval; - error ("not implemented"); - return retval; -} - +// Note that the bitshift operators are undefined if shifted by more bits than +// in the type. Therefore need to test for the size of the shift #define DO_BITSHIFT(T) \ - do \ - { \ - T ## NDArray m = m_arg.T ## _array_value (); \ - \ if (! error_state) \ { \ double d1, d2; \ @@ -216,9 +336,15 @@ for (int i = 0; i < m_nel; i++) \ if (is_scalar_op) \ for (int k = 0; k < n_nel; k++) \ - result(i+k) = bitshift (m(i), static_cast<int> (n(k))); \ + if (static_cast<int> (n(k)) >= bits_in_type) \ + result(i+k) = 0; \ + else \ + result(i+k) = bitshift (m(i), static_cast<int> (n(k))) & mask; \ else \ - result(i) = bitshift (m(i), static_cast<int> (n(i))); \ + if (static_cast<int> (n(i)) >= bits_in_type) \ + result(i) = 0; \ + else \ + result(i) = bitshift (m(i), static_cast<int> (n(i))) & mask; \ \ retval = result; \ } \ @@ -227,8 +353,34 @@ } \ else \ error ("bitshift: expecting second argument to be integer"); \ - } \ - } \ + } + +#define DO_UBITSHIFT(T, N) \ + do \ + { \ + int bits_in_type = sizeof (octave_ ## T) << 3; \ + T ## NDArray m = m_arg.T ## _array_value (); \ + octave_ ## T mask = ~0ULL; \ + if ((N) < static_cast<int>(sizeof (octave_ ## T) << 3)) \ + mask = mask >> ((sizeof (octave_ ## T) << 3) - (N)); \ + else if ((N) < 1) \ + mask = 0; \ + DO_BITSHIFT (T); \ + } \ + while (0) + +#define DO_SBITSHIFT(T, N) \ + do \ + { \ + int bits_in_type = sizeof (octave_ ## T) << 3; \ + T ## NDArray m = m_arg.T ## _array_value (); \ + octave_ ## T mask = -1; \ + if ((N) < static_cast<int>(sizeof (octave_ ## T) << 3)) \ + mask = mask >> ((sizeof (octave_ ## T) << 3) - (N)); \ + else if ((N) < 1) \ + mask = 0; \ + DO_BITSHIFT (T); \ + } \ while (0) DEFUN (bitshift, args, , @@ -237,9 +389,9 @@ @deftypefnx {Function File} {} bitshift (@var{a}, @var{k}, @var{n})\n\ return a @var{k} bit shift of @var{n}- digit unsigned\n\ integers in @var{a}. A positive @var{k} leads to a left shift.\n\ -A negative value to a right shift. If @var{N} is omitted it defaults\n\ +A negative value to a right shift. If @var{n} is omitted it defaults\n\ to log2(bitmax)+1. \n\ -@var{N} must be in range [1,log2(bitmax)+1] usually [1,33]\n\ +@var{n} must be in range [1,log2(bitmax)+1] usually [1,33]\n\ \n\ @example\n\ bitshift (eye (3), 1))\n\ @@ -263,22 +415,53 @@ int nargin = args.length (); - if (nargin == 2) + if (nargin == 2 || nargin == 3) { NDArray n = args(1).array_value (); + int nbits = 64; + + if (nargin == 3) + { + nbits = args(2).nint_value (); + + if (nbits < 0) + error ("bitshift: number of bits to mask must be positive"); + } + + if (error_state) + return retval; octave_value m_arg = args(0); - std::string cname = m_arg.class_name (); if (cname == "uint8") - DO_BITSHIFT (uint8); + DO_UBITSHIFT (uint8, nbits < 8 ? nbits : 8); else if (cname == "uint16") - DO_BITSHIFT (uint16); + DO_UBITSHIFT (uint16, nbits < 16 ? nbits : 16); else if (cname == "uint32") - DO_BITSHIFT (uint32); + DO_UBITSHIFT (uint32, nbits < 32 ? nbits : 32); else if (cname == "uint64") - DO_BITSHIFT (uint64); + DO_UBITSHIFT (uint64, nbits < 64 ? nbits : 64); + else if (cname == "int8") + DO_SBITSHIFT (int8, nbits < 8 ? nbits : 8); + else if (cname == "int16") + DO_SBITSHIFT (int16, nbits < 16 ? nbits : 16); + else if (cname == "int32") + DO_SBITSHIFT (int32, nbits < 32 ? nbits : 32); + else if (cname == "int64") + DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64); + else if (cname == "double") + { + nbits = (nbits < 53 ? nbits : 53); + EIGHT_BYTE_INT mask = 0x1FFFFFFFFFFFFFLL; + if (nbits < 53) + mask = mask >> (53 - nbits); + else if (nbits < 1) + mask = 0; + int bits_in_type = 64; + NDArray m = m_arg.array_value (); + DO_BITSHIFT ( ); + } else error ("bitshift: not defined for %s objects", cname.c_str ()); } @@ -290,11 +473,94 @@ DEFUN (bitmax, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} bitmax (@var{x}, @var{y})\n\ +@deftypefn {Built-in Function} {} bitmax ()\n\ +Returns the largest integer that can be represented as a floating point\n\ +value. That is for IEEE-754 compatiable systems with @code{2^53 - 1}.\n\ +@end deftypefn") +{ + octave_value retval; + if (args.length() != 0) + print_usage ("bitmax"); + else + retval = ((double)0x1FFFFFFFFFFFFFLL); + return retval; +} + +DEFUN (intmax, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} intmax (@var{type})\n\ @end deftypefn") { octave_value retval; - error ("not implemented"); + std::string cname = "int32"; + int nargin = args.length (); + + if (nargin == 1 && args(0).is_string()) + cname = args(0).string_value (); + else if (nargin != 0) + { + print_usage ("intmax"); + return retval; + } + + if (cname == "uint8") + retval = octave_uint8 (std::numeric_limits<octave_uint8_t>::max()); + else if (cname == "uint16") + retval = octave_uint16 (std::numeric_limits<octave_uint16_t>::max()); + else if (cname == "uint32") + retval = octave_uint32 (std::numeric_limits<octave_uint32_t>::max()); + else if (cname == "uint64") + retval = octave_uint64 (std::numeric_limits<octave_uint64_t>::max()); + else if (cname == "int8") + retval = octave_int8 (std::numeric_limits<octave_int8_t>::max()); + else if (cname == "int16") + retval = octave_int16 (std::numeric_limits<octave_int16_t>::max()); + else if (cname == "int32") + retval = octave_int32 (std::numeric_limits<octave_int32_t>::max()); + else if (cname == "int64") + retval = octave_int64 (std::numeric_limits<octave_int64_t>::max()); + else + error ("intmax: not defined for '%s' objects", cname.c_str ()); + + return retval; +} + +DEFUN (intmin, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} intmin (@var{type})\n\ +@end deftypefn") +{ + octave_value retval; + std::string cname = "int32"; + int nargin = args.length (); + + if (nargin == 1 && args(0).is_string()) + cname = args(0).string_value (); + else if (nargin != 0) + { + print_usage ("intmin"); + return retval; + } + + if (cname == "uint8") + retval = octave_uint8 (std::numeric_limits<octave_uint8_t>::min()); + else if (cname == "uint16") + retval = octave_uint16 (std::numeric_limits<octave_uint16_t>::min()); + else if (cname == "uint32") + retval = octave_uint32 (std::numeric_limits<octave_uint32_t>::min()); + else if (cname == "uint64") + retval = octave_uint64 (std::numeric_limits<octave_uint64_t>::min()); + else if (cname == "int8") + retval = octave_int8 (std::numeric_limits<octave_int8_t>::min()); + else if (cname == "int16") + retval = octave_int16 (std::numeric_limits<octave_int16_t>::min()); + else if (cname == "int32") + retval = octave_int32 (std::numeric_limits<octave_int32_t>::min()); + else if (cname == "int64") + retval = octave_int64 (std::numeric_limits<octave_int64_t>::min()); + else + error ("intmin: not defined for '%s' objects", cname.c_str ()); + return retval; }
--- a/src/data.cc +++ b/src/data.cc @@ -42,6 +42,7 @@ #include "utils.h" #include "Cell.h" #include "oct-map.h" +#include "pt-mat.h" #define ANY_ALL(FCN) \ \ @@ -667,91 +668,6 @@ DATA_REDUCTION (prod); } -static bool -cat_add_dims (dim_vector& dv_new, const dim_vector& dv_arg, int dim) -{ - // dv_arg is [] - - if (dv_arg.all_zero ()) - return true; - - // dv_new is [] - - if (dv_new.all_zero ()) - { - dv_new = dv_arg; - return true; - } - - int n_new = dv_new.length (); - int n_args = dv_arg.length (); - - // Find the max and min value of n_new and n_args - - int n_max = n_new > n_args ? n_new : n_args; - int n_min = n_new < n_args ? n_new : n_args; - - // 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 (dv_new(i) != dv_arg(i) && dim != i) - { - error ("cat: dimension mismatch"); - return false; - } - } - - // Ditto. - - for (int i = n_min; i < n_max; i++) - { - if (n_new > n_min) - { - if (dv_new(i) != 1 && dim != i) - { - error ("cat: dimension mismatch"); - return false; - } - } - else - { - if (dv_arg(i) != 1 && dim != i) - { - error ("cat: dimension mismatch"); - 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 dv_new to the right dimension. - - n_max = n_max > (dim + 1) ? n_max : (dim + 1); - - // Resize dv_new to new the appropriate dimensions. - - if (n_max > n_new) - { - dv_new.resize (n_max); - - for (int i = n_new; i < n_max; i++) - dv_new.elem (i) = 1; - } - - // Larger or equal since dim has been decremented by one. - - if (dim >= n_args) - dv_new.elem (dim) = dv_new.elem (dim)++; - else - dv_new.elem (dim) += dv_arg(dim); - - return true; -} - static octave_value do_cat (const octave_value_list& args, std::string fname) { @@ -771,183 +687,67 @@ if (dim >= 0) { + + dim_vector dv = args(1).dims (); - dim_vector dv = args(1).dims (); - - for (int i = 2; i < args.length (); i++) - { - // add_dims constructs a dimension vector which holds the + 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)) + if (! dv.concat (args(i).dims (), dim)) { // Dimensions do not match. - // cat_add_dims printed a error msg + error ("cat: dimension mismatch"); 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: + // The lines below might seem crazy, since we take a copy + // of the first argument, resize it to be empty and then resize + // it to be full. This is done since it means that there is no + // recopying of data, as would happen if we used a single resize. + // It should be noted that resize operation is also significantly + // slower than the do_cat_op function, so it makes sense to have an + // empty matrix and copy all data. // - // 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 (); + // We might also start with a empty octave_value using + // tmp = octave_value_typeinfo::lookup_type (args(1).type_name()); + // and then directly resize. However, for some types there might be + // some additional setup needed, and so this should be avoided. + octave_value tmp; + bool any_strings = false; + bool all_strings = true; + for (int i = 1; i < n_args; i++) + if (args(i).is_string ()) + any_strings = true; + else + all_strings = false; - if (error_state) - return retval; + if (all_strings) + tmp = octave_value (charNDArray (dv, Vstring_fill_char), true); + else + tmp = args(1).resize (dim_vector (0,0)).resize (dv); - 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; + 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; + Array<int> ra_idx (dv.length (), 0); + for (int i = 1; i < n_args; i++) + { + tmp = do_cat_op (tmp, args (i), ra_idx); - 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; + 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; + dim_vector dv_tmp = args (i).dims (); + ra_idx (dim) += (dim < dv_tmp.length () ? dv_tmp (dim) : 1); + } - 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); + if (any_strings && !all_strings) + retval = tmp.convert_to_str (); + else + retval = tmp; } else print_usage (fname); }
--- a/src/oct-map.cc +++ b/src/oct-map.cc @@ -88,11 +88,14 @@ return retval; } -int -Octave_map::cat (const Octave_map& ra_arg, int dim, int iidx, int move) +Octave_map +concat (const Octave_map& ra, const Octave_map& rb, const Array<int>& ra_idx) { - //return ::cat_ra (*this, ra_arg, dim, iidx, move); - return 0; + // XXX FIXME XXX + Octave_map retval; + //Octave_map retval (ra); + //::concat_ra (retval, rb, dim) + return retval; } static string_vector
--- a/src/oct-map.h +++ b/src/oct-map.h @@ -118,7 +118,8 @@ int numel (void) const; - int cat (const Octave_map& ra_arg, int dim, int iidx, int move); + friend Octave_map concat (const Octave_map& ra, const Octave_map& rb, + const Array<int>& ra_idx); Octave_map& assign (const octave_value_list& idx, const Octave_map& rhs);
--- a/src/ops.h +++ b/src/ops.h @@ -40,6 +40,10 @@ (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ oct_binop_ ## f); +#define INSTALL_CATOP(t1, t2, f) \ + octave_value_typeinfo::register_cat_op \ + (t1::static_type_id (), t2::static_type_id (), oct_catop_ ## f); + #define INSTALL_ASSIGNOP(op, t1, t2, f) \ octave_value_typeinfo::register_assign_op \ (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ @@ -306,6 +310,39 @@ a2.rows (), a2.columns ()); \ return octave_value () +#define CATOPDECL(name, a1, a2) \ + static octave_value \ + oct_catop_ ## name (const octave_value& a1, const octave_value& a2, \ + const Array<int>& ra_idx) + +#define DEFCATOPX(name, t1, t2) \ + CATOPDECL (name, , ) + +#define DEFCATOP(name, t1, t2) \ + CATOPDECL (name, a1, a2) + +// XXX FIXME XXX -- in some cases, the constructor isn't necessary. + +#define DEFCATOP_FN(name, t1, t2, f) \ + CATOPDECL (name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value (f (v1.t1 ## _value (), v2.t2 ## _value (), ra_idx)); \ + } + +#define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \ + CATOPDECL (name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value (f (v1.e1 ## _value (), v2.e2 ## _value (), ra_idx)); \ + } + +#define CATOP_NONCONFORMANT(msg) \ + gripe_nonconformant (msg, \ + a1.rows (), a1.columns (), \ + a2.rows (), a2.columns ()); \ + return octave_value () + #endif /*
--- a/src/ov-base-mat.cc +++ b/src/ov-base-mat.cc @@ -211,14 +211,14 @@ bool retval = false; dim_vector dv = matrix.dims (); int nel = dv.numel (); - + if (nel > 0) { MT t1 (matrix.reshape (dim_vector (nel, 1))); boolNDArray t2 = t1.all (); - retval = t2(0,0); + retval = t2(0); } return retval;
--- a/src/ov-base-mat.h +++ b/src/ov-base-mat.h @@ -103,6 +103,9 @@ octave_value permute (const Array<int>& vec, bool inv = false) const { return MT (matrix.permute (vec, inv)); } + octave_value resize (const dim_vector& dv) const + { MT retval (matrix); retval.resize (dv); return retval; } + octave_value all (int dim = 0) const { return matrix.all (dim); } octave_value any (int dim = 0) const { return matrix.any (dim); }
--- a/src/ov-base.cc +++ b/src/ov-base.cc @@ -191,6 +191,13 @@ } octave_value +octave_base_value::resize (const dim_vector& dv) const +{ + gripe_wrong_type_arg ("octave_base_value::resize ()", type_name ()); + return octave_value (); +} + +octave_value octave_base_value::convert_to_str_internal (bool, bool) const { gripe_wrong_type_arg ("octave_base_value::convert_to_str_internal ()",
--- a/src/ov-base.h +++ b/src/ov-base.h @@ -102,6 +102,8 @@ octave_value permute (const Array<int>& vec, bool = false) const; + octave_value resize (const dim_vector& dv) const; + bool is_defined (void) const { return false; } bool is_cell (void) const { return false; }
--- a/src/ov-bool.h +++ b/src/ov-bool.h @@ -111,6 +111,9 @@ boolNDArray bool_array_value (void) const { return boolNDArray (dim_vector (1, 1), scalar); } + octave_value resize (const dim_vector& dv) const + { boolNDArray retval (dv); if (dv.numel()) retval(0) = scalar; return retval; } + octave_value convert_to_str_internal (bool pad, bool force) const; bool save_ascii (std::ostream& os, bool& infnan_warned,
--- a/src/ov-complex.h +++ b/src/ov-complex.h @@ -95,6 +95,9 @@ NDArray array_value (bool = false) const; + octave_value resize (const dim_vector& dv) const + { ComplexNDArray retval (dv); if (dv.numel()) retval(0) = scalar; return retval; } + Complex complex_value (bool = false) const; ComplexMatrix complex_matrix_value (bool = false) const;
--- a/src/ov-intx.h +++ b/src/ov-intx.h @@ -61,6 +61,16 @@ OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION (void) const { return matrix; } + NDArray + array_value (bool = false) const + { + NDArray retval (matrix.dims ()); + int nel = matrix.numel (); + for (int i = 0; i < nel; i++) + retval (i) = double (matrix(i)); + return retval; + } + private: DECLARE_OCTAVE_ALLOCATOR @@ -98,6 +108,17 @@ OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION (void) const { return OCTAVE_INT_NDARRAY_T (dim_vector (1, 1), scalar); } + octave_value resize (const dim_vector& dv) const + { OCTAVE_INT_NDARRAY_T retval (dv); if (dv.numel()) retval(0) = scalar; return retval; } + + NDArray + array_value (bool = false) const + { + NDArray retval (dim_vector (1,1)); + retval (0) = double (scalar); + return retval; + } + private: DECLARE_OCTAVE_ALLOCATOR
--- a/src/ov-range.h +++ b/src/ov-range.h @@ -108,6 +108,9 @@ return dim_vector (n > 0, n); } + octave_value resize (const dim_vector& dv) const + { NDArray retval = array_value (); retval.resize (dv); return retval; } + size_t byte_size (void) const { return 3 * sizeof (double); } octave_value reshape (const dim_vector& new_dims) const
--- a/src/ov-scalar.h +++ b/src/ov-scalar.h @@ -97,6 +97,9 @@ NDArray array_value (bool = false) const { return NDArray (dim_vector (1, 1), scalar); } + octave_value resize (const dim_vector& dv) const + { NDArray retval (dv); if (dv.numel()) retval(0) = scalar; return retval; } + Complex complex_value (bool = false) const { return scalar; } ComplexMatrix complex_matrix_value (bool = false) const
--- a/src/ov-typeinfo.cc +++ b/src/ov-typeinfo.cc @@ -56,6 +56,9 @@ template class Array2<binary_op_fcn>; template class Array3<binary_op_fcn>; +INSTANTIATE_ARRAY (cat_op_fcn); +template class Array2<cat_op_fcn>; + INSTANTIATE_ARRAY (assign_op_fcn); template class Array2<assign_op_fcn>; template class Array3<assign_op_fcn>; @@ -116,6 +119,13 @@ } bool +octave_value_typeinfo::register_cat_op (int t1, int t2, cat_op_fcn f) +{ + return (instance_ok ()) + ? instance->do_register_cat_op (t1, t2, f) : false; +} + +bool octave_value_typeinfo::register_assign_op (octave_value::assign_op op, int t_lhs, int t_rhs, assign_op_fcn f) @@ -190,6 +200,8 @@ binary_ops.resize (static_cast<int> (octave_value::num_binary_ops), len, len, static_cast<binary_op_fcn> (0)); + cat_ops.resize (len, len, static_cast<cat_op_fcn> (0)); + assign_ops.resize (static_cast<int> (octave_value::num_assign_ops), len, len, static_cast<assign_op_fcn> (0)); @@ -269,6 +281,23 @@ } bool +octave_value_typeinfo::do_register_cat_op (int t1, int t2, cat_op_fcn f) +{ + if (lookup_cat_op (t1, t2)) + { + std::string t1_name = types(t1); + std::string t2_name = types(t2); + + warning ("duplicate concatenation operator for types `%s' and `%s'", + t1_name.c_str (), t1_name.c_str ()); + } + + cat_ops.checkelem (t1, t2) = f; + + return false; +} + +bool octave_value_typeinfo::do_register_assign_op (octave_value::assign_op op, int t_lhs, int t_rhs, assign_op_fcn f) @@ -398,6 +427,12 @@ return binary_ops.checkelem (static_cast<int> (op), t1, t2); } +cat_op_fcn +octave_value_typeinfo::do_lookup_cat_op (int t1, int t2) +{ + return cat_ops.checkelem (t1, t2); +} + assign_op_fcn octave_value_typeinfo::do_lookup_assign_op (octave_value::assign_op op, int t_lhs, int t_rhs)
--- a/src/ov-typeinfo.h +++ b/src/ov-typeinfo.h @@ -55,6 +55,8 @@ static bool register_binary_op (octave_value::binary_op, int, int, binary_op_fcn); + static bool register_cat_op (int, int, cat_op_fcn); + static bool register_assign_op (octave_value::assign_op, int, int, assign_op_fcn); @@ -91,6 +93,12 @@ return instance->do_lookup_binary_op (op, t1, t2); } + static cat_op_fcn + lookup_cat_op (int t1, int t2) + { + return instance->do_lookup_cat_op (t1, t2); + } + static assign_op_fcn lookup_assign_op (octave_value::assign_op op, int t_lhs, int t_rhs) { @@ -137,6 +145,7 @@ (non_const_unary_op_fcn) 0), binary_ops (octave_value::num_binary_ops, init_tab_sz, init_tab_sz, (binary_op_fcn) 0), + cat_ops (init_tab_sz, init_tab_sz, (cat_op_fcn) 0), assign_ops (octave_value::num_assign_ops, init_tab_sz, init_tab_sz, (assign_op_fcn) 0), assignany_ops (octave_value::num_assign_ops, init_tab_sz, @@ -163,6 +172,8 @@ Array3<binary_op_fcn> binary_ops; + Array2<cat_op_fcn> cat_ops; + Array3<assign_op_fcn> assign_ops; Array2<assign_op_fcn> assignany_ops; @@ -184,6 +195,8 @@ bool do_register_binary_op (octave_value::binary_op, int, int, binary_op_fcn); + bool do_register_cat_op (int, int, cat_op_fcn); + bool do_register_assign_op (octave_value::assign_op, int, int, assign_op_fcn); @@ -205,6 +218,8 @@ binary_op_fcn do_lookup_binary_op (octave_value::binary_op, int, int); + cat_op_fcn do_lookup_cat_op (int, int); + assign_op_fcn do_lookup_assign_op (octave_value::assign_op, int, int); assign_op_fcn do_lookup_assignany_op (octave_value::assign_op, int);
--- a/src/ov.cc +++ b/src/ov.cc @@ -1662,6 +1662,92 @@ return retval; } +static void +gripe_cat_op (const std::string& tn1, const std::string& tn2) +{ + error ("concatenation operator not implemented for `%s' by `%s' operations", + tn1.c_str (), tn2.c_str ()); +} + +static void +gripe_cat_op_conv (void) +{ + error ("type conversion failed for concatenation operator"); +} + +octave_value +do_cat_op (const octave_value& v1, const octave_value& v2, + const Array<int>& ra_idx) +{ + octave_value retval; + + int t1 = v1.type_id (); + int t2 = v2.type_id (); + + cat_op_fcn f = octave_value_typeinfo::lookup_cat_op (t1, t2); + + if (f) + retval = f (*v1.rep, *v2.rep, ra_idx); + else + { + octave_value tv1; + type_conv_fcn cf1 = v1.numeric_conversion_function (); + + if (cf1) + { + octave_value *tmp = cf1 (*v1.rep); + + if (tmp) + { + tv1 = octave_value (tmp); + t1 = tv1.type_id (); + } + else + { + gripe_cat_op_conv (); + return retval; + } + } + else + tv1 = v1; + + octave_value tv2; + type_conv_fcn cf2 = v2.numeric_conversion_function (); + + if (cf2) + { + octave_value *tmp = cf2 (*v2.rep); + + if (tmp) + { + tv2 = octave_value (tmp); + t2 = tv2.type_id (); + } + else + { + gripe_cat_op_conv (); + return retval; + } + } + else + tv2 = v2; + + if (cf1 || cf2) + { + f = octave_value_typeinfo::lookup_cat_op (t1, t2); + + if (f) + retval = f (*tv1.rep, *tv2.rep, ra_idx); + else + gripe_cat_op (v1.type_name (), v2.type_name ()); + } + else + gripe_cat_op (v1.type_name (), v2.type_name ()); + } + + return retval; +} + void octave_value::print_info (std::ostream& os, const std::string& prefix) const {
--- a/src/ov.h +++ b/src/ov.h @@ -84,6 +84,9 @@ typedef octave_value (*binary_op_fcn) (const octave_value&, const octave_value&); +typedef octave_value (*cat_op_fcn) + (const octave_value&, const octave_value&, const Array<int>& ra_idx); + typedef octave_value (*assign_op_fcn) (octave_value&, const octave_value_list&, const octave_value&); @@ -367,6 +370,9 @@ octave_value ipermute (const Array<int>& vec) const { return rep->permute (vec, true); } + virtual octave_value resize (const dim_vector& dv) const + { return rep->resize (dv);} + // Does this constant have a type? Both of these are provided since // it is sometimes more natural to write is_undefined() instead of // ! is_defined(). @@ -711,6 +717,10 @@ const octave_value& a, const octave_value& b); + friend octave_value do_cat_op (const octave_value& a, + const octave_value& b, + const Array<int>& ra_idx); + const octave_value& get_rep (void) const { return *rep; } virtual void print_info (std::ostream& os,
--- a/src/pt-mat.cc +++ b/src/pt-mat.cc @@ -215,12 +215,13 @@ } dv.elem (1) = dv.elem (1) + this_elt_nc; - append (val); } else if (Vwarn_empty_list_elements) eval_warning ("empty matrix found in matrix list", elt->line (), elt->column ()); + append (val); + if (all_str && ! val.is_string ()) all_str = false; @@ -491,10 +492,6 @@ return true; } -// Just about as ugly as it gets. -// Less ugly than before, anyway. -// Looking better all the time. - octave_value_list tree_matrix::rvalue (int nargout) { @@ -515,123 +512,84 @@ { octave_value retval; - tm_const tmp (*this); + bool all_strings_p = false; + bool all_empty_p = false; + bool frc_str_conv = false; - bool all_strings_p = false; - bool some_strings_p = false; - bool all_empty_p = false; - - bool frc_str_conv = false; + tm_const tmp (*this); if (tmp) { dim_vector dv = tmp.dims (); + all_strings_p = tmp.all_strings_p (); + all_empty_p = tmp.all_empty_p (); + frc_str_conv = tmp.some_strings_p (); - NDArray nd; - ComplexNDArray cnd; - charNDArray chnd; + // XXX FIXME XX + // The previous version of this code obtained the return type and + // initialized an array of the correct type. However the return type + // is now built-up from the return types of do_cat_op. Should we special + // case the situation where there are only NDArray and ComplexNDArray + // elements, or things like boolMatrix that widen to them, and do the + // correct initialization? How to do this? Will it be faster? Check against + // version 2.1.57 + + + // The line below might seem crazy, since we take a copy + // of the first argument, resize it to be empty and then resize + // it to be full. This is done since it means that there is no + // recopying of data, as would happen if we used a single resize. + // It should be noted that resize operation is also significantly + // slower than the do_cat_op function, so it makes sense to have an + // empty matrix and copy all data. + // + // We might also start with a empty octave_value using + // ctmp = octave_value_typeinfo::lookup_type + // (tmp.begin() -> begin() -> type_name()); + // and then directly resize. However, for some types there might be + // some additional setup needed, and so this should be avoided. + + octave_value ctmp; + if (all_strings_p) + if (all_empty_p) + ctmp = octave_value (charNDArray (), true); + else + ctmp = octave_value (charNDArray (dv, Vstring_fill_char), true); + else + { + if (all_empty_p) + ctmp = (*(tmp.begin() -> begin())); + else + ctmp = (*(tmp.begin() -> begin())).resize (dim_vector (0,0)).resize (dv); + } + + if (error_state) + goto done; // Now, extract the values from the individual elements and // insert them in the result matrix. - - bool found_complex = tmp.complex_p (); - - all_strings_p = tmp.all_strings_p (); - some_strings_p = tmp.some_strings_p (); - all_empty_p = tmp.all_empty_p (); - - frc_str_conv = some_strings_p; - - if (all_strings_p) - chnd.resize_and_fill (dv, Vstring_fill_char); - else if (found_complex) - cnd.resize_and_fill (dv, 0.0); - else - nd.resize_and_fill (dv, 0.0); - - int put_row = 0; - + Array<int> ra_idx (dv.length (), 0); for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++) { - int put_col = 0; - tm_row_const row = *p; - for (tm_row_const::iterator q = row.begin (); q != row.end (); q++) { octave_value elt = *q; - if (found_complex) - { - if (elt.is_real_scalar ()) - cnd (put_row, put_col) = elt.double_value (); - else if (elt.is_real_matrix () || elt.is_range ()) - cnd.insert (elt.array_value (), put_row, put_col); - else if (elt.is_complex_scalar ()) - cnd (put_row, put_col) = elt.complex_value (); - else - { - ComplexNDArray cnd_elt = elt.complex_array_value (); - - if (error_state) - goto done; - - cnd.insert (cnd_elt, put_row, put_col); - } - } - else - { - if (elt.is_real_scalar ()) - nd (put_row, put_col) = elt.double_value (); - else if (elt.is_string () && all_strings_p) - { - charNDArray chnd_elt = elt.char_array_value (); - - if (error_state) - goto done; - - chnd.insert (chnd_elt, put_row, put_col); - } - else - { - NDArray nd_elt = elt.array_value (frc_str_conv); - - if (error_state) - goto done; - - nd.insert (nd_elt, put_row, put_col); - } - } - - if (all_strings_p && chnd.rows () > 0 && chnd.cols () > 0) - retval = octave_value (chnd, true); - else if (found_complex) - retval = cnd; - else - retval = nd; - - put_col += elt.columns (); + ctmp = do_cat_op (ctmp, elt, ra_idx); + if (error_state) + goto done; + ra_idx (1) += elt.columns (); } - - put_row += row.rows (); + ra_idx (0) += row.rows (); + ra_idx (1) = 0; } + retval = ctmp; + if (frc_str_conv && ! retval.is_string ()) + retval = retval.convert_to_str (); } done: - - if (! error_state) - { - if (retval.is_undefined () && all_empty_p) - { - if (all_strings_p) - retval = ""; - else - retval = NDArray (); - } - else if (frc_str_conv && ! retval.is_string ()) - retval = retval.convert_to_str (); - } - return retval; }