GNU Octave  4.0.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-2015 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-hdf5.h"
36 #include "oct-stream.h"
37 #include "ops.h"
38 #include "ov-complex.h"
39 #include "ov-base.h"
40 #include "ov-base-scalar.h"
41 #include "ov-base-scalar.cc"
42 #include "ov-flt-cx-mat.h"
43 #include "ov-float.h"
44 #include "ov-flt-complex.h"
45 #include "gripes.h"
46 #include "pr-output.h"
47 #include "ops.h"
48 
49 #include "ls-oct-ascii.h"
50 #include "ls-hdf5.h"
51 
53 
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 
86 
87  return tmp.do_index_op (idx, resize_ok);
88 }
89 
90 double
91 octave_float_complex::double_value (bool force_conversion) const
92 {
93  double retval;
94 
95  if (! force_conversion)
96  gripe_implicit_conversion ("Octave:imag-to-real",
97  "complex scalar", "real scalar");
98 
99  retval = std::real (scalar);
100 
101  return retval;
102 }
103 
104 float
105 octave_float_complex::float_value (bool force_conversion) const
106 {
107  float retval;
108 
109  if (! force_conversion)
110  gripe_implicit_conversion ("Octave:imag-to-real",
111  "complex scalar", "real scalar");
112 
113  retval = std::real (scalar);
114 
115  return retval;
116 }
117 
118 Matrix
119 octave_float_complex::matrix_value (bool force_conversion) const
120 {
121  Matrix retval;
122 
123  if (! force_conversion)
124  gripe_implicit_conversion ("Octave:imag-to-real",
125  "complex scalar", "real matrix");
126 
127  retval = Matrix (1, 1, std::real (scalar));
128 
129  return retval;
130 }
131 
133 octave_float_complex::float_matrix_value (bool force_conversion) const
134 {
135  FloatMatrix retval;
136 
137  if (! force_conversion)
138  gripe_implicit_conversion ("Octave:imag-to-real",
139  "complex scalar", "real matrix");
140 
141  retval = FloatMatrix (1, 1, std::real (scalar));
142 
143  return retval;
144 }
145 
146 NDArray
147 octave_float_complex::array_value (bool force_conversion) const
148 {
149  NDArray retval;
150 
151  if (! force_conversion)
152  gripe_implicit_conversion ("Octave:imag-to-real",
153  "complex scalar", "real matrix");
154 
155  retval = NDArray (dim_vector (1, 1), std::real (scalar));
156 
157  return retval;
158 }
159 
161 octave_float_complex::float_array_value (bool force_conversion) const
162 {
163  FloatNDArray retval;
164 
165  if (! force_conversion)
166  gripe_implicit_conversion ("Octave:imag-to-real",
167  "complex scalar", "real matrix");
168 
169  retval = FloatNDArray (dim_vector (1, 1), std::real (scalar));
170 
171  return retval;
172 }
173 
174 Complex
176 {
177  return scalar;
178 }
179 
182 {
183  return static_cast<FloatComplex> (scalar);
184 }
185 
188 {
189  return ComplexMatrix (1, 1, scalar);
190 }
191 
194 {
195  return FloatComplexMatrix (1, 1, scalar);
196 }
197 
199 octave_float_complex::complex_array_value (bool /* force_conversion */) const
200 {
201  return ComplexNDArray (dim_vector (1, 1), scalar);
202 }
203 
205 octave_float_complex::float_complex_array_value (bool /* force_conversion */) const
206 {
207  return FloatComplexNDArray (dim_vector (1, 1), scalar);
208 }
209 
211 octave_float_complex::resize (const dim_vector& dv, bool fill) const
212 {
213  if (fill)
214  {
215  FloatComplexNDArray retval (dv, FloatComplex (0));
216 
217  if (dv.numel ())
218  retval(0) = scalar;
219 
220  return retval;
221  }
222  else
223  {
224  FloatComplexNDArray retval (dv);
225 
226  if (dv.numel ())
227  retval(0) = scalar;
228 
229  return retval;
230  }
231 }
232 
235 {
236  return
238  m, n);
239 }
240 
241 bool
243 {
245 
247 
248  os << "\n";
249 
250  return true;
251 }
252 
253 bool
255 {
256  scalar = octave_read_value<FloatComplex> (is);
257 
258  if (!is)
259  {
260  error ("load: failed to load complex scalar constant");
261  return false;
262  }
263 
264  return true;
265 }
266 
267 
268 bool
269 octave_float_complex::save_binary (std::ostream& os, bool& /* save_as_floats */)
270 {
271  char tmp = static_cast<char> (LS_FLOAT);
272  os.write (reinterpret_cast<char *> (&tmp), 1);
274  os.write (reinterpret_cast<char *> (&ctmp), 8);
275 
276  return true;
277 }
278 
279 bool
280 octave_float_complex::load_binary (std::istream& is, bool swap,
282 {
283  char tmp;
284  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
285  return false;
286 
287  FloatComplex ctmp;
288  read_floats (is, reinterpret_cast<float *> (&ctmp),
289  static_cast<save_type> (tmp), 2, swap, fmt);
290  if (error_state || ! is)
291  return false;
292 
293  scalar = ctmp;
294  return true;
295 }
296 
297 bool
299  bool /* save_as_floats */)
300 {
301  bool retval = false;
302 
303 #if defined (HAVE_HDF5)
304 
305  hsize_t dimens[3];
306  hid_t space_hid, type_hid, data_hid;
307  space_hid = type_hid = data_hid = -1;
308 
309  space_hid = H5Screate_simple (0, dimens, 0);
310  if (space_hid < 0)
311  return false;
312 
313  type_hid = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
314  if (type_hid < 0)
315  {
316  H5Sclose (space_hid);
317  return false;
318  }
319 #if HAVE_HDF5_18
320  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid,
321  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
322 #else
323  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
324 #endif
325  if (data_hid < 0)
326  {
327  H5Sclose (space_hid);
328  H5Tclose (type_hid);
329  return false;
330  }
331 
333  retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
334  &tmp) >= 0;
335 
336  H5Dclose (data_hid);
337  H5Tclose (type_hid);
338  H5Sclose (space_hid);
339 
340 #else
341  gripe_save ("hdf5");
342 #endif
343 
344  return retval;
345 }
346 
347 bool
349 {
350  bool retval = false;
351 
352 #if defined (HAVE_HDF5)
353 
354 #if HAVE_HDF5_18
355  hid_t data_hid = H5Dopen (loc_id, name, H5P_DEFAULT);
356 #else
357  hid_t data_hid = H5Dopen (loc_id, name);
358 #endif
359  hid_t type_hid = H5Dget_type (data_hid);
360 
361  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
362 
363  if (! hdf5_types_compatible (type_hid, complex_type))
364  {
365  H5Tclose (complex_type);
366  H5Dclose (data_hid);
367  return false;
368  }
369 
370  hid_t space_id = H5Dget_space (data_hid);
371  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
372 
373  if (rank != 0)
374  {
375  H5Tclose (complex_type);
376  H5Sclose (space_id);
377  H5Dclose (data_hid);
378  return false;
379  }
380 
381  // complex scalar:
382  FloatComplex ctmp;
383  if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
384  &ctmp) >= 0)
385  {
386  retval = true;
387  scalar = ctmp;
388  }
389 
390  H5Tclose (complex_type);
391  H5Sclose (space_id);
392  H5Dclose (data_hid);
393 
394 #else
395  gripe_load ("hdf5");
396 #endif
397 
398  return retval;
399 }
400 
401 mxArray *
403 {
404  mxArray *retval = new mxArray (mxSINGLE_CLASS, 1, 1, mxCOMPLEX);
405 
406  float *pr = static_cast<float *> (retval->get_data ());
407  float *pi = static_cast<float *> (retval->get_imag_data ());
408 
409  pr[0] = std::real (scalar);
410  pi[0] = std::imag (scalar);
411 
412  return retval;
413 }
414 
417 {
418  switch (umap)
419  {
420 #define SCALAR_MAPPER(UMAP, FCN) \
421  case umap_ ## UMAP: \
422  return octave_value (FCN (scalar))
423 
425  SCALAR_MAPPER (acos, ::acos);
427  SCALAR_MAPPER (angle, std::arg);
429  SCALAR_MAPPER (asin, ::asin);
431  SCALAR_MAPPER (atan, ::atan);
433  SCALAR_MAPPER (erf, ::erf);
434  SCALAR_MAPPER (erfc, ::erfc);
436  SCALAR_MAPPER (erfi, ::erfi);
438  SCALAR_MAPPER (ceil, ::ceil);
440  SCALAR_MAPPER (cos, std::cos);
441  SCALAR_MAPPER (cosh, std::cosh);
442  SCALAR_MAPPER (exp, std::exp);
444  SCALAR_MAPPER (fix, ::fix);
447  SCALAR_MAPPER (log, std::log);
448  SCALAR_MAPPER (log2, xlog2);
449  SCALAR_MAPPER (log10, std::log10);
452  SCALAR_MAPPER (round, xround);
453  SCALAR_MAPPER (roundb, xroundb);
455  SCALAR_MAPPER (sin, std::sin);
456  SCALAR_MAPPER (sinh, std::sinh);
457  SCALAR_MAPPER (sqrt, std::sqrt);
458  SCALAR_MAPPER (tan, std::tan);
459  SCALAR_MAPPER (tanh, std::tanh);
460  SCALAR_MAPPER (finite, xfinite);
461  SCALAR_MAPPER (isinf, xisinf);
462  SCALAR_MAPPER (isna, octave_is_NA);
463  SCALAR_MAPPER (isnan, xisnan);
464 
465  default:
466  return octave_base_value::map (umap);
467  }
468 }
octave_base_value * try_narrowing_conversion(void)
void gripe_implicit_conversion(const char *id, const char *from, const char *to)
Definition: gripes.cc:180
ComplexNDArray complex_array_value(bool=false) const
bool hdf5_types_compatible(hid_t t1, hid_t t2)
Definition: ls-hdf5.cc:107
ComplexMatrix complex_matrix_value(bool=false) const
double xround(double x)
Definition: lo-mappers.cc:63
float float_value(bool=false) const
bool xisnan(double x)
Definition: lo-mappers.cc:144
double log1p(double x)
Definition: lo-specfun.cc:620
#define SCALAR_MAPPER(UMAP, FCN)
std::complex< double > erfi(std::complex< double > z, double relerr=0)
void gripe_load(const char *type) const
Definition: ov-base.cc:1258
function atanh(X)
Definition: atanh.f:2
bool load_binary(std::istream &is, bool swap, oct_mach_info::float_format fmt)
void error(const char *fmt,...)
Definition: error.cc:476
void * get_data(void) const
Definition: mxarray.h:433
bool xisinf(double x)
Definition: lo-mappers.cc:160
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:164
void gripe_save(const char *type) const
Definition: ov-base.cc:1267
NDArray array_value(bool=false) const
double expm1(double x)
Definition: lo-specfun.cc:510
double xlog2(double x)
Definition: lo-mappers.cc:93
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Complex complex_value(bool=false) const
std::complex< double > erf(std::complex< double > z, double relerr=0)
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:361
octave_value diag(octave_idx_type m, octave_idx_type n) const
hid_t hdf5_make_complex_type(hid_t num_type)
Definition: ls-hdf5.cc:228
double signum(double x)
Definition: lo-mappers.cc:80
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:244
Matrix matrix_value(bool=false) const
bool load_ascii(std::istream &is)
function asinh(X)
Definition: asinh.f:2
std::complex< T > ceil(const std::complex< T > &x)
Definition: lo-mappers.h:275
int error_state
Definition: error.cc:101
FloatComplexMatrix float_complex_matrix_value(bool=false) const
octave_value resize(const dim_vector &dv, bool fill=false) const
std::complex< double > erfcx(std::complex< double > z, double relerr=0)
double xroundb(double x)
Definition: lo-mappers.cc:69
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
bool save_ascii(std::ostream &os)
FloatMatrix float_matrix_value(bool=false) const
Definition: dMatrix.h:35
FloatComplexNDArray float_complex_array_value(bool=false) const
void mxArray
Definition: mex.h:53
function acosh(X)
Definition: acosh.f:2
double arg(double x)
Definition: lo-mappers.h:37
double double_value(bool=false) const
FloatComplex float_complex_value(bool=false) const
octave_value map(unary_mapper_t umap) const
bool xfinite(double x)
Definition: lo-mappers.cc:152
void * get_imag_data(void) const
Definition: mxarray.h:435
virtual octave_value map(unary_mapper_t) const
Definition: ov-base.cc:1276
double fix(double x)
Definition: lo-mappers.h:39
float dawson(float x)
Definition: lo-specfun.cc:349
Complex asin(const Complex &x)
Definition: lo-mappers.cc:204
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:162
std::complex< float > FloatComplex
Definition: oct-cmplx.h:30
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:282
bool save_binary(std::ostream &os, bool &save_as_floats)
std::complex< double > Complex
Definition: oct-cmplx.h:29
FloatNDArray float_array_value(bool=false) const
void octave_write_float_complex(std::ostream &os, const FloatComplex &c)
Definition: lo-utils.cc:422
Complex acos(const Complex &x)
Definition: lo-mappers.cc:177
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:156
T abs(T x)
Definition: pr-output.cc:3062
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
mxArray * as_mxArray(void) const
Complex atan(const Complex &x)
Definition: lo-mappers.cc:231
void read_floats(std::istream &is, float *data, save_type type, octave_idx_type len, bool swap, oct_mach_info::float_format fmt)
Definition: data-conv.cc:837
bool octave_is_NA(double x)
Definition: lo-mappers.cc:167
std::complex< double > erfc(std::complex< double > z, double relerr=0)
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition: ov.h:438