From c1bee6353b6b3cf2ef54c9f3042d60d008c99aa3 Mon Sep 17 00:00:00 2001 From: Saksham Date: Wed, 3 Jun 2020 17:54:06 +0530 Subject: [PATCH 1/8] utils bindings --- src/bindings/PyDP/algorithms/util.cpp | 3 +++ tests/algorithms/test_util.py | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 tests/algorithms/test_util.py diff --git a/src/bindings/PyDP/algorithms/util.cpp b/src/bindings/PyDP/algorithms/util.cpp index ae81dc27..7883d4c2 100644 --- a/src/bindings/PyDP/algorithms/util.cpp +++ b/src/bindings/PyDP/algorithms/util.cpp @@ -1,6 +1,7 @@ // Provides bindings for Util #include "pybind11/pybind11.h" +#include #include "differential_privacy/algorithms/util.h" @@ -14,4 +15,6 @@ void init_algorithms_util(py::module& m) { util.def("default_epsilon", &dp::DefaultEpsilon); util.def("get_next_power_of_two", &dp::GetNextPowerOfTwo); util.def("qnorm", &dp::Qnorm); + util.def("mean",&dp::Mean); + // util.def("hello", &dp:: ) } diff --git a/tests/algorithms/test_util.py b/tests/algorithms/test_util.py new file mode 100644 index 00000000..2c14199a --- /dev/null +++ b/tests/algorithms/test_util.py @@ -0,0 +1,6 @@ +import pytest +import pydp as dp + +def test_mean (): + a = [1,2,4,6.0,8] + assert dp.util.mean(a) == 4.2 \ No newline at end of file From 184ef44e224a2bfc6994d8144a1efaba18a67570 Mon Sep 17 00:00:00 2001 From: Saksham Date: Wed, 3 Jun 2020 17:55:11 +0530 Subject: [PATCH 2/8] style fix --- tests/algorithms/test_util.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/algorithms/test_util.py b/tests/algorithms/test_util.py index 2c14199a..02a67733 100644 --- a/tests/algorithms/test_util.py +++ b/tests/algorithms/test_util.py @@ -1,6 +1,7 @@ import pytest import pydp as dp -def test_mean (): - a = [1,2,4,6.0,8] - assert dp.util.mean(a) == 4.2 \ No newline at end of file + +def test_mean(): + a = [1, 2, 4, 6.0, 8] + assert dp.util.mean(a) == 4.2 From d5f8c9cb1331c0e89be9c2a405a42ba2741033a9 Mon Sep 17 00:00:00 2001 From: Saksham Date: Thu, 4 Jun 2020 06:56:11 +0530 Subject: [PATCH 3/8] more bindings and tests --- src/bindings/PyDP/algorithms/util.cpp | 14 ++++-- tests/algorithms/test_util.py | 69 +++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/bindings/PyDP/algorithms/util.cpp b/src/bindings/PyDP/algorithms/util.cpp index 7883d4c2..b05c02b0 100644 --- a/src/bindings/PyDP/algorithms/util.cpp +++ b/src/bindings/PyDP/algorithms/util.cpp @@ -1,7 +1,7 @@ // Provides bindings for Util #include "pybind11/pybind11.h" -#include +#include "pybind11/stl.h" #include "differential_privacy/algorithms/util.h" @@ -15,6 +15,12 @@ void init_algorithms_util(py::module& m) { util.def("default_epsilon", &dp::DefaultEpsilon); util.def("get_next_power_of_two", &dp::GetNextPowerOfTwo); util.def("qnorm", &dp::Qnorm); - util.def("mean",&dp::Mean); - // util.def("hello", &dp:: ) -} + util.def("mean", &dp::Mean); + util.def("mean", &dp::Mean); + util.def("variance", &dp::Variance); + util.def("standard_deviation", &dp::StandardDev); + util.def("order_statistics", &dp::OrderStatistic); + util.def("correlation", &dp::Correlation); + util.def("vector_filter", &dp::VectorFilter); + util.def("vector_to_string", &dp::VectorToString); +} \ No newline at end of file diff --git a/tests/algorithms/test_util.py b/tests/algorithms/test_util.py index 02a67733..390c6ed0 100644 --- a/tests/algorithms/test_util.py +++ b/tests/algorithms/test_util.py @@ -1,7 +1,70 @@ import pytest import pydp as dp +import math -def test_mean(): - a = [1, 2, 4, 6.0, 8] - assert dp.util.mean(a) == 4.2 +def test_default_epsilon(): + assert dp.util.default_epsilon() == math.log(3) + + +def test_next_power_positive(): + kTolerance = 1e-5 + npp1 = dp.util.get_next_power_of_two(3.0) + npp2 = dp.util.get_next_power_of_two(5.0) + npp3 = dp.util.get_next_power_of_two(7.9) + assert abs(npp1 - 4) < kTolerance + assert abs(npp2 - 8) < kTolerance + assert abs(npp3 - 8) < kTolerance + + +def test_next_power_exact_positive(): + kTolerance = 1e-5 + npep1 = dp.util.get_next_power_of_two(2.0) + npep2 = dp.util.get_next_power_of_two(8.0) + assert abs(npep1 - 2) < kTolerance + assert abs(npep2 - 8) < kTolerance + + +def test_next_power_one(): + kTolerance = 1e-5 + npo = dp.util.get_next_power_of_two(1.0) + assert abs(npo - 1) < kTolerance + + +def test_next_power_negative(): + kTolerance = 1e-5 + npn1 = dp.util.get_next_power_of_two(0.4) + npn2 = dp.util.get_next_power_of_two(0.2) + assert abs(npn1 - 0.5) < kTolerance + assert abs(npn2 - 0.25) < kTolerance + + +def test_next_power_exact_negative(): + kTolerance = 1e-5 + npn1 = dp.util.get_next_power_of_two(0.5) + npn2 = dp.util.get_next_power_of_two(0.125) + assert abs(npn1 - 0.5) < kTolerance + assert abs(npn2 - 0.125) < kTolerance + + +def test_statistics(): + a = [1.0, 5.0, 7.0, 9.0, 13.0] + assert dp.util.mean(a) == 7.0 + assert dp.util.variance(a) == 16.0 + assert dp.util.standard_deviation(a) == 4.0 + assert dp.util.order_statistics(0.6, a) == 8.0 + assert dp.util.order_statistics(0, a) == 1.0 + assert dp.util.order_statistics(1, a) == 13.0 + + +def test_vector_filter(): + v = [1.0, 2.0, 2.0, 3.0] + selection = [False, True, True, False] + expected = [2.0, 2.0] + assert expected == dp.util.vector_filter(v, selection) + + +def test_vector_to_string(): + v = [1.0, 2.0, 2.0, 3.0] + expected = "[1, 2, 2, 3]" + assert dp.util.vector_to_string(v) == expected From 7da5fe72592c82f05b8aad900b6143b3e2f5595d Mon Sep 17 00:00:00 2001 From: Saksham Date: Thu, 4 Jun 2020 07:58:50 +0530 Subject: [PATCH 4/8] more bindings and tests --- src/bindings/PyDP/algorithms/util.cpp | 1 + tests/algorithms/test_util.py | 28 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/bindings/PyDP/algorithms/util.cpp b/src/bindings/PyDP/algorithms/util.cpp index b05c02b0..571bcdbd 100644 --- a/src/bindings/PyDP/algorithms/util.cpp +++ b/src/bindings/PyDP/algorithms/util.cpp @@ -23,4 +23,5 @@ void init_algorithms_util(py::module& m) { util.def("correlation", &dp::Correlation); util.def("vector_filter", &dp::VectorFilter); util.def("vector_to_string", &dp::VectorToString); + util.def("round_to_nearest_multiple", &dp::RoundToNearestMultiple); } \ No newline at end of file diff --git a/tests/algorithms/test_util.py b/tests/algorithms/test_util.py index 390c6ed0..a6514797 100644 --- a/tests/algorithms/test_util.py +++ b/tests/algorithms/test_util.py @@ -47,6 +47,34 @@ def test_next_power_exact_negative(): assert abs(npn2 - 0.125) < kTolerance +def test_round_positive(): + kTolerance = 1e-5 + rp1 = dp.util.round_to_nearest_multiple(4.9, 2.0) + rp2 = dp.util.round_to_nearest_multiple(5.1, 2.0) + assert abs(rp1 - 4) < kTolerance + assert abs(rp2 - 6) < kTolerance + + +def test_round_negative(): + kTolerance = 1e-5 + rn1 = dp.util.round_to_nearest_multiple(-4.9, 2.0) + rn2 = dp.util.round_to_nearest_multiple(-5.1, 2.0) + assert abs(rn1 + 4) < kTolerance + assert abs(rn2 + 6) < kTolerance + + +def test_round_positive_ties(): + kTolerance = 1e-5 + rpt = dp.util.round_to_nearest_multiple(5.0, 2.0) + assert abs(rpt - 6.0) < kTolerance + + +def test_round_negative_ties(): + kTolerance = 1e-5 + rnt = dp.util.round_to_nearest_multiple(-5.0, 2.0) + assert abs(rnt + 4.0) < kTolerance + + def test_statistics(): a = [1.0, 5.0, 7.0, 9.0, 13.0] assert dp.util.mean(a) == 7.0 From 65923f32404471bad3c1074a0428b1ddd6832f23 Mon Sep 17 00:00:00 2001 From: Saksham Date: Fri, 5 Jun 2020 20:31:06 +0530 Subject: [PATCH 5/8] bindings for add,subtract and sqaure --- src/bindings/PyDP/algorithms/util.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/bindings/PyDP/algorithms/util.cpp b/src/bindings/PyDP/algorithms/util.cpp index 571bcdbd..582b89bb 100644 --- a/src/bindings/PyDP/algorithms/util.cpp +++ b/src/bindings/PyDP/algorithms/util.cpp @@ -24,4 +24,19 @@ void init_algorithms_util(py::module& m) { util.def("vector_filter", &dp::VectorFilter); util.def("vector_to_string", &dp::VectorToString); util.def("round_to_nearest_multiple", &dp::RoundToNearestMultiple); + util.def("safe_add", [](int64_t i,int64_t j){ + int64_t k; + bool result = dp::SafeAdd(i,j,&k); + return k; + }); + util.def("safe_subtract", [](int64_t i,int64_t j){ + int64_t k; + bool result = dp::SafeSubtract(i,j,&k); + return k; + }); + util.def("safe_square", [](int64_t i){ + int64_t k; + bool result = dp::SafeSquare(i,&k); + return k; + }); } \ No newline at end of file From b5cf90777dfc60f79b3c3320901776b4d13ead4d Mon Sep 17 00:00:00 2001 From: Saksham Date: Fri, 5 Jun 2020 20:32:58 +0530 Subject: [PATCH 6/8] style fix and TODO added --- src/bindings/PyDP/algorithms/util.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/bindings/PyDP/algorithms/util.cpp b/src/bindings/PyDP/algorithms/util.cpp index 582b89bb..23758700 100644 --- a/src/bindings/PyDP/algorithms/util.cpp +++ b/src/bindings/PyDP/algorithms/util.cpp @@ -24,19 +24,20 @@ void init_algorithms_util(py::module& m) { util.def("vector_filter", &dp::VectorFilter); util.def("vector_to_string", &dp::VectorToString); util.def("round_to_nearest_multiple", &dp::RoundToNearestMultiple); - util.def("safe_add", [](int64_t i,int64_t j){ + // TODO: Throw an exception in case the function returns false. + util.def("safe_add", [](int64_t i, int64_t j) { int64_t k; - bool result = dp::SafeAdd(i,j,&k); + bool result = dp::SafeAdd(i, j, &k); return k; }); - util.def("safe_subtract", [](int64_t i,int64_t j){ + util.def("safe_subtract", [](int64_t i, int64_t j) { int64_t k; - bool result = dp::SafeSubtract(i,j,&k); + bool result = dp::SafeSubtract(i, j, &k); return k; }); - util.def("safe_square", [](int64_t i){ + util.def("safe_square", [](int64_t i) { int64_t k; - bool result = dp::SafeSquare(i,&k); + bool result = dp::SafeSquare(i, &k); return k; }); } \ No newline at end of file From 36cb188c778e5d37dd53d1a07197fa2fa08880a7 Mon Sep 17 00:00:00 2001 From: Saksham Date: Wed, 17 Jun 2020 17:23:04 +0530 Subject: [PATCH 7/8] throwing runtime error during invalid operations --- src/bindings/PyDP/algorithms/util.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/bindings/PyDP/algorithms/util.cpp b/src/bindings/PyDP/algorithms/util.cpp index 23758700..72cb4726 100644 --- a/src/bindings/PyDP/algorithms/util.cpp +++ b/src/bindings/PyDP/algorithms/util.cpp @@ -28,16 +28,19 @@ void init_algorithms_util(py::module& m) { util.def("safe_add", [](int64_t i, int64_t j) { int64_t k; bool result = dp::SafeAdd(i, j, &k); - return k; + if (result) return k; + throw std::runtime_error("Result of addition will overflow."); }); util.def("safe_subtract", [](int64_t i, int64_t j) { int64_t k; bool result = dp::SafeSubtract(i, j, &k); - return k; + if (result) return k; + throw std::runtime_error("Result of subtraction will overflow."); }); util.def("safe_square", [](int64_t i) { int64_t k; bool result = dp::SafeSquare(i, &k); - return k; + if (result) return k; + throw std::runtime_error("Result of squaring will overflow."); }); } \ No newline at end of file From 61e825c1ec911f743d377113a6eedbdcda458c7b Mon Sep 17 00:00:00 2001 From: Saksham Date: Sat, 20 Jun 2020 23:43:32 +0530 Subject: [PATCH 8/8] removed TODO --- src/bindings/PyDP/algorithms/util.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bindings/PyDP/algorithms/util.cpp b/src/bindings/PyDP/algorithms/util.cpp index 72cb4726..796d625d 100644 --- a/src/bindings/PyDP/algorithms/util.cpp +++ b/src/bindings/PyDP/algorithms/util.cpp @@ -24,7 +24,6 @@ void init_algorithms_util(py::module& m) { util.def("vector_filter", &dp::VectorFilter); util.def("vector_to_string", &dp::VectorToString); util.def("round_to_nearest_multiple", &dp::RoundToNearestMultiple); - // TODO: Throw an exception in case the function returns false. util.def("safe_add", [](int64_t i, int64_t j) { int64_t k; bool result = dp::SafeAdd(i, j, &k);