Mercurial > hg > octave-nkf
annotate liboctave/dNDArray.cc @ 7919:9d080df0c843
new NDArray constructor for ArrayN<octave_idx_type>
author | David Bateman <dbateman@free.fr> |
---|---|
date | Mon, 30 Jun 2008 15:51:31 +0200 |
parents | 82be108cc558 |
children | 935be827eaf8 |
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 | |
559 | |
560 bool | |
561 NDArray::any_element_is_inf_or_nan (void) const | |
562 { | |
5275 | 563 octave_idx_type nel = nelem (); |
4634 | 564 |
5275 | 565 for (octave_idx_type i = 0; i < nel; i++) |
4634 | 566 { |
567 double val = elem (i); | |
568 if (xisinf (val) || xisnan (val)) | |
569 return true; | |
570 } | |
571 | |
572 return false; | |
573 } | |
574 | |
575 bool | |
5943 | 576 NDArray::any_element_not_one_or_zero (void) const |
577 { | |
578 octave_idx_type nel = nelem (); | |
579 | |
580 for (octave_idx_type i = 0; i < nel; i++) | |
581 { | |
582 double val = elem (i); | |
583 if (val != 0 && val != 1) | |
584 return true; | |
585 } | |
586 | |
587 return false; | |
588 } | |
589 | |
590 bool | |
6989 | 591 NDArray::all_elements_are_zero (void) const |
592 { | |
593 octave_idx_type nel = nelem (); | |
594 | |
595 for (octave_idx_type i = 0; i < nel; i++) | |
596 if (elem (i) != 0) | |
597 return false; | |
598 | |
599 return true; | |
600 } | |
601 | |
602 bool | |
4634 | 603 NDArray::all_elements_are_int_or_inf_or_nan (void) const |
604 { | |
5275 | 605 octave_idx_type nel = nelem (); |
4634 | 606 |
5275 | 607 for (octave_idx_type i = 0; i < nel; i++) |
4634 | 608 { |
609 double val = elem (i); | |
610 if (xisnan (val) || D_NINT (val) == val) | |
611 continue; | |
612 else | |
613 return false; | |
614 } | |
615 | |
616 return true; | |
617 } | |
618 | |
619 // Return nonzero if any element of M is not an integer. Also extract | |
620 // the largest and smallest values and return them in MAX_VAL and MIN_VAL. | |
621 | |
622 bool | |
623 NDArray::all_integers (double& max_val, double& min_val) const | |
624 { | |
5275 | 625 octave_idx_type nel = nelem (); |
4634 | 626 |
627 if (nel > 0) | |
628 { | |
629 max_val = elem (0); | |
630 min_val = elem (0); | |
631 } | |
632 else | |
633 return false; | |
634 | |
5275 | 635 for (octave_idx_type i = 0; i < nel; i++) |
4634 | 636 { |
637 double val = elem (i); | |
638 | |
639 if (val > max_val) | |
640 max_val = val; | |
641 | |
642 if (val < min_val) | |
643 min_val = val; | |
644 | |
645 if (D_NINT (val) != val) | |
646 return false; | |
647 } | |
648 | |
649 return true; | |
650 } | |
651 | |
652 bool | |
653 NDArray::too_large_for_float (void) const | |
654 { | |
5275 | 655 octave_idx_type nel = nelem (); |
4634 | 656 |
5275 | 657 for (octave_idx_type i = 0; i < nel; i++) |
4634 | 658 { |
659 double val = elem (i); | |
660 | |
5389 | 661 if (! (xisnan (val) || xisinf (val)) |
5387 | 662 && fabs (val) > FLT_MAX) |
4634 | 663 return true; |
664 } | |
665 | |
666 return false; | |
667 } | |
668 | |
5775 | 669 // FIXME -- this is not quite the right thing. |
4513 | 670 |
4556 | 671 boolNDArray |
4513 | 672 NDArray::all (int dim) const |
673 { | |
4569 | 674 MX_ND_ANY_ALL_REDUCTION (MX_ND_ALL_EVAL (MX_ND_ALL_EXPR), true); |
4513 | 675 } |
676 | |
4556 | 677 boolNDArray |
4513 | 678 NDArray::any (int dim) const |
679 { | |
5110 | 680 MX_ND_ANY_ALL_REDUCTION |
681 (MX_ND_ANY_EVAL (elem (iter_idx) != 0 | |
682 && ! lo_ieee_isnan (elem (iter_idx))), false); | |
4569 | 683 } |
684 | |
4584 | 685 NDArray |
4569 | 686 NDArray::cumprod (int dim) const |
687 { | |
4584 | 688 MX_ND_CUMULATIVE_OP (NDArray, double, 1, *); |
4569 | 689 } |
690 | |
4584 | 691 NDArray |
4569 | 692 NDArray::cumsum (int dim) const |
693 { | |
4584 | 694 MX_ND_CUMULATIVE_OP (NDArray, double, 0, +); |
4513 | 695 } |
696 | |
4569 | 697 NDArray |
698 NDArray::prod (int dim) const | |
699 { | |
700 MX_ND_REAL_OP_REDUCTION (*= elem (iter_idx), 1); | |
701 } | |
702 | |
703 NDArray | |
704 NDArray::sumsq (int dim) const | |
705 { | |
706 MX_ND_REAL_OP_REDUCTION (+= std::pow (elem (iter_idx), 2), 0); | |
707 } | |
708 | |
709 NDArray | |
710 NDArray::sum (int dim) const | |
711 { | |
712 MX_ND_REAL_OP_REDUCTION (+= elem (iter_idx), 0); | |
713 } | |
714 | |
4844 | 715 NDArray |
716 NDArray::max (int dim) const | |
717 { | |
5275 | 718 ArrayN<octave_idx_type> dummy_idx; |
4844 | 719 return max (dummy_idx, dim); |
720 } | |
721 | |
722 NDArray | |
5275 | 723 NDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const |
4844 | 724 { |
725 dim_vector dv = dims (); | |
726 dim_vector dr = dims (); | |
727 | |
728 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
729 return NDArray (); | |
730 | |
731 dr(dim) = 1; | |
732 | |
733 NDArray result (dr); | |
734 idx_arg.resize (dr); | |
735 | |
5275 | 736 octave_idx_type x_stride = 1; |
737 octave_idx_type x_len = dv(dim); | |
4844 | 738 for (int i = 0; i < dim; i++) |
739 x_stride *= dv(i); | |
740 | |
5275 | 741 for (octave_idx_type i = 0; i < dr.numel (); i++) |
4844 | 742 { |
5275 | 743 octave_idx_type x_offset; |
4844 | 744 if (x_stride == 1) |
745 x_offset = i * x_len; | |
746 else | |
747 { | |
5275 | 748 octave_idx_type x_offset2 = 0; |
4844 | 749 x_offset = i; |
750 while (x_offset >= x_stride) | |
751 { | |
752 x_offset -= x_stride; | |
753 x_offset2++; | |
754 } | |
755 x_offset += x_offset2 * x_stride * x_len; | |
756 } | |
757 | |
5275 | 758 octave_idx_type idx_j; |
4844 | 759 |
760 double tmp_max = octave_NaN; | |
761 | |
762 for (idx_j = 0; idx_j < x_len; idx_j++) | |
763 { | |
764 tmp_max = elem (idx_j * x_stride + x_offset); | |
765 | |
5389 | 766 if (! xisnan (tmp_max)) |
4844 | 767 break; |
768 } | |
769 | |
5275 | 770 for (octave_idx_type j = idx_j+1; j < x_len; j++) |
4844 | 771 { |
772 double tmp = elem (j * x_stride + x_offset); | |
773 | |
5389 | 774 if (xisnan (tmp)) |
4844 | 775 continue; |
776 else if (tmp > tmp_max) | |
777 { | |
778 idx_j = j; | |
779 tmp_max = tmp; | |
780 } | |
781 } | |
782 | |
783 result.elem (i) = tmp_max; | |
5389 | 784 idx_arg.elem (i) = xisnan (tmp_max) ? 0 : idx_j; |
4844 | 785 } |
786 | |
7600
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
787 result.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
788 idx_arg.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
789 |
4844 | 790 return result; |
791 } | |
792 | |
793 NDArray | |
794 NDArray::min (int dim) const | |
795 { | |
5275 | 796 ArrayN<octave_idx_type> dummy_idx; |
4844 | 797 return min (dummy_idx, dim); |
798 } | |
799 | |
800 NDArray | |
5275 | 801 NDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const |
4844 | 802 { |
803 dim_vector dv = dims (); | |
804 dim_vector dr = dims (); | |
805 | |
806 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
807 return NDArray (); | |
808 | |
809 dr(dim) = 1; | |
810 | |
811 NDArray result (dr); | |
812 idx_arg.resize (dr); | |
813 | |
5275 | 814 octave_idx_type x_stride = 1; |
815 octave_idx_type x_len = dv(dim); | |
4844 | 816 for (int i = 0; i < dim; i++) |
817 x_stride *= dv(i); | |
818 | |
5275 | 819 for (octave_idx_type i = 0; i < dr.numel (); i++) |
4844 | 820 { |
5275 | 821 octave_idx_type x_offset; |
4844 | 822 if (x_stride == 1) |
823 x_offset = i * x_len; | |
824 else | |
825 { | |
5275 | 826 octave_idx_type x_offset2 = 0; |
4844 | 827 x_offset = i; |
828 while (x_offset >= x_stride) | |
829 { | |
830 x_offset -= x_stride; | |
831 x_offset2++; | |
832 } | |
833 x_offset += x_offset2 * x_stride * x_len; | |
834 } | |
835 | |
5275 | 836 octave_idx_type idx_j; |
4844 | 837 |
838 double tmp_min = octave_NaN; | |
839 | |
840 for (idx_j = 0; idx_j < x_len; idx_j++) | |
841 { | |
842 tmp_min = elem (idx_j * x_stride + x_offset); | |
843 | |
5389 | 844 if (! xisnan (tmp_min)) |
4844 | 845 break; |
846 } | |
847 | |
5275 | 848 for (octave_idx_type j = idx_j+1; j < x_len; j++) |
4844 | 849 { |
850 double tmp = elem (j * x_stride + x_offset); | |
851 | |
5389 | 852 if (xisnan (tmp)) |
4844 | 853 continue; |
854 else if (tmp < tmp_min) | |
855 { | |
856 idx_j = j; | |
857 tmp_min = tmp; | |
858 } | |
859 } | |
860 | |
861 result.elem (i) = tmp_min; | |
5389 | 862 idx_arg.elem (i) = xisnan (tmp_min) ? 0 : idx_j; |
4844 | 863 } |
864 | |
7600
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
865 result.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
866 idx_arg.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
867 |
4844 | 868 return result; |
869 } | |
870 | |
4915 | 871 NDArray |
5275 | 872 NDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx) |
4758 | 873 { |
5073 | 874 if (rb.numel () > 0) |
875 insert (rb, ra_idx); | |
876 return *this; | |
877 } | |
878 | |
879 ComplexNDArray | |
5275 | 880 NDArray::concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx) |
5073 | 881 { |
882 ComplexNDArray retval (*this); | |
4940 | 883 if (rb.numel () > 0) |
4915 | 884 retval.insert (rb, ra_idx); |
885 return retval; | |
4758 | 886 } |
887 | |
5073 | 888 charNDArray |
5275 | 889 NDArray::concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx) |
5073 | 890 { |
891 charNDArray retval (dims ()); | |
5275 | 892 octave_idx_type nel = numel (); |
5073 | 893 |
5275 | 894 for (octave_idx_type i = 0; i < nel; i++) |
5073 | 895 { |
896 double d = elem (i); | |
897 | |
898 if (xisnan (d)) | |
899 { | |
900 (*current_liboctave_error_handler) | |
901 ("invalid conversion from NaN to character"); | |
902 return retval; | |
903 } | |
904 else | |
905 { | |
5275 | 906 octave_idx_type ival = NINTbig (d); |
5073 | 907 |
908 if (ival < 0 || ival > UCHAR_MAX) | |
5775 | 909 // FIXME -- is there something |
5073 | 910 // better we could do? Should we warn the user? |
911 ival = 0; | |
912 | |
913 retval.elem (i) = static_cast<char>(ival); | |
914 } | |
915 } | |
916 | |
917 if (rb.numel () == 0) | |
918 return retval; | |
919 | |
920 retval.insert (rb, ra_idx); | |
921 return retval; | |
922 } | |
923 | |
4634 | 924 NDArray |
925 real (const ComplexNDArray& a) | |
926 { | |
5275 | 927 octave_idx_type a_len = a.length (); |
4634 | 928 NDArray retval; |
929 if (a_len > 0) | |
930 retval = NDArray (mx_inline_real_dup (a.data (), a_len), a.dims ()); | |
931 return retval; | |
932 } | |
933 | |
934 NDArray | |
935 imag (const ComplexNDArray& a) | |
936 { | |
5275 | 937 octave_idx_type a_len = a.length (); |
4634 | 938 NDArray retval; |
939 if (a_len > 0) | |
940 retval = NDArray (mx_inline_imag_dup (a.data (), a_len), a.dims ()); | |
941 return retval; | |
942 } | |
943 | |
4915 | 944 NDArray& |
5275 | 945 NDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c) |
4915 | 946 { |
947 Array<double>::insert (a, r, c); | |
948 return *this; | |
949 } | |
950 | |
951 NDArray& | |
5275 | 952 NDArray::insert (const NDArray& a, const Array<octave_idx_type>& ra_idx) |
4915 | 953 { |
954 Array<double>::insert (a, ra_idx); | |
955 return *this; | |
956 } | |
957 | |
4634 | 958 NDArray |
4569 | 959 NDArray::abs (void) const |
960 { | |
4634 | 961 NDArray retval (dims ()); |
4569 | 962 |
5275 | 963 octave_idx_type nel = nelem (); |
4634 | 964 |
5275 | 965 for (octave_idx_type i = 0; i < nel; i++) |
4634 | 966 retval(i) = fabs (elem (i)); |
4569 | 967 |
968 return retval; | |
969 } | |
970 | |
4532 | 971 Matrix |
972 NDArray::matrix_value (void) const | |
973 { | |
974 Matrix retval; | |
975 | |
976 int nd = ndims (); | |
977 | |
978 switch (nd) | |
979 { | |
980 case 1: | |
981 retval = Matrix (Array2<double> (*this, dimensions(0), 1)); | |
982 break; | |
983 | |
984 case 2: | |
985 retval = Matrix (Array2<double> (*this, dimensions(0), dimensions(1))); | |
986 break; | |
987 | |
988 default: | |
989 (*current_liboctave_error_handler) | |
4770 | 990 ("invalid conversion of NDArray to Matrix"); |
4532 | 991 break; |
992 } | |
993 | |
994 return retval; | |
995 } | |
996 | |
997 void | |
5275 | 998 NDArray::increment_index (Array<octave_idx_type>& ra_idx, |
4532 | 999 const dim_vector& dimensions, |
1000 int start_dimension) | |
1001 { | |
1002 ::increment_index (ra_idx, dimensions, start_dimension); | |
1003 } | |
1004 | |
5275 | 1005 octave_idx_type |
1006 NDArray::compute_index (Array<octave_idx_type>& ra_idx, | |
4556 | 1007 const dim_vector& dimensions) |
1008 { | |
1009 return ::compute_index (ra_idx, dimensions); | |
1010 } | |
1011 | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1012 NDArray |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1013 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
|
1014 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1015 return MArrayN<double>::diag (k); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1016 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1017 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1018 NDArray |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1019 NDArray::map (dmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1020 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1021 return MArrayN<double>::map<double> (func_ptr (fcn)); |
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 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1024 ComplexNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1025 NDArray::map (cmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1026 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1027 return MArrayN<double>::map<Complex> (func_ptr (fcn)); |
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 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1030 boolNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1031 NDArray::map (bmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1032 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1033 return MArrayN<double>::map<bool> (func_ptr (fcn)); |
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 |
4687 | 1036 // This contains no information on the array structure !!! |
1037 std::ostream& | |
1038 operator << (std::ostream& os, const NDArray& a) | |
1039 { | |
5275 | 1040 octave_idx_type nel = a.nelem (); |
4687 | 1041 |
5275 | 1042 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 1043 { |
1044 os << " "; | |
1045 octave_write_double (os, a.elem (i)); | |
1046 os << "\n"; | |
1047 } | |
1048 return os; | |
1049 } | |
1050 | |
1051 std::istream& | |
1052 operator >> (std::istream& is, NDArray& a) | |
1053 { | |
5275 | 1054 octave_idx_type nel = a.nelem (); |
4687 | 1055 |
1056 if (nel < 1 ) | |
1057 is.clear (std::ios::badbit); | |
1058 else | |
1059 { | |
1060 double tmp; | |
5275 | 1061 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 1062 { |
1063 tmp = octave_read_double (is); | |
1064 if (is) | |
1065 a.elem (i) = tmp; | |
1066 else | |
1067 goto done; | |
1068 } | |
1069 } | |
1070 | |
1071 done: | |
1072 | |
1073 return is; | |
1074 } | |
1075 | |
5775 | 1076 // FIXME -- it would be nice to share code among the min/max |
4844 | 1077 // functions below. |
1078 | |
1079 #define EMPTY_RETURN_CHECK(T) \ | |
1080 if (nel == 0) \ | |
1081 return T (dv); | |
1082 | |
1083 NDArray | |
1084 min (double d, const NDArray& m) | |
1085 { | |
1086 dim_vector dv = m.dims (); | |
5275 | 1087 octave_idx_type nel = dv.numel (); |
4844 | 1088 |
1089 EMPTY_RETURN_CHECK (NDArray); | |
1090 | |
1091 NDArray result (dv); | |
1092 | |
5275 | 1093 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1094 { |
1095 OCTAVE_QUIT; | |
1096 result (i) = xmin (d, m (i)); | |
1097 } | |
1098 | |
1099 return result; | |
1100 } | |
1101 | |
1102 NDArray | |
1103 min (const NDArray& m, double d) | |
1104 { | |
1105 dim_vector dv = m.dims (); | |
5275 | 1106 octave_idx_type nel = dv.numel (); |
4844 | 1107 |
1108 EMPTY_RETURN_CHECK (NDArray); | |
1109 | |
1110 NDArray result (dv); | |
1111 | |
5275 | 1112 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1113 { |
1114 OCTAVE_QUIT; | |
1115 result (i) = xmin (d, m (i)); | |
1116 } | |
1117 | |
1118 return result; | |
1119 } | |
1120 | |
1121 NDArray | |
1122 min (const NDArray& a, const NDArray& b) | |
1123 { | |
1124 dim_vector dv = a.dims (); | |
5275 | 1125 octave_idx_type nel = dv.numel (); |
4844 | 1126 |
1127 if (dv != b.dims ()) | |
1128 { | |
1129 (*current_liboctave_error_handler) | |
1130 ("two-arg min expecting args of same size"); | |
1131 return NDArray (); | |
1132 } | |
1133 | |
1134 EMPTY_RETURN_CHECK (NDArray); | |
1135 | |
1136 NDArray result (dv); | |
1137 | |
5275 | 1138 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1139 { |
1140 OCTAVE_QUIT; | |
1141 result (i) = xmin (a (i), b (i)); | |
1142 } | |
1143 | |
1144 return result; | |
1145 } | |
1146 | |
1147 NDArray | |
1148 max (double d, const NDArray& m) | |
1149 { | |
1150 dim_vector dv = m.dims (); | |
5275 | 1151 octave_idx_type nel = dv.numel (); |
4844 | 1152 |
1153 EMPTY_RETURN_CHECK (NDArray); | |
1154 | |
1155 NDArray result (dv); | |
1156 | |
5275 | 1157 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1158 { |
1159 OCTAVE_QUIT; | |
1160 result (i) = xmax (d, m (i)); | |
1161 } | |
1162 | |
1163 return result; | |
1164 } | |
1165 | |
1166 NDArray | |
1167 max (const NDArray& m, double d) | |
1168 { | |
1169 dim_vector dv = m.dims (); | |
5275 | 1170 octave_idx_type nel = dv.numel (); |
4844 | 1171 |
1172 EMPTY_RETURN_CHECK (NDArray); | |
1173 | |
1174 NDArray result (dv); | |
1175 | |
5275 | 1176 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1177 { |
1178 OCTAVE_QUIT; | |
1179 result (i) = xmax (d, m (i)); | |
1180 } | |
1181 | |
1182 return result; | |
1183 } | |
1184 | |
1185 NDArray | |
1186 max (const NDArray& a, const NDArray& b) | |
1187 { | |
1188 dim_vector dv = a.dims (); | |
5275 | 1189 octave_idx_type nel = dv.numel (); |
4844 | 1190 |
1191 if (dv != b.dims ()) | |
1192 { | |
1193 (*current_liboctave_error_handler) | |
1194 ("two-arg max expecting args of same size"); | |
1195 return NDArray (); | |
1196 } | |
1197 | |
1198 EMPTY_RETURN_CHECK (NDArray); | |
1199 | |
1200 NDArray result (dv); | |
1201 | |
5275 | 1202 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1203 { |
1204 OCTAVE_QUIT; | |
1205 result (i) = xmax (a (i), b (i)); | |
1206 } | |
1207 | |
1208 return result; | |
1209 } | |
1210 | |
4543 | 1211 NDS_CMP_OPS(NDArray, , double, ) |
1212 NDS_BOOL_OPS(NDArray, double, 0.0) | |
1213 | |
1214 SND_CMP_OPS(double, , NDArray, ) | |
1215 SND_BOOL_OPS(double, NDArray, 0.0) | |
1216 | |
1217 NDND_CMP_OPS(NDArray, , NDArray, ) | |
1218 NDND_BOOL_OPS(NDArray, NDArray, 0.0) | |
1219 | |
4513 | 1220 /* |
1221 ;;; Local Variables: *** | |
1222 ;;; mode: C++ *** | |
1223 ;;; End: *** | |
1224 */ |