Mercurial > hg > octave-nkf
annotate liboctave/Array.cc @ 9546:1beb23d2b892
optimize op= in common cases
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 19 Aug 2009 13:47:59 +0200 |
parents | b096d11237be |
children | 948795dc1974 |
rev | line source |
---|---|
1993 | 1 // Template array classes |
237 | 2 /* |
3 | |
8920 | 4 Copyright (C) 2008, 2009 Jaroslav Hajek |
7017 | 5 Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, |
6 2005, 2006, 2007 John W. Eaton | |
237 | 7 |
8 This file is part of Octave. | |
9 | |
10 Octave is free software; you can redistribute it and/or modify it | |
11 under the terms of the GNU General Public License as published by the | |
7016 | 12 Free Software Foundation; either version 3 of the License, or (at your |
13 option) any later version. | |
237 | 14 |
15 Octave is distributed in the hope that it will be useful, but WITHOUT | |
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
7016 | 21 along with Octave; see the file COPYING. If not, see |
22 <http://www.gnu.org/licenses/>. | |
237 | 23 |
24 */ | |
25 | |
26 #ifdef HAVE_CONFIG_H | |
1192 | 27 #include <config.h> |
237 | 28 #endif |
29 | |
1367 | 30 #include <cassert> |
4518 | 31 #include <climits> |
449 | 32 |
3503 | 33 #include <iostream> |
5765 | 34 #include <sstream> |
5607 | 35 #include <vector> |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
36 #include <algorithm> |
6674 | 37 #include <new> |
1560 | 38 |
237 | 39 #include "Array.h" |
4588 | 40 #include "Array-util.h" |
1560 | 41 #include "idx-vector.h" |
42 #include "lo-error.h" | |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
8333
diff
changeset
|
43 #include "oct-locbuf.h" |
1560 | 44 |
1360 | 45 // One dimensional array class. Handles the reference counting for |
46 // all the derived classes. | |
237 | 47 |
48 template <class T> | |
8524
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
49 void |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
50 Array<T>::make_unique (void) |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
51 { |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
52 if (rep->count > 1) |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
53 { |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
54 --rep->count; |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
55 rep = new ArrayRep (slice_data, slice_len, true); |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
56 slice_data = rep->data; |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
57 } |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
58 } |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
59 |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
60 template <class T> |
4834 | 61 Array<T>::Array (const Array<T>& a, const dim_vector& dv) |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
62 : rep (a.rep), dimensions (dv), |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
63 slice_data (a.slice_data), slice_len (a.slice_len) |
4834 | 64 { |
65 rep->count++; | |
66 | |
67 if (a.numel () < dv.numel ()) | |
68 (*current_liboctave_error_handler) | |
69 ("Array::Array (const Array&, const dim_vector&): dimension mismatch"); | |
70 } | |
71 | |
72 template <class T> | |
1619 | 73 Array<T>::~Array (void) |
74 { | |
75 if (--rep->count <= 0) | |
76 delete rep; | |
4513 | 77 } |
78 | |
4532 | 79 template <class T> |
7717
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
80 Array<T>& |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
81 Array<T>::operator = (const Array<T>& a) |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
82 { |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
83 if (this != &a) |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
84 { |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
85 if (--rep->count <= 0) |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
86 delete rep; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
87 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
88 rep = a.rep; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
89 rep->count++; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
90 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
91 dimensions = a.dimensions; |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
92 slice_data = a.slice_data; |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
93 slice_len = a.slice_len; |
7717
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
94 } |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
95 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
96 return *this; |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
97 } |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
98 |
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7646
diff
changeset
|
99 template <class T> |
8524
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
100 void |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
101 Array<T>::fill (const T& val) |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
102 { |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
103 if (rep->count > 1) |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
104 { |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
105 --rep->count; |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
106 rep = new ArrayRep (length (), val); |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
107 slice_data = rep->data; |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
108 } |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
109 else |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
110 std::fill (slice_data, slice_data + slice_len, val); |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
111 } |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
112 |
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
113 template <class T> |
9546
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
114 void |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
115 Array<T>::clear (void) |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
116 { |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
117 if (--rep->count <= 0) |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
118 delete rep; |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
119 |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
120 rep = nil_rep (); |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
121 rep->count++; |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
122 slice_data = rep->data; |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
123 slice_len = rep->len; |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
124 |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
125 dimensions = dim_vector (); |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
126 } |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
127 |
1beb23d2b892
optimize op= in common cases
Jaroslav Hajek <highegg@gmail.com>
parents:
9507
diff
changeset
|
128 template <class T> |
4532 | 129 Array<T> |
130 Array<T>::squeeze (void) const | |
131 { | |
132 Array<T> retval = *this; | |
133 | |
4929 | 134 if (ndims () > 2) |
4532 | 135 { |
4929 | 136 bool dims_changed = false; |
137 | |
138 dim_vector new_dimensions = dimensions; | |
139 | |
140 int k = 0; | |
141 | |
142 for (int i = 0; i < ndims (); i++) | |
4759 | 143 { |
4929 | 144 if (dimensions(i) == 1) |
145 dims_changed = true; | |
146 else | |
147 new_dimensions(k++) = dimensions(i); | |
148 } | |
149 | |
150 if (dims_changed) | |
151 { | |
152 switch (k) | |
153 { | |
154 case 0: | |
155 new_dimensions = dim_vector (1, 1); | |
156 break; | |
157 | |
158 case 1: | |
4759 | 159 { |
5275 | 160 octave_idx_type tmp = new_dimensions(0); |
4929 | 161 |
162 new_dimensions.resize (2); | |
163 | |
4759 | 164 new_dimensions(0) = tmp; |
165 new_dimensions(1) = 1; | |
166 } | |
4929 | 167 break; |
168 | |
169 default: | |
170 new_dimensions.resize (k); | |
171 break; | |
172 } | |
4759 | 173 } |
4532 | 174 |
8524
937921654627
clean up Array and DiagArray2
Jaroslav Hajek <highegg@gmail.com>
parents:
8523
diff
changeset
|
175 retval = Array<T> (*this, new_dimensions); |
4532 | 176 } |
177 | |
178 return retval; | |
179 } | |
180 | |
6674 | 181 // KLUGE |
182 | |
183 // The following get_size functions will throw a std::bad_alloc () | |
184 // exception if the requested size is larger than can be indexed by | |
185 // octave_idx_type. This may be smaller than the actual amount of | |
186 // memory that can be safely allocated on a system. However, if we | |
187 // don't fail here, we can end up with a mysterious crash inside a | |
188 // function that is iterating over an array using octave_idx_type | |
189 // indices. | |
190 | |
4513 | 191 // A guess (should be quite conservative). |
192 #define MALLOC_OVERHEAD 1024 | |
193 | |
194 template <class T> | |
5275 | 195 octave_idx_type |
196 Array<T>::get_size (octave_idx_type r, octave_idx_type c) | |
4513 | 197 { |
198 static int nl; | |
199 static double dl | |
5275 | 200 = frexp (static_cast<double> |
201 (std::numeric_limits<octave_idx_type>::max() - MALLOC_OVERHEAD) / sizeof (T), &nl); | |
4513 | 202 |
203 int nr, nc; | |
5275 | 204 double dr = frexp (static_cast<double> (r), &nr); // r = dr * 2^nr |
205 double dc = frexp (static_cast<double> (c), &nc); // c = dc * 2^nc | |
4513 | 206 |
207 int nt = nr + nc; | |
208 double dt = dr * dc; | |
209 | |
4532 | 210 if (dt < 0.5) |
4513 | 211 { |
212 nt--; | |
213 dt *= 2; | |
214 } | |
215 | |
6674 | 216 if (nt < nl || (nt == nl && dt < dl)) |
217 return r * c; | |
218 else | |
219 { | |
220 throw std::bad_alloc (); | |
221 return 0; | |
222 } | |
237 | 223 } |
224 | |
225 template <class T> | |
5275 | 226 octave_idx_type |
227 Array<T>::get_size (octave_idx_type r, octave_idx_type c, octave_idx_type p) | |
237 | 228 { |
4513 | 229 static int nl; |
230 static double dl | |
231 = frexp (static_cast<double> | |
5275 | 232 (std::numeric_limits<octave_idx_type>::max() - MALLOC_OVERHEAD) / sizeof (T), &nl); |
4513 | 233 |
234 int nr, nc, np; | |
235 double dr = frexp (static_cast<double> (r), &nr); | |
236 double dc = frexp (static_cast<double> (c), &nc); | |
237 double dp = frexp (static_cast<double> (p), &np); | |
238 | |
239 int nt = nr + nc + np; | |
240 double dt = dr * dc * dp; | |
241 | |
4532 | 242 if (dt < 0.5) |
659 | 243 { |
4513 | 244 nt--; |
245 dt *= 2; | |
237 | 246 |
4532 | 247 if (dt < 0.5) |
248 { | |
249 nt--; | |
250 dt *= 2; | |
251 } | |
659 | 252 } |
1619 | 253 |
6674 | 254 if (nt < nl || (nt == nl && dt < dl)) |
255 return r * c * p; | |
256 else | |
257 { | |
258 throw std::bad_alloc (); | |
259 return 0; | |
260 } | |
237 | 261 } |
262 | |
263 template <class T> | |
5275 | 264 octave_idx_type |
4513 | 265 Array<T>::get_size (const dim_vector& ra_idx) |
237 | 266 { |
4513 | 267 static int nl; |
268 static double dl | |
269 = frexp (static_cast<double> | |
5275 | 270 (std::numeric_limits<octave_idx_type>::max() - MALLOC_OVERHEAD) / sizeof (T), &nl); |
4513 | 271 |
272 int n = ra_idx.length (); | |
273 | |
274 int nt = 0; | |
275 double dt = 1; | |
276 | |
277 for (int i = 0; i < n; i++) | |
237 | 278 { |
4513 | 279 int nra_idx; |
280 double dra_idx = frexp (static_cast<double> (ra_idx(i)), &nra_idx); | |
281 | |
282 nt += nra_idx; | |
283 dt *= dra_idx; | |
4532 | 284 |
285 if (dt < 0.5) | |
286 { | |
287 nt--; | |
288 dt *= 2; | |
289 } | |
237 | 290 } |
291 | |
4513 | 292 if (nt < nl || (nt == nl && dt < dl)) |
293 { | |
6674 | 294 octave_idx_type retval = 1; |
4513 | 295 |
296 for (int i = 0; i < n; i++) | |
297 retval *= ra_idx(i); | |
6674 | 298 |
299 return retval; | |
4513 | 300 } |
6674 | 301 else |
302 { | |
303 throw std::bad_alloc (); | |
304 return 0; | |
305 } | |
237 | 306 } |
307 | |
4513 | 308 #undef MALLOC_OVERHEAD |
309 | |
237 | 310 template <class T> |
5275 | 311 octave_idx_type |
312 Array<T>::compute_index (const Array<octave_idx_type>& ra_idx) const | |
237 | 313 { |
5275 | 314 octave_idx_type retval = -1; |
4513 | 315 |
316 int n = dimensions.length (); | |
317 | |
318 if (n > 0 && n == ra_idx.length ()) | |
237 | 319 { |
4513 | 320 retval = ra_idx(--n); |
237 | 321 |
4513 | 322 while (--n >= 0) |
323 { | |
324 retval *= dimensions(n); | |
325 retval += ra_idx(n); | |
326 } | |
327 } | |
328 else | |
329 (*current_liboctave_error_handler) | |
330 ("Array<T>::compute_index: invalid ra_idxing operation"); | |
237 | 331 |
4513 | 332 return retval; |
237 | 333 } |
334 | |
2049 | 335 template <class T> |
336 T | |
5275 | 337 Array<T>::range_error (const char *fcn, octave_idx_type n) const |
2049 | 338 { |
2109 | 339 (*current_liboctave_error_handler) ("%s (%d): range error", fcn, n); |
2049 | 340 return T (); |
341 } | |
342 | |
343 template <class T> | |
344 T& | |
5275 | 345 Array<T>::range_error (const char *fcn, octave_idx_type n) |
2049 | 346 { |
2109 | 347 (*current_liboctave_error_handler) ("%s (%d): range error", fcn, n); |
2049 | 348 static T foo; |
349 return foo; | |
350 } | |
351 | |
3933 | 352 template <class T> |
4513 | 353 T |
5275 | 354 Array<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const |
4513 | 355 { |
356 (*current_liboctave_error_handler) | |
357 ("%s (%d, %d): range error", fcn, i, j); | |
358 return T (); | |
359 } | |
360 | |
361 template <class T> | |
362 T& | |
5275 | 363 Array<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j) |
4513 | 364 { |
365 (*current_liboctave_error_handler) | |
366 ("%s (%d, %d): range error", fcn, i, j); | |
367 static T foo; | |
368 return foo; | |
369 } | |
370 | |
371 template <class T> | |
372 T | |
5275 | 373 Array<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k) const |
4513 | 374 { |
375 (*current_liboctave_error_handler) | |
376 ("%s (%d, %d, %d): range error", fcn, i, j, k); | |
377 return T (); | |
378 } | |
379 | |
380 template <class T> | |
381 T& | |
5275 | 382 Array<T>::range_error (const char *fcn, octave_idx_type i, octave_idx_type j, octave_idx_type k) |
4513 | 383 { |
384 (*current_liboctave_error_handler) | |
385 ("%s (%d, %d, %d): range error", fcn, i, j, k); | |
386 static T foo; | |
387 return foo; | |
388 } | |
389 | |
390 template <class T> | |
391 T | |
6867 | 392 Array<T>::range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const |
4513 | 393 { |
5765 | 394 std::ostringstream buf; |
4661 | 395 |
396 buf << fcn << " ("; | |
397 | |
5275 | 398 octave_idx_type n = ra_idx.length (); |
4661 | 399 |
400 if (n > 0) | |
401 buf << ra_idx(0); | |
402 | |
5275 | 403 for (octave_idx_type i = 1; i < n; i++) |
4661 | 404 buf << ", " << ra_idx(i); |
405 | |
406 buf << "): range error"; | |
407 | |
5765 | 408 std::string buf_str = buf.str (); |
409 | |
410 (*current_liboctave_error_handler) (buf_str.c_str ()); | |
4513 | 411 |
412 return T (); | |
413 } | |
414 | |
415 template <class T> | |
416 T& | |
6867 | 417 Array<T>::range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) |
4513 | 418 { |
5765 | 419 std::ostringstream buf; |
4661 | 420 |
421 buf << fcn << " ("; | |
422 | |
5275 | 423 octave_idx_type n = ra_idx.length (); |
4661 | 424 |
425 if (n > 0) | |
426 buf << ra_idx(0); | |
427 | |
5275 | 428 for (octave_idx_type i = 1; i < n; i++) |
4661 | 429 buf << ", " << ra_idx(i); |
430 | |
431 buf << "): range error"; | |
432 | |
5765 | 433 std::string buf_str = buf.str (); |
434 | |
435 (*current_liboctave_error_handler) (buf_str.c_str ()); | |
4513 | 436 |
437 static T foo; | |
438 return foo; | |
439 } | |
440 | |
441 template <class T> | |
4567 | 442 Array<T> |
443 Array<T>::reshape (const dim_vector& new_dims) const | |
444 { | |
445 Array<T> retval; | |
446 | |
447 if (dimensions != new_dims) | |
448 { | |
449 if (dimensions.numel () == new_dims.numel ()) | |
450 retval = Array<T> (*this, new_dims); | |
451 else | |
8527
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
452 { |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
453 std::string dimensions_str = dimensions.str (); |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
454 std::string new_dims_str = new_dims.str (); |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
455 |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
456 (*current_liboctave_error_handler) |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
457 ("reshape: can't reshape %s array to %s array", |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
458 dimensions_str.c_str (), new_dims_str.c_str ()); |
6b074f37e8d7
reshape: improve error message
John W. Eaton <jwe@octave.org>
parents:
8526
diff
changeset
|
459 } |
4567 | 460 } |
4916 | 461 else |
462 retval = *this; | |
4567 | 463 |
464 return retval; | |
465 } | |
466 | |
8410 | 467 // Helper class for multi-d dimension permuting (generalized transpose). |
468 class rec_permute_helper | |
469 { | |
470 octave_idx_type *dim, *stride; | |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
471 bool use_blk; |
8410 | 472 int top; |
473 | |
474 public: | |
475 rec_permute_helper (const dim_vector& dv, const Array<octave_idx_type>& perm) | |
476 { | |
477 int n = dv.length (); | |
478 assert (n == perm.length ()); | |
479 | |
480 dim = new octave_idx_type [2*n]; | |
481 // A hack to avoid double allocation | |
482 stride = dim + n; | |
483 | |
484 // Get cumulative dimensions. | |
485 OCTAVE_LOCAL_BUFFER (octave_idx_type, cdim, n+1); | |
486 cdim[0] = 1; | |
487 for (int i = 1; i < n+1; i++) cdim[i] = cdim[i-1] * dv(i-1); | |
488 | |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
489 // Setup the permuted strides. |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
490 for (int k = 0; k < n; k++) |
8410 | 491 { |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
492 int kk = perm(k); |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
493 dim[k] = dv(kk); |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
494 stride[k] = cdim[kk]; |
8410 | 495 } |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
496 |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
497 // Reduce contiguous runs. |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
498 top = 0; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
499 for (int k = 1; k < n; k++) |
8410 | 500 { |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
501 if (stride[k] == stride[top]*dim[top]) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
502 dim[top] *= dim[k]; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
503 else |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
504 { |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
505 top++; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
506 dim[top] = dim[k]; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
507 stride[top] = stride[k]; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
508 } |
8410 | 509 } |
510 | |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
511 // Determine whether we can use block transposes. |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
512 use_blk = top >= 1 && stride[1] == 1 && stride[0] == dim[1]; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
513 |
8410 | 514 } |
515 | |
516 ~rec_permute_helper (void) { delete [] dim; } | |
517 | |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
518 // Helper method for fast blocked transpose. |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
519 template <class T> |
9121
bb62bc406ea7
reuse fast blocked transpose implementation from rec_permute_helper in Array<T>::transpose
Jaroslav Hajek <highegg@gmail.com>
parents:
9100
diff
changeset
|
520 static T * |
bb62bc406ea7
reuse fast blocked transpose implementation from rec_permute_helper in Array<T>::transpose
Jaroslav Hajek <highegg@gmail.com>
parents:
9100
diff
changeset
|
521 blk_trans (const T *src, T *dest, octave_idx_type nr, octave_idx_type nc) |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
522 { |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
523 static const octave_idx_type m = 8; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
524 OCTAVE_LOCAL_BUFFER (T, blk, m*m); |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
525 for (octave_idx_type kr = 0; kr < nr; kr += m) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
526 for (octave_idx_type kc = 0; kc < nc; kc += m) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
527 { |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
528 octave_idx_type lr = std::min (m, nr - kr); |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
529 octave_idx_type lc = std::min (m, nc - kc); |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
530 if (lr == m && lc == m) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
531 { |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
532 const T *ss = src + kc * nr + kr; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
533 for (octave_idx_type j = 0; j < m; j++) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
534 for (octave_idx_type i = 0; i < m; i++) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
535 blk[j*m+i] = ss[j*nr + i]; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
536 T *dd = dest + kr * nc + kc; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
537 for (octave_idx_type j = 0; j < m; j++) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
538 for (octave_idx_type i = 0; i < m; i++) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
539 dd[j*nc+i] = blk[i*m+j]; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
540 } |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
541 else |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
542 { |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
543 const T *ss = src + kc * nr + kr; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
544 for (octave_idx_type j = 0; j < lc; j++) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
545 for (octave_idx_type i = 0; i < lr; i++) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
546 blk[j*m+i] = ss[j*nr + i]; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
547 T *dd = dest + kr * nc + kc; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
548 for (octave_idx_type j = 0; j < lr; j++) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
549 for (octave_idx_type i = 0; i < lc; i++) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
550 dd[j*nc+i] = blk[i*m+j]; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
551 } |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
552 } |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
553 |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
554 return dest + nr*nc; |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
555 } |
8410 | 556 private: |
557 | |
558 // Recursive N-d generalized transpose | |
559 template <class T> | |
560 T *do_permute (const T *src, T *dest, int lev) const | |
561 { | |
562 if (lev == 0) | |
563 { | |
564 octave_idx_type step = stride[0], len = dim[0]; | |
565 if (step == 1) | |
566 dest = std::copy (src, src + len, dest); | |
567 else | |
568 { | |
569 for (octave_idx_type i = 0, j = 0; i < len; i++, j += step) | |
570 dest[i] = src[j]; | |
571 | |
572 dest += len; | |
573 } | |
574 } | |
9012
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
575 else if (use_blk && lev == 1) |
9f5e095555fc
smarter algorithm for permute
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
576 dest = blk_trans (src, dest, dim[1], dim[0]); |
8410 | 577 else |
578 { | |
579 octave_idx_type step = stride[lev], len = dim[lev]; | |
580 for (octave_idx_type i = 0, j = 0; i < len; i++, j+= step) | |
581 dest = do_permute (src + i * step, dest, lev-1); | |
582 } | |
583 | |
584 return dest; | |
585 } | |
586 | |
587 public: | |
588 | |
589 template <class T> | |
590 void permute (const T *src, T *dest) const { do_permute (src, dest, top); } | |
591 | |
592 }; | |
7241 | 593 |
5607 | 594 |
4567 | 595 template <class T> |
4593 | 596 Array<T> |
5607 | 597 Array<T>::permute (const Array<octave_idx_type>& perm_vec_arg, bool inv) const |
4593 | 598 { |
599 Array<T> retval; | |
600 | |
5607 | 601 Array<octave_idx_type> perm_vec = perm_vec_arg; |
602 | |
4593 | 603 dim_vector dv = dims (); |
604 | |
8410 | 605 int perm_vec_len = perm_vec_arg.length (); |
5148 | 606 |
607 if (perm_vec_len < dv.length ()) | |
608 (*current_liboctave_error_handler) | |
609 ("%s: invalid permutation vector", inv ? "ipermute" : "permute"); | |
610 | |
9507
b096d11237be
dim_vector improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9341
diff
changeset
|
611 dim_vector dv_new = dim_vector::alloc (perm_vec_len); |
5148 | 612 |
613 // Append singleton dimensions as needed. | |
614 dv.resize (perm_vec_len, 1); | |
615 | |
4593 | 616 // Need this array to check for identical elements in permutation array. |
8410 | 617 OCTAVE_LOCAL_BUFFER_INIT (bool, checked, perm_vec_len, false); |
4593 | 618 |
619 // Find dimension vector of permuted array. | |
5148 | 620 for (int i = 0; i < perm_vec_len; i++) |
4593 | 621 { |
5275 | 622 octave_idx_type perm_elt = perm_vec.elem (i); |
5148 | 623 if (perm_elt >= perm_vec_len || perm_elt < 0) |
4593 | 624 { |
625 (*current_liboctave_error_handler) | |
5148 | 626 ("%s: permutation vector contains an invalid element", |
627 inv ? "ipermute" : "permute"); | |
4593 | 628 |
629 return retval; | |
630 } | |
631 | |
8410 | 632 if (checked[perm_elt]) |
4593 | 633 { |
634 (*current_liboctave_error_handler) | |
5148 | 635 ("%s: permutation vector cannot contain identical elements", |
636 inv ? "ipermute" : "permute"); | |
4593 | 637 |
638 return retval; | |
639 } | |
640 else | |
8410 | 641 checked[perm_elt] = true; |
5148 | 642 |
643 dv_new(i) = dv(perm_elt); | |
4593 | 644 } |
645 | |
5607 | 646 if (inv) |
647 { | |
8410 | 648 for (int i = 0; i < perm_vec_len; i++) |
649 perm_vec(perm_vec_arg(i)) = i; | |
5607 | 650 } |
651 | |
8410 | 652 retval = Array<T> (dv_new); |
4593 | 653 |
5940 | 654 if (numel () > 0) |
5607 | 655 { |
8410 | 656 rec_permute_helper rh (dv, perm_vec); |
657 rh.permute (data (), retval.fortran_vec ()); | |
4593 | 658 } |
659 | |
5340 | 660 retval.chop_trailing_singletons (); |
5338 | 661 |
4593 | 662 return retval; |
663 } | |
664 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
665 // Helper class for multi-d index reduction and recursive indexing/indexed assignment. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
666 // Rationale: we could avoid recursion using a state machine instead. However, using |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
667 // recursion is much more amenable to possible parallelization in the future. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
668 // Also, the recursion solution is cleaner and more understandable. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
669 class rec_index_helper |
4513 | 670 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
671 octave_idx_type *dim, *cdim; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
672 idx_vector *idx; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
673 int top; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
674 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
675 public: |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
676 rec_index_helper (const dim_vector& dv, const Array<idx_vector>& ia) |
4513 | 677 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
678 int n = ia.length (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
679 assert (n > 0 && (dv.length () == std::max (n, 2))); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
680 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
681 dim = new octave_idx_type [2*n]; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
682 // A hack to avoid double allocation |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
683 cdim = dim + n; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
684 idx = new idx_vector [n]; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
685 top = 0; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
686 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
687 dim[0] = dv(0); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
688 cdim[0] = 1; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
689 idx[0] = ia(0); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
690 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
691 for (int i = 1; i < n; i++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
692 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
693 // Try reduction... |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
694 if (idx[top].maybe_reduce (dim[top], ia(i), dv(i))) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
695 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
696 // Reduction successful, fold dimensions. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
697 dim[top] *= dv(i); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
698 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
699 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
700 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
701 // Unsuccessful, store index & cumulative dim. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
702 top++; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
703 idx[top] = ia(i); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
704 dim[top] = dv(i); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
705 cdim[top] = cdim[top-1] * dim[top-1]; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
706 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
707 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
708 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
709 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
710 ~rec_index_helper (void) { delete [] idx; delete [] dim; } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
711 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
712 private: |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
713 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
714 // Recursive N-d indexing |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
715 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
716 T *do_index (const T *src, T *dest, int lev) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
717 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
718 if (lev == 0) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
719 dest += idx[0].index (src, dim[0], dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
720 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
721 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
722 octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev]; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
723 for (octave_idx_type i = 0; i < n; i++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
724 dest = do_index (src + d*idx[lev].xelem (i), dest, lev-1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
725 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
726 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
727 return dest; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
728 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
729 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
730 // Recursive N-d indexed assignment |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
731 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
732 const T *do_assign (const T *src, T *dest, int lev) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
733 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
734 if (lev == 0) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
735 src += idx[0].assign (src, dim[0], dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
736 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
737 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
738 octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev]; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
739 for (octave_idx_type i = 0; i < n; i++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
740 src = do_assign (src, dest + d*idx[lev].xelem (i), lev-1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
741 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
742 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
743 return src; |
4513 | 744 } |
745 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
746 // Recursive N-d indexed assignment |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
747 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
748 void do_fill (const T& val, T *dest, int lev) const |
4513 | 749 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
750 if (lev == 0) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
751 idx[0].fill (val, dim[0], dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
752 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
753 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
754 octave_idx_type n = idx[lev].length (dim[lev]), d = cdim[lev]; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
755 for (octave_idx_type i = 0; i < n; i++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
756 do_fill (val, dest + d*idx[lev].xelem (i), lev-1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
757 } |
4513 | 758 } |
759 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
760 public: |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
761 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
762 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
763 void index (const T *src, T *dest) const { do_index (src, dest, top); } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
764 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
765 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
766 void assign (const T *src, T *dest) const { do_assign (src, dest, top); } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
767 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
768 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
769 void fill (const T& val, T *dest) const { do_fill (val, dest, top); } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
770 |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
771 bool is_cont_range (octave_idx_type& l, |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
772 octave_idx_type& u) const |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
773 { |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
774 return top == 0 && idx[0].is_cont_range (dim[0], l, u); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
775 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
776 }; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
777 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
778 // Helper class for multi-d recursive resizing |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
779 // This handles resize () in an efficient manner, touching memory only |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
780 // once (apart from reinitialization) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
781 class rec_resize_helper |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
782 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
783 octave_idx_type *cext, *sext, *dext; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
784 int n; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
785 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
786 public: |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
787 rec_resize_helper (const dim_vector& ndv, const dim_vector& odv) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
788 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
789 int l = ndv.length (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
790 assert (odv.length () == l); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
791 octave_idx_type ld = 1; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
792 int i = 0; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
793 for (; i < l-1 && ndv(i) == odv(i); i++) ld *= ndv(i); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
794 n = l - i; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
795 cext = new octave_idx_type[3*n]; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
796 // Trick to avoid three allocations |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
797 sext = cext + n; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
798 dext = sext + n; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
799 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
800 octave_idx_type sld = ld, dld = ld; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
801 for (int j = 0; j < n; j++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
802 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
803 cext[j] = std::min (ndv(i+j), odv(i+j)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
804 sext[j] = sld *= odv(i+j); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
805 dext[j] = dld *= ndv(i+j); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
806 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
807 cext[0] *= ld; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
808 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
809 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
810 ~rec_resize_helper (void) { delete [] cext; } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
811 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
812 private: |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
813 // recursive resizing |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
814 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
815 void do_resize_fill (const T* src, T *dest, const T& rfv, int lev) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
816 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
817 if (lev == 0) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
818 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
819 T* destc = std::copy (src, src + cext[0], dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
820 std::fill (destc, dest + dext[0], rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
821 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
822 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
823 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
824 octave_idx_type sd = sext[lev-1], dd = dext[lev-1], k; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
825 for (k = 0; k < cext[lev]; k++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
826 do_resize_fill (src + k * sd, dest + k * dd, rfv, lev - 1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
827 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
828 std::fill (dest + k * dd, dest + dext[lev], rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
829 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
830 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
831 public: |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
832 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
833 void resize_fill (const T* src, T *dest, const T& rfv) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
834 { do_resize_fill (src, dest, rfv, n-1); } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
835 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
836 }; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
837 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
838 static void gripe_index_out_of_range (void) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
839 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
840 (*current_liboctave_error_handler) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
841 ("A(I): Index exceeds matrix dimension."); |
4513 | 842 } |
843 | |
844 template <class T> | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
845 Array<T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
846 Array<T>::index (const idx_vector& i) const |
4513 | 847 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
848 octave_idx_type n = numel (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
849 Array<T> retval; |
5275 | 850 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
851 if (i.is_colon ()) |
4513 | 852 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
853 // A(:) produces a shallow copy as a column vector. |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
854 retval = Array<T> (*this, dim_vector (n, 1)); |
4513 | 855 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
856 else if (i.extent (n) != n) |
4548 | 857 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
858 gripe_index_out_of_range (); |
4548 | 859 } |
860 else | |
4513 | 861 { |
8333 | 862 // FIXME -- this is the only place where orig_dimensions are used. |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
863 dim_vector rd = i.orig_dimensions (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
864 octave_idx_type il = i.length (n); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
865 |
8333 | 866 // FIXME -- this is for Matlab compatibility. Matlab 2007 given |
867 // | |
868 // b = ones(3,1) | |
869 // | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
870 // yields the following: |
8333 | 871 // |
872 // b(zeros(0,0)) gives [] | |
873 // b(zeros(1,0)) gives zeros(0,1) | |
874 // b(zeros(0,1)) gives zeros(0,1) | |
875 // b(zeros(0,m)) gives zeros(0,m) | |
876 // b(zeros(m,0)) gives zeros(m,0) | |
877 // b(1:2) gives ones(2,1) | |
878 // b(ones(2)) gives ones(2) etc. | |
879 // | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
880 // As you can see, the behaviour is weird, but the tests end up pretty |
8333 | 881 // simple. Nah, I don't want to suggest that this is ad hoc :) |
882 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
883 if (ndims () == 2 && n != 1) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
884 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
885 if (columns () == 1 && rd(0) == 1) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
886 rd = dim_vector (il, 1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
887 else if (rows () == 1 && rd(1) == 1) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
888 rd = dim_vector (1, il); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
889 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
890 |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
891 octave_idx_type l, u; |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
892 if (il != 0 && i.is_cont_range (n, l, u)) |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
893 // If suitable, produce a shallow slice. |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
894 retval = Array<T> (*this, rd, l, u); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
895 else |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
896 { |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
897 // Don't use resize here to avoid useless initialization for POD |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
898 // types. |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
899 retval = Array<T> (rd); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
900 |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
901 if (il != 0) |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
902 i.index (data (), n, retval.fortran_vec ()); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
903 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
904 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
905 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
906 return retval; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
907 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
908 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
909 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
910 Array<T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
911 Array<T>::index (const idx_vector& i, const idx_vector& j) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
912 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
913 // Get dimensions, allowing Fortran indexing in the 2nd dim. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
914 dim_vector dv = dimensions.redim (2); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
915 octave_idx_type r = dv(0), c = dv(1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
916 Array<T> retval; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
917 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
918 if (i.is_colon () && j.is_colon ()) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
919 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
920 // A(:,:) produces a shallow copy. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
921 retval = Array<T> (*this, dv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
922 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
923 else if (i.extent (r) != r || j.extent (c) != c) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
924 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
925 gripe_index_out_of_range (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
926 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
927 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
928 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
929 octave_idx_type n = numel (), il = i.length (r), jl = j.length (c); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
930 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
931 idx_vector ii (i); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
932 |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
933 if (ii.maybe_reduce (r, j, c)) |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
934 { |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
935 octave_idx_type l, u; |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
936 if (ii.length () > 0 && ii.is_cont_range (n, l, u)) |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
937 // If suitable, produce a shallow slice. |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
938 retval = Array<T> (*this, dim_vector (il, jl), l, u); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
939 else |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
940 { |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
941 // Don't use resize here to avoid useless initialization for POD types. |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
942 retval = Array<T> (dim_vector (il, jl)); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
943 |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
944 ii.index (data (), n, retval.fortran_vec ()); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
945 } |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
946 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
947 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
948 { |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
949 // Don't use resize here to avoid useless initialization for POD types. |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
950 retval = Array<T> (dim_vector (il, jl)); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
951 |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
952 const T* src = data (); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
953 T *dest = retval.fortran_vec (); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
954 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
955 for (octave_idx_type k = 0; k < jl; k++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
956 dest += i.index (src + r * j.xelem (k), r, dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
957 } |
4513 | 958 } |
959 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
960 return retval; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
961 } |
4747 | 962 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
963 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
964 Array<T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
965 Array<T>::index (const Array<idx_vector>& ia) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
966 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
967 int ial = ia.length (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
968 Array<T> retval; |
4587 | 969 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
970 // FIXME: is this dispatching necessary? |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
971 if (ial == 1) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
972 retval = index (ia(0)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
973 else if (ial == 2) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
974 retval = index (ia(0), ia(1)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
975 else if (ial > 0) |
4513 | 976 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
977 // Get dimensions, allowing Fortran indexing in the last dim. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
978 dim_vector dv = dimensions.redim (ial); |
4747 | 979 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
980 // Check for out of bounds conditions. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
981 bool all_colons = true, mismatch = false; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
982 for (int i = 0; i < ial; i++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
983 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
984 if (ia(i).extent (dv(i)) != dv(i)) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
985 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
986 mismatch = true; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
987 break; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
988 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
989 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
990 all_colons = all_colons && ia(i).is_colon (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
991 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
992 |
4870 | 993 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
994 if (mismatch) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
995 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
996 gripe_index_out_of_range (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
997 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
998 else if (all_colons) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
999 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1000 // A(:,:,...,:) produces a shallow copy. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1001 retval = Array<T> (*this, dv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1002 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1003 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1004 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1005 // Form result dimensions. |
9507
b096d11237be
dim_vector improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9341
diff
changeset
|
1006 dim_vector rdv = dim_vector::alloc (ial); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1007 for (int i = 0; i < ial; i++) rdv(i) = ia(i).length (dv(i)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1008 rdv.chop_trailing_singletons (); |
4870 | 1009 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1010 // Prepare for recursive indexing |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1011 rec_index_helper rh (dv, ia); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1012 |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1013 octave_idx_type l, u; |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1014 if (rh.is_cont_range (l, u)) |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1015 // If suitable, produce a shallow slice. |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1016 retval = Array<T> (*this, rdv, l, u); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1017 else |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1018 { |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1019 // Don't use resize here to avoid useless initialization for POD types. |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1020 retval = Array<T> (rdv); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1021 |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1022 // Do it. |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1023 rh.index (data (), retval.fortran_vec ()); |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1024 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1025 } |
4513 | 1026 } |
1027 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1028 return retval; |
4513 | 1029 } |
1030 | |
8333 | 1031 // FIXME -- the following is a common error message to resize, |
1032 // regardless of whether it's called from assign or elsewhere. It | |
1033 // seems OK to me, but eventually the gripe can be specialized. | |
1034 // Anyway, propagating various error messages into procedure is, IMHO, | |
1035 // a nonsense. If anything, we should change error handling here (and | |
1036 // throughout liboctave) to allow custom handling of errors | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1037 static void gripe_invalid_resize (void) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1038 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1039 (*current_liboctave_error_handler) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1040 ("resize: Invalid resizing operation or ambiguous assignment to an out-of-bounds array element."); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1041 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1042 |
8333 | 1043 // The default fill value. Override if you want a different one. |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1044 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1045 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1046 T Array<T>::resize_fill_value () |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1047 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1048 return T (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1049 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1050 |
8333 | 1051 // Yes, we could do resize using index & assign. However, that would |
1052 // possibly involve a lot more memory traffic than we actually need. | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1053 |
4513 | 1054 template <class T> |
1055 void | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1056 Array<T>::resize_fill (octave_idx_type n, const T& rfv) |
4513 | 1057 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1058 if (n >= 0 && ndims () == 2) |
4513 | 1059 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1060 dim_vector dv; |
8333 | 1061 // This is driven by Matlab's behaviour of giving a *row* vector |
1062 // on some out-of-bounds assignments. Specifically, Matlab | |
1063 // allows a(i) with out-of-bouds i when a is either of 0x0, 1x0, | |
1064 // 1x1, 0xN, and gives a row vector in all cases (yes, even the | |
1065 // last one, search me why). Giving a column vector would make | |
1066 // much more sense (given the way trailing singleton dims are | |
1067 // treated). | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1068 bool invalid = false; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1069 if (rows () == 0 || rows () == 1) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1070 dv = dim_vector (1, n); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1071 else if (columns () == 1) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1072 dv = dim_vector (n, 1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1073 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1074 invalid = true; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1075 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1076 if (invalid) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1077 gripe_invalid_resize (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1078 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1079 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1080 octave_idx_type nx = numel (); |
9100
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1081 if (n == nx - 1 && n > 0) |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1082 { |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1083 // Stack "pop" operation. |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1084 if (rep->count == 1) |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1085 slice_data[slice_len-1] = T (); |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1086 slice_len--; |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1087 dimensions = dv; |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1088 } |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1089 else if (n == nx + 1 && nx > 0) |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1090 { |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1091 // Stack "push" operation. |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1092 if (rep->count == 1 && slice_data + slice_len < rep->data + rep->len) |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1093 { |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1094 slice_data[slice_len++] = rfv; |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1095 dimensions = dv; |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1096 } |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1097 else |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1098 { |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1099 static const octave_idx_type max_stack_chunk = 1024; |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1100 octave_idx_type nn = n + std::min (nx, max_stack_chunk); |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1101 Array<T> tmp (Array<T> (nn), dv, 0, n); |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1102 T *dest = tmp.fortran_vec (); |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1103 |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1104 std::copy (data (), data () + nx, dest); |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1105 dest[nx] = rfv; |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1106 |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1107 *this = tmp; |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1108 } |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1109 } |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1110 else if (n != nx) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1111 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1112 Array<T> tmp = Array<T> (dv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1113 T *dest = tmp.fortran_vec (); |
4513 | 1114 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1115 octave_idx_type n0 = std::min (n, nx), n1 = n - n0; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1116 dest = std::copy (data (), data () + n0, dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1117 std::fill (dest, dest + n1, rfv); |
4513 | 1118 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1119 *this = tmp; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1120 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1121 } |
4513 | 1122 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1123 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1124 gripe_invalid_resize (); |
4513 | 1125 } |
1126 | |
1127 template <class T> | |
1128 void | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1129 Array<T>::resize_fill (octave_idx_type r, octave_idx_type c, const T& rfv) |
4513 | 1130 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1131 if (r >= 0 && c >= 0 && ndims () == 2) |
4513 | 1132 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1133 octave_idx_type rx = rows (), cx = columns (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1134 if (r != rx || c != cx) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1135 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1136 Array<T> tmp = Array<T> (dim_vector (r, c)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1137 T *dest = tmp.fortran_vec (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1138 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1139 octave_idx_type r0 = std::min (r, rx), r1 = r - r0; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1140 octave_idx_type c0 = std::min (c, cx), c1 = c - c0; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1141 const T *src = data (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1142 if (r == rx) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1143 dest = std::copy (src, src + r * c0, dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1144 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1145 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1146 for (octave_idx_type k = 0; k < c0; k++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1147 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1148 dest = std::copy (src, src + r0, dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1149 src += rx; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1150 std::fill (dest, dest + r1, rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1151 dest += r1; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1152 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1153 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1154 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1155 std::fill (dest, dest + r * c1, rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1156 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1157 *this = tmp; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1158 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1159 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1160 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1161 gripe_invalid_resize (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1162 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1163 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1164 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1165 template<class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1166 void |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1167 Array<T>::resize_fill (const dim_vector& dv, const T& rfv) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1168 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1169 int dvl = dv.length (); |
8784
374cb30311a8
remove dead branch in Array.cc
Jaroslav Hajek <highegg@gmail.com>
parents:
8760
diff
changeset
|
1170 if (dvl == 2) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1171 resize (dv(0), dv(1), rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1172 else if (dimensions != dv) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1173 { |
8799
f6dc6eb57045
improve resize & resize on assignment
Jaroslav Hajek <highegg@gmail.com>
parents:
8784
diff
changeset
|
1174 if (dimensions.length () <= dvl && ! dv.any_neg ()) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1175 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1176 Array<T> tmp (dv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1177 // Prepare for recursive resizing. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1178 rec_resize_helper rh (dv, dimensions.redim (dvl)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1179 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1180 // Do it. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1181 rh.resize_fill (data (), tmp.fortran_vec (), rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1182 *this = tmp; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1183 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1184 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1185 gripe_invalid_resize (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1186 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1187 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1188 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1189 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1190 Array<T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1191 Array<T>::index (const idx_vector& i, bool resize_ok, const T& rfv) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1192 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1193 Array<T> tmp = *this; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1194 if (resize_ok) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1195 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1196 octave_idx_type n = numel (), nx = i.extent (n); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1197 if (n != nx) |
8563
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1198 { |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1199 if (i.is_scalar ()) |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1200 return Array<T> (1, rfv); |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1201 else |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1202 tmp.resize_fill (nx, rfv); |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1203 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1204 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1205 if (tmp.numel () != nx) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1206 return Array<T> (); |
4513 | 1207 } |
1208 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1209 return tmp.index (i); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1210 } |
4513 | 1211 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1212 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1213 Array<T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1214 Array<T>::index (const idx_vector& i, const idx_vector& j, |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1215 bool resize_ok, const T& rfv) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1216 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1217 Array<T> tmp = *this; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1218 if (resize_ok) |
4513 | 1219 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1220 dim_vector dv = dimensions.redim (2); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1221 octave_idx_type r = dv(0), c = dv(1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1222 octave_idx_type rx = i.extent (r), cx = j.extent (c); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1223 if (r != rx || c != cx) |
8563
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1224 { |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1225 if (i.is_scalar () && j.is_scalar ()) |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1226 return Array<T> (1, rfv); |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1227 else |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1228 tmp.resize_fill (rx, cx, rfv); |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1229 } |
4747 | 1230 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1231 if (tmp.rows () != rx || tmp.columns () != cx) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1232 return Array<T> (); |
4513 | 1233 } |
1234 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1235 return tmp.index (i, j); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1236 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1237 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1238 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1239 Array<T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1240 Array<T>::index (const Array<idx_vector>& ia, |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1241 bool resize_ok, const T& rfv) const |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1242 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1243 Array<T> tmp = *this; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1244 if (resize_ok) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1245 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1246 int ial = ia.length (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1247 dim_vector dv = dimensions.redim (ial); |
9507
b096d11237be
dim_vector improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9341
diff
changeset
|
1248 dim_vector dvx = dim_vector::alloc (ial); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1249 for (int i = 0; i < ial; i++) dvx(i) = ia(i).extent (dv (i)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1250 if (! (dvx == dv)) |
8563
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1251 { |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1252 bool all_scalars = true; |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1253 for (int i = 0; i < ial; i++) |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1254 all_scalars = all_scalars && ia(i).is_scalar (); |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1255 if (all_scalars) |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1256 return Array<T> (1, rfv); |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1257 else |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1258 tmp.resize_fill (dvx, rfv); |
3a3421a9f0bb
optimize resizable indexing with scalars
Jaroslav Hajek <highegg@gmail.com>
parents:
8527
diff
changeset
|
1259 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1260 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1261 if (tmp.dimensions != dvx) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1262 return Array<T> (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1263 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1264 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1265 return tmp.index (ia); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1266 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1267 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1268 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1269 static void |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1270 gripe_invalid_assignment_size (void) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1271 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1272 (*current_liboctave_error_handler) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1273 ("A(I) = X: X must have the same size as I"); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1274 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1275 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1276 static void |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1277 gripe_assignment_dimension_mismatch (void) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1278 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1279 (*current_liboctave_error_handler) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1280 ("A(I,J,...) = X: dimensions mismatch"); |
4513 | 1281 } |
1282 | |
1283 template <class T> | |
1284 void | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1285 Array<T>::assign (const idx_vector& i, const Array<T>& rhs, const T& rfv) |
4513 | 1286 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1287 octave_idx_type n = numel (), rhl = rhs.numel (); |
4548 | 1288 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1289 if (rhl == 1 || i.length (n) == rhl) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1290 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1291 octave_idx_type nx = i.extent (n); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1292 // Try to resize first if necessary. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1293 if (nx != n) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1294 { |
8580
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1295 // Optimize case A = []; A(1:n) = X with A empty. |
8390
49901b624316
optimize repmat for scalar & matrix case
Jaroslav Hajek <highegg@gmail.com>
parents:
8379
diff
changeset
|
1296 if (rows () == 0 && columns () == 0 && ndims () == 2 |
8580
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1297 && i.is_colon_equiv (nx)) |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1298 { |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1299 if (rhl == 1) |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1300 *this = Array<T> (dim_vector (1, nx), rhs(0)); |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1301 else |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1302 *this = Array<T> (rhs, dim_vector (1, nx)); |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1303 return; |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1304 } |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1305 |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1306 resize_fill (nx, rfv); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1307 n = numel (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1308 } |
4747 | 1309 |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1310 if (i.is_colon ()) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1311 { |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1312 // A(:) = X makes a full fill or a shallow copy. |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1313 if (rhl == 1) |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1314 fill (rhs(0)); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1315 else |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1316 *this = rhs.reshape (dimensions); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1317 } |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1318 else |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1319 { |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1320 if (rhl == 1) |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1321 i.fill (rhs(0), n, fortran_vec ()); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1322 else |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1323 i.assign (rhs.data (), n, fortran_vec ()); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1324 } |
4513 | 1325 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1326 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1327 gripe_invalid_assignment_size (); |
4513 | 1328 } |
1329 | |
1330 template <class T> | |
1331 void | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1332 Array<T>::assign (const idx_vector& i, const idx_vector& j, |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1333 const Array<T>& rhs, const T& rfv) |
4513 | 1334 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1335 // Get RHS extents, discarding singletons. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1336 dim_vector rhdv = rhs.dims (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1337 // Get LHS extents, allowing Fortran indexing in the second dim. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1338 dim_vector dv = dimensions.redim (2); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1339 // Check for out-of-bounds and form resizing dimensions. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1340 dim_vector rdv; |
8333 | 1341 // In the special when all dimensions are zero, colons are allowed |
1342 // to inquire the shape of RHS. The rules are more obscure, so we | |
1343 // solve that elsewhere. | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1344 if (dv.all_zero ()) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1345 rdv = zero_dims_inquire (i, j, rhdv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1346 else |
4513 | 1347 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1348 rdv(0) = i.extent (dv(0)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1349 rdv(1) = j.extent (dv(1)); |
4513 | 1350 } |
1351 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1352 bool isfill = rhs.numel () == 1; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1353 octave_idx_type il = i.length (rdv(0)), jl = j.length (rdv(1)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1354 rhdv.chop_all_singletons (); |
8333 | 1355 bool match = (isfill |
1356 || (rhdv.length () == 2 && il == rhdv(0) && jl == rhdv(1))); | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1357 match = match || (il == 1 && jl == rhdv(0) && rhdv(1) == 1); |
4548 | 1358 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1359 if (match) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1360 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1361 // Resize if requested. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1362 if (rdv != dv) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1363 { |
8580
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1364 // Optimize case A = []; A(1:m, 1:n) = X |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1365 if (dv.all_zero () && i.is_colon_equiv (rdv(0)) |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1366 && j.is_colon_equiv (rdv(1))) |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1367 { |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1368 if (isfill) |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1369 *this = Array<T> (rdv, rhs(0)); |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1370 else |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1371 *this = Array<T> (rhs, rdv); |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1372 return; |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1373 } |
188d38a553c7
further indexing optimization touches
Jaroslav Hajek <highegg@gmail.com>
parents:
8563
diff
changeset
|
1374 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1375 resize (rdv, rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1376 dv = dimensions; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1377 } |
4513 | 1378 |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1379 if (i.is_colon () && j.is_colon ()) |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1380 { |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1381 // A(:,:) = X makes a full fill or a shallow copy |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1382 if (isfill) |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1383 fill (rhs(0)); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1384 else |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1385 *this = rhs.reshape (dimensions); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1386 } |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1387 else |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1388 { |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1389 // The actual work. |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1390 octave_idx_type n = numel (), r = dv (0), c = dv (1); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1391 idx_vector ii (i); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1392 |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1393 const T* src = rhs.data (); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1394 T *dest = fortran_vec (); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1395 |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1396 // Try reduction first. |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1397 if (ii.maybe_reduce (r, j, c)) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1398 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1399 if (isfill) |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1400 ii.fill (*src, n, dest); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1401 else |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1402 ii.assign (src, n, dest); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1403 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1404 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1405 { |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1406 if (isfill) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1407 { |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1408 for (octave_idx_type k = 0; k < jl; k++) |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1409 i.fill (*src, r, dest + r * j.xelem (k)); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1410 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1411 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1412 { |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1413 for (octave_idx_type k = 0; k < jl; k++) |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1414 src += i.assign (src, r, dest + r * j.xelem (k)); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1415 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1416 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1417 } |
4747 | 1418 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1419 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1420 gripe_assignment_dimension_mismatch (); |
4513 | 1421 } |
1422 | |
1423 template <class T> | |
1424 void | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1425 Array<T>::assign (const Array<idx_vector>& ia, |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1426 const Array<T>& rhs, const T& rfv) |
4513 | 1427 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1428 int ial = ia.length (); |
5275 | 1429 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1430 // FIXME: is this dispatching necessary / desirable? |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1431 if (ial == 1) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1432 assign (ia(0), rhs, rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1433 else if (ial == 2) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1434 assign (ia(0), ia(1), rhs, rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1435 else if (ial > 0) |
4513 | 1436 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1437 // Get RHS extents, discarding singletons. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1438 dim_vector rhdv = rhs.dims (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1439 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1440 // Get LHS extents, allowing Fortran indexing in the second dim. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1441 dim_vector dv = dimensions.redim (ial); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1442 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1443 // Get the extents forced by indexing. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1444 dim_vector rdv; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1445 |
8333 | 1446 // In the special when all dimensions are zero, colons are |
1447 // allowed to inquire the shape of RHS. The rules are more | |
1448 // obscure, so we solve that elsewhere. | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1449 if (dv.all_zero ()) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1450 rdv = zero_dims_inquire (ia, rhdv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1451 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1452 { |
9507
b096d11237be
dim_vector improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9341
diff
changeset
|
1453 rdv = dim_vector::alloc (ial); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1454 for (int i = 0; i < ial; i++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1455 rdv(i) = ia(i).extent (dv(i)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1456 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1457 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1458 // Check whether LHS and RHS match, up to singleton dims. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1459 bool match = true, all_colons = true, isfill = rhs.numel () == 1; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1460 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1461 rhdv.chop_all_singletons (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1462 int j = 0, rhdvl = rhdv.length (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1463 for (int i = 0; i < ial; i++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1464 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1465 all_colons = all_colons && ia(i).is_colon (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1466 octave_idx_type l = ia(i).length (rdv(i)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1467 if (l == 1) continue; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1468 match = match && j < rhdvl && l == rhdv(j++); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1469 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1470 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1471 match = match && (j == rhdvl || rhdv(j) == 1); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1472 match = match || isfill; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1473 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1474 if (match) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1475 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1476 // Resize first if necessary. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1477 if (rdv != dv) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1478 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1479 resize_fill (rdv, rfv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1480 dv = dimensions; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1481 chop_trailing_singletons (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1482 } |
4513 | 1483 |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1484 if (all_colons) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1485 { |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1486 // A(:,:,...,:) = X makes a full fill or a shallow copy. |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1487 if (isfill) |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1488 fill (rhs(0)); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1489 else |
9058
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1490 *this = rhs.reshape (dimensions); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1491 } |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1492 else |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1493 { |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1494 // Do the actual work. |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1495 |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1496 // Prepare for recursive indexing |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1497 rec_index_helper rh (dv, ia); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1498 |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1499 // Do it. |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1500 if (isfill) |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1501 rh.fill (rhs(0), fortran_vec ()); |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1502 else |
2da105bf2507
remove redundant checks from Array<T>::index
Jaroslav Hajek <highegg@gmail.com>
parents:
9046
diff
changeset
|
1503 rh.assign (rhs.data (), fortran_vec ()); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1504 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1505 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1506 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1507 gripe_assignment_dimension_mismatch (); |
4553 | 1508 } |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1509 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1510 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1511 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1512 void |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1513 Array<T>::delete_elements (const idx_vector& i) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1514 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1515 octave_idx_type n = numel (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1516 if (i.is_colon ()) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1517 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1518 *this = Array<T> (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1519 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1520 else if (i.extent (n) != n) |
4513 | 1521 { |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1522 gripe_index_out_of_range (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1523 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1524 else if (i.length (n) != 0) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1525 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1526 octave_idx_type l, u; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1527 bool col_vec = ndims () == 2 && columns () == 1 && rows () != 1; |
9100
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1528 if (i.is_scalar () && i(0) == n-1) |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1529 { |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1530 // Stack "pop" operation. |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1531 resize (n-1); |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1532 } |
1a8bbfb2f7cf
optimize simple stack operations on arrays
Jaroslav Hajek <highegg@gmail.com>
parents:
9058
diff
changeset
|
1533 else if (i.is_cont_range (n, l, u)) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1534 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1535 // Special case deleting a contiguous range. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1536 octave_idx_type m = n + l - u; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1537 Array<T> tmp (dim_vector (col_vec ? m : 1, !col_vec ? m : 1)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1538 const T *src = data (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1539 T *dest = tmp.fortran_vec (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1540 dest = std::copy (src, src + l, dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1541 dest = std::copy (src + u, src + n, dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1542 *this = tmp; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1543 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1544 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1545 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1546 // Use index. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1547 *this = index (i.complement (n)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1548 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1549 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1550 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1551 |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1552 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1553 void |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1554 Array<T>::delete_elements (int dim, const idx_vector& i) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1555 { |
8302
f2e050b62199
fix dim check in Array<T>::delete_elements
Jaroslav Hajek <highegg@gmail.com>
parents:
8290
diff
changeset
|
1556 if (dim < 0 || dim >= ndims ()) |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1557 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1558 (*current_liboctave_error_handler) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1559 ("invalid dimension in delete_elements"); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1560 return; |
4513 | 1561 } |
1562 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1563 octave_idx_type n = dimensions (dim); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1564 if (i.is_colon ()) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1565 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1566 *this = Array<T> (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1567 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1568 else if (i.extent (n) != n) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1569 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1570 gripe_index_out_of_range (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1571 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1572 else if (i.length (n) != 0) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1573 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1574 octave_idx_type l, u; |
4513 | 1575 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1576 if (i.is_cont_range (n, l, u)) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1577 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1578 // Special case deleting a contiguous range. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1579 octave_idx_type nd = n + l - u, dl = 1, du = 1; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1580 dim_vector rdv = dimensions; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1581 rdv(dim) = nd; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1582 for (int k = 0; k < dim; k++) dl *= dimensions(k); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1583 for (int k = dim + 1; k < ndims (); k++) du *= dimensions(k); |
4513 | 1584 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1585 // Special case deleting a contiguous range. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1586 Array<T> tmp = Array<T> (rdv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1587 const T *src = data (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1588 T *dest = tmp.fortran_vec (); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1589 l *= dl; u *= dl; n *= dl; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1590 for (octave_idx_type k = 0; k < du; k++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1591 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1592 dest = std::copy (src, src + l, dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1593 dest = std::copy (src + u, src + n, dest); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1594 src += n; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1595 } |
4870 | 1596 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1597 *this = tmp; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1598 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1599 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1600 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1601 // Use index. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1602 Array<idx_vector> ia (ndims (), idx_vector::colon); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1603 ia (dim) = i.complement (n); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1604 *this = index (ia); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1605 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1606 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1607 } |
4747 | 1608 |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1609 template <class T> |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1610 void |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1611 Array<T>::delete_elements (const Array<idx_vector>& ia) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1612 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1613 if (ia.length () == 1) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1614 delete_elements (ia(0)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1615 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1616 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1617 int len = ia.length (), k, dim = -1; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1618 for (k = 0; k < len; k++) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1619 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1620 if (! ia(k).is_colon ()) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1621 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1622 if (dim < 0) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1623 dim = k; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1624 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1625 break; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1626 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1627 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1628 if (dim < 0) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1629 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1630 dim_vector dv = dimensions; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1631 dv(0) = 0; |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1632 *this = Array<T> (dv); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1633 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1634 else if (k == len) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1635 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1636 delete_elements (dim, ia(dim)); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1637 } |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1638 else |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1639 { |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1640 (*current_liboctave_error_handler) |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1641 ("A null assignment can only have one non-colon index."); |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1642 } |
4513 | 1643 } |
1644 | |
1645 } | |
1646 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1647 // FIXME: Remove these methods or implement them using assign. |
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1648 |
4513 | 1649 template <class T> |
1650 Array<T>& | |
5275 | 1651 Array<T>::insert (const Array<T>& a, octave_idx_type r, octave_idx_type c) |
4513 | 1652 { |
4786 | 1653 if (ndims () == 2 && a.ndims () == 2) |
1654 insert2 (a, r, c); | |
1655 else | |
1656 insertN (a, r, c); | |
1657 | |
1658 return *this; | |
1659 } | |
1660 | |
1661 | |
1662 template <class T> | |
1663 Array<T>& | |
5275 | 1664 Array<T>::insert2 (const Array<T>& a, octave_idx_type r, octave_idx_type c) |
4786 | 1665 { |
5275 | 1666 octave_idx_type a_rows = a.rows (); |
1667 octave_idx_type a_cols = a.cols (); | |
4786 | 1668 |
1669 if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ()) | |
1670 { | |
1671 (*current_liboctave_error_handler) ("range error for insert"); | |
1672 return *this; | |
1673 } | |
1674 | |
5275 | 1675 for (octave_idx_type j = 0; j < a_cols; j++) |
1676 for (octave_idx_type i = 0; i < a_rows; i++) | |
4786 | 1677 elem (r+i, c+j) = a.elem (i, j); |
1678 | |
1679 return *this; | |
1680 } | |
1681 | |
1682 template <class T> | |
1683 Array<T>& | |
5275 | 1684 Array<T>::insertN (const Array<T>& a, octave_idx_type r, octave_idx_type c) |
4786 | 1685 { |
4806 | 1686 dim_vector dv = dims (); |
1687 | |
4765 | 1688 dim_vector a_dv = a.dims (); |
1689 | |
1690 int n = a_dv.length (); | |
1691 | |
1692 if (n == dimensions.length ()) | |
4513 | 1693 { |
5275 | 1694 Array<octave_idx_type> a_ra_idx (a_dv.length (), 0); |
4765 | 1695 |
1696 a_ra_idx.elem (0) = r; | |
1697 a_ra_idx.elem (1) = c; | |
1698 | |
1699 for (int i = 0; i < n; i++) | |
1700 { | |
4806 | 1701 if (a_ra_idx(i) < 0 || (a_ra_idx(i) + a_dv(i)) > dv(i)) |
4765 | 1702 { |
1703 (*current_liboctave_error_handler) | |
1704 ("Array<T>::insert: range error for insert"); | |
1705 return *this; | |
1706 } | |
1707 } | |
1708 | |
5275 | 1709 octave_idx_type n_elt = a.numel (); |
4806 | 1710 |
1711 const T *a_data = a.data (); | |
1712 | |
5275 | 1713 octave_idx_type iidx = 0; |
4806 | 1714 |
5275 | 1715 octave_idx_type a_rows = a_dv(0); |
1716 | |
1717 octave_idx_type this_rows = dv(0); | |
4806 | 1718 |
5275 | 1719 octave_idx_type numel_page = a_dv(0) * a_dv(1); |
1720 | |
1721 octave_idx_type count_pages = 0; | |
4806 | 1722 |
5275 | 1723 for (octave_idx_type i = 0; i < n_elt; i++) |
4765 | 1724 { |
4806 | 1725 if (i != 0 && i % a_rows == 0) |
1726 iidx += (this_rows - a_rows); | |
1727 | |
1728 if (i % numel_page == 0) | |
1729 iidx = c * dv(0) + r + dv(0) * dv(1) * count_pages++; | |
1730 | |
1731 elem (iidx++) = a_data[i]; | |
4765 | 1732 } |
4513 | 1733 } |
4765 | 1734 else |
1735 (*current_liboctave_error_handler) | |
1736 ("Array<T>::insert: invalid indexing operation"); | |
4513 | 1737 |
1738 return *this; | |
1739 } | |
1740 | |
1741 template <class T> | |
1742 Array<T>& | |
5275 | 1743 Array<T>::insert (const Array<T>& a, const Array<octave_idx_type>& ra_idx) |
4513 | 1744 { |
5275 | 1745 octave_idx_type n = ra_idx.length (); |
4513 | 1746 |
1747 if (n == dimensions.length ()) | |
1748 { | |
4915 | 1749 dim_vector dva = a.dims (); |
1750 dim_vector dv = dims (); | |
1751 int len_a = dva.length (); | |
5120 | 1752 int non_full_dim = 0; |
4513 | 1753 |
5275 | 1754 for (octave_idx_type i = 0; i < n; i++) |
4513 | 1755 { |
4915 | 1756 if (ra_idx(i) < 0 || (ra_idx(i) + |
1757 (i < len_a ? dva(i) : 1)) > dimensions(i)) | |
4513 | 1758 { |
1759 (*current_liboctave_error_handler) | |
1760 ("Array<T>::insert: range error for insert"); | |
1761 return *this; | |
1762 } | |
5120 | 1763 |
1764 if (dv(i) != (i < len_a ? dva(i) : 1)) | |
1765 non_full_dim++; | |
4513 | 1766 } |
1767 | |
4915 | 1768 if (dva.numel ()) |
1769 { | |
5120 | 1770 if (non_full_dim < 2) |
4915 | 1771 { |
5120 | 1772 // Special case for fast concatenation |
1773 const T *a_data = a.data (); | |
5275 | 1774 octave_idx_type numel_to_move = 1; |
1775 octave_idx_type skip = 0; | |
5120 | 1776 for (int i = 0; i < len_a; i++) |
1777 if (ra_idx(i) == 0 && dva(i) == dv(i)) | |
1778 numel_to_move *= dva(i); | |
1779 else | |
1780 { | |
1781 skip = numel_to_move * (dv(i) - dva(i)); | |
1782 numel_to_move *= dva(i); | |
1783 break; | |
1784 } | |
1785 | |
5275 | 1786 octave_idx_type jidx = ra_idx(n-1); |
5120 | 1787 for (int i = n-2; i >= 0; i--) |
1788 { | |
1789 jidx *= dv(i); | |
1790 jidx += ra_idx(i); | |
1791 } | |
1792 | |
5275 | 1793 octave_idx_type iidx = 0; |
1794 octave_idx_type moves = dva.numel () / numel_to_move; | |
1795 for (octave_idx_type i = 0; i < moves; i++) | |
5120 | 1796 { |
5275 | 1797 for (octave_idx_type j = 0; j < numel_to_move; j++) |
5120 | 1798 elem (jidx++) = a_data[iidx++]; |
1799 jidx += skip; | |
1800 } | |
4915 | 1801 } |
5120 | 1802 else |
4915 | 1803 { |
5120 | 1804 // Generic code |
1805 const T *a_data = a.data (); | |
1806 int nel = a.numel (); | |
5275 | 1807 Array<octave_idx_type> a_idx (n, 0); |
5120 | 1808 |
1809 for (int i = 0; i < nel; i++) | |
1810 { | |
1811 int iidx = a_idx(n-1) + ra_idx(n-1); | |
1812 for (int j = n-2; j >= 0; j--) | |
1813 { | |
1814 iidx *= dv(j); | |
1815 iidx += a_idx(j) + ra_idx(j); | |
1816 } | |
1817 | |
1818 elem (iidx) = a_data[i]; | |
1819 | |
1820 increment_index (a_idx, dva); | |
1821 } | |
4915 | 1822 } |
1823 } | |
4513 | 1824 } |
1825 else | |
1826 (*current_liboctave_error_handler) | |
1827 ("Array<T>::insert: invalid indexing operation"); | |
1828 | |
1829 return *this; | |
1830 } | |
1831 | |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
1832 |
4513 | 1833 template <class T> |
1834 Array<T> | |
1835 Array<T>::transpose (void) const | |
1836 { | |
4548 | 1837 assert (ndims () == 2); |
1838 | |
5275 | 1839 octave_idx_type nr = dim1 (); |
1840 octave_idx_type nc = dim2 (); | |
4513 | 1841 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1842 if (nr >= 8 && nc >= 8) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1843 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1844 Array<T> result (dim_vector (nc, nr)); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1845 |
9121
bb62bc406ea7
reuse fast blocked transpose implementation from rec_permute_helper in Array<T>::transpose
Jaroslav Hajek <highegg@gmail.com>
parents:
9100
diff
changeset
|
1846 // Reuse the implementation used for permuting. |
bb62bc406ea7
reuse fast blocked transpose implementation from rec_permute_helper in Array<T>::transpose
Jaroslav Hajek <highegg@gmail.com>
parents:
9100
diff
changeset
|
1847 |
bb62bc406ea7
reuse fast blocked transpose implementation from rec_permute_helper in Array<T>::transpose
Jaroslav Hajek <highegg@gmail.com>
parents:
9100
diff
changeset
|
1848 rec_permute_helper::blk_trans (data (), result.fortran_vec (), nr, nc); |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1849 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1850 return result; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1851 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1852 else if (nr > 1 && nc > 1) |
4513 | 1853 { |
1854 Array<T> result (dim_vector (nc, nr)); | |
1855 | |
5275 | 1856 for (octave_idx_type j = 0; j < nc; j++) |
1857 for (octave_idx_type i = 0; i < nr; i++) | |
4513 | 1858 result.xelem (j, i) = xelem (i, j); |
1859 | |
1860 return result; | |
1861 } | |
1862 else | |
1863 { | |
8333 | 1864 // Fast transpose for vectors and empty matrices. |
4513 | 1865 return Array<T> (*this, dim_vector (nc, nr)); |
1866 } | |
1867 } | |
1868 | |
1869 template <class T> | |
8028
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1870 static T |
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1871 no_op_fcn (const T& x) |
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1872 { |
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1873 return x; |
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1874 } |
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1875 |
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1876 template <class T> |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1877 Array<T> |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1878 Array<T>::hermitian (T (*fcn) (const T&)) const |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1879 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1880 assert (ndims () == 2); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1881 |
8028
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1882 if (! fcn) |
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1883 fcn = no_op_fcn<T>; |
f0fbf47c914c
avoid null pointer call in Array<T>::hermitian
Jaroslav Hajek <highegg@gmail.com>
parents:
7796
diff
changeset
|
1884 |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1885 octave_idx_type nr = dim1 (); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1886 octave_idx_type nc = dim2 (); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1887 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1888 if (nr >= 8 && nc >= 8) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1889 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1890 Array<T> result (dim_vector (nc, nr)); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1891 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1892 // Blocked transpose to attempt to avoid cache misses. |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1893 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1894 // Don't use OCTAVE_LOCAL_BUFFER here as it doesn't work with bool |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1895 // on some compilers. |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1896 T buf[64]; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1897 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1898 octave_idx_type ii = 0, jj; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1899 for (jj = 0; jj < (nc - 8 + 1); jj += 8) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1900 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1901 for (ii = 0; ii < (nr - 8 + 1); ii += 8) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1902 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1903 // Copy to buffer |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1904 for (octave_idx_type j = jj, k = 0, idxj = jj * nr; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1905 j < jj + 8; j++, idxj += nr) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1906 for (octave_idx_type i = ii; i < ii + 8; i++) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1907 buf[k++] = xelem (i + idxj); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1908 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1909 // Copy from buffer |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1910 for (octave_idx_type i = ii, idxi = ii * nc; i < ii + 8; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1911 i++, idxi += nc) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1912 for (octave_idx_type j = jj, k = i - ii; j < jj + 8; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1913 j++, k+=8) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1914 result.xelem (j + idxi) = fcn (buf[k]); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1915 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1916 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1917 if (ii < nr) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1918 for (octave_idx_type j = jj; j < jj + 8; j++) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1919 for (octave_idx_type i = ii; i < nr; i++) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1920 result.xelem (j, i) = fcn (xelem (i, j)); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1921 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1922 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1923 for (octave_idx_type j = jj; j < nc; j++) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1924 for (octave_idx_type i = 0; i < nr; i++) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1925 result.xelem (j, i) = fcn (xelem (i, j)); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1926 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1927 return result; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1928 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1929 else |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1930 { |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1931 Array<T> result (dim_vector (nc, nr)); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1932 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1933 for (octave_idx_type j = 0; j < nc; j++) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1934 for (octave_idx_type i = 0; i < nr; i++) |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1935 result.xelem (j, i) = fcn (xelem (i, j)); |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1936 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1937 return result; |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1938 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1939 } |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1940 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1941 /* |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1942 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1943 %% Tranpose tests for matrices of the tile size and plus or minus a row |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1944 %% and with four tiles. |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1945 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1946 %!shared m7, mt7, m8, mt8, m9, mt9 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1947 %! m7 = reshape (1 : 7*8, 8, 7); |
7796
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1948 %! mt7 = [1:8; 9:16; 17:24; 25:32; 33:40; 41:48; 49:56]; |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1949 %! m8 = reshape (1 : 8*8, 8, 8); |
7796
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1950 %! mt8 = mt8 = [mt7; 57:64]; |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1951 %! m9 = reshape (1 : 9*8, 8, 9); |
7796
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1952 %! mt9 = [mt8; 65:72]; |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1953 |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1954 %!assert(m7', mt7) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1955 %!assert((1i*m7).', 1i * mt7) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1956 %!assert((1i*m7)', conj (1i * mt7)) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1957 %!assert(m8', mt8) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1958 %!assert((1i*m8).', 1i * mt8) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1959 %!assert((1i*m8)', conj (1i * mt8)) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1960 %!assert(m9', mt9) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1961 %!assert((1i*m9).', 1i * mt9) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1962 %!assert((1i*m9)', conj (1i * mt9)) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1963 %!assert([m7, m8; m7, m8]', [mt7, mt7; mt8, mt8]) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1964 %!assert((1i*[m7, m8; m7, m8]).', 1i * [mt7, mt7; mt8, mt8]) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1965 %!assert((1i*[m7, m8; m7, m8])', conj (1i * [mt7, mt7; mt8, mt8])) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1966 %!assert([m8, m8; m8, m8]', [mt8, mt8; mt8, mt8]) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1967 %!assert((1i*[m8, m8; m8, m8]).', 1i * [mt8, mt8; mt8, mt8]) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1968 %!assert((1i*[m8, m8; m8, m8])', conj (1i * [mt8, mt8; mt8, mt8])) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1969 %!assert([m9, m8; m9, m8]', [mt9, mt9; mt8, mt8]) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1970 %!assert((1i*[m9, m8; m9, m8]).', 1i * [mt9, mt9; mt8, mt8]) |
762801c50b21
Fix tests for transpose in Array.cc
David Bateman <dbateman@free.fr>
parents:
7789
diff
changeset
|
1971 %!assert((1i*[m9, m8; m9, m8])', conj (1i * [mt9, mt9; mt8, mt8])) |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1972 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1973 */ |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1974 |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7717
diff
changeset
|
1975 template <class T> |
4513 | 1976 T * |
1977 Array<T>::fortran_vec (void) | |
1978 { | |
6881 | 1979 make_unique (); |
1980 | |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
1981 return slice_data; |
4513 | 1982 } |
1983 | |
1984 template <class T> | |
3933 | 1985 void |
4517 | 1986 Array<T>::maybe_delete_dims (void) |
1987 { | |
4587 | 1988 int nd = dimensions.length (); |
4517 | 1989 |
1990 dim_vector new_dims (1, 1); | |
1991 | |
1992 bool delete_dims = true; | |
1993 | |
4587 | 1994 for (int i = nd - 1; i >= 0; i--) |
4517 | 1995 { |
1996 if (delete_dims) | |
1997 { | |
1998 if (dimensions(i) != 1) | |
1999 { | |
2000 delete_dims = false; | |
2001 | |
2002 new_dims = dim_vector (i + 1, dimensions(i)); | |
2003 } | |
2004 } | |
2005 else | |
2006 new_dims(i) = dimensions(i); | |
2007 } | |
4530 | 2008 |
4587 | 2009 if (nd != new_dims.length ()) |
4517 | 2010 dimensions = new_dims; |
2011 } | |
2012 | |
8700 | 2013 // Non-real types don't have NaNs. |
4517 | 2014 template <class T> |
8725 | 2015 inline bool |
2016 sort_isnan (typename ref_param<T>::type) | |
7433 | 2017 { |
8700 | 2018 return false; |
7433 | 2019 } |
2020 | |
2021 template <class T> | |
2022 Array<T> | |
2023 Array<T>::sort (octave_idx_type dim, sortmode mode) const | |
2024 { | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2025 if (dim < 0 || dim >= ndims ()) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2026 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2027 (*current_liboctave_error_handler) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2028 ("sort: invalid dimension"); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2029 return Array<T> (); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2030 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2031 |
8651
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2032 Array<T> m (dims ()); |
7433 | 2033 |
2034 dim_vector dv = m.dims (); | |
2035 | |
2036 if (m.length () < 1) | |
2037 return m; | |
2038 | |
2039 octave_idx_type ns = dv(dim); | |
2040 octave_idx_type iter = dv.numel () / ns; | |
2041 octave_idx_type stride = 1; | |
8505 | 2042 |
7433 | 2043 for (int i = 0; i < dim; i++) |
2044 stride *= dv(i); | |
2045 | |
2046 T *v = m.fortran_vec (); | |
8651
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2047 const T *ov = data (); |
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2048 |
7433 | 2049 octave_sort<T> lsort; |
2050 | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2051 if (mode) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2052 lsort.set_compare (mode); |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7443
diff
changeset
|
2053 else |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2054 return m; |
7433 | 2055 |
2056 if (stride == 1) | |
2057 { | |
2058 for (octave_idx_type j = 0; j < iter; j++) | |
2059 { | |
8700 | 2060 // copy and partition out NaNs. |
2061 // FIXME: impact on integer types noticeable? | |
2062 octave_idx_type kl = 0, ku = ns; | |
2063 for (octave_idx_type i = 0; i < ns; i++) | |
2064 { | |
2065 T tmp = ov[i]; | |
8725 | 2066 if (sort_isnan<T> (tmp)) |
8700 | 2067 v[--ku] = tmp; |
2068 else | |
2069 v[kl++] = tmp; | |
2070 } | |
2071 | |
2072 // sort. | |
2073 lsort.sort (v, kl); | |
2074 | |
2075 if (ku < ns) | |
2076 { | |
2077 // NaNs are in reverse order | |
2078 std::reverse (v + ku, v + ns); | |
2079 if (mode == DESCENDING) | |
2080 std::rotate (v, v + ku, v + ns); | |
2081 } | |
2082 | |
7433 | 2083 v += ns; |
8651
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2084 ov += ns; |
7433 | 2085 } |
2086 } | |
2087 else | |
2088 { | |
8700 | 2089 OCTAVE_LOCAL_BUFFER (T, buf, ns); |
7433 | 2090 |
2091 for (octave_idx_type j = 0; j < iter; j++) | |
2092 { | |
8505 | 2093 octave_idx_type offset = j; |
2094 octave_idx_type offset2 = 0; | |
2095 | |
7433 | 2096 while (offset >= stride) |
2097 { | |
2098 offset -= stride; | |
2099 offset2++; | |
2100 } | |
8505 | 2101 |
7433 | 2102 offset += offset2 * stride * ns; |
2103 | |
8700 | 2104 // gather and partition out NaNs. |
2105 // FIXME: impact on integer types noticeable? | |
2106 octave_idx_type kl = 0, ku = ns; | |
2107 for (octave_idx_type i = 0; i < ns; i++) | |
2108 { | |
2109 T tmp = ov[i*stride + offset]; | |
8725 | 2110 if (sort_isnan<T> (tmp)) |
8700 | 2111 buf[--ku] = tmp; |
2112 else | |
2113 buf[kl++] = tmp; | |
2114 } | |
7433 | 2115 |
8700 | 2116 // sort. |
2117 lsort.sort (buf, kl); | |
2118 | |
2119 if (ku < ns) | |
2120 { | |
2121 // NaNs are in reverse order | |
2122 std::reverse (buf + ku, buf + ns); | |
2123 if (mode == DESCENDING) | |
2124 std::rotate (buf, buf + ku, buf + ns); | |
2125 } | |
2126 | |
2127 // scatter. | |
7433 | 2128 for (octave_idx_type i = 0; i < ns; i++) |
8700 | 2129 v[i*stride + offset] = buf[i]; |
7433 | 2130 } |
2131 } | |
2132 | |
2133 return m; | |
2134 } | |
2135 | |
2136 template <class T> | |
2137 Array<T> | |
2138 Array<T>::sort (Array<octave_idx_type> &sidx, octave_idx_type dim, | |
2139 sortmode mode) const | |
2140 { | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2141 if (dim < 0 || dim >= ndims ()) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2142 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2143 (*current_liboctave_error_handler) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2144 ("sort: invalid dimension"); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2145 return Array<T> (); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2146 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2147 |
8651
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2148 Array<T> m (dims ()); |
7433 | 2149 |
2150 dim_vector dv = m.dims (); | |
2151 | |
2152 if (m.length () < 1) | |
2153 { | |
2154 sidx = Array<octave_idx_type> (dv); | |
2155 return m; | |
2156 } | |
2157 | |
2158 octave_idx_type ns = dv(dim); | |
2159 octave_idx_type iter = dv.numel () / ns; | |
2160 octave_idx_type stride = 1; | |
8505 | 2161 |
7433 | 2162 for (int i = 0; i < dim; i++) |
2163 stride *= dv(i); | |
2164 | |
2165 T *v = m.fortran_vec (); | |
8651
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2166 const T *ov = data (); |
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2167 |
8700 | 2168 octave_sort<T> lsort; |
7433 | 2169 |
8700 | 2170 sidx = Array<octave_idx_type> (dv); |
2171 octave_idx_type *vi = sidx.fortran_vec (); | |
2172 | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2173 if (mode) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2174 lsort.set_compare (mode); |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7443
diff
changeset
|
2175 else |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2176 return m; |
7433 | 2177 |
2178 if (stride == 1) | |
2179 { | |
2180 for (octave_idx_type j = 0; j < iter; j++) | |
2181 { | |
8700 | 2182 // copy and partition out NaNs. |
2183 // FIXME: impact on integer types noticeable? | |
2184 octave_idx_type kl = 0, ku = ns; | |
2185 for (octave_idx_type i = 0; i < ns; i++) | |
2186 { | |
2187 T tmp = ov[i]; | |
8725 | 2188 if (sort_isnan<T> (tmp)) |
8700 | 2189 { |
2190 --ku; | |
2191 v[ku] = tmp; | |
2192 vi[ku] = i; | |
2193 } | |
2194 else | |
2195 { | |
2196 v[kl] = tmp; | |
2197 vi[kl] = i; | |
2198 kl++; | |
2199 } | |
2200 } | |
7433 | 2201 |
8700 | 2202 // sort. |
2203 lsort.sort (v, vi, kl); | |
2204 | |
2205 if (ku < ns) | |
2206 { | |
2207 // NaNs are in reverse order | |
2208 std::reverse (v + ku, v + ns); | |
2209 std::reverse (vi + ku, vi + ns); | |
2210 if (mode == DESCENDING) | |
2211 { | |
2212 std::rotate (v, v + ku, v + ns); | |
2213 std::rotate (vi, vi + ku, vi + ns); | |
2214 } | |
2215 } | |
2216 | |
7433 | 2217 v += ns; |
8700 | 2218 vi += ns; |
8651
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2219 ov += ns; |
7433 | 2220 } |
2221 } | |
2222 else | |
2223 { | |
8700 | 2224 OCTAVE_LOCAL_BUFFER (T, buf, ns); |
2225 OCTAVE_LOCAL_BUFFER (octave_idx_type, bufi, ns); | |
8651
ea8e65ca234f
reduce memory usage in sorting
Jaroslav Hajek <highegg@gmail.com>
parents:
8580
diff
changeset
|
2226 |
8700 | 2227 for (octave_idx_type j = 0; j < iter; j++) |
7433 | 2228 { |
2229 octave_idx_type offset = j; | |
2230 octave_idx_type offset2 = 0; | |
8505 | 2231 |
7433 | 2232 while (offset >= stride) |
2233 { | |
2234 offset -= stride; | |
2235 offset2++; | |
2236 } | |
8505 | 2237 |
7433 | 2238 offset += offset2 * stride * ns; |
8700 | 2239 |
2240 // gather and partition out NaNs. | |
2241 // FIXME: impact on integer types noticeable? | |
2242 octave_idx_type kl = 0, ku = ns; | |
2243 for (octave_idx_type i = 0; i < ns; i++) | |
2244 { | |
2245 T tmp = ov[i*stride + offset]; | |
8725 | 2246 if (sort_isnan<T> (tmp)) |
8700 | 2247 { |
2248 --ku; | |
2249 buf[ku] = tmp; | |
2250 bufi[ku] = i; | |
2251 } | |
2252 else | |
2253 { | |
2254 buf[kl] = tmp; | |
2255 bufi[kl] = i; | |
2256 kl++; | |
2257 } | |
2258 } | |
7433 | 2259 |
8700 | 2260 // sort. |
2261 lsort.sort (buf, bufi, kl); | |
2262 | |
2263 if (ku < ns) | |
2264 { | |
2265 // NaNs are in reverse order | |
2266 std::reverse (buf + ku, buf + ns); | |
2267 std::reverse (bufi + ku, bufi + ns); | |
2268 if (mode == DESCENDING) | |
2269 { | |
2270 std::rotate (buf, buf + ku, buf + ns); | |
2271 std::rotate (bufi, bufi + ku, bufi + ns); | |
2272 } | |
2273 } | |
2274 | |
2275 // scatter. | |
7433 | 2276 for (octave_idx_type i = 0; i < ns; i++) |
8700 | 2277 v[i*stride + offset] = buf[i]; |
2278 for (octave_idx_type i = 0; i < ns; i++) | |
2279 vi[i*stride + offset] = bufi[i]; | |
7433 | 2280 } |
2281 } | |
2282 | |
2283 return m; | |
2284 } | |
2285 | |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2286 template <class T> |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2287 sortmode |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2288 Array<T>::is_sorted (sortmode mode) const |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2289 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2290 if (nelem () <= 1) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2291 return ASCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2292 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2293 const T *lo = data (), *hi = data () + nelem () - 1; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2294 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2295 // Check for NaNs at the beginning and end. |
8725 | 2296 if (mode != ASCENDING && sort_isnan<T> (*lo)) |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2297 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2298 mode = DESCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2299 do |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2300 ++lo; |
8725 | 2301 while (lo < hi && sort_isnan<T> (*lo)); |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2302 } |
8725 | 2303 else if (mode != DESCENDING && sort_isnan<T> (*hi)) |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2304 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2305 mode = ASCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2306 do |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2307 --hi; |
8725 | 2308 while (lo < hi && sort_isnan<T> (*hi)); |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2309 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2310 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2311 octave_sort<T> lsort; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2312 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2313 // If mode is still unknown, compare lo and hi |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2314 if (! mode) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2315 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2316 if (lsort.descending_compare (*lo, *hi)) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2317 mode = DESCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2318 else if (lsort.ascending_compare (*lo, *hi)) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2319 mode = ASCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2320 else |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2321 mode = ASCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2322 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2323 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2324 lsort.set_compare (mode); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2325 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2326 if (! lsort.is_sorted (lo, hi - lo + 1)) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2327 mode = UNSORTED; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2328 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2329 return mode; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2330 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2331 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2332 template <class T> |
8725 | 2333 typename Array<T>::compare_fcn_type |
2334 sortrows_comparator (sortmode mode, const Array<T>& /* a */, | |
2335 bool /* allow_chk */) | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2336 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2337 if (mode == ASCENDING) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2338 return octave_sort<T>::ascending_compare; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2339 else if (mode == DESCENDING) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2340 return octave_sort<T>::descending_compare; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2341 else |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2342 return 0; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2343 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2344 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2345 template <class T> |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2346 Array<octave_idx_type> |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2347 Array<T>::sort_rows_idx (sortmode mode) const |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2348 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2349 Array<octave_idx_type> idx; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2350 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2351 octave_sort<T> lsort; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2352 |
8725 | 2353 lsort.set_compare (sortrows_comparator (mode, *this, true)); |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2354 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2355 octave_idx_type r = rows (), c = cols (); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2356 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2357 idx = Array<octave_idx_type> (r); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2358 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2359 lsort.sort_rows (data (), idx.fortran_vec (), r, c); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2360 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2361 return idx; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2362 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2363 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2364 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2365 template <class T> |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2366 sortmode |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2367 Array<T>::is_sorted_rows (sortmode mode) const |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2368 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2369 octave_sort<T> lsort; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2370 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2371 octave_idx_type r = rows (), c = cols (); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2372 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2373 if (r <= 1 || c == 0) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2374 return mode ? mode : ASCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2375 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2376 if (! mode) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2377 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2378 // Auto-detect mode. |
8725 | 2379 compare_fcn_type compare |
2380 = sortrows_comparator (ASCENDING, *this, false); | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2381 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2382 octave_idx_type i; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2383 for (i = 0; i < cols (); i++) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2384 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2385 T l = elem (0, i), u = elem (rows () - 1, i); |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2386 if (compare (l, u)) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2387 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2388 if (mode == DESCENDING) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2389 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2390 mode = UNSORTED; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2391 break; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2392 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2393 else |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2394 mode = ASCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2395 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2396 else if (compare (u, l)) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2397 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2398 if (mode == ASCENDING) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2399 { |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2400 mode = UNSORTED; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2401 break; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2402 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2403 else |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2404 mode = DESCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2405 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2406 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2407 if (! mode && i == cols ()) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2408 mode = ASCENDING; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2409 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2410 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2411 if (mode) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2412 { |
8725 | 2413 lsort.set_compare (sortrows_comparator (mode, *this, false)); |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2414 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2415 if (! lsort.is_sorted_rows (data (), r, c)) |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2416 mode = UNSORTED; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2417 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2418 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2419 return mode; |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2420 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2421 } |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2422 |
8814
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2423 // Do a binary lookup in a sorted array. |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2424 template <class T> |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2425 octave_idx_type |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2426 Array<T>::lookup (const T& value, sortmode mode) const |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2427 { |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2428 octave_idx_type n = numel (); |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2429 octave_sort<T> lsort; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2430 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2431 if (mode == UNSORTED) |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2432 { |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2433 // auto-detect mode |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2434 if (n > 1 && lsort.descending_compare (elem (0), elem (n-1))) |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2435 mode = DESCENDING; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2436 else |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2437 mode = ASCENDING; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2438 } |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2439 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2440 lsort.set_compare (mode); |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2441 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2442 return lsort.lookup (data (), n, value); |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2443 } |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2444 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2445 // Ditto, but for an array of values, specializing on long runs. |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2446 // Adds optional offset to all indices. |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2447 template <class T> |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2448 Array<octave_idx_type> |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2449 Array<T>::lookup (const Array<T>& values, sortmode mode, |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2450 bool linf, bool rinf) const |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2451 { |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2452 octave_idx_type n = numel (); |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2453 octave_sort<T> lsort; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2454 Array<octave_idx_type> idx (values.dims ()); |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2455 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2456 if (mode == UNSORTED) |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2457 { |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2458 // auto-detect mode |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2459 if (n > 1 && lsort.descending_compare (elem (0), elem (n-1))) |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2460 mode = DESCENDING; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2461 else |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2462 mode = ASCENDING; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2463 } |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2464 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2465 lsort.set_compare (mode); |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2466 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2467 // set offset and shift size. |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2468 octave_idx_type offset = 0; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2469 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2470 if (linf && n > 0) |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2471 { |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2472 offset++; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2473 n--; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2474 } |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2475 if (rinf && n > 0) |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2476 n--; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2477 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2478 lsort.lookup (data () + offset, n, values.data (), values.numel (), |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2479 idx.fortran_vec (), offset); |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2480 |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2481 return idx; |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2482 } |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2483 |
9025 | 2484 template <class T> |
2485 Array<octave_idx_type> | |
9341
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2486 Array<T>::lookupm (const Array<T>& values, sortmode mode) const |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2487 { |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2488 octave_idx_type n = numel (); |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2489 octave_sort<T> lsort; |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2490 Array<octave_idx_type> idx (values.dims ()); |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2491 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2492 if (mode == UNSORTED) |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2493 { |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2494 // auto-detect mode |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2495 if (n > 1 && lsort.descending_compare (elem (0), elem (n-1))) |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2496 mode = DESCENDING; |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2497 else |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2498 mode = ASCENDING; |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2499 } |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2500 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2501 lsort.set_compare (mode); |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2502 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2503 lsort.lookupm (data (), n, values.data (), values.numel (), |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2504 idx.fortran_vec ()); |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2505 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2506 return idx; |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2507 } |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2508 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2509 template <class T> |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2510 Array<bool> |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2511 Array<T>::lookupb (const Array<T>& values, sortmode mode) const |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2512 { |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2513 octave_idx_type n = numel (); |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2514 octave_sort<T> lsort; |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2515 Array<bool> match (values.dims ()); |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2516 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2517 if (mode == UNSORTED) |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2518 { |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2519 // auto-detect mode |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2520 if (n > 1 && lsort.descending_compare (elem (0), elem (n-1))) |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2521 mode = DESCENDING; |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2522 else |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2523 mode = ASCENDING; |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2524 } |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2525 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2526 lsort.set_compare (mode); |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2527 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2528 lsort.lookupb (data (), n, values.data (), values.numel (), |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2529 match.fortran_vec ()); |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2530 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2531 return match; |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2532 } |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2533 |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2534 template <class T> |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2535 Array<octave_idx_type> |
9025 | 2536 Array<T>::find (octave_idx_type n, bool backward) const |
2537 { | |
2538 Array<octave_idx_type> retval; | |
2539 const T *src = data (); | |
2540 octave_idx_type nel = nelem (); | |
2541 const T zero = T (); | |
9310 | 2542 if (n < 0 || n >= nel) |
9025 | 2543 { |
2544 // We want all elements, which means we'll almost surely need | |
2545 // to resize. So count first, then allocate array of exact size. | |
2546 octave_idx_type cnt = 0; | |
2547 for (octave_idx_type i = 0; i < nel; i++) | |
2548 cnt += src[i] != zero; | |
2549 | |
2550 retval = Array<octave_idx_type> (cnt); | |
2551 octave_idx_type *dest = retval.fortran_vec (); | |
2552 for (octave_idx_type i = 0; i < nel; i++) | |
2553 if (src[i] != zero) *dest++ = i; | |
2554 } | |
2555 else | |
2556 { | |
2557 // We want a fixed max number of elements, usually small. So be | |
2558 // optimistic, alloc the array in advance, and then resize if | |
2559 // needed. | |
2560 retval = Array<octave_idx_type> (n); | |
2561 if (backward) | |
2562 { | |
2563 // Do the search as a series of successive single-element searches. | |
2564 octave_idx_type k = 0, l = nel - 1; | |
2565 for (; k < n; k++) | |
2566 { | |
2567 for (;l >= 0 && src[l] == zero; l--) ; | |
2568 if (l >= 0) | |
2569 retval(k) = l--; | |
2570 else | |
2571 break; | |
2572 } | |
2573 if (k < n) | |
2574 retval.resize (k); | |
9310 | 2575 octave_idx_type *rdata = retval.fortran_vec (); |
2576 std::reverse (rdata, rdata + k); | |
9025 | 2577 } |
2578 else | |
2579 { | |
2580 // Do the search as a series of successive single-element searches. | |
2581 octave_idx_type k = 0, l = 0; | |
2582 for (; k < n; k++) | |
2583 { | |
2584 for (;l != nel && src[l] == zero; l++) ; | |
9029
2df28ad88b0e
small fix in Array::find
Jaroslav Hajek <highegg@gmail.com>
parents:
9025
diff
changeset
|
2585 if (l != nel) |
9025 | 2586 retval(k) = l++; |
2587 else | |
2588 break; | |
2589 } | |
2590 if (k < n) | |
2591 retval.resize (k); | |
2592 } | |
2593 } | |
2594 | |
9046
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2595 // Fixup return dimensions, for Matlab compatibility. |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2596 // find(zeros(0,0)) -> zeros(0,0) |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2597 // find(zeros(1,0)) -> zeros(1,0) |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2598 // find(zeros(0,1)) -> zeros(0,1) |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2599 // find(zeros(0,X)) -> zeros(0,1) |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2600 // find(zeros(1,1)) -> zeros(0,0) !!!! WHY? |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2601 // find(zeros(0,1,0)) -> zeros(0,0) |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2602 // find(zeros(0,1,0,1)) -> zeros(0,0) etc |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2603 |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2604 if ((numel () == 1 && retval.is_empty ()) |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2605 || (rows () == 0 && dims ().numel (1) == 0)) |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2606 retval.dimensions = dim_vector (); |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2607 else if (rows () == 1 && ndims () == 2) |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2608 retval.dimensions = dim_vector (1, retval.length ()); |
88bf56bbccca
make Array::find already return Matlab-compatible dimensions
Jaroslav Hajek <highegg@gmail.com>
parents:
9029
diff
changeset
|
2609 |
9025 | 2610 return retval; |
2611 } | |
2612 | |
2613 | |
9237
3c1762c7e787
Add missing xxx_API decoration and remove misplaced ones
Michael Goffioul <michael.goffioul@gmail.com>
parents:
9222
diff
changeset
|
2614 #define INSTANTIATE_ARRAY_SORT(T) template class OCTAVE_API octave_sort<T>; |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2615 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2616 #define NO_INSTANTIATE_ARRAY_SORT(T) \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2617 \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2618 template <> Array<T> \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2619 Array<T>::sort (octave_idx_type, sortmode) const { return *this; } \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2620 \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2621 template <> Array<T> \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2622 Array<T>::sort (Array<octave_idx_type> &sidx, octave_idx_type, sortmode) const \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2623 { sidx = Array<octave_idx_type> (); return *this; } \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2624 \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2625 template <> sortmode \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2626 Array<T>::is_sorted (sortmode) const \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2627 { return UNSORTED; } \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2628 \ |
8725 | 2629 Array<T>::compare_fcn_type \ |
2630 sortrows_comparator (sortmode, const Array<T>&, bool) \ | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2631 { return 0; } \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2632 \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2633 template <> Array<octave_idx_type> \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2634 Array<T>::sort_rows_idx (sortmode) const \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2635 { return Array<octave_idx_type> (); } \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2636 \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2637 template <> sortmode \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2638 Array<T>::is_sorted_rows (sortmode) const \ |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2639 { return UNSORTED; } \ |
8814
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2640 \ |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2641 template <> octave_idx_type \ |
9222
7bd406e12e4d
instantiate Array<void *> in liboctave
Jaroslav Hajek <highegg@gmail.com>
parents:
9201
diff
changeset
|
2642 Array<T>::lookup (T const &, sortmode) const \ |
8814
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2643 { return 0; } \ |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2644 template <> Array<octave_idx_type> \ |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2645 Array<T>::lookup (const Array<T>&, sortmode, bool, bool) const \ |
de16ebeef93d
improve lookup, provide Array<T>::lookup
Jaroslav Hajek <highegg@gmail.com>
parents:
8799
diff
changeset
|
2646 { return Array<octave_idx_type> (); } \ |
9341
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2647 template <> Array<octave_idx_type> \ |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2648 Array<T>::lookupm (const Array<T>&, sortmode) const \ |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2649 { return Array<octave_idx_type> (); } \ |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2650 template <> Array<bool> \ |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2651 Array<T>::lookupb (const Array<T>&, sortmode) const \ |
9fd5c56ce57a
extend lookup capabilities
Jaroslav Hajek <highegg@gmail.com>
parents:
9310
diff
changeset
|
2652 { return Array<bool> (); } \ |
9025 | 2653 template <> Array<octave_idx_type> \ |
2654 Array<T>::find (octave_idx_type, bool) const\ | |
2655 { return Array<octave_idx_type> (); } \ | |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2656 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2657 |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2658 template <class T> |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2659 Array<T> |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2660 Array<T>::diag (octave_idx_type k) const |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2661 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2662 dim_vector dv = dims (); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2663 octave_idx_type nd = dv.length (); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2664 Array<T> d; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2665 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2666 if (nd > 2) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2667 (*current_liboctave_error_handler) ("Matrix must be 2-dimensional"); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2668 else |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2669 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2670 octave_idx_type nnr = dv (0); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2671 octave_idx_type nnc = dv (1); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2672 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2673 if (nnr == 0 || nnc == 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2674 ; // do nothing |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2675 else if (nnr != 1 && nnc != 1) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2676 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2677 if (k > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2678 nnc -= k; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2679 else if (k < 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2680 nnr += k; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2681 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2682 if (nnr > 0 && nnc > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2683 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2684 octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2685 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2686 d.resize (dim_vector (ndiag, 1)); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2687 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2688 if (k > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2689 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2690 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2691 d.xelem (i) = elem (i, i+k); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2692 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2693 else if (k < 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2694 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2695 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2696 d.xelem (i) = elem (i-k, i); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2697 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2698 else |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2699 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2700 for (octave_idx_type i = 0; i < ndiag; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2701 d.xelem (i) = elem (i, i); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2702 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2703 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2704 else |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2705 (*current_liboctave_error_handler) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2706 ("diag: requested diagonal out of range"); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2707 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2708 else if (nnr != 0 && nnc != 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2709 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2710 octave_idx_type roff = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2711 octave_idx_type coff = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2712 if (k > 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2713 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2714 roff = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2715 coff = k; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2716 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2717 else if (k < 0) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2718 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2719 roff = -k; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2720 coff = 0; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2721 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2722 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2723 if (nnr == 1) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2724 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2725 octave_idx_type n = nnc + std::abs (k); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
2726 d = Array<T> (dim_vector (n, n), resize_fill_value ()); |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2727 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2728 for (octave_idx_type i = 0; i < nnc; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2729 d.xelem (i+roff, i+coff) = elem (0, i); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2730 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2731 else |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2732 { |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2733 octave_idx_type n = nnr + std::abs (k); |
8290
7cbe01c21986
improve dense array indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8179
diff
changeset
|
2734 d = Array<T> (dim_vector (n, n), resize_fill_value ()); |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2735 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2736 for (octave_idx_type i = 0; i < nnr; i++) |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2737 d.xelem (i+roff, i+coff) = elem (i, 0); |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2738 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2739 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2740 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2741 |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2742 return d; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2743 } |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7605
diff
changeset
|
2744 |
4517 | 2745 template <class T> |
2746 void | |
3933 | 2747 Array<T>::print_info (std::ostream& os, const std::string& prefix) const |
2748 { | |
8523
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
2749 os << prefix << "rep address: " << rep << '\n' |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
2750 << prefix << "rep->len: " << rep->len << '\n' |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
2751 << prefix << "rep->data: " << static_cast<void *> (rep->data) << '\n' |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
2752 << prefix << "rep->count: " << rep->count << '\n' |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
2753 << prefix << "slice_data: " << static_cast<void *> (slice_data) << '\n' |
ad3afaaa19c1
implement non-copying contiguous range indexing
Jaroslav Hajek <highegg@gmail.com>
parents:
8505
diff
changeset
|
2754 << prefix << "slice_len: " << slice_len << '\n'; |
4513 | 2755 |
2756 // 2D info: | |
2757 // | |
4657 | 2758 // << pefix << "rows: " << rows () << "\n" |
4513 | 2759 // << prefix << "cols: " << cols () << "\n"; |
3933 | 2760 } |
2761 | |
9201
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2762 template <class T> |
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2763 void Array<T>::instantiation_guard () |
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2764 { |
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2765 // This guards against accidental implicit instantiations. |
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2766 // Array<T> instances should always be explicit and use INSTANTIATE_ARRAY. |
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2767 T::__xXxXx__(); |
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2768 } |
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2769 |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2770 #define INSTANTIATE_ARRAY(T, API) \ |
9201
472f0e22aa60
guard against implicit instantiation
Jaroslav Hajek <highegg@gmail.com>
parents:
9121
diff
changeset
|
2771 template <> void Array<T>::instantiation_guard () { } \ |
8721
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2772 template class API Array<T> |
e9cb742df9eb
imported patch sort3.diff
Jaroslav Hajek <highegg@gmail.com>
parents:
8700
diff
changeset
|
2773 |
237 | 2774 /* |
2775 ;;; Local Variables: *** | |
2776 ;;; mode: C++ *** | |
2777 ;;; End: *** | |
2778 */ |