From 3fe6a9aecc06638df4c7ff496a63f34ed779663c Mon Sep 17 00:00:00 2001 From: Yu-Xiang Wang Date: Fri, 23 Jun 2023 09:35:15 -0700 Subject: [PATCH 1/5] removing specified bounds for brents --- autodp/converter.py | 14 ++-- example/example_amplification_by_sampling.py | 6 +- tutorials/tutorial_PATE_with_autoDP.ipynb | 10 +-- tutorials/tutorial_calibrator.ipynb | 8 +-- .../tutorial_fdp_of_basic_mechanisms.ipynb | 2 +- tutorials/tutorial_new_api.ipynb | 65 ++++++++++--------- tutorials/tutorial_online_query_release.ipynb | 4 +- .../tutorial_private_deep_learning.ipynb | 6 +- 8 files changed, 58 insertions(+), 57 deletions(-) diff --git a/autodp/converter.py b/autodp/converter.py index 46621f7..9430dbb 100644 --- a/autodp/converter.py +++ b/autodp/converter.py @@ -92,7 +92,7 @@ def fun(x): # the input the RDP's \alpha result = utils.stable_logsumexp_two(term_1 - np.log(x)- np.log(delta),0) return min(result*1.0/(x - 1), bbghs) - results = minimize_scalar(fun, method='Brent', bracket=(1, 2), bounds=[1, 100000]) + results = minimize_scalar(fun, method='Brent', bracket=(1, 2))#, bounds=[1, 100000]) if results.success: # print('delta', delta,'eps under rdp', results.fun) return results.fun @@ -146,7 +146,7 @@ def fun(x): # the input the RDP's \alpha else: return np.log(1 / delta) / (x - 1) + rdp(x) - results = minimize_scalar(fun, method='Brent', bracket=(1,2), bounds=[1, alpha_max]) + results = minimize_scalar(fun, method='Brent', bracket=(1,2))#, bounds=[1, alpha_max]) if results.success: return results.fun else: @@ -250,7 +250,7 @@ def fun(alpha): return -single_fdp(x) # This will use brent to start with 1,2. - results = minimize_scalar(fun, bracket=(0.5, 2), bounds=(0.5, alpha_max)) + results = minimize_scalar(fun, bracket=(0.5, 2))#, bounds=(0.5, alpha_max)) if results.success: return -results.fun else: @@ -527,7 +527,7 @@ def fun(alpha): return log_one_minus_fdp_alpha(logx) # This will use brent to start with 1,2. - results = minimize_scalar(fun, bracket=(0.5, 2), bounds=(0.5, alpha_max)) + results = minimize_scalar(fun, bracket=(0.5, 2))#, bounds=(0.5, alpha_max)) if results.success: return [results.fun, results.x] else: @@ -720,9 +720,9 @@ def normal_equation_loglogx(loglogx): bound1 = np.log(-tmp - tmp**2 / 2 - tmp**3 / 6) else: bound1 = np.log(1-np.exp(fun1(np.log(1-delta)))) - #results = minimize_scalar(normal_equation, bounds=[-np.inf,0], bracket=[-1,-2]) - results = minimize_scalar(normal_equation, method="Bounded", bounds=[bound1,0], - options={'xatol': 1e-10, 'maxiter': 500, 'disp': 0}) + results = minimize_scalar(normal_equation, bracket=[-1,-2]) + #results = minimize_scalar(normal_equation, method="Bounded", bounds=[bound1,0], + # options={'xatol': 1e-10, 'maxiter': 500, 'disp': 0}) if results.success: if abs(results.fun) > 1e-4 and abs(results.x)>1e-10: # This means that we hit xatol (x is close to 0, but diff --git a/example/example_amplification_by_sampling.py b/example/example_amplification_by_sampling.py index 96f7319..09c269f 100644 --- a/example/example_amplification_by_sampling.py +++ b/example/example_amplification_by_sampling.py @@ -38,9 +38,9 @@ # Now let's do subsampling. First we need to use replace-one version of the base mechanisms. -gm1.replace_one = True -gm2.replace_one = True -SVT.replace_one = True +gm1.neighboring = "replace_one" +gm2.neighboring = "replace_one" +SVT.neighboring = "replace_one" composed_subsampled_mech = compose([subsample(gm1,prob), subsample(gm2,prob), diff --git a/tutorials/tutorial_PATE_with_autoDP.ipynb b/tutorials/tutorial_PATE_with_autoDP.ipynb index 0b575be..843176d 100644 --- a/tutorials/tutorial_PATE_with_autoDP.ipynb +++ b/tutorials/tutorial_PATE_with_autoDP.ipynb @@ -54,7 +54,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "2.2540846502197414 1e-06\n", + "2.2540846502197396 1e-06\n", "4.886554117462211 1e-06\n" ] }, @@ -62,7 +62,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2884: RuntimeWarning: invalid value encountered in scalar divide\n", " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n" ] } @@ -111,8 +111,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "PATE_eps=2 {'sigma': 22.30476293897311} 1.999999977711552\n", - "PATE_eps=0.5 {'sigma': 80.57618519751232} 0.49999999740790046\n" + "PATE_eps=2 {'sigma': 22.304762938973138} 1.9999999777115467\n", + "PATE_eps=0.5 {'sigma': 80.57618519751239} 0.49999999740789647\n" ] } ], @@ -177,7 +177,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/tutorials/tutorial_calibrator.ipynb b/tutorials/tutorial_calibrator.ipynb index 19d691b..810e2c5 100644 --- a/tutorials/tutorial_calibrator.ipynb +++ b/tutorials/tutorial_calibrator.ipynb @@ -33,8 +33,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "GM {'sigma': 36.304688756269286} 0.10000000492560832\n", - "Ana_GM {'sigma': 36.304691899114694} 0.09999999565548537\n" + "GM {'sigma': 36.30468875626822} 0.10000000492561108\n", + "Ana_GM {'sigma': 36.304691899114694} 0.09999999565548348\n" ] } ], @@ -80,7 +80,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2884: RuntimeWarning: invalid value encountered in scalar divide\n", " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n" ] } @@ -307,7 +307,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/tutorials/tutorial_fdp_of_basic_mechanisms.ipynb b/tutorials/tutorial_fdp_of_basic_mechanisms.ipynb index d9de142..d6e3cee 100644 --- a/tutorials/tutorial_fdp_of_basic_mechanisms.ipynb +++ b/tutorials/tutorial_fdp_of_basic_mechanisms.ipynb @@ -321,7 +321,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/tutorials/tutorial_new_api.ipynb b/tutorials/tutorial_new_api.ipynb index 8e24478..60ec276 100644 --- a/tutorials/tutorial_new_api.ipynb +++ b/tutorials/tutorial_new_api.ipynb @@ -62,7 +62,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2884: RuntimeWarning: invalid value encountered in scalar divide\n", " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n" ] } @@ -135,14 +135,14 @@ "Generic composition: epsilon(delta) = 2.1309868424169824 , at delta = 1e-06\n", "Gaussian composition: epsilon(delta) = 1.984273919801572 , at delta = 1e-06\n", "Generic composition: epsilon(delta) = 1.6484258167240666 , at delta = 0.0001\n", - "Gaussian composition: epsilon(delta) = 1.4867384204500818 , at delta = 0.0001\n" + "Gaussian composition: epsilon(delta) = 1.4867384204500813 , at delta = 0.0001\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2884: RuntimeWarning: invalid value encountered in scalar divide\n", " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n" ] } @@ -265,11 +265,11 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2884: RuntimeWarning: invalid value encountered in scalar divide\n", " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n", - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2149: RuntimeWarning: invalid value encountered in double_scalars\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2417: RuntimeWarning: invalid value encountered in scalar multiply\n", " tmp2 = (x - v) * (fx - fw)\n", - "/Users/yuxiangw/Documents/bitbucket/autodp/autodp/autodp_core.py:233: RuntimeWarning: divide by zero encountered in log\n", + "/Users/yuxiangw/Documents/bitbucket/autodp/autodp/autodp_core.py:272: RuntimeWarning: divide by zero encountered in log\n", " fdp = lambda x: 1 - np.exp(fun1(np.log(x)))\n" ] }, @@ -318,15 +318,17 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", - " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n" + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2884: RuntimeWarning: invalid value encountered in scalar divide\n", + " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2417: RuntimeWarning: invalid value encountered in scalar multiply\n", + " tmp2 = (x - v) * (fx - fw)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "[5.298525912188081, 4.728386984943314, 4.7283856025045115, 4.377178095681224, 4.377178095627265, 1.4142111312027956]\n" + "[5.298525912188081, 4.728386984943314, 4.7283856417872805, 4.377178095681228, 4.377178095762625, 1.4142111312027956]\n" ] }, { @@ -406,7 +408,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -436,9 +438,9 @@ "\n", "\n", "# Now let's do subsampling. First we need to use replace-one version of the base mechanisms.\n", - "gm1.replace_one = True\n", - "gm2.replace_one = True\n", - "SVT.replace_one = True\n", + "gm1.neighboring = \"replace_one\"\n", + "gm2.neighboring = \"replace_one\"\n", + "SVT.neighboring = \"replace_one\"\n", "\n", "composed_subsampled_mech = compose([subsample(gm1,prob),\n", " subsample(gm2,prob),\n", @@ -453,17 +455,9 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", - " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n" - ] - }, { "name": "stdout", "output_type": "stream", @@ -482,7 +476,7 @@ "epsilon(delta) = 0.48950668976148426 , at delta = 0.0001\n", "---------------------------------------------------\n", "Mechanism name is \" Compose:{Subsample:GM1: 30, Subsample:GM2: 50, Subsample:SVT: 10} \"\n", - "Parameters are: {'Subsample:GM1:sigma': 5.0, 'Subsample:GM1:PoissonSample': 0.1, 'Subsample:GM1:Subsample': 0.1, 'Subsample:GM2:sigma': 8.0, 'Subsample:GM2:PoissonSample': 0.1, 'Subsample:GM2:Subsample': 0.1, 'Subsample:SVT:eps': 0.1, 'Subsample:SVT:PoissonSample': 0.1, 'Subsample:SVT:Subsample': 0.1}\n", + "Parameters are: {'Subsample:GM1:sigma': 5.0, 'Subsample:GM1:Subsample': 0.1, 'Subsample:GM2:sigma': 8.0, 'Subsample:GM2:Subsample': 0.1, 'Subsample:SVT:eps': 0.1, 'Subsample:SVT:Subsample': 0.1}\n", "epsilon(delta) = 3.161674646617909 , at delta = 1e-06\n", "epsilon(delta) = 2.2643681643522973 , at delta = 0.0001\n", "------- If qualified for the improved bounds --------\n", @@ -549,14 +543,14 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "GM1 {'sigma': 2.904058395116701} 1.4999997486031456\n", + "GM1 {'sigma': 2.904058395116711} 1.4999997486031442\n", "Laplace {'eps': 1.500001569629506} 1.500001346499671\n" ] } @@ -593,7 +587,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -602,7 +596,7 @@ "2.0677358464697515" ] }, - "execution_count": 14, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -624,7 +618,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -650,7 +644,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -686,7 +680,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -748,7 +742,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -769,6 +763,13 @@ "print(online_ngd.get_approxDP(delta))" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, @@ -793,7 +794,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/tutorials/tutorial_online_query_release.ipynb b/tutorials/tutorial_online_query_release.ipynb index b647abb..027b76b 100644 --- a/tutorials/tutorial_online_query_release.ipynb +++ b/tutorials/tutorial_online_query_release.ipynb @@ -57,7 +57,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2884: RuntimeWarning: invalid value encountered in scalar divide\n", " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n" ] }, @@ -212,7 +212,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.16" } }, "nbformat": 4, diff --git a/tutorials/tutorial_private_deep_learning.ipynb b/tutorials/tutorial_private_deep_learning.ipynb index 11f9dde..5c858ae 100644 --- a/tutorials/tutorial_private_deep_learning.ipynb +++ b/tutorials/tutorial_private_deep_learning.ipynb @@ -42,7 +42,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.8/site-packages/scipy/optimize/optimize.py:2555: RuntimeWarning: invalid value encountered in double_scalars\n", + "/usr/local/lib/python3.8/site-packages/scipy/optimize/_optimize.py:2884: RuntimeWarning: invalid value encountered in scalar divide\n", " w = xb - ((xb - xc) * tmp2 - (xb - xa) * tmp1) / denom\n" ] }, @@ -186,7 +186,7 @@ { "data": { "text/plain": [ - "10.997151214220652" + "10.99715121422065" ] }, "execution_count": 3, @@ -383,7 +383,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.16" } }, "nbformat": 4, From e67b8ebbf0045b2ef3dd2747dd76c988f2d62287 Mon Sep 17 00:00:00 2001 From: Yu-Xiang Wang Date: Fri, 23 Jun 2023 10:17:05 -0700 Subject: [PATCH 2/5] fixing find_logx from delta by reintroducing the carefully chosen bounds --- autodp/converter.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autodp/converter.py b/autodp/converter.py index 9430dbb..3c096f5 100644 --- a/autodp/converter.py +++ b/autodp/converter.py @@ -720,9 +720,9 @@ def normal_equation_loglogx(loglogx): bound1 = np.log(-tmp - tmp**2 / 2 - tmp**3 / 6) else: bound1 = np.log(1-np.exp(fun1(np.log(1-delta)))) - results = minimize_scalar(normal_equation, bracket=[-1,-2]) - #results = minimize_scalar(normal_equation, method="Bounded", bounds=[bound1,0], - # options={'xatol': 1e-10, 'maxiter': 500, 'disp': 0}) + #results = minimize_scalar(normal_equation, bracket=[-1,-2]) + results = minimize_scalar(normal_equation, method="Bounded", bounds=[bound1,0], + options={'xatol': 1e-10, 'maxiter': 500, 'disp': 0}) if results.success: if abs(results.fun) > 1e-4 and abs(results.x)>1e-10: # This means that we hit xatol (x is close to 0, but From 827eb2bac1df26d33905af57af0a7922d54fb636 Mon Sep 17 00:00:00 2001 From: Yu-Xiang Wang Date: Fri, 22 Sep 2023 01:06:38 -0700 Subject: [PATCH 3/5] adding the closed-form rdp2delta implementation --- autodp/autodp_core.py | 5 ++- autodp/converter.py | 94 +++++++++++++++++++++++++------------------ 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/autodp/autodp_core.py b/autodp/autodp_core.py index b2577a0..c564e9f 100644 --- a/autodp/autodp_core.py +++ b/autodp/autodp_core.py @@ -200,7 +200,6 @@ def approx_dp_func(delta1): elif type_of_update == 'RDP': # function output RDP eps as a function of alpha self.RenyiDP = converter.pointwise_minimum(self.RenyiDP, func) - self.approx_delta = converter.pointwise_minimum(self.approx_delta, converter.rdp_to_delta(self.RenyiDP)) if fDP_based_conversion: fdp_log, fdp_grad_log = converter.rdp_to_fdp_and_fdp_grad_log(func) @@ -234,12 +233,16 @@ def approx_dp_func(delta1): converter.fdp_fdp_grad_to_approxdp( fdp_log, fdp_grad_log, log_flag=True)) + self.approx_delta = converter.pointwise_minimum(self.approx_delta, + converter.rdp_to_delta(self.RenyiDP, BBGHS_conversion=BBGHS_conversion)) # self.approxDP = converter.pointwise_minimum(self.approxDP, # converter.fdp_to_approxdp(self.fDP)) else: self.approxDP = converter.pointwise_minimum(self.approxDP, converter.rdp_to_approxdp(self.RenyiDP, BBGHS_conversion=BBGHS_conversion)) + self.approx_delta = converter.pointwise_minimum(self.approx_delta, + converter.rdp_to_delta(self.RenyiDP, BBGHS_conversion=BBGHS_conversion)) self.fDP = converter.pointwise_maximum(self.fDP, converter.approxdp_func_to_fdp( self.approxDP)) diff --git a/autodp/converter.py b/autodp/converter.py index 3c096f5..bd740f6 100644 --- a/autodp/converter.py +++ b/autodp/converter.py @@ -60,7 +60,7 @@ def approxdp(delta): return approxdp -def rdp_to_delta(rdp): +def rdp_to_delta(rdp, BBGHS_conversion=True): """ from RDP to delta with a fixed epsilon """ @@ -70,48 +70,64 @@ def approx_delta(eps, naive=False): """ approximate delta as a function of epsilon """ - - def get_eps(delta): - if delta == 0: - return rdp(np.inf) + def get_delta(alpha): + if BBGHS_conversion: + # Also by Canonne et al., 2020 + return np.minimum( + (np.exp((alpha-1)*(rdp(alpha)-eps))/alpha)*((1-1/alpha)**(alpha-1)), 1.0) else: - def fun(x): # the input the RDP's \alpha - if x <= 1: - return np.inf - else: - - if naive: - return np.log(1 / delta) / (x - 1) + rdp(x) - bbghs = np.maximum(rdp(x) + np.log((x-1)/x) - - (np.log(delta) + np.log(x))/(x-1), 0) - """ - The following is for optimal conversion - 1/(alpha -1 )log(e^{(alpha-1)*rdp -1}/(alpha*delta) +1 ) - """ - sign, term_1= utils.stable_log_diff_exp((x-1)*rdp(x),0) - result = utils.stable_logsumexp_two(term_1 - np.log(x)- np.log(delta),0) - return min(result*1.0/(x - 1), bbghs) - - results = minimize_scalar(fun, method='Brent', bracket=(1, 2))#, bounds=[1, 100000]) - if results.success: - # print('delta', delta,'eps under rdp', results.fun) - return results.fun - else: - return np.inf + # Naive conversion from Mironov + return np.minimum(np.exp((alpha-1)*(rdp(alpha)-eps)),1.0) - - def err(delta): - current_eps = get_eps(delta) - #print('current delta', delta, 'eps', current_eps) - return abs(eps - current_eps) - - results = minimize_scalar(err, method='bounded', bounds=[0, 0.1],options={'xatol':1e-14}) + results = minimize_scalar(get_delta, method = 'Brent', bracket=(1,2)) if results.success: - #print('results', results.x) - return results.x + # print('delta', delta,'eps under rdp', results.fun) + return results.fun else: print('not found') - return 1 + return 1.0 + + # def get_eps(delta): + # if delta == 0: + # return rdp(np.inf) + # else: + # def fun(x): # the input the RDP's \alpha + # if x <= 1: + # return np.inf + # else: + # + # if naive: + # return np.log(1 / delta) / (x - 1) + rdp(x) + # bbghs = np.maximum(rdp(x) + np.log((x-1)/x) + # - (np.log(delta) + np.log(x))/(x-1), 0) + # """ + # The following is for optimal conversion + # 1/(alpha -1 )log(e^{(alpha-1)*rdp -1}/(alpha*delta) +1 ) + # """ + # sign, term_1= utils.stable_log_diff_exp((x-1)*rdp(x),0) + # result = utils.stable_logsumexp_two(term_1 - np.log(x)- np.log(delta),0) + # return min(result*1.0/(x - 1), bbghs) + # + # results = minimize_scalar(fun, method='Brent', bracket=(1, 2))#, bounds=[1, 100000]) + # if results.success: + # # print('delta', delta,'eps under rdp', results.fun) + # return results.fun + # else: + # return np.inf + # + # + # def err(delta): + # current_eps = get_eps(delta) + # #print('current delta', delta, 'eps', current_eps) + # return abs(eps - current_eps) + # + # results = minimize_scalar(err, method='bounded', bounds=[0, 0.1],options={'xatol':1e-14}) + # if results.success: + # #print('results', results.x) + # return results.x + # else: + # print('not found') + # return 1 return approx_delta @@ -244,7 +260,7 @@ def fdp(x): def fun(alpha): if alpha < 0.5: - return np.inf + return 0 else: single_fdp = single_rdp_to_fdp(alpha, rdp(alpha)) return -single_fdp(x) From 12390bd85d201d1e71868559e48f56161274923f Mon Sep 17 00:00:00 2001 From: Yu-Xiang Wang Date: Fri, 3 Nov 2023 14:57:45 -0700 Subject: [PATCH 4/5] fixing naming convention and its use in GaussianSVT --- autodp/dp_bank.py | 2 +- autodp/mechanism_zoo.py | 2 +- setup.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/autodp/dp_bank.py b/autodp/dp_bank.py index 4fbcbaf..d4a1f1e 100644 --- a/autodp/dp_bank.py +++ b/autodp/dp_bank.py @@ -85,7 +85,7 @@ def fun(x): else: raise RuntimeError(f"Failed to find epsilon: {results.flag}") -def eps_generalized_gaussian(x, sigma, delta,k, c, c_tilde): +def get_eps_gaussian_svt(x, sigma, delta, k, c, c_tilde): """ submodule for generalized SVT with Gaussian noise we want to partition c into [c/c'] parts, each part using (k choose c') diff --git a/autodp/mechanism_zoo.py b/autodp/mechanism_zoo.py index f0f1725..e03a61f 100644 --- a/autodp/mechanism_zoo.py +++ b/autodp/mechanism_zoo.py @@ -431,7 +431,7 @@ def __init__(self, params=None,approxDP_off=False, name='StageWiseMechanism'): self.delta0 = 0 if not approxDP_off: # Direct implementation of approxDP - new_approxdp = lambda x: dp_bank.get_generalized_gaussian(params, x) + new_approxdp = lambda x: dp_bank.get_gaussian_svt(params, x) self.propagate_updates(new_approxdp, 'approxDP_func') diff --git a/setup.py b/setup.py index a264b39..83d35b1 100644 --- a/setup.py +++ b/setup.py @@ -18,14 +18,14 @@ def _parse_requirements(path): setup( name='autodp', - version='0.2.1b', + version='0.2.3', description='Automating Differential Privacy Computation', license="Apache", long_description="The package helps researchers and developers to correctly use advanced methods in differential privacy and obtain provable DP guarantees. The core of the package is an analytical moments accountant that keeps track of Renyi Differential Privacy in analytical forms.", author='Yu-Xiang Wang', author_email='yuxiangw@cs.ucsb.edu', url='https://github.com/yuxiangw/autodp', - download_url = 'https://github.com/yuxiangw/autodp/archive/refs/tags/v0.2.1b.tar.gz', + download_url = 'https://github.com/yuxiangw/autodp/archive/refs/tags/v0.2.3.tar.gz', keywords = ['Differential Privacy','Moments Accountant','Renyi Differential Privacy'], packages=['autodp'], #same as name install_requires=[_parse_requirements('requirements.txt')], #external packages as dependencies From 0abd50c52ff5062d16ac75b2a54628928af90d49 Mon Sep 17 00:00:00 2001 From: Yu-Xiang Wang Date: Fri, 3 Nov 2023 15:03:49 -0700 Subject: [PATCH 5/5] fixing function names --- autodp/mechanism_zoo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autodp/mechanism_zoo.py b/autodp/mechanism_zoo.py index e03a61f..af008eb 100644 --- a/autodp/mechanism_zoo.py +++ b/autodp/mechanism_zoo.py @@ -431,7 +431,7 @@ def __init__(self, params=None,approxDP_off=False, name='StageWiseMechanism'): self.delta0 = 0 if not approxDP_off: # Direct implementation of approxDP - new_approxdp = lambda x: dp_bank.get_gaussian_svt(params, x) + new_approxdp = lambda x: dp_bank.get_eps_gaussian_svt(params, x) self.propagate_updates(new_approxdp, 'approxDP_func')