GNU Octave  4.2.1
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-complex.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2017 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 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <iostream>
28 #include <sstream>
29 
30 #include "lo-ieee.h"
31 #include "lo-specfun.h"
32 #include "lo-mappers.h"
33 
34 #include "mxarray.h"
35 #include "ovl.h"
36 #include "oct-hdf5.h"
37 #include "oct-stream.h"
38 #include "ops.h"
39 #include "ov-complex.h"
40 #include "ov-flt-complex.h"
41 #include "ov-base.h"
42 #include "ov-base-scalar.h"
43 #include "ov-base-scalar.cc"
44 #include "ov-cx-mat.h"
45 #include "ov-scalar.h"
46 #include "errwarn.h"
47 #include "pr-output.h"
48 #include "ops.h"
49 
50 #include "ls-oct-text.h"
51 #include "ls-hdf5.h"
52 
53 // Prevent implicit instantiations on some systems (Windows, others?)
54 // that can lead to duplicate definitions of static data members.
55 
56 extern template class OCTINTERP_API octave_base_scalar<double>;
58 
59 template class octave_base_scalar<Complex>;
60 
62  "complex scalar", "double");
63 
64 namespace octave
65 {
66  // Complain if a complex value is used as a subscript.
67 
69  {
70  public:
71 
73  : index_exception (value) { }
74 
76 
77  std::string details (void) const
78  {
79  return "subscripts must be real (forgot to initialize i or j?)";
80  }
81 
82  // ID of error to throw.
83  const char *err_id (void) const
84  {
85  return "Octave:invalid-index";
86  }
87  };
88 }
89 
90 static octave_base_value *
92 {
93  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
94 
95  return new octave_float_complex (v.float_complex_value ());
96 }
97 
100 {
101  return
104 }
105 
108 {
110 
111  double im = scalar.imag ();
112 
113  if (im == 0.0)
114  retval = new octave_scalar (scalar.real ());
115 
116  return retval;
117 }
118 
120 octave_complex::do_index_op (const octave_value_list& idx, bool resize_ok)
121 {
122  // FIXME: this doesn't solve the problem of
123  //
124  // a = i; a([1,1], [1,1], [1,1])
125  //
126  // and similar constructions. Hmm...
127 
128  // FIXME: using this constructor avoids narrowing the
129  // 1x1 matrix back to a scalar value. Need a better solution
130  // to this problem.
131 
133 
134  return tmp.do_index_op (idx, resize_ok);
135 }
136 
137 // Can't make an index_vector from a complex number. Throw an error.
140 {
141  std::ostringstream buf;
142  buf << scalar.real () << std::showpos << scalar.imag () << "i";
143  octave::complex_index_exception e (buf.str ());
144 
145  throw e;
146 }
147 
148 double
149 octave_complex::double_value (bool force_conversion) const
150 {
151  if (! force_conversion)
152  warn_implicit_conversion ("Octave:imag-to-real",
153  "complex scalar", "real scalar");
154 
155  return scalar.real ();
156 }
157 
158 float
159 octave_complex::float_value (bool force_conversion) const
160 {
161  if (! force_conversion)
162  warn_implicit_conversion ("Octave:imag-to-real",
163  "complex scalar", "real scalar");
164 
165  return scalar.real ();
166 }
167 
168 Matrix
169 octave_complex::matrix_value (bool force_conversion) const
170 {
171  Matrix retval;
172 
173  if (! force_conversion)
174  warn_implicit_conversion ("Octave:imag-to-real",
175  "complex scalar", "real matrix");
176 
177  retval = Matrix (1, 1, scalar.real ());
178 
179  return retval;
180 }
181 
183 octave_complex::float_matrix_value (bool force_conversion) const
184 {
186 
187  if (! force_conversion)
188  warn_implicit_conversion ("Octave:imag-to-real",
189  "complex scalar", "real matrix");
190 
191  retval = FloatMatrix (1, 1, scalar.real ());
192 
193  return retval;
194 }
195 
196 NDArray
197 octave_complex::array_value (bool force_conversion) const
198 {
199  NDArray retval;
200 
201  if (! force_conversion)
202  warn_implicit_conversion ("Octave:imag-to-real",
203  "complex scalar", "real matrix");
204 
205  retval = NDArray (dim_vector (1, 1), scalar.real ());
206 
207  return retval;
208 }
209 
211 octave_complex::float_array_value (bool force_conversion) const
212 {
214 
215  if (! force_conversion)
216  warn_implicit_conversion ("Octave:imag-to-real",
217  "complex scalar", "real matrix");
218 
219  retval = FloatNDArray (dim_vector (1, 1), scalar.real ());
220 
221  return retval;
222 }
223 
224 Complex
226 {
227  return scalar;
228 }
229 
232 {
233  return static_cast<FloatComplex> (scalar);
234 }
235 
238 {
239  return ComplexMatrix (1, 1, scalar);
240 }
241 
244 {
245  return FloatComplexMatrix (1, 1, static_cast<FloatComplex> (scalar));
246 }
247 
249 octave_complex::complex_array_value (bool /* force_conversion */) const
250 {
251  return ComplexNDArray (dim_vector (1, 1), scalar);
252 }
253 
255 octave_complex::float_complex_array_value (bool /* force_conversion */) const
256 {
257  return FloatComplexNDArray (dim_vector (1, 1),
258  static_cast<FloatComplex> (scalar));
259 }
260 
262 octave_complex::resize (const dim_vector& dv, bool fill) const
263 {
264  if (fill)
265  {
266  ComplexNDArray retval (dv, Complex (0));
267 
268  if (dv.numel ())
269  retval(0) = scalar;
270 
271  return retval;
272  }
273  else
274  {
275  ComplexNDArray retval (dv);
276 
277  if (dv.numel ())
278  retval(0) = scalar;
279 
280  return retval;
281  }
282 }
283 
286 {
287  return scalar;
288 }
289 
292 {
293  return FloatComplex (scalar);
294 }
295 
298 {
299  return ComplexDiagMatrix (Array<Complex> (dim_vector (1, 1), scalar), m, n);
300 }
301 
302 bool
303 octave_complex::save_ascii (std::ostream& os)
304 {
305  Complex c = complex_value ();
306 
307  octave_write_complex (os, c);
308 
309  os << "\n";
310 
311  return true;
312 }
313 
314 bool
316 {
317  scalar = octave_read_value<Complex> (is);
318 
319  if (! is)
320  error ("load: failed to load complex scalar constant");
321 
322  return true;
323 }
324 
325 bool
326 octave_complex::save_binary (std::ostream& os, bool& /* save_as_floats */)
327 {
328  char tmp = static_cast<char> (LS_DOUBLE);
329  os.write (reinterpret_cast<char *> (&tmp), 1);
330  Complex ctmp = complex_value ();
331  os.write (reinterpret_cast<char *> (&ctmp), 16);
332 
333  return true;
334 }
335 
336 bool
337 octave_complex::load_binary (std::istream& is, bool swap,
339 {
340  char tmp;
341  if (! is.read (reinterpret_cast<char *> (&tmp), 1))
342  return false;
343 
344  Complex ctmp;
345  read_doubles (is, reinterpret_cast<double *> (&ctmp),
346  static_cast<save_type> (tmp), 2, swap, fmt);
347 
348  if (! is)
349  return false;
350 
351  scalar = ctmp;
352  return true;
353 }
354 
355 bool
357  bool /* save_as_floats */)
358 {
359  bool retval = false;
360 
361 #if defined (HAVE_HDF5)
362 
363  hsize_t dimens[3];
364  hid_t space_hid, type_hid, data_hid;
365  space_hid = type_hid = data_hid = -1;
366 
367  space_hid = H5Screate_simple (0, dimens, 0);
368  if (space_hid < 0)
369  return false;
370 
371  type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
372  if (type_hid < 0)
373  {
374  H5Sclose (space_hid);
375  return false;
376  }
377 #if defined (HAVE_HDF5_18)
378  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid,
380 #else
381  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, octave_H5P_DEFAULT);
382 #endif
383  if (data_hid < 0)
384  {
385  H5Sclose (space_hid);
386  H5Tclose (type_hid);
387  return false;
388  }
389 
391  retval = H5Dwrite (data_hid, type_hid, octave_H5S_ALL, octave_H5S_ALL,
392  octave_H5P_DEFAULT, &tmp) >= 0;
393 
394  H5Dclose (data_hid);
395  H5Tclose (type_hid);
396  H5Sclose (space_hid);
397 
398 #else
399  octave_unused_parameter (loc_id);
400  octave_unused_parameter (name);
401 
402  warn_save ("hdf5");
403 #endif
404 
405  return retval;
406 }
407 
408 bool
410 {
411  bool retval = false;
412 
413 #if defined (HAVE_HDF5)
414 
415 #if defined (HAVE_HDF5_18)
416  hid_t data_hid = H5Dopen (loc_id, name, octave_H5P_DEFAULT);
417 #else
418  hid_t data_hid = H5Dopen (loc_id, name);
419 #endif
420  hid_t type_hid = H5Dget_type (data_hid);
421 
422  hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE);
423 
424  if (! hdf5_types_compatible (type_hid, complex_type))
425  {
426  H5Tclose (complex_type);
427  H5Dclose (data_hid);
428  return false;
429  }
430 
431  hid_t space_id = H5Dget_space (data_hid);
432  hsize_t rank = H5Sget_simple_extent_ndims (space_id);
433 
434  if (rank != 0)
435  {
436  H5Tclose (complex_type);
437  H5Sclose (space_id);
438  H5Dclose (data_hid);
439  return false;
440  }
441 
442  // complex scalar:
443  Complex ctmp;
444  if (H5Dread (data_hid, complex_type, octave_H5S_ALL, octave_H5S_ALL,
445  octave_H5P_DEFAULT, &ctmp) >= 0)
446  {
447  retval = true;
448  scalar = ctmp;
449  }
450 
451  H5Tclose (complex_type);
452  H5Sclose (space_id);
453  H5Dclose (data_hid);
454 
455 #else
456  octave_unused_parameter (loc_id);
457  octave_unused_parameter (name);
458 
459  warn_load ("hdf5");
460 #endif
461 
462  return retval;
463 }
464 
465 mxArray *
467 {
469 
470  double *pr = static_cast<double *> (retval->get_data ());
471  double *pi = static_cast<double *> (retval->get_imag_data ());
472 
473  pr[0] = scalar.real ();
474  pi[0] = scalar.imag ();
475 
476  return retval;
477 }
478 
481 {
482  switch (umap)
483  {
484 #define SCALAR_MAPPER(UMAP, FCN) \
485  case umap_ ## UMAP: \
486  return octave_value (FCN (scalar))
487 
491  SCALAR_MAPPER (angle, std::arg);
504  SCALAR_MAPPER (cos, std::cos);
505  SCALAR_MAPPER (cosh, std::cosh);
506  SCALAR_MAPPER (exp, std::exp);
513  SCALAR_MAPPER (log10, std::log10);
519  SCALAR_MAPPER (sin, std::sin);
520  SCALAR_MAPPER (sinh, std::sinh);
521  SCALAR_MAPPER (sqrt, std::sqrt);
522  SCALAR_MAPPER (tan, std::tan);
523  SCALAR_MAPPER (tanh, std::tanh);
528 
529  default:
530  return octave_base_value::map (umap);
531  }
532 }
idx_vector index_vector(bool=false) const
Definition: ov-complex.cc:139
Octave interface to the compression and uncompression libraries.
Definition: aepbalance.cc:47
bool save_binary(std::ostream &os, bool &save_as_floats)
Definition: ov-complex.cc:326
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition: ov-complex.cc:120
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
Definition: ov-complex.cc:356
octave_value diag(octave_idx_type m, octave_idx_type n) const
Definition: ov-complex.cc:297
float erfcx(float x)
Definition: lo-specfun.cc:271
function erf(X)
Definition: erf.f:2
static octave_base_value * default_numeric_demotion_function(const octave_base_value &a)
Definition: ov-complex.cc:91
std::complex< double > erfi(std::complex< double > z, double relerr=0)
const octave_hdf5_id octave_H5S_ALL
static int static_type_id(void)
bool isnan(double x)
Definition: lo-mappers.cc:347
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
Definition: ov-complex.cc:409
bool save_ascii(std::ostream &os)
Definition: ov-complex.cc:303
double atanh(double x)
Definition: lo-specfun.cc:149
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)
double ceil(double x)
Definition: lo-mappers.h:138
function atanh(X)
Definition: atanh.f:2
void octave_write_complex(std::ostream &os, const Complex &c)
Definition: lo-utils.cc:401
void error(const char *fmt,...)
Definition: error.cc:570
mxArray * as_mxArray(void) const
Definition: ov-complex.cc:466
FloatComplexNDArray float_complex_array_value(bool=false) const
Definition: ov-complex.cc:255
void * get_data(void) const
Definition: mxarray.h:449
double double_value(bool=false) const
Definition: ov-complex.cc:149
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
Definition: ov-complex.cc:337
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:169
Complex acos(const Complex &x)
Definition: lo-mappers.cc:90
double expm1(double x)
Definition: lo-specfun.cc:473
type_conv_info numeric_demotion_function(void) const
Definition: ov-complex.cc:99
double asinh(double x)
Definition: lo-specfun.cc:105
#define SCALAR_MAPPER(UMAP, FCN)
double fix(double x)
Definition: lo-mappers.h:158
Complex asin(const Complex &x)
Definition: lo-mappers.cc:150
octave_value as_single(void) const
Definition: ov-complex.cc:291
i e
Definition: data.cc:2724
octave_value arg
Definition: pr-output.cc:3440
FloatNDArray float_array_value(bool=false) const
Definition: ov-complex.cc:211
double acosh(double x)
Definition: lo-specfun.cc:61
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:389
double round(double x)
Definition: lo-mappers.cc:333
bool is_NA(double x)
Definition: lo-mappers.cc:54
std::string details(void) const
Definition: ov-complex.cc:77
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
bool swap
Definition: load-save.cc:725
octave_value resize(const dim_vector &dv, bool fill=false) const
Definition: ov-complex.cc:262
float erfi(float x)
Definition: lo-specfun.cc:289
void warn_load(const char *type) const
Definition: ov-base.cc:1151
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:216
OCTAVE_EXPORT octave_value_list any number nd example oindent prints the prompt xample Pick a any number!nd example oindent and waits for the user to enter a value The string entered by the user is evaluated as an so it may be a literal a variable name
Definition: input.cc:871
Complex atan(const Complex &x)
Definition: lo-mappers.cc:210
#define OCTINTERP_API
Definition: mexproto.h:69
function asinh(X)
Definition: asinh.f:2
ComplexNDArray complex_array_value(bool=false) const
Definition: ov-complex.cc:249
void read_doubles(std::istream &is, double *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
Definition: data-conv.cc:771
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
octave_base_value * try_narrowing_conversion(void)
Definition: ov-complex.cc:107
bool hdf5_types_compatible(octave_hdf5_id t1, octave_hdf5_id t2)
Definition: ls-hdf5.cc:192
Matrix matrix_value(bool=false) const
Definition: ov-complex.cc:169
double signum(double x)
Definition: lo-mappers.h:259
float float_value(bool=false) const
Definition: ov-complex.cc:159
FloatMatrix float_matrix_value(bool=false) const
Definition: ov-complex.cc:183
float dawson(float x)
Definition: lo-specfun.cc:307
double tmp
Definition: data.cc:6300
octave_value retval
Definition: data.cc:6294
bool finite(double x)
Definition: lo-mappers.cc:367
std::complex< double > erfcx(std::complex< double > z, double relerr=0)
int64_t octave_hdf5_id
Definition: dMatrix.h:37
octave_value map(unary_mapper_t umap) const
Definition: ov-complex.cc:480
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
Definition: lu.cc:138
void warn_save(const char *type) const
Definition: ov-base.cc:1160
void mxArray
Definition: mex.h:55
bool isinf(double x)
Definition: lo-mappers.cc:387
function acosh(X)
Definition: acosh.f:2
double erf(double x)
Definition: lo-specfun.cc:193
complex_index_exception(const std::string &value)
Definition: ov-complex.cc:72
ComplexMatrix complex_matrix_value(bool=false) const
Definition: ov-complex.cc:237
void * get_imag_data(void) const
Definition: mxarray.h:451
double log1p(double x)
Definition: lo-specfun.cc:587
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup abs(local error in x(i))<
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by nd tex zero divided by nd ifnottex and any operation involving another NaN value(5+NaN).Note that NaN always compares not equal to NaN(NaN!
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:332
NDArray array_value(bool=false) const
Definition: ov-complex.cc:197
double roundb(double x)
Definition: lo-mappers.h:189
FloatComplexMatrix float_complex_matrix_value(bool=false) const
Definition: ov-complex.cc:243
octave_value as_double(void) const
Definition: ov-complex.cc:285
virtual octave_value map(unary_mapper_t) const
Definition: ov-base.cc:1175
FloatComplex float_complex_value(bool=false) const
Definition: ov-complex.cc:231
bool load_ascii(std::istream &is)
Definition: ov-complex.cc:315
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:142
double floor(double x)
Definition: lo-mappers.cc:330
const octave_hdf5_id octave_H5P_DEFAULT
double erfc(double x)
Definition: lo-specfun.cc:232
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
std::complex< double > Complex
Definition: oct-cmplx.h:31
const char * err_id(void) const
Definition: ov-complex.cc:83
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:136
write the output to stdout if nargout is
Definition: load-save.cc:1576
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:328
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
dim_vector dv
Definition: sub2ind.cc:263
Complex complex_value(bool=false) const
Definition: ov-complex.cc:225
double log2(double x)
Definition: lo-mappers.cc:233
static const double pi
Definition: lo-specfun.cc:3610
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:454