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