///|
/// Policy ranking entry with estimated incremental value.
pub struct PolicyRankEntry {
index : Int
score : Double
treatment_effect : Double
selected : Bool
cumulative_value : Double
}
///|
/// Policy ranking summary.
pub struct PolicyRanking {
entries : Array[PolicyRankEntry]
selected_count : Int
selected_fraction : Double
total_value : Double
average_value : Double
passes : Bool
}
///|
/// Ranks units by an estimated individualized effect.
pub fn rank_by_effect(
effects : Array[Double],
costs? : Array[Double] = [],
budget? : Double = 1.0e300,
) -> PolicyRanking {
let order : Array[Int] = Array::new(capacity=effects.length())
for i in 0.. 0 && effects[order[cursor - 1]] < effects[value] {
order[cursor] = order[cursor - 1]
cursor -= 1
}
order[cursor] = value
}
let entries : Array[PolicyRankEntry] = Array::new(capacity=effects.length())
let mut cumulative = 0.0
let mut selected = 0
for position in 0.. Array[Array[Double]] {
let result : Array[Array[Double]] = Array::new(
capacity=ranking.entries.length(),
)
for i in 0.. Double {
let n = effects.length().min(selected.length())
let selected_values = Array::new()
let oracle = effects[:n].to_owned()
for i in 0.. 0 && oracle[cursor - 1] < value {
oracle[cursor] = oracle[cursor - 1]
cursor -= 1
}
oracle[cursor] = value
}
let oracle_total = sum(oracle[:selected_values.length()].to_owned())
oracle_total - sum(selected_values)
}
///|
/// Applies a minimum-effect policy constraint.
pub fn select_effect_threshold(
effects : Array[Double],
threshold : Double,
) -> Array[Bool] {
let result = Array::new(capacity=effects.length())
for effect in effects {
result.push(effect >= threshold)
}
result
}
///|
/// Computes treatment-rate disparity across integer groups.
pub fn policy_group_rates(
groups : Array[Int],
selected : Array[Bool],
) -> Array[Array[Double]] {
let n = groups.length().min(selected.length())
let unique : Array[Int] = Array::new()
for group in groups[:n] {
if !unique.contains(group) {
unique.push(group)
}
}
let result : Array[Array[Double]] = Array::new(capacity=unique.length())
for group in unique {
let mut count = 0
let mut treated = 0
for i in 0.. Array[Bool] {
let n = effects.length().min(groups.length())
let result = Array::make(n, false)
let rates = policy_group_rates(groups[:n].to_owned(), Array::make(n, true))
for rate in rates {
let group = rate[0].to_int()
let candidates : Array[Int] = Array::new()
for i in 0.. 0 && effects[candidates[cursor - 1]] < effects[value] {
candidates[cursor] = candidates[cursor - 1]
cursor -= 1
}
candidates[cursor] = value
}
let take = (candidates.length().to_double() * clamp(target_rate, 0.0, 1.0))
.round()
.to_int()
for i in 0.. Array[Double] {
[
ranking.entries.length().to_double(),
ranking.selected_count.to_double(),
ranking.selected_fraction,
ranking.total_value,
ranking.average_value,
if ranking.passes {
1.0
} else {
0.0
},
]
}