ov-intx.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2004-2012 John W. Eaton
00004 Copyright (C) 2010 VZLU Prague
00005 
00006 This file is part of Octave.
00007 
00008 Octave is free software; you can redistribute it and/or modify it
00009 under the terms of the GNU General Public License as published by the
00010 Free Software Foundation; either version 3 of the License, or (at your
00011 option) any later version.
00012 
00013 Octave is distributed in the hope that it will be useful, but WITHOUT
00014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00015 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00016 for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with Octave; see the file COPYING.  If not, see
00020 <http://www.gnu.org/licenses/>.
00021 
00022 */
00023 
00024 #include <cstdlib>
00025 
00026 #include <iosfwd>
00027 #include <string>
00028 
00029 #include "mx-base.h"
00030 #include "oct-alloc.h"
00031 #include "str-vec.h"
00032 
00033 #include "error.h"
00034 #include "oct-stream.h"
00035 #include "ov-base.h"
00036 #include "ov-base-int.h"
00037 #include "ov-typeinfo.h"
00038 #include "gripes.h"
00039 
00040 #include "ov-re-mat.h"
00041 #include "ov-scalar.h"
00042 
00043 class
00044 OCTINTERP_API
00045 OCTAVE_VALUE_INT_MATRIX_T
00046   : public octave_base_int_matrix<intNDArray<OCTAVE_INT_T> >
00047 {
00048 public:
00049 
00050   OCTAVE_VALUE_INT_MATRIX_T (void)
00051     : octave_base_int_matrix<intNDArray<OCTAVE_INT_T> > () { }
00052 
00053   OCTAVE_VALUE_INT_MATRIX_T (const intNDArray<OCTAVE_INT_T>& nda)
00054     : octave_base_int_matrix<intNDArray<OCTAVE_INT_T> > (nda) { }
00055 
00056   OCTAVE_VALUE_INT_MATRIX_T (const Array<OCTAVE_INT_T>& nda)
00057     : octave_base_int_matrix<intNDArray<OCTAVE_INT_T> >
00058         (intNDArray<OCTAVE_INT_T> (nda)) { }
00059 
00060   ~OCTAVE_VALUE_INT_MATRIX_T (void) { }
00061 
00062   octave_base_value *clone (void) const
00063     { return new OCTAVE_VALUE_INT_MATRIX_T (*this); }
00064 
00065   octave_base_value *empty_clone (void) const
00066     { return new OCTAVE_VALUE_INT_MATRIX_T (); }
00067 
00068   bool OCTAVE_TYPE_PREDICATE_FUNCTION (void) const { return true; }
00069 
00070   bool is_integer_type (void) const { return true; }
00071 
00072   builtin_type_t builtin_type (void) const { return OCTAVE_INT_BTYP; }
00073 
00074 public:
00075 
00076   int8NDArray
00077   int8_array_value (void) const { return int8NDArray (matrix); }
00078 
00079   int16NDArray
00080   int16_array_value (void) const { return int16NDArray (matrix); }
00081 
00082   int32NDArray
00083   int32_array_value (void) const { return int32NDArray (matrix); }
00084 
00085   int64NDArray
00086   int64_array_value (void) const { return int64NDArray (matrix); }
00087 
00088   uint8NDArray
00089   uint8_array_value (void) const { return uint8NDArray (matrix); }
00090 
00091   uint16NDArray
00092   uint16_array_value (void) const { return uint16NDArray (matrix); }
00093 
00094   uint32NDArray
00095   uint32_array_value (void) const { return uint32NDArray (matrix); }
00096 
00097   uint64NDArray
00098   uint64_array_value (void) const { return uint64NDArray (matrix); }
00099 
00100   double
00101   double_value (bool = false) const
00102     {
00103       double retval = lo_ieee_nan_value ();
00104 
00105       if (numel () > 0)
00106         {
00107           gripe_implicit_conversion ("Octave:array-as-scalar",
00108                                      type_name (), "real scalar");
00109 
00110           retval = matrix(0).double_value ();
00111         }
00112       else
00113         gripe_invalid_conversion (type_name (), "real scalar");
00114 
00115       return retval;
00116 
00117     }
00118 
00119   float
00120   float_value (bool = false) const
00121     {
00122       float retval = lo_ieee_float_nan_value ();
00123 
00124       if (numel () > 0)
00125         {
00126           gripe_implicit_conversion ("Octave:array-as-scalar",
00127                                      type_name (), "real scalar");
00128 
00129           retval = matrix(0).float_value ();
00130         }
00131       else
00132         gripe_invalid_conversion (type_name (), "real scalar");
00133 
00134       return retval;
00135 
00136     }
00137 
00138   double scalar_value (bool = false) const { return double_value (); }
00139 
00140   float float_scalar_value (bool = false) const { return float_value (); }
00141 
00142   Matrix
00143   matrix_value (bool = false) const
00144     {
00145       Matrix retval;
00146       dim_vector dv = dims ();
00147       if (dv.length () > 2)
00148         error ("invalid conversion of %s to Matrix", type_name().c_str ());
00149       else
00150         {
00151           retval = Matrix (dv(0), dv(1));
00152           double *vec = retval.fortran_vec ();
00153           octave_idx_type nel = matrix.numel ();
00154           for (octave_idx_type i = 0; i < nel; i++)
00155             vec[i] = matrix(i).double_value ();
00156         }
00157       return retval;
00158     }
00159 
00160   FloatMatrix
00161   float_matrix_value (bool = false) const
00162     {
00163       FloatMatrix retval;
00164       dim_vector dv = dims ();
00165       if (dv.length () > 2)
00166         error ("invalid conversion of %s to FloatMatrix", type_name().c_str ());
00167       else
00168         {
00169           retval = FloatMatrix (dv(0), dv(1));
00170           float *vec = retval.fortran_vec ();
00171           octave_idx_type nel = matrix.numel ();
00172           for (octave_idx_type i = 0; i < nel; i++)
00173             vec[i] = matrix(i).float_value ();
00174         }
00175       return retval;
00176     }
00177 
00178   ComplexMatrix
00179   complex_matrix_value (bool = false) const
00180     {
00181       ComplexMatrix retval;
00182       dim_vector dv = dims();
00183       if (dv.length () > 2)
00184         error ("invalid conversion of %s to Matrix", type_name().c_str ());
00185       else
00186         {
00187           retval = ComplexMatrix (dv(0), dv(1));
00188           Complex *vec = retval.fortran_vec ();
00189           octave_idx_type nel = matrix.numel ();
00190           for (octave_idx_type i = 0; i < nel; i++)
00191             vec[i] = Complex (matrix(i).double_value ());
00192         }
00193       return retval;
00194     }
00195 
00196   FloatComplexMatrix
00197   float_complex_matrix_value (bool = false) const
00198     {
00199       FloatComplexMatrix retval;
00200       dim_vector dv = dims();
00201       if (dv.length () > 2)
00202         error ("invalid conversion of %s to FloatMatrix", type_name().c_str ());
00203       else
00204         {
00205           retval = FloatComplexMatrix (dv(0), dv(1));
00206           FloatComplex *vec = retval.fortran_vec ();
00207           octave_idx_type nel = matrix.numel ();
00208           for (octave_idx_type i = 0; i < nel; i++)
00209             vec[i] = FloatComplex (matrix(i).float_value ());
00210         }
00211       return retval;
00212     }
00213 
00214   NDArray
00215   array_value (bool = false) const
00216     {
00217       NDArray retval (matrix.dims ());
00218       double *vec = retval.fortran_vec ();
00219       octave_idx_type nel = matrix.numel ();
00220       for (octave_idx_type i = 0; i < nel; i++)
00221         vec[i] = matrix(i).double_value ();
00222       return retval;
00223     }
00224 
00225   FloatNDArray
00226   float_array_value (bool = false) const
00227     {
00228       FloatNDArray retval (matrix.dims ());
00229       float *vec = retval.fortran_vec ();
00230       octave_idx_type nel = matrix.numel ();
00231       for (octave_idx_type i = 0; i < nel; i++)
00232         vec[i] = matrix(i).float_value ();
00233       return retval;
00234     }
00235 
00236   ComplexNDArray
00237   complex_array_value (bool = false) const
00238     {
00239       ComplexNDArray retval (matrix.dims ());
00240       Complex *vec = retval.fortran_vec ();
00241       octave_idx_type nel = matrix.numel ();
00242       for (octave_idx_type i = 0; i < nel; i++)
00243         vec[i] = Complex (matrix(i).double_value ());
00244       return retval;
00245     }
00246 
00247   FloatComplexNDArray
00248   float_complex_array_value (bool = false) const
00249     {
00250       FloatComplexNDArray retval (matrix.dims ());
00251       FloatComplex *vec = retval.fortran_vec ();
00252       octave_idx_type nel = matrix.numel ();
00253       for (octave_idx_type i = 0; i < nel; i++)
00254         vec[i] = FloatComplex (matrix(i).float_value ());
00255       return retval;
00256     }
00257 
00258   boolNDArray
00259   bool_array_value (bool warn = false) const
00260   {
00261     boolNDArray retval (dims ());
00262 
00263     octave_idx_type nel = numel ();
00264 
00265     if (warn && matrix.any_element_not_one_or_zero ())
00266       gripe_logical_conversion ();
00267 
00268     bool *vec = retval.fortran_vec ();
00269     for (octave_idx_type i = 0; i < nel; i++)
00270       vec[i] = matrix(i).bool_value ();
00271 
00272     return retval;
00273   }
00274 
00275   charNDArray
00276   char_array_value (bool = false) const
00277   {
00278     charNDArray retval (dims ());
00279 
00280     octave_idx_type nel = numel ();
00281 
00282     char *vec = retval.fortran_vec ();
00283     for (octave_idx_type i = 0; i < nel; i++)
00284       vec[i] = matrix(i).char_value ();
00285 
00286     return retval;
00287   }
00288 
00289   // Use matrix_ref here to clear index cache.
00290   void increment (void)
00291    {
00292      matrix_ref() += OCTAVE_INT_T (1);
00293    }
00294 
00295   void decrement (void)
00296    {
00297      matrix_ref() -= OCTAVE_INT_T (1);
00298    }
00299 
00300   void changesign (void)
00301    {
00302      matrix_ref ().changesign ();
00303    }
00304 
00305   idx_vector index_vector (void) const
00306     { return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix)); }
00307 
00308   int write (octave_stream& os, int block_size,
00309              oct_data_conv::data_type output_type, int skip,
00310              oct_mach_info::float_format flt_fmt) const
00311     { return os.write (matrix, block_size, output_type, skip, flt_fmt); }
00312 
00313   // Unsafe.  This function exists to support the MEX interface.
00314   // You should not use it anywhere else.
00315   void *mex_get_data (void) const { return matrix.mex_get_data (); }
00316 
00317   mxArray *as_mxArray (void) const
00318   {
00319     mxArray *retval = new mxArray (OCTAVE_INT_MX_CLASS, dims (), mxREAL);
00320 
00321     OCTAVE_INT_T::val_type *pr = static_cast<OCTAVE_INT_T::val_type *> (retval->get_data ());
00322 
00323     mwSize nel = numel ();
00324 
00325     const OCTAVE_INT_T *p = matrix.data ();
00326 
00327     for (mwIndex i = 0; i < nel; i++)
00328       pr[i] = p[i].value ();
00329 
00330     return retval;
00331   }
00332 
00333   octave_value map (unary_mapper_t umap) const
00334     {
00335       switch (umap)
00336         {
00337         case umap_abs:
00338           return matrix.abs ();
00339         case umap_signum:
00340           return matrix.signum ();
00341         case umap_ceil:
00342         case umap_conj:
00343         case umap_fix:
00344         case umap_floor:
00345         case umap_real:
00346         case umap_round:
00347           return matrix;
00348         case umap_imag:
00349           return intNDArray<OCTAVE_INT_T> (matrix.dims (), OCTAVE_INT_T ());
00350         case umap_isnan:
00351         case umap_isna:
00352         case umap_isinf:
00353           return boolNDArray (matrix.dims (), false);
00354         case umap_finite:
00355           return boolNDArray (matrix.dims (), true);
00356 
00357         default:
00358           {
00359             octave_matrix m (array_value ());
00360             return m.map (umap);
00361           }
00362         }
00363     }
00364 
00365 private:
00366 
00367   DECLARE_OCTAVE_ALLOCATOR
00368 
00369   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
00370 };
00371 
00372 class
00373 OCTINTERP_API
00374 OCTAVE_VALUE_INT_SCALAR_T
00375   : public octave_base_int_scalar<OCTAVE_INT_T>
00376 {
00377 public:
00378 
00379   OCTAVE_VALUE_INT_SCALAR_T (void)
00380     : octave_base_int_scalar<OCTAVE_INT_T> () { }
00381 
00382   OCTAVE_VALUE_INT_SCALAR_T (const OCTAVE_INT_T& nda)
00383     : octave_base_int_scalar<OCTAVE_INT_T> (nda) { }
00384 
00385   ~OCTAVE_VALUE_INT_SCALAR_T (void) { }
00386 
00387   octave_base_value *clone (void) const
00388     { return new OCTAVE_VALUE_INT_SCALAR_T (*this); }
00389 
00390   octave_base_value *empty_clone (void) const
00391     { return new OCTAVE_VALUE_INT_MATRIX_T (); }
00392 
00393   octave_value do_index_op (const octave_value_list& idx,
00394                             bool resize_ok = false)
00395     {
00396       // FIXME -- this doesn't solve the problem of
00397       //
00398       //   a = 1; a([1,1], [1,1], [1,1])
00399       //
00400       // and similar constructions.  Hmm...
00401 
00402       // FIXME -- using this constructor avoids narrowing the
00403       // 1x1 matrix back to a scalar value.  Need a better solution
00404       // to this problem.
00405 
00406       octave_value tmp
00407         (new OCTAVE_VALUE_INT_MATRIX_T
00408          (OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION ()));
00409 
00410       return tmp.do_index_op (idx, resize_ok);
00411     }
00412 
00413   bool OCTAVE_TYPE_PREDICATE_FUNCTION (void) const { return true; }
00414 
00415   bool is_integer_type (void) const { return true; }
00416 
00417   builtin_type_t builtin_type (void) const { return OCTAVE_INT_BTYP; }
00418 
00419 public:
00420 
00421   octave_int8
00422   int8_scalar_value (void) const { return octave_int8 (scalar); }
00423 
00424   octave_int16
00425   int16_scalar_value (void) const { return octave_int16 (scalar); }
00426 
00427   octave_int32
00428   int32_scalar_value (void) const { return octave_int32 (scalar); }
00429 
00430   octave_int64
00431   int64_scalar_value (void) const { return octave_int64 (scalar); }
00432 
00433   octave_uint8
00434   uint8_scalar_value (void) const { return octave_uint8 (scalar); }
00435 
00436   octave_uint16
00437   uint16_scalar_value (void) const { return octave_uint16 (scalar); }
00438 
00439   octave_uint32
00440   uint32_scalar_value (void) const { return octave_uint32 (scalar); }
00441 
00442   octave_uint64
00443   uint64_scalar_value (void) const { return octave_uint64 (scalar); }
00444 
00445   int8NDArray
00446   int8_array_value (void) const
00447     { return int8NDArray (dim_vector (1, 1), int8_scalar_value ()); }
00448 
00449   int16NDArray
00450   int16_array_value (void) const
00451     { return int16NDArray (dim_vector (1, 1), int16_scalar_value ()); }
00452 
00453   int32NDArray
00454   int32_array_value (void) const
00455     { return int32NDArray (dim_vector (1, 1), int32_scalar_value ()); }
00456 
00457   int64NDArray
00458   int64_array_value (void) const
00459     { return int64NDArray (dim_vector (1, 1), int64_scalar_value ()); }
00460 
00461   uint8NDArray
00462   uint8_array_value (void) const
00463     { return uint8NDArray (dim_vector (1, 1), uint8_scalar_value ()); }
00464 
00465   uint16NDArray
00466   uint16_array_value (void) const
00467     { return uint16NDArray (dim_vector (1, 1), uint16_scalar_value ()); }
00468 
00469   uint32NDArray
00470   uint32_array_value (void) const
00471     { return uint32NDArray (dim_vector (1, 1), uint32_scalar_value ()); }
00472 
00473   uint64NDArray
00474   uint64_array_value (void) const
00475     { return uint64NDArray (dim_vector (1, 1), uint64_scalar_value ()); }
00476 
00477   octave_value resize (const dim_vector& dv, bool fill = false) const
00478     {
00479       if (fill)
00480         {
00481           intNDArray<OCTAVE_INT_T> retval (dv, 0);
00482           if (dv.numel())
00483             retval(0) = scalar;
00484           return retval;
00485         }
00486       else
00487         {
00488           intNDArray<OCTAVE_INT_T> retval (dv);
00489           if (dv.numel())
00490             retval(0) = scalar;
00491           return retval;
00492         }
00493     }
00494 
00495   double double_value (bool = false) const { return scalar.double_value (); }
00496 
00497   float float_value (bool = false) const { return scalar.float_value (); }
00498 
00499   double scalar_value (bool = false) const { return scalar.double_value (); }
00500 
00501   float float_scalar_value (bool = false) const { return scalar.float_value (); }
00502 
00503   Matrix
00504   matrix_value (bool = false) const
00505     {
00506       Matrix retval (1, 1);
00507       retval(0,0) = scalar.double_value ();
00508       return retval;
00509     }
00510 
00511   FloatMatrix
00512   float_matrix_value (bool = false) const
00513     {
00514       FloatMatrix retval (1, 1);
00515       retval(0,0) = scalar.float_value ();
00516       return retval;
00517     }
00518 
00519   ComplexMatrix
00520   complex_matrix_value (bool = false) const
00521     {
00522       ComplexMatrix retval (1, 1);
00523       retval(0,0) = Complex (scalar.double_value ());
00524       return retval;
00525     }
00526 
00527   FloatComplexMatrix
00528   float_complex_matrix_value (bool = false) const
00529     {
00530       FloatComplexMatrix retval (1, 1);
00531       retval(0,0) = FloatComplex (scalar.float_value ());
00532       return retval;
00533     }
00534 
00535   NDArray
00536   array_value (bool = false) const
00537     {
00538       NDArray retval (dim_vector (1, 1));
00539       retval(0) = scalar.double_value ();
00540       return retval;
00541     }
00542 
00543   FloatNDArray
00544   float_array_value (bool = false) const
00545     {
00546       FloatNDArray retval (dim_vector (1, 1));
00547       retval(0) = scalar.float_value ();
00548       return retval;
00549     }
00550 
00551   ComplexNDArray
00552   complex_array_value (bool = false) const
00553     {
00554       ComplexNDArray retval (dim_vector (1, 1));
00555       retval(0) = FloatComplex (scalar.double_value ());
00556       return retval;
00557     }
00558 
00559   FloatComplexNDArray
00560   float_complex_array_value (bool = false) const
00561     {
00562       FloatComplexNDArray retval (dim_vector (1, 1));
00563       retval(0) = FloatComplex (scalar.float_value ());
00564       return retval;
00565     }
00566 
00567   bool bool_value (bool warn = false) const
00568   {
00569     if (warn && scalar != 0.0 && scalar != 1.0)
00570       gripe_logical_conversion ();
00571 
00572     return scalar.bool_value ();
00573   }
00574 
00575   boolNDArray
00576   bool_array_value (bool warn = false) const
00577   {
00578     boolNDArray retval (dim_vector (1, 1));
00579 
00580     if (warn && scalar != 0.0 && scalar != 1.0)
00581       gripe_logical_conversion ();
00582 
00583     retval(0) = scalar.bool_value ();
00584 
00585     return retval;
00586   }
00587 
00588   charNDArray
00589   char_array_value (bool = false) const
00590   {
00591     charNDArray retval (dim_vector (1, 1));
00592     retval(0) = scalar.char_value ();
00593     return retval;
00594   }
00595 
00596   void increment (void)
00597    {
00598      scalar += OCTAVE_INT_T (1);
00599    }
00600 
00601   void decrement (void)
00602    {
00603      scalar -= OCTAVE_INT_T (1);
00604    }
00605 
00606   idx_vector index_vector (void) const { return idx_vector (scalar); }
00607 
00608   int write (octave_stream& os, int block_size,
00609              oct_data_conv::data_type output_type, octave_idx_type skip,
00610              oct_mach_info::float_format flt_fmt) const
00611     {
00612       return os.write (OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION (),
00613                        block_size, output_type, skip, flt_fmt);
00614     }
00615 
00616   // Unsafe.  This function exists to support the MEX interface.
00617   // You should not use it anywhere else.
00618   void *mex_get_data (void) const { return scalar.mex_get_data (); }
00619 
00620   mxArray *as_mxArray (void) const
00621   {
00622     mxArray *retval = new mxArray (OCTAVE_INT_MX_CLASS, 1, 1, mxREAL);
00623 
00624     OCTAVE_INT_T::val_type *pr = static_cast<OCTAVE_INT_T::val_type *> (retval->get_data ());
00625 
00626     pr[0] = scalar.value ();
00627 
00628     return retval;
00629   }
00630 
00631   octave_value map (unary_mapper_t umap) const
00632     {
00633       switch (umap)
00634         {
00635         case umap_abs:
00636           return scalar.abs ();
00637         case umap_signum:
00638           return scalar.signum ();
00639         case umap_ceil:
00640         case umap_conj:
00641         case umap_fix:
00642         case umap_floor:
00643         case umap_real:
00644         case umap_round:
00645           return scalar;
00646         case umap_imag:
00647           return OCTAVE_INT_T ();
00648         case umap_isnan:
00649         case umap_isna:
00650         case umap_isinf:
00651           return false;
00652         case umap_finite:
00653           return true;
00654 
00655         default:
00656           {
00657             octave_scalar m (scalar_value ());
00658             return m.map (umap);
00659           }
00660         }
00661     }
00662 
00663 private:
00664 
00665   DECLARE_OCTAVE_ALLOCATOR
00666 
00667   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
00668 };
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines