4#include <rapidfuzz/details/PatternMatchVector.hpp>
5#include <rapidfuzz/details/Range.hpp>
6#include <rapidfuzz/details/common.hpp>
7#include <rapidfuzz/details/distance.hpp>
8#include <rapidfuzz/details/intrinsics.hpp>
9#include <rapidfuzz/distance/LCSseq.hpp>
14template <
typename InputIt1,
typename InputIt2>
15size_t indel_distance(
const BlockPatternMatchVector& block,
const Range<InputIt1>& s1,
16 const Range<InputIt2>& s2,
size_t score_cutoff)
18 size_t maximum = s1.size() + s2.size();
19 size_t lcs_cutoff = (maximum / 2 >= score_cutoff) ? maximum / 2 - score_cutoff : 0;
20 size_t lcs_sim = lcs_seq_similarity(block, s1, s2, lcs_cutoff);
21 size_t dist = maximum - 2 * lcs_sim;
22 return (dist <= score_cutoff) ? dist : score_cutoff + 1;
25template <
typename InputIt1,
typename InputIt2>
26double indel_normalized_distance(
const BlockPatternMatchVector& block,
const Range<InputIt1>& s1,
27 const Range<InputIt2>& s2,
double score_cutoff)
29 size_t maximum = s1.size() + s2.size();
30 size_t cutoff_distance =
static_cast<size_t>(std::ceil(
static_cast<double>(maximum) * score_cutoff));
31 size_t dist = indel_distance(block, s1, s2, cutoff_distance);
32 double norm_dist = (maximum) ?
static_cast<double>(dist) /
static_cast<double>(maximum) : 0.0;
33 return (norm_dist <= score_cutoff) ? norm_dist : 1.0;
36template <
typename InputIt1,
typename InputIt2>
37double indel_normalized_similarity(
const BlockPatternMatchVector& block,
const Range<InputIt1>& s1,
38 const Range<InputIt2>& s2,
double score_cutoff)
40 double cutoff_score = NormSim_to_NormDist(score_cutoff);
41 double norm_dist = indel_normalized_distance(block, s1, s2, cutoff_score);
42 double norm_sim = 1.0 - norm_dist;
43 return (norm_sim >= score_cutoff) ? norm_sim : 0.0;
46class Indel :
public DistanceBase<Indel, size_t, 0, std::numeric_limits<int64_t>::max()> {
47 friend DistanceBase<Indel, size_t, 0, std::numeric_limits<int64_t>::max()>;
48 friend NormalizedMetricBase<Indel>;
50 template <
typename InputIt1,
typename InputIt2>
51 static size_t maximum(
const Range<InputIt1>& s1,
const Range<InputIt2>& s2)
53 return s1.size() + s2.size();
56 template <
typename InputIt1,
typename InputIt2>
57 static size_t _distance(
const Range<InputIt1>& s1,
const Range<InputIt2>& s2,
size_t score_cutoff,
60 size_t maximum = Indel::maximum(s1, s2);
61 size_t lcs_cutoff = (maximum / 2 >= score_cutoff) ? maximum / 2 - score_cutoff : 0;
62 size_t lcs_hint = (maximum / 2 >= score_hint) ? maximum / 2 - score_hint : 0;
63 size_t lcs_sim = LCSseq::similarity(s1, s2, lcs_cutoff, lcs_hint);
64 size_t dist = maximum - 2 * lcs_sim;
65 return (dist <= score_cutoff) ? dist : score_cutoff + 1;