Mercurial > hg > octave-nkf
annotate src/ov-complex.cc @ 7638:2df457529cfa
implement expm1 and log1p functions
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Tue, 25 Mar 2008 19:47:21 -0400 |
parents | 99c410f7f0b0 |
children | fb3a6c53c2b2 |
rev | line source |
---|---|
2376 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, |
4 2006, 2007 John W. Eaton | |
2376 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2376 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2376 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
3503 | 28 #include <iostream> |
2901 | 29 |
2376 | 30 #include "lo-ieee.h" |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
31 #include "lo-specfun.h" |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
32 #include "lo-mappers.h" |
2376 | 33 |
34 #include "oct-obj.h" | |
4944 | 35 #include "oct-stream.h" |
2410 | 36 #include "ops.h" |
2376 | 37 #include "ov-complex.h" |
3223 | 38 #include "ov-base.h" |
39 #include "ov-base-scalar.h" | |
40 #include "ov-base-scalar.cc" | |
2423 | 41 #include "ov-cx-mat.h" |
2410 | 42 #include "ov-scalar.h" |
2376 | 43 #include "gripes.h" |
44 #include "pr-output.h" | |
45 | |
4687 | 46 #include "ls-oct-ascii.h" |
47 #include "ls-hdf5.h" | |
48 | |
3223 | 49 template class octave_base_scalar<Complex>; |
50 | |
3219 | 51 DEFINE_OCTAVE_ALLOCATOR (octave_complex); |
2376 | 52 |
4612 | 53 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex, |
54 "complex scalar", "double"); | |
2376 | 55 |
5759 | 56 octave_base_value * |
2410 | 57 octave_complex::try_narrowing_conversion (void) |
58 { | |
5759 | 59 octave_base_value *retval = 0; |
2410 | 60 |
5450 | 61 double im = std::imag (scalar); |
62 | |
63 if (im == 0.0 && ! lo_ieee_signbit (im)) | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
64 retval = new octave_scalar (std::real (scalar)); |
2410 | 65 |
66 return retval; | |
67 } | |
68 | |
2376 | 69 octave_value |
5885 | 70 octave_complex::do_index_op (const octave_value_list& idx, bool resize_ok) |
2376 | 71 { |
72 octave_value retval; | |
73 | |
3933 | 74 if (idx.valid_scalar_indices ()) |
2376 | 75 retval = scalar; |
76 else | |
77 { | |
5775 | 78 // FIXME -- this doesn't solve the problem of |
2376 | 79 // |
80 // a = i; a([1,1], [1,1], [1,1]) | |
81 // | |
82 // and similar constructions. Hmm... | |
83 | |
5775 | 84 // FIXME -- using this constructor avoids narrowing the |
2423 | 85 // 1x1 matrix back to a scalar value. Need a better solution |
86 // to this problem. | |
87 | |
88 octave_value tmp (new octave_complex_matrix (complex_matrix_value ())); | |
2376 | 89 |
3933 | 90 retval = tmp.do_index_op (idx, resize_ok); |
2376 | 91 } |
92 | |
93 return retval; | |
94 } | |
95 | |
96 double | |
97 octave_complex::double_value (bool force_conversion) const | |
98 { | |
4102 | 99 double retval = lo_ieee_nan_value (); |
2376 | 100 |
5781 | 101 if (! force_conversion) |
102 gripe_implicit_conversion ("Octave:imag-to-real", | |
103 "complex scalar", "real scalar"); | |
2376 | 104 |
4451 | 105 retval = std::real (scalar); |
2376 | 106 |
107 return retval; | |
108 } | |
109 | |
110 Matrix | |
111 octave_complex::matrix_value (bool force_conversion) const | |
112 { | |
113 Matrix retval; | |
114 | |
5781 | 115 if (! force_conversion) |
116 gripe_implicit_conversion ("Octave:imag-to-real", | |
117 "complex scalar", "real matrix"); | |
2376 | 118 |
4451 | 119 retval = Matrix (1, 1, std::real (scalar)); |
2376 | 120 |
121 return retval; | |
122 } | |
123 | |
4569 | 124 NDArray |
125 octave_complex::array_value (bool force_conversion) const | |
126 { | |
127 NDArray retval; | |
128 | |
5781 | 129 if (! force_conversion) |
130 gripe_implicit_conversion ("Octave:imag-to-real", | |
131 "complex scalar", "real matrix"); | |
4569 | 132 |
133 retval = NDArray (dim_vector (1, 1), std::real (scalar)); | |
134 | |
135 return retval; | |
136 } | |
137 | |
2376 | 138 Complex |
139 octave_complex::complex_value (bool) const | |
140 { | |
141 return scalar; | |
142 } | |
143 | |
144 | |
145 ComplexMatrix | |
146 octave_complex::complex_matrix_value (bool) const | |
147 { | |
148 return ComplexMatrix (1, 1, scalar); | |
149 } | |
150 | |
4569 | 151 ComplexNDArray |
4664 | 152 octave_complex::complex_array_value (bool /* force_conversion */) const |
4569 | 153 { |
154 return ComplexNDArray (dim_vector (1, 1), scalar); | |
155 } | |
156 | |
5731 | 157 octave_value |
158 octave_complex::resize (const dim_vector& dv, bool fill) const | |
159 { | |
160 if (fill) | |
161 { | |
162 ComplexNDArray retval (dv, ComplexNDArray::resize_fill_value ()); | |
163 | |
164 if (dv.numel ()) | |
165 retval(0) = scalar; | |
166 | |
167 return retval; | |
168 } | |
169 else | |
170 { | |
171 ComplexNDArray retval (dv); | |
172 | |
173 if (dv.numel ()) | |
174 retval(0) = scalar; | |
175 | |
176 return retval; | |
177 } | |
178 } | |
179 | |
4687 | 180 bool |
6974 | 181 octave_complex::save_ascii (std::ostream& os) |
4687 | 182 { |
183 Complex c = complex_value (); | |
184 | |
5958 | 185 octave_write_complex (os, c); |
4687 | 186 |
5958 | 187 os << "\n"; |
4687 | 188 |
189 return true; | |
190 } | |
191 | |
192 bool | |
193 octave_complex::load_ascii (std::istream& is) | |
194 { | |
195 scalar = octave_read_complex (is); | |
196 | |
197 if (!is) | |
198 { | |
199 error ("load: failed to load complex scalar constant"); | |
200 return false; | |
201 } | |
202 | |
203 return true; | |
204 } | |
205 | |
206 | |
207 bool | |
208 octave_complex::save_binary (std::ostream& os, bool& /* save_as_floats */) | |
209 { | |
5760 | 210 char tmp = static_cast<char> (LS_DOUBLE); |
211 os.write (reinterpret_cast<char *> (&tmp), 1); | |
4687 | 212 Complex ctmp = complex_value (); |
5760 | 213 os.write (reinterpret_cast<char *> (&ctmp), 16); |
4687 | 214 |
215 return true; | |
216 } | |
217 | |
218 bool | |
219 octave_complex::load_binary (std::istream& is, bool swap, | |
220 oct_mach_info::float_format fmt) | |
221 { | |
222 char tmp; | |
5760 | 223 if (! is.read (reinterpret_cast<char *> (&tmp), 1)) |
4687 | 224 return false; |
225 | |
226 Complex ctmp; | |
5760 | 227 read_doubles (is, reinterpret_cast<double *> (&ctmp), |
228 static_cast<save_type> (tmp), 2, swap, fmt); | |
4687 | 229 if (error_state || ! is) |
230 return false; | |
231 | |
232 scalar = ctmp; | |
233 return true; | |
234 } | |
235 | |
236 #if defined (HAVE_HDF5) | |
4944 | 237 |
4687 | 238 bool |
239 octave_complex::save_hdf5 (hid_t loc_id, const char *name, | |
240 bool /* save_as_floats */) | |
241 { | |
242 hsize_t dimens[3]; | |
243 hid_t space_hid = -1, type_hid = -1, data_hid = -1; | |
244 bool retval = true; | |
245 | |
4815 | 246 space_hid = H5Screate_simple (0, dimens, 0); |
4837 | 247 if (space_hid < 0) |
248 return false; | |
4687 | 249 |
250 type_hid = hdf5_make_complex_type (H5T_NATIVE_DOUBLE); | |
251 if (type_hid < 0) | |
252 { | |
253 H5Sclose (space_hid); | |
254 return false; | |
255 } | |
256 | |
257 data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT); | |
258 if (data_hid < 0) | |
259 { | |
260 H5Sclose (space_hid); | |
261 H5Tclose (type_hid); | |
262 return false; | |
263 } | |
264 | |
265 Complex tmp = complex_value (); | |
266 retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT, | |
4815 | 267 &tmp) >= 0; |
4687 | 268 |
269 H5Dclose (data_hid); | |
270 H5Tclose (type_hid); | |
271 H5Sclose (space_hid); | |
4837 | 272 |
4687 | 273 return retval; |
274 } | |
275 | |
276 bool | |
277 octave_complex::load_hdf5 (hid_t loc_id, const char *name, | |
278 bool /* have_h5giterate_bug */) | |
279 { | |
280 bool retval = false; | |
281 hid_t data_hid = H5Dopen (loc_id, name); | |
282 hid_t type_hid = H5Dget_type (data_hid); | |
283 | |
284 hid_t complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE); | |
285 | |
286 if (! hdf5_types_compatible (type_hid, complex_type)) | |
287 { | |
4837 | 288 H5Tclose (complex_type); |
4687 | 289 H5Dclose (data_hid); |
290 return false; | |
291 } | |
292 | |
293 hid_t space_id = H5Dget_space (data_hid); | |
294 hsize_t rank = H5Sget_simple_extent_ndims (space_id); | |
295 | |
296 if (rank != 0) | |
297 { | |
4837 | 298 H5Tclose (complex_type); |
4687 | 299 H5Sclose (space_id); |
300 H5Dclose (data_hid); | |
301 return false; | |
302 } | |
303 | |
304 // complex scalar: | |
305 Complex ctmp; | |
306 if (H5Dread (data_hid, complex_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, | |
4815 | 307 &ctmp) >= 0) |
4687 | 308 { |
309 retval = true; | |
310 scalar = ctmp; | |
311 } | |
312 | |
4837 | 313 H5Tclose (complex_type); |
4687 | 314 H5Sclose (space_id); |
315 H5Dclose (data_hid); | |
4837 | 316 |
4687 | 317 return retval; |
318 } | |
4944 | 319 |
4687 | 320 #endif |
321 | |
5900 | 322 mxArray * |
323 octave_complex::as_mxArray (void) const | |
324 { | |
325 mxArray *retval = new mxArray (mxDOUBLE_CLASS, 1, 1, mxCOMPLEX); | |
326 | |
327 double *pr = static_cast<double *> (retval->get_data ()); | |
328 double *pi = static_cast<double *> (retval->get_imag_data ()); | |
329 | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
330 pr[0] = std::real (scalar); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
331 pi[0] = std::imag (scalar); |
5900 | 332 |
333 return retval; | |
334 } | |
335 | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
336 static double |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
337 xabs (const Complex& x) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
338 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
339 return (xisinf (x.real ()) || xisinf (x.imag ())) ? octave_Inf : abs (x); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
340 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
341 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
342 static double |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
343 ximag (const Complex& x) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
344 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
345 return x.imag (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
346 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
347 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
348 static double |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
349 xreal (const Complex& x) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
350 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
351 return x.real (); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
352 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
353 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
354 #define COMPLEX_MAPPER(MAP, FCN) \ |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
355 octave_value \ |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
356 octave_complex::MAP (void) const \ |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
357 { \ |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
358 return octave_value (FCN (scalar)); \ |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
359 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
360 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
361 COMPLEX_MAPPER (abs, xabs) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
362 COMPLEX_MAPPER (acos, ::acos) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
363 COMPLEX_MAPPER (acosh, ::acosh) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
364 COMPLEX_MAPPER (angle, std::arg) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
365 COMPLEX_MAPPER (arg, std::arg) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
366 COMPLEX_MAPPER (asin, ::asin) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
367 COMPLEX_MAPPER (asinh, ::asinh) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
368 COMPLEX_MAPPER (atan, ::atan) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
369 COMPLEX_MAPPER (atanh, ::atanh) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
370 COMPLEX_MAPPER (ceil, ::ceil) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
371 COMPLEX_MAPPER (conj, std::conj) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
372 COMPLEX_MAPPER (cos, std::cos) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
373 COMPLEX_MAPPER (cosh, std::cosh) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
374 COMPLEX_MAPPER (exp, std::exp) |
7638
2df457529cfa
implement expm1 and log1p functions
Jaroslav Hajek <highegg@gmail.com>
parents:
7636
diff
changeset
|
375 COMPLEX_MAPPER (expm1, ::expm1) |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
376 COMPLEX_MAPPER (fix, ::fix) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
377 COMPLEX_MAPPER (floor, ::floor) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
378 COMPLEX_MAPPER (imag, ximag) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
379 COMPLEX_MAPPER (log, std::log) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
380 COMPLEX_MAPPER (log10, std::log10) |
7638
2df457529cfa
implement expm1 and log1p functions
Jaroslav Hajek <highegg@gmail.com>
parents:
7636
diff
changeset
|
381 COMPLEX_MAPPER (log1p, ::log1p) |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
382 COMPLEX_MAPPER (real, xreal) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
383 COMPLEX_MAPPER (round, xround) |
7636
99c410f7f0b0
implement mapper function for banker's rounding
Jaroslav Hajek <highegg@gmail.com>
parents:
7503
diff
changeset
|
384 COMPLEX_MAPPER (roundb, xroundb) |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
385 COMPLEX_MAPPER (signum, ::signum) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
386 COMPLEX_MAPPER (sin, std::sin) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
387 COMPLEX_MAPPER (sinh, std::sinh) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
388 COMPLEX_MAPPER (sqrt, std::sqrt) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
389 COMPLEX_MAPPER (tan, std::tan) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
390 COMPLEX_MAPPER (tanh, std::tanh) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
391 COMPLEX_MAPPER (finite, xfinite) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
392 COMPLEX_MAPPER (isinf, xisinf) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
393 COMPLEX_MAPPER (isna, octave_is_NA) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
394 COMPLEX_MAPPER (isnan, xisnan) |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
395 |
2376 | 396 /* |
397 ;;; Local Variables: *** | |
398 ;;; mode: C++ *** | |
399 ;;; End: *** | |
400 */ |