Skip to content

Commit

Permalink
use generated int vectors as params for rmq, improve rmq tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dimak24 committed May 18, 2019
1 parent c07114e commit 8346469
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 70 deletions.
2 changes: 1 addition & 1 deletion pysdsl/__init__.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ PYBIND11_MODULE(pysdsl, m)

auto csa_classes = add_csa(m);

auto rmq_classes_tuple = add_rmq_classes(m);
auto rmq_classes_tuple = add_rmq_classes(m, iv_classes_as_params);
auto& rmq_sparse_tables = std::get<0>(rmq_classes_tuple);
auto& rmq_sada = std::get<1>(rmq_classes_tuple);
auto& rmq_sct = std::get<2>(rmq_classes_tuple);
Expand Down
44 changes: 0 additions & 44 deletions pysdsl/test/test_rmq.py

This file was deleted.

44 changes: 21 additions & 23 deletions pysdsl/types/rmq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void add_rac_constructor(PybindClass& cls)
} // namespace details


// containers names
// containers names for sparse
namespace RAC_names {
constexpr char INT_VECTOR_NAME[] = "IntVector",
INT16_VECTOR_NAME[] = "Int16Vector";
Expand Down Expand Up @@ -80,7 +80,8 @@ struct add_rmq_sparse_table_functor {
std::string key = std::string(t_min ? "Min" : "Max") + "_in_" + rac_name;

m.attr("rmq_sparse_tables").attr("__setitem__")(key, cls);
m.attr("all_rmq_classes").attr("append")(cls);
m.attr((std::string("all_range_") + (t_min ? "min" : "max") + "_classes").c_str())
.attr("append")(cls);

return cls;
}
Expand Down Expand Up @@ -111,7 +112,7 @@ struct add_rmq_sada_functor {
.def("__call__",
(size_type (RMQClass::*)(size_type, size_type) const)& RMQClass::operator(),
(std::string("Returns an index of the ") + (t_min ? "minimal" : "maximal") +
" value on the segment [l,r].").c_str());;
" value on the segment [l,r].").c_str());;

detail::add_rac_constructor<decltype(cls), t_rac...>(cls);

Expand All @@ -122,7 +123,8 @@ struct add_rmq_sada_functor {
cls.doc() = doc;

m.attr("rmq_sada").attr("__setitem__")(t_min ? "Min" : "Max", cls);
m.attr("all_rmq_classes").attr("append")(cls);
m.attr((std::string("all_range_") + (t_min ? "min" : "max") + "_classes").c_str())
.attr("append")(cls);

return cls;
}
Expand Down Expand Up @@ -165,7 +167,8 @@ struct add_rmq_sct_functor {
cls.doc() = doc;

m.attr("rmq_sct").attr("__setitem__")(t_min ? "Min" : "Max", cls);
m.attr("all_rmq_classes").attr("append")(cls);
m.attr((std::string("all_range_") + (t_min ? "min" : "max") + "_classes").c_str())
.attr("append")(cls);

return cls;
}
Expand All @@ -190,12 +193,21 @@ using general_rmq_sct = py::class_<
typename sdsl::range_maximum_sct<>::type>::type>;


inline auto add_rmq_classes(py::module& m)
template <typename... Ts>
static
auto make_rmq_params(const std::tuple<py::class_<Ts>&...>& params) {
return std::tuple<std::tuple<std::tuple<Ts...>, std::integral_constant<bool, true>>,
std::tuple<std::tuple<Ts...>, std::integral_constant<bool, false>>>();
}


inline auto add_rmq_classes(py::module& m, auto params)
{
m.attr("rmq_sparse_tables") = py::dict();
m.attr("rmq_sada") = py::dict();
m.attr("rmq_sct") = py::dict();
m.attr("all_rmq_classes") = py::list();
m.attr("all_range_min_classes") = py::list();
m.attr("all_range_max_classes") = py::list();

using rmq_support_sparse_table_params = std::tuple<
std::tuple<sdsl::int_vector<>,
Expand All @@ -212,25 +224,11 @@ inline auto add_rmq_classes(py::module& m)
std::integral_constant<bool, false>>
>;

using rmq_sada_params = std::tuple<
std::tuple<std::tuple<sdsl::int_vector<>, sdsl::int_vector<16>>,
std::integral_constant<bool, true>>,
std::tuple<std::tuple<sdsl::int_vector<>, sdsl::int_vector<16>>,
std::integral_constant<bool, false>>
>;

using rmq_sct_params = std::tuple<
std::tuple<std::tuple<sdsl::int_vector<>, sdsl::int_vector<16>>,
std::integral_constant<bool, true>>,
std::tuple<std::tuple<sdsl::int_vector<>, sdsl::int_vector<16>>,
std::integral_constant<bool, false>>
>;

auto rmq_sparse_tables = for_each_in_tuple(rmq_support_sparse_table_params(),
add_rmq_sparse_table_functor(m, doc_rmq_sparse_table));
auto rmq_sada_classes = for_each_in_tuple(rmq_sada_params(),
auto rmq_sada_classes = for_each_in_tuple(make_rmq_params(params),
add_rmq_sada_functor(m, doc_rmq_sada));
auto rmq_sct_classes = for_each_in_tuple(rmq_sct_params(),
auto rmq_sct_classes = for_each_in_tuple(make_rmq_params(params),
add_rmq_sct_functor(m, doc_rmq_sct));

return std::make_tuple(rmq_sparse_tables, rmq_sada_classes, rmq_sct_classes);
Expand Down
4 changes: 2 additions & 2 deletions pysdsl/util/tupletricks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ decltype(auto) for_each(const std::tuple<T...>& t, Function&& f) {

template<typename... T, typename Function>
constexpr
decltype(auto) for_each(std::tuple<T...>& t, Function&& f) {
decltype(auto) for_each(std::tuple<T...>&& t, Function&& f) {
return for_each_impl(t, f, std::index_sequence_for<T...>{}); }

template<typename P, typename Function, std::size_t... Is>
Expand Down Expand Up @@ -58,7 +58,7 @@ decltype(auto) for_each_in_tuple(const std::tuple<Ts...> &t, F f) {

template <typename... Ts, typename F>
constexpr
decltype(auto) for_each_in_tuple(std::tuple<Ts...> &t, F f) {
decltype(auto) for_each_in_tuple(std::tuple<Ts...> &&t, F f) {
return detail::for_each(t, f); }

template <typename... Ts, typename F>
Expand Down
65 changes: 65 additions & 0 deletions tests/test_rmq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import random
import pytest

from pysdsl import Int8Vector, Int64Vector
from pysdsl import rmq_sada, rmq_sct




def _test_rmq(rmq_class, container_class, target):
cont = container_class(50)
a = []

for i in range(50):
a.append(random.randint(0, 50))
cont[i] = a[i]

rmq = rmq_class(cont)

for _ in range(50):
l = random.randint(0, 49)
r = random.randint(l, 49)

i = rmq(l, r)

assert cont[i] == target(a[l:r+1])



@pytest.mark.parametrize('container_class', (Int8Vector, Int64Vector))
def test_rmq_sada(container_class):
_test_rmq(rmq_sada['Min'], container_class, min)
_test_rmq(rmq_sada['Max'], container_class, max)


@pytest.mark.parametrize('container_class', (Int8Vector, Int64Vector))
def test_rmq_sct(container_class):
_test_rmq(rmq_sct['Min'], container_class, min)
_test_rmq(rmq_sct['Max'], container_class, max)



@pytest.mark.parametrize("rmq_class", list(rmq_sada.values()) + list(rmq_sct.values()))
def test_rmq_on_container_remove(rmq_class):
cont = Int64Vector(3)

cont[0] = 1
cont[1] = 2
cont[2] = 3

rmq = rmq_class(cont)

ans1 = rmq(0, 2)

cont[0] = 3
cont[1] = 2
cont[2] = 1

ans2 = rmq(0, 2)
assert ans1 == ans2

cont = None

ans2 = rmq(0, 2)
assert ans1 == ans2

0 comments on commit 8346469

Please sign in to comment.