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