4#include <rapidfuzz/distance/Jaro.hpp>
9template <
typename InputIt1,
typename InputIt2>
10double jaro_winkler_similarity(
const Range<InputIt1>& P,
const Range<InputIt2>& T,
double prefix_weight,
13 size_t P_len = P.size();
14 size_t T_len = T.size();
15 size_t min_len = std::min(P_len, T_len);
17 size_t max_prefix = std::min(min_len,
size_t(4));
19 for (; prefix < max_prefix; ++prefix)
20 if (T[prefix] != P[prefix])
break;
22 double jaro_score_cutoff = score_cutoff;
23 if (jaro_score_cutoff > 0.7) {
24 double prefix_sim =
static_cast<double>(prefix) * prefix_weight;
26 if (prefix_sim >= 1.0)
27 jaro_score_cutoff = 0.7;
29 jaro_score_cutoff = std::max(0.7, (prefix_sim - jaro_score_cutoff) / (prefix_sim - 1.0));
32 double Sim = jaro_similarity(P, T, jaro_score_cutoff);
34 Sim +=
static_cast<double>(prefix) * prefix_weight * (1.0 - Sim);
35 Sim = std::min(Sim, 1.0);
38 return (Sim >= score_cutoff) ? Sim : 0;
41template <
typename InputIt1,
typename InputIt2>
42double jaro_winkler_similarity(
const BlockPatternMatchVector& PM,
const Range<InputIt1>& P,
43 const Range<InputIt2>& T,
double prefix_weight,
double score_cutoff)
45 size_t P_len = P.size();
46 size_t T_len = T.size();
47 size_t min_len = std::min(P_len, T_len);
49 size_t max_prefix = std::min(min_len,
size_t(4));
51 for (; prefix < max_prefix; ++prefix)
52 if (T[prefix] != P[prefix])
break;
54 double jaro_score_cutoff = score_cutoff;
55 if (jaro_score_cutoff > 0.7) {
56 double prefix_sim =
static_cast<double>(prefix) * prefix_weight;
58 if (prefix_sim >= 1.0)
59 jaro_score_cutoff = 0.7;
61 jaro_score_cutoff = std::max(0.7, (prefix_sim - jaro_score_cutoff) / (prefix_sim - 1.0));
64 double Sim = jaro_similarity(PM, P, T, jaro_score_cutoff);
66 Sim +=
static_cast<double>(prefix) * prefix_weight * (1.0 - Sim);
67 Sim = std::min(Sim, 1.0);
70 return (Sim >= score_cutoff) ? Sim : 0;
73class JaroWinkler :
public SimilarityBase<JaroWinkler, double, 0, 1, double> {
74 friend SimilarityBase<JaroWinkler, double, 0, 1, double>;
75 friend NormalizedMetricBase<JaroWinkler, double>;
77 template <
typename InputIt1,
typename InputIt2>
78 static double maximum(
const Range<InputIt1>&,
const Range<InputIt2>&,
double)
noexcept
83 template <
typename InputIt1,
typename InputIt2>
84 static double _similarity(
const Range<InputIt1>& s1,
const Range<InputIt2>& s2,
double prefix_weight,
85 double score_cutoff,
double)
87 return jaro_winkler_similarity(s1, s2, prefix_weight, score_cutoff);