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 ()