pub const BM25_K1: f32 = 1.2;
pub const BM25_B: f32 = 0.75;
#[inline]
pub fn bm25_score(tf: f32, idf: f32, doc_len: f32, avg_doc_len: f32) -> f32 {
let length_norm = 1.0 - BM25_B + BM25_B * (doc_len / avg_doc_len.max(1.0));
let tf_norm = (tf * (BM25_K1 + 1.0)) / (tf + BM25_K1 * length_norm);
idf * tf_norm
}
#[inline]
pub fn bm25f_score(tf: f32, idf: f32, doc_len: f32, avg_doc_len: f32, field_boost: f32) -> f32 {
let length_norm = 1.0 - BM25_B + BM25_B * (doc_len / avg_doc_len.max(1.0));
let tf_norm = (tf * field_boost * (BM25_K1 + 1.0)) / (tf * field_boost + BM25_K1 * length_norm);
idf * tf_norm
}
#[inline]
pub fn bm25_upper_bound(max_tf: f32, idf: f32) -> f32 {
let min_length_norm = 1.0 - BM25_B;
let tf_norm = (max_tf * (BM25_K1 + 1.0)) / (max_tf + BM25_K1 * min_length_norm);
idf * tf_norm
}
#[inline]
pub fn bm25f_upper_bound(max_tf: f32, idf: f32, field_boost: f32) -> f32 {
let min_length_norm = 1.0 - BM25_B;
let tf_norm = (max_tf * field_boost * (BM25_K1 + 1.0))
/ (max_tf * field_boost + BM25_K1 * min_length_norm);
idf * tf_norm
}
#[inline]
pub fn bm25_idf(doc_freq: f32, total_docs: f32) -> f32 {
((total_docs - doc_freq + 0.5) / (doc_freq + 0.5) + 1.0).ln()
}