##// END OF EJS Templates
push method of worker return the id of the nextRange which is canceled
push method of worker return the id of the nextRange which is canceled

File last commit:

r577:997f682a3d4f
r584:d6648352006d
Show More
SortUtils.h
117 lines | 4.1 KiB | text/x-c | CLexer
#ifndef SCIQLOP_SORTUTILS_H
#define SCIQLOP_SORTUTILS_H
#include <algorithm>
#include <cmath>
#include <numeric>
#include <vector>
/**
* Utility class with methods for sorting data
*/
struct SortUtils {
/**
* Generates a vector representing the index of insertion of each data of a container if this
* one had to be sorted according to a comparison function.
*
* For example:
* If the container is a vector {1; 4; 2; 5; 3} and the comparison function is std::less, the
* result would be : {0; 3; 1; 4; 2}
*
* @tparam Container the type of the container.
* @tparam Compare the type of the comparison function
* @param container the container from which to generate the result. The container must have a
* at() method that returns a value associated to an index
* @param compare the comparison function
*/
template <typename Container, typename Compare>
static std::vector<int> sortPermutation(const Container &container, const Compare &compare)
{
auto permutation = std::vector<int>{};
permutation.resize(container.size());
std::iota(permutation.begin(), permutation.end(), 0);
std::sort(permutation.begin(), permutation.end(),
[&](int i, int j) { return compare(container.at(i), container.at(j)); });
return permutation;
}
/**
* Sorts a container according to indices passed in parameter
* @param container the container sorted
* @param sortPermutation the indices used to sort the container
* @return the container sorted
* @warning no verification is made on validity of sortPermutation (i.e. the vector has unique
* indices and its range is [0 ; vector.size()[ )
*/
template <typename Container>
static Container sort(const Container &container, const std::vector<int> &sortPermutation)
{
if (container.size() != sortPermutation.size()) {
return Container{};
}
// Inits result
auto sortedData = Container{};
sortedData.resize(container.size());
std::transform(sortPermutation.cbegin(), sortPermutation.cend(), sortedData.begin(),
[&container](int i) { return container.at(i); });
return sortedData;
}
/**
* Compares two values that can be NaN. This method is intended to be used as a compare function
* for searching min value by excluding NaN values.
*
* Examples of use:
* - f({1, 3, 2, 4, 5}) will return 1
* - f({NaN, 3, 2, 4, 5}) will return 2 (NaN is excluded)
* - f({NaN, NaN, 3, NaN, NaN}) will return 3 (NaN are excluded)
* - f({NaN, NaN, NaN, NaN, NaN}) will return NaN (no existing value)
*
* @param v1 first value
* @param v2 second value
* @return true if v1 < v2, false otherwise
* @sa std::min_element
*/
template <typename T>
static bool minCompareWithNaN(const T &v1, const T &v2)
{
// Table used with NaN values:
// NaN < v2 -> false
// v1 < NaN -> true
// NaN < NaN -> false
// v1 < v2 -> v1 < v2
return std::isnan(v1) ? false : std::isnan(v2) || (v1 < v2);
}
/**
* Compares two values that can be NaN. This method is intended to be used as a compare function
* for searching max value by excluding NaN values.
*
* Examples of use:
* - f({1, 3, 2, 4, 5}) will return 5
* - f({1, 3, 2, 4, NaN}) will return 4 (NaN is excluded)
* - f({NaN, NaN, 3, NaN, NaN}) will return 3 (NaN are excluded)
* - f({NaN, NaN, NaN, NaN, NaN}) will return NaN (no existing value)
*
* @param v1 first value
* @param v2 second value
* @return true if v1 < v2, false otherwise
* @sa std::max_element
*/
template <typename T>
static bool maxCompareWithNaN(const T &v1, const T &v2)
{
// Table used with NaN values:
// NaN < v2 -> true
// v1 < NaN -> false
// NaN < NaN -> false
// v1 < v2 -> v1 < v2
return std::isnan(v1) ? true : !std::isnan(v2) && (v1 < v2);
}
};
#endif // SCIQLOP_SORTUTILS_H