Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: nearest neighbor lookup selection #232

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion include/xframe/xaxis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef XFRAME_XAXIS_HPP
#define XFRAME_XAXIS_HPP

extern double global_tolerance;

#include <initializer_list>
#include <iterator>
#include <algorithm>
Expand Down Expand Up @@ -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 <class F>
self_type filter(const F& f) const noexcept;
Expand Down Expand Up @@ -404,6 +410,45 @@ namespace xf
return m_index.count(key) != typename map_type::size_type(0);
}

template <class L, class T, class MT>
inline auto xaxis<L, T, MT>::tolerance(const key_type& key, std::true_type) const -> mapped_type
{
return with_tolerance(key);
}

template <class L, class T, class MT>
inline auto xaxis<L, T, MT>::tolerance(const key_type& key, std::false_type) const -> mapped_type
{
return without_tolerance(key);
}

template <class L, class T, class MT>
inline auto xaxis<L, T, MT>::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 <class L, class T, class MT>
inline auto xaxis<L, T, MT>::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.
Expand All @@ -412,7 +457,7 @@ namespace xf
template <class L, class T, class MT>
inline auto xaxis<L, T, MT>::operator[](const key_type& key) const -> mapped_type
{
return m_index.at(key);
return tolerance(key, std::integral_constant<bool, std::is_floating_point<key_type>::value>{});
}
//@}

Expand Down
5 changes: 3 additions & 2 deletions include/xframe/xvariable_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ namespace xf
auto locate(E&& e, S&&... slices);

template <class E, class L = XFRAME_DEFAULT_LABEL_LIST>
auto select(E&& e, std::map<typename std::decay_t<E>::key_type, xaxis_slice<L>>&& slices);
auto select(E&& e, std::map<typename std::decay_t<E>::key_type, xaxis_slice<L>>&& slices, double tolerance=0.);

template <class E, class T = typename std::decay_t<E>::difference_type>
auto iselect(E&& e, std::map<typename std::decay_t<E>::key_type, xt::xdynamic_slice<T>>&& slices);
Expand Down Expand Up @@ -1089,8 +1089,9 @@ namespace xf
}

template <class E, class L>
inline auto select(E&& e, std::map<typename std::decay_t<E>::key_type, xaxis_slice<L>>&& slices)
inline auto select(E&& e, std::map<typename std::decay_t<E>::key_type, xaxis_slice<L>>&& slices, double tolerance)
{
global_tolerance = tolerance;
using coordinate_type = typename std::decay_t<E>::coordinate_type;
using dimension_type = typename std::decay_t<E>::dimension_type;
using dimension_label_list = typename dimension_type::label_list;
Expand Down