Mercurial > octave
comparison liboctave/Array.cc @ 10350:12884915a8e4
merge MArray classes & improve Array interface
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Sat, 23 Jan 2010 21:41:03 +0100 |
parents | 07ebe522dac2 |
children | a3635bc1ea19 |
comparison
equal
deleted
inserted
replaced
10349:d4d13389c957 | 10350:12884915a8e4 |
---|---|
874 } | 874 } |
875 | 875 |
876 // The default fill value. Override if you want a different one. | 876 // The default fill value. Override if you want a different one. |
877 | 877 |
878 template <class T> | 878 template <class T> |
879 T Array<T>::resize_fill_value () | 879 const T& Array<T>::resize_fill_value () |
880 { | 880 { |
881 return T (); | 881 static T zero = T (); |
882 return zero; | |
882 } | 883 } |
883 | 884 |
884 // Yes, we could do resize using index & assign. However, that would | 885 // Yes, we could do resize using index & assign. However, that would |
885 // possibly involve a lot more memory traffic than we actually need. | 886 // possibly involve a lot more memory traffic than we actually need. |
886 | 887 |
887 template <class T> | 888 template <class T> |
888 void | 889 void |
889 Array<T>::resize_fill (octave_idx_type n, const T& rfv) | 890 Array<T>::resize1 (octave_idx_type n, const T& rfv) |
890 { | 891 { |
891 if (n >= 0 && ndims () == 2) | 892 if (n >= 0 && ndims () == 2) |
892 { | 893 { |
893 dim_vector dv; | 894 dim_vector dv; |
894 // This is driven by Matlab's behaviour of giving a *row* vector | 895 // This is driven by Matlab's behaviour of giving a *row* vector |
929 } | 930 } |
930 else | 931 else |
931 { | 932 { |
932 static const octave_idx_type max_stack_chunk = 1024; | 933 static const octave_idx_type max_stack_chunk = 1024; |
933 octave_idx_type nn = n + std::min (nx, max_stack_chunk); | 934 octave_idx_type nn = n + std::min (nx, max_stack_chunk); |
934 Array<T> tmp (Array<T> (nn), dv, 0, n); | 935 Array<T> tmp (Array<T> (nn, 1), dv, 0, n); |
935 T *dest = tmp.fortran_vec (); | 936 T *dest = tmp.fortran_vec (); |
936 | 937 |
937 copy_or_memcpy (nx, data (), dest); | 938 copy_or_memcpy (nx, data (), dest); |
938 dest[nx] = rfv; | 939 dest[nx] = rfv; |
939 | 940 |
957 gripe_invalid_resize (); | 958 gripe_invalid_resize (); |
958 } | 959 } |
959 | 960 |
960 template <class T> | 961 template <class T> |
961 void | 962 void |
962 Array<T>::resize_fill (octave_idx_type r, octave_idx_type c, const T& rfv) | 963 Array<T>::resize (octave_idx_type r, octave_idx_type c, const T& rfv) |
963 { | 964 { |
964 if (r >= 0 && c >= 0 && ndims () == 2) | 965 if (r >= 0 && c >= 0 && ndims () == 2) |
965 { | 966 { |
966 octave_idx_type rx = rows (), cx = columns (); | 967 octave_idx_type rx = rows (), cx = columns (); |
967 if (r != rx || c != cx) | 968 if (r != rx || c != cx) |
999 | 1000 |
1000 } | 1001 } |
1001 | 1002 |
1002 template<class T> | 1003 template<class T> |
1003 void | 1004 void |
1004 Array<T>::resize_fill (const dim_vector& dv, const T& rfv) | 1005 Array<T>::resize (const dim_vector& dv, const T& rfv) |
1005 { | 1006 { |
1006 int dvl = dv.length (); | 1007 int dvl = dv.length (); |
1007 if (dvl == 2) | 1008 if (dvl == 2) |
1008 resize (dv(0), dv(1), rfv); | 1009 resize (dv(0), dv(1), rfv); |
1009 else if (dimensions != dv) | 1010 else if (dimensions != dv) |
1032 { | 1033 { |
1033 octave_idx_type n = numel (), nx = i.extent (n); | 1034 octave_idx_type n = numel (), nx = i.extent (n); |
1034 if (n != nx) | 1035 if (n != nx) |
1035 { | 1036 { |
1036 if (i.is_scalar ()) | 1037 if (i.is_scalar ()) |
1037 return Array<T> (1, rfv); | 1038 return Array<T> (1, 1, rfv); |
1038 else | 1039 else |
1039 tmp.resize_fill (nx, rfv); | 1040 tmp.resize1 (nx, rfv); |
1040 } | 1041 } |
1041 | 1042 |
1042 if (tmp.numel () != nx) | 1043 if (tmp.numel () != nx) |
1043 return Array<T> (); | 1044 return Array<T> (); |
1044 } | 1045 } |
1058 octave_idx_type r = dv(0), c = dv(1); | 1059 octave_idx_type r = dv(0), c = dv(1); |
1059 octave_idx_type rx = i.extent (r), cx = j.extent (c); | 1060 octave_idx_type rx = i.extent (r), cx = j.extent (c); |
1060 if (r != rx || c != cx) | 1061 if (r != rx || c != cx) |
1061 { | 1062 { |
1062 if (i.is_scalar () && j.is_scalar ()) | 1063 if (i.is_scalar () && j.is_scalar ()) |
1063 return Array<T> (1, rfv); | 1064 return Array<T> (1, 1, rfv); |
1064 else | 1065 else |
1065 tmp.resize_fill (rx, cx, rfv); | 1066 tmp.resize (rx, cx, rfv); |
1066 } | 1067 } |
1067 | 1068 |
1068 if (tmp.rows () != rx || tmp.columns () != cx) | 1069 if (tmp.rows () != rx || tmp.columns () != cx) |
1069 return Array<T> (); | 1070 return Array<T> (); |
1070 } | 1071 } |
1088 { | 1089 { |
1089 bool all_scalars = true; | 1090 bool all_scalars = true; |
1090 for (int i = 0; i < ial; i++) | 1091 for (int i = 0; i < ial; i++) |
1091 all_scalars = all_scalars && ia(i).is_scalar (); | 1092 all_scalars = all_scalars && ia(i).is_scalar (); |
1092 if (all_scalars) | 1093 if (all_scalars) |
1093 return Array<T> (1, rfv); | 1094 return Array<T> (1, 1, rfv); |
1094 else | 1095 else |
1095 tmp.resize_fill (dvx, rfv); | 1096 tmp.resize (dvx, rfv); |
1096 } | 1097 } |
1097 | 1098 |
1098 if (tmp.dimensions != dvx) | 1099 if (tmp.dimensions != dvx) |
1099 return Array<T> (); | 1100 return Array<T> (); |
1100 } | 1101 } |
1138 else | 1139 else |
1139 *this = Array<T> (rhs, dim_vector (1, nx)); | 1140 *this = Array<T> (rhs, dim_vector (1, nx)); |
1140 return; | 1141 return; |
1141 } | 1142 } |
1142 | 1143 |
1143 resize_fill (nx, rfv); | 1144 resize1 (nx, rfv); |
1144 n = numel (); | 1145 n = numel (); |
1145 } | 1146 } |
1146 | 1147 |
1147 if (colon) | 1148 if (colon) |
1148 { | 1149 { |
1323 else | 1324 else |
1324 *this = Array<T> (rhs, rdv); | 1325 *this = Array<T> (rhs, rdv); |
1325 return; | 1326 return; |
1326 } | 1327 } |
1327 | 1328 |
1328 resize_fill (rdv, rfv); | 1329 resize (rdv, rfv); |
1329 dv = rdv; | 1330 dv = rdv; |
1330 } | 1331 } |
1331 | 1332 |
1332 if (all_colons) | 1333 if (all_colons) |
1333 { | 1334 { |
1374 octave_idx_type l, u; | 1375 octave_idx_type l, u; |
1375 bool col_vec = ndims () == 2 && columns () == 1 && rows () != 1; | 1376 bool col_vec = ndims () == 2 && columns () == 1 && rows () != 1; |
1376 if (i.is_scalar () && i(0) == n-1) | 1377 if (i.is_scalar () && i(0) == n-1) |
1377 { | 1378 { |
1378 // Stack "pop" operation. | 1379 // Stack "pop" operation. |
1379 resize (n-1); | 1380 resize1 (n-1); |
1380 } | 1381 } |
1381 else if (i.is_cont_range (n, l, u)) | 1382 else if (i.is_cont_range (n, l, u)) |
1382 { | 1383 { |
1383 // Special case deleting a contiguous range. | 1384 // Special case deleting a contiguous range. |
1384 octave_idx_type m = n + l - u; | 1385 octave_idx_type m = n + l - u; |
1447 *this = tmp; | 1448 *this = tmp; |
1448 } | 1449 } |
1449 else | 1450 else |
1450 { | 1451 { |
1451 // Use index. | 1452 // Use index. |
1452 Array<idx_vector> ia (ndims (), idx_vector::colon); | 1453 Array<idx_vector> ia (ndims (), 1, idx_vector::colon); |
1453 ia (dim) = i.complement (n); | 1454 ia (dim) = i.complement (n); |
1454 *this = index (ia); | 1455 *this = index (ia); |
1455 } | 1456 } |
1456 } | 1457 } |
1457 } | 1458 } |
1502 idx_vector j (c, c + a.columns ()); | 1503 idx_vector j (c, c + a.columns ()); |
1503 if (ndims () == 2 && a.ndims () == 2) | 1504 if (ndims () == 2 && a.ndims () == 2) |
1504 assign (i, j, a); | 1505 assign (i, j, a); |
1505 else | 1506 else |
1506 { | 1507 { |
1507 Array<idx_vector> idx (a.ndims ()); | 1508 Array<idx_vector> idx (a.ndims (), 1); |
1508 idx(0) = i; | 1509 idx(0) = i; |
1509 idx(1) = j; | 1510 idx(1) = j; |
1510 for (int k = 0; k < a.ndims (); k++) | 1511 for (int k = 0; k < a.ndims (); k++) |
1511 idx(k) = idx_vector (0, a.dimensions(k)); | 1512 idx(k) = idx_vector (0, a.dimensions(k)); |
1512 assign (idx, a); | 1513 assign (idx, a); |
1518 template <class T> | 1519 template <class T> |
1519 Array<T>& | 1520 Array<T>& |
1520 Array<T>::insert (const Array<T>& a, const Array<octave_idx_type>& ra_idx) | 1521 Array<T>::insert (const Array<T>& a, const Array<octave_idx_type>& ra_idx) |
1521 { | 1522 { |
1522 octave_idx_type n = ra_idx.length (); | 1523 octave_idx_type n = ra_idx.length (); |
1523 Array<idx_vector> idx (n); | 1524 Array<idx_vector> idx (n, 1); |
1524 const dim_vector dva = a.dims ().redim (n); | 1525 const dim_vector dva = a.dims ().redim (n); |
1525 for (octave_idx_type k = 0; k < n; k++) | 1526 for (octave_idx_type k = 0; k < n; k++) |
1526 idx(k) = idx_vector (ra_idx (k), ra_idx (k) + dva(k)); | 1527 idx(k) = idx_vector (ra_idx (k), ra_idx (k) + dva(k)); |
1527 | 1528 |
1528 assign (idx, a); | 1529 assign (idx, a); |
2040 | 2041 |
2041 octave_sort<T> lsort (safe_comparator (mode, *this, true)); | 2042 octave_sort<T> lsort (safe_comparator (mode, *this, true)); |
2042 | 2043 |
2043 octave_idx_type r = rows (), c = cols (); | 2044 octave_idx_type r = rows (), c = cols (); |
2044 | 2045 |
2045 idx = Array<octave_idx_type> (r); | 2046 idx = Array<octave_idx_type> (r, 1); |
2046 | 2047 |
2047 lsort.sort_rows (data (), idx.fortran_vec (), r, c); | 2048 lsort.sort_rows (data (), idx.fortran_vec (), r, c); |
2048 | 2049 |
2049 return idx; | 2050 return idx; |
2050 } | 2051 } |
2200 // to resize. So count first, then allocate array of exact size. | 2201 // to resize. So count first, then allocate array of exact size. |
2201 octave_idx_type cnt = 0; | 2202 octave_idx_type cnt = 0; |
2202 for (octave_idx_type i = 0; i < nel; i++) | 2203 for (octave_idx_type i = 0; i < nel; i++) |
2203 cnt += src[i] != zero; | 2204 cnt += src[i] != zero; |
2204 | 2205 |
2205 retval = Array<octave_idx_type> (cnt); | 2206 retval.clear (cnt, 1); |
2206 octave_idx_type *dest = retval.fortran_vec (); | 2207 octave_idx_type *dest = retval.fortran_vec (); |
2207 for (octave_idx_type i = 0; i < nel; i++) | 2208 for (octave_idx_type i = 0; i < nel; i++) |
2208 if (src[i] != zero) *dest++ = i; | 2209 if (src[i] != zero) *dest++ = i; |
2209 } | 2210 } |
2210 else | 2211 else |
2211 { | 2212 { |
2212 // We want a fixed max number of elements, usually small. So be | 2213 // We want a fixed max number of elements, usually small. So be |
2213 // optimistic, alloc the array in advance, and then resize if | 2214 // optimistic, alloc the array in advance, and then resize if |
2214 // needed. | 2215 // needed. |
2215 retval = Array<octave_idx_type> (n); | 2216 retval.clear (n, 1); |
2216 if (backward) | 2217 if (backward) |
2217 { | 2218 { |
2218 // Do the search as a series of successive single-element searches. | 2219 // Do the search as a series of successive single-element searches. |
2219 octave_idx_type k = 0, l = nel - 1; | 2220 octave_idx_type k = 0, l = nel - 1; |
2220 for (; k < n; k++) | 2221 for (; k < n; k++) |
2224 retval(k) = l--; | 2225 retval(k) = l--; |
2225 else | 2226 else |
2226 break; | 2227 break; |
2227 } | 2228 } |
2228 if (k < n) | 2229 if (k < n) |
2229 retval.resize (k); | 2230 retval.resize (k, 1); |
2230 octave_idx_type *rdata = retval.fortran_vec (); | 2231 octave_idx_type *rdata = retval.fortran_vec (); |
2231 std::reverse (rdata, rdata + k); | 2232 std::reverse (rdata, rdata + k); |
2232 } | 2233 } |
2233 else | 2234 else |
2234 { | 2235 { |
2241 retval(k) = l++; | 2242 retval(k) = l++; |
2242 else | 2243 else |
2243 break; | 2244 break; |
2244 } | 2245 } |
2245 if (k < n) | 2246 if (k < n) |
2246 retval.resize (k); | 2247 retval.resize (k, 1); |
2247 } | 2248 } |
2248 } | 2249 } |
2249 | 2250 |
2250 // Fixup return dimensions, for Matlab compatibility. | 2251 // Fixup return dimensions, for Matlab compatibility. |
2251 // find(zeros(0,0)) -> zeros(0,0) | 2252 // find(zeros(0,0)) -> zeros(0,0) |
2597 | 2598 |
2598 if (n_dims) | 2599 if (n_dims) |
2599 { | 2600 { |
2600 os << "data:"; | 2601 os << "data:"; |
2601 | 2602 |
2602 Array<octave_idx_type> ra_idx (n_dims, 0); | 2603 Array<octave_idx_type> ra_idx (n_dims, 1, 0); |
2603 | 2604 |
2604 // Number of times the first 2d-array is to be displayed. | 2605 // Number of times the first 2d-array is to be displayed. |
2605 | 2606 |
2606 octave_idx_type m = 1; | 2607 octave_idx_type m = 1; |
2607 for (int i = 2; i < n_dims; i++) | 2608 for (int i = 2; i < n_dims; i++) |