Mercurial > octave-nkf
comparison liboctave/Array.cc @ 9921:7c8392a034e6
fix & improve lookup API
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Sat, 05 Dec 2009 06:10:41 +0100 |
parents | 56fbe170d354 |
children | bb30843c4929 |
comparison
equal
deleted
inserted
replaced
9920:56fbe170d354 | 9921:7c8392a034e6 |
---|---|
2240 Array<octave_idx_type> | 2240 Array<octave_idx_type> |
2241 Array<T>::sort_rows_idx (sortmode mode) const | 2241 Array<T>::sort_rows_idx (sortmode mode) const |
2242 { | 2242 { |
2243 Array<octave_idx_type> idx; | 2243 Array<octave_idx_type> idx; |
2244 | 2244 |
2245 octave_sort<T> lsort; | 2245 octave_sort<T> lsort (safe_comparator (mode, *this, true)); |
2246 | |
2247 lsort.set_compare (safe_comparator (mode, *this, true)); | |
2248 | 2246 |
2249 octave_idx_type r = rows (), c = cols (); | 2247 octave_idx_type r = rows (), c = cols (); |
2250 | 2248 |
2251 idx = Array<octave_idx_type> (r); | 2249 idx = Array<octave_idx_type> (r); |
2252 | 2250 |
2334 lsort.set_compare (mode); | 2332 lsort.set_compare (mode); |
2335 | 2333 |
2336 return lsort.lookup (data (), n, value); | 2334 return lsort.lookup (data (), n, value); |
2337 } | 2335 } |
2338 | 2336 |
2339 // Ditto, but for an array of values, specializing on long runs. | |
2340 // Adds optional offset to all indices. | |
2341 template <class T> | 2337 template <class T> |
2342 Array<octave_idx_type> | 2338 Array<octave_idx_type> |
2343 Array<T>::lookup (const Array<T>& values, sortmode mode, | 2339 Array<T>::lookup (const Array<T>& values, sortmode mode) const |
2344 bool linf, bool rinf) const | 2340 { |
2345 { | 2341 octave_idx_type n = numel (), nval = values.numel (); |
2346 octave_idx_type n = numel (); | |
2347 octave_sort<T> lsort; | 2342 octave_sort<T> lsort; |
2348 Array<octave_idx_type> idx (values.dims ()); | 2343 Array<octave_idx_type> idx (values.dims ()); |
2349 | 2344 |
2350 if (mode == UNSORTED) | 2345 if (mode == UNSORTED) |
2351 { | 2346 { |
2356 mode = ASCENDING; | 2351 mode = ASCENDING; |
2357 } | 2352 } |
2358 | 2353 |
2359 lsort.set_compare (mode); | 2354 lsort.set_compare (mode); |
2360 | 2355 |
2361 // set offset and shift size. | 2356 // This determines the split ratio between the O(M*log2(N)) and O(M+N) algorithms. |
2362 octave_idx_type offset = 0; | 2357 static const double ratio = 1.0; |
2363 | 2358 sortmode vmode = UNSORTED; |
2364 if (linf && n > 0) | 2359 |
2365 { | 2360 // Attempt the O(M+N) algorithm if M is large enough. |
2366 offset++; | 2361 if (nval > ratio * n / xlog2 (n + 1.0)) |
2367 n--; | 2362 { |
2368 } | 2363 vmode = values.is_sorted (); |
2369 if (rinf && n > 0) | 2364 // The table must not contain a NaN. |
2370 n--; | 2365 if ((vmode == ASCENDING && sort_isnan<T> (values(nval-1))) |
2371 | 2366 || (vmode == DESCENDING && sort_isnan<T> (values(0)))) |
2372 lsort.lookup (data () + offset, n, values.data (), values.numel (), | 2367 vmode = UNSORTED; |
2373 idx.fortran_vec (), offset); | 2368 } |
2369 | |
2370 if (vmode != UNSORTED) | |
2371 lsort.lookup_sorted (data (), n, values.data (), nval, | |
2372 idx.fortran_vec (), vmode != mode); | |
2373 else | |
2374 lsort.lookup (data (), n, values.data (), nval, idx.fortran_vec ()); | |
2374 | 2375 |
2375 return idx; | 2376 return idx; |
2376 } | |
2377 | |
2378 template <class T> | |
2379 Array<octave_idx_type> | |
2380 Array<T>::lookupm (const Array<T>& values, sortmode mode) const | |
2381 { | |
2382 octave_idx_type n = numel (); | |
2383 octave_sort<T> lsort; | |
2384 Array<octave_idx_type> idx (values.dims ()); | |
2385 | |
2386 if (mode == UNSORTED) | |
2387 { | |
2388 // auto-detect mode | |
2389 if (n > 1 && lsort.descending_compare (elem (0), elem (n-1))) | |
2390 mode = DESCENDING; | |
2391 else | |
2392 mode = ASCENDING; | |
2393 } | |
2394 | |
2395 lsort.set_compare (mode); | |
2396 | |
2397 lsort.lookupm (data (), n, values.data (), values.numel (), | |
2398 idx.fortran_vec ()); | |
2399 | |
2400 return idx; | |
2401 } | |
2402 | |
2403 template <class T> | |
2404 Array<bool> | |
2405 Array<T>::lookupb (const Array<T>& values, sortmode mode) const | |
2406 { | |
2407 octave_idx_type n = numel (); | |
2408 octave_sort<T> lsort; | |
2409 Array<bool> match (values.dims ()); | |
2410 | |
2411 if (mode == UNSORTED) | |
2412 { | |
2413 // auto-detect mode | |
2414 if (n > 1 && lsort.descending_compare (elem (0), elem (n-1))) | |
2415 mode = DESCENDING; | |
2416 else | |
2417 mode = ASCENDING; | |
2418 } | |
2419 | |
2420 lsort.set_compare (mode); | |
2421 | |
2422 lsort.lookupb (data (), n, values.data (), values.numel (), | |
2423 match.fortran_vec ()); | |
2424 | |
2425 return match; | |
2426 } | 2377 } |
2427 | 2378 |
2428 template <class T> | 2379 template <class T> |
2429 octave_idx_type | 2380 octave_idx_type |
2430 Array<T>::nnz (void) const | 2381 Array<T>::nnz (void) const |
2698 \ | 2649 \ |
2699 template <> octave_idx_type \ | 2650 template <> octave_idx_type \ |
2700 Array<T>::lookup (T const &, sortmode) const \ | 2651 Array<T>::lookup (T const &, sortmode) const \ |
2701 { return 0; } \ | 2652 { return 0; } \ |
2702 template <> Array<octave_idx_type> \ | 2653 template <> Array<octave_idx_type> \ |
2703 Array<T>::lookup (const Array<T>&, sortmode, bool, bool) const \ | 2654 Array<T>::lookup (const Array<T>&, sortmode) const \ |
2704 { return Array<octave_idx_type> (); } \ | 2655 { return Array<octave_idx_type> (); } \ |
2705 template <> Array<octave_idx_type> \ | |
2706 Array<T>::lookupm (const Array<T>&, sortmode) const \ | |
2707 { return Array<octave_idx_type> (); } \ | |
2708 template <> Array<bool> \ | |
2709 Array<T>::lookupb (const Array<T>&, sortmode) const \ | |
2710 { return Array<bool> (); } \ | |
2711 \ | 2656 \ |
2712 template <> octave_idx_type \ | 2657 template <> octave_idx_type \ |
2713 Array<T>::nnz (void) const\ | 2658 Array<T>::nnz (void) const\ |
2714 { return 0; } \ | 2659 { return 0; } \ |
2715 template <> Array<octave_idx_type> \ | 2660 template <> Array<octave_idx_type> \ |