@@ -1045,5 +1045,110 @@ def is_monotonic(self) -> bool:
10451045 self .assertSetEqual (chosen_values , {0 , 1 })
10461046
10471047
1048+ class ComputeDpQuantilesTest (parameterized .TestCase ):
1049+
1050+ def test_compute_dp_quantiles_std_dev_set_laplace (self ):
1051+ # Arrange
1052+ mock_tree = MagicMock ()
1053+ mock_tree .compute_quantiles .return_value = [10.0 , 20.0 ]
1054+
1055+ spec = budget_accounting .MechanismSpec (
1056+ aggregate_params .MechanismType .LAPLACE )
1057+ spec .set_noise_standard_deviation (2.0 )
1058+
1059+ quantiles = [0.5 , 0.9 ]
1060+ max_partitions = 5
1061+ max_contributions = 2
1062+
1063+ # Act
1064+ result = dp_computations .compute_dp_quantiles (
1065+ quantile_tree = mock_tree ,
1066+ mechanism_spec = spec ,
1067+ quantiles_to_compute = quantiles ,
1068+ max_partitions_contributed = max_partitions ,
1069+ max_contributions_per_partition = max_contributions ,
1070+ )
1071+
1072+ # Assert
1073+ expected_eps = np .sqrt (2 ) / 2.0
1074+ mock_tree .compute_quantiles .assert_called_once_with (
1075+ epsilon = expected_eps ,
1076+ delta = 0.0 ,
1077+ max_partitions_contributed = max_partitions ,
1078+ max_contributions_per_partition = max_contributions ,
1079+ quantiles = quantiles ,
1080+ noise_type = "laplace" ,
1081+ )
1082+ self .assertEqual (result , [10.0 , 20.0 ])
1083+
1084+ def test_compute_dp_quantiles_std_dev_set_gaussian (self ):
1085+ # Arrange
1086+ mock_tree = MagicMock ()
1087+ mock_tree .compute_quantiles .return_value = [10.0 , 20.0 ]
1088+
1089+ spec = budget_accounting .MechanismSpec (
1090+ aggregate_params .MechanismType .GAUSSIAN )
1091+ spec .set_noise_standard_deviation (2.0 )
1092+
1093+ quantiles = [0.5 , 0.9 ]
1094+ max_partitions = 5
1095+ max_contributions = 2
1096+
1097+ # Act
1098+ result = dp_computations .compute_dp_quantiles (
1099+ quantile_tree = mock_tree ,
1100+ mechanism_spec = spec ,
1101+ quantiles_to_compute = quantiles ,
1102+ max_partitions_contributed = max_partitions ,
1103+ max_contributions_per_partition = max_contributions ,
1104+ )
1105+
1106+ # Assert
1107+ expected_eps = 1.0
1108+ expected_delta = dp_computations .gaussian_delta (2.0 , 1.0 )
1109+ mock_tree .compute_quantiles .assert_called_once_with (
1110+ epsilon = expected_eps ,
1111+ delta = expected_delta ,
1112+ max_partitions_contributed = max_partitions ,
1113+ max_contributions_per_partition = max_contributions ,
1114+ quantiles = quantiles ,
1115+ noise_type = "gaussian" ,
1116+ )
1117+ self .assertEqual (result , [10.0 , 20.0 ])
1118+
1119+ def test_compute_dp_quantiles_std_dev_not_set_gaussian (self ):
1120+ # Arrange
1121+ mock_tree = MagicMock ()
1122+ mock_tree .compute_quantiles .return_value = [10.0 , 20.0 ]
1123+
1124+ spec = budget_accounting .MechanismSpec (
1125+ aggregate_params .MechanismType .GAUSSIAN )
1126+ spec .set_eps_delta (1.0 , 1e-5 )
1127+
1128+ quantiles = [0.5 , 0.9 ]
1129+ max_partitions = 5
1130+ max_contributions = 2
1131+
1132+ # Act
1133+ result = dp_computations .compute_dp_quantiles (
1134+ quantile_tree = mock_tree ,
1135+ mechanism_spec = spec ,
1136+ quantiles_to_compute = quantiles ,
1137+ max_partitions_contributed = max_partitions ,
1138+ max_contributions_per_partition = max_contributions ,
1139+ )
1140+
1141+ # Assert
1142+ mock_tree .compute_quantiles .assert_called_once_with (
1143+ epsilon = 1.0 ,
1144+ delta = 1e-5 ,
1145+ max_partitions_contributed = max_partitions ,
1146+ max_contributions_per_partition = max_contributions ,
1147+ quantiles = quantiles ,
1148+ noise_type = "gaussian" ,
1149+ )
1150+ self .assertEqual (result , [10.0 , 20.0 ])
1151+
1152+
10481153if __name__ == '__main__' :
10491154 absltest .main ()
0 commit comments