GNU Octave 7.1.0
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-2022 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <istream>
31#include <ostream>
32
33#include "lo-ieee.h"
34#include "lo-specfun.h"
35#include "lo-mappers.h"
36
37#include "mxarray.h"
38#include "ovl.h"
39#include "oct-hdf5.h"
40#include "oct-stream.h"
41#include "ops.h"
42#include "ov-complex.h"
43#include "ov-base.h"
44#include "ov-base-scalar.h"
45#include "ov-base-scalar.cc"
46#include "ov-flt-cx-mat.h"
47#include "ov-float.h"
48#include "ov-flt-complex.h"
49#include "errwarn.h"
50#include "pr-output.h"
51#include "ops.h"
52
53#include "ls-oct-text.h"
54#include "ls-hdf5.h"
55
56// Prevent implicit instantiations on some systems (Windows, others?)
57// that can lead to duplicate definitions of static data members.
58
59extern template class octave_base_scalar<float>;
60
62
64 "float complex scalar", "single");
65
68{
69 octave_base_value *retval = nullptr;
70
71 float im = scalar.imag ();
72
73 if (im == 0.0)
74 retval = new octave_float_scalar (scalar.real ());
75
76 return retval;
77}
78
81{
82 // FIXME: this doesn't solve the problem of
83 //
84 // a = i; a([1,1], [1,1], [1,1])
85 //
86 // and similar constructions. Hmm...
87
88 // FIXME: using this constructor avoids narrowing the
89 // 1x1 matrix back to a scalar value. Need a better solution
90 // to this problem.
91
93
94 return tmp.index_op (idx, resize_ok);
95}
96
97double
98octave_float_complex::double_value (bool force_conversion) const
99{
100 if (! force_conversion)
101 warn_implicit_conversion ("Octave:imag-to-real",
102 "complex scalar", "real scalar");
103
104 return scalar.real ();
105}
106
107float
108octave_float_complex::float_value (bool force_conversion) const
109{
110 if (! force_conversion)
111 warn_implicit_conversion ("Octave:imag-to-real",
112 "complex scalar", "real scalar");
113
114 return scalar.real ();
115}
116
117Matrix
118octave_float_complex::matrix_value (bool force_conversion) const
119{
120 Matrix retval;
121
122 if (! force_conversion)
123 warn_implicit_conversion ("Octave:imag-to-real",
124 "complex scalar", "real matrix");
125
126 retval = Matrix (1, 1, scalar.real ());
127
128 return retval;
129}
130
132octave_float_complex::float_matrix_value (bool force_conversion) const
133{
134 FloatMatrix retval;
135
136 if (! force_conversion)
137 warn_implicit_conversion ("Octave:imag-to-real",
138 "complex scalar", "real matrix");
139
140 retval = FloatMatrix (1, 1, scalar.real ());
141
142 return retval;
143}
144
146octave_float_complex::array_value (bool force_conversion) const
147{
148 NDArray retval;
149
150 if (! force_conversion)
151 warn_implicit_conversion ("Octave:imag-to-real",
152 "complex scalar", "real matrix");
153
154 retval = NDArray (dim_vector (1, 1), scalar.real ());
155
156 return retval;
157}
158
160octave_float_complex::float_array_value (bool force_conversion) const
161{
162 FloatNDArray retval;
163
164 if (! force_conversion)
165 warn_implicit_conversion ("Octave:imag-to-real",
166 "complex scalar", "real matrix");
167
168 retval = FloatNDArray (dim_vector (1, 1), scalar.real ());
169
170 return retval;
171}
172
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
198octave_float_complex::complex_array_value (bool /* force_conversion */) const
199{
200 return ComplexNDArray (dim_vector (1, 1), scalar);
201}
202
204octave_float_complex::float_complex_array_value (bool /* force_conversion */) const
205{
206 return FloatComplexNDArray (dim_vector (1, 1), scalar);
207}
208
210octave_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 Complex (scalar);
236}
237
240{
241 return scalar;
242}
243
246{
247 return
249 m, n);
250}
251
252bool
254{
256
257 octave::write_value<FloatComplex> (os, c);
258
259 os << "\n";
260
261 return true;
262}
263
264bool
266{
267 scalar = octave::read_value<FloatComplex> (is);
268
269 if (! is)
270 error ("load: failed to load complex scalar constant");
271
272 return true;
273}
274
275bool
276octave_float_complex::save_binary (std::ostream& os, bool /* save_as_floats */)
277{
278 char tmp = static_cast<char> (LS_FLOAT);
279 os.write (reinterpret_cast<char *> (&tmp), 1);
281 os.write (reinterpret_cast<char *> (&ctmp), 8);
282
283 return true;
284}
285
286bool
287octave_float_complex::load_binary (std::istream& is, bool swap,
289{
290 char tmp;
291 if (! is.read (reinterpret_cast<char *> (&tmp), 1))
292 return false;
293
294 FloatComplex ctmp;
295 read_floats (is, reinterpret_cast<float *> (&ctmp),
296 static_cast<save_type> (tmp), 2, swap, fmt);
297
298 if (! is)
299 return false;
300
301 scalar = ctmp;
302 return true;
303}
304
305bool
307 bool /* save_as_floats */)
308{
309 bool retval = false;
310
311#if defined (HAVE_HDF5)
312
313 hsize_t dimens[3] = {0};
314 hid_t space_hid, type_hid, data_hid;
315 space_hid = type_hid = data_hid = -1;
316
317 space_hid = H5Screate_simple (0, dimens, nullptr);
318 if (space_hid < 0)
319 return false;
320
321 type_hid = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
322 if (type_hid < 0)
323 {
324 H5Sclose (space_hid);
325 return false;
326 }
327#if defined (HAVE_HDF5_18)
328 data_hid = H5Dcreate (loc_id, name, type_hid, space_hid,
330#else
331 data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, octave_H5P_DEFAULT);
332#endif
333 if (data_hid < 0)
334 {
335 H5Sclose (space_hid);
336 H5Tclose (type_hid);
337 return false;
338 }
339
341 retval = H5Dwrite (data_hid, type_hid, octave_H5S_ALL, octave_H5S_ALL,
342 octave_H5P_DEFAULT, &tmp) >= 0;
343
344 H5Dclose (data_hid);
345 H5Tclose (type_hid);
346 H5Sclose (space_hid);
347
348#else
349 octave_unused_parameter (loc_id);
350 octave_unused_parameter (name);
351
352 warn_save ("hdf5");
353#endif
354
355 return retval;
356}
357
358bool
360{
361 bool retval = false;
362
363#if defined (HAVE_HDF5)
364
365#if defined (HAVE_HDF5_18)
366 hid_t data_hid = H5Dopen (loc_id, name, octave_H5P_DEFAULT);
367#else
368 hid_t data_hid = H5Dopen (loc_id, name);
369#endif
370 hid_t type_hid = H5Dget_type (data_hid);
371
372 hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
373
374 if (! hdf5_types_compatible (type_hid, complex_type))
375 {
376 H5Tclose (complex_type);
377 H5Dclose (data_hid);
378 return false;
379 }
380
381 hid_t space_id = H5Dget_space (data_hid);
382 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
383
384 if (rank != 0)
385 {
386 H5Tclose (complex_type);
387 H5Sclose (space_id);
388 H5Dclose (data_hid);
389 return false;
390 }
391
392 // complex scalar:
393 FloatComplex ctmp;
394 if (H5Dread (data_hid, complex_type, octave_H5S_ALL, octave_H5S_ALL,
395 octave_H5P_DEFAULT, &ctmp)
396 >= 0)
397 {
398 retval = true;
399 scalar = ctmp;
400 }
401
402 H5Tclose (complex_type);
403 H5Sclose (space_id);
404 H5Dclose (data_hid);
405
406#else
407 octave_unused_parameter (loc_id);
408 octave_unused_parameter (name);
409
410 warn_load ("hdf5");
411#endif
412
413 return retval;
414}
415
416mxArray *
417octave_float_complex::as_mxArray (bool interleaved) const
418{
419 mxArray *retval = new mxArray (interleaved, mxSINGLE_CLASS, 1, 1, mxCOMPLEX);
420
421 if (interleaved)
422 {
423 mxComplexSingle *pd
424 = static_cast<mxComplexSingle *> (retval->get_data ());
425
426 pd[0].real = scalar.real ();
427 pd[0].imag = scalar.imag ();
428 }
429 else
430 {
431 mxSingle *pr = static_cast<mxSingle *> (retval->get_data ());
432 mxSingle *pi = static_cast<mxSingle *> (retval->get_imag_data ());
433
434 pr[0] = scalar.real ();
435 pi[0] = scalar.imag ();
436 }
437
438 return retval;
439}
440
443{
444 switch (umap)
445 {
446#define SCALAR_MAPPER(UMAP, FCN) \
447 case umap_ ## UMAP: \
448 return octave_value (FCN (scalar))
449
453 SCALAR_MAPPER (angle, std::arg);
454 SCALAR_MAPPER (arg, std::arg);
466 SCALAR_MAPPER (cos, std::cos);
467 SCALAR_MAPPER (cosh, std::cosh);
468 SCALAR_MAPPER (exp, std::exp);
473 SCALAR_MAPPER (log, std::log);
475 SCALAR_MAPPER (log10, std::log10);
481 SCALAR_MAPPER (sin, std::sin);
482 SCALAR_MAPPER (sinh, std::sinh);
483 SCALAR_MAPPER (sqrt, std::sqrt);
484 SCALAR_MAPPER (tan, std::tan);
485 SCALAR_MAPPER (tanh, std::tanh);
490
491 // Special cases for Matlab compatibility
492 case umap_xtolower:
493 case umap_xtoupper:
494 return scalar;
495
496 default:
497 return octave_base_value::map (umap);
498 }
499}
ComplexColumnVector conj(const ComplexColumnVector &a)
Definition: CColVector.cc:217
Definition: dMatrix.h:42
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:335
void * get_data(void) const
Definition: mxarray.h:497
void * get_imag_data(void) const
Definition: mxarray.h:562
virtual octave_value map(unary_mapper_t) const
Definition: ov-base.cc:1176
OCTINTERP_API void warn_load(const char *type) const
Definition: ov-base.cc:1152
OCTINTERP_API void warn_save(const char *type) const
Definition: ov-base.cc:1161
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
bool load_ascii(std::istream &is)
FloatMatrix float_matrix_value(bool=false) const
bool save_ascii(std::ostream &os)
FloatComplexNDArray float_complex_array_value(bool=false) const
Complex complex_value(bool=false) const
NDArray array_value(bool=false) const
ComplexNDArray complex_array_value(bool=false) const
octave_value as_single(void) const
bool save_binary(std::ostream &os, bool save_as_floats)
octave_value map(unary_mapper_t umap) const
ComplexMatrix complex_matrix_value(bool=false) const
mxArray * as_mxArray(bool interleaved) const
octave_value as_double(void) const
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
octave_value diag(octave_idx_type m, octave_idx_type n) const
float float_value(bool=false) const
Matrix matrix_value(bool=false) const
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
double double_value(bool=false) const
FloatComplexMatrix float_complex_matrix_value(bool=false) const
FloatNDArray float_array_value(bool=false) const
octave_base_value * try_narrowing_conversion(void)
FloatComplex float_complex_value(bool=false) const
octave_value resize(const dim_vector &dv, bool fill=false) const
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
octave_value index_op(const octave_value_list &idx, bool resize_ok=false)
Definition: ov.h:550
const octave_hdf5_id octave_H5P_DEFAULT
const octave_hdf5_id octave_H5S_ALL
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:137
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:143
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:836
save_type
Definition: data-conv.h:87
@ LS_FLOAT
Definition: data-conv.h:94
void error(const char *fmt,...)
Definition: error.cc:980
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition: errwarn.cc:344
QString name
octave_hdf5_id hdf5_make_complex_type(octave_hdf5_id num_type)
Definition: ls-hdf5.cc:405
bool hdf5_types_compatible(octave_hdf5_id t1, octave_hdf5_id t2)
Definition: ls-hdf5.cc:269
void mxArray
Definition: mex.h:58
class OCTAVE_API NDArray
Definition: mx-fwd.h:38
class OCTAVE_API Matrix
Definition: mx-fwd.h:31
class OCTAVE_API ComplexMatrix
Definition: mx-fwd.h:32
class OCTAVE_API FloatComplexMatrix
Definition: mx-fwd.h:34
class OCTAVE_API FloatMatrix
Definition: mx-fwd.h:33
class OCTAVE_API ComplexNDArray
Definition: mx-fwd.h:39
class OCTAVE_API FloatComplexNDArray
Definition: mx-fwd.h:41
class OCTAVE_API FloatNDArray
Definition: mx-fwd.h:40
class OCTAVE_API FloatComplexDiagMatrix
Definition: mx-fwd.h:62
std::complex< double > erfi(std::complex< double > z, double relerr=0)
std::complex< double > erfc(std::complex< double > z, double relerr=0)
std::complex< double > erfcx(std::complex< double > z, double relerr=0)
std::complex< double > erf(std::complex< double > z, double relerr=0)
double fix(double x)
Definition: lo-mappers.h:118
Complex atan(const Complex &x)
Definition: lo-mappers.h:71
double signum(double x)
Definition: lo-mappers.h:229
double asinh(double x)
Definition: lo-specfun.h:58
bool isna(double x)
Definition: lo-mappers.cc:47
double atanh(double x)
Definition: lo-specfun.h:63
bool isfinite(double x)
Definition: lo-mappers.h:192
double roundb(double x)
Definition: lo-mappers.h:147
static const double pi
Definition: lo-specfun.cc:1995
bool isnan(bool)
Definition: lo-mappers.h:178
Complex log1p(const Complex &x)
Definition: lo-specfun.cc:1958
bool isinf(double x)
Definition: lo-mappers.h:203
Complex acos(const Complex &x)
Definition: lo-mappers.cc:85
double round(double x)
Definition: lo-mappers.h:136
Complex asin(const Complex &x)
Definition: lo-mappers.cc:107
double erfcx(double x)
Definition: lo-specfun.cc:1755
Complex erfc(const Complex &x)
Definition: lo-specfun.cc:1652
double acosh(double x)
Definition: lo-specfun.h:40
double erfi(double x)
Definition: lo-specfun.cc:1774
std::complex< T > ceil(const std::complex< T > &x)
Definition: lo-mappers.h:103
std::complex< T > floor(const std::complex< T > &x)
Definition: lo-mappers.h:130
double dawson(double x)
Definition: lo-specfun.cc:1517
Complex log2(const Complex &x)
Definition: lo-mappers.cc:139
Complex erf(const Complex &x)
Definition: lo-specfun.cc:1637
Complex expm1(const Complex &x)
Definition: lo-specfun.cc:1874
std::complex< double > Complex
Definition: oct-cmplx.h:33
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34
int64_t octave_hdf5_id
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:222
#define SCALAR_MAPPER(UMAP, FCN)
static T abs(T x)
Definition: pr-output.cc:1678