GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
ov-scalar.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 "oct-inttypes-fwd.h"
34
35#include "data-conv.h"
36#include "mach-info.h"
37#include "lo-specfun.h"
38#include "lo-mappers.h"
39
40#include "defun.h"
41#include "errwarn.h"
42#include "mxarray.h"
43#include "ovl.h"
44#include "oct-hdf5.h"
45#include "oct-stream.h"
46#include "ov-scalar.h"
47#include "ov-float.h"
48#include "ov-base.h"
49#include "ov-re-mat.h"
50#include "ov-typeinfo.h"
51#include "pr-output.h"
52#include "xdiv.h"
53#include "xpow.h"
54#include "ops.h"
55#include "ov-inline.h"
56
57#include "ls-oct-text.h"
58#include "ls-hdf5.h"
59
61
62static octave_base_value *
63default_numeric_demotion_function (const octave_base_value& a)
64{
65 const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
66
67 return new octave_float_scalar (v.float_value ());
68}
69
72{
74 (default_numeric_demotion_function,
76}
77
80{
81 // FIXME: this doesn't solve the problem of
82 //
83 // a = 1; a([1,1], [1,1], [1,1])
84 //
85 // and similar constructions. Hmm...
86
87 // FIXME: using this constructor avoids narrowing the
88 // 1x1 matrix back to a scalar value. Need a better solution
89 // to this problem.
90
92
93 return tmp.index_op (idx, resize_ok);
94}
95
97octave_scalar::resize (const dim_vector& dv, bool fill) const
98{
99 if (fill)
100 {
101 NDArray retval (dv, 0);
102
103 if (dv.numel ())
104 retval(0) = scalar;
105
106 return retval;
107 }
108 else
109 {
110 NDArray retval (dv);
111
112 if (dv.numel ())
113 retval(0) = scalar;
114
115 return retval;
116 }
117}
118
124
127{
128 return scalar;
129}
130
133{
134 return static_cast<float> (scalar);
135}
136
139{
140 return octave_int8 (scalar);
141}
142
145{
146 return octave_int16 (scalar);
147}
148
151{
152 return octave_int32 (scalar);
153}
154
157{
158 return octave_int64 (scalar);
159}
160
163{
164 return octave_uint8 (scalar);
165}
166
169{
170 return octave_uint16 (scalar);
171}
172
175{
176 return octave_uint32 (scalar);
177}
178
181{
182 return octave_uint64 (scalar);
183}
184
190
192octave_scalar::convert_to_str_internal (bool, bool, char type) const
193{
194 octave_value retval;
195
196 if (octave::math::isnan (scalar))
197 octave::err_nan_to_character_conversion ();
198
199 int ival = octave::math::nint (scalar);
200
201 if (ival < 0 || ival > std::numeric_limits<unsigned char>::max ())
202 {
203 // FIXME: is there something better we could do?
204
205 ival = 0;
206
207 ::warning ("range error for conversion to character value");
208 }
209
210 retval = octave_value (std::string (1, static_cast<char> (ival)), type);
211
212 return retval;
213}
214
215bool
217{
218 double d = double_value ();
219
220 octave::write_value<double> (os, d);
221
222 os << "\n";
223
224 return true;
225}
226
227bool
229{
230 scalar = octave::read_value<double> (is);
231
232 if (! is)
233 error ("load: failed to load scalar constant");
234
235 return true;
236}
237
238bool
239octave_scalar::save_binary (std::ostream& os, bool /* save_as_floats */)
240{
241 char tmp = LS_DOUBLE;
242 os.write (reinterpret_cast<char *> (&tmp), 1);
243 double dtmp = double_value ();
244 os.write (reinterpret_cast<char *> (&dtmp), 8);
245
246 return true;
247}
248
249bool
250octave_scalar::load_binary (std::istream& is, bool swap,
251 octave::mach_info::float_format fmt)
252{
253 char tmp;
254 if (! is.read (reinterpret_cast<char *> (&tmp), 1))
255 return false;
256
257 double dtmp;
258 read_doubles (is, &dtmp, static_cast<save_type> (tmp), 1, swap, fmt);
259
260 if (! is)
261 return false;
262
263 scalar = dtmp;
264 return true;
265}
266
267bool
268octave_scalar::save_hdf5 (octave_hdf5_id loc_id, const char *name,
269 bool /* save_as_floats */)
270{
271 bool retval = false;
272
273#if defined (HAVE_HDF5)
274
275 hsize_t dimens[3] = {0};
276 hid_t space_hid, data_hid;
277 space_hid = data_hid = -1;
278
279 space_hid = H5Screate_simple (0, dimens, nullptr);
280 if (space_hid < 0) return false;
281
282#if defined (HAVE_HDF5_18)
283 data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_DOUBLE, space_hid,
286#else
287 data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_DOUBLE, space_hid,
289#endif
290 if (data_hid < 0)
291 {
292 H5Sclose (space_hid);
293 return false;
294 }
295
296 double tmp = double_value ();
297 retval = H5Dwrite (data_hid, H5T_NATIVE_DOUBLE, octave_H5S_ALL,
299
300 H5Dclose (data_hid);
301 H5Sclose (space_hid);
302
303#else
304 octave_unused_parameter (loc_id);
305 octave_unused_parameter (name);
306
307 warn_save ("hdf5");
308#endif
309
310 return retval;
311}
312
313bool
314octave_scalar::load_hdf5 (octave_hdf5_id loc_id, const char *name)
315{
316#if defined (HAVE_HDF5)
317
318#if defined (HAVE_HDF5_18)
319 hid_t data_hid = H5Dopen (loc_id, name, octave_H5P_DEFAULT);
320#else
321 hid_t data_hid = H5Dopen (loc_id, name);
322#endif
323 hid_t space_id = H5Dget_space (data_hid);
324
325 hsize_t rank = H5Sget_simple_extent_ndims (space_id);
326
327 if (rank != 0)
328 {
329 H5Dclose (data_hid);
330 return false;
331 }
332
333 double dtmp;
334 if (H5Dread (data_hid, H5T_NATIVE_DOUBLE, octave_H5S_ALL, octave_H5S_ALL,
335 octave_H5P_DEFAULT, &dtmp) < 0)
336 {
337 H5Dclose (data_hid);
338 return false;
339 }
340
341 scalar = dtmp;
342
343 H5Dclose (data_hid);
344
345 return true;
346
347#else
348 octave_unused_parameter (loc_id);
349 octave_unused_parameter (name);
350
351 warn_load ("hdf5");
352
353 return false;
354#endif
355}
356
357mxArray *
358octave_scalar::as_mxArray (bool interleaved) const
359{
360 mxArray *retval = new mxArray (interleaved, mxDOUBLE_CLASS, 1, 1, mxREAL);
361
362 mxDouble *pd = static_cast<mxDouble *> (retval->get_data ());
363
364 pd[0] = scalar;
365
366 return retval;
367}
368
371{
372 switch (umap)
373 {
374 case umap_imag:
375 return 0.0;
376
377 case umap_real:
378 case umap_conj:
379 return scalar;
380
381#define SCALAR_MAPPER(UMAP, FCN) \
382 case umap_ ## UMAP: \
383 return octave_value (FCN (scalar))
384
385 SCALAR_MAPPER (abs, ::fabs);
386 SCALAR_MAPPER (acos, octave::math::rc_acos);
387 SCALAR_MAPPER (acosh, octave::math::rc_acosh);
388 SCALAR_MAPPER (angle, std::arg);
389 SCALAR_MAPPER (arg, std::arg);
390 SCALAR_MAPPER (asin, octave::math::rc_asin);
391 SCALAR_MAPPER (asinh, octave::math::asinh);
393 SCALAR_MAPPER (atanh, octave::math::rc_atanh);
394 SCALAR_MAPPER (erf, octave::math::erf);
395 SCALAR_MAPPER (erfinv, octave::math::erfinv);
396 SCALAR_MAPPER (erfcinv, octave::math::erfcinv);
397 SCALAR_MAPPER (erfc, octave::math::erfc);
398 SCALAR_MAPPER (erfcx, octave::math::erfcx);
399 SCALAR_MAPPER (erfi, octave::math::erfi);
400 SCALAR_MAPPER (dawson, octave::math::dawson);
401 SCALAR_MAPPER (gamma, octave::math::gamma);
402 SCALAR_MAPPER (lgamma, octave::math::rc_lgamma);
403 SCALAR_MAPPER (cbrt, octave::math::cbrt);
405 SCALAR_MAPPER (cos, ::cos);
406 SCALAR_MAPPER (cosh, ::cosh);
407 SCALAR_MAPPER (exp, ::exp);
408 SCALAR_MAPPER (expm1, octave::math::expm1);
409 SCALAR_MAPPER (fix, octave::math::fix);
410 SCALAR_MAPPER (floor, std::floor);
411 SCALAR_MAPPER (log, octave::math::rc_log);
412 SCALAR_MAPPER (log2, octave::math::rc_log2);
413 SCALAR_MAPPER (log10, octave::math::rc_log10);
414 SCALAR_MAPPER (log1p, octave::math::rc_log1p);
415 SCALAR_MAPPER (round, octave::math::round);
416 SCALAR_MAPPER (roundb, octave::math::roundb);
417 SCALAR_MAPPER (signum, octave::math::signum);
418 SCALAR_MAPPER (sin, ::sin);
419 SCALAR_MAPPER (sinh, ::sinh);
420 SCALAR_MAPPER (sqrt, octave::math::rc_sqrt);
421 SCALAR_MAPPER (tan, ::tan);
422 SCALAR_MAPPER (tanh, ::tanh);
423 SCALAR_MAPPER (isfinite, octave::math::isfinite);
424 SCALAR_MAPPER (isinf, octave::math::isinf);
425 SCALAR_MAPPER (isna, octave::math::isna);
426 SCALAR_MAPPER (isnan, octave::math::isnan);
427 SCALAR_MAPPER (xsignbit, octave::math::signbit);
428
429 // Special cases for Matlab compatibility.
430 case umap_xtolower:
431 case umap_xtoupper:
432 return scalar;
433
434 case umap_xisalnum:
435 case umap_xisalpha:
436 case umap_xisascii:
437 case umap_xiscntrl:
438 case umap_xisdigit:
439 case umap_xisgraph:
440 case umap_xislower:
441 case umap_xisprint:
442 case umap_xispunct:
443 case umap_xisspace:
444 case umap_xisupper:
445 case umap_xisxdigit:
446 {
447 octave_value str_conv = convert_to_str (true, true);
448 return str_conv.map (umap);
449 }
450
451 default:
452 return octave_base_value::map (umap);
453 }
454}
455
456bool
458{
459
460 // Support inline real->complex conversion.
461 if (btyp == btyp_double)
462 {
463 *(reinterpret_cast<double *> (where)) = scalar;
464 return true;
465 }
466 else if (btyp == btyp_complex)
467 {
468 *(reinterpret_cast<Complex *> (where)) = scalar;
469 return true;
470 }
471 else
472 return false;
473}
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
virtual octave_value map(unary_mapper_t) const
Definition ov-base.cc:1170
virtual octave_value convert_to_str(bool pad=false, bool force=false, char type='\'') const
Definition ov-base.cc:431
void warn_load(const char *type) const
Definition ov-base.cc:1152
friend class octave_value
Definition ov-base.h:278
void warn_save(const char *type) const
Definition ov-base.cc:1161
static int static_type_id()
Definition ov-float.h:277
octave_value map(unary_mapper_t umap) const
Definition ov-scalar.cc:370
octave_value as_int64() const
Definition ov-scalar.cc:156
type_conv_info numeric_demotion_function() const
Definition ov-scalar.cc:71
octave_value as_int8() const
Definition ov-scalar.cc:138
bool fast_elem_insert_self(void *where, builtin_type_t btyp) const
Definition ov-scalar.cc:457
octave_value as_uint16() const
Definition ov-scalar.cc:168
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
Definition ov-scalar.cc:314
octave_value as_uint64() const
Definition ov-scalar.cc:180
bool load_ascii(std::istream &is)
Definition ov-scalar.cc:228
octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition ov-scalar.cc:79
octave_value as_uint32() const
Definition ov-scalar.cc:174
octave_value convert_to_str_internal(bool pad, bool force, char type) const
Definition ov-scalar.cc:192
octave_value as_double() const
Definition ov-scalar.cc:126
double double_value(bool=false) const
Definition ov-scalar.h:146
octave_value as_single() const
Definition ov-scalar.cc:132
bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
Definition ov-scalar.cc:268
bool save_ascii(std::ostream &os)
Definition ov-scalar.cc:216
octave_value as_uint8() const
Definition ov-scalar.cc:162
octave_value diag(octave_idx_type m, octave_idx_type n) const
Definition ov-scalar.cc:186
octave_value as_double_or_copy()
Definition ov-scalar.cc:120
float float_value(bool=false) const
Definition ov-scalar.h:148
Matrix matrix_value(bool=false) const
Definition ov-scalar.h:156
bool save_binary(std::ostream &os, bool save_as_floats)
Definition ov-scalar.cc:239
octave_value as_int16() const
Definition ov-scalar.cc:144
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
Definition ov-scalar.cc:250
mxArray * as_mxArray(bool interleaved) const
Definition ov-scalar.cc:358
octave_value resize(const dim_vector &dv, bool fill=false) const
Definition ov-scalar.cc:97
octave_value as_int32() const
Definition ov-scalar.cc:150
static octave_value make_copy(octave_base_value *rep)
Definition ov-inline.h:129
octave_value index_op(const octave_value_list &idx, bool resize_ok=false)
Definition ov.h:504
octave_value map(octave_base_value::unary_mapper_t umap) const
Definition ov.h:1528
const octave_hdf5_id octave_H5P_DEFAULT
const octave_hdf5_id octave_H5S_ALL
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:802
save_type
Definition data-conv.h:85
@ LS_DOUBLE
Definition data-conv.h:93
void warning(const char *fmt,...)
Definition error.cc:1078
void error(const char *fmt,...)
Definition error.cc:1003
function gamma(x)
Definition gamma.f:3
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
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
double erfinv(double x)
double erfi(double x)
double dawson(double x)
Complex erf(const Complex &x)
double erfcinv(double x)
double erfcx(double x)
Complex expm1(const Complex &x)
Complex log1p(const Complex &x)
Complex erfc(const Complex &x)
double cbrt(double x)
Definition lo-specfun.h:289
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
double lgamma(double x)
Definition lo-specfun.h:336
std::complex< double > Complex
Definition oct-cmplx.h:33
int64_t octave_hdf5_id
octave_int< uint32_t > octave_uint32
octave_int< int32_t > octave_int32
octave_int< int16_t > octave_int16
octave_int< int8_t > octave_int8
octave_int< int64_t > octave_int64
octave_int< uint64_t > octave_uint64
octave_int< uint16_t > octave_uint16
octave_int< uint8_t > octave_uint8
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition ov-base.h:246
builtin_type_t
Definition ov-base.h:83
@ btyp_double
Definition ov-base.h:84
@ btyp_complex
Definition ov-base.h:86
#define SCALAR_MAPPER(UMAP, FCN)
template int8_t abs(int8_t)