Mercurial > octave-nkf
comparison liboctave/Array.cc @ 11586:12df7854fa7c
strip trailing whitespace from source files
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 20 Jan 2011 17:24:59 -0500 |
parents | a83bad07f7e3 |
children | 4ced6b90fffb |
comparison
equal
deleted
inserted
replaced
11585:1473d0cf86d2 | 11586:12df7854fa7c |
---|---|
1 // Template array classes | 1 // Template array classes |
2 /* | 2 /* |
3 | 3 |
4 Copyright (C) 1993-2011 John W. Eaton | 4 Copyright (C) 1993-2011 John W. Eaton |
5 Copyright (C) 2008-2009 Jaroslav Hajek | 5 Copyright (C) 2008-2009 Jaroslav Hajek |
6 Copyright (C) 2009 VZLU Prague | 6 Copyright (C) 2009 VZLU Prague |
7 | 7 |
8 This file is part of Octave. | 8 This file is part of Octave. |
9 | 9 |
86 { | 86 { |
87 if (--rep->count <= 0) | 87 if (--rep->count <= 0) |
88 delete rep; | 88 delete rep; |
89 | 89 |
90 rep = nil_rep (); | 90 rep = nil_rep (); |
91 rep->count++; | 91 rep->count++; |
92 slice_data = rep->data; | 92 slice_data = rep->data; |
93 slice_len = rep->len; | 93 slice_len = rep->len; |
94 | 94 |
95 dimensions = dim_vector (); | 95 dimensions = dim_vector (); |
96 } | 96 } |
183 { | 183 { |
184 return ::compute_index (ra_idx, dimensions); | 184 return ::compute_index (ra_idx, dimensions); |
185 } | 185 } |
186 | 186 |
187 template <class T> | 187 template <class T> |
188 T& | 188 T& |
189 Array<T>::checkelem (octave_idx_type n) | 189 Array<T>::checkelem (octave_idx_type n) |
190 { | 190 { |
191 // Do checks directly to avoid recomputing slice_len. | 191 // Do checks directly to avoid recomputing slice_len. |
192 if (n < 0) | 192 if (n < 0) |
193 gripe_invalid_index (); | 193 gripe_invalid_index (); |
196 | 196 |
197 return elem (n); | 197 return elem (n); |
198 } | 198 } |
199 | 199 |
200 template <class T> | 200 template <class T> |
201 T& | 201 T& |
202 Array<T>::checkelem (octave_idx_type i, octave_idx_type j) | 202 Array<T>::checkelem (octave_idx_type i, octave_idx_type j) |
203 { | 203 { |
204 return elem (compute_index (i, j)); | 204 return elem (compute_index (i, j)); |
205 } | 205 } |
206 | 206 |
207 template <class T> | 207 template <class T> |
208 T& | 208 T& |
209 Array<T>::checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) | 209 Array<T>::checkelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) |
210 { | 210 { |
211 return elem (compute_index (i, j, k)); | 211 return elem (compute_index (i, j, k)); |
212 } | 212 } |
213 | 213 |
214 template <class T> | 214 template <class T> |
215 T& | 215 T& |
216 Array<T>::checkelem (const Array<octave_idx_type>& ra_idx) | 216 Array<T>::checkelem (const Array<octave_idx_type>& ra_idx) |
217 { | 217 { |
218 return elem (compute_index (ra_idx)); | 218 return elem (compute_index (ra_idx)); |
219 } | 219 } |
220 | 220 |
414 dest = do_permute (src + i * step, dest, lev-1); | 414 dest = do_permute (src + i * step, dest, lev-1); |
415 } | 415 } |
416 | 416 |
417 return dest; | 417 return dest; |
418 } | 418 } |
419 | 419 |
420 public: | 420 public: |
421 | 421 |
422 template <class T> | 422 template <class T> |
423 void permute (const T *src, T *dest) const { do_permute (src, dest, top); } | 423 void permute (const T *src, T *dest) const { do_permute (src, dest, top); } |
424 | 424 |
503 } | 503 } |
504 | 504 |
505 // Helper class for multi-d index reduction and recursive | 505 // Helper class for multi-d index reduction and recursive |
506 // indexing/indexed assignment. Rationale: we could avoid recursion | 506 // indexing/indexed assignment. Rationale: we could avoid recursion |
507 // using a state machine instead. However, using recursion is much | 507 // using a state machine instead. However, using recursion is much |
508 // more amenable to possible parallelization in the future. | 508 // more amenable to possible parallelization in the future. |
509 // Also, the recursion solution is cleaner and more understandable. | 509 // Also, the recursion solution is cleaner and more understandable. |
510 | 510 |
511 class rec_index_helper | 511 class rec_index_helper |
512 { | 512 { |
513 // CDIM occupies the last half of the space allocated for dim to | 513 // CDIM occupies the last half of the space allocated for dim to |
543 // Unsuccessful, store index & cumulative dim. | 543 // Unsuccessful, store index & cumulative dim. |
544 top++; | 544 top++; |
545 idx[top] = ia(i); | 545 idx[top] = ia(i); |
546 dim[top] = dv(i); | 546 dim[top] = dv(i); |
547 cdim[top] = cdim[top-1] * dim[top-1]; | 547 cdim[top] = cdim[top-1] * dim[top-1]; |
548 } | 548 } |
549 } | 549 } |
550 } | 550 } |
551 | 551 |
552 ~rec_index_helper (void) { delete [] idx; delete [] dim; } | 552 ~rec_index_helper (void) { delete [] idx; delete [] dim; } |
553 | 553 |
566 dest = do_index (src + d*idx[lev].xelem (i), dest, lev-1); | 566 dest = do_index (src + d*idx[lev].xelem (i), dest, lev-1); |
567 } | 567 } |
568 | 568 |
569 return dest; | 569 return dest; |
570 } | 570 } |
571 | 571 |
572 // Recursive N-d indexed assignment | 572 // Recursive N-d indexed assignment |
573 template <class T> | 573 template <class T> |
574 const T *do_assign (const T *src, T *dest, int lev) const | 574 const T *do_assign (const T *src, T *dest, int lev) const |
575 { | 575 { |
576 if (lev == 0) | 576 if (lev == 0) |
608 void assign (const T *src, T *dest) const { do_assign (src, dest, top); } | 608 void assign (const T *src, T *dest) const { do_assign (src, dest, top); } |
609 | 609 |
610 template <class T> | 610 template <class T> |
611 void fill (const T& val, T *dest) const { do_fill (val, dest, top); } | 611 void fill (const T& val, T *dest) const { do_fill (val, dest, top); } |
612 | 612 |
613 bool is_cont_range (octave_idx_type& l, | 613 bool is_cont_range (octave_idx_type& l, |
614 octave_idx_type& u) const | 614 octave_idx_type& u) const |
615 { | 615 { |
616 return top == 0 && idx[0].is_cont_range (dim[0], l, u); | 616 return top == 0 && idx[0].is_cont_range (dim[0], l, u); |
617 } | 617 } |
618 }; | 618 }; |
673 fill_or_memset (dext[lev] - k * dd, rfv, dest + k * dd); | 673 fill_or_memset (dext[lev] - k * dd, rfv, dest + k * dd); |
674 } | 674 } |
675 } | 675 } |
676 public: | 676 public: |
677 template <class T> | 677 template <class T> |
678 void resize_fill (const T* src, T *dest, const T& rfv) const | 678 void resize_fill (const T* src, T *dest, const T& rfv) const |
679 { do_resize_fill (src, dest, rfv, n-1); } | 679 { do_resize_fill (src, dest, rfv, n-1); } |
680 | 680 |
681 }; | 681 }; |
682 | 682 |
683 template <class T> | 683 template <class T> |
831 { | 831 { |
832 // A(:,:,...,:) produces a shallow copy. | 832 // A(:,:,...,:) produces a shallow copy. |
833 dv.chop_trailing_singletons (); | 833 dv.chop_trailing_singletons (); |
834 retval = Array<T> (*this, dv); | 834 retval = Array<T> (*this, dv); |
835 } | 835 } |
836 else | 836 else |
837 { | 837 { |
838 // Form result dimensions. | 838 // Form result dimensions. |
839 dim_vector rdv = dim_vector::alloc (ial); | 839 dim_vector rdv = dim_vector::alloc (ial); |
840 for (int i = 0; i < ial; i++) rdv(i) = ia(i).length (dv(i)); | 840 for (int i = 0; i < ial; i++) rdv(i) = ia(i).length (dv(i)); |
841 rdv.chop_trailing_singletons (); | 841 rdv.chop_trailing_singletons (); |
887 // last one, search me why). Giving a column vector would make | 887 // last one, search me why). Giving a column vector would make |
888 // much more sense (given the way trailing singleton dims are | 888 // much more sense (given the way trailing singleton dims are |
889 // treated). | 889 // treated). |
890 bool invalid = false; | 890 bool invalid = false; |
891 if (rows () == 0 || rows () == 1) | 891 if (rows () == 0 || rows () == 1) |
892 dv = dim_vector (1, n); | 892 dv = dim_vector (1, n); |
893 else if (columns () == 1) | 893 else if (columns () == 1) |
894 dv = dim_vector (n, 1); | 894 dv = dim_vector (n, 1); |
895 else | 895 else |
896 invalid = true; | 896 invalid = true; |
897 | 897 |
898 if (invalid) | 898 if (invalid) |
899 gripe_invalid_resize (); | 899 gripe_invalid_resize (); |
900 else | 900 else |
901 { | 901 { |
902 octave_idx_type nx = numel (); | 902 octave_idx_type nx = numel (); |
1002 Array<T> tmp (dv); | 1002 Array<T> tmp (dv); |
1003 // Prepare for recursive resizing. | 1003 // Prepare for recursive resizing. |
1004 rec_resize_helper rh (dv, dimensions.redim (dvl)); | 1004 rec_resize_helper rh (dv, dimensions.redim (dvl)); |
1005 | 1005 |
1006 // Do it. | 1006 // Do it. |
1007 rh.resize_fill (data (), tmp.fortran_vec (), rfv); | 1007 rh.resize_fill (data (), tmp.fortran_vec (), rfv); |
1008 *this = tmp; | 1008 *this = tmp; |
1009 } | 1009 } |
1010 else | 1010 else |
1011 gripe_invalid_resize (); | 1011 gripe_invalid_resize (); |
1012 } | 1012 } |
1013 } | 1013 } |
1014 | 1014 |
1015 template <class T> | 1015 template <class T> |
1016 Array<T> | 1016 Array<T> |
1017 Array<T>::index (const idx_vector& i, bool resize_ok, const T& rfv) const | 1017 Array<T>::index (const idx_vector& i, bool resize_ok, const T& rfv) const |
1018 { | 1018 { |
1019 Array<T> tmp = *this; | 1019 Array<T> tmp = *this; |
1020 if (resize_ok) | 1020 if (resize_ok) |
1021 { | 1021 { |
1034 | 1034 |
1035 return tmp.index (i); | 1035 return tmp.index (i); |
1036 } | 1036 } |
1037 | 1037 |
1038 template <class T> | 1038 template <class T> |
1039 Array<T> | 1039 Array<T> |
1040 Array<T>::index (const idx_vector& i, const idx_vector& j, | 1040 Array<T>::index (const idx_vector& i, const idx_vector& j, |
1041 bool resize_ok, const T& rfv) const | 1041 bool resize_ok, const T& rfv) const |
1042 { | 1042 { |
1043 Array<T> tmp = *this; | 1043 Array<T> tmp = *this; |
1044 if (resize_ok) | 1044 if (resize_ok) |
1045 { | 1045 { |
1056 | 1056 |
1057 if (tmp.rows () != rx || tmp.columns () != cx) | 1057 if (tmp.rows () != rx || tmp.columns () != cx) |
1058 return Array<T> (); | 1058 return Array<T> (); |
1059 } | 1059 } |
1060 | 1060 |
1061 return tmp.index (i, j); | 1061 return tmp.index (i, j); |
1062 } | 1062 } |
1063 | 1063 |
1064 template <class T> | 1064 template <class T> |
1065 Array<T> | 1065 Array<T> |
1066 Array<T>::index (const Array<idx_vector>& ia, | 1066 Array<T>::index (const Array<idx_vector>& ia, |
1067 bool resize_ok, const T& rfv) const | 1067 bool resize_ok, const T& rfv) const |
1068 { | 1068 { |
1069 Array<T> tmp = *this; | 1069 Array<T> tmp = *this; |
1070 if (resize_ok) | 1070 if (resize_ok) |
1074 dim_vector dvx = dim_vector::alloc (ial); | 1074 dim_vector dvx = dim_vector::alloc (ial); |
1075 for (int i = 0; i < ial; i++) dvx(i) = ia(i).extent (dv (i)); | 1075 for (int i = 0; i < ial; i++) dvx(i) = ia(i).extent (dv (i)); |
1076 if (! (dvx == dv)) | 1076 if (! (dvx == dv)) |
1077 { | 1077 { |
1078 bool all_scalars = true; | 1078 bool all_scalars = true; |
1079 for (int i = 0; i < ial; i++) | 1079 for (int i = 0; i < ial; i++) |
1080 all_scalars = all_scalars && ia(i).is_scalar (); | 1080 all_scalars = all_scalars && ia(i).is_scalar (); |
1081 if (all_scalars) | 1081 if (all_scalars) |
1082 return Array<T> (dim_vector (1, 1), rfv); | 1082 return Array<T> (dim_vector (1, 1), rfv); |
1083 else | 1083 else |
1084 tmp.resize (dvx, rfv); | 1084 tmp.resize (dvx, rfv); |
1086 | 1086 |
1087 if (tmp.dimensions != dvx) | 1087 if (tmp.dimensions != dvx) |
1088 return Array<T> (); | 1088 return Array<T> (); |
1089 } | 1089 } |
1090 | 1090 |
1091 return tmp.index (ia); | 1091 return tmp.index (ia); |
1092 } | 1092 } |
1093 | 1093 |
1094 | 1094 |
1095 template <class T> | 1095 template <class T> |
1096 void | 1096 void |
1100 | 1100 |
1101 if (rhl == 1 || i.length (n) == rhl) | 1101 if (rhl == 1 || i.length (n) == rhl) |
1102 { | 1102 { |
1103 octave_idx_type nx = i.extent (n); | 1103 octave_idx_type nx = i.extent (n); |
1104 bool colon = i.is_colon_equiv (nx); | 1104 bool colon = i.is_colon_equiv (nx); |
1105 // Try to resize first if necessary. | 1105 // Try to resize first if necessary. |
1106 if (nx != n) | 1106 if (nx != n) |
1107 { | 1107 { |
1108 // Optimize case A = []; A(1:n) = X with A empty. | 1108 // Optimize case A = []; A(1:n) = X with A empty. |
1109 if (dimensions.zero_by_zero () && colon) | 1109 if (dimensions.zero_by_zero () && colon) |
1110 { | 1110 { |
1111 if (rhl == 1) | 1111 if (rhl == 1) |
1112 *this = Array<T> (dim_vector (1, nx), rhs(0)); | 1112 *this = Array<T> (dim_vector (1, nx), rhs(0)); |
1113 else | 1113 else |
1114 *this = Array<T> (rhs, dim_vector (1, nx)); | 1114 *this = Array<T> (rhs, dim_vector (1, nx)); |
1115 return; | 1115 return; |
1116 } | 1116 } |
1117 | 1117 |
1118 resize1 (nx, rfv); | 1118 resize1 (nx, rfv); |
1119 n = numel (); | 1119 n = numel (); |
1120 } | 1120 } |
1121 | 1121 |
1122 if (colon) | 1122 if (colon) |
1123 { | 1123 { |
1143 void | 1143 void |
1144 Array<T>::assign (const idx_vector& i, const idx_vector& j, | 1144 Array<T>::assign (const idx_vector& i, const idx_vector& j, |
1145 const Array<T>& rhs, const T& rfv) | 1145 const Array<T>& rhs, const T& rfv) |
1146 { | 1146 { |
1147 // Get RHS extents, discarding singletons. | 1147 // Get RHS extents, discarding singletons. |
1148 dim_vector rhdv = rhs.dims (); | 1148 dim_vector rhdv = rhs.dims (); |
1149 // Get LHS extents, allowing Fortran indexing in the second dim. | 1149 // Get LHS extents, allowing Fortran indexing in the second dim. |
1150 dim_vector dv = dimensions.redim (2); | 1150 dim_vector dv = dimensions.redim (2); |
1151 // Check for out-of-bounds and form resizing dimensions. | 1151 // Check for out-of-bounds and form resizing dimensions. |
1152 dim_vector rdv; | 1152 dim_vector rdv; |
1153 // In the special when all dimensions are zero, colons are allowed | 1153 // In the special when all dimensions are zero, colons are allowed |
1154 // to inquire the shape of RHS. The rules are more obscure, so we | 1154 // to inquire the shape of RHS. The rules are more obscure, so we |
1155 // solve that elsewhere. | 1155 // solve that elsewhere. |
1156 if (dv.all_zero ()) | 1156 if (dv.all_zero ()) |
1157 rdv = zero_dims_inquire (i, j, rhdv); | 1157 rdv = zero_dims_inquire (i, j, rhdv); |
1168 || (rhdv.length () == 2 && il == rhdv(0) && jl == rhdv(1))); | 1168 || (rhdv.length () == 2 && il == rhdv(0) && jl == rhdv(1))); |
1169 match = match || (il == 1 && jl == rhdv(0) && rhdv(1) == 1); | 1169 match = match || (il == 1 && jl == rhdv(0) && rhdv(1) == 1); |
1170 | 1170 |
1171 if (match) | 1171 if (match) |
1172 { | 1172 { |
1173 bool all_colons = (i.is_colon_equiv (rdv(0)) | 1173 bool all_colons = (i.is_colon_equiv (rdv(0)) |
1174 && j.is_colon_equiv (rdv(1))); | 1174 && j.is_colon_equiv (rdv(1))); |
1175 // Resize if requested. | 1175 // Resize if requested. |
1176 if (rdv != dv) | 1176 if (rdv != dv) |
1177 { | 1177 { |
1178 // Optimize case A = []; A(1:m, 1:n) = X | 1178 // Optimize case A = []; A(1:m, 1:n) = X |
1250 // Get RHS extents, discarding singletons. | 1250 // Get RHS extents, discarding singletons. |
1251 dim_vector rhdv = rhs.dims (); | 1251 dim_vector rhdv = rhs.dims (); |
1252 | 1252 |
1253 // Get LHS extents, allowing Fortran indexing in the second dim. | 1253 // Get LHS extents, allowing Fortran indexing in the second dim. |
1254 dim_vector dv = dimensions.redim (ial); | 1254 dim_vector dv = dimensions.redim (ial); |
1255 | 1255 |
1256 // Get the extents forced by indexing. | 1256 // Get the extents forced by indexing. |
1257 dim_vector rdv; | 1257 dim_vector rdv; |
1258 | 1258 |
1259 // In the special when all dimensions are zero, colons are | 1259 // In the special when all dimensions are zero, colons are |
1260 // allowed to inquire the shape of RHS. The rules are more | 1260 // allowed to inquire the shape of RHS. The rules are more |
1261 // obscure, so we solve that elsewhere. | 1261 // obscure, so we solve that elsewhere. |
1281 match = match && j < rhdvl && l == rhdv(j++); | 1281 match = match && j < rhdvl && l == rhdv(j++); |
1282 } | 1282 } |
1283 | 1283 |
1284 match = match && (j == rhdvl || rhdv(j) == 1); | 1284 match = match && (j == rhdvl || rhdv(j) == 1); |
1285 match = match || isfill; | 1285 match = match || isfill; |
1286 | 1286 |
1287 if (match) | 1287 if (match) |
1288 { | 1288 { |
1289 // Resize first if necessary. | 1289 // Resize first if necessary. |
1290 if (rdv != dv) | 1290 if (rdv != dv) |
1291 { | 1291 { |
1324 rh.fill (rhs(0), fortran_vec ()); | 1324 rh.fill (rhs(0), fortran_vec ()); |
1325 else | 1325 else |
1326 rh.assign (rhs.data (), fortran_vec ()); | 1326 rh.assign (rhs.data (), fortran_vec ()); |
1327 } | 1327 } |
1328 } | 1328 } |
1329 else | 1329 else |
1330 gripe_assignment_dimension_mismatch (); | 1330 gripe_assignment_dimension_mismatch (); |
1331 } | 1331 } |
1332 } | 1332 } |
1333 | 1333 |
1334 template <class T> | 1334 template <class T> |
1335 void | 1335 void |
1336 Array<T>::delete_elements (const idx_vector& i) | 1336 Array<T>::delete_elements (const idx_vector& i) |
1337 { | 1337 { |
1338 octave_idx_type n = numel (); | 1338 octave_idx_type n = numel (); |
1339 if (i.is_colon ()) | 1339 if (i.is_colon ()) |
1340 { | 1340 { |
1341 *this = Array<T> (); | 1341 *this = Array<T> (); |
1342 } | 1342 } |
1343 else if (i.length (n) != 0) | 1343 else if (i.length (n) != 0) |
1344 { | 1344 { |
1345 if (i.extent (n) != n) | 1345 if (i.extent (n) != n) |
1370 } | 1370 } |
1371 } | 1371 } |
1372 } | 1372 } |
1373 | 1373 |
1374 template <class T> | 1374 template <class T> |
1375 void | 1375 void |
1376 Array<T>::delete_elements (int dim, const idx_vector& i) | 1376 Array<T>::delete_elements (int dim, const idx_vector& i) |
1377 { | 1377 { |
1378 if (dim < 0 || dim >= ndims ()) | 1378 if (dim < 0 || dim >= ndims ()) |
1379 { | 1379 { |
1380 (*current_liboctave_error_handler) | 1380 (*current_liboctave_error_handler) |
1382 return; | 1382 return; |
1383 } | 1383 } |
1384 | 1384 |
1385 octave_idx_type n = dimensions (dim); | 1385 octave_idx_type n = dimensions (dim); |
1386 if (i.is_colon ()) | 1386 if (i.is_colon ()) |
1387 { | 1387 { |
1388 *this = Array<T> (); | 1388 *this = Array<T> (); |
1389 } | 1389 } |
1390 else if (i.length (n) != 0) | 1390 else if (i.length (n) != 0) |
1391 { | 1391 { |
1392 if (i.extent (n) != n) | 1392 if (i.extent (n) != n) |
1428 } | 1428 } |
1429 } | 1429 } |
1430 } | 1430 } |
1431 | 1431 |
1432 template <class T> | 1432 template <class T> |
1433 void | 1433 void |
1434 Array<T>::delete_elements (const Array<idx_vector>& ia) | 1434 Array<T>::delete_elements (const Array<idx_vector>& ia) |
1435 { | 1435 { |
1436 if (ia.length () == 1) | 1436 if (ia.length () == 1) |
1437 delete_elements (ia(0)); | 1437 delete_elements (ia(0)); |
1438 else | 1438 else |
1573 for (jj = 0; jj < (nc - 8 + 1); jj += 8) | 1573 for (jj = 0; jj < (nc - 8 + 1); jj += 8) |
1574 { | 1574 { |
1575 for (ii = 0; ii < (nr - 8 + 1); ii += 8) | 1575 for (ii = 0; ii < (nr - 8 + 1); ii += 8) |
1576 { | 1576 { |
1577 // Copy to buffer | 1577 // Copy to buffer |
1578 for (octave_idx_type j = jj, k = 0, idxj = jj * nr; | 1578 for (octave_idx_type j = jj, k = 0, idxj = jj * nr; |
1579 j < jj + 8; j++, idxj += nr) | 1579 j < jj + 8; j++, idxj += nr) |
1580 for (octave_idx_type i = ii; i < ii + 8; i++) | 1580 for (octave_idx_type i = ii; i < ii + 8; i++) |
1581 buf[k++] = xelem (i + idxj); | 1581 buf[k++] = xelem (i + idxj); |
1582 | 1582 |
1583 // Copy from buffer | 1583 // Copy from buffer |
1584 for (octave_idx_type i = ii, idxi = ii * nc; i < ii + 8; | 1584 for (octave_idx_type i = ii, idxi = ii * nc; i < ii + 8; |
1585 i++, idxi += nc) | 1585 i++, idxi += nc) |
1586 for (octave_idx_type j = jj, k = i - ii; j < jj + 8; | 1586 for (octave_idx_type j = jj, k = i - ii; j < jj + 8; |
1587 j++, k+=8) | 1587 j++, k+=8) |
1588 result.xelem (j + idxi) = fcn (buf[k]); | 1588 result.xelem (j + idxi) = fcn (buf[k]); |
1589 } | 1589 } |
1590 | 1590 |
1591 if (ii < nr) | 1591 if (ii < nr) |
1592 for (octave_idx_type j = jj; j < jj + 8; j++) | 1592 for (octave_idx_type j = jj; j < jj + 8; j++) |
1593 for (octave_idx_type i = ii; i < nr; i++) | 1593 for (octave_idx_type i = ii; i < nr; i++) |
1594 result.xelem (j, i) = fcn (xelem (i, j)); | 1594 result.xelem (j, i) = fcn (xelem (i, j)); |
1595 } | 1595 } |
1596 | 1596 |
1597 for (octave_idx_type j = jj; j < nc; j++) | 1597 for (octave_idx_type j = jj; j < nc; j++) |
1598 for (octave_idx_type i = 0; i < nr; i++) | 1598 for (octave_idx_type i = 0; i < nr; i++) |
1599 result.xelem (j, i) = fcn (xelem (i, j)); | 1599 result.xelem (j, i) = fcn (xelem (i, j)); |
1600 | 1600 |
1693 | 1693 |
1694 T *v = m.fortran_vec (); | 1694 T *v = m.fortran_vec (); |
1695 const T *ov = data (); | 1695 const T *ov = data (); |
1696 | 1696 |
1697 octave_sort<T> lsort; | 1697 octave_sort<T> lsort; |
1698 | 1698 |
1699 if (mode != UNSORTED) | 1699 if (mode != UNSORTED) |
1700 lsort.set_compare (mode); | 1700 lsort.set_compare (mode); |
1701 else | 1701 else |
1702 return m; | 1702 return m; |
1703 | 1703 |
1704 if (stride == 1) | 1704 if (stride == 1) |
1705 { | 1705 { |
1706 for (octave_idx_type j = 0; j < iter; j++) | 1706 for (octave_idx_type j = 0; j < iter; j++) |
1707 { | 1707 { |
1708 // copy and partition out NaNs. | 1708 // copy and partition out NaNs. |
1709 // FIXME: impact on integer types noticeable? | 1709 // FIXME: impact on integer types noticeable? |
1710 octave_idx_type kl = 0, ku = ns; | 1710 octave_idx_type kl = 0, ku = ns; |
1711 for (octave_idx_type i = 0; i < ns; i++) | 1711 for (octave_idx_type i = 0; i < ns; i++) |
1712 { | 1712 { |
1713 T tmp = ov[i]; | 1713 T tmp = ov[i]; |
1734 } | 1734 } |
1735 else | 1735 else |
1736 { | 1736 { |
1737 OCTAVE_LOCAL_BUFFER (T, buf, ns); | 1737 OCTAVE_LOCAL_BUFFER (T, buf, ns); |
1738 | 1738 |
1739 for (octave_idx_type j = 0; j < iter; j++) | 1739 for (octave_idx_type j = 0; j < iter; j++) |
1740 { | 1740 { |
1741 octave_idx_type offset = j; | 1741 octave_idx_type offset = j; |
1742 octave_idx_type offset2 = 0; | 1742 octave_idx_type offset2 = 0; |
1743 | 1743 |
1744 while (offset >= stride) | 1744 while (offset >= stride) |
1746 offset -= stride; | 1746 offset -= stride; |
1747 offset2++; | 1747 offset2++; |
1748 } | 1748 } |
1749 | 1749 |
1750 offset += offset2 * stride * ns; | 1750 offset += offset2 * stride * ns; |
1751 | 1751 |
1752 // gather and partition out NaNs. | 1752 // gather and partition out NaNs. |
1753 // FIXME: impact on integer types noticeable? | 1753 // FIXME: impact on integer types noticeable? |
1754 octave_idx_type kl = 0, ku = ns; | 1754 octave_idx_type kl = 0, ku = ns; |
1755 for (octave_idx_type i = 0; i < ns; i++) | 1755 for (octave_idx_type i = 0; i < ns; i++) |
1756 { | 1756 { |
1757 T tmp = ov[i*stride + offset]; | 1757 T tmp = ov[i*stride + offset]; |
1781 return m; | 1781 return m; |
1782 } | 1782 } |
1783 | 1783 |
1784 template <class T> | 1784 template <class T> |
1785 Array<T> | 1785 Array<T> |
1786 Array<T>::sort (Array<octave_idx_type> &sidx, int dim, | 1786 Array<T>::sort (Array<octave_idx_type> &sidx, int dim, |
1787 sortmode mode) const | 1787 sortmode mode) const |
1788 { | 1788 { |
1789 if (dim < 0 || dim >= ndims ()) | 1789 if (dim < 0 || dim >= ndims ()) |
1790 { | 1790 { |
1791 (*current_liboctave_error_handler) | 1791 (*current_liboctave_error_handler) |
1815 | 1815 |
1816 octave_sort<T> lsort; | 1816 octave_sort<T> lsort; |
1817 | 1817 |
1818 sidx = Array<octave_idx_type> (dv); | 1818 sidx = Array<octave_idx_type> (dv); |
1819 octave_idx_type *vi = sidx.fortran_vec (); | 1819 octave_idx_type *vi = sidx.fortran_vec (); |
1820 | 1820 |
1821 if (mode != UNSORTED) | 1821 if (mode != UNSORTED) |
1822 lsort.set_compare (mode); | 1822 lsort.set_compare (mode); |
1823 else | 1823 else |
1824 return m; | 1824 return m; |
1825 | 1825 |
1826 if (stride == 1) | 1826 if (stride == 1) |
1827 { | 1827 { |
1828 for (octave_idx_type j = 0; j < iter; j++) | 1828 for (octave_idx_type j = 0; j < iter; j++) |
1829 { | 1829 { |
1830 // copy and partition out NaNs. | 1830 // copy and partition out NaNs. |
1831 // FIXME: impact on integer types noticeable? | 1831 // FIXME: impact on integer types noticeable? |
1832 octave_idx_type kl = 0, ku = ns; | 1832 octave_idx_type kl = 0, ku = ns; |
1833 for (octave_idx_type i = 0; i < ns; i++) | 1833 for (octave_idx_type i = 0; i < ns; i++) |
1834 { | 1834 { |
1835 T tmp = ov[i]; | 1835 T tmp = ov[i]; |
1870 else | 1870 else |
1871 { | 1871 { |
1872 OCTAVE_LOCAL_BUFFER (T, buf, ns); | 1872 OCTAVE_LOCAL_BUFFER (T, buf, ns); |
1873 OCTAVE_LOCAL_BUFFER (octave_idx_type, bufi, ns); | 1873 OCTAVE_LOCAL_BUFFER (octave_idx_type, bufi, ns); |
1874 | 1874 |
1875 for (octave_idx_type j = 0; j < iter; j++) | 1875 for (octave_idx_type j = 0; j < iter; j++) |
1876 { | 1876 { |
1877 octave_idx_type offset = j; | 1877 octave_idx_type offset = j; |
1878 octave_idx_type offset2 = 0; | 1878 octave_idx_type offset2 = 0; |
1879 | 1879 |
1880 while (offset >= stride) | 1880 while (offset >= stride) |
1882 offset -= stride; | 1882 offset -= stride; |
1883 offset2++; | 1883 offset2++; |
1884 } | 1884 } |
1885 | 1885 |
1886 offset += offset2 * stride * ns; | 1886 offset += offset2 * stride * ns; |
1887 | 1887 |
1888 // gather and partition out NaNs. | 1888 // gather and partition out NaNs. |
1889 // FIXME: impact on integer types noticeable? | 1889 // FIXME: impact on integer types noticeable? |
1890 octave_idx_type kl = 0, ku = ns; | 1890 octave_idx_type kl = 0, ku = ns; |
1891 for (octave_idx_type i = 0; i < ns; i++) | 1891 for (octave_idx_type i = 0; i < ns; i++) |
1892 { | 1892 { |
1893 T tmp = ov[i*stride + offset]; | 1893 T tmp = ov[i*stride + offset]; |
1996 return idx; | 1996 return idx; |
1997 } | 1997 } |
1998 | 1998 |
1999 | 1999 |
2000 template <class T> | 2000 template <class T> |
2001 sortmode | 2001 sortmode |
2002 Array<T>::is_sorted_rows (sortmode mode) const | 2002 Array<T>::is_sorted_rows (sortmode mode) const |
2003 { | 2003 { |
2004 octave_sort<T> lsort; | 2004 octave_sort<T> lsort; |
2005 | 2005 |
2006 octave_idx_type r = rows (), c = cols (); | 2006 octave_idx_type r = rows (), c = cols (); |
2055 | 2055 |
2056 } | 2056 } |
2057 | 2057 |
2058 // Do a binary lookup in a sorted array. | 2058 // Do a binary lookup in a sorted array. |
2059 template <class T> | 2059 template <class T> |
2060 octave_idx_type | 2060 octave_idx_type |
2061 Array<T>::lookup (const T& value, sortmode mode) const | 2061 Array<T>::lookup (const T& value, sortmode mode) const |
2062 { | 2062 { |
2063 octave_idx_type n = numel (); | 2063 octave_idx_type n = numel (); |
2064 octave_sort<T> lsort; | 2064 octave_sort<T> lsort; |
2065 | 2065 |
2076 | 2076 |
2077 return lsort.lookup (data (), n, value); | 2077 return lsort.lookup (data (), n, value); |
2078 } | 2078 } |
2079 | 2079 |
2080 template <class T> | 2080 template <class T> |
2081 Array<octave_idx_type> | 2081 Array<octave_idx_type> |
2082 Array<T>::lookup (const Array<T>& values, sortmode mode) const | 2082 Array<T>::lookup (const Array<T>& values, sortmode mode) const |
2083 { | 2083 { |
2084 octave_idx_type n = numel (), nval = values.numel (); | 2084 octave_idx_type n = numel (), nval = values.numel (); |
2085 octave_sort<T> lsort; | 2085 octave_sort<T> lsort; |
2086 Array<octave_idx_type> idx (values.dims ()); | 2086 Array<octave_idx_type> idx (values.dims ()); |
2118 | 2118 |
2119 return idx; | 2119 return idx; |
2120 } | 2120 } |
2121 | 2121 |
2122 template <class T> | 2122 template <class T> |
2123 octave_idx_type | 2123 octave_idx_type |
2124 Array<T>::nnz (void) const | 2124 Array<T>::nnz (void) const |
2125 { | 2125 { |
2126 const T *src = data (); | 2126 const T *src = data (); |
2127 octave_idx_type nel = nelem (), retval = 0; | 2127 octave_idx_type nel = nelem (), retval = 0; |
2128 const T zero = T (); | 2128 const T zero = T (); |
2132 | 2132 |
2133 return retval; | 2133 return retval; |
2134 } | 2134 } |
2135 | 2135 |
2136 template <class T> | 2136 template <class T> |
2137 Array<octave_idx_type> | 2137 Array<octave_idx_type> |
2138 Array<T>::find (octave_idx_type n, bool backward) const | 2138 Array<T>::find (octave_idx_type n, bool backward) const |
2139 { | 2139 { |
2140 Array<octave_idx_type> retval; | 2140 Array<octave_idx_type> retval; |
2141 const T *src = data (); | 2141 const T *src = data (); |
2142 octave_idx_type nel = nelem (); | 2142 octave_idx_type nel = nelem (); |
2300 { | 2300 { |
2301 octave_idx_type kl = 0, ku = ns; | 2301 octave_idx_type kl = 0, ku = ns; |
2302 | 2302 |
2303 if (stride == 1) | 2303 if (stride == 1) |
2304 { | 2304 { |
2305 // copy without NaNs. | 2305 // copy without NaNs. |
2306 // FIXME: impact on integer types noticeable? | 2306 // FIXME: impact on integer types noticeable? |
2307 for (octave_idx_type i = 0; i < ns; i++) | 2307 for (octave_idx_type i = 0; i < ns; i++) |
2308 { | 2308 { |
2309 T tmp = ov[i]; | 2309 T tmp = ov[i]; |
2310 if (sort_isnan<T> (tmp)) | 2310 if (sort_isnan<T> (tmp)) |
2316 ov += ns; | 2316 ov += ns; |
2317 } | 2317 } |
2318 else | 2318 else |
2319 { | 2319 { |
2320 octave_idx_type offset = j % stride; | 2320 octave_idx_type offset = j % stride; |
2321 // copy without NaNs. | 2321 // copy without NaNs. |
2322 // FIXME: impact on integer types noticeable? | 2322 // FIXME: impact on integer types noticeable? |
2323 for (octave_idx_type i = 0; i < ns; i++) | 2323 for (octave_idx_type i = 0; i < ns; i++) |
2324 { | 2324 { |
2325 T tmp = ov[offset + i*stride]; | 2325 T tmp = ov[offset + i*stride]; |
2326 if (sort_isnan<T> (tmp)) | 2326 if (sort_isnan<T> (tmp)) |
2419 dim_vector dv = dims (); | 2419 dim_vector dv = dims (); |
2420 octave_idx_type nd = dv.length (); | 2420 octave_idx_type nd = dv.length (); |
2421 Array<T> d; | 2421 Array<T> d; |
2422 | 2422 |
2423 if (nd > 2) | 2423 if (nd > 2) |
2424 (*current_liboctave_error_handler) ("Matrix must be 2-dimensional"); | 2424 (*current_liboctave_error_handler) ("Matrix must be 2-dimensional"); |
2425 else | 2425 else |
2426 { | 2426 { |
2427 octave_idx_type nnr = dv (0); | 2427 octave_idx_type nnr = dv (0); |
2428 octave_idx_type nnc = dv (1); | 2428 octave_idx_type nnc = dv (1); |
2429 | 2429 |
2626 bool Array<T>::optimize_dimensions (const dim_vector& dv) | 2626 bool Array<T>::optimize_dimensions (const dim_vector& dv) |
2627 { | 2627 { |
2628 bool retval = dimensions == dv; | 2628 bool retval = dimensions == dv; |
2629 if (retval) | 2629 if (retval) |
2630 dimensions = dv; | 2630 dimensions = dv; |
2631 | 2631 |
2632 return retval; | 2632 return retval; |
2633 } | 2633 } |
2634 | 2634 |
2635 template <class T> | 2635 template <class T> |
2636 void Array<T>::instantiation_guard () | 2636 void Array<T>::instantiation_guard () |