Source code for opendp.measurements

# Auto-generated. Do not edit!
'''
The ``measurements`` module provides functions that apply calibrated noise to data to ensure differential privacy.
'''
from opendp._convert import *
from opendp._lib import *
from opendp.mod import *
from opendp.typing import *
from opendp.core import *
from opendp.domains import *
from opendp.metrics import *
from opendp.measures import *
__all__ = [
    "make_alp_queryable",
    "make_base_discrete_gaussian",
    "make_base_discrete_laplace",
    "make_base_discrete_laplace_cks20",
    "make_base_discrete_laplace_linear",
    "make_base_gaussian",
    "make_base_geometric",
    "make_base_laplace",
    "make_base_laplace_threshold",
    "make_gaussian",
    "make_laplace",
    "make_randomized_response",
    "make_randomized_response_bool",
    "make_report_noisy_max_gumbel",
    "make_user_measurement",
    "then_alp_queryable",
    "then_base_discrete_gaussian",
    "then_base_discrete_laplace",
    "then_base_discrete_laplace_cks20",
    "then_base_discrete_laplace_linear",
    "then_base_gaussian",
    "then_base_geometric",
    "then_base_laplace",
    "then_base_laplace_threshold",
    "then_gaussian",
    "then_laplace",
    "then_report_noisy_max_gumbel",
    "then_user_measurement"
]


[docs] @versioned def make_alp_queryable( input_domain: Domain, input_metric: Metric, scale, total_limit, value_limit = None, size_factor = 50, alpha = 4, CO: Optional[RuntimeTypeDescriptor] = None ) -> Measurement: r"""Measurement to release a queryable containing a DP projection of bounded sparse data. The size of the projection is O(total * size_factor * scale / alpha). The evaluation time of post-processing is O(beta * scale / alpha). `size_factor` is an optional multiplier (defaults to 50) for setting the size of the projection. There is a memory/utility trade-off. The value should be sufficiently large to limit hash collisions. [make_alp_queryable in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_alp_queryable.html) **Citations:** * [ALP21 Differentially Private Sparse Vectors with Low Error, Optimal Space, and Fast Access](https://arxiv.org/abs/2106.10068) Algorithm 4 **Supporting Elements:** * Input Domain: `MapDomain<AtomDomain<K>, AtomDomain<CI>>` * Output Type: `Queryable<K, CO>` * Input Metric: `L1Distance<CI>` * Output Measure: `MaxDivergence<CO>` :param input_domain: :type input_domain: Domain :param input_metric: :type input_metric: Metric :param scale: Privacy loss parameter. This is equal to epsilon/sensitivity. :param total_limit: Either the true value or an upper bound estimate of the sum of all values in the input. :param value_limit: Upper bound on individual values (referred to as β). Entries above β are clamped. :param size_factor: Optional multiplier (default of 50) for setting the size of the projection. :param alpha: Optional parameter (default of 4) for scaling and determining p in randomized response step. :param CO: :type CO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. CO = RuntimeType.parse_or_infer(type_name=CO, public_example=scale) CI = get_value_type(get_carrier_type(input_domain)) # type: ignore # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=CO) c_total_limit = py_to_c(total_limit, c_type=ctypes.c_void_p, type_name=CI) c_value_limit = py_to_c(value_limit, c_type=ctypes.c_void_p, type_name=RuntimeType(origin='Option', args=[CI])) c_size_factor = py_to_c(size_factor, c_type=ctypes.c_void_p, type_name=RuntimeType(origin='Option', args=[u32])) c_alpha = py_to_c(alpha, c_type=ctypes.c_void_p, type_name=RuntimeType(origin='Option', args=[u32])) c_CO = py_to_c(CO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_alp_queryable lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_total_limit, c_value_limit, c_size_factor, c_alpha, c_CO), Measurement)) return output
[docs] def then_alp_queryable( scale, total_limit, value_limit = None, size_factor = 50, alpha = 4, CO: Optional[RuntimeTypeDescriptor] = None ): r"""partial constructor of make_alp_queryable .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_alp_queryable` :param scale: Privacy loss parameter. This is equal to epsilon/sensitivity. :param total_limit: Either the true value or an upper bound estimate of the sum of all values in the input. :param value_limit: Upper bound on individual values (referred to as β). Entries above β are clamped. :param size_factor: Optional multiplier (default of 50) for setting the size of the projection. :param alpha: Optional parameter (default of 4) for scaling and determining p in randomized response step. :param CO: :type CO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_alp_queryable( input_domain=input_domain, input_metric=input_metric, scale=scale, total_limit=total_limit, value_limit=value_limit, size_factor=size_factor, alpha=alpha, CO=CO))
[docs] @versioned def make_base_discrete_gaussian( input_domain: Domain, input_metric: Metric, scale, MO: RuntimeTypeDescriptor = "ZeroConcentratedDivergence<QO>" ) -> Measurement: r"""Make a Measurement that adds noise from the discrete_gaussian(`scale`) distribution to the input. Valid inputs for `input_domain` and `input_metric` are: | `input_domain` | input type | `input_metric` | | ------------------------------- | ------------ | ---------------------- | | `atom_domain(T)` | `T` | `absolute_distance(QI)` | | `vector_domain(atom_domain(T))` | `Vec<T>` | `l2_distance(QI)` | [make_base_discrete_gaussian in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_base_discrete_gaussian.html) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MO` :param input_domain: Domain of the data type to be privatized. :type input_domain: Domain :param input_metric: Metric of the data type to be privatized. :type input_metric: Metric :param scale: Noise scale parameter for the gaussian distribution. `scale` == standard_deviation. :param MO: Output measure. The only valid measure is `ZeroConcentratedDivergence<QO>`, but QO can be any float. :type MO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. MO = RuntimeType.parse(type_name=MO, generics=["QO"]) QO = get_atom_or_infer(MO, scale) # type: ignore MO = MO.substitute(QO=QO) # type: ignore # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=QO) c_MO = py_to_c(MO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_base_discrete_gaussian lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_MO), Measurement)) return output
[docs] def then_base_discrete_gaussian( scale, MO: RuntimeTypeDescriptor = "ZeroConcentratedDivergence<QO>" ): r"""partial constructor of make_base_discrete_gaussian .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_base_discrete_gaussian` :param scale: Noise scale parameter for the gaussian distribution. `scale` == standard_deviation. :param MO: Output measure. The only valid measure is `ZeroConcentratedDivergence<QO>`, but QO can be any float. :type MO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_base_discrete_gaussian( input_domain=input_domain, input_metric=input_metric, scale=scale, MO=MO))
[docs] @versioned def make_base_discrete_laplace( input_domain: Domain, input_metric: Metric, scale, QO: Optional[RuntimeTypeDescriptor] = None ) -> Measurement: r"""Make a Measurement that adds noise from the discrete_laplace(`scale`) distribution to the input. Valid inputs for `input_domain` and `input_metric` are: | `input_domain` | input type | `input_metric` | | ------------------------------- | ------------ | ---------------------- | | `atom_domain(T)` (default) | `T` | `absolute_distance(T)` | | `vector_domain(atom_domain(T))` | `Vec<T>` | `l1_distance(T)` | This uses `make_base_discrete_laplace_cks20` if scale is greater than 10, otherwise it uses `make_base_discrete_laplace_linear`. [make_base_discrete_laplace in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_base_discrete_laplace.html) **Citations:** * [GRS12 Universally Utility-Maximizing Privacy Mechanisms](https://theory.stanford.edu/~tim/papers/priv.pdf) * [CKS20 The Discrete Gaussian for Differential Privacy](https://arxiv.org/pdf/2004.00010.pdf#subsection.5.2) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MaxDivergence<QO>` :param input_domain: Domain of the data type to be privatized. :type input_domain: Domain :param input_metric: Metric of the data type to be privatized. :type input_metric: Metric :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param QO: Data type of the output distance and scale. `f32` or `f64`. :type QO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. QO = RuntimeType.parse_or_infer(type_name=QO, public_example=scale) # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=QO) c_QO = py_to_c(QO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_base_discrete_laplace lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_QO), Measurement)) return output
[docs] def then_base_discrete_laplace( scale, QO: Optional[RuntimeTypeDescriptor] = None ): r"""partial constructor of make_base_discrete_laplace .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_base_discrete_laplace` :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param QO: Data type of the output distance and scale. `f32` or `f64`. :type QO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_base_discrete_laplace( input_domain=input_domain, input_metric=input_metric, scale=scale, QO=QO))
[docs] @versioned def make_base_discrete_laplace_cks20( input_domain: Domain, input_metric: Metric, scale, QO: Optional[RuntimeTypeDescriptor] = None ) -> Measurement: r"""Make a Measurement that adds noise from the discrete_laplace(`scale`) distribution to the input, using an efficient algorithm on rational bignums. Valid inputs for `input_domain` and `input_metric` are: | `input_domain` | input type | `input_metric` | | ------------------------------- | ------------ | ---------------------- | | `atom_domain(T)` (default) | `T` | `absolute_distance(T)` | | `vector_domain(atom_domain(T))` | `Vec<T>` | `l1_distance(T)` | [make_base_discrete_laplace_cks20 in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_base_discrete_laplace_cks20.html) **Citations:** * [CKS20 The Discrete Gaussian for Differential Privacy](https://arxiv.org/pdf/2004.00010.pdf#subsection.5.2) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MaxDivergence<QO>` :param input_domain: :type input_domain: Domain :param input_metric: :type input_metric: Metric :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param QO: Data type of the output distance and scale. :type QO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. QO = RuntimeType.parse_or_infer(type_name=QO, public_example=scale) # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=QO) c_QO = py_to_c(QO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_base_discrete_laplace_cks20 lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_QO), Measurement)) return output
[docs] def then_base_discrete_laplace_cks20( scale, QO: Optional[RuntimeTypeDescriptor] = None ): r"""partial constructor of make_base_discrete_laplace_cks20 .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_base_discrete_laplace_cks20` :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param QO: Data type of the output distance and scale. :type QO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_base_discrete_laplace_cks20( input_domain=input_domain, input_metric=input_metric, scale=scale, QO=QO))
[docs] @versioned def make_base_discrete_laplace_linear( input_domain: Domain, input_metric: Metric, scale, bounds: Optional[Any] = None, QO: Optional[RuntimeTypeDescriptor] = None ) -> Measurement: r"""Make a Measurement that adds noise from the discrete_laplace(`scale`) distribution to the input, using a linear-time algorithm on finite data types. This algorithm can be executed in constant time if bounds are passed. Valid inputs for `input_domain` and `input_metric` are: | `input_domain` | input type | `input_metric` | | ------------------------------- | ------------ | ---------------------- | | `atom_domain(T)` (default) | `T` | `absolute_distance(T)` | | `vector_domain(atom_domain(T))` | `Vec<T>` | `l1_distance(T)` | [make_base_discrete_laplace_linear in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_base_discrete_laplace_linear.html) **Citations:** * [GRS12 Universally Utility-Maximizing Privacy Mechanisms](https://theory.stanford.edu/~tim/papers/priv.pdf) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MaxDivergence<QO>` :param input_domain: Domain of the data type to be privatized. :type input_domain: Domain :param input_metric: Metric of the data type to be privatized. :type input_metric: Metric :param scale: Noise scale parameter for the distribution. `scale` == standard_deviation / sqrt(2). :param bounds: Set bounds on the count to make the algorithm run in constant-time. :type bounds: Any :param QO: Data type of the scale and output distance. :type QO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. QO = RuntimeType.parse_or_infer(type_name=QO, public_example=scale) T = get_atom(get_carrier_type(input_domain)) # type: ignore OptionT = RuntimeType(origin='Option', args=[RuntimeType(origin='Tuple', args=[T, T])]) # type: ignore # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=QO) c_bounds = py_to_c(bounds, c_type=AnyObjectPtr, type_name=OptionT) c_QO = py_to_c(QO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_base_discrete_laplace_linear lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, AnyObjectPtr, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_bounds, c_QO), Measurement)) return output
[docs] def then_base_discrete_laplace_linear( scale, bounds: Optional[Any] = None, QO: Optional[RuntimeTypeDescriptor] = None ): r"""partial constructor of make_base_discrete_laplace_linear .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_base_discrete_laplace_linear` :param scale: Noise scale parameter for the distribution. `scale` == standard_deviation / sqrt(2). :param bounds: Set bounds on the count to make the algorithm run in constant-time. :type bounds: Any :param QO: Data type of the scale and output distance. :type QO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_base_discrete_laplace_linear( input_domain=input_domain, input_metric=input_metric, scale=scale, bounds=bounds, QO=QO))
[docs] @versioned def make_base_gaussian( input_domain: Domain, input_metric: Metric, scale, k: int = -1074, MO: RuntimeTypeDescriptor = "ZeroConcentratedDivergence<T>" ) -> Measurement: r"""Make a Measurement that adds noise from the gaussian(`scale`) distribution to the input. Valid inputs for `input_domain` and `input_metric` are: | `input_domain` | input type | `input_metric` | | ------------------------------- | ------------ | ---------------------- | | `atom_domain(T)` (default) | `T` | `absolute_distance(T)` | | `vector_domain(atom_domain(T))` | `Vec<T>` | `l2_distance(T)` | This function takes a noise granularity in terms of 2^k. Larger granularities are more computationally efficient, but have a looser privacy map. If k is not set, k defaults to the smallest granularity. [make_base_gaussian in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_base_gaussian.html) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MO` :param input_domain: Domain of the data type to be privatized. Valid values are `VectorDomain<AtomDomain<T>>` or `AtomDomain<T>`. :type input_domain: Domain :param input_metric: Metric of the data type to be privatized. Valid values are `AbsoluteDistance<T>` or `L2Distance<T>`. :type input_metric: Metric :param scale: Noise scale parameter for the gaussian distribution. `scale` == standard_deviation. :param k: The noise granularity in terms of 2^k. :type k: int :param MO: Output Measure. The only valid measure is `ZeroConcentratedDivergence<T>`. :type MO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. MO = RuntimeType.parse(type_name=MO, generics=["T"]) T = get_atom_or_infer(get_carrier_type(input_domain), scale) # type: ignore MO = MO.substitute(T=T) # type: ignore # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=T) c_k = py_to_c(k, c_type=ctypes.c_uint32, type_name=i32) c_MO = py_to_c(MO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_base_gaussian lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_uint32, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_k, c_MO), Measurement)) return output
[docs] def then_base_gaussian( scale, k: int = -1074, MO: RuntimeTypeDescriptor = "ZeroConcentratedDivergence<T>" ): r"""partial constructor of make_base_gaussian .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_base_gaussian` :param scale: Noise scale parameter for the gaussian distribution. `scale` == standard_deviation. :param k: The noise granularity in terms of 2^k. :type k: int :param MO: Output Measure. The only valid measure is `ZeroConcentratedDivergence<T>`. :type MO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_base_gaussian( input_domain=input_domain, input_metric=input_metric, scale=scale, k=k, MO=MO))
[docs] @versioned def make_base_geometric( input_domain: Domain, input_metric: Metric, scale, bounds: Optional[Any] = None, QO: Optional[RuntimeTypeDescriptor] = None ) -> Measurement: r"""An alias for `make_base_discrete_laplace_linear`. If you don't need timing side-channel protections via `bounds`, `make_base_discrete_laplace` is more efficient. [make_base_geometric in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_base_geometric.html) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MaxDivergence<QO>` :param input_domain: :type input_domain: Domain :param input_metric: :type input_metric: Metric :param scale: :param bounds: :type bounds: Any :param QO: :type QO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. QO = RuntimeType.parse_or_infer(type_name=QO, public_example=scale) T = get_atom(get_carrier_type(input_domain)) # type: ignore OptionT = RuntimeType(origin='Option', args=[RuntimeType(origin='Tuple', args=[T, T])]) # type: ignore # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=QO) c_bounds = py_to_c(bounds, c_type=AnyObjectPtr, type_name=OptionT) c_QO = py_to_c(QO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_base_geometric lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, AnyObjectPtr, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_bounds, c_QO), Measurement)) return output
[docs] def then_base_geometric( scale, bounds: Optional[Any] = None, QO: Optional[RuntimeTypeDescriptor] = None ): r"""partial constructor of make_base_geometric .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_base_geometric` :param scale: :param bounds: :type bounds: Any :param QO: :type QO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_base_geometric( input_domain=input_domain, input_metric=input_metric, scale=scale, bounds=bounds, QO=QO))
[docs] @versioned def make_base_laplace( input_domain: Domain, input_metric: Metric, scale, k: int = -1074 ) -> Measurement: r"""Make a Measurement that adds noise from the Laplace(`scale`) distribution to a scalar value. Valid inputs for `input_domain` and `input_metric` are: | `input_domain` | input type | `input_metric` | | ------------------------------- | ------------ | ---------------------- | | `atom_domain(T)` (default) | `T` | `absolute_distance(T)` | | `vector_domain(atom_domain(T))` | `Vec<T>` | `l1_distance(T)` | This function takes a noise granularity in terms of 2^k. Larger granularities are more computationally efficient, but have a looser privacy map. If k is not set, k defaults to the smallest granularity. [make_base_laplace in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_base_laplace.html) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MaxDivergence<D::Atom>` :param input_domain: Domain of the data type to be privatized. :type input_domain: Domain :param input_metric: Metric of the data type to be privatized. :type input_metric: Metric :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param k: The noise granularity in terms of 2^k. :type k: int :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. T = get_atom_or_infer(get_carrier_type(input_domain), scale) # type: ignore # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=T) c_k = py_to_c(k, c_type=ctypes.c_uint32, type_name=i32) # Call library function. lib_function = lib.opendp_measurements__make_base_laplace lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_uint32] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_k), Measurement)) return output
[docs] def then_base_laplace( scale, k: int = -1074 ): r"""partial constructor of make_base_laplace .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_base_laplace` :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param k: The noise granularity in terms of 2^k. :type k: int """ return PartialConstructor(lambda input_domain, input_metric: make_base_laplace( input_domain=input_domain, input_metric=input_metric, scale=scale, k=k))
[docs] @versioned def make_base_laplace_threshold( input_domain: Domain, input_metric: Metric, scale, threshold, k: int = -1074 ) -> Measurement: r"""Make a Measurement that uses propose-test-release to privatize a hashmap of counts. This function takes a noise granularity in terms of 2^k. Larger granularities are more computationally efficient, but have a looser privacy map. If k is not set, k defaults to the smallest granularity. [make_base_laplace_threshold in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_base_laplace_threshold.html) **Supporting Elements:** * Input Domain: `MapDomain<AtomDomain<TK>, AtomDomain<TV>>` * Output Type: `HashMap<TK, TV>` * Input Metric: `L1Distance<TV>` * Output Measure: `FixedSmoothedMaxDivergence<TV>` :param input_domain: Domain of the input. :type input_domain: Domain :param input_metric: Metric for the input domain. :type input_metric: Metric :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param threshold: Exclude counts that are less than this minimum value. :param k: The noise granularity in terms of 2^k. :type k: int :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib", "floating-point") # Standardize type arguments. TV = get_distance_type(input_metric) # type: ignore # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=TV) c_threshold = py_to_c(threshold, c_type=ctypes.c_void_p, type_name=TV) c_k = py_to_c(k, c_type=ctypes.c_uint32, type_name=i32) # Call library function. lib_function = lib.opendp_measurements__make_base_laplace_threshold lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint32] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_threshold, c_k), Measurement)) return output
[docs] def then_base_laplace_threshold( scale, threshold, k: int = -1074 ): r"""partial constructor of make_base_laplace_threshold .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_base_laplace_threshold` :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param threshold: Exclude counts that are less than this minimum value. :param k: The noise granularity in terms of 2^k. :type k: int """ return PartialConstructor(lambda input_domain, input_metric: make_base_laplace_threshold( input_domain=input_domain, input_metric=input_metric, scale=scale, threshold=threshold, k=k))
[docs] @versioned def make_gaussian( input_domain: Domain, input_metric: Metric, scale, MO: RuntimeTypeDescriptor = "ZeroConcentratedDivergence<QO>" ) -> Measurement: r"""Make a Measurement that adds noise from the gaussian(`scale`) distribution to the input. Valid inputs for `input_domain` and `input_metric` are: | `input_domain` | input type | `input_metric` | | ------------------------------- | ------------ | ----------------------- | | `atom_domain(T)` | `T` | `absolute_distance(QI)` | | `vector_domain(atom_domain(T))` | `Vec<T>` | `l2_distance(QI)` | [make_gaussian in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_gaussian.html) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MO` :param input_domain: Domain of the data type to be privatized. :type input_domain: Domain :param input_metric: Metric of the data type to be privatized. :type input_metric: Metric :param scale: Noise scale parameter for the gaussian distribution. `scale` == standard_deviation. :param MO: Output Measure. The only valid measure is `ZeroConcentratedDivergence<T>`. :type MO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. MO = RuntimeType.parse(type_name=MO, generics=["QO"]) QO = get_atom_or_infer(MO, scale) # type: ignore MO = MO.substitute(QO=QO) # type: ignore # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=get_atom(MO)) c_MO = py_to_c(MO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_gaussian lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_MO), Measurement)) return output
[docs] def then_gaussian( scale, MO: RuntimeTypeDescriptor = "ZeroConcentratedDivergence<QO>" ): r"""partial constructor of make_gaussian .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_gaussian` :param scale: Noise scale parameter for the gaussian distribution. `scale` == standard_deviation. :param MO: Output Measure. The only valid measure is `ZeroConcentratedDivergence<T>`. :type MO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_gaussian( input_domain=input_domain, input_metric=input_metric, scale=scale, MO=MO))
[docs] @versioned def make_laplace( input_domain: Domain, input_metric: Metric, scale, QO: RuntimeTypeDescriptor = "float" ) -> Measurement: r"""Make a Measurement that adds noise from the laplace(`scale`) distribution to the input. Valid inputs for `input_domain` and `input_metric` are: | `input_domain` | input type | `input_metric` | | ------------------------------- | ------------ | ---------------------- | | `atom_domain(T)` (default) | `T` | `absolute_distance(T)` | | `vector_domain(atom_domain(T))` | `Vec<T>` | `l1_distance(T)` | This uses `make_base_laplace` if `T` is float, otherwise it uses `make_base_discrete_laplace`. [make_laplace in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_laplace.html) **Citations:** * [GRS12 Universally Utility-Maximizing Privacy Mechanisms](https://theory.stanford.edu/~tim/papers/priv.pdf) * [CKS20 The Discrete Gaussian for Differential Privacy](https://arxiv.org/pdf/2004.00010.pdf#subsection.5.2) **Supporting Elements:** * Input Domain: `D` * Output Type: `D::Carrier` * Input Metric: `D::InputMetric` * Output Measure: `MaxDivergence<QO>` :param input_domain: Domain of the data type to be privatized. :type input_domain: Domain :param input_metric: Metric of the data type to be privatized. :type input_metric: Metric :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param QO: Data type of the output distance and scale. `f32` or `f64`. :type QO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. QO = RuntimeType.parse(type_name=QO) # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=ctypes.c_void_p, type_name=get_atom(QO)) c_QO = py_to_c(QO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_laplace lib_function.argtypes = [Domain, Metric, ctypes.c_void_p, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_QO), Measurement)) return output
[docs] def then_laplace( scale, QO: RuntimeTypeDescriptor = "float" ): r"""partial constructor of make_laplace .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_laplace` :param scale: Noise scale parameter for the laplace distribution. `scale` == standard_deviation / sqrt(2). :param QO: Data type of the output distance and scale. `f32` or `f64`. :type QO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_laplace( input_domain=input_domain, input_metric=input_metric, scale=scale, QO=QO))
[docs] @versioned def make_randomized_response( categories: Any, prob, constant_time: bool = False, T: Optional[RuntimeTypeDescriptor] = None, QO: Optional[RuntimeTypeDescriptor] = None ) -> Measurement: r"""Make a Measurement that implements randomized response on a categorical value. [make_randomized_response in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_randomized_response.html) **Supporting Elements:** * Input Domain: `AtomDomain<T>` * Output Type: `T` * Input Metric: `DiscreteDistance` * Output Measure: `MaxDivergence<QO>` :param categories: Set of valid outcomes :type categories: Any :param prob: Probability of returning the correct answer. Must be in `[1/num_categories, 1)` :param constant_time: Set to true to enable constant time. Slower. :type constant_time: bool :param T: Data type of a category. :type T: :py:ref:`RuntimeTypeDescriptor` :param QO: Data type of probability and output distance. :type QO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. T = RuntimeType.parse_or_infer(type_name=T, public_example=get_first(categories)) QO = RuntimeType.parse_or_infer(type_name=QO, public_example=prob) # Convert arguments to c types. c_categories = py_to_c(categories, c_type=AnyObjectPtr, type_name=RuntimeType(origin='Vec', args=[T])) c_prob = py_to_c(prob, c_type=ctypes.c_void_p, type_name=QO) c_constant_time = py_to_c(constant_time, c_type=ctypes.c_bool, type_name=bool) c_T = py_to_c(T, c_type=ctypes.c_char_p) c_QO = py_to_c(QO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_randomized_response lib_function.argtypes = [AnyObjectPtr, ctypes.c_void_p, ctypes.c_bool, ctypes.c_char_p, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_categories, c_prob, c_constant_time, c_T, c_QO), Measurement)) return output
[docs] @versioned def make_randomized_response_bool( prob, constant_time: bool = False, QO: Optional[RuntimeTypeDescriptor] = None ) -> Measurement: r"""Make a Measurement that implements randomized response on a boolean value. [make_randomized_response_bool in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_randomized_response_bool.html) **Supporting Elements:** * Input Domain: `AtomDomain<bool>` * Output Type: `bool` * Input Metric: `DiscreteDistance` * Output Measure: `MaxDivergence<QO>` **Proof Definition:** [(Proof Document)](https://docs.opendp.org/en/nightly/proofs/rust/src/measurements/randomized_response/make_randomized_response_bool.pdf) :param prob: Probability of returning the correct answer. Must be in `[0.5, 1)` :param constant_time: Set to true to enable constant time. Slower. :type constant_time: bool :param QO: Data type of probability and output distance. :type QO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. QO = RuntimeType.parse_or_infer(type_name=QO, public_example=prob) # Convert arguments to c types. c_prob = py_to_c(prob, c_type=ctypes.c_void_p, type_name=QO) c_constant_time = py_to_c(constant_time, c_type=ctypes.c_bool, type_name=bool) c_QO = py_to_c(QO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_randomized_response_bool lib_function.argtypes = [ctypes.c_void_p, ctypes.c_bool, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_prob, c_constant_time, c_QO), Measurement)) return output
[docs] @versioned def make_report_noisy_max_gumbel( input_domain: Domain, input_metric: Metric, scale: Any, optimize: str, QO: Optional[RuntimeTypeDescriptor] = None ) -> Measurement: r"""Make a Measurement that takes a vector of scores and privately selects the index of the highest score. [make_report_noisy_max_gumbel in Rust documentation.](https://docs.rs/opendp/latest/opendp/measurements/fn.make_report_noisy_max_gumbel.html) **Supporting Elements:** * Input Domain: `VectorDomain<AtomDomain<TIA>>` * Output Type: `usize` * Input Metric: `LInfDistance<TIA>` * Output Measure: `MaxDivergence<QO>` **Proof Definition:** [(Proof Document)](https://docs.opendp.org/en/nightly/proofs/rust/src/measurements/gumbel_max/make_report_noisy_max_gumbel.pdf) :param input_domain: Domain of the input vector. Must be a non-nullable VectorDomain. :type input_domain: Domain :param input_metric: Metric on the input domain. Must be LInfDistance :type input_metric: Metric :param scale: Higher scales are more private. :type scale: Any :param optimize: Indicate whether to privately return the "Max" or "Min" :type optimize: str :param QO: Output Distance Type. :type QO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib") # Standardize type arguments. QO = RuntimeType.parse_or_infer(type_name=QO, public_example=scale) # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_scale = py_to_c(scale, c_type=AnyObjectPtr, type_name=QO) c_optimize = py_to_c(optimize, c_type=ctypes.c_char_p, type_name=String) c_QO = py_to_c(QO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_report_noisy_max_gumbel lib_function.argtypes = [Domain, Metric, AnyObjectPtr, ctypes.c_char_p, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_scale, c_optimize, c_QO), Measurement)) return output
[docs] def then_report_noisy_max_gumbel( scale: Any, optimize: str, QO: Optional[RuntimeTypeDescriptor] = None ): r"""partial constructor of make_report_noisy_max_gumbel .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_report_noisy_max_gumbel` :param scale: Higher scales are more private. :type scale: Any :param optimize: Indicate whether to privately return the "Max" or "Min" :type optimize: str :param QO: Output Distance Type. :type QO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_report_noisy_max_gumbel( input_domain=input_domain, input_metric=input_metric, scale=scale, optimize=optimize, QO=QO))
[docs] @versioned def make_user_measurement( input_domain: Domain, input_metric: Metric, output_measure: Measure, function, privacy_map, TO: RuntimeTypeDescriptor = "ExtrinsicObject" ) -> Measurement: r"""Construct a Measurement from user-defined callbacks. **Supporting Elements:** * Input Domain: `AnyDomain` * Output Type: `AnyObject` * Input Metric: `AnyMetric` * Output Measure: `AnyMeasure` :param input_domain: A domain describing the set of valid inputs for the function. :type input_domain: Domain :param input_metric: The metric from which distances between adjacent inputs are measured. :type input_metric: Metric :param output_measure: The measure from which distances between adjacent output distributions are measured. :type output_measure: Measure :param function: A function mapping data from `input_domain` to a release of type `TO`. :param privacy_map: A function mapping distances from `input_metric` to `output_measure`. :param TO: The data type of outputs from the function. :type TO: :py:ref:`RuntimeTypeDescriptor` :rtype: Measurement :raises TypeError: if an argument's type differs from the expected type :raises UnknownTypeException: if a type argument fails to parse :raises OpenDPException: packaged error from the core OpenDP library """ assert_features("contrib", "honest-but-curious") # Standardize type arguments. TO = RuntimeType.parse(type_name=TO) # Convert arguments to c types. c_input_domain = py_to_c(input_domain, c_type=Domain, type_name=None) c_input_metric = py_to_c(input_metric, c_type=Metric, type_name=None) c_output_measure = py_to_c(output_measure, c_type=Measure, type_name=AnyMeasure) c_function = py_to_c(function, c_type=CallbackFn, type_name=pass_through(TO)) c_privacy_map = py_to_c(privacy_map, c_type=CallbackFn, type_name=measure_distance_type(output_measure)) c_TO = py_to_c(TO, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_measurements__make_user_measurement lib_function.argtypes = [Domain, Metric, Measure, CallbackFn, CallbackFn, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_input_domain, c_input_metric, c_output_measure, c_function, c_privacy_map, c_TO), Measurement)) output._depends_on(input_domain, input_metric, output_measure, c_function, c_privacy_map) return output
[docs] def then_user_measurement( output_measure: Measure, function, privacy_map, TO: RuntimeTypeDescriptor = "ExtrinsicObject" ): r"""partial constructor of make_user_measurement .. seealso:: Delays application of `input_domain` and `input_metric` in :py:func:`opendp.measurements.make_user_measurement` :param output_measure: The measure from which distances between adjacent output distributions are measured. :type output_measure: Measure :param function: A function mapping data from `input_domain` to a release of type `TO`. :param privacy_map: A function mapping distances from `input_metric` to `output_measure`. :param TO: The data type of outputs from the function. :type TO: :py:ref:`RuntimeTypeDescriptor` """ return PartialConstructor(lambda input_domain, input_metric: make_user_measurement( input_domain=input_domain, input_metric=input_metric, output_measure=output_measure, function=function, privacy_map=privacy_map, TO=TO))