ov-float.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include <iostream>
00028 
00029 #include "data-conv.h"
00030 #include "mach-info.h"
00031 #include "lo-specfun.h"
00032 #include "lo-mappers.h"
00033 
00034 #include "defun.h"
00035 #include "gripes.h"
00036 #include "oct-obj.h"
00037 #include "oct-stream.h"
00038 #include "ov-scalar.h"
00039 #include "ov-float.h"
00040 #include "ov-base.h"
00041 #include "ov-base-scalar.h"
00042 #include "ov-base-scalar.cc"
00043 #include "ov-flt-re-mat.h"
00044 #include "ov-typeinfo.h"
00045 #include "pr-output.h"
00046 #include "xdiv.h"
00047 #include "xpow.h"
00048 #include "ops.h"
00049 
00050 #include "ls-oct-ascii.h"
00051 #include "ls-hdf5.h"
00052 
00053 template class octave_base_scalar<float>;
00054 
00055 DEFINE_OCTAVE_ALLOCATOR (octave_float_scalar);
00056 
00057 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_scalar, "float scalar", "single");
00058 
00059 octave_value
00060 octave_float_scalar::do_index_op (const octave_value_list& idx, bool resize_ok)
00061 {
00062   // FIXME -- this doesn't solve the problem of
00063   //
00064   //   a = 1; a([1,1], [1,1], [1,1])
00065   //
00066   // and similar constructions.  Hmm...
00067 
00068   // FIXME -- using this constructor avoids narrowing the
00069   // 1x1 matrix back to a scalar value.  Need a better solution
00070   // to this problem.
00071 
00072   octave_value tmp (new octave_float_matrix (float_matrix_value ()));
00073 
00074   return tmp.do_index_op (idx, resize_ok);
00075 }
00076 
00077 octave_value
00078 octave_float_scalar::resize (const dim_vector& dv, bool fill) const
00079 {
00080   if (fill)
00081     {
00082       FloatNDArray retval (dv, NDArray::resize_fill_value());
00083 
00084       if (dv.numel ())
00085         retval(0) = scalar;
00086 
00087       return retval;
00088     }
00089   else
00090     {
00091       FloatNDArray retval (dv);
00092 
00093       if (dv.numel ())
00094         retval(0) = scalar;
00095 
00096       return retval;
00097     }
00098 }
00099 
00100 octave_value
00101 octave_float_scalar::convert_to_str_internal (bool, bool, char type) const
00102 {
00103   octave_value retval;
00104 
00105   if (xisnan (scalar))
00106     gripe_nan_to_character_conversion ();
00107   else
00108     {
00109       int ival = NINT (scalar);
00110 
00111       if (ival < 0 || ival > UCHAR_MAX)
00112         {
00113           // FIXME -- is there something better we could do?
00114 
00115           ival = 0;
00116 
00117           ::warning ("range error for conversion to character value");
00118         }
00119 
00120       retval = octave_value (std::string (1, static_cast<char> (ival)), type);
00121     }
00122 
00123   return retval;
00124 }
00125 
00126 bool
00127 octave_float_scalar::save_ascii (std::ostream& os)
00128 {
00129   float d = float_value ();
00130 
00131   octave_write_float (os, d);
00132 
00133   os << "\n";
00134 
00135   return true;
00136 }
00137 
00138 bool
00139 octave_float_scalar::load_ascii (std::istream& is)
00140 {
00141   scalar = octave_read_value<float> (is);
00142   if (!is)
00143     {
00144       error ("load: failed to load scalar constant");
00145       return false;
00146     }
00147 
00148   return true;
00149 }
00150 
00151 bool
00152 octave_float_scalar::save_binary (std::ostream& os, bool& /* save_as_floats */)
00153 {
00154   char tmp = LS_FLOAT;
00155   os.write (reinterpret_cast<char *> (&tmp), 1);
00156   float dtmp = float_value ();
00157   os.write (reinterpret_cast<char *> (&dtmp), 4);
00158 
00159   return true;
00160 }
00161 
00162 bool
00163 octave_float_scalar::load_binary (std::istream& is, bool swap,
00164                             oct_mach_info::float_format fmt)
00165 {
00166   char tmp;
00167   if (! is.read (reinterpret_cast<char *> (&tmp), 1))
00168     return false;
00169 
00170   float dtmp;
00171   read_floats (is, &dtmp, static_cast<save_type> (tmp), 1, swap, fmt);
00172   if (error_state || ! is)
00173     return false;
00174 
00175   scalar = dtmp;
00176   return true;
00177 }
00178 
00179 #if defined (HAVE_HDF5)
00180 
00181 bool
00182 octave_float_scalar::save_hdf5 (hid_t loc_id, const char *name,
00183                           bool /* save_as_floats */)
00184 {
00185   hsize_t dimens[3];
00186   hid_t space_hid = -1, data_hid = -1;
00187   bool retval = true;
00188 
00189   space_hid = H5Screate_simple (0, dimens, 0);
00190   if (space_hid < 0) return false;
00191 #if HAVE_HDF5_18
00192   data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_FLOAT, space_hid,
00193                         H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00194 #else
00195   data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_FLOAT, space_hid,
00196                         H5P_DEFAULT);
00197 #endif
00198   if (data_hid < 0)
00199     {
00200       H5Sclose (space_hid);
00201       return false;
00202     }
00203 
00204   float tmp = float_value ();
00205   retval = H5Dwrite (data_hid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
00206                      H5P_DEFAULT, &tmp) >= 0;
00207 
00208   H5Dclose (data_hid);
00209   H5Sclose (space_hid);
00210 
00211   return retval;
00212 }
00213 
00214 bool
00215 octave_float_scalar::load_hdf5 (hid_t loc_id, const char *name)
00216 {
00217 #if HAVE_HDF5_18
00218   hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
00219 #else
00220   hid_t data_hid = H5Dopen (loc_id, name);
00221 #endif
00222   hid_t space_id = H5Dget_space (data_hid);
00223 
00224   hsize_t rank = H5Sget_simple_extent_ndims (space_id);
00225 
00226   if (rank != 0)
00227     {
00228       H5Dclose (data_hid);
00229       return false;
00230     }
00231 
00232   float dtmp;
00233   if (H5Dread (data_hid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
00234                H5P_DEFAULT, &dtmp) < 0)
00235     {
00236       H5Dclose (data_hid);
00237       return false;
00238     }
00239 
00240   scalar = dtmp;
00241 
00242   H5Dclose (data_hid);
00243 
00244   return true;
00245 }
00246 
00247 #endif
00248 
00249 mxArray *
00250 octave_float_scalar::as_mxArray (void) const
00251 {
00252   mxArray *retval = new mxArray (mxSINGLE_CLASS, 1, 1, mxREAL);
00253 
00254   float *pr = static_cast<float *> (retval->get_data ());
00255 
00256   pr[0] = scalar;
00257 
00258   return retval;
00259 }
00260 
00261 octave_value
00262 octave_float_scalar::map (unary_mapper_t umap) const
00263 {
00264   switch (umap)
00265     {
00266     case umap_imag:
00267       return 0.0f;
00268 
00269     case umap_real:
00270     case umap_conj:
00271       return scalar;
00272 
00273 #define SCALAR_MAPPER(UMAP, FCN) \
00274     case umap_ ## UMAP: \
00275       return octave_value (FCN (scalar))
00276 
00277       SCALAR_MAPPER (abs, ::fabsf);
00278       SCALAR_MAPPER (acos, rc_acos);
00279       SCALAR_MAPPER (acosh, rc_acosh);
00280       SCALAR_MAPPER (angle, ::arg);
00281       SCALAR_MAPPER (arg, ::arg);
00282       SCALAR_MAPPER (asin, rc_asin);
00283       SCALAR_MAPPER (asinh, ::asinhf);
00284       SCALAR_MAPPER (atan, ::atanf);
00285       SCALAR_MAPPER (atanh, rc_atanh);
00286       SCALAR_MAPPER (erf, ::erff);
00287       SCALAR_MAPPER (erfinv, ::erfinv);
00288       SCALAR_MAPPER (erfc, ::erfcf);
00289       SCALAR_MAPPER (erfcx, ::erfcx);
00290       SCALAR_MAPPER (gamma, xgamma);
00291       SCALAR_MAPPER (lgamma, rc_lgamma);
00292       SCALAR_MAPPER (cbrt, ::cbrtf);
00293       SCALAR_MAPPER (ceil, ::ceilf);
00294       SCALAR_MAPPER (cos, ::cosf);
00295       SCALAR_MAPPER (cosh, ::coshf);
00296       SCALAR_MAPPER (exp, ::expf);
00297       SCALAR_MAPPER (expm1, ::expm1f);
00298       SCALAR_MAPPER (fix, ::fix);
00299       SCALAR_MAPPER (floor, ::floorf);
00300       SCALAR_MAPPER (log, rc_log);
00301       SCALAR_MAPPER (log2, rc_log2);
00302       SCALAR_MAPPER (log10, rc_log10);
00303       SCALAR_MAPPER (log1p, rc_log1p);
00304       SCALAR_MAPPER (round, xround);
00305       SCALAR_MAPPER (roundb, xroundb);
00306       SCALAR_MAPPER (signum, ::signum);
00307       SCALAR_MAPPER (sin, ::sinf);
00308       SCALAR_MAPPER (sinh, ::sinhf);
00309       SCALAR_MAPPER (sqrt, rc_sqrt);
00310       SCALAR_MAPPER (tan, ::tanf);
00311       SCALAR_MAPPER (tanh, ::tanhf);
00312       SCALAR_MAPPER (finite, xfinite);
00313       SCALAR_MAPPER (isinf, xisinf);
00314       SCALAR_MAPPER (isna, octave_is_NA);
00315       SCALAR_MAPPER (isnan, xisnan);
00316 
00317     default:
00318       return octave_base_value::map (umap);
00319     }
00320 }
00321 
00322 bool
00323 octave_float_scalar::fast_elem_insert_self (void *where, builtin_type_t btyp) const
00324 {
00325 
00326   // Support inline real->complex conversion.
00327   if (btyp == btyp_float)
00328     {
00329       *(reinterpret_cast<float *>(where)) = scalar;
00330       return true;
00331     }
00332   else if (btyp == btyp_float_complex)
00333     {
00334       *(reinterpret_cast<FloatComplex *>(where)) = scalar;
00335       return true;
00336     }
00337   else
00338     return false;
00339 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines