diff --git a/include/xframe/xaxis.hpp b/include/xframe/xaxis.hpp index 2698189..79a3811 100644 --- a/include/xframe/xaxis.hpp +++ b/include/xframe/xaxis.hpp @@ -9,6 +9,8 @@ #ifndef XFRAME_XAXIS_HPP #define XFRAME_XAXIS_HPP +extern double global_tolerance; + #include #include #include @@ -114,6 +116,10 @@ namespace xf bool contains(const key_type& key) const; mapped_type operator[](const key_type& key) const; + mapped_type tolerance(const key_type& key, std::true_type) const; + mapped_type tolerance(const key_type& key, std::false_type) const; + mapped_type with_tolerance(const key_type& key) const; + mapped_type without_tolerance(const key_type& key) const; template self_type filter(const F& f) const noexcept; @@ -404,6 +410,45 @@ namespace xf return m_index.count(key) != typename map_type::size_type(0); } + template + inline auto xaxis::tolerance(const key_type& key, std::true_type) const -> mapped_type + { + return with_tolerance(key); + } + + template + inline auto xaxis::tolerance(const key_type& key, std::false_type) const -> mapped_type + { + return without_tolerance(key); + } + + template + inline auto xaxis::with_tolerance(const key_type& key) const -> mapped_type + { + if (global_tolerance > 0.) + { + double smallest; + int position = -1; + for (const auto& it: m_index) + { + double diff = fabs(double(it.first) - key); + if ((diff <= global_tolerance) && ((position < 0) || (diff < smallest))) + { + smallest = diff; + position = it.second; + } + } + return position >= 0 ? position : m_index.at(key); + } + return m_index.at(key); + } + + template + inline auto xaxis::without_tolerance(const key_type& key) const -> mapped_type + { + return m_index.at(key); + } + /** * Returns the position of the specified label. If this last one is * not found, an exception is thrown. @@ -412,7 +457,7 @@ namespace xf template inline auto xaxis::operator[](const key_type& key) const -> mapped_type { - return m_index.at(key); + return tolerance(key, std::integral_constant::value>{}); } //@} diff --git a/include/xframe/xvariable_view.hpp b/include/xframe/xvariable_view.hpp index 364f0fc..fa4af02 100644 --- a/include/xframe/xvariable_view.hpp +++ b/include/xframe/xvariable_view.hpp @@ -281,7 +281,7 @@ namespace xf auto locate(E&& e, S&&... slices); template - auto select(E&& e, std::map::key_type, xaxis_slice>&& slices); + auto select(E&& e, std::map::key_type, xaxis_slice>&& slices, double tolerance=0.); template ::difference_type> auto iselect(E&& e, std::map::key_type, xt::xdynamic_slice>&& slices); @@ -1089,8 +1089,9 @@ namespace xf } template - inline auto select(E&& e, std::map::key_type, xaxis_slice>&& slices) + inline auto select(E&& e, std::map::key_type, xaxis_slice>&& slices, double tolerance) { + global_tolerance = tolerance; using coordinate_type = typename std::decay_t::coordinate_type; using dimension_type = typename std::decay_t::dimension_type; using dimension_label_list = typename dimension_type::label_list;