pub struct TermScorer { /* private fields */ }Expand description
One term’s scoring constants, hoisted out of the per-posting loop.
idf costs a ln() and avgdl costs a division, and neither depends on
the document being scored. Computing them once per (term, query) instead
of once per posting is the whole purpose of this type.
§Bit-exactness is by construction
term_score is implemented as TermScorer::new(..).score(..), so
there is exactly one expression tree and one rounding order in the
engine. Pre-multiplying idf * (k1 + 1) would be the obvious next
saving and is deliberately refused: floating-point multiplication is not
associative, so it moves scores by an ULP, and an ULP is a changed
ranking and a changed published nDCG record.
Implementations§
Source§impl TermScorer
impl TermScorer
Sourcepub fn new(df: Df, stats: &CorpusStats, params: Bm25Params) -> Self
pub fn new(df: Df, stats: &CorpusStats, params: Bm25Params) -> Self
Builds the constants for one term against one corpus.
Sourcepub fn score(&self, tf: Tf, length: DocLen) -> f64
pub fn score(&self, tf: Tf, length: DocLen) -> f64
Scores this term against one document.
idf * (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * len / avgdl)).
Returns zero when tf is zero, so a term absent from a document
contributes nothing rather than a length-only artefact.
Sourcepub fn ceiling(&self) -> f64
pub fn ceiling(&self) -> f64
The largest score this term can contribute to any document.
The term-frequency factor saturates at k1 + 1 as tf grows without
bound, and the length normalization is smallest for the shortest
document, so the ceiling is idf * (k1 + 1). Any real score is
strictly below it.