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-flt-complex.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 "lo-ieee.h"
30 #include "lo-specfun.h"
31 #include "lo-mappers.h"
32 
33 #include "mxarray.h"
34 #include "oct-obj.h"
35 #include "oct-stream.h"
36 #include "ops.h"
37 #include "ov-complex.h"
38 #include "ov-base.h"
39 #include "ov-base-scalar.h"
40 #include "ov-base-scalar.cc"
41 #include "ov-flt-cx-mat.h"
42 #include "ov-float.h"
43 #include "ov-flt-complex.h"
44 #include "gripes.h"
45 #include "pr-output.h"
46 #include "ops.h"
47 
48 #include "ls-oct-ascii.h"
49 #include "ls-hdf5.h"
50 
52 
54 
56  "float complex scalar", "single");
57 
60 {
61  octave_base_value *retval = 0;
62 
63  float im = std::imag (scalar);
64 
65  if (im == 0.0)
66  retval = new octave_float_scalar (std::real (scalar));
67 
68  return retval;
69 }
70 
73 {
74  // FIXME: this doesn't solve the problem of
75  //
76  // a = i; a([1,1], [1,1], [1,1])
77  //
78  // and similar constructions. Hmm...
79 
80  // FIXME: using this constructor avoids narrowing the
81  // 1x1 matrix back to a scalar value. Need a better solution
82  // to this problem.
83 
85 
86  return tmp.do_index_op (idx, resize_ok);
87 }
88 
89 double
90 octave_float_complex::double_value (bool force_conversion) const
91 {
92  double retval = lo_ieee_nan_value ();
93 
94  if (! force_conversion)
95  gripe_implicit_conversion ("Octave:imag-to-real",
96  "complex scalar", "real scalar");
97 
98  retval = std::real (scalar);
99 
100  return retval;
101 }
102 
103 float
104 octave_float_complex::float_value (bool force_conversion) const
105 {
106  float retval = lo_ieee_float_nan_value ();
107 
108  if (! force_conversion)
109  gripe_implicit_conversion ("Octave:imag-to-real",
110  "complex scalar", "real scalar");
111 
112  retval = std::real (scalar);
113 
114  return retval;
115 }
116 
117 Matrix
118 octave_float_complex::matrix_value (bool force_conversion) const
119 {
120  Matrix retval;
121 
122  if (! force_conversion)
123  gripe_implicit_conversion ("Octave:imag-to-real",
124  "complex scalar", "real matrix");
125 
126  retval = Matrix (1, 1, std::real (scalar));
127 
128  return retval;
129 }
130 
132 octave_float_complex::float_matrix_value (bool force_conversion) const
133 {
134  FloatMatrix retval;
135 
136  if (! force_conversion)
137  gripe_implicit_conversion ("Octave:imag-to-real",
138  "complex scalar", "real matrix");
139 
140  retval = FloatMatrix (1, 1, std::real (scalar));
141 
142  return retval;
143 }
144 
145 NDArray
146 octave_float_complex::array_value (bool force_conversion) const
147 {
148  NDArray retval;
149 
150  if (! force_conversion)
151  gripe_implicit_conversion ("Octave:imag-to-real",
152  "complex scalar", "real matrix");
153 
154  retval = NDArray (dim_vector (1, 1), std::real (scalar));
155 
156  return retval;
157 }
158 
160 octave_float_complex::float_array_value (bool force_conversion) const
161 {
162  FloatNDArray retval;
163 
164  if (! force_conversion)
165  gripe_implicit_conversion ("Octave:imag-to-real",
166  "complex scalar", "real matrix");
167 
168  retval = FloatNDArray (dim_vector (1, 1), std::real (scalar));
169 
170  return retval;
171 }
172 
173 Complex
175 {
176  return scalar;
177 }
178 
181 {
182  return static_cast<FloatComplex> (scalar);
183 }
184 
187 {
188  return ComplexMatrix (1, 1, scalar);
189 }
190 
193 {
194  return FloatComplexMatrix (1, 1, scalar);
195 }
196 
198 octave_float_complex::complex_array_value (bool /* force_conversion */) const
199 {
200  return ComplexNDArray (dim_vector (1, 1), scalar);
201 }
202 
204 octave_float_complex::float_complex_array_value (bool /* force_conversion */) const
205 {
206  return FloatComplexNDArray (dim_vector (1, 1), scalar);
207 }
208 
210 octave_float_complex::resize (const dim_vector& dv, bool fill) const
211 {
212  if (fill)
213  {
214  FloatComplexNDArray retval (dv, FloatComplex (0));
215 
216  if (dv.numel ())
217  retval(0) = scalar;
218 
219  return retval;
220  }
221  else
222  {
223  FloatComplexNDArray retval (dv);
224 
225  if (dv.numel ())
226  retval(0) = scalar;
227 
228  return retval;
229  }
230 }
231 
234 {
235  return
237  m, n);
238 }
239 
240 bool
242 {
244 
246 
247  os << "\n";
248 
249  return true;
250 }
251 
252 bool
254 {
255  scalar = octave_read_value<FloatComplex> (is);
256 
257  if (!is)
258  {
259  error ("load: failed to load complex scalar constant");
260  return false;
261  }
262 
263  return true;
264 }
265 
266 
267 bool
268 octave_float_complex::save_binary (std::ostream& os, bool& /* save_as_floats */)
269 {
270  char tmp = static_cast<char> (LS_FLOAT);
271  os.write (reinterpret_cast<char *> (&tmp), 1);
273  os.write (reinterpret_cast<char *> (&ctmp), 8);
274 
275  return true;
276 }
277 
278 bool
279 octave_float_complex::load_binary (std::istream& is, bool swap,
281 {
282  char tmp;
283  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
284  return false;
285 
286  FloatComplex ctmp;
287  read_floats (is, reinterpret_cast<float *> (&ctmp),
288  static_cast<save_type> (tmp), 2, swap, fmt);
289  if (error_state || ! is)
290  return false;
291 
292  scalar = ctmp;
293  return true;
294 }
295 
296 #if defined (HAVE_HDF5)
297 
298 bool
299 octave_float_complex::save_hdf5 (hid_t loc_id, const char *name,
300  bool /* save_as_floats */)
301 {
302  hsize_t dimens[3];
303  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
304  bool retval = true;
305 
306  space_hid = H5Screate_simple (0, dimens, 0);
307  if (space_hid < 0)
308  return false;
309 
310  type_hid = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
311  if (type_hid < 0)
312  {
313  H5Sclose (space_hid);
314  return false;
315  }
316 #if HAVE_HDF5_18
317  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid,
318  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
319 #else
320  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
321 #endif
322  if (data_hid < 0)
323  {
324  H5Sclose (space_hid);
325  H5Tclose (type_hid);
326  return false;
327  }
328 
330  retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
331  &tmp) >= 0;
332 
333  H5Dclose (data_hid);
334  H5Tclose (type_hid);
335  H5Sclose (space_hid);
336 
337  return retval;
338 }
339 
340 bool
341 octave_float_complex::load_hdf5 (hid_t loc_id, const char *name)
342 {
343  bool retval = false;
344 #if HAVE_HDF5_18
345  hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
346 #else
347  hid_t data_hid = H5Dopen (loc_id, name);
348 #endif
349  hid_t type_hid = H5Dget_type (data_hid);
350 
351  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
352 
353  if (! hdf5_types_compatible (type_hid, complex_type))
354  {
355  H5Tclose (complex_type);
356  H5Dclose (data_hid);
357  return false;
358  }
359 
360  hid_t space_id = H5Dget_space (data_hid);
361  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
362 
363  if (rank != 0)
364  {
365  H5Tclose (complex_type);
366  H5Sclose (space_id);
367  H5Dclose (data_hid);
368  return false;
369  }
370 
371  // complex scalar:
372  FloatComplex ctmp;
373  if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
374  &ctmp) >= 0)
375  {
376  retval = true;
377  scalar = ctmp;
378  }
379 
380  H5Tclose (complex_type);
381  H5Sclose (space_id);
382  H5Dclose (data_hid);
383 
384  return retval;
385 }
386 
387 #endif
388 
389 mxArray *
391 {
392  mxArray *retval = new mxArray (mxSINGLE_CLASS, 1, 1, mxCOMPLEX);
393 
394  float *pr = static_cast<float *> (retval->get_data ());
395  float *pi = static_cast<float *> (retval->get_imag_data ());
396 
397  pr[0] = std::real (scalar);
398  pi[0] = std::imag (scalar);
399 
400  return retval;
401 }
402 
405 {
406  switch (umap)
407  {
408 #define SCALAR_MAPPER(UMAP, FCN) \
409  case umap_ ## UMAP: \
410  return octave_value (FCN (scalar))
411 
413  SCALAR_MAPPER (acos, ::acos);
415  SCALAR_MAPPER (angle, std::arg);
417  SCALAR_MAPPER (asin, ::asin);
419  SCALAR_MAPPER (atan, ::atan);
421  SCALAR_MAPPER (erf, ::erf);
422  SCALAR_MAPPER (erfc, ::erfc);
424  SCALAR_MAPPER (erfi, ::erfi);
426  SCALAR_MAPPER (ceil, ::ceil);
428  SCALAR_MAPPER (cos, std::cos);
429  SCALAR_MAPPER (cosh, std::cosh);
430  SCALAR_MAPPER (exp, std::exp);
432  SCALAR_MAPPER (fix, ::fix);
435  SCALAR_MAPPER (log, std::log);
436  SCALAR_MAPPER (log2, xlog2);
437  SCALAR_MAPPER (log10, std::log10);
440  SCALAR_MAPPER (round, xround);
441  SCALAR_MAPPER (roundb, xroundb);
443  SCALAR_MAPPER (sin, std::sin);
444  SCALAR_MAPPER (sinh, std::sinh);
445  SCALAR_MAPPER (sqrt, std::sqrt);
446  SCALAR_MAPPER (tan, std::tan);
447  SCALAR_MAPPER (tanh, std::tanh);
448  SCALAR_MAPPER (finite, xfinite);
449  SCALAR_MAPPER (isinf, xisinf);
450  SCALAR_MAPPER (isna, octave_is_NA);
451  SCALAR_MAPPER (isnan, xisnan);
452 
453  default:
454  return octave_base_value::map (umap);
455  }
456 }