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