def test_convolve_dictionary(self): dictionary1 = {1: 2, 3: 4} dictionary2 = {2: 3, 4: 6} expected_result = {3: 6, 5: 24, 7: 24} result = privacy_loss_distribution.convolve_dictionary( dictionary1, dictionary2) test_util.dictionary_almost_equal(self, expected_result, result)
def test_laplace_discretization( self, value_discretization_interval, expected_rounded_probability_mass_function): pld = privacy_loss_distribution.PrivacyLossDistribution.from_laplace_mechanism( 1, value_discretization_interval=value_discretization_interval) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_laplace_optimistic(self, sensitivity, expected_rounded_probability_mass_function): pld = privacy_loss_distribution.PrivacyLossDistribution.from_laplace_mechanism( 1, sensitivity=sensitivity, pessimistic_estimate=False, value_discretization_interval=1) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_discrete_laplace_varying_standard_deviation_and_sensitivity( self, parameter, sensitivity, expected_rounded_probability_mass_function): pld = privacy_loss_distribution.PrivacyLossDistribution.from_discrete_laplace_mechanism( parameter, sensitivity=sensitivity, value_discretization_interval=1) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_discrete_gaussian_truncation( self, truncation_bound, expected_rounded_probability_mass_function, expected_infinity_mass): pld = (privacy_loss_distribution.PrivacyLossDistribution. from_discrete_gaussian_mechanism( 1, truncation_bound=truncation_bound)) self.assertAlmostEqual(pld.infinity_mass, expected_infinity_mass) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_gaussian_discretization( self, value_discretization_interval, expected_rounded_probability_mass_function): pld = privacy_loss_distribution.PrivacyLossDistribution.from_gaussian_mechanism( 1, log_mass_truncation_bound=math.log(2) + stats.norm.logcdf(-0.9), value_discretization_interval=value_discretization_interval) self.assertAlmostEqual(stats.norm.cdf(-0.9), pld.infinity_mass) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_randomized_response_basic( self, noise_parameter, num_buckets, expected_rounded_probability_mass_function): # Set value_discretization_interval = 1 here. pld = (privacy_loss_distribution.PrivacyLossDistribution. from_randomized_response(noise_parameter, num_buckets, value_discretization_interval=1)) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_from_privacy_parameters( self, epsilon, delta, value_discretization_interval, expected_rounded_probability_mass_function, expected_infinity_mass): pld = privacy_loss_distribution.PrivacyLossDistribution.from_privacy_parameters( common.DifferentialPrivacyParameters(epsilon, delta), value_discretization_interval=value_discretization_interval) self.assertAlmostEqual(expected_infinity_mass, pld.infinity_mass) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_gaussian_varying_standard_deviation_and_sensitivity( self, standard_deviation, sensitivity, expected_rounded_probability_mass_function): pld = privacy_loss_distribution.PrivacyLossDistribution.from_gaussian_mechanism( standard_deviation, sensitivity=sensitivity, log_mass_truncation_bound=math.log(2) + stats.norm.logcdf(-0.9), value_discretization_interval=1) self.assertAlmostEqual(stats.norm.cdf(-0.9), pld.infinity_mass) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_gaussian_optimistic(self, sensitivity, expected_rounded_probability_mass_function): pld = privacy_loss_distribution.PrivacyLossDistribution.from_gaussian_mechanism( 1, sensitivity=sensitivity, pessimistic_estimate=False, log_mass_truncation_bound=math.log(2) + stats.norm.logcdf(-0.9), value_discretization_interval=1) self.assertAlmostEqual(0, pld.infinity_mass) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_discrete_gaussian_varying_sigma_and_sensitivity( self, sigma, sensitivity, expected_rounded_probability_mass_function, expected_infinity_mass): pld = (privacy_loss_distribution.PrivacyLossDistribution. from_discrete_gaussian_mechanism(sigma, sensitivity=sensitivity, truncation_bound=1)) self.assertAlmostEqual(pld.infinity_mass, expected_infinity_mass) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_discrete_laplace_privacy_loss_tail( self, parameter, sensitivity, expected_lower_x_truncation, expected_upper_x_truncation, expected_tail_probability_mass_function): pl = privacy_loss_mechanism.DiscreteLaplacePrivacyLoss( parameter, sensitivity=sensitivity) tail_pld = pl.privacy_loss_tail() self.assertAlmostEqual(expected_lower_x_truncation, tail_pld.lower_x_truncation) self.assertAlmostEqual(expected_upper_x_truncation, tail_pld.upper_x_truncation) test_util.dictionary_almost_equal(self, expected_tail_probability_mass_function, tail_pld.tail_probability_mass_function)
def test_discrete_gaussian_privacy_loss_tail( self, sigma, sensitivity, truncation_bound, expected_lower_x_truncation, expected_upper_x_truncation, expected_tail_probability_mass_function): pl = privacy_loss_mechanism.DiscreteGaussianPrivacyLoss( sigma, sensitivity=sensitivity, truncation_bound=truncation_bound) tail_pld = pl.privacy_loss_tail() self.assertAlmostEqual(expected_lower_x_truncation, tail_pld.lower_x_truncation) self.assertAlmostEqual(expected_upper_x_truncation, tail_pld.upper_x_truncation) test_util.dictionary_almost_equal(self, expected_tail_probability_mass_function, tail_pld.tail_probability_mass_function)
def test_self_convolve_dictionary(self): inp_dictionary = {1: 2, 3: 5, 4: 6} expected_result = { 3: 8, 5: 60, 6: 72, 7: 150, 8: 360, 9: 341, 10: 450, 11: 540, 12: 216 } result = common.self_convolve_dictionary(inp_dictionary, 3) test_util.dictionary_almost_equal(self, expected_result, result)
def test_randomized_response_discretization( self, value_discretization_interval, expected_rounded_probability_mass_function): # Set noise_parameter = 0.2, num_buckets = 4 here. # The true (non-discretized) PLD is # {2.83321334: 0.85, -2.83321334: 0.05, 0: 0.1}. pld = ( privacy_loss_distribution.PrivacyLossDistribution. from_randomized_response( 0.2, 4, value_discretization_interval=value_discretization_interval)) test_util.dictionary_almost_equal( self, expected_rounded_probability_mass_function, pld.rounded_probability_mass_function)
def test_gaussian_privacy_loss_tail( self, standard_deviation, sensitivity, expected_lower_x_truncation, expected_upper_x_truncation, pessimistic_estimate, expected_tail_probability_mass_function): pl = privacy_loss_mechanism.GaussianPrivacyLoss( standard_deviation, sensitivity=sensitivity, pessimistic_estimate=pessimistic_estimate, log_mass_truncation_bound=math.log(2) + stats.norm.logcdf(-1)) tail_pld = pl.privacy_loss_tail() self.assertAlmostEqual(expected_lower_x_truncation, tail_pld.lower_x_truncation) self.assertAlmostEqual(expected_upper_x_truncation, tail_pld.upper_x_truncation) test_util.dictionary_almost_equal( self, expected_tail_probability_mass_function, tail_pld.tail_probability_mass_function)
def test_identity(self): pld = privacy_loss_distribution.PrivacyLossDistribution.identity() test_util.dictionary_almost_equal( self, pld.rounded_probability_mass_function, {0: 1}) self.assertAlmostEqual(pld.infinity_mass, 0) pld = pld.compose( privacy_loss_distribution.PrivacyLossDistribution({ 1: 0.5, -1: 0.5 }, 1e-4, 0)) test_util.dictionary_almost_equal( self, pld.rounded_probability_mass_function, { 1: 0.5, -1: 0.5 }) self.assertAlmostEqual(pld.infinity_mass, 0)
def test_composition_with_truncation(self): pld1 = privacy_loss_distribution.PrivacyLossDistribution( { 0: 0.1, 1: 0.7, 2: 0.1 }, 1, 0.1) pld2 = privacy_loss_distribution.PrivacyLossDistribution( { 0: 0.1, 1: 0.6, 2: 0.2 }, 1, 0.1) pld_composed = pld1.compose(pld2, tail_mass_truncation=0.021) self.assertAlmostEqual(pld_composed.infinity_mass, 0.211) test_util.dictionary_almost_equal( self, { 1: 0.13, 2: 0.45, 3: 0.20, 4: 0.02, }, pld_composed.rounded_probability_mass_function)
def test_list_to_dict_truncation(self, input_list, offset, tail_mass_truncation, expected_result): result = common.list_to_dictionary( input_list, offset, tail_mass_truncation=tail_mass_truncation) test_util.dictionary_almost_equal(self, expected_result, result)
def test_convolve_dictionary_with_truncation(self): dictionary1 = {1: 0.4, 2: 0.6} dictionary2 = {1: 0.7, 3: 0.3} expected_result = {3: 0.42, 4: 0.12} result = common.convolve_dictionary(dictionary1, dictionary2, 0.57) test_util.dictionary_almost_equal(self, expected_result, result)