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