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