Mercurial > hg > octave-nkf
annotate liboctave/CNDArray.cc @ 8377:25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 29 Oct 2008 16:52:10 +0100 |
parents | 935be827eaf8 |
children | a1ae2aae903e |
rev | line source |
---|---|
4514 | 1 // N-D Array manipulations. |
2 /* | |
3 | |
7017 | 4 Copyright (C) 1996, 1997, 2003, 2004, 2005, 2006, 2007 John W. Eaton |
4514 | 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. | |
4514 | 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/>. | |
4514 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
4687 | 28 #include <cfloat> |
5164 | 29 |
4780 | 30 #include <vector> |
4687 | 31 |
4588 | 32 #include "Array-util.h" |
4514 | 33 #include "CNDArray.h" |
34 #include "mx-base.h" | |
4773 | 35 #include "f77-fcn.h" |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
36 #include "functor.h" |
4514 | 37 #include "lo-ieee.h" |
4687 | 38 #include "lo-mappers.h" |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
7922
diff
changeset
|
39 #include "oct-locbuf.h" |
4514 | 40 |
4773 | 41 #if defined (HAVE_FFTW3) |
4780 | 42 #include "oct-fftw.h" |
4773 | 43 #else |
44 extern "C" | |
45 { | |
46 // Note that the original complex fft routines were not written for | |
47 // double complex arguments. They have been modified by adding an | |
48 // implicit double precision (a-h,o-z) statement at the beginning of | |
49 // each subroutine. | |
50 | |
51 F77_RET_T | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
52 F77_FUNC (zffti, ZFFTI) (const octave_idx_type&, Complex*); |
4773 | 53 |
54 F77_RET_T | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
55 F77_FUNC (zfftf, ZFFTF) (const octave_idx_type&, Complex*, Complex*); |
4773 | 56 |
57 F77_RET_T | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
58 F77_FUNC (zfftb, ZFFTB) (const octave_idx_type&, Complex*, Complex*); |
4773 | 59 } |
60 #endif | |
61 | |
62 #if defined (HAVE_FFTW3) | |
63 ComplexNDArray | |
64 ComplexNDArray::fourier (int dim) const | |
65 { | |
66 dim_vector dv = dims (); | |
67 | |
68 if (dim > dv.length () || dim < 0) | |
69 return ComplexNDArray (); | |
70 | |
5275 | 71 octave_idx_type stride = 1; |
72 octave_idx_type n = dv(dim); | |
4773 | 73 |
74 for (int i = 0; i < dim; i++) | |
75 stride *= dv(i); | |
76 | |
5275 | 77 octave_idx_type howmany = numel () / dv (dim); |
4773 | 78 howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany)); |
5275 | 79 octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride); |
80 octave_idx_type dist = (stride == 1 ? n : 1); | |
4773 | 81 |
82 const Complex *in (fortran_vec ()); | |
83 ComplexNDArray retval (dv); | |
84 Complex *out (retval.fortran_vec ()); | |
85 | |
86 // Need to be careful here about the distance between fft's | |
5275 | 87 for (octave_idx_type k = 0; k < nloop; k++) |
4773 | 88 octave_fftw::fft (in + k * stride * n, out + k * stride * n, |
89 n, howmany, stride, dist); | |
90 | |
91 return retval; | |
92 } | |
93 | |
94 ComplexNDArray | |
4816 | 95 ComplexNDArray::ifourier (int dim) const |
4773 | 96 { |
97 dim_vector dv = dims (); | |
98 | |
99 if (dim > dv.length () || dim < 0) | |
100 return ComplexNDArray (); | |
101 | |
5275 | 102 octave_idx_type stride = 1; |
103 octave_idx_type n = dv(dim); | |
4773 | 104 |
105 for (int i = 0; i < dim; i++) | |
106 stride *= dv(i); | |
107 | |
5275 | 108 octave_idx_type howmany = numel () / dv (dim); |
4773 | 109 howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany)); |
5275 | 110 octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride); |
111 octave_idx_type dist = (stride == 1 ? n : 1); | |
4773 | 112 |
113 const Complex *in (fortran_vec ()); | |
114 ComplexNDArray retval (dv); | |
115 Complex *out (retval.fortran_vec ()); | |
116 | |
117 // Need to be careful here about the distance between fft's | |
5275 | 118 for (octave_idx_type k = 0; k < nloop; k++) |
4773 | 119 octave_fftw::ifft (in + k * stride * n, out + k * stride * n, |
120 n, howmany, stride, dist); | |
121 | |
122 return retval; | |
123 } | |
124 | |
125 ComplexNDArray | |
126 ComplexNDArray::fourier2d (void) const | |
127 { | |
128 dim_vector dv = dims(); | |
129 if (dv.length () < 2) | |
130 return ComplexNDArray (); | |
131 | |
132 dim_vector dv2(dv(0), dv(1)); | |
133 const Complex *in = fortran_vec (); | |
134 ComplexNDArray retval (dv); | |
135 Complex *out = retval.fortran_vec (); | |
5275 | 136 octave_idx_type howmany = numel() / dv(0) / dv(1); |
137 octave_idx_type dist = dv(0) * dv(1); | |
4773 | 138 |
5275 | 139 for (octave_idx_type i=0; i < howmany; i++) |
4773 | 140 octave_fftw::fftNd (in + i*dist, out + i*dist, 2, dv2); |
141 | |
142 return retval; | |
143 } | |
144 | |
145 ComplexNDArray | |
146 ComplexNDArray::ifourier2d (void) const | |
147 { | |
148 dim_vector dv = dims(); | |
149 if (dv.length () < 2) | |
150 return ComplexNDArray (); | |
151 | |
152 dim_vector dv2(dv(0), dv(1)); | |
153 const Complex *in = fortran_vec (); | |
154 ComplexNDArray retval (dv); | |
155 Complex *out = retval.fortran_vec (); | |
5275 | 156 octave_idx_type howmany = numel() / dv(0) / dv(1); |
157 octave_idx_type dist = dv(0) * dv(1); | |
4773 | 158 |
5275 | 159 for (octave_idx_type i=0; i < howmany; i++) |
4773 | 160 octave_fftw::ifftNd (in + i*dist, out + i*dist, 2, dv2); |
161 | |
162 return retval; | |
163 } | |
164 | |
165 ComplexNDArray | |
166 ComplexNDArray::fourierNd (void) const | |
167 { | |
168 dim_vector dv = dims (); | |
169 int rank = dv.length (); | |
170 | |
171 const Complex *in (fortran_vec ()); | |
172 ComplexNDArray retval (dv); | |
173 Complex *out (retval.fortran_vec ()); | |
174 | |
175 octave_fftw::fftNd (in, out, rank, dv); | |
176 | |
177 return retval; | |
178 } | |
179 | |
180 ComplexNDArray | |
181 ComplexNDArray::ifourierNd (void) const | |
182 { | |
183 dim_vector dv = dims (); | |
184 int rank = dv.length (); | |
185 | |
186 const Complex *in (fortran_vec ()); | |
187 ComplexNDArray retval (dv); | |
188 Complex *out (retval.fortran_vec ()); | |
189 | |
190 octave_fftw::ifftNd (in, out, rank, dv); | |
191 | |
192 return retval; | |
193 } | |
194 | |
195 #else | |
196 ComplexNDArray | |
197 ComplexNDArray::fourier (int dim) const | |
198 { | |
199 dim_vector dv = dims (); | |
200 | |
201 if (dim > dv.length () || dim < 0) | |
202 return ComplexNDArray (); | |
203 | |
204 ComplexNDArray retval (dv); | |
5275 | 205 octave_idx_type npts = dv(dim); |
206 octave_idx_type nn = 4*npts+15; | |
4773 | 207 Array<Complex> wsave (nn); |
208 Complex *pwsave = wsave.fortran_vec (); | |
209 | |
210 OCTAVE_LOCAL_BUFFER (Complex, tmp, npts); | |
211 | |
5275 | 212 octave_idx_type stride = 1; |
4773 | 213 |
214 for (int i = 0; i < dim; i++) | |
215 stride *= dv(i); | |
216 | |
5275 | 217 octave_idx_type howmany = numel () / npts; |
4773 | 218 howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany)); |
5275 | 219 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride); |
220 octave_idx_type dist = (stride == 1 ? npts : 1); | |
4773 | 221 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
222 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
4773 | 223 |
5275 | 224 for (octave_idx_type k = 0; k < nloop; k++) |
4773 | 225 { |
5275 | 226 for (octave_idx_type j = 0; j < howmany; j++) |
4773 | 227 { |
228 OCTAVE_QUIT; | |
229 | |
5275 | 230 for (octave_idx_type i = 0; i < npts; i++) |
4773 | 231 tmp[i] = elem((i + k*npts)*stride + j*dist); |
232 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
233 F77_FUNC (zfftf, ZFFTF) (npts, tmp, pwsave); |
4773 | 234 |
5275 | 235 for (octave_idx_type i = 0; i < npts; i++) |
4773 | 236 retval ((i + k*npts)*stride + j*dist) = tmp[i]; |
237 } | |
238 } | |
239 | |
240 return retval; | |
241 } | |
242 | |
243 ComplexNDArray | |
244 ComplexNDArray::ifourier (int dim) const | |
245 { | |
246 dim_vector dv = dims (); | |
247 | |
248 if (dim > dv.length () || dim < 0) | |
249 return ComplexNDArray (); | |
250 | |
251 ComplexNDArray retval (dv); | |
5275 | 252 octave_idx_type npts = dv(dim); |
253 octave_idx_type nn = 4*npts+15; | |
4773 | 254 Array<Complex> wsave (nn); |
255 Complex *pwsave = wsave.fortran_vec (); | |
256 | |
257 OCTAVE_LOCAL_BUFFER (Complex, tmp, npts); | |
258 | |
5275 | 259 octave_idx_type stride = 1; |
4773 | 260 |
261 for (int i = 0; i < dim; i++) | |
262 stride *= dv(i); | |
263 | |
5275 | 264 octave_idx_type howmany = numel () / npts; |
4773 | 265 howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany)); |
5275 | 266 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride); |
267 octave_idx_type dist = (stride == 1 ? npts : 1); | |
4773 | 268 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
269 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
4773 | 270 |
5275 | 271 for (octave_idx_type k = 0; k < nloop; k++) |
4773 | 272 { |
5275 | 273 for (octave_idx_type j = 0; j < howmany; j++) |
4773 | 274 { |
275 OCTAVE_QUIT; | |
276 | |
5275 | 277 for (octave_idx_type i = 0; i < npts; i++) |
4773 | 278 tmp[i] = elem((i + k*npts)*stride + j*dist); |
279 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
280 F77_FUNC (zfftb, ZFFTB) (npts, tmp, pwsave); |
4773 | 281 |
5275 | 282 for (octave_idx_type i = 0; i < npts; i++) |
4773 | 283 retval ((i + k*npts)*stride + j*dist) = tmp[i] / |
284 static_cast<double> (npts); | |
285 } | |
286 } | |
287 | |
288 return retval; | |
289 } | |
290 | |
291 ComplexNDArray | |
292 ComplexNDArray::fourier2d (void) const | |
293 { | |
294 dim_vector dv = dims (); | |
295 dim_vector dv2 (dv(0), dv(1)); | |
296 int rank = 2; | |
297 ComplexNDArray retval (*this); | |
5275 | 298 octave_idx_type stride = 1; |
4773 | 299 |
300 for (int i = 0; i < rank; i++) | |
301 { | |
5275 | 302 octave_idx_type npts = dv2(i); |
303 octave_idx_type nn = 4*npts+15; | |
4773 | 304 Array<Complex> wsave (nn); |
305 Complex *pwsave = wsave.fortran_vec (); | |
306 Array<Complex> row (npts); | |
307 Complex *prow = row.fortran_vec (); | |
308 | |
5275 | 309 octave_idx_type howmany = numel () / npts; |
4773 | 310 howmany = (stride == 1 ? howmany : |
311 (howmany > stride ? stride : howmany)); | |
5275 | 312 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride); |
313 octave_idx_type dist = (stride == 1 ? npts : 1); | |
4773 | 314 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
315 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
4773 | 316 |
5275 | 317 for (octave_idx_type k = 0; k < nloop; k++) |
4773 | 318 { |
5275 | 319 for (octave_idx_type j = 0; j < howmany; j++) |
4773 | 320 { |
321 OCTAVE_QUIT; | |
322 | |
5275 | 323 for (octave_idx_type l = 0; l < npts; l++) |
4773 | 324 prow[l] = retval ((l + k*npts)*stride + j*dist); |
325 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
326 F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave); |
4773 | 327 |
5275 | 328 for (octave_idx_type l = 0; l < npts; l++) |
4773 | 329 retval ((l + k*npts)*stride + j*dist) = prow[l]; |
330 } | |
331 } | |
332 | |
333 stride *= dv2(i); | |
334 } | |
335 | |
336 return retval; | |
337 } | |
338 | |
339 ComplexNDArray | |
340 ComplexNDArray::ifourier2d (void) const | |
341 { | |
342 dim_vector dv = dims(); | |
343 dim_vector dv2 (dv(0), dv(1)); | |
344 int rank = 2; | |
345 ComplexNDArray retval (*this); | |
5275 | 346 octave_idx_type stride = 1; |
4773 | 347 |
348 for (int i = 0; i < rank; i++) | |
349 { | |
5275 | 350 octave_idx_type npts = dv2(i); |
351 octave_idx_type nn = 4*npts+15; | |
4773 | 352 Array<Complex> wsave (nn); |
353 Complex *pwsave = wsave.fortran_vec (); | |
354 Array<Complex> row (npts); | |
355 Complex *prow = row.fortran_vec (); | |
356 | |
5275 | 357 octave_idx_type howmany = numel () / npts; |
4773 | 358 howmany = (stride == 1 ? howmany : |
359 (howmany > stride ? stride : howmany)); | |
5275 | 360 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride); |
361 octave_idx_type dist = (stride == 1 ? npts : 1); | |
4773 | 362 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
363 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
4773 | 364 |
5275 | 365 for (octave_idx_type k = 0; k < nloop; k++) |
4773 | 366 { |
5275 | 367 for (octave_idx_type j = 0; j < howmany; j++) |
4773 | 368 { |
369 OCTAVE_QUIT; | |
370 | |
5275 | 371 for (octave_idx_type l = 0; l < npts; l++) |
4773 | 372 prow[l] = retval ((l + k*npts)*stride + j*dist); |
373 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
374 F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave); |
4773 | 375 |
5275 | 376 for (octave_idx_type l = 0; l < npts; l++) |
4773 | 377 retval ((l + k*npts)*stride + j*dist) = prow[l] / |
378 static_cast<double> (npts); | |
379 } | |
380 } | |
381 | |
382 stride *= dv2(i); | |
383 } | |
384 | |
385 return retval; | |
386 } | |
387 | |
388 ComplexNDArray | |
389 ComplexNDArray::fourierNd (void) const | |
390 { | |
391 dim_vector dv = dims (); | |
392 int rank = dv.length (); | |
393 ComplexNDArray retval (*this); | |
5275 | 394 octave_idx_type stride = 1; |
4773 | 395 |
396 for (int i = 0; i < rank; i++) | |
397 { | |
5275 | 398 octave_idx_type npts = dv(i); |
399 octave_idx_type nn = 4*npts+15; | |
4773 | 400 Array<Complex> wsave (nn); |
401 Complex *pwsave = wsave.fortran_vec (); | |
402 Array<Complex> row (npts); | |
403 Complex *prow = row.fortran_vec (); | |
404 | |
5275 | 405 octave_idx_type howmany = numel () / npts; |
4773 | 406 howmany = (stride == 1 ? howmany : |
407 (howmany > stride ? stride : howmany)); | |
5275 | 408 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride); |
409 octave_idx_type dist = (stride == 1 ? npts : 1); | |
4773 | 410 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
411 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
4773 | 412 |
5275 | 413 for (octave_idx_type k = 0; k < nloop; k++) |
4773 | 414 { |
5275 | 415 for (octave_idx_type j = 0; j < howmany; j++) |
4773 | 416 { |
417 OCTAVE_QUIT; | |
418 | |
5275 | 419 for (octave_idx_type l = 0; l < npts; l++) |
4773 | 420 prow[l] = retval ((l + k*npts)*stride + j*dist); |
421 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
422 F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave); |
4773 | 423 |
5275 | 424 for (octave_idx_type l = 0; l < npts; l++) |
4773 | 425 retval ((l + k*npts)*stride + j*dist) = prow[l]; |
426 } | |
427 } | |
428 | |
429 stride *= dv(i); | |
430 } | |
431 | |
432 return retval; | |
433 } | |
434 | |
435 ComplexNDArray | |
436 ComplexNDArray::ifourierNd (void) const | |
437 { | |
438 dim_vector dv = dims (); | |
439 int rank = dv.length (); | |
440 ComplexNDArray retval (*this); | |
5275 | 441 octave_idx_type stride = 1; |
4773 | 442 |
443 for (int i = 0; i < rank; i++) | |
444 { | |
5275 | 445 octave_idx_type npts = dv(i); |
446 octave_idx_type nn = 4*npts+15; | |
4773 | 447 Array<Complex> wsave (nn); |
448 Complex *pwsave = wsave.fortran_vec (); | |
449 Array<Complex> row (npts); | |
450 Complex *prow = row.fortran_vec (); | |
451 | |
5275 | 452 octave_idx_type howmany = numel () / npts; |
4773 | 453 howmany = (stride == 1 ? howmany : |
454 (howmany > stride ? stride : howmany)); | |
5275 | 455 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride); |
456 octave_idx_type dist = (stride == 1 ? npts : 1); | |
4773 | 457 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
458 F77_FUNC (zffti, ZFFTI) (npts, pwsave); |
4773 | 459 |
5275 | 460 for (octave_idx_type k = 0; k < nloop; k++) |
4773 | 461 { |
5275 | 462 for (octave_idx_type j = 0; j < howmany; j++) |
4773 | 463 { |
464 OCTAVE_QUIT; | |
465 | |
5275 | 466 for (octave_idx_type l = 0; l < npts; l++) |
4773 | 467 prow[l] = retval ((l + k*npts)*stride + j*dist); |
468 | |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
469 F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave); |
4773 | 470 |
5275 | 471 for (octave_idx_type l = 0; l < npts; l++) |
4773 | 472 retval ((l + k*npts)*stride + j*dist) = prow[l] / |
473 static_cast<double> (npts); | |
474 } | |
475 } | |
476 | |
477 stride *= dv(i); | |
478 } | |
479 | |
480 return retval; | |
481 } | |
482 | |
483 #endif | |
484 | |
4543 | 485 // unary operations |
486 | |
487 boolNDArray | |
488 ComplexNDArray::operator ! (void) const | |
489 { | |
490 boolNDArray b (dims ()); | |
491 | |
5275 | 492 for (octave_idx_type i = 0; i < length (); i++) |
5139 | 493 b.elem (i) = elem (i) == 0.0; |
4543 | 494 |
495 return b; | |
496 } | |
497 | |
5775 | 498 // FIXME -- this is not quite the right thing. |
4514 | 499 |
4687 | 500 bool |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
501 ComplexNDArray::any_element_is_nan (void) const |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
502 { |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
503 octave_idx_type nel = nelem (); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
504 |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
505 for (octave_idx_type i = 0; i < nel; i++) |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
506 { |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
507 Complex val = elem (i); |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
508 if (xisnan (val)) |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
509 return true; |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
510 } |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
511 return false; |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
512 } |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
513 |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
514 bool |
4687 | 515 ComplexNDArray::any_element_is_inf_or_nan (void) const |
516 { | |
5275 | 517 octave_idx_type nel = nelem (); |
4687 | 518 |
5275 | 519 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 520 { |
521 Complex val = elem (i); | |
522 if (xisinf (val) || xisnan (val)) | |
523 return true; | |
524 } | |
525 return false; | |
526 } | |
527 | |
528 // Return true if no elements have imaginary components. | |
529 | |
530 bool | |
531 ComplexNDArray::all_elements_are_real (void) const | |
532 { | |
5275 | 533 octave_idx_type nel = nelem (); |
4687 | 534 |
5275 | 535 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 536 { |
5260 | 537 double ip = std::imag (elem (i)); |
4687 | 538 |
539 if (ip != 0.0 || lo_ieee_signbit (ip)) | |
540 return false; | |
541 } | |
542 | |
543 return true; | |
544 } | |
545 | |
546 // Return nonzero if any element of CM has a non-integer real or | |
547 // imaginary part. Also extract the largest and smallest (real or | |
548 // imaginary) values and return them in MAX_VAL and MIN_VAL. | |
549 | |
550 bool | |
551 ComplexNDArray::all_integers (double& max_val, double& min_val) const | |
552 { | |
5275 | 553 octave_idx_type nel = nelem (); |
4687 | 554 |
555 if (nel > 0) | |
556 { | |
557 Complex val = elem (0); | |
558 | |
5260 | 559 double r_val = std::real (val); |
560 double i_val = std::imag (val); | |
4687 | 561 |
562 max_val = r_val; | |
563 min_val = r_val; | |
564 | |
565 if (i_val > max_val) | |
566 max_val = i_val; | |
567 | |
568 if (i_val < max_val) | |
569 min_val = i_val; | |
570 } | |
571 else | |
572 return false; | |
573 | |
5275 | 574 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 575 { |
576 Complex val = elem (i); | |
577 | |
5260 | 578 double r_val = std::real (val); |
579 double i_val = std::imag (val); | |
4687 | 580 |
581 if (r_val > max_val) | |
582 max_val = r_val; | |
583 | |
584 if (i_val > max_val) | |
585 max_val = i_val; | |
586 | |
587 if (r_val < min_val) | |
588 min_val = r_val; | |
589 | |
590 if (i_val < min_val) | |
591 min_val = i_val; | |
592 | |
593 if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val) | |
594 return false; | |
595 } | |
596 | |
597 return true; | |
598 } | |
599 | |
600 bool | |
601 ComplexNDArray::too_large_for_float (void) const | |
602 { | |
5275 | 603 octave_idx_type nel = nelem (); |
4687 | 604 |
5275 | 605 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 606 { |
607 Complex val = elem (i); | |
608 | |
5260 | 609 double r_val = std::real (val); |
610 double i_val = std::imag (val); | |
4687 | 611 |
5389 | 612 if ((! (xisnan (r_val) || xisinf (r_val)) |
5387 | 613 && fabs (r_val) > FLT_MAX) |
5389 | 614 || (! (xisnan (i_val) || xisinf (i_val)) |
5387 | 615 && fabs (i_val) > FLT_MAX)) |
4687 | 616 return true; |
617 } | |
618 | |
619 return false; | |
620 } | |
621 | |
4556 | 622 boolNDArray |
4514 | 623 ComplexNDArray::all (int dim) const |
624 { | |
4569 | 625 MX_ND_ANY_ALL_REDUCTION |
626 (MX_ND_ALL_EVAL (elem (iter_idx) == Complex (0, 0)), true); | |
4514 | 627 } |
628 | |
4556 | 629 boolNDArray |
4514 | 630 ComplexNDArray::any (int dim) const |
631 { | |
4569 | 632 MX_ND_ANY_ALL_REDUCTION |
5110 | 633 (MX_ND_ANY_EVAL (elem (iter_idx) != Complex (0, 0) |
5260 | 634 && ! (lo_ieee_isnan (std::real (elem (iter_idx))) |
635 || lo_ieee_isnan (std::imag (elem (iter_idx))))), | |
5110 | 636 false); |
4569 | 637 } |
638 | |
4584 | 639 ComplexNDArray |
4569 | 640 ComplexNDArray::cumprod (int dim) const |
641 { | |
4584 | 642 MX_ND_CUMULATIVE_OP (ComplexNDArray, Complex, Complex (1, 0), *); |
4569 | 643 } |
644 | |
4584 | 645 ComplexNDArray |
4569 | 646 ComplexNDArray::cumsum (int dim) const |
647 { | |
4584 | 648 MX_ND_CUMULATIVE_OP (ComplexNDArray, Complex, Complex (0, 0), +); |
4569 | 649 } |
650 | |
651 ComplexNDArray | |
652 ComplexNDArray::prod (int dim) const | |
653 { | |
654 MX_ND_COMPLEX_OP_REDUCTION (*= elem (iter_idx), Complex (1, 0)); | |
655 } | |
656 | |
657 ComplexNDArray | |
658 ComplexNDArray::sumsq (int dim) const | |
659 { | |
660 MX_ND_COMPLEX_OP_REDUCTION | |
5260 | 661 (+= std::imag (elem (iter_idx)) |
4569 | 662 ? elem (iter_idx) * conj (elem (iter_idx)) |
663 : std::pow (elem (iter_idx), 2), Complex (0, 0)); | |
664 } | |
665 | |
666 ComplexNDArray | |
667 ComplexNDArray::sum (int dim) const | |
668 { | |
669 MX_ND_COMPLEX_OP_REDUCTION (+= elem (iter_idx), Complex (0, 0)); | |
670 } | |
671 | |
4915 | 672 ComplexNDArray |
5275 | 673 ComplexNDArray::concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx) |
4915 | 674 { |
4940 | 675 if (rb.numel () > 0) |
5073 | 676 insert (rb, ra_idx); |
677 return *this; | |
4915 | 678 } |
679 | |
680 ComplexNDArray | |
5275 | 681 ComplexNDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx) |
4758 | 682 { |
4915 | 683 ComplexNDArray tmp (rb); |
4940 | 684 if (rb.numel () > 0) |
5073 | 685 insert (tmp, ra_idx); |
686 return *this; | |
4915 | 687 } |
688 | |
689 ComplexNDArray | |
5275 | 690 concat (NDArray& ra, ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx) |
4915 | 691 { |
692 ComplexNDArray retval (ra); | |
4940 | 693 if (rb.numel () > 0) |
4915 | 694 retval.insert (rb, ra_idx); |
695 return retval; | |
4758 | 696 } |
697 | |
4844 | 698 static const Complex Complex_NaN_result (octave_NaN, octave_NaN); |
699 | |
700 ComplexNDArray | |
701 ComplexNDArray::max (int dim) const | |
702 { | |
5275 | 703 ArrayN<octave_idx_type> dummy_idx; |
4844 | 704 return max (dummy_idx, dim); |
705 } | |
706 | |
707 ComplexNDArray | |
5275 | 708 ComplexNDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const |
4844 | 709 { |
710 dim_vector dv = dims (); | |
711 dim_vector dr = dims (); | |
712 | |
713 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
714 return ComplexNDArray (); | |
715 | |
716 dr(dim) = 1; | |
717 | |
718 ComplexNDArray result (dr); | |
719 idx_arg.resize (dr); | |
720 | |
5275 | 721 octave_idx_type x_stride = 1; |
722 octave_idx_type x_len = dv(dim); | |
4844 | 723 for (int i = 0; i < dim; i++) |
724 x_stride *= dv(i); | |
725 | |
5275 | 726 for (octave_idx_type i = 0; i < dr.numel (); i++) |
4844 | 727 { |
5275 | 728 octave_idx_type x_offset; |
4844 | 729 if (x_stride == 1) |
730 x_offset = i * x_len; | |
731 else | |
732 { | |
5275 | 733 octave_idx_type x_offset2 = 0; |
4844 | 734 x_offset = i; |
735 while (x_offset >= x_stride) | |
736 { | |
737 x_offset -= x_stride; | |
738 x_offset2++; | |
739 } | |
740 x_offset += x_offset2 * x_stride * x_len; | |
741 } | |
742 | |
5275 | 743 octave_idx_type idx_j; |
4844 | 744 |
745 Complex tmp_max; | |
746 | |
747 double abs_max = octave_NaN; | |
748 | |
749 for (idx_j = 0; idx_j < x_len; idx_j++) | |
750 { | |
751 tmp_max = elem (idx_j * x_stride + x_offset); | |
752 | |
5389 | 753 if (! xisnan (tmp_max)) |
4844 | 754 { |
5260 | 755 abs_max = std::abs(tmp_max); |
4844 | 756 break; |
757 } | |
758 } | |
759 | |
5275 | 760 for (octave_idx_type j = idx_j+1; j < x_len; j++) |
4844 | 761 { |
762 Complex tmp = elem (j * x_stride + x_offset); | |
763 | |
5389 | 764 if (xisnan (tmp)) |
4844 | 765 continue; |
766 | |
5260 | 767 double abs_tmp = std::abs (tmp); |
4844 | 768 |
769 if (abs_tmp > abs_max) | |
770 { | |
771 idx_j = j; | |
772 tmp_max = tmp; | |
773 abs_max = abs_tmp; | |
774 } | |
775 } | |
776 | |
5389 | 777 if (xisnan (tmp_max)) |
4844 | 778 { |
779 result.elem (i) = Complex_NaN_result; | |
780 idx_arg.elem (i) = 0; | |
781 } | |
782 else | |
783 { | |
784 result.elem (i) = tmp_max; | |
785 idx_arg.elem (i) = idx_j; | |
786 } | |
787 } | |
788 | |
7600
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
789 result.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
790 idx_arg.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
791 |
4844 | 792 return result; |
793 } | |
794 | |
795 ComplexNDArray | |
796 ComplexNDArray::min (int dim) const | |
797 { | |
5275 | 798 ArrayN<octave_idx_type> dummy_idx; |
4844 | 799 return min (dummy_idx, dim); |
800 } | |
801 | |
802 ComplexNDArray | |
5275 | 803 ComplexNDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const |
4844 | 804 { |
805 dim_vector dv = dims (); | |
806 dim_vector dr = dims (); | |
807 | |
808 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
809 return ComplexNDArray (); | |
810 | |
811 dr(dim) = 1; | |
812 | |
813 ComplexNDArray result (dr); | |
814 idx_arg.resize (dr); | |
815 | |
5275 | 816 octave_idx_type x_stride = 1; |
817 octave_idx_type x_len = dv(dim); | |
4844 | 818 for (int i = 0; i < dim; i++) |
819 x_stride *= dv(i); | |
820 | |
5275 | 821 for (octave_idx_type i = 0; i < dr.numel (); i++) |
4844 | 822 { |
5275 | 823 octave_idx_type x_offset; |
4844 | 824 if (x_stride == 1) |
825 x_offset = i * x_len; | |
826 else | |
827 { | |
5275 | 828 octave_idx_type x_offset2 = 0; |
4844 | 829 x_offset = i; |
830 while (x_offset >= x_stride) | |
831 { | |
832 x_offset -= x_stride; | |
833 x_offset2++; | |
834 } | |
835 x_offset += x_offset2 * x_stride * x_len; | |
836 } | |
837 | |
5275 | 838 octave_idx_type idx_j; |
4844 | 839 |
840 Complex tmp_min; | |
841 | |
842 double abs_min = octave_NaN; | |
843 | |
844 for (idx_j = 0; idx_j < x_len; idx_j++) | |
845 { | |
846 tmp_min = elem (idx_j * x_stride + x_offset); | |
847 | |
5389 | 848 if (! xisnan (tmp_min)) |
4844 | 849 { |
5260 | 850 abs_min = std::abs(tmp_min); |
4844 | 851 break; |
852 } | |
853 } | |
854 | |
5275 | 855 for (octave_idx_type j = idx_j+1; j < x_len; j++) |
4844 | 856 { |
857 Complex tmp = elem (j * x_stride + x_offset); | |
858 | |
5389 | 859 if (xisnan (tmp)) |
4844 | 860 continue; |
861 | |
5260 | 862 double abs_tmp = std::abs (tmp); |
4844 | 863 |
864 if (abs_tmp < abs_min) | |
865 { | |
866 idx_j = j; | |
867 tmp_min = tmp; | |
868 abs_min = abs_tmp; | |
869 } | |
870 } | |
871 | |
5389 | 872 if (xisnan (tmp_min)) |
4844 | 873 { |
874 result.elem (i) = Complex_NaN_result; | |
875 idx_arg.elem (i) = 0; | |
876 } | |
877 else | |
878 { | |
879 result.elem (i) = tmp_min; | |
880 idx_arg.elem (i) = idx_j; | |
881 } | |
882 } | |
883 | |
7600
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
884 result.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
885 idx_arg.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
886 |
4844 | 887 return result; |
888 } | |
889 | |
4634 | 890 NDArray |
4569 | 891 ComplexNDArray::abs (void) const |
892 { | |
4634 | 893 NDArray retval (dims ()); |
4569 | 894 |
5275 | 895 octave_idx_type nel = nelem (); |
4634 | 896 |
5275 | 897 for (octave_idx_type i = 0; i < nel; i++) |
5260 | 898 retval(i) = std::abs (elem (i)); |
4569 | 899 |
900 return retval; | |
4514 | 901 } |
902 | |
4765 | 903 ComplexNDArray& |
5275 | 904 ComplexNDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c) |
4765 | 905 { |
906 dim_vector a_dv = a.dims (); | |
907 | |
908 int n = a_dv.length (); | |
909 | |
910 if (n == dimensions.length ()) | |
911 { | |
5275 | 912 Array<octave_idx_type> a_ra_idx (a_dv.length (), 0); |
4765 | 913 |
914 a_ra_idx.elem (0) = r; | |
915 a_ra_idx.elem (1) = c; | |
916 | |
917 for (int i = 0; i < n; i++) | |
918 { | |
919 if (a_ra_idx (i) < 0 || (a_ra_idx (i) + a_dv (i)) > dimensions (i)) | |
920 { | |
921 (*current_liboctave_error_handler) | |
922 ("Array<T>::insert: range error for insert"); | |
923 return *this; | |
924 } | |
925 } | |
926 | |
927 a_ra_idx.elem (0) = 0; | |
928 a_ra_idx.elem (1) = 0; | |
929 | |
5275 | 930 octave_idx_type n_elt = a.numel (); |
4765 | 931 |
932 // IS make_unique () NECCESSARY HERE?? | |
933 | |
5275 | 934 for (octave_idx_type i = 0; i < n_elt; i++) |
4765 | 935 { |
5275 | 936 Array<octave_idx_type> ra_idx = a_ra_idx; |
4765 | 937 |
938 ra_idx.elem (0) = a_ra_idx (0) + r; | |
939 ra_idx.elem (1) = a_ra_idx (1) + c; | |
940 | |
941 elem (ra_idx) = a.elem (a_ra_idx); | |
942 | |
943 increment_index (a_ra_idx, a_dv); | |
944 } | |
945 } | |
946 else | |
947 (*current_liboctave_error_handler) | |
948 ("Array<T>::insert: invalid indexing operation"); | |
949 | |
950 return *this; | |
951 } | |
952 | |
953 ComplexNDArray& | |
5275 | 954 ComplexNDArray::insert (const ComplexNDArray& a, octave_idx_type r, octave_idx_type c) |
4765 | 955 { |
956 Array<Complex>::insert (a, r, c); | |
957 return *this; | |
958 } | |
959 | |
4915 | 960 ComplexNDArray& |
5275 | 961 ComplexNDArray::insert (const ComplexNDArray& a, const Array<octave_idx_type>& ra_idx) |
4915 | 962 { |
963 Array<Complex>::insert (a, ra_idx); | |
964 return *this; | |
965 } | |
966 | |
4514 | 967 ComplexMatrix |
968 ComplexNDArray::matrix_value (void) const | |
969 { | |
970 ComplexMatrix retval; | |
971 | |
972 int nd = ndims (); | |
973 | |
974 switch (nd) | |
975 { | |
976 case 1: | |
977 retval = ComplexMatrix (Array2<Complex> (*this, dimensions(0), 1)); | |
978 break; | |
979 | |
980 case 2: | |
981 retval = ComplexMatrix (Array2<Complex> (*this, dimensions(0), | |
982 dimensions(1))); | |
983 break; | |
984 | |
985 default: | |
986 (*current_liboctave_error_handler) | |
4770 | 987 ("invalid conversion of ComplexNDArray to ComplexMatrix"); |
4514 | 988 break; |
989 } | |
990 | |
991 return retval; | |
992 } | |
993 | |
4532 | 994 void |
5275 | 995 ComplexNDArray::increment_index (Array<octave_idx_type>& ra_idx, |
4532 | 996 const dim_vector& dimensions, |
997 int start_dimension) | |
998 { | |
999 ::increment_index (ra_idx, dimensions, start_dimension); | |
1000 } | |
1001 | |
5275 | 1002 octave_idx_type |
1003 ComplexNDArray::compute_index (Array<octave_idx_type>& ra_idx, | |
4556 | 1004 const dim_vector& dimensions) |
1005 { | |
1006 return ::compute_index (ra_idx, dimensions); | |
1007 } | |
1008 | |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1009 ComplexNDArray |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1010 ComplexNDArray::diag (octave_idx_type k) const |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1011 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1012 return MArrayN<Complex>::diag (k); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1013 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1014 |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1015 NDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1016 ComplexNDArray::map (dmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1017 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1018 return MArrayN<Complex>::map<double> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1019 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1020 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1021 ComplexNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1022 ComplexNDArray::map (cmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1023 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1024 return MArrayN<Complex>::map<Complex> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1025 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1026 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1027 boolNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1028 ComplexNDArray::map (bmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1029 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1030 return MArrayN<Complex>::map<bool> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1031 } |
4687 | 1032 |
1033 // This contains no information on the array structure !!! | |
1034 std::ostream& | |
1035 operator << (std::ostream& os, const ComplexNDArray& a) | |
1036 { | |
5275 | 1037 octave_idx_type nel = a.nelem (); |
4687 | 1038 |
5275 | 1039 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 1040 { |
1041 os << " "; | |
1042 octave_write_complex (os, a.elem (i)); | |
1043 os << "\n"; | |
1044 } | |
1045 return os; | |
1046 } | |
1047 | |
1048 std::istream& | |
1049 operator >> (std::istream& is, ComplexNDArray& a) | |
1050 { | |
5275 | 1051 octave_idx_type nel = a.nelem (); |
4687 | 1052 |
1053 if (nel < 1 ) | |
1054 is.clear (std::ios::badbit); | |
1055 else | |
1056 { | |
1057 Complex tmp; | |
5275 | 1058 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 1059 { |
1060 tmp = octave_read_complex (is); | |
1061 if (is) | |
1062 a.elem (i) = tmp; | |
1063 else | |
1064 goto done; | |
1065 } | |
1066 } | |
1067 | |
1068 done: | |
1069 | |
1070 return is; | |
1071 } | |
1072 | |
5775 | 1073 // FIXME -- it would be nice to share code among the min/max |
4844 | 1074 // functions below. |
1075 | |
1076 #define EMPTY_RETURN_CHECK(T) \ | |
1077 if (nel == 0) \ | |
1078 return T (dv); | |
1079 | |
1080 ComplexNDArray | |
1081 min (const Complex& c, const ComplexNDArray& m) | |
1082 { | |
1083 dim_vector dv = m.dims (); | |
1084 int nel = dv.numel (); | |
1085 | |
1086 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1087 | |
1088 ComplexNDArray result (dv); | |
1089 | |
1090 for (int i = 0; i < nel; i++) | |
1091 { | |
1092 OCTAVE_QUIT; | |
1093 result (i) = xmin (c, m (i)); | |
1094 } | |
1095 | |
1096 return result; | |
1097 } | |
1098 | |
1099 ComplexNDArray | |
1100 min (const ComplexNDArray& m, const Complex& c) | |
1101 { | |
1102 dim_vector dv = m.dims (); | |
1103 int nel = dv.numel (); | |
1104 | |
1105 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1106 | |
1107 ComplexNDArray result (dv); | |
1108 | |
1109 for (int i = 0; i < nel; i++) | |
1110 { | |
1111 OCTAVE_QUIT; | |
1112 result (i) = xmin (c, m (i)); | |
1113 } | |
1114 | |
1115 return result; | |
1116 } | |
1117 | |
1118 ComplexNDArray | |
1119 min (const ComplexNDArray& a, const ComplexNDArray& b) | |
1120 { | |
1121 dim_vector dv = a.dims (); | |
1122 int nel = dv.numel (); | |
1123 | |
1124 if (dv != b.dims ()) | |
1125 { | |
1126 (*current_liboctave_error_handler) | |
1127 ("two-arg min expecting args of same size"); | |
1128 return ComplexNDArray (); | |
1129 } | |
1130 | |
1131 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1132 | |
1133 ComplexNDArray result (dv); | |
1134 | |
1135 for (int i = 0; i < nel; i++) | |
1136 { | |
1137 OCTAVE_QUIT; | |
1138 result (i) = xmin (a (i), b (i)); | |
1139 } | |
1140 | |
1141 return result; | |
1142 } | |
1143 | |
1144 ComplexNDArray | |
1145 max (const Complex& c, const ComplexNDArray& m) | |
1146 { | |
1147 dim_vector dv = m.dims (); | |
1148 int nel = dv.numel (); | |
1149 | |
1150 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1151 | |
1152 ComplexNDArray result (dv); | |
1153 | |
1154 for (int i = 0; i < nel; i++) | |
1155 { | |
1156 OCTAVE_QUIT; | |
1157 result (i) = xmax (c, m (i)); | |
1158 } | |
1159 | |
1160 return result; | |
1161 } | |
1162 | |
1163 ComplexNDArray | |
1164 max (const ComplexNDArray& m, const Complex& c) | |
1165 { | |
1166 dim_vector dv = m.dims (); | |
1167 int nel = dv.numel (); | |
1168 | |
1169 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1170 | |
1171 ComplexNDArray result (dv); | |
1172 | |
1173 for (int i = 0; i < nel; i++) | |
1174 { | |
1175 OCTAVE_QUIT; | |
1176 result (i) = xmax (c, m (i)); | |
1177 } | |
1178 | |
1179 return result; | |
1180 } | |
1181 | |
1182 ComplexNDArray | |
1183 max (const ComplexNDArray& a, const ComplexNDArray& b) | |
1184 { | |
1185 dim_vector dv = a.dims (); | |
1186 int nel = dv.numel (); | |
1187 | |
1188 if (dv != b.dims ()) | |
1189 { | |
1190 (*current_liboctave_error_handler) | |
1191 ("two-arg max expecting args of same size"); | |
1192 return ComplexNDArray (); | |
1193 } | |
1194 | |
1195 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1196 | |
1197 ComplexNDArray result (dv); | |
1198 | |
1199 for (int i = 0; i < nel; i++) | |
1200 { | |
1201 OCTAVE_QUIT; | |
1202 result (i) = xmax (a (i), b (i)); | |
1203 } | |
1204 | |
1205 return result; | |
1206 } | |
1207 | |
5260 | 1208 NDS_CMP_OPS(ComplexNDArray, std::real, Complex, std::real) |
4543 | 1209 NDS_BOOL_OPS(ComplexNDArray, Complex, 0.0) |
1210 | |
5260 | 1211 SND_CMP_OPS(Complex, std::real, ComplexNDArray, std::real) |
4543 | 1212 SND_BOOL_OPS(Complex, ComplexNDArray, 0.0) |
1213 | |
5260 | 1214 NDND_CMP_OPS(ComplexNDArray, std::real, ComplexNDArray, std::real) |
4543 | 1215 NDND_BOOL_OPS(ComplexNDArray, ComplexNDArray, 0.0) |
1216 | |
4514 | 1217 /* |
1218 ;;; Local Variables: *** | |
1219 ;;; mode: C++ *** | |
1220 ;;; End: *** | |
1221 */ |