File: | libinterp/octave-value/ov-complex.cc |
Location: | line 122, column 9 |
Description: | Value stored to 'retval' during its initialization is never read |
1 | /* |
2 | |
3 | Copyright (C) 1996-2013 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 | #ifdef HAVE_CONFIG_H1 |
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 "oct-obj.h" |
35 | #include "oct-stream.h" |
36 | #include "ops.h" |
37 | #include "ov-complex.h" |
38 | #include "ov-flt-complex.h" |
39 | #include "ov-base.h" |
40 | #include "ov-base-scalar.h" |
41 | #include "ov-base-scalar.cc" |
42 | #include "ov-cx-mat.h" |
43 | #include "ov-scalar.h" |
44 | #include "gripes.h" |
45 | #include "pr-output.h" |
46 | #include "ops.h" |
47 | |
48 | #include "ls-oct-ascii.h" |
49 | #include "ls-hdf5.h" |
50 | |
51 | template class octave_base_scalar<Complex>; |
52 | |
53 | DEFINE_OCTAVE_ALLOCATOR (octave_complex); |
54 | |
55 | DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex,int octave_complex::t_id (-1); const std::string octave_complex ::t_name ("complex scalar"); const std::string octave_complex ::c_name ("double"); void octave_complex::register_type (void ) { static octave_complex exemplar; octave_value v (&exemplar , true); t_id = octave_value_typeinfo::register_type (octave_complex ::t_name, octave_complex::c_name, v); } |
56 | "complex scalar", "double")int octave_complex::t_id (-1); const std::string octave_complex ::t_name ("complex scalar"); const std::string octave_complex ::c_name ("double"); void octave_complex::register_type (void ) { static octave_complex exemplar; octave_value v (&exemplar , true); t_id = octave_value_typeinfo::register_type (octave_complex ::t_name, octave_complex::c_name, v); }; |
57 | |
58 | static octave_base_value * |
59 | default_numeric_demotion_function (const octave_base_value& a) |
60 | { |
61 | CAST_CONV_ARG (const octave_complex&)const octave_complex& v = dynamic_cast<const octave_complex &> (a); |
62 | |
63 | return new octave_float_complex (v.float_complex_value ()); |
64 | } |
65 | |
66 | octave_base_value::type_conv_info |
67 | octave_complex::numeric_demotion_function (void) const |
68 | { |
69 | return |
70 | octave_base_value::type_conv_info (default_numeric_demotion_function, |
71 | octave_float_complex::static_type_id ()); |
72 | } |
73 | |
74 | octave_base_value * |
75 | octave_complex::try_narrowing_conversion (void) |
76 | { |
77 | octave_base_value *retval = 0; |
78 | |
79 | double im = std::imag (scalar); |
80 | |
81 | if (im == 0.0) |
82 | retval = new octave_scalar (std::real (scalar)); |
83 | |
84 | return retval; |
85 | } |
86 | |
87 | octave_value |
88 | octave_complex::do_index_op (const octave_value_list& idx, bool resize_ok) |
89 | { |
90 | // FIXME: this doesn't solve the problem of |
91 | // |
92 | // a = i; a([1,1], [1,1], [1,1]) |
93 | // |
94 | // and similar constructions. Hmm... |
95 | |
96 | // FIXME: using this constructor avoids narrowing the |
97 | // 1x1 matrix back to a scalar value. Need a better solution |
98 | // to this problem. |
99 | |
100 | octave_value tmp (new octave_complex_matrix (complex_matrix_value ())); |
101 | |
102 | return tmp.do_index_op (idx, resize_ok); |
103 | } |
104 | |
105 | double |
106 | octave_complex::double_value (bool force_conversion) const |
107 | { |
108 | double retval = lo_ieee_nan_value (); |
109 | |
110 | if (! force_conversion) |
111 | gripe_implicit_conversion ("Octave:imag-to-real", |
112 | "complex scalar", "real scalar"); |
113 | |
114 | retval = std::real (scalar); |
115 | |
116 | return retval; |
117 | } |
118 | |
119 | float |
120 | octave_complex::float_value (bool force_conversion) const |
121 | { |
122 | float retval = lo_ieee_float_nan_value (); |
Value stored to 'retval' during its initialization is never read | |
123 | |
124 | if (! force_conversion) |
125 | gripe_implicit_conversion ("Octave:imag-to-real", |
126 | "complex scalar", "real scalar"); |
127 | |
128 | retval = std::real (scalar); |
129 | |
130 | return retval; |
131 | } |
132 | |
133 | Matrix |
134 | octave_complex::matrix_value (bool force_conversion) const |
135 | { |
136 | Matrix retval; |
137 | |
138 | if (! force_conversion) |
139 | gripe_implicit_conversion ("Octave:imag-to-real", |
140 | "complex scalar", "real matrix"); |
141 | |
142 | retval = Matrix (1, 1, std::real (scalar)); |
143 | |
144 | return retval; |
145 | } |
146 | |
147 | FloatMatrix |
148 | octave_complex::float_matrix_value (bool force_conversion) const |
149 | { |
150 | FloatMatrix retval; |
151 | |
152 | if (! force_conversion) |
153 | gripe_implicit_conversion ("Octave:imag-to-real", |
154 | "complex scalar", "real matrix"); |
155 | |
156 | retval = FloatMatrix (1, 1, std::real (scalar)); |
157 | |
158 | return retval; |
159 | } |
160 | |
161 | NDArray |
162 | octave_complex::array_value (bool force_conversion) const |
163 | { |
164 | NDArray retval; |
165 | |
166 | if (! force_conversion) |
167 | gripe_implicit_conversion ("Octave:imag-to-real", |
168 | "complex scalar", "real matrix"); |
169 | |
170 | retval = NDArray (dim_vector (1, 1), std::real (scalar)); |
171 | |
172 | return retval; |
173 | } |
174 | |
175 | FloatNDArray |
176 | octave_complex::float_array_value (bool force_conversion) const |
177 | { |
178 | FloatNDArray retval; |
179 | |
180 | if (! force_conversion) |
181 | gripe_implicit_conversion ("Octave:imag-to-real", |
182 | "complex scalar", "real matrix"); |
183 | |
184 | retval = FloatNDArray (dim_vector (1, 1), std::real (scalar)); |
185 | |
186 | return retval; |
187 | } |
188 | |
189 | Complex |
190 | octave_complex::complex_value (bool) const |
191 | { |
192 | return scalar; |
193 | } |
194 | |
195 | FloatComplex |
196 | octave_complex::float_complex_value (bool) const |
197 | { |
198 | return static_cast<FloatComplex> (scalar); |
199 | } |
200 | |
201 | ComplexMatrix |
202 | octave_complex::complex_matrix_value (bool) const |
203 | { |
204 | return ComplexMatrix (1, 1, scalar); |
205 | } |
206 | |
207 | FloatComplexMatrix |
208 | octave_complex::float_complex_matrix_value (bool) const |
209 | { |
210 | return FloatComplexMatrix (1, 1, static_cast<FloatComplex> (scalar)); |
211 | } |
212 | |
213 | ComplexNDArray |
214 | octave_complex::complex_array_value (bool /* force_conversion */) const |
215 | { |
216 | return ComplexNDArray (dim_vector (1, 1), scalar); |
217 | } |
218 | |
219 | FloatComplexNDArray |
220 | octave_complex::float_complex_array_value (bool /* force_conversion */) const |
221 | { |
222 | return FloatComplexNDArray (dim_vector (1, 1), |
223 | static_cast<FloatComplex> (scalar)); |
224 | } |
225 | |
226 | octave_value |
227 | octave_complex::resize (const dim_vector& dv, bool fill) const |
228 | { |
229 | if (fill) |
230 | { |
231 | ComplexNDArray retval (dv, Complex (0)); |
232 | |
233 | if (dv.numel ()) |
234 | retval(0) = scalar; |
235 | |
236 | return retval; |
237 | } |
238 | else |
239 | { |
240 | ComplexNDArray retval (dv); |
241 | |
242 | if (dv.numel ()) |
243 | retval(0) = scalar; |
244 | |
245 | return retval; |
246 | } |
247 | } |
248 | |
249 | octave_value |
250 | octave_complex::diag (octave_idx_type m, octave_idx_type n) const |
251 | { |
252 | return ComplexDiagMatrix (Array<Complex> (dim_vector (1, 1), scalar), m, n); |
253 | } |
254 | |
255 | bool |
256 | octave_complex::save_ascii (std::ostream& os) |
257 | { |
258 | Complex c = complex_value (); |
259 | |
260 | octave_write_complex (os, c); |
261 | |
262 | os << "\n"; |
263 | |
264 | return true; |
265 | } |
266 | |
267 | bool |
268 | octave_complex::load_ascii (std::istream& is) |
269 | { |
270 | scalar = octave_read_value<Complex> (is); |
271 | |
272 | if (!is) |
273 | { |
274 | error ("load: failed to load complex scalar constant"); |
275 | return false; |
276 | } |
277 | |
278 | return true; |
279 | } |
280 | |
281 | |
282 | bool |
283 | octave_complex::save_binary (std::ostream& os, bool& /* save_as_floats */) |
284 | { |
285 | char tmp = static_cast<char> (LS_DOUBLE); |
286 | os.write (reinterpret_cast<char *> (&tmp), 1); |
287 | Complex ctmp = complex_value (); |
288 | os.write (reinterpret_cast<char *> (&ctmp), 16); |
289 | |
290 | return true; |
291 | } |
292 | |
293 | bool |
294 | octave_complex::load_binary (std::istream& is, bool swap, |
295 | oct_mach_info::float_format fmt) |
296 | { |
297 | char tmp; |
298 | if (! is.read (reinterpret_cast<char *> (&tmp), 1)) |
299 | return false; |
300 | |
301 | Complex ctmp; |
302 | read_doubles (is, reinterpret_cast<double *> (&ctmp), |
303 | static_cast<save_type> (tmp), 2, swap, fmt); |
304 | if (error_state || ! is) |
305 | return false; |
306 | |
307 | scalar = ctmp; |
308 | return true; |
309 | } |
310 | |
311 | #if defined (HAVE_HDF51) |
312 | |
313 | bool |
314 | octave_complex::save_hdf5 (hid_t loc_id, const char *name, |
315 | bool /* save_as_floats */) |
316 | { |
317 | hsize_t dimens[3]; |
318 | hid_t space_hid = -1, type_hid = -1, data_hid = -1; |
319 | bool retval = true; |
320 | |
321 | space_hid = H5Screate_simple (0, dimens, 0); |
322 | if (space_hid < 0) |
323 | return false; |
324 | |
325 | type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE(H5open(), H5T_NATIVE_DOUBLE_g)); |
326 | if (type_hid < 0) |
327 | { |
328 | H5Sclose (space_hid); |
329 | return false; |
330 | } |
331 | #if HAVE_HDF5_181 |
332 | data_hid = H5DcreateH5Dcreate2 (loc_id, name, type_hid, space_hid, |
333 | H5P_DEFAULT0, H5P_DEFAULT0, H5P_DEFAULT0); |
334 | #else |
335 | data_hid = H5DcreateH5Dcreate2 (loc_id, name, type_hid, space_hid, H5P_DEFAULT0); |
336 | #endif |
337 | if (data_hid < 0) |
338 | { |
339 | H5Sclose (space_hid); |
340 | H5Tclose (type_hid); |
341 | return false; |
342 | } |
343 | |
344 | Complex tmp = complex_value (); |
345 | retval = H5Dwrite (data_hid, type_hid, H5S_ALL0, H5S_ALL0, H5P_DEFAULT0, |
346 | &tmp) >= 0; |
347 | |
348 | H5Dclose (data_hid); |
349 | H5Tclose (type_hid); |
350 | H5Sclose (space_hid); |
351 | |
352 | return retval; |
353 | } |
354 | |
355 | bool |
356 | octave_complex::load_hdf5 (hid_t loc_id, const char *name) |
357 | { |
358 | bool retval = false; |
359 | #if HAVE_HDF5_181 |
360 | hid_t data_hid = H5DopenH5Dopen2 (loc_id, name, H5P_DEFAULT0); |
361 | #else |
362 | hid_t data_hid = H5DopenH5Dopen2 (loc_id, name); |
363 | #endif |
364 | hid_t type_hid = H5Dget_type (data_hid); |
365 | |
366 | hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE(H5open(), H5T_NATIVE_DOUBLE_g)); |
367 | |
368 | if (! hdf5_types_compatible (type_hid, complex_type)) |
369 | { |
370 | H5Tclose (complex_type); |
371 | H5Dclose (data_hid); |
372 | return false; |
373 | } |
374 | |
375 | hid_t space_id = H5Dget_space (data_hid); |
376 | hsize_t rank = H5Sget_simple_extent_ndims (space_id); |
377 | |
378 | if (rank != 0) |
379 | { |
380 | H5Tclose (complex_type); |
381 | H5Sclose (space_id); |
382 | H5Dclose (data_hid); |
383 | return false; |
384 | } |
385 | |
386 | // complex scalar: |
387 | Complex ctmp; |
388 | if (H5Dread (data_hid, complex_type, H5S_ALL0, H5S_ALL0, H5P_DEFAULT0, |
389 | &ctmp) >= 0) |
390 | { |
391 | retval = true; |
392 | scalar = ctmp; |
393 | } |
394 | |
395 | H5Tclose (complex_type); |
396 | H5Sclose (space_id); |
397 | H5Dclose (data_hid); |
398 | |
399 | return retval; |
400 | } |
401 | |
402 | #endif |
403 | |
404 | mxArray * |
405 | octave_complex::as_mxArray (void) const |
406 | { |
407 | mxArray *retval = new mxArray (mxDOUBLE_CLASS, 1, 1, mxCOMPLEX); |
408 | |
409 | double *pr = static_cast<double *> (retval->get_data ()); |
410 | double *pi = static_cast<double *> (retval->get_imag_data ()); |
411 | |
412 | pr[0] = std::real (scalar); |
413 | pi[0] = std::imag (scalar); |
414 | |
415 | return retval; |
416 | } |
417 | |
418 | octave_value |
419 | octave_complex::map (unary_mapper_t umap) const |
420 | { |
421 | switch (umap) |
422 | { |
423 | #define SCALAR_MAPPER(UMAP, FCN)case umap_UMAP: return octave_value (FCN (scalar)) \ |
424 | case umap_ ## UMAP: \ |
425 | return octave_value (FCN (scalar)) |
426 | |
427 | SCALAR_MAPPER (abs, std::abs)case umap_abs: return octave_value (std::abs (scalar)); |
428 | SCALAR_MAPPER (acos, ::acos)case umap_acos: return octave_value (::acos (scalar)); |
429 | SCALAR_MAPPER (acosh, ::acosh)case umap_acosh: return octave_value (::acosh (scalar)); |
430 | SCALAR_MAPPER (angle, std::arg)case umap_angle: return octave_value (std::arg (scalar)); |
431 | SCALAR_MAPPER (arg, std::arg)case umap_arg: return octave_value (std::arg (scalar)); |
432 | SCALAR_MAPPER (asin, ::asin)case umap_asin: return octave_value (::asin (scalar)); |
433 | SCALAR_MAPPER (asinh, ::asinh)case umap_asinh: return octave_value (::asinh (scalar)); |
434 | SCALAR_MAPPER (atan, ::atan)case umap_atan: return octave_value (::atan (scalar)); |
435 | SCALAR_MAPPER (atanh, ::atanh)case umap_atanh: return octave_value (::atanh (scalar)); |
436 | SCALAR_MAPPER (erf, ::erf)case umap_erf: return octave_value (::erf (scalar)); |
437 | SCALAR_MAPPER (erfc, ::erfc)case umap_erfc: return octave_value (::erfc (scalar)); |
438 | SCALAR_MAPPER (erfcx, ::erfcx)case umap_erfcx: return octave_value (::erfcx (scalar)); |
439 | SCALAR_MAPPER (erfi, ::erfi)case umap_erfi: return octave_value (::erfi (scalar)); |
440 | SCALAR_MAPPER (dawson, ::dawson)case umap_dawson: return octave_value (::dawson (scalar)); |
441 | SCALAR_MAPPER (ceil, ::ceil)case umap_ceil: return octave_value (::ceil (scalar)); |
442 | SCALAR_MAPPER (conj, std::conj)case umap_conj: return octave_value (std::conj (scalar)); |
443 | SCALAR_MAPPER (cos, std::cos)case umap_cos: return octave_value (std::cos (scalar)); |
444 | SCALAR_MAPPER (cosh, std::cosh)case umap_cosh: return octave_value (std::cosh (scalar)); |
445 | SCALAR_MAPPER (exp, std::exp)case umap_exp: return octave_value (std::exp (scalar)); |
446 | SCALAR_MAPPER (expm1, ::expm1)case umap_expm1: return octave_value (::expm1 (scalar)); |
447 | SCALAR_MAPPER (fix, ::fix)case umap_fix: return octave_value (::fix (scalar)); |
448 | SCALAR_MAPPER (floor, ::floor)case umap_floor: return octave_value (::floor (scalar)); |
449 | SCALAR_MAPPER (imag, std::imag)case umap_imag: return octave_value (std::imag (scalar)); |
450 | SCALAR_MAPPER (log, std::log)case umap_log: return octave_value (std::log (scalar)); |
451 | SCALAR_MAPPER (log2, xlog2)case umap_log2: return octave_value (xlog2 (scalar)); |
452 | SCALAR_MAPPER (log10, std::log10)case umap_log10: return octave_value (std::log10 (scalar)); |
453 | SCALAR_MAPPER (log1p, ::log1p)case umap_log1p: return octave_value (::log1p (scalar)); |
454 | SCALAR_MAPPER (real, std::real)case umap_real: return octave_value (std::real (scalar)); |
455 | SCALAR_MAPPER (round, xround)case umap_round: return octave_value (xround (scalar)); |
456 | SCALAR_MAPPER (roundb, xroundb)case umap_roundb: return octave_value (xroundb (scalar)); |
457 | SCALAR_MAPPER (signum, ::signum)case umap_signum: return octave_value (::signum (scalar)); |
458 | SCALAR_MAPPER (sin, std::sin)case umap_sin: return octave_value (std::sin (scalar)); |
459 | SCALAR_MAPPER (sinh, std::sinh)case umap_sinh: return octave_value (std::sinh (scalar)); |
460 | SCALAR_MAPPER (sqrt, std::sqrt)case umap_sqrt: return octave_value (std::sqrt (scalar)); |
461 | SCALAR_MAPPER (tan, std::tan)case umap_tan: return octave_value (std::tan (scalar)); |
462 | SCALAR_MAPPER (tanh, std::tanh)case umap_tanh: return octave_value (std::tanh (scalar)); |
463 | SCALAR_MAPPER (finite, xfinite)case umap_finite: return octave_value (xfinite (scalar)); |
464 | SCALAR_MAPPER (isinf, xisinf)case umap_isinf: return octave_value (xisinf (scalar)); |
465 | SCALAR_MAPPER (isna, octave_is_NA)case umap_isna: return octave_value (octave_is_NA (scalar)); |
466 | SCALAR_MAPPER (isnan, xisnan)case umap_isnan: return octave_value (xisnan (scalar)); |
467 | |
468 | default: |
469 | return octave_base_value::map (umap); |
470 | } |
471 | } |