00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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-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<double>;
00054
00055 DEFINE_OCTAVE_ALLOCATOR (octave_scalar);
00056
00057 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_scalar, "scalar", "double");
00058
00059 static octave_base_value *
00060 default_numeric_demotion_function (const octave_base_value& a)
00061 {
00062 CAST_CONV_ARG (const octave_scalar&);
00063
00064 return new octave_float_scalar (v.float_value ());
00065 }
00066
00067 octave_base_value::type_conv_info
00068 octave_scalar::numeric_demotion_function (void) const
00069 {
00070 return octave_base_value::type_conv_info(default_numeric_demotion_function,
00071 octave_float_scalar::static_type_id ());
00072 }
00073
00074 octave_value
00075 octave_scalar::do_index_op (const octave_value_list& idx, bool resize_ok)
00076 {
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 octave_value tmp (new octave_matrix (matrix_value ()));
00088
00089 return tmp.do_index_op (idx, resize_ok);
00090 }
00091
00092 octave_value
00093 octave_scalar::resize (const dim_vector& dv, bool fill) const
00094 {
00095 if (fill)
00096 {
00097 NDArray retval (dv, NDArray::resize_fill_value());
00098
00099 if (dv.numel ())
00100 retval(0) = scalar;
00101
00102 return retval;
00103 }
00104 else
00105 {
00106 NDArray retval (dv);
00107
00108 if (dv.numel ())
00109 retval(0) = scalar;
00110
00111 return retval;
00112 }
00113 }
00114
00115 octave_value
00116 octave_scalar::convert_to_str_internal (bool, bool, char type) const
00117 {
00118 octave_value retval;
00119
00120 if (xisnan (scalar))
00121 gripe_nan_to_character_conversion ();
00122 else
00123 {
00124 int ival = NINT (scalar);
00125
00126 if (ival < 0 || ival > UCHAR_MAX)
00127 {
00128
00129
00130 ival = 0;
00131
00132 ::warning ("range error for conversion to character value");
00133 }
00134
00135 retval = octave_value (std::string (1, static_cast<char> (ival)), type);
00136 }
00137
00138 return retval;
00139 }
00140
00141 bool
00142 octave_scalar::save_ascii (std::ostream& os)
00143 {
00144 double d = double_value ();
00145
00146 octave_write_double (os, d);
00147
00148 os << "\n";
00149
00150 return true;
00151 }
00152
00153 bool
00154 octave_scalar::load_ascii (std::istream& is)
00155 {
00156 scalar = octave_read_value<double> (is);
00157 if (!is)
00158 {
00159 error ("load: failed to load scalar constant");
00160 return false;
00161 }
00162
00163 return true;
00164 }
00165
00166 bool
00167 octave_scalar::save_binary (std::ostream& os, bool& )
00168 {
00169 char tmp = LS_DOUBLE;
00170 os.write (reinterpret_cast<char *> (&tmp), 1);
00171 double dtmp = double_value ();
00172 os.write (reinterpret_cast<char *> (&dtmp), 8);
00173
00174 return true;
00175 }
00176
00177 bool
00178 octave_scalar::load_binary (std::istream& is, bool swap,
00179 oct_mach_info::float_format fmt)
00180 {
00181 char tmp;
00182 if (! is.read (reinterpret_cast<char *> (&tmp), 1))
00183 return false;
00184
00185 double dtmp;
00186 read_doubles (is, &dtmp, static_cast<save_type> (tmp), 1, swap, fmt);
00187 if (error_state || ! is)
00188 return false;
00189
00190 scalar = dtmp;
00191 return true;
00192 }
00193
00194 #if defined (HAVE_HDF5)
00195
00196 bool
00197 octave_scalar::save_hdf5 (hid_t loc_id, const char *name,
00198 bool )
00199 {
00200 hsize_t dimens[3];
00201 hid_t space_hid = -1, data_hid = -1;
00202 bool retval = true;
00203
00204 space_hid = H5Screate_simple (0, dimens, 0);
00205 if (space_hid < 0) return false;
00206
00207 #if HAVE_HDF5_18
00208 data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_DOUBLE, space_hid,
00209 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
00210 #else
00211 data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_DOUBLE, space_hid,
00212 H5P_DEFAULT);
00213 #endif
00214 if (data_hid < 0)
00215 {
00216 H5Sclose (space_hid);
00217 return false;
00218 }
00219
00220 double tmp = double_value ();
00221 retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
00222 H5P_DEFAULT, &tmp) >= 0;
00223
00224 H5Dclose (data_hid);
00225 H5Sclose (space_hid);
00226
00227 return retval;
00228 }
00229
00230 bool
00231 octave_scalar::load_hdf5 (hid_t loc_id, const char *name)
00232 {
00233 #if HAVE_HDF5_18
00234 hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
00235 #else
00236 hid_t data_hid = H5Dopen (loc_id, name);
00237 #endif
00238 hid_t space_id = H5Dget_space (data_hid);
00239
00240 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
00241
00242 if (rank != 0)
00243 {
00244 H5Dclose (data_hid);
00245 return false;
00246 }
00247
00248 double dtmp;
00249 if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
00250 H5P_DEFAULT, &dtmp) < 0)
00251 {
00252 H5Dclose (data_hid);
00253 return false;
00254 }
00255
00256 scalar = dtmp;
00257
00258 H5Dclose (data_hid);
00259
00260 return true;
00261 }
00262
00263 #endif
00264
00265 mxArray *
00266 octave_scalar::as_mxArray (void) const
00267 {
00268 mxArray *retval = new mxArray (mxDOUBLE_CLASS, 1, 1, mxREAL);
00269
00270 double *pr = static_cast<double *> (retval->get_data ());
00271
00272 pr[0] = scalar;
00273
00274 return retval;
00275 }
00276
00277 octave_value
00278 octave_scalar::map (unary_mapper_t umap) const
00279 {
00280 switch (umap)
00281 {
00282 case umap_imag:
00283 return 0.0;
00284
00285 case umap_real:
00286 case umap_conj:
00287 return scalar;
00288
00289 #define SCALAR_MAPPER(UMAP, FCN) \
00290 case umap_ ## UMAP: \
00291 return octave_value (FCN (scalar))
00292
00293 SCALAR_MAPPER (abs, ::fabs);
00294 SCALAR_MAPPER (acos, rc_acos);
00295 SCALAR_MAPPER (acosh, rc_acosh);
00296 SCALAR_MAPPER (angle, ::arg);
00297 SCALAR_MAPPER (arg, ::arg);
00298 SCALAR_MAPPER (asin, rc_asin);
00299 SCALAR_MAPPER (asinh, ::asinh);
00300 SCALAR_MAPPER (atan, ::atan);
00301 SCALAR_MAPPER (atanh, rc_atanh);
00302 SCALAR_MAPPER (erf, ::erf);
00303 SCALAR_MAPPER (erfinv, ::erfinv);
00304 SCALAR_MAPPER (erfc, ::erfc);
00305 SCALAR_MAPPER (erfcx, ::erfcx);
00306 SCALAR_MAPPER (gamma, xgamma);
00307 SCALAR_MAPPER (lgamma, rc_lgamma);
00308 SCALAR_MAPPER (cbrt, ::cbrt);
00309 SCALAR_MAPPER (ceil, ::ceil);
00310 SCALAR_MAPPER (cos, ::cos);
00311 SCALAR_MAPPER (cosh, ::cosh);
00312 SCALAR_MAPPER (exp, ::exp);
00313 SCALAR_MAPPER (expm1, ::expm1);
00314 SCALAR_MAPPER (fix, ::fix);
00315 SCALAR_MAPPER (floor, gnulib::floor);
00316 SCALAR_MAPPER (log, rc_log);
00317 SCALAR_MAPPER (log2, rc_log2);
00318 SCALAR_MAPPER (log10, rc_log10);
00319 SCALAR_MAPPER (log1p, rc_log1p);
00320 SCALAR_MAPPER (round, xround);
00321 SCALAR_MAPPER (roundb, xroundb);
00322 SCALAR_MAPPER (signum, ::signum);
00323 SCALAR_MAPPER (sin, ::sin);
00324 SCALAR_MAPPER (sinh, ::sinh);
00325 SCALAR_MAPPER (sqrt, rc_sqrt);
00326 SCALAR_MAPPER (tan, ::tan);
00327 SCALAR_MAPPER (tanh, ::tanh);
00328 SCALAR_MAPPER (finite, xfinite);
00329 SCALAR_MAPPER (isinf, xisinf);
00330 SCALAR_MAPPER (isna, octave_is_NA);
00331 SCALAR_MAPPER (isnan, xisnan);
00332
00333 default:
00334 if (umap >= umap_xisalnum && umap <= umap_xtoupper)
00335 {
00336 octave_value str_conv = convert_to_str (true, true);
00337 return error_state ? octave_value () : str_conv.map (umap);
00338 }
00339 else
00340 return octave_base_value::map (umap);
00341 }
00342 }
00343
00344 bool
00345 octave_scalar::fast_elem_insert_self (void *where, builtin_type_t btyp) const
00346 {
00347
00348
00349 if (btyp == btyp_double)
00350 {
00351 *(reinterpret_cast<double *>(where)) = scalar;
00352 return true;
00353 }
00354 else if (btyp == btyp_complex)
00355 {
00356 *(reinterpret_cast<Complex *>(where)) = scalar;
00357 return true;
00358 }
00359 else
00360 return false;
00361 }