# Path: diffprivlib/mechanisms/base.py
# def bernoulli_neg_exp(gamma, rng=None):
#     """Sample from Bernoulli(exp(-gamma)).
# 
#     Adapted from "The Discrete Gaussian for Differential Privacy", Canonne, Kamath, Steinke, 2020.
#     https://arxiv.org/pdf/2004.00010v2.pdf
# 
#     Parameters
#     ----------
#     gamma : float
#         Parameter to sample from Bernoulli(exp(-gamma)).  Must be non-negative.
# 
#     rng : Random number generator, optional
#         Random number generator to use.  If not provided, uses SystemRandom from secrets by default.
# 
#     Returns
#     -------
#     One sample from the Bernoulli(exp(-gamma)) distribution.
# 
#     """
#     if gamma < 0:
#         raise ValueError(f"Gamma must be non-negative, got {gamma}.")
# 
#     if rng is None:
#         rng = secrets.SystemRandom()
# 
#     while gamma > 1:
#         gamma -= 1
#         if not bernoulli_neg_exp(1, rng):
#             return 0
# 
#     counter = 1
# 
#     while rng.random() <= gamma / counter:
#         counter += 1
# 
#     return counter % 2


import secrets
import numpy as np
from unittest import TestCase
from diffprivlib.mechanisms.base import bernoulli_neg_exp

    def teardown_method(self, method):
        del self.rng

    def test_bad_gamma(self):
        self.assertRaises(ValueError, bernoulli_neg_exp, -1)
        self.assertRaises(TypeError, bernoulli_neg_exp, 1j)

    def test_infinite_gamma(self):
        for i in range(1000):
            self.assertEqual(0, bernoulli_neg_exp(float("inf"), self.rng))

    def test_zero_gamma(self):
        for i in range(1000):
            self.assertEqual(1, bernoulli_neg_exp(0, self.rng))

    def test_no_rng(self):
        for i in range(100):
            self.assertIn(bernoulli_neg_exp(1), [0, 1])

    def test_bad_rng(self):
        self.assertRaises(AttributeError, bernoulli_neg_exp, 1, "rng")

    def test_output_domain(self):
        for i in range(1000):
            self.assertIn(bernoulli_neg_exp(1, self.rng), [0, 1])

    def test_bernoulli_exp_prob(self):
        runs = 5000


# Path: diffprivlib/mechanisms/base.py
# def bernoulli_neg_exp(gamma, rng=None):
#     """Sample from Bernoulli(exp(-gamma)).
# 
#     Adapted from "The Discrete Gaussian for Differential Privacy", Canonne, Kamath, Steinke, 2020.
#     https://arxiv.org/pdf/2004.00010v2.pdf
# 
#     Parameters
#     ----------
#     gamma : float
#         Parameter to sample from Bernoulli(exp(-gamma)).  Must be non-negative.
# 
#     rng : Random number generator, optional
#         Random number generator to use.  If not provided, uses SystemRandom from secrets by default.
# 
#     Returns
#     -------
#     One sample from the Bernoulli(exp(-gamma)) distribution.
# 
#     """
#     if gamma < 0:
#         raise ValueError(f"Gamma must be non-negative, got {gamma}.")
# 
#     if rng is None:
#         rng = secrets.SystemRandom()
# 
#     while gamma > 1:
#         gamma -= 1
#         if not bernoulli_neg_exp(1, rng):
#             return 0
# 
#     counter = 1
# 
#     while rng.random() <= gamma / counter:
#         counter += 1
# 
#     return counter % 2


# Path: tests/mechanisms/test_BernoulliNegExp.py
import secrets
import numpy as np
from unittest import TestCase
from diffprivlib.mechanisms.base import bernoulli_neg_exp


    def teardown_method(self, method):
        del self.rng

    def test_bad_gamma(self):
        self.assertRaises(ValueError, bernoulli_neg_exp, -1)
        self.assertRaises(TypeError, bernoulli_neg_exp, 1j)

    def test_infinite_gamma(self):
        for i in range(1000):
            self.assertEqual(0, bernoulli_neg_exp(float("inf"), self.rng))

    def test_zero_gamma(self):
        for i in range(1000):
            self.assertEqual(1, bernoulli_neg_exp(0, self.rng))

    def test_no_rng(self):
        for i in range(100):
            self.assertIn(bernoulli_neg_exp(1), [0, 1])

    def test_bad_rng(self):
        self.assertRaises(AttributeError, bernoulli_neg_exp, 1, "rng")

    def test_output_domain(self):
        for i in range(1000):
            self.assertIn(bernoulli_neg_exp(1, self.rng), [0, 1])

    def test_bernoulli_exp_prob(self):
        runs = 5000


        self.assertAlmostEqual(sum(bernoulli_neg_exp(-np.log(0.5), self.rng) for _ in range(runs)) / runs,