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