12#ifndef RD_Z_MATRIX_UTILS_H
13#define RD_Z_MATRIX_UTILS_H
18#include <unordered_set>
22#define M_PI 3.14159265358979323846
31 using Ts::operator()...;
35constexpr double TORSION_PRECISION =
38inline double dequantize(int64_t val) {
39 return static_cast<double>(val) / TORSION_PRECISION;
44inline int64_t
quantize(
double val,
double precision = TORSION_PRECISION) {
45 val = std::fmod(val +
M_PI, 2.0 *
M_PI);
51 return static_cast<int64_t
>(val * precision);
61 if (d_qLower == d_qUpper) {
63 d_qUpper =
static_cast<int64_t
>(
M_PI * TORSION_PRECISION);
64 d_qLower = -
static_cast<int64_t
>(
M_PI * TORSION_PRECISION);
69 : d_qLower(qLower), d_qUpper(qUpper) {
70 lower = dequantize(qLower);
71 upper = dequantize(qUpper);
75 if (d_qLower <= d_qUpper) {
76 return value >= d_qLower && value <= d_qUpper;
79 return (value < d_qLower) != (value > d_qUpper);
88 return res + 2.0 *
M_PI;
98 return this->d_qLower == other.d_qLower && this->d_qUpper == other.d_qUpper;
106 int64_t d_qLower, d_qUpper;
111 using iterator = std::unordered_set<value_type>::iterator;
117 content.reserve(values.size());
119 for (
auto val : values) {
124 bool empty()
const {
return content.empty(); }
125 std::size_t
size()
const {
return content.size(); }
133 rhs.content.merge(lhs.content);
139 static_cast<std::size_t
>(rng() *
static_cast<double>(this->
size()));
142 std::advance(it, idxT);
146 return dequantize(*it);
149 return content == other.content;
151 double firstValue()
const {
return dequantize(*content.begin()); }
153 std::pair<iterator, bool>
insert(
const double val) {
154 return content.insert(
quantize(val));
157 std::pair<iterator, bool>
insertQ(
const int64_t val) {
158 return content.insert(val);
162 const std::int64_t qVal =
quantize(value);
163 return content.contains(qVal);
167 std::unordered_set<int64_t> content;
193 for (
const auto &val : values) {
199 if (!mergedValues.
empty()) {
203 const auto &[minIt, maxIt] = std::ranges::minmax_element(values);
206 return merge(range, minMaxValues);
211 return merge(range, values);
225 return lhs.size() < rhs.
size();
258 [&rng](
const auto &torsionCand) ->
double {
259 return torsionCand.sample(rng);
267 [](
const auto &l,
const auto &r) ->
bool {
return less(l, r); }, lhs,
273 [](
const auto &l,
const auto &r) ->
bool {
return equal(l, r); }, lhs,
280 [value](
const auto &x) ->
bool {
return x.contains(value); },
#define PRECONDITION(expr, mess)
bool less(const TorsionCandidates &lhs, const TorsionCandidates &rhs)
bool equal(const TorsionCandidates &lhs, const TorsionCandidates &rhs)
std::variant< TorsionRange, TorsionValues > TorsionCandidates
TorsionCandidates merge(const TorsionCandidates &lhs, const TorsionCandidates &rhs)
bool contains(const TorsionCandidates &torsionCand, const double value)
double sample(const TorsionCandidates &torsionCand, RDKit::double_source_type &rng)
int64_t quantize(double val, double precision=TORSION_PRECISION)
boost::variate_generator< rng_type &, uniform_double > double_source_type
bool operator==(const TorsionRange &other) const
bool contains(const double value) const
TorsionRange(double lower, double upper)
TorsionRange(int64_t qLower, int64_t qUpper)
bool qContains(const int64_t value) const
bool operator<(const TorsionRange &other) const
double sample(RDKit::double_source_type &rng) const
double firstValue() const
bool operator==(const TorsionValues &other) const
const_iterator cend() const
friend TorsionValues merge(TorsionValues lhs, TorsionValues rhs)
bool contains(const double value) const
const_iterator begin() const
TorsionValues(std::initializer_list< double > values)
const_iterator end() const
std::pair< iterator, bool > insert(const double val)
std::unordered_set< value_type >::iterator iterator
double sample(RDKit::double_source_type &rng) const
std::pair< iterator, bool > insertQ(const int64_t val)
std::unordered_set< value_type >::const_iterator const_iterator
const_iterator cbegin() const