GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
ov-flt-complex.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1996-2025 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-flt-cx-mat.h"
44#include "ov-float.h"
45#include "ov-flt-complex.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
54 "float complex scalar", "single");
55
58{
59 octave_base_value *retval = nullptr;
60
61 float im = scalar.imag ();
62
63 if (im == 0.0)
64 retval = new octave_float_scalar (scalar.real ());
65
66 return retval;
67}
68
71{
72 // FIXME: this doesn't solve the problem of
73 //
74 // a = i; a([1,1], [1,1], [1,1])
75 //
76 // and similar constructions. Hmm...
77
78 // FIXME: using this constructor avoids narrowing the
79 // 1x1 matrix back to a scalar value. Need a better solution
80 // to this problem.
81
83
84 return tmp.index_op (idx, resize_ok);
85}
86
87double
88octave_float_complex::double_value (bool force_conversion) const
89{
90 if (! force_conversion)
91 warn_implicit_conversion ("Octave:imag-to-real",
92 "complex scalar", "real scalar");
93
94 return scalar.real ();
95}
96
97float
98octave_float_complex::float_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
107Matrix
108octave_float_complex::matrix_value (bool force_conversion) const
109{
110 Matrix retval;
111
112 if (! force_conversion)
113 warn_implicit_conversion ("Octave:imag-to-real",
114 "complex scalar", "real matrix");
115
116 retval = Matrix (1, 1, scalar.real ());
117
118 return retval;
119}
120
122octave_float_complex::float_matrix_value (bool force_conversion) const
123{
124 FloatMatrix retval;
125
126 if (! force_conversion)
127 warn_implicit_conversion ("Octave:imag-to-real",
128 "complex scalar", "real matrix");
129
130 retval = FloatMatrix (1, 1, scalar.real ());
131
132 return retval;
133}
134
136octave_float_complex::array_value (bool force_conversion) const
137{
138 NDArray retval;
139
140 if (! force_conversion)
141 warn_implicit_conversion ("Octave:imag-to-real",
142 "complex scalar", "real matrix");
143
144 retval = NDArray (dim_vector (1, 1), scalar.real ());
145
146 return retval;
147}
148
150octave_float_complex::float_array_value (bool force_conversion) const
151{
152 FloatNDArray retval;
153
154 if (! force_conversion)
155 warn_implicit_conversion ("Octave:imag-to-real",
156 "complex scalar", "real matrix");
157
158 retval = FloatNDArray (dim_vector (1, 1), scalar.real ());
159
160 return retval;
161}
162
165{
166 return scalar;
167}
168
171{
172 return static_cast<FloatComplex> (scalar);
173}
174
177{
178 return ComplexMatrix (1, 1, scalar);
179}
180
186
188octave_float_complex::complex_array_value (bool /* force_conversion */) const
189{
190 return ComplexNDArray (dim_vector (1, 1), scalar);
191}
192
194octave_float_complex::float_complex_array_value (bool /* force_conversion */) const
195{
196 return FloatComplexNDArray (dim_vector (1, 1), scalar);
197}
198
200octave_float_complex::resize (const dim_vector& dv, bool fill) const
201{
202 if (fill)
203 {
204 FloatComplexNDArray retval (dv, FloatComplex (0));
205
206 if (dv.numel ())
207 retval(0) = scalar;
208
209 return retval;
210 }
211 else
212 {
213 FloatComplexNDArray retval (dv);
214
215 if (dv.numel ())
216 retval(0) = scalar;
217
218 return retval;
219 }
220}
221
224{
225 return Complex (scalar);
226}
227
230{
231 return scalar;
232}
233
241
242bool
244{
246
247 octave::write_value<FloatComplex> (os, c);
248
249 os << "\n";
250
251 return true;
252}
253
254bool
256{
257 scalar = octave::read_value<FloatComplex> (is);
258
259 if (! is)
260 error ("load: failed to load complex scalar constant");
261
262 return true;
263}
264
265bool
266octave_float_complex::save_binary (std::ostream& os, bool /* save_as_floats */)
267{
268 char tmp = static_cast<char> (LS_FLOAT);
269 os.write (reinterpret_cast<char *> (&tmp), 1);
271 os.write (reinterpret_cast<char *> (&ctmp), 8);
272
273 return true;
274}
275
276bool
277octave_float_complex::load_binary (std::istream& is, bool swap,
278 octave::mach_info::float_format fmt)
279{
280 char tmp;
281 if (! is.read (reinterpret_cast<char *> (&tmp), 1))
282 return false;
283
284 FloatComplex ctmp;
285 read_floats (is, reinterpret_cast<float *> (&ctmp),
286 static_cast<save_type> (tmp), 2, swap, fmt);
287
288 if (! is)
289 return false;
290
291 scalar = ctmp;
292 return true;
293}
294
295bool
297 bool /* save_as_floats */)
298{
299 bool retval = false;
300
301#if defined (HAVE_HDF5)
302
303 hsize_t dimens[3] = {0};
304 hid_t space_hid, type_hid, data_hid;
305 space_hid = type_hid = data_hid = -1;
306
307 space_hid = H5Screate_simple (0, dimens, nullptr);
308 if (space_hid < 0)
309 return false;
310
311 type_hid = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
312 if (type_hid < 0)
313 {
314 H5Sclose (space_hid);
315 return false;
316 }
317#if defined (HAVE_HDF5_18)
318 data_hid = H5Dcreate (loc_id, name, type_hid, space_hid,
321#else
322 data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, octave_H5P_DEFAULT);
323#endif
324 if (data_hid < 0)
325 {
326 H5Sclose (space_hid);
327 H5Tclose (type_hid);
328 return false;
329 }
330
332 retval = H5Dwrite (data_hid, type_hid, octave_H5S_ALL, octave_H5S_ALL,
333 octave_H5P_DEFAULT, &tmp) >= 0;
334
335 H5Dclose (data_hid);
336 H5Tclose (type_hid);
337 H5Sclose (space_hid);
338
339#else
340 octave_unused_parameter (loc_id);
341 octave_unused_parameter (name);
342
343 warn_save ("hdf5");
344#endif
345
346 return retval;
347}
348
349bool
351{
352 bool retval = false;
353
354#if defined (HAVE_HDF5)
355
356#if defined (HAVE_HDF5_18)
357 hid_t data_hid = H5Dopen (loc_id, name, octave_H5P_DEFAULT);
358#else
359 hid_t data_hid = H5Dopen (loc_id, name);
360#endif
361 hid_t type_hid = H5Dget_type (data_hid);
362
363 hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_FLOAT);
364
365 if (! hdf5_types_compatible (type_hid, complex_type))
366 {
367 H5Tclose (complex_type);
368 H5Dclose (data_hid);
369 return false;
370 }
371
372 hid_t space_id = H5Dget_space (data_hid);
373 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
374
375 if (rank != 0)
376 {
377 H5Tclose (complex_type);
378 H5Sclose (space_id);
379 H5Dclose (data_hid);
380 return false;
381 }
382
383 // complex scalar:
384 FloatComplex ctmp;
385 if (H5Dread (data_hid, complex_type, octave_H5S_ALL, octave_H5S_ALL,
386 octave_H5P_DEFAULT, &ctmp)
387 >= 0)
388 {
389 retval = true;
390 scalar = ctmp;
391 }
392
393 H5Tclose (complex_type);
394 H5Sclose (space_id);
395 H5Dclose (data_hid);
396
397#else
398 octave_unused_parameter (loc_id);
399 octave_unused_parameter (name);
400
401 warn_load ("hdf5");
402#endif
403
404 return retval;
405}
406
407mxArray *
408octave_float_complex::as_mxArray (bool interleaved) const
409{
410 mxArray *retval = new mxArray (interleaved, mxSINGLE_CLASS, 1, 1, mxCOMPLEX);
411
412 if (interleaved)
413 {
414 mxComplexSingle *pd
415 = static_cast<mxComplexSingle *> (retval->get_data ());
416
417 pd[0].real = scalar.real ();
418 pd[0].imag = scalar.imag ();
419 }
420 else
421 {
422 mxSingle *pr = static_cast<mxSingle *> (retval->get_data ());
423 mxSingle *pi = static_cast<mxSingle *> (retval->get_imag_data ());
424
425 pr[0] = scalar.real ();
426 pi[0] = scalar.imag ();
427 }
428
429 return retval;
430}
431
434{
435 switch (umap)
436 {
437#define SCALAR_MAPPER(UMAP, FCN) \
438 case umap_ ## UMAP: \
439 return octave_value (FCN (scalar))
440
441 SCALAR_MAPPER (abs, std::abs);
442 SCALAR_MAPPER (acos, octave::math::acos);
443 SCALAR_MAPPER (acosh, octave::math::acosh);
444 SCALAR_MAPPER (angle, std::arg);
445 SCALAR_MAPPER (arg, std::arg);
446 SCALAR_MAPPER (asin, octave::math::asin);
447 SCALAR_MAPPER (asinh, octave::math::asinh);
448 SCALAR_MAPPER (atan, octave::math::atan);
449 SCALAR_MAPPER (atanh, octave::math::atanh);
450 SCALAR_MAPPER (erf, octave::math::erf);
451 SCALAR_MAPPER (erfc, octave::math::erfc);
452 SCALAR_MAPPER (erfcx, octave::math::erfcx);
453 SCALAR_MAPPER (erfi, octave::math::erfi);
454 SCALAR_MAPPER (dawson, octave::math::dawson);
455 SCALAR_MAPPER (ceil, octave::math::ceil);
456 SCALAR_MAPPER (conj, std::conj);
457 SCALAR_MAPPER (cos, std::cos);
458 SCALAR_MAPPER (cosh, std::cosh);
459 SCALAR_MAPPER (exp, std::exp);
460 SCALAR_MAPPER (expm1, octave::math::expm1);
461 SCALAR_MAPPER (fix, octave::math::fix);
462 SCALAR_MAPPER (floor, octave::math::floor);
463 SCALAR_MAPPER (imag, std::imag);
464 SCALAR_MAPPER (log, std::log);
465 SCALAR_MAPPER (log2, octave::math::log2);
466 SCALAR_MAPPER (log10, std::log10);
467 SCALAR_MAPPER (log1p, octave::math::log1p);
468 SCALAR_MAPPER (real, std::real);
469 SCALAR_MAPPER (round, octave::math::round);
470 SCALAR_MAPPER (roundb, octave::math::roundb);
471 SCALAR_MAPPER (signum, octave::math::signum);
472 SCALAR_MAPPER (sin, std::sin);
473 SCALAR_MAPPER (sinh, std::sinh);
474 SCALAR_MAPPER (sqrt, std::sqrt);
475 SCALAR_MAPPER (tan, std::tan);
476 SCALAR_MAPPER (tanh, std::tanh);
477 SCALAR_MAPPER (isfinite, octave::math::isfinite);
478 SCALAR_MAPPER (isinf, octave::math::isinf);
479 SCALAR_MAPPER (isna, octave::math::isna);
480 SCALAR_MAPPER (isnan, octave::math::isnan);
481
482 // Special cases for Matlab compatibility
483 case umap_xtolower:
484 case umap_xtoupper:
485 return scalar;
486
487 default:
488 return octave_base_value::map (umap);
489 }
490}
ComplexColumnVector conj(const ComplexColumnVector &a)
N Dimensional Array with copy-on-write semantics.
Definition Array.h:130
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition dim-vector.h:331
void * get_data() const
Definition mxarray.h:482
void * get_imag_data() const
Definition mxarray.h:520
virtual octave_value map(unary_mapper_t) const
Definition ov-base.cc:1170
void warn_load(const char *type) const
Definition ov-base.cc:1152
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
octave_value as_double() 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
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
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
octave_value as_single() const
FloatNDArray float_array_value(bool=false) const
octave_base_value * try_narrowing_conversion()
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:504
const octave_hdf5_id octave_H5P_DEFAULT
const octave_hdf5_id octave_H5S_ALL
ColumnVector real(const ComplexColumnVector &a)
ColumnVector imag(const ComplexColumnVector &a)
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:862
save_type
Definition data-conv.h:85
@ LS_FLOAT
Definition data-conv.h:92
void error(const char *fmt,...)
Definition error.cc:1003
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition errwarn.cc:344
Complex log2(const Complex &x)
Complex asin(const Complex &x)
bool isna(double x)
Definition lo-mappers.cc:47
Complex acos(const Complex &x)
Definition lo-mappers.cc:85
std::complex< T > ceil(const std::complex< T > &x)
Definition lo-mappers.h:103
Complex atan(const Complex &x)
Definition lo-mappers.h:71
double roundb(double x)
Definition lo-mappers.h:147
std::complex< T > floor(const std::complex< T > &x)
Definition lo-mappers.h:130
bool isfinite(double x)
Definition lo-mappers.h:192
bool isinf(double x)
Definition lo-mappers.h:203
double signum(double x)
Definition lo-mappers.h:229
double round(double x)
Definition lo-mappers.h:136
bool isnan(bool)
Definition lo-mappers.h:178
double fix(double x)
Definition lo-mappers.h:118
double erfi(double x)
double dawson(double x)
Complex erf(const Complex &x)
double erfcx(double x)
Complex expm1(const Complex &x)
Complex log1p(const Complex &x)
Complex erfc(const Complex &x)
double asinh(double x)
Definition lo-specfun.h:58
double atanh(double x)
Definition lo-specfun.h:63
double acosh(double x)
Definition lo-specfun.h:40
octave_hdf5_id hdf5_make_complex_type(octave_hdf5_id num_type)
Definition ls-hdf5.cc:410
bool hdf5_types_compatible(octave_hdf5_id t1, octave_hdf5_id t2)
Definition ls-hdf5.cc:274
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:246
#define SCALAR_MAPPER(UMAP, FCN)
template int8_t abs(int8_t)