Mercurial > hg > octave-lyh
annotate liboctave/dNDArray.cc @ 8650:a1ae2aae903e
abs,real,imag,conj: use code from mx-inlines rather than the generic map
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Mon, 02 Feb 2009 15:35:32 +0100 |
parents | 25bc2d31e1bf |
children | 53b4fdeacc2e |
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 { | |
4569 | 692 MX_ND_ANY_ALL_REDUCTION (MX_ND_ALL_EVAL (MX_ND_ALL_EXPR), true); |
4513 | 693 } |
694 | |
4556 | 695 boolNDArray |
4513 | 696 NDArray::any (int dim) const |
697 { | |
5110 | 698 MX_ND_ANY_ALL_REDUCTION |
699 (MX_ND_ANY_EVAL (elem (iter_idx) != 0 | |
700 && ! lo_ieee_isnan (elem (iter_idx))), false); | |
4569 | 701 } |
702 | |
4584 | 703 NDArray |
4569 | 704 NDArray::cumprod (int dim) const |
705 { | |
4584 | 706 MX_ND_CUMULATIVE_OP (NDArray, double, 1, *); |
4569 | 707 } |
708 | |
4584 | 709 NDArray |
4569 | 710 NDArray::cumsum (int dim) const |
711 { | |
4584 | 712 MX_ND_CUMULATIVE_OP (NDArray, double, 0, +); |
4513 | 713 } |
714 | |
4569 | 715 NDArray |
716 NDArray::prod (int dim) const | |
717 { | |
718 MX_ND_REAL_OP_REDUCTION (*= elem (iter_idx), 1); | |
719 } | |
720 | |
721 NDArray | |
722 NDArray::sumsq (int dim) const | |
723 { | |
724 MX_ND_REAL_OP_REDUCTION (+= std::pow (elem (iter_idx), 2), 0); | |
725 } | |
726 | |
727 NDArray | |
728 NDArray::sum (int dim) const | |
729 { | |
730 MX_ND_REAL_OP_REDUCTION (+= elem (iter_idx), 0); | |
731 } | |
732 | |
4844 | 733 NDArray |
734 NDArray::max (int dim) const | |
735 { | |
5275 | 736 ArrayN<octave_idx_type> dummy_idx; |
4844 | 737 return max (dummy_idx, dim); |
738 } | |
739 | |
740 NDArray | |
5275 | 741 NDArray::max (ArrayN<octave_idx_type>& idx_arg, int dim) const |
4844 | 742 { |
743 dim_vector dv = dims (); | |
744 dim_vector dr = dims (); | |
745 | |
746 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
747 return NDArray (); | |
748 | |
749 dr(dim) = 1; | |
750 | |
751 NDArray result (dr); | |
752 idx_arg.resize (dr); | |
753 | |
5275 | 754 octave_idx_type x_stride = 1; |
755 octave_idx_type x_len = dv(dim); | |
4844 | 756 for (int i = 0; i < dim; i++) |
757 x_stride *= dv(i); | |
758 | |
5275 | 759 for (octave_idx_type i = 0; i < dr.numel (); i++) |
4844 | 760 { |
5275 | 761 octave_idx_type x_offset; |
4844 | 762 if (x_stride == 1) |
763 x_offset = i * x_len; | |
764 else | |
765 { | |
5275 | 766 octave_idx_type x_offset2 = 0; |
4844 | 767 x_offset = i; |
768 while (x_offset >= x_stride) | |
769 { | |
770 x_offset -= x_stride; | |
771 x_offset2++; | |
772 } | |
773 x_offset += x_offset2 * x_stride * x_len; | |
774 } | |
775 | |
5275 | 776 octave_idx_type idx_j; |
4844 | 777 |
778 double tmp_max = octave_NaN; | |
779 | |
780 for (idx_j = 0; idx_j < x_len; idx_j++) | |
781 { | |
782 tmp_max = elem (idx_j * x_stride + x_offset); | |
783 | |
5389 | 784 if (! xisnan (tmp_max)) |
4844 | 785 break; |
786 } | |
787 | |
5275 | 788 for (octave_idx_type j = idx_j+1; j < x_len; j++) |
4844 | 789 { |
790 double tmp = elem (j * x_stride + x_offset); | |
791 | |
5389 | 792 if (xisnan (tmp)) |
4844 | 793 continue; |
794 else if (tmp > tmp_max) | |
795 { | |
796 idx_j = j; | |
797 tmp_max = tmp; | |
798 } | |
799 } | |
800 | |
801 result.elem (i) = tmp_max; | |
5389 | 802 idx_arg.elem (i) = xisnan (tmp_max) ? 0 : idx_j; |
4844 | 803 } |
804 | |
7600
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
805 result.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
806 idx_arg.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
807 |
4844 | 808 return result; |
809 } | |
810 | |
811 NDArray | |
812 NDArray::min (int dim) const | |
813 { | |
5275 | 814 ArrayN<octave_idx_type> dummy_idx; |
4844 | 815 return min (dummy_idx, dim); |
816 } | |
817 | |
818 NDArray | |
5275 | 819 NDArray::min (ArrayN<octave_idx_type>& idx_arg, int dim) const |
4844 | 820 { |
821 dim_vector dv = dims (); | |
822 dim_vector dr = dims (); | |
823 | |
824 if (dv.numel () == 0 || dim > dv.length () || dim < 0) | |
825 return NDArray (); | |
826 | |
827 dr(dim) = 1; | |
828 | |
829 NDArray result (dr); | |
830 idx_arg.resize (dr); | |
831 | |
5275 | 832 octave_idx_type x_stride = 1; |
833 octave_idx_type x_len = dv(dim); | |
4844 | 834 for (int i = 0; i < dim; i++) |
835 x_stride *= dv(i); | |
836 | |
5275 | 837 for (octave_idx_type i = 0; i < dr.numel (); i++) |
4844 | 838 { |
5275 | 839 octave_idx_type x_offset; |
4844 | 840 if (x_stride == 1) |
841 x_offset = i * x_len; | |
842 else | |
843 { | |
5275 | 844 octave_idx_type x_offset2 = 0; |
4844 | 845 x_offset = i; |
846 while (x_offset >= x_stride) | |
847 { | |
848 x_offset -= x_stride; | |
849 x_offset2++; | |
850 } | |
851 x_offset += x_offset2 * x_stride * x_len; | |
852 } | |
853 | |
5275 | 854 octave_idx_type idx_j; |
4844 | 855 |
856 double tmp_min = octave_NaN; | |
857 | |
858 for (idx_j = 0; idx_j < x_len; idx_j++) | |
859 { | |
860 tmp_min = elem (idx_j * x_stride + x_offset); | |
861 | |
5389 | 862 if (! xisnan (tmp_min)) |
4844 | 863 break; |
864 } | |
865 | |
5275 | 866 for (octave_idx_type j = idx_j+1; j < x_len; j++) |
4844 | 867 { |
868 double tmp = elem (j * x_stride + x_offset); | |
869 | |
5389 | 870 if (xisnan (tmp)) |
4844 | 871 continue; |
872 else if (tmp < tmp_min) | |
873 { | |
874 idx_j = j; | |
875 tmp_min = tmp; | |
876 } | |
877 } | |
878 | |
879 result.elem (i) = tmp_min; | |
5389 | 880 idx_arg.elem (i) = xisnan (tmp_min) ? 0 : idx_j; |
4844 | 881 } |
882 | |
7600
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
883 result.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
884 idx_arg.chop_trailing_singletons (); |
24abf5a702d9
Chop trailing singletons in min/max functions
David Bateman <dbateman@free.fr>
parents:
7503
diff
changeset
|
885 |
4844 | 886 return result; |
887 } | |
888 | |
4915 | 889 NDArray |
5275 | 890 NDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx) |
4758 | 891 { |
5073 | 892 if (rb.numel () > 0) |
893 insert (rb, ra_idx); | |
894 return *this; | |
895 } | |
896 | |
897 ComplexNDArray | |
5275 | 898 NDArray::concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx) |
5073 | 899 { |
900 ComplexNDArray retval (*this); | |
4940 | 901 if (rb.numel () > 0) |
4915 | 902 retval.insert (rb, ra_idx); |
903 return retval; | |
4758 | 904 } |
905 | |
5073 | 906 charNDArray |
5275 | 907 NDArray::concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx) |
5073 | 908 { |
909 charNDArray retval (dims ()); | |
5275 | 910 octave_idx_type nel = numel (); |
5073 | 911 |
5275 | 912 for (octave_idx_type i = 0; i < nel; i++) |
5073 | 913 { |
914 double d = elem (i); | |
915 | |
916 if (xisnan (d)) | |
917 { | |
918 (*current_liboctave_error_handler) | |
919 ("invalid conversion from NaN to character"); | |
920 return retval; | |
921 } | |
922 else | |
923 { | |
5275 | 924 octave_idx_type ival = NINTbig (d); |
5073 | 925 |
926 if (ival < 0 || ival > UCHAR_MAX) | |
5775 | 927 // FIXME -- is there something |
5073 | 928 // better we could do? Should we warn the user? |
929 ival = 0; | |
930 | |
931 retval.elem (i) = static_cast<char>(ival); | |
932 } | |
933 } | |
934 | |
935 if (rb.numel () == 0) | |
936 return retval; | |
937 | |
938 retval.insert (rb, ra_idx); | |
939 return retval; | |
940 } | |
941 | |
4634 | 942 NDArray |
943 real (const ComplexNDArray& a) | |
944 { | |
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
|
945 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
|
946 a.dims ()); |
4634 | 947 } |
948 | |
949 NDArray | |
950 imag (const ComplexNDArray& a) | |
951 { | |
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
|
952 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
|
953 a.dims ()); |
4634 | 954 } |
955 | |
4915 | 956 NDArray& |
5275 | 957 NDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c) |
4915 | 958 { |
959 Array<double>::insert (a, r, c); | |
960 return *this; | |
961 } | |
962 | |
963 NDArray& | |
5275 | 964 NDArray::insert (const NDArray& a, const Array<octave_idx_type>& ra_idx) |
4915 | 965 { |
966 Array<double>::insert (a, ra_idx); | |
967 return *this; | |
968 } | |
969 | |
4634 | 970 NDArray |
4569 | 971 NDArray::abs (void) const |
972 { | |
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
|
973 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
|
974 dims ()); |
4569 | 975 } |
976 | |
4532 | 977 Matrix |
978 NDArray::matrix_value (void) const | |
979 { | |
980 Matrix retval; | |
981 | |
982 int nd = ndims (); | |
983 | |
984 switch (nd) | |
985 { | |
986 case 1: | |
987 retval = Matrix (Array2<double> (*this, dimensions(0), 1)); | |
988 break; | |
989 | |
990 case 2: | |
991 retval = Matrix (Array2<double> (*this, dimensions(0), dimensions(1))); | |
992 break; | |
993 | |
994 default: | |
995 (*current_liboctave_error_handler) | |
4770 | 996 ("invalid conversion of NDArray to Matrix"); |
4532 | 997 break; |
998 } | |
999 | |
1000 return retval; | |
1001 } | |
1002 | |
1003 void | |
5275 | 1004 NDArray::increment_index (Array<octave_idx_type>& ra_idx, |
4532 | 1005 const dim_vector& dimensions, |
1006 int start_dimension) | |
1007 { | |
1008 ::increment_index (ra_idx, dimensions, start_dimension); | |
1009 } | |
1010 | |
5275 | 1011 octave_idx_type |
1012 NDArray::compute_index (Array<octave_idx_type>& ra_idx, | |
4556 | 1013 const dim_vector& dimensions) |
1014 { | |
1015 return ::compute_index (ra_idx, dimensions); | |
1016 } | |
1017 | |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1018 NDArray |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1019 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
|
1020 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1021 return MArrayN<double>::diag (k); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1022 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1023 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7600
diff
changeset
|
1024 NDArray |
7503
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1025 NDArray::map (dmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1026 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1027 return MArrayN<double>::map<double> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1028 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1029 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1030 ComplexNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1031 NDArray::map (cmapper fcn) const |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1032 { |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1033 return MArrayN<double>::map<Complex> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1034 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1035 |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1036 boolNDArray |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1037 NDArray::map (bmapper fcn) const |
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 return MArrayN<double>::map<bool> (func_ptr (fcn)); |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1040 } |
8c32f95c2639
convert mapper functions to new format
David Bateman <dbateman@free.fr>
parents:
7017
diff
changeset
|
1041 |
4687 | 1042 // This contains no information on the array structure !!! |
1043 std::ostream& | |
1044 operator << (std::ostream& os, const NDArray& a) | |
1045 { | |
5275 | 1046 octave_idx_type nel = a.nelem (); |
4687 | 1047 |
5275 | 1048 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 1049 { |
1050 os << " "; | |
1051 octave_write_double (os, a.elem (i)); | |
1052 os << "\n"; | |
1053 } | |
1054 return os; | |
1055 } | |
1056 | |
1057 std::istream& | |
1058 operator >> (std::istream& is, NDArray& a) | |
1059 { | |
5275 | 1060 octave_idx_type nel = a.nelem (); |
4687 | 1061 |
1062 if (nel < 1 ) | |
1063 is.clear (std::ios::badbit); | |
1064 else | |
1065 { | |
1066 double tmp; | |
5275 | 1067 for (octave_idx_type i = 0; i < nel; i++) |
4687 | 1068 { |
1069 tmp = octave_read_double (is); | |
1070 if (is) | |
1071 a.elem (i) = tmp; | |
1072 else | |
1073 goto done; | |
1074 } | |
1075 } | |
1076 | |
1077 done: | |
1078 | |
1079 return is; | |
1080 } | |
1081 | |
5775 | 1082 // FIXME -- it would be nice to share code among the min/max |
4844 | 1083 // functions below. |
1084 | |
1085 #define EMPTY_RETURN_CHECK(T) \ | |
1086 if (nel == 0) \ | |
1087 return T (dv); | |
1088 | |
1089 NDArray | |
1090 min (double d, const NDArray& m) | |
1091 { | |
1092 dim_vector dv = m.dims (); | |
5275 | 1093 octave_idx_type nel = dv.numel (); |
4844 | 1094 |
1095 EMPTY_RETURN_CHECK (NDArray); | |
1096 | |
1097 NDArray result (dv); | |
1098 | |
5275 | 1099 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1100 { |
1101 OCTAVE_QUIT; | |
1102 result (i) = xmin (d, m (i)); | |
1103 } | |
1104 | |
1105 return result; | |
1106 } | |
1107 | |
1108 NDArray | |
1109 min (const NDArray& m, double d) | |
1110 { | |
1111 dim_vector dv = m.dims (); | |
5275 | 1112 octave_idx_type nel = dv.numel (); |
4844 | 1113 |
1114 EMPTY_RETURN_CHECK (NDArray); | |
1115 | |
1116 NDArray result (dv); | |
1117 | |
5275 | 1118 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1119 { |
1120 OCTAVE_QUIT; | |
1121 result (i) = xmin (d, m (i)); | |
1122 } | |
1123 | |
1124 return result; | |
1125 } | |
1126 | |
1127 NDArray | |
1128 min (const NDArray& a, const NDArray& b) | |
1129 { | |
1130 dim_vector dv = a.dims (); | |
5275 | 1131 octave_idx_type nel = dv.numel (); |
4844 | 1132 |
1133 if (dv != b.dims ()) | |
1134 { | |
1135 (*current_liboctave_error_handler) | |
1136 ("two-arg min expecting args of same size"); | |
1137 return NDArray (); | |
1138 } | |
1139 | |
1140 EMPTY_RETURN_CHECK (NDArray); | |
1141 | |
1142 NDArray result (dv); | |
1143 | |
5275 | 1144 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1145 { |
1146 OCTAVE_QUIT; | |
1147 result (i) = xmin (a (i), b (i)); | |
1148 } | |
1149 | |
1150 return result; | |
1151 } | |
1152 | |
1153 NDArray | |
1154 max (double d, const NDArray& m) | |
1155 { | |
1156 dim_vector dv = m.dims (); | |
5275 | 1157 octave_idx_type nel = dv.numel (); |
4844 | 1158 |
1159 EMPTY_RETURN_CHECK (NDArray); | |
1160 | |
1161 NDArray result (dv); | |
1162 | |
5275 | 1163 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1164 { |
1165 OCTAVE_QUIT; | |
1166 result (i) = xmax (d, m (i)); | |
1167 } | |
1168 | |
1169 return result; | |
1170 } | |
1171 | |
1172 NDArray | |
1173 max (const NDArray& m, double d) | |
1174 { | |
1175 dim_vector dv = m.dims (); | |
5275 | 1176 octave_idx_type nel = dv.numel (); |
4844 | 1177 |
1178 EMPTY_RETURN_CHECK (NDArray); | |
1179 | |
1180 NDArray result (dv); | |
1181 | |
5275 | 1182 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1183 { |
1184 OCTAVE_QUIT; | |
1185 result (i) = xmax (d, m (i)); | |
1186 } | |
1187 | |
1188 return result; | |
1189 } | |
1190 | |
1191 NDArray | |
1192 max (const NDArray& a, const NDArray& b) | |
1193 { | |
1194 dim_vector dv = a.dims (); | |
5275 | 1195 octave_idx_type nel = dv.numel (); |
4844 | 1196 |
1197 if (dv != b.dims ()) | |
1198 { | |
1199 (*current_liboctave_error_handler) | |
1200 ("two-arg max expecting args of same size"); | |
1201 return NDArray (); | |
1202 } | |
1203 | |
1204 EMPTY_RETURN_CHECK (NDArray); | |
1205 | |
1206 NDArray result (dv); | |
1207 | |
5275 | 1208 for (octave_idx_type i = 0; i < nel; i++) |
4844 | 1209 { |
1210 OCTAVE_QUIT; | |
1211 result (i) = xmax (a (i), b (i)); | |
1212 } | |
1213 | |
1214 return result; | |
1215 } | |
1216 | |
4543 | 1217 NDS_CMP_OPS(NDArray, , double, ) |
1218 NDS_BOOL_OPS(NDArray, double, 0.0) | |
1219 | |
1220 SND_CMP_OPS(double, , NDArray, ) | |
1221 SND_BOOL_OPS(double, NDArray, 0.0) | |
1222 | |
1223 NDND_CMP_OPS(NDArray, , NDArray, ) | |
1224 NDND_BOOL_OPS(NDArray, NDArray, 0.0) | |
1225 | |
4513 | 1226 /* |
1227 ;;; Local Variables: *** | |
1228 ;;; mode: C++ *** | |
1229 ;;; End: *** | |
1230 */ |