Commit b66c6e36 authored by LEFEBVREJP email's avatar LEFEBVREJP email
Browse files

Adding implemention of sort_permutation and apply_permutation.

parent d91869fa
Pipeline #8391 passed with stages
in 24 minutes and 50 seconds
......@@ -2,6 +2,7 @@ TRIBITS_PACKAGE_DEFINE_DEPENDENCIES(
SUBPACKAGES_DIRS_CLASSIFICATIONS_OPTREQS
bug radixbug SS OPTIONAL
pattern radixpattern SS OPTIONAL
algorithm radixalgorithm SS OPTIONAL
para radixpara SS OPTIONAL
command radixcommand SS OPTIONAL
math radixmath SS OPTIONAL
......
TRIBITS_SUBPACKAGE(algorithm)
SET(SOURCE
ordering.cc
)
SET(HEADERS
ordering.hh
)
TRIBITS_ADD_LIBRARY(radixalgorithmlib
SOURCES ${SOURCE}
NOINSTALLHEADERS ${HEADERS}
)
INSTALL(FILES ${HEADERS} DESTINATION "include/radixalgorithm/")
TRIBITS_ADD_TEST_DIRECTORIES(tests)
TRIBITS_SUBPACKAGE_POSTPROCESS()
TRIBITS_PACKAGE_DEFINE_DEPENDENCIES(
LIB_REQUIRED_PACKAGES
LIB_OPTIONAL_TPLS
TEST_REQUIRED_PACKAGES testframework
)
#include "radixalgorithm/ordering.hh"
#include <iostream>
namespace radix
{
void ordering_dummy_struct::foo_method()
{
std::cout << "This is a dummy method for compilation symbol" << std::endl;
}
} // namespace radix
#include <vector>
#include <numeric>
#include <utility> // swap
#include <algorithm>
#include <radixbug/bug.hh>
namespace radix
{
struct ordering_dummy_struct
{
void foo_method();
};
template<typename list_type
, typename compare_type>
std::vector<size_t> sort_permutation(const list_type& data
, compare_type& comparator)
{
// create list of indices the size of the incoming data
std::vector<std::size_t> order(data.size());
// initialize list with initial index, starting at zero
std::iota(order.begin(), order.end(), 0);
// order ordering according to comparator
std::sort(order.begin(), order.end(),
[&](std::size_t data_i, std::size_t data_j)
{
radix_line("Comparing [" << data_i
<< ", " << data_j << "]");
return comparator(data[data_i], data[data_j]);
});
return order;
} // sort_permutation
template <typename list_type>
void apply_permutation(list_type& data
, const std::vector<size_t>& order)
{
std::vector<bool> done(data.size(), false);
for (size_t i = 0; i < data.size(); ++i)
{
if (done[i]) continue;
done[i] = true;
// previous ordering is that of the loop, so index i it is
size_t prev_j = i;
// get the new order lookup
size_t j = order[i];
//
while(i != j)
{
radix_line( i << ". swapping " << prev_j << " for " << j);
std::swap(data[prev_j], data[j]);
done[j] = true;
prev_j = j;
j = order[j];
}
}
} // apply_permutation
} // namespace radix
INCLUDE(GoogleTest)
ADD_GOOGLE_TEST(tstOrdering.cc NP 1)
#include <iostream>
#include "gtest/gtest.h"
#include "radixbug/bug.hh"
#include "radixalgorithm/ordering.hh"
TEST(radixalgorithm, Ordering)
{
std::vector<double> list {2.0, 1.0, 3.0, 4.0, 5.0, 0.0, 10.0};
// permutation 5, 1, 0, 2, 3, 4, 6
// correct ordering
std::vector<int> list2 { 0, 1, 2, 3, 4, 5, 6};
auto comparator = [](double a, double b)
{
radix_line("\t[" << a << "," << b << "]");
return a<b;
};
std::vector<size_t> permutation = radix::sort_permutation(list, comparator);
// test edges
EXPECT_EQ(permutation[0], 5);
EXPECT_EQ(permutation[6], 6);
std::cout << "Ordering:" << std::endl;
for(size_t i = 0; i < permutation.size(); ++i)
{
std::cout << "index " << i << ". (" << list[i]
<< ") recieves value from "
<< permutation[i]
<< " (" << list[permutation[i]] << ")"
<< std::endl;
}
//
// sort list given the
radix::apply_permutation(list, permutation);
EXPECT_DOUBLE_EQ(list[0], 0.0);
EXPECT_DOUBLE_EQ(list[6], 10.0);
radix::apply_permutation(list2, permutation);
EXPECT_EQ(list2[0], 5);
EXPECT_EQ(list2[6], 6);
for(size_t i = 0; i < list.size(); ++i)
{
std::cout << "[" << list[i] << "," << list2[i] << "]" << std::endl;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment