6#include <rapidfuzz/details/Range.hpp>
7#include <rapidfuzz/distance/Jaro_impl.hpp>
17template <
typename InputIt1,
typename InputIt2>
18double jaro_distance(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
19 double score_cutoff = 1.0)
21 return detail::Jaro::distance(first1, last1, first2, last2, score_cutoff, score_cutoff);
24template <
typename Sentence1,
typename Sentence2>
25double jaro_distance(
const Sentence1& s1,
const Sentence2& s2,
double score_cutoff = 1.0)
27 return detail::Jaro::distance(s1, s2, score_cutoff, score_cutoff);
30template <
typename InputIt1,
typename InputIt2>
31double jaro_similarity(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
32 double score_cutoff = 0.0)
34 return detail::Jaro::similarity(first1, last1, first2, last2, score_cutoff, score_cutoff);
37template <
typename Sentence1,
typename Sentence2>
38double jaro_similarity(
const Sentence1& s1,
const Sentence2& s2,
double score_cutoff = 0.0)
40 return detail::Jaro::similarity(s1, s2, score_cutoff, score_cutoff);
43template <
typename InputIt1,
typename InputIt2>
44double jaro_normalized_distance(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
45 double score_cutoff = 1.0)
47 return detail::Jaro::normalized_distance(first1, last1, first2, last2, score_cutoff, score_cutoff);
50template <
typename Sentence1,
typename Sentence2>
51double jaro_normalized_distance(
const Sentence1& s1,
const Sentence2& s2,
double score_cutoff = 1.0)
53 return detail::Jaro::normalized_distance(s1, s2, score_cutoff, score_cutoff);
56template <
typename InputIt1,
typename InputIt2>
57double jaro_normalized_similarity(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
58 double score_cutoff = 0.0)
60 return detail::Jaro::normalized_similarity(first1, last1, first2, last2, score_cutoff, score_cutoff);
63template <
typename Sentence1,
typename Sentence2>
64double jaro_normalized_similarity(
const Sentence1& s1,
const Sentence2& s2,
double score_cutoff = 0.0)
66 return detail::Jaro::normalized_similarity(s1, s2, score_cutoff, score_cutoff);
70namespace experimental {
72struct MultiJaro :
public detail::MultiSimilarityBase<MultiJaro<MaxLen>, double, 0, 1> {
75 friend detail::MultiSimilarityBase<MultiJaro<MaxLen>, double, 0, 1>;
76 friend detail::MultiNormalizedMetricBase<MultiJaro<MaxLen>,
double>;
78 static_assert(MaxLen == 8 || MaxLen == 16 || MaxLen == 32 || MaxLen == 64,
"incorrect MaxLen used");
80 using VecType =
typename std::conditional<
82 typename std::conditional<MaxLen == 16, uint16_t,
83 typename std::conditional<MaxLen == 32, uint32_t, uint64_t>::type>::type>::
86 constexpr static size_t get_vec_size()
89 return detail::simd_avx2::native_simd<VecType>::size;
91 return detail::simd_sse2::native_simd<VecType>::size;
95 constexpr static size_t get_vec_alignment()
98 return detail::simd_avx2::native_simd<VecType>::alignment;
100 return detail::simd_sse2::native_simd<VecType>::alignment;
104 static size_t find_block_count(
size_t count)
106 size_t vec_size = get_vec_size();
107 size_t simd_vec_count = detail::ceil_div(count, vec_size);
108 return detail::ceil_div(simd_vec_count * vec_size * MaxLen, 64);
112 MultiJaro(
size_t count) : input_count(count), PM(find_block_count(count) * 64)
115 str_lens_size = result_count();
117 str_lens =
static_cast<VecType*
>(
118 detail::rf_aligned_alloc(get_vec_alignment(),
sizeof(VecType) * str_lens_size));
119 std::fill(str_lens, str_lens + str_lens_size, VecType(0));
124 detail::rf_aligned_free(str_lens);
136 size_t result_count()
const
138 size_t vec_size = get_vec_size();
139 size_t simd_vec_count = detail::ceil_div(input_count, vec_size);
140 return simd_vec_count * vec_size;
143 template <
typename Sentence1>
144 void insert(
const Sentence1& s1_)
146 insert(detail::to_begin(s1_), detail::to_end(s1_));
149 template <
typename InputIt1>
150 void insert(InputIt1 first1, InputIt1 last1)
152 auto len = std::distance(first1, last1);
153 int block_pos =
static_cast<int>((pos * MaxLen) % 64);
154 auto block = (pos * MaxLen) / 64;
155 assert(len <= MaxLen);
157 if (pos >= input_count)
throw std::invalid_argument(
"out of bounds insert");
159 str_lens[pos] =
static_cast<VecType
>(len);
160 for (; first1 != last1; ++first1) {
161 PM.insert(block, *first1, block_pos);
168 template <
typename InputIt2>
169 void _similarity(
double* scores,
size_t score_count,
const detail::Range<InputIt2>& s2,
170 double score_cutoff = 0.0)
const
172 if (score_count < result_count())
173 throw std::invalid_argument(
"scores has to have >= result_count() elements");
175 auto scores_ = detail::make_range(scores, scores + score_count);
176 detail::jaro_similarity_simd<VecType>(scores_, PM, str_lens, str_lens_size, s2, score_cutoff);
179 template <
typename InputIt2>
180 double maximum(
size_t,
const detail::Range<InputIt2>&)
const
185 size_t get_input_count() const noexcept
192 detail::BlockPatternMatchVector PM;
194 size_t str_lens_size;
200template <
typename CharT1>
201struct CachedJaro :
public detail::CachedSimilarityBase<CachedJaro<CharT1>, double, 0, 1> {
202 template <
typename Sentence1>
203 explicit CachedJaro(
const Sentence1& s1_) : CachedJaro(detail::to_begin(s1_), detail::to_end(s1_))
206 template <
typename InputIt1>
207 CachedJaro(InputIt1 first1, InputIt1 last1) : s1(first1, last1), PM(detail::make_range(first1, last1))
211 friend detail::CachedSimilarityBase<CachedJaro<CharT1>, double, 0, 1>;
212 friend detail::CachedNormalizedMetricBase<CachedJaro<CharT1>>;
214 template <
typename InputIt2>
215 double maximum(
const detail::Range<InputIt2>&)
const
220 template <
typename InputIt2>
221 double _similarity(
const detail::Range<InputIt2>& s2,
double score_cutoff,
double)
const
223 return detail::jaro_similarity(PM, detail::make_range(s1), s2, score_cutoff);
226 std::vector<CharT1> s1;
227 detail::BlockPatternMatchVector PM;
230#ifdef RAPIDFUZZ_DEDUCTION_GUIDES
231template <
typename Sentence1>
232explicit CachedJaro(
const Sentence1& s1_) -> CachedJaro<char_type<Sentence1>>;
234template <
typename InputIt1>
235CachedJaro(InputIt1 first1, InputIt1 last1) -> CachedJaro<iter_value_t<InputIt1>>;