///|
pub(all) struct Sensitivity {
queries : Array[Double]
lower : Array[Double]
median : Array[Double]
upper : Array[Double]
fits : Int
} derive(Debug)
///|
/// Explicit resampling plans only. No random-number generation or confidence-level claim.
pub fn resample_sensitivity(
samples : Array[Sample],
plans : Array[Array[Int]],
queries : Array[Double],
lower_tau? : Double = 0.1,
upper_tau? : Double = 0.9,
loss? : Loss = Squared,
direction? : Direction = Increasing,
) -> Result[Sensitivity, String] {
match validate_samples(samples) {
Err(e) => return Err(e)
Ok(_) => ()
}
if plans.length() == 0 ||
plans.length() > 200 ||
queries.length() == 0 ||
queries.length() > 10000 {
return Err("sensitivity budget exceeded")
}
if !finite(lower_tau) ||
!finite(upper_tau) ||
lower_tau < 0.0 ||
upper_tau > 1.0 ||
lower_tau > 0.5 ||
upper_tau < 0.5 {
return Err("invalid sensitivity quantiles")
}
let predictions : Array[Array[Double]] = []
let mut entries = 0
for plan in plans {
if plan.length() == 0 || plan.length() > 1000000 - entries {
return Err("resample row budget exceeded")
}
entries = entries + plan.length()
let rows = []
for index in plan {
if index < 0 || index >= samples.length() {
return Err("resample index outside dataset")
}
rows.push(samples[index])
}
let model = match train(rows, loss~, direction~) {
Err(e) => return Err(e)
Ok(v) => v
}
let values = match predict_many(model, queries) {
Err(e) => return Err(e)
Ok(v) => v
}
predictions.push(values)
}
let lower = []
let median = []
let upper = []
let weights = Array::make(plans.length(), 1.0)
for i = 0; i < queries.length(); i = i + 1 {
let values = predictions.map(fn(row) { row[i] })
match weighted_quantile(values, weights, lower_tau) {
Err(e) => return Err(e)
Ok(v) => lower.push(v)
}
match weighted_quantile(values, weights, 0.5) {
Err(e) => return Err(e)
Ok(v) => median.push(v)
}
match weighted_quantile(values, weights, upper_tau) {
Err(e) => return Err(e)
Ok(v) => upper.push(v)
}
}
Ok({ queries: queries.copy(), lower, median, upper, fits: plans.length(), })
}
///|
#deprecated
pub extend Sensitivity with @debug.Debug::{to_repr}