///|
pub fn profile_candidate_pools(
pools : Array[CandidatePool],
) -> CandidatePoolProfile {
let unique : Map[String, Unit] = Map([])
let mut total = 0
let mut duplicates = 0
let mut minimum = 0
let mut maximum = 0
for pool_index, pool in pools {
let seen_in_pool : Map[String, Unit] = Map([])
total += pool.doc_ids.length()
if pool_index == 0 || pool.doc_ids.length() < minimum {
minimum = pool.doc_ids.length()
}
if pool.doc_ids.length() > maximum {
maximum = pool.doc_ids.length()
}
for doc_id in pool.doc_ids {
if seen_in_pool.contains(doc_id) {
duplicates += 1
} else {
seen_in_pool[doc_id] = ()
}
unique["\{pool.query_id}:\{doc_id}"] = ()
}
}
{
pool_count: pools.length(),
total_candidate_count: total,
unique_candidate_count: unique.length(),
duplicate_candidate_count: duplicates,
mean_pool_size: if pools.is_empty() {
0.0
} else {
Double::from_int(total) / Double::from_int(pools.length())
},
min_pool_size: minimum,
max_pool_size: maximum,
}
}
///|
pub fn candidate_pool_coverage(
qrels : Array[JudgedDoc],
pools : Array[CandidatePool],
) -> Double {
let relevant : Map[String, Unit] = Map([])
for item in qrels {
if item.relevance > 0 {
relevant["\{item.query_id}:\{item.doc_id}"] = ()
}
}
if relevant.is_empty() {
return 0.0
}
let covered : Map[String, Unit] = Map([])
for pool in pools {
for doc_id in pool.doc_ids {
let key = "\{pool.query_id}:\{doc_id}"
if relevant.contains(key) {
covered[key] = ()
}
}
}
to_ratio(covered.length(), relevant.length())
}
///|
pub fn merge_candidate_pools(
left : Array[CandidatePool],
right : Array[CandidatePool],
) -> Array[CandidatePool] {
let merged : Map[String, Array[String]] = Map([])
for pool in left {
let docs = merged.get_or_init(pool.query_id, fn() { [] })
for doc_id in pool.doc_ids {
if !docs.contains(doc_id) {
docs.push(doc_id)
}
}
}
for pool in right {
let docs = merged.get_or_init(pool.query_id, fn() { [] })
for doc_id in pool.doc_ids {
if !docs.contains(doc_id) {
docs.push(doc_id)
}
}
}
let result : Array[CandidatePool] = []
for query_id, doc_ids in merged {
doc_ids.sort()
result.push({ query_id, doc_ids })
}
result.sort_by(fn(a, b) { a.query_id.compare(b.query_id) })
result
}