Skip to content

Commit

Permalink
rmq
Browse files Browse the repository at this point in the history
  • Loading branch information
dimak24 committed Apr 13, 2019
1 parent c59007e commit 9347e8c
Show file tree
Hide file tree
Showing 5 changed files with 279 additions and 2 deletions.
7 changes: 7 additions & 0 deletions pysdsl/__init__.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "types/intvector.hpp"
#include "types/suffixarray.hpp"
#include "types/wavelet.hpp"
#include "types/rmq.hpp"

namespace py = pybind11;

Expand All @@ -40,6 +41,12 @@ PYBIND11_MODULE(pysdsl, m)

auto csa_classes = add_csa(m);

// new
auto rmq_classes_tuple = add_rmq_classes(m);
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);

for_each_in_tuple(iv_classes, make_inits_many_functor(iv_classes));
for_each_in_tuple(iv_classes, make_inits_many_functor(enc_classes));
for_each_in_tuple(iv_classes,
Expand Down
4 changes: 4 additions & 0 deletions pysdsl/docstrings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,7 @@ const char* doc_csa_wt(
"A class for the Compressed Suffix Array (CSA) based on a Wavelet Tree "
"(WT) of the Burrow Wheeler Transform of the original text."
);

const char* doc_rmq_sada("");

const char* doc_rmq_sparse_table("");
215 changes: 215 additions & 0 deletions pysdsl/types/rmq.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#pragma once

#include <string>
#include <tuple>
#include <utility>

#include <pybind11/pybind11.h>

#include <sdsl/rmq_support_sparse_table.hpp>
#include <sdsl/rmq_succinct_sada.hpp>

#include "operations/sizes.hpp"
#include "operations/iteration.hpp"
#include "util/tupletricks.hpp"
#include "docstrings.hpp"
#include "io.hpp"
#include "calc.hpp"



namespace detail {
// adds constructors of t_rac... containers
template <typename PybindClass, typename... t_rac>
typename std::enable_if<sizeof...(t_rac) == 0>::type add_rac_constructor(const PybindClass&) {}

template <typename PybindClass, typename t_rac_head, typename... t_rac_tail>
void add_rac_constructor(PybindClass& cls) {
cls.def(py::init([](const t_rac_head* rac) {
return typename PybindClass::type(rac);
}));
add_rac_constructor<PybindClass, t_rac_tail...>(cls);
}
}

// containers names
namespace RAC_names {
const char INT_VECTOR_NAME[] = "IntVector",
INT16_VECTOR_NAME[] = "Int16Vector";
}


struct add_rmq_sparse_table_functor {
py::module& m;
const char* doc;

constexpr add_rmq_sparse_table_functor(py::module& m, const char* doc = nullptr)
: m(m), doc(doc) {}

template <typename t_rac, const char* rac_name, bool t_min>
decltype(auto) operator()(std::tuple<t_rac,
std::integral_constant<const char*, rac_name>,
std::integral_constant<bool, t_min>>) {
using T = sdsl::rmq_support_sparse_table<t_rac, t_min>;

std::string name =
std::string("Range") + (t_min ? "Min" : "Max") + "QuerySparseTable_for_" + rac_name;

auto cls = py::class_<T>(m, name.c_str())
.def_property_readonly("size", (typename T::size_type(T::*)(void) const)& T::size)
.def(py::init([](const t_rac* rac) {return T(rac);}))
.def("set_vector", &T::set_vector)
.def("__call__",
(typename T::size_type
(T::*)(typename T::size_type, typename T::size_type) const)& T::operator());

add_sizes(cls);
add_description(cls);

// load takes two params
// add_serialization(cls);

return cls;
}
};


struct add_rmq_sada_functor {
py::module& m;
const char* doc;

constexpr add_rmq_sada_functor(py::module& m, const char* doc = nullptr)
: m(m), doc(doc) {}


template <typename... t_rac, bool t_min>
decltype(auto) operator()(std::tuple<std::tuple<t_rac...>,
std::integral_constant<bool, t_min>>) {
using T = typename std::conditional<t_min, sdsl::rmq_succinct_sada<>,
typename sdsl::range_maximum_support_sada<>::type>::type;

std::string name =
std::string("Range") + (t_min ? "Min" : "Max") + "QuerySuccintSada";

auto cls = py::class_<T>(m, name.c_str())
.def_property_readonly("size", (typename T::size_type(T::*)(void) const)& T::size)
.def(py::init())
.def("__call__",
(typename T::size_type
(T::*)(typename T::size_type, typename T::size_type) const)& T::operator());

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

add_sizes(cls);
add_description(cls);
add_serialization(cls);

return cls;
}
};


struct add_rmq_sct_functor {
py::module& m;
const char* doc;

constexpr add_rmq_sct_functor(py::module& m, const char* doc = nullptr)
: m(m), doc(doc) {}


template <typename... t_rac, bool t_min>
decltype(auto) operator()(std::tuple<std::tuple<t_rac...>,
std::integral_constant<bool, t_min>>) {
using T = typename std::conditional<t_min, sdsl::rmq_succinct_sct<>,
typename sdsl::range_maximum_sct<>::type>::type;

std::string name =
std::string("Range") + (t_min ? "Min" : "Max") + "QuerySuccintSct";

auto cls = py::class_<T>(m, name.c_str())
.def_property_readonly("size", (typename T::size_type(T::*)(void) const)& T::size)
.def(py::init())
.def("__call__",
(typename T::size_type
(T::*)(typename T::size_type, typename T::size_type) const)& T::operator());

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

add_sizes(cls);
add_description(cls);
add_serialization(cls);

return cls;
}
};


// generalized (constants -> typenames) template for usage with GeneralSubsetFunctor
template <typename t_rac, typename t_min_ic>
using general_rmq_sparse_table = py::class_<sdsl::rmq_support_sparse_table<t_rac, t_min_ic::value>>;

template <typename t_min_ic>
using general_rmq_sada = py::class_<
typename std::conditional<t_min_ic::value,
sdsl::rmq_succinct_sada<>,
typename sdsl::range_maximum_support_sada<>::type>::type>;

template <typename t_min_ic>
using general_rmq_sct = py::class_<
typename std::conditional<t_min_ic::value,
sdsl::rmq_succinct_sct<>,
typename sdsl::range_maximum_sct<>::type>::type>;


inline auto add_rmq_classes(py::module& m) {
m.attr("rmq_sparse_table") = py::dict();


using rmq_support_sparse_table_params = std::tuple<
std::tuple<sdsl::int_vector<>,
std::integral_constant<const char*, RAC_names::INT_VECTOR_NAME>,
std::integral_constant<bool, true>>,
std::tuple<sdsl::int_vector<>,
std::integral_constant<const char*, RAC_names::INT_VECTOR_NAME>,
std::integral_constant<bool, false>>,
std::tuple<sdsl::int_vector<16>,
std::integral_constant<const char*, RAC_names::INT16_VECTOR_NAME>,
std::integral_constant<bool, true>>,
std::tuple<sdsl::int_vector<16>,
std::integral_constant<const char*, RAC_names::INT16_VECTOR_NAME>,
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(),
add_rmq_sada_functor(m, doc_rmq_sada));
auto rmq_sct_classes = for_each_in_tuple(rmq_sct_params(),
add_rmq_sct_functor(m, doc_rmq_sada));

////////////// as params //////////////////////
using rmq_support_sparse_table_as_params = std::tuple<
std::tuple<sdsl::int_vector<>, std::integral_constant<bool, true>>,
std::tuple<sdsl::int_vector<>, std::integral_constant<bool, false>>
>;

auto rmq_sparse_tables_as_params = for_each_in_tuple(rmq_support_sparse_table_as_params(),
make_general_sybset_functor<general_rmq_sparse_table>(rmq_sparse_tables));
///////////////////////////////////////////////

return std::make_tuple(rmq_sparse_tables, rmq_sada_classes, rmq_sct_classes);
}
53 changes: 52 additions & 1 deletion pysdsl/util/tupletricks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ decltype(auto) for_each_impl(P&& t, Function&& f, std::index_sequence<Is...>) {

template<typename P, typename Function, std::size_t... Is>
constexpr
decltype(auto) for_each_impl(P& t, Function&& f, std::index_sequence<Is...>) {
decltype(auto) for_each_impl(const P& t, Function&& f, std::index_sequence<Is...>) {
return std::make_tuple(f(std::get<Is>(t))...); }

template<typename... T, typename Function>
Expand All @@ -27,6 +27,26 @@ constexpr
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>
constexpr
decltype(auto) forward_each_impl(P&& t, Function&& f, std::index_sequence<Is...>) {
return std::forward_as_tuple(f(std::get<Is>(t))...); }

template<typename P, typename Function, std::size_t... Is>
constexpr
decltype(auto) forward_each_impl(const P& t, Function&& f, std::index_sequence<Is...>) {
return std::forward_as_tuple(f(std::get<Is>(t))...); }

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

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

} // namespace detail


Expand All @@ -40,3 +60,34 @@ template <typename... Ts, typename F>
constexpr
decltype(auto) for_each_in_tuple(std::tuple<Ts...> &t, F f) {
return detail::for_each(t, f); }

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


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


// subset functor
template <template <typename...> typename general_template, typename... Ts>
struct GeneralSubsetFunctor {
std::tuple<Ts...>& tpl;

constexpr GeneralSubsetFunctor(std::tuple<Ts...>& tpl) noexcept
: tpl(tpl) {}

template <typename... Args>
auto& operator()(std::tuple<Args...>) const {
return std::get<general_template<Args...>>(tpl);
}
};

template <template <typename...> typename general_template, typename... Ts>
auto make_general_sybset_functor(std::tuple<Ts...>& tpl) {
return GeneralSubsetFunctor<general_template, Ts...>(tpl);
}
2 changes: 1 addition & 1 deletion sdsl-lite

0 comments on commit 9347e8c

Please sign in to comment.