GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ov-float.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <iostream>
28 
29 #include "data-conv.h"
30 #include "mach-info.h"
31 #include "lo-specfun.h"
32 #include "lo-mappers.h"
33 
34 #include "defun.h"
35 #include "gripes.h"
36 #include "mxarray.h"
37 #include "oct-obj.h"
38 #include "oct-stream.h"
39 #include "ov-scalar.h"
40 #include "ov-float.h"
41 #include "ov-base.h"
42 #include "ov-base-scalar.h"
43 #include "ov-base-scalar.cc"
44 #include "ov-flt-re-mat.h"
45 #include "ov-typeinfo.h"
46 #include "pr-output.h"
47 #include "xdiv.h"
48 #include "xpow.h"
49 #include "ops.h"
50 
51 #include "ls-oct-ascii.h"
52 #include "ls-hdf5.h"
53 
54 template class octave_base_scalar<float>;
55 
57 
59  "single");
60 
63 {
64  // FIXME: this doesn't solve the problem of
65  //
66  // a = 1; a([1,1], [1,1], [1,1])
67  //
68  // and similar constructions. Hmm...
69 
70  // FIXME: using this constructor avoids narrowing the
71  // 1x1 matrix back to a scalar value. Need a better solution
72  // to this problem.
73 
75 
76  return tmp.do_index_op (idx, resize_ok);
77 }
78 
80 octave_float_scalar::resize (const dim_vector& dv, bool fill) const
81 {
82  if (fill)
83  {
84  FloatNDArray retval (dv, 0);
85 
86  if (dv.numel ())
87  retval(0) = scalar;
88 
89  return retval;
90  }
91  else
92  {
93  FloatNDArray retval (dv);
94 
95  if (dv.numel ())
96  retval(0) = scalar;
97 
98  return retval;
99  }
100 }
101 
104 {
105  return FloatDiagMatrix (Array<float> (dim_vector (1, 1), scalar), m, n);
106 }
107 
110 {
111  octave_value retval;
112 
113  if (xisnan (scalar))
115  else
116  {
117  int ival = NINT (scalar);
118 
119  if (ival < 0 || ival > std::numeric_limits<unsigned char>::max ())
120  {
121  // FIXME: is there something better we could do?
122 
123  ival = 0;
124 
125  ::warning ("range error for conversion to character value");
126  }
127 
128  retval = octave_value (std::string (1, static_cast<char> (ival)), type);
129  }
130 
131  return retval;
132 }
133 
134 bool
136 {
137  float d = float_value ();
138 
139  octave_write_float (os, d);
140 
141  os << "\n";
142 
143  return true;
144 }
145 
146 bool
148 {
149  scalar = octave_read_value<float> (is);
150  if (!is)
151  {
152  error ("load: failed to load scalar constant");
153  return false;
154  }
155 
156  return true;
157 }
158 
159 bool
160 octave_float_scalar::save_binary (std::ostream& os, bool& /* save_as_floats */)
161 {
162  char tmp = LS_FLOAT;
163  os.write (reinterpret_cast<char *> (&tmp), 1);
164  float dtmp = float_value ();
165  os.write (reinterpret_cast<char *> (&dtmp), 4);
166 
167  return true;
168 }
169 
170 bool
171 octave_float_scalar::load_binary (std::istream& is, bool swap,
173 {
174  char tmp;
175  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
176  return false;
177 
178  float dtmp;
179  read_floats (is, &dtmp, static_cast<save_type> (tmp), 1, swap, fmt);
180  if (error_state || ! is)
181  return false;
182 
183  scalar = dtmp;
184  return true;
185 }
186 
187 #if defined (HAVE_HDF5)
188 
189 bool
190 octave_float_scalar::save_hdf5 (hid_t loc_id, const char *name,
191  bool /* save_as_floats */)
192 {
193  hsize_t dimens[3];
194  hid_t space_hid = -1, data_hid = -1;
195  bool retval = true;
196 
197  space_hid = H5Screate_simple (0, dimens, 0);
198  if (space_hid < 0) return false;
199 #if HAVE_HDF5_18
200  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_FLOAT, space_hid,
201  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
202 #else
203  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_FLOAT, space_hid,
204  H5P_DEFAULT);
205 #endif
206  if (data_hid < 0)
207  {
208  H5Sclose (space_hid);
209  return false;
210  }
211 
212  float tmp = float_value ();
213  retval = H5Dwrite (data_hid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
214  H5P_DEFAULT, &tmp) >= 0;
215 
216  H5Dclose (data_hid);
217  H5Sclose (space_hid);
218 
219  return retval;
220 }
221 
222 bool
223 octave_float_scalar::load_hdf5 (hid_t loc_id, const char *name)
224 {
225 #if HAVE_HDF5_18
226  hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
227 #else
228  hid_t data_hid = H5Dopen (loc_id, name);
229 #endif
230  hid_t space_id = H5Dget_space (data_hid);
231 
232  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
233 
234  if (rank != 0)
235  {
236  H5Dclose (data_hid);
237  return false;
238  }
239 
240  float dtmp;
241  if (H5Dread (data_hid, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
242  H5P_DEFAULT, &dtmp) < 0)
243  {
244  H5Dclose (data_hid);
245  return false;
246  }
247 
248  scalar = dtmp;
249 
250  H5Dclose (data_hid);
251 
252  return true;
253 }
254 
255 #endif
256 
257 mxArray *
259 {
260  mxArray *retval = new mxArray (mxSINGLE_CLASS, 1, 1, mxREAL);
261 
262  float *pr = static_cast<float *> (retval->get_data ());
263 
264  pr[0] = scalar;
265 
266  return retval;
267 }
268 
271 {
272  switch (umap)
273  {
274  case umap_imag:
275  return 0.0f;
276 
277  case umap_real:
278  case umap_conj:
279  return scalar;
280 
281 #define SCALAR_MAPPER(UMAP, FCN) \
282  case umap_ ## UMAP: \
283  return octave_value (FCN (scalar))
284 
285  SCALAR_MAPPER (abs, ::fabsf);
288  SCALAR_MAPPER (angle, ::arg);
289  SCALAR_MAPPER (arg, ::arg);
292  SCALAR_MAPPER (atan, ::atanf);
294  SCALAR_MAPPER (erf, ::erff);
297  SCALAR_MAPPER (erfc, ::erfcf);
299  SCALAR_MAPPER (erfi, ::erfi);
302  SCALAR_MAPPER (lgamma, rc_lgamma);
303  SCALAR_MAPPER (cbrt, ::cbrtf);
304  SCALAR_MAPPER (ceil, ::ceilf);
305  SCALAR_MAPPER (cos, ::cosf);
306  SCALAR_MAPPER (cosh, ::coshf);
307  SCALAR_MAPPER (exp, ::expf);
309  SCALAR_MAPPER (fix, ::fix);
310  SCALAR_MAPPER (floor, gnulib::floorf);
311  SCALAR_MAPPER (log, rc_log);
312  SCALAR_MAPPER (log2, rc_log2);
313  SCALAR_MAPPER (log10, rc_log10);
315  SCALAR_MAPPER (round, xround);
316  SCALAR_MAPPER (roundb, xroundb);
318  SCALAR_MAPPER (sin, ::sinf);
319  SCALAR_MAPPER (sinh, ::sinhf);
320  SCALAR_MAPPER (sqrt, rc_sqrt);
321  SCALAR_MAPPER (tan, ::tanf);
322  SCALAR_MAPPER (tanh, ::tanhf);
323  SCALAR_MAPPER (finite, xfinite);
324  SCALAR_MAPPER (isinf, xisinf);
325  SCALAR_MAPPER (isna, octave_is_NA);
326  SCALAR_MAPPER (isnan, xisnan);
328 
329  default:
330  return octave_base_value::map (umap);
331  }
332 }
333 
334 bool
336  builtin_type_t btyp) const
337 {
338 
339  // Support inline real->complex conversion.
340  if (btyp == btyp_float)
341  {
342  *(reinterpret_cast<float *>(where)) = scalar;
343  return true;
344  }
345  else if (btyp == btyp_float_complex)
346  {
347  *(reinterpret_cast<FloatComplex *>(where)) = scalar;
348  return true;
349  }
350  else
351  return false;
352 }