Mercurial > octave-nkf
annotate liboctave/CNDArray.cc @ 8743:1bd918cfb6e2
reimplement any & all using the new reduction code
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Sat, 14 Feb 2009 19:50:43 +0100 |
parents | 53b4fdeacc2e |
children | 9f7ce4bf7650 |
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 { | |
8743
1bd918cfb6e2
reimplement any & all using the new reduction code
Jaroslav Hajek <highegg@gmail.com>
parents:
8736
diff
changeset
|
625 return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_all); |
4514 | 626 } |
627 | |
4556 | 628 boolNDArray |
4514 | 629 ComplexNDArray::any (int dim) const |
630 { | |
8743
1bd918cfb6e2
reimplement any & all using the new reduction code
Jaroslav Hajek <highegg@gmail.com>
parents:
8736
diff
changeset
|
631 return do_mx_red_op<boolNDArray> (*this, dim, mx_inline_any); |
4569 | 632 } |
633 | |
4584 | 634 ComplexNDArray |
4569 | 635 ComplexNDArray::cumprod (int dim) const |
636 { | |
8736
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
637 return do_mx_cum_op<ComplexNDArray> (*this, dim, mx_inline_cumprod); |
4569 | 638 } |
639 | |
4584 | 640 ComplexNDArray |
4569 | 641 ComplexNDArray::cumsum (int dim) const |
642 { | |
8736
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
643 return do_mx_cum_op<ComplexNDArray> (*this, dim, mx_inline_cumsum); |
4569 | 644 } |
645 | |
646 ComplexNDArray | |
647 ComplexNDArray::prod (int dim) const | |
648 { | |
8736
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
649 return do_mx_red_op<ComplexNDArray> (*this, dim, mx_inline_prod); |
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
650 } |
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
651 |
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
652 ComplexNDArray |
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
653 ComplexNDArray::sum (int dim) const |
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
654 { |
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
655 return do_mx_red_op<ComplexNDArray> (*this, dim, mx_inline_sum); |
4569 | 656 } |
657 | |
658 ComplexNDArray | |
659 ComplexNDArray::sumsq (int dim) const | |
660 { | |
8736
53b4fdeacc2e
improve reduction functions
Jaroslav Hajek <highegg@gmail.com>
parents:
8650
diff
changeset
|
661 return do_mx_red_op<NDArray> (*this, dim, mx_inline_sumsq); |
4569 | 662 } |
663 | |
4915 | 664 ComplexNDArray |
5275 | 665 ComplexNDArray::concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx) |
4915 | 666 { |
4940 | 667 if (rb.numel () > 0) |
5073 | 668 insert (rb, ra_idx); |
669 return *this; | |
4915 | 670 } |
671 | |
672 ComplexNDArray | |
5275 | 673 ComplexNDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx) |
4758 | 674 { |
4915 | 675 ComplexNDArray tmp (rb); |
4940 | 676 if (rb.numel () > 0) |
5073 | 677 insert (tmp, ra_idx); |
678 return *this; | |
4915 | 679 } |
680 | |
681 ComplexNDArray | |
5275 | 682 concat (NDArray& ra, ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx) |
4915 | 683 { |
684 ComplexNDArray retval (ra); | |
4940 | 685 if (rb.numel () > 0) |
4915 | 686 retval.insert (rb, ra_idx); |
687 return retval; | |
4758 | 688 } |
689 | |
4844 | 690 static const Complex Complex_NaN_result (octave_NaN, octave_NaN); |
691 | |
692 ComplexNDArray | |
693 ComplexNDArray::max (int dim) const | |
694 { | |
5275 | 695 ArrayN<octave_idx_type> dummy_idx; |
4844 | 696 return max (dummy_idx, dim); |
697 } | |
698 | |
699 ComplexNDArray | |
5275 | 700 ComplexNDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const |
4844 | 701 { |
702 dim_vector dv = dims (); | |
703 dim_vector dr = dims (); | |
704 | |
705 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
706 return ComplexNDArray (); | |
707 | |
708 dr(dim) = 1; | |
709 | |
710 ComplexNDArray result (dr); | |
711 idx_arg.resize (dr); | |
712 | |
5275 | 713 octave_idx_type x_stride = 1; |
714 octave_idx_type x_len = dv(dim); | |
4844 | 715 for (int i = 0; i < dim; i++) |
716 x_stride *= dv(i); | |
717 | |
5275 | 718 for (octave_idx_type i = 0; i < dr.numel (); i++) |
4844 | 719 { |
5275 | 720 octave_idx_type x_offset; |
4844 | 721 if (x_stride == 1) |
722 x_offset = i * x_len; | |
723 else | |
724 { | |
5275 | 725 octave_idx_type x_offset2 = 0; |
4844 | 726 x_offset = i; |
727 while (x_offset >= x_stride) | |
728 { | |
729 x_offset -= x_stride; | |
730 x_offset2++; | |
731 } | |
732 x_offset += x_offset2 * x_stride * x_len; | |
733 } | |
734 | |
5275 | 735 octave_idx_type idx_j; |
4844 | 736 |
737 Complex tmp_max; | |
738 | |
739 double abs_max = octave_NaN; | |
740 | |
741 for (idx_j = 0; idx_j < x_len; idx_j++) | |
742 { | |
743 tmp_max = elem (idx_j * x_stride + x_offset); | |
744 | |
5389 | 745 if (! xisnan (tmp_max)) |
4844 | 746 { |
5260 | 747 abs_max = std::abs(tmp_max); |
4844 | 748 break; |
749 } | |
750 } | |
751 | |
5275 | 752 for (octave_idx_type j = idx_j+1; j < x_len; j++) |
4844 | 753 { |
754 Complex tmp = elem (j * x_stride + x_offset); | |
755 | |
5389 | 756 if (xisnan (tmp)) |
4844 | 757 continue; |
758 | |
5260 | 759 double abs_tmp = std::abs (tmp); |
4844 | 760 |
761 if (abs_tmp > abs_max) | |
762 { | |
763 idx_j = j; | |
764 tmp_max = tmp; | |
765 abs_max = abs_tmp; | |
766 } | |
767 } | |
768 | |
5389 | 769 if (xisnan (tmp_max)) |
4844 | 770 { |
771 result.elem (i) = Complex_NaN_result; | |
772 idx_arg.elem (i) = 0; | |
773 } | |
774 else | |
775 { | |
776 result.elem (i) = tmp_max; | |
777 idx_arg.elem (i) = idx_j; | |
778 } | |
779 } | |
780 | |
7600
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
781 result.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
782 idx_arg.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
783 |
4844 | 784 return result; |
785 } | |
786 | |
787 ComplexNDArray | |
788 ComplexNDArray::min (int dim) const | |
789 { | |
5275 | 790 ArrayN<octave_idx_type> dummy_idx; |
4844 | 791 return min (dummy_idx, dim); |
792 } | |
793 | |
794 ComplexNDArray | |
5275 | 795 ComplexNDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const |
4844 | 796 { |
797 dim_vector dv = dims (); | |
798 dim_vector dr = dims (); | |
799 | |
800 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
801 return ComplexNDArray (); | |
802 | |
803 dr(dim) = 1; | |
804 | |
805 ComplexNDArray result (dr); | |
806 idx_arg.resize (dr); | |
807 | |
5275 | 808 octave_idx_type x_stride = 1; |
809 octave_idx_type x_len = dv(dim); | |
4844 | 810 for (int i = 0; i < dim; i++) |
811 x_stride *= dv(i); | |
812 | |
5275 | 813 for (octave_idx_type i = 0; i < dr.numel (); i++) |
4844 | 814 { |
5275 | 815 octave_idx_type x_offset; |
4844 | 816 if (x_stride == 1) |
817 x_offset = i * x_len; | |
818 else | |
819 { | |
5275 | 820 octave_idx_type x_offset2 = 0; |
4844 | 821 x_offset = i; |
822 while (x_offset >= x_stride) | |
823 { | |
824 x_offset -= x_stride; | |
825 x_offset2++; | |
826 } | |
827 x_offset += x_offset2 * x_stride * x_len; | |
828 } | |
829 | |
5275 | 830 octave_idx_type idx_j; |
4844 | 831 |
832 Complex tmp_min; | |
833 | |
834 double abs_min = octave_NaN; | |
835 | |
836 for (idx_j = 0; idx_j < x_len; idx_j++) | |
837 { | |
838 tmp_min = elem (idx_j * x_stride + x_offset); | |
839 | |
5389 | 840 if (! xisnan (tmp_min)) |
4844 | 841 { |
5260 | 842 abs_min = std::abs(tmp_min); |
4844 | 843 break; |
844 } | |
845 } | |
846 | |
5275 | 847 for (octave_idx_type j = idx_j+1; j < x_len; j++) |
4844 | 848 { |
849 Complex tmp = elem (j * x_stride + x_offset); | |
850 | |
5389 | 851 if (xisnan (tmp)) |
4844 | 852 continue; |
853 | |
5260 | 854 double abs_tmp = std::abs (tmp); |
4844 | 855 |
856 if (abs_tmp < abs_min) | |
857 { | |
858 idx_j = j; | |
859 tmp_min = tmp; | |
860 abs_min = abs_tmp; | |
861 } | |
862 } | |
863 | |
5389 | 864 if (xisnan (tmp_min)) |
4844 | 865 { |
866 result.elem (i) = Complex_NaN_result; | |
867 idx_arg.elem (i) = 0; | |
868 } | |
869 else | |
870 { | |
871 result.elem (i) = tmp_min; | |
872 idx_arg.elem (i) = idx_j; | |
873 } | |
874 } | |
875 | |
7600
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
876 result.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
877 idx_arg.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
878 |
4844 | 879 return result; |
880 } | |
881 | |
4634 | 882 NDArray |
4569 | 883 ComplexNDArray::abs (void) const |
884 { | |
8650
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
885 return NDArray (mx_inline_cabs_dup (data (), length ()), |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
886 dims ()); |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
887 } |
4634 | 888 |
8650
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
889 ComplexNDArray |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
890 conj (const ComplexNDArray& a) |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
891 { |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
892 return ComplexNDArray (mx_inline_conj_dup (a.data (), a.length ()), |
a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
893 a.dims ()); |
4514 | 894 } |
895 | |
4765 | 896 ComplexNDArray& |
5275 | 897 ComplexNDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c) |
4765 | 898 { |
899 dim_vector a_dv = a.dims (); | |
900 | |
901 int n = a_dv.length (); | |
902 | |
903 if (n == dimensions.length ()) | |
904 { | |
5275 | 905 Array<octave_idx_type> a_ra_idx (a_dv.length (), 0); |
4765 | 906 |
907 a_ra_idx.elem (0) = r; | |
908 a_ra_idx.elem (1) = c; | |
909 | |
910 for (int i = 0; i < n; i++) | |
911 { | |
912 if (a_ra_idx (i) < 0 || (a_ra_idx (i) + a_dv (i)) > dimensions (i)) | |
913 { | |
914 (*current_liboctave_error_handler) | |
915 ("Array<T>::insert: range error for insert"); | |
916 return *this; | |
917 } | |
918 } | |
919 | |
920 a_ra_idx.elem (0) = 0; | |
921 a_ra_idx.elem (1) = 0; | |
922 | |
5275 | 923 octave_idx_type n_elt = a.numel (); |
4765 | 924 |
925 // IS make_unique () NECCESSARY HERE?? | |
926 | |
5275 | 927 for (octave_idx_type i = 0; i < n_elt; i++) |
4765 | 928 { |
5275 | 929 Array<octave_idx_type> ra_idx = a_ra_idx; |
4765 | 930 |
931 ra_idx.elem (0) = a_ra_idx (0) + r; | |
932 ra_idx.elem (1) = a_ra_idx (1) + c; | |
933 | |
934 elem (ra_idx) = a.elem (a_ra_idx); | |
935 | |
936 increment_index (a_ra_idx, a_dv); | |
937 } | |
938 } | |
939 else | |
940 (*current_liboctave_error_handler) | |
941 ("Array<T>::insert: invalid indexing operation"); | |
942 | |
943 return *this; | |
944 } | |
945 | |
946 ComplexNDArray& | |
5275 | 947 ComplexNDArray::insert (const ComplexNDArray& a, octave_idx_type r, octave_idx_type c) |
4765 | 948 { |
949 Array<Complex>::insert (a, r, c); | |
950 return *this; | |
951 } | |
952 | |
4915 | 953 ComplexNDArray& |
5275 | 954 ComplexNDArray::insert (const ComplexNDArray& a, const Array<octave_idx_type>& ra_idx) |
4915 | 955 { |
956 Array<Complex>::insert (a, ra_idx); | |
957 return *this; | |
958 } | |
959 | |
4514 | 960 ComplexMatrix |
961 ComplexNDArray::matrix_value (void) const | |
962 { | |
963 ComplexMatrix retval; | |
964 | |
965 int nd = ndims (); | |
966 | |
967 switch (nd) | |
968 { | |
969 case 1: | |
970 retval = ComplexMatrix (Array2<Complex> (*this, dimensions(0), 1)); | |
971 break; | |
972 | |
973 case 2: | |
974 retval = ComplexMatrix (Array2<Complex> (*this, dimensions(0), | |
975 dimensions(1))); | |
976 break; | |
977 | |
978 default: | |
979 (*current_liboctave_error_handler) | |
4770 | 980 ("invalid conversion of ComplexNDArray to ComplexMatrix"); |
4514 | 981 break; |
982 } | |
983 | |
984 return retval; | |
985 } | |
986 | |
4532 | 987 void |
5275 | 988 ComplexNDArray::increment_index (Array<octave_idx_type>& ra_idx, |
4532 | 989 const dim_vector& dimensions, |
990 int start_dimension) | |
991 { | |
992 ::increment_index (ra_idx, dimensions, start_dimension); | |
993 } | |
994 | |
5275 | 995 octave_idx_type |
996 ComplexNDArray::compute_index (Array<octave_idx_type>& ra_idx, | |
4556 | 997 const dim_vector& dimensions) |
998 { | |
999 return ::compute_index (ra_idx, dimensions); | |
1000 } | |
1001 | |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1002 ComplexNDArray |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1003 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
|
1004 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1005 return MArrayN<Complex>::diag (k); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1006 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1007 |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1008 NDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1009 ComplexNDArray::map (dmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1010 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1011 return MArrayN<Complex>::map<double> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1012 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1013 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1014 ComplexNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1015 ComplexNDArray::map (cmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1016 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1017 return MArrayN<Complex>::map<Complex> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1018 } |
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 boolNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1021 ComplexNDArray::map (bmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1022 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1023 return MArrayN<Complex>::map<bool> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1024 } |
4687 | 1025 |
1026 // This contains no information on the array structure !!! | |
1027 std::ostream& | |
1028 operator << (std::ostream& os, const ComplexNDArray& a) | |
1029 { | |
5275 | 1030 octave_idx_type nel = a.nelem (); |
4687 | 1031 |
5275 | 1032 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 1033 { |
1034 os << " "; | |
1035 octave_write_complex (os, a.elem (i)); | |
1036 os << "\n"; | |
1037 } | |
1038 return os; | |
1039 } | |
1040 | |
1041 std::istream& | |
1042 operator >> (std::istream& is, ComplexNDArray& a) | |
1043 { | |
5275 | 1044 octave_idx_type nel = a.nelem (); |
4687 | 1045 |
1046 if (nel < 1 ) | |
1047 is.clear (std::ios::badbit); | |
1048 else | |
1049 { | |
1050 Complex tmp; | |
5275 | 1051 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 1052 { |
1053 tmp = octave_read_complex (is); | |
1054 if (is) | |
1055 a.elem (i) = tmp; | |
1056 else | |
1057 goto done; | |
1058 } | |
1059 } | |
1060 | |
1061 done: | |
1062 | |
1063 return is; | |
1064 } | |
1065 | |
5775 | 1066 // FIXME -- it would be nice to share code among the min/max |
4844 | 1067 // functions below. |
1068 | |
1069 #define EMPTY_RETURN_CHECK(T) \ | |
1070 if (nel == 0) \ | |
1071 return T (dv); | |
1072 | |
1073 ComplexNDArray | |
1074 min (const Complex& c, const ComplexNDArray& m) | |
1075 { | |
1076 dim_vector dv = m.dims (); | |
1077 int nel = dv.numel (); | |
1078 | |
1079 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1080 | |
1081 ComplexNDArray result (dv); | |
1082 | |
1083 for (int i = 0; i < nel; i++) | |
1084 { | |
1085 OCTAVE_QUIT; | |
1086 result (i) = xmin (c, m (i)); | |
1087 } | |
1088 | |
1089 return result; | |
1090 } | |
1091 | |
1092 ComplexNDArray | |
1093 min (const ComplexNDArray& m, const Complex& c) | |
1094 { | |
1095 dim_vector dv = m.dims (); | |
1096 int nel = dv.numel (); | |
1097 | |
1098 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1099 | |
1100 ComplexNDArray result (dv); | |
1101 | |
1102 for (int i = 0; i < nel; i++) | |
1103 { | |
1104 OCTAVE_QUIT; | |
1105 result (i) = xmin (c, m (i)); | |
1106 } | |
1107 | |
1108 return result; | |
1109 } | |
1110 | |
1111 ComplexNDArray | |
1112 min (const ComplexNDArray& a, const ComplexNDArray& b) | |
1113 { | |
1114 dim_vector dv = a.dims (); | |
1115 int nel = dv.numel (); | |
1116 | |
1117 if (dv != b.dims ()) | |
1118 { | |
1119 (*current_liboctave_error_handler) | |
1120 ("two-arg min expecting args of same size"); | |
1121 return ComplexNDArray (); | |
1122 } | |
1123 | |
1124 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1125 | |
1126 ComplexNDArray result (dv); | |
1127 | |
1128 for (int i = 0; i < nel; i++) | |
1129 { | |
1130 OCTAVE_QUIT; | |
1131 result (i) = xmin (a (i), b (i)); | |
1132 } | |
1133 | |
1134 return result; | |
1135 } | |
1136 | |
1137 ComplexNDArray | |
1138 max (const Complex& c, const ComplexNDArray& m) | |
1139 { | |
1140 dim_vector dv = m.dims (); | |
1141 int nel = dv.numel (); | |
1142 | |
1143 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1144 | |
1145 ComplexNDArray result (dv); | |
1146 | |
1147 for (int i = 0; i < nel; i++) | |
1148 { | |
1149 OCTAVE_QUIT; | |
1150 result (i) = xmax (c, m (i)); | |
1151 } | |
1152 | |
1153 return result; | |
1154 } | |
1155 | |
1156 ComplexNDArray | |
1157 max (const ComplexNDArray& m, const Complex& c) | |
1158 { | |
1159 dim_vector dv = m.dims (); | |
1160 int nel = dv.numel (); | |
1161 | |
1162 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1163 | |
1164 ComplexNDArray result (dv); | |
1165 | |
1166 for (int i = 0; i < nel; i++) | |
1167 { | |
1168 OCTAVE_QUIT; | |
1169 result (i) = xmax (c, m (i)); | |
1170 } | |
1171 | |
1172 return result; | |
1173 } | |
1174 | |
1175 ComplexNDArray | |
1176 max (const ComplexNDArray& a, const ComplexNDArray& b) | |
1177 { | |
1178 dim_vector dv = a.dims (); | |
1179 int nel = dv.numel (); | |
1180 | |
1181 if (dv != b.dims ()) | |
1182 { | |
1183 (*current_liboctave_error_handler) | |
1184 ("two-arg max expecting args of same size"); | |
1185 return ComplexNDArray (); | |
1186 } | |
1187 | |
1188 EMPTY_RETURN_CHECK (ComplexNDArray); | |
1189 | |
1190 ComplexNDArray result (dv); | |
1191 | |
1192 for (int i = 0; i < nel; i++) | |
1193 { | |
1194 OCTAVE_QUIT; | |
1195 result (i) = xmax (a (i), b (i)); | |
1196 } | |
1197 | |
1198 return result; | |
1199 } | |
1200 | |
5260 | 1201 NDS_CMP_OPS(ComplexNDArray, std::real, Complex, std::real) |
4543 | 1202 NDS_BOOL_OPS(ComplexNDArray, Complex, 0.0) |
1203 | |
5260 | 1204 SND_CMP_OPS(Complex, std::real, ComplexNDArray, std::real) |
4543 | 1205 SND_BOOL_OPS(Complex, ComplexNDArray, 0.0) |
1206 | |
5260 | 1207 NDND_CMP_OPS(ComplexNDArray, std::real, ComplexNDArray, std::real) |
4543 | 1208 NDND_BOOL_OPS(ComplexNDArray, ComplexNDArray, 0.0) |
1209 | |
4514 | 1210 /* |
1211 ;;; Local Variables: *** | |
1212 ;;; mode: C++ *** | |
1213 ;;; End: *** | |
1214 */ |