GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-flt-complex.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2018 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
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License 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 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (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 "ovl.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 "errwarn.h"
46 #include "pr-output.h"
47 #include "ops.h"
48 
49 #include "ls-oct-text.h"
50 #include "ls-hdf5.h"
51 
52 // Prevent implicit instantiations on some systems (Windows, others?)
53 // that can lead to duplicate definitions of static data members.
54 
55 extern template class OCTINTERP_API octave_base_scalar<float>;
56 
58 
60  "float complex scalar", "single");
61 
64 {
65  octave_base_value *retval = nullptr;
66 
67  float im = scalar.imag ();
68 
69  if (im == 0.0)
70  retval = new octave_float_scalar (scalar.real ());
71 
72  return retval;
73 }
74 
77 {
78  // FIXME: this doesn't solve the problem of
79  //
80  // a = i; a([1,1], [1,1], [1,1])
81  //
82  // and similar constructions. Hmm...
83 
84  // FIXME: using this constructor avoids narrowing the
85  // 1x1 matrix back to a scalar value. Need a better solution
86  // to this problem.
87 
90 
91  return tmp.do_index_op (idx, resize_ok);
92 }
93 
94 double
95 octave_float_complex::double_value (bool force_conversion) const
96 {
97  if (! force_conversion)
98  warn_implicit_conversion ("Octave:imag-to-real",
99  "complex scalar", "real scalar");
100 
101  return scalar.real ();
102 }
103 
104 float
105 octave_float_complex::float_value (bool force_conversion) const
106 {
107  if (! force_conversion)
108  warn_implicit_conversion ("Octave:imag-to-real",
109  "complex scalar", "real scalar");
110 
111  return scalar.real ();
112 }
113 
114 Matrix
115 octave_float_complex::matrix_value (bool force_conversion) const
116 {
117  Matrix retval;
118 
119  if (! force_conversion)
120  warn_implicit_conversion ("Octave:imag-to-real",
121  "complex scalar", "real matrix");
122 
123  retval = Matrix (1, 1, scalar.real ());
124 
125  return retval;
126 }
127 
129 octave_float_complex::float_matrix_value (bool force_conversion) const
130 {
132 
133  if (! force_conversion)
134  warn_implicit_conversion ("Octave:imag-to-real",
135  "complex scalar", "real matrix");
136 
137  retval = FloatMatrix (1, 1, scalar.real ());
138 
139  return retval;
140 }
141 
142 NDArray
143 octave_float_complex::array_value (bool force_conversion) const
144 {
145  NDArray retval;
146 
147  if (! force_conversion)
148  warn_implicit_conversion ("Octave:imag-to-real",
149  "complex scalar", "real matrix");
150 
151  retval = NDArray (dim_vector (1, 1), scalar.real ());
152 
153  return retval;
154 }
155 
157 octave_float_complex::float_array_value (bool force_conversion) const
158 {
160 
161  if (! force_conversion)
162  warn_implicit_conversion ("Octave:imag-to-real",
163  "complex scalar", "real matrix");
164 
165  retval = FloatNDArray (dim_vector (1, 1), scalar.real ());
166 
167  return retval;
168 }
169 
170 Complex
172 {
173  return scalar;
174 }
175 
178 {
179  return static_cast<FloatComplex> (scalar);
180 }
181 
184 {
185  return ComplexMatrix (1, 1, scalar);
186 }
187 
190 {
191  return FloatComplexMatrix (1, 1, scalar);
192 }
193 
195 octave_float_complex::complex_array_value (bool /* force_conversion */) const
196 {
197  return ComplexNDArray (dim_vector (1, 1), scalar);
198 }
199 
201 octave_float_complex::float_complex_array_value (bool /* force_conversion */) const
202 {
203  return FloatComplexNDArray (dim_vector (1, 1), scalar);
204 }
205 
207 octave_float_complex::resize (const dim_vector& dv, bool fill) const
208 {
209  if (fill)
210  {
212 
213  if (dv.numel ())
214  retval(0) = scalar;
215 
216  return retval;
217  }
218  else
219  {
221 
222  if (dv.numel ())
223  retval(0) = scalar;
224 
225  return retval;
226  }
227 }
228 
231 {
232  return Complex (scalar);
233 }
234 
237 {
238  return scalar;
239 }
240 
243 {
244  return
246  m, n);
247 }
248 
249 bool
251 {
253 
255 
256  os << "\n";
257 
258  return true;
259 }
260 
261 bool
263 {
264  scalar = octave_read_value<FloatComplex> (is);
265 
266  if (! is)
267  error ("load: failed to load complex scalar constant");
268 
269  return true;
270 }
271 
272 bool
273 octave_float_complex::save_binary (std::ostream& os, bool& /* save_as_floats */)
274 {
275  char tmp = static_cast<char> (LS_FLOAT);
276  os.write (reinterpret_cast<char *> (&tmp), 1);
278  os.write (reinterpret_cast<char *> (&ctmp), 8);
279 
280  return true;
281 }
282 
283 bool
286 {
287  char tmp;
288  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
289  return false;
290 
291  FloatComplex ctmp;
292  read_floats (is, reinterpret_cast<float *> (&ctmp),
293  static_cast<save_type> (tmp), 2, swap, fmt);
294 
295  if (! is)
296  return false;
297 
298  scalar = ctmp;
299  return true;
300 }
301 
302 bool
304  bool /* save_as_floats */)
305 {
306  bool retval = false;
307 
308 #if defined (HAVE_HDF5)
309 
310  hsize_t dimens[3];
311  hid_t space_hid, type_hid, data_hid;
312  space_hid = type_hid = data_hid = -1;
313 
314  space_hid = H5Screate_simple (0, dimens, nullptr);
315  if (space_hid < 0)
316  return false;
317 
318  type_hid = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
319  if (type_hid < 0)
320  {
321  H5Sclose (space_hid);
322  return false;
323  }
324 #if defined (HAVE_HDF5_18)
325  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid,
327 #else
328  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, octave_H5P_DEFAULT);
329 #endif
330  if (data_hid < 0)
331  {
332  H5Sclose (space_hid);
333  H5Tclose (type_hid);
334  return false;
335  }
336 
338  retval = H5Dwrite (data_hid, type_hid, octave_H5S_ALL, octave_H5S_ALL,
339  octave_H5P_DEFAULT, &tmp) >= 0;
340 
341  H5Dclose (data_hid);
342  H5Tclose (type_hid);
343  H5Sclose (space_hid);
344 
345 #else
346  octave_unused_parameter (loc_id);
347  octave_unused_parameter (name);
348 
349  warn_save ("hdf5");
350 #endif
351 
352  return retval;
353 }
354 
355 bool
357 {
358  bool retval = false;
359 
360 #if defined (HAVE_HDF5)
361 
362 #if defined (HAVE_HDF5_18)
363  hid_t data_hid = H5Dopen (loc_id, name, octave_H5P_DEFAULT);
364 #else
365  hid_t data_hid = H5Dopen (loc_id, name);
366 #endif
367  hid_t type_hid = H5Dget_type (data_hid);
368 
369  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
370 
371  if (! hdf5_types_compatible (type_hid, complex_type))
372  {
373  H5Tclose (complex_type);
374  H5Dclose (data_hid);
375  return false;
376  }
377 
378  hid_t space_id = H5Dget_space (data_hid);
379  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
380 
381  if (rank != 0)
382  {
383  H5Tclose (complex_type);
384  H5Sclose (space_id);
385  H5Dclose (data_hid);
386  return false;
387  }
388 
389  // complex scalar:
390  FloatComplex ctmp;
391  if (H5Dread (data_hid, complex_type, octave_H5S_ALL, octave_H5S_ALL,
392  octave_H5P_DEFAULT, &ctmp)
393  >= 0)
394  {
395  retval = true;
396  scalar = ctmp;
397  }
398 
399  H5Tclose (complex_type);
400  H5Sclose (space_id);
401  H5Dclose (data_hid);
402 
403 #else
404  octave_unused_parameter (loc_id);
405  octave_unused_parameter (name);
406 
407  warn_load ("hdf5");
408 #endif
409 
410  return retval;
411 }
412 
413 mxArray *
415 {
417 
418  float *pr = static_cast<float *> (retval->get_data ());
419  float *pi = static_cast<float *> (retval->get_imag_data ());
420 
421  pr[0] = scalar.real ();
422  pi[0] = scalar.imag ();
423 
424  return retval;
425 }
426 
429 {
430  switch (umap)
431  {
432 #define SCALAR_MAPPER(UMAP, FCN) \
433  case umap_ ## UMAP: \
434  return octave_value (FCN (scalar))
435 
439  SCALAR_MAPPER (angle, std::arg);
452  SCALAR_MAPPER (cos, std::cos);
453  SCALAR_MAPPER (cosh, std::cosh);
454  SCALAR_MAPPER (exp, std::exp);
461  SCALAR_MAPPER (log10, std::log10);
467  SCALAR_MAPPER (sin, std::sin);
468  SCALAR_MAPPER (sinh, std::sinh);
469  SCALAR_MAPPER (sqrt, std::sqrt);
470  SCALAR_MAPPER (tan, std::tan);
471  SCALAR_MAPPER (tanh, std::tanh);
476 
477  // Special cases for Matlab compatibility
478  case umap_xtolower:
479  case umap_xtoupper:
480  return scalar;
481 
482  default:
483  return octave_base_value::map (umap);
484  }
485 }
octave_idx_type write(const octave_value &data, octave_idx_type block_size, oct_data_conv::data_type output_type, octave_idx_type skip, mach_info::float_format flt_fmt)
Definition: oct-stream.cc:6704
double erfcx(double x)
Definition: lo-specfun.cc:1756
octave_base_value * try_narrowing_conversion(void)
ComplexNDArray complex_array_value(bool=false) const
float float_value(bool=false) const
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
#define SCALAR_MAPPER(UMAP, FCN)
std::complex< double > erfi(std::complex< double > z, double relerr=0)
const octave_hdf5_id octave_H5S_ALL
double erfi(double x)
Definition: lo-specfun.cc:1775
double asinh(double x)
Definition: lo-specfun.h:67
bool isna(double x)
Definition: lo-mappers.cc:45
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the base of natural logarithms The constant ex $e satisfies the equation log(e)
bool isnan(bool)
Definition: lo-mappers.h:187
std::complex< T > ceil(const std::complex< T > &x)
Definition: lo-mappers.h:112
void error(const char *fmt,...)
Definition: error.cc:578
bool isinf(double x)
Definition: lo-mappers.h:225
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:139
Complex complex_value(bool=false) const
static T abs(T x)
Definition: pr-output.cc:1696
octave_value as_single(void) const
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:180
Complex acos(const Complex &x)
Definition: lo-mappers.cc:83
Complex atan(const Complex &x)
Definition: lo-mappers.h:80
octave_value diag(octave_idx_type m, octave_idx_type n) const
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
double fix(double x)
Definition: lo-mappers.h:127
void read_floats(std::istream &is, float *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
Definition: data-conv.cc:831
Complex asin(const Complex &x)
Definition: lo-mappers.cc:105
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Complex log2(const Complex &x)
Definition: lo-mappers.cc:137
Complex erfc(const Complex &x)
Definition: lo-specfun.cc:1653
std::complex< double > erf(std::complex< double > z, double relerr=0)
virtual octave_value map(unary_mapper_t) const
Definition: ov-base.cc:1121
octave_value resize(const dim_vector &dv, bool fill=false) const
octave_value arg
Definition: pr-output.cc:3244
void warn_load(const char *type) const
Definition: ov-base.cc:1097
FloatComplexNDArray float_complex_array_value(bool=false) const
bool swap
Definition: load-save.cc:738
FloatComplex float_complex_value(bool=false) const
Complex expm1(const Complex &x)
Definition: lo-specfun.cc:1875
FloatNDArray float_array_value(bool=false) const
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:215
nd deftypefn *std::string name
Definition: sysdep.cc:647
double acosh(double x)
Definition: lo-specfun.h:49
bool load_ascii(std::istream &is)
Matrix matrix_value(bool=false) const
Complex log1p(const Complex &x)
Definition: lo-specfun.cc:1959
bool hdf5_types_compatible(octave_hdf5_id t1, octave_hdf5_id t2)
Definition: ls-hdf5.cc:190
double signum(double x)
Definition: lo-mappers.h:244
double dawson(double x)
Definition: lo-specfun.cc:1518
double tmp
Definition: data.cc:6252
octave_value retval
Definition: data.cc:6246
std::complex< double > erfcx(std::complex< double > z, double relerr=0)
int64_t octave_hdf5_id
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
double atanh(double x)
Definition: lo-specfun.h:72
void warn_save(const char *type) const
Definition: ov-base.cc:1106
bool save_ascii(std::ostream &os)
Definition: dMatrix.h:36
Complex erf(const Complex &x)
Definition: lo-specfun.cc:1638
ComplexMatrix complex_matrix_value(bool=false) const
void mxArray
Definition: mex.h:55
FloatMatrix float_matrix_value(bool=false) const
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:362
mxArray * as_mxArray(void) const
double double_value(bool=false) const
FloatComplexMatrix float_complex_matrix_value(bool=false) const
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:338
bool isfinite(double x)
Definition: lo-mappers.h:201
double roundb(double x)
Definition: lo-mappers.h:156
octave_value as_double(void) const
double round(double x)
Definition: lo-mappers.h:145
NDArray array_value(bool=false) const
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:141
const octave_hdf5_id octave_H5P_DEFAULT
octave_value map(unary_mapper_t umap) const
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
bool save_binary(std::ostream &os, bool &save_as_floats)
std::complex< double > Complex
Definition: oct-cmplx.h:31
void octave_write_float_complex(std::ostream &os, const FloatComplex &c)
Definition: lo-utils.cc:431
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:135
write the output to stdout if nargout is
Definition: load-save.cc:1612
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
octave_hdf5_id hdf5_make_complex_type(octave_hdf5_id num_type)
Definition: ls-hdf5.cc:326
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
dim_vector dv
Definition: sub2ind.cc:263
octave::stream os
Definition: file-io.cc:627
static const double pi
Definition: lo-specfun.cc:1996
std::complex< double > erfc(std::complex< double > z, double relerr=0)