entrenar/optim/dp/
utils.rs1use super::accountant::RdpAccountant;
4
5pub fn estimate_noise_multiplier(
10 target_epsilon: f64,
11 delta: f64,
12 dataset_size: usize,
13 batch_size: usize,
14 epochs: usize,
15) -> f64 {
16 if target_epsilon <= 0.0 || delta <= 0.0 {
17 return f64::INFINITY;
18 }
19
20 let sample_rate = batch_size as f64 / dataset_size as f64;
21 let steps = (epochs * dataset_size) / batch_size;
22
23 let mut low = 0.1;
25 let mut high = 100.0;
26
27 for _ in 0..100 {
28 let mid = f64::midpoint(low, high);
29
30 let mut accountant = RdpAccountant::new();
32 for _ in 0..steps {
33 accountant.step(mid, sample_rate);
34 }
35
36 let (epsilon, _) = accountant.get_privacy_spent(delta);
37
38 if epsilon < target_epsilon {
39 high = mid;
40 } else {
41 low = mid;
42 }
43
44 if (high - low) < 0.01 {
45 break;
46 }
47 }
48
49 high * 1.1 }
51
52pub fn privacy_cost_per_step(noise_multiplier: f64, sample_rate: f64, delta: f64) -> f64 {
54 let mut accountant = RdpAccountant::new();
55 accountant.step(noise_multiplier, sample_rate);
56 accountant.get_privacy_spent(delta).0
57}