This documentation is for an old version of OpenDP.

The current release of OpenDP is v0.11.1.

opendp.mod module#

class opendp.mod.Measurement[source]#

Bases: LP_AnyMeasurement

A differentially private unit of computation. A measurement contains a function and a privacy relation. The function releases a differentially-private release. The privacy relation maps from an input metric to an output measure.

Example:

>>> from opendp.mod import Measurement
>>>
>>> # create an instance of Measurement using a constructor from the meas module
>>> from opendp.meas import make_base_geometric
>>> base_geometric: Measurement = make_base_geometric(scale=2., lower=0, upper=20)
>>>
>>> # invoke the measurement (invoke and __call__ are equivalent)
>>> base_geometric.invoke(100)  # -> 101
>>> base_geometric(100)  # -> 99
>>>
>>> # check the measurement's relation at
>>> #     (1, 0.5): (AbsoluteDistance<u32>, MaxDivergence)
>>> assert base_geometric.check(1, 0.5)
>>>
>>> # chain with a transformation from the trans module
>>> from opendp.trans import make_count
>>> from opendp.typing import SubstituteDistance
>>> chained = (
>>>     make_count(MI=SubstituteDistance, TI=int) >>
>>>     base_geometric
>>> )
>>>
>>> # the resulting measurement has the same features
>>> chained([1, 2, 3])  # -> 4
>>> # check the chained measurement's relation at
>>> #     (1, 0.5): (SubstituteDistance, MaxDivergence)
>>> assert chained.check(1, 0.5)
check(d_in, d_out, *, debug=False)[source]#

Check if the measurement satisfies the privacy relation at d_in, d_out.

Parameters:
  • d_in – Distance in terms of the input metric.

  • d_out – Distance in terms of the output measure.

  • debug – Enable to raise Exceptions to help identify why the privacy relation failed.

Returns:

If True, a release is differentially private at d_in, d_out.

Return type:

bool

property input_carrier_type#

Retrieve the carrier type of the input domain. Any member of the input domain is a member of the carrier type.

Returns:

carrier type

property input_distance_type#

Retrieve the distance type of the input metric. This may be any integral type for dataset metrics, or any numeric type for sensitivity metrics.

Returns:

distance type

invoke(arg)[source]#

Create a differentially-private release with arg.

Parameters:

arg – Input to the measurement.

Returns:

differentially-private release

Raises:

OpenDPException – packaged error from the core OpenDP library

property output_distance_type#

Retrieve the distance type of the output measure. This is the type that the budget is expressed in.

Returns:

distance type

exception opendp.mod.OpenDPException(variant, message=None, inner_traceback=None)[source]#

Bases: Exception

General exception for errors originating from the underlying OpenDP library. The variant attribute corresponds to one of the following variants and can be matched on. Error variants may change in library updates.

Parameters:
  • variant (str) –

  • message (str) –

  • inner_traceback (str) –

class opendp.mod.Transformation[source]#

Bases: LP_AnyTransformation

A non-differentially private unit of computation. A transformation contains a function and a stability relation. The function maps from an input domain to an output domain. The stability relation maps from an input metric to an output metric.

Example:

>>> from opendp.mod import Transformation
>>>
>>> # create an instance of Transformation using a constructor from the trans module
>>> from opendp.trans import make_count
>>> count: Transformation = make_count(MI=SymmetricDistance, TI=int)
>>>
>>> # invoke the transformation (invoke and __call__ are equivalent)
>>> count.invoke([1, 2, 3])  # -> 3
>>> count([1, 2, 3])  # -> 3
>>>
>>> # check the transformation's relation at
>>> #     (1, 1): (SymmetricDistance, AbsoluteDistance<u32>)
>>> assert count.check(1, 1)
>>>
>>> # chain with more transformations from the trans module
>>> from opendp.trans import make_split_lines, make_cast
>>> from opendp.typing import SymmetricDistance
>>> chained = (
>>>     make_split_lines(M=SymmetricDistance) >>
>>>     make_cast(M=SymmetricDistance, TI=str, TO=int) >>
>>>     count
>>> )
>>>
>>> # the resulting transformation has the same features
>>> chained("1\n2\n3")  # -> 3
>>> assert chained.check(1, 1)  # both chained transformations were 1-stable
check(d_in, d_out, *, debug=False)[source]#

Check if the transformation satisfies the stability relation at d_in, d_out.

Parameters:
  • d_in – Distance in terms of the input metric.

  • d_out – Distance in terms of the output metric.

  • debug – Enable to raise Exceptions to help identify why the stability relation failed.

Returns:

True if the relation passes. False if the relation failed.

Return type:

bool

Raises:

OpenDPException – packaged error from the core OpenDP library

property input_carrier_type#

Retrieve the carrier type of the input domain. Any member of the input domain is a member of the carrier type.

Returns:

carrier type

property input_distance_type#

Retrieve the distance type of the input metric. This may be any integral type for dataset metrics, or any numeric type for sensitivity metrics.

Returns:

distance type

invoke(arg)[source]#

Execute a non-differentially-private query with arg.

Parameters:

arg – Input to the transformation.

Returns:

non-differentially-private answer

Raises:

OpenDPException – packaged error from the core OpenDP library

property output_distance_type#

Retrieve the distance type of the output metric. This may be any integral type for dataset metrics, or any numeric type for sensitivity metrics.

Returns:

distance type

exception opendp.mod.UnknownTypeException[source]#

Bases: Exception

opendp.mod.assert_features(*features)[source]#
Parameters:

features (str) –

Return type:

None

Find the closest passing value to the decision boundary of predicate within float or integer bounds.

If bounds are float, tolerance defaults to 1e-8.

Example:

Parameters:
  • predicate (Callable[[float | int], bool]) –

  • bounds (Tuple[float, float] | Tuple[int, int]) –

>>> from opendp.mod import binary_search
>>> # Integer binary search
>>> assert binary_search(lambda x: x > 5, bounds=(0, 10)) == 6
>>> assert binary_search(lambda x: x < 5, bounds=(0, 10)) == 4
>>> # Float binary search
>>> assert binary_search(lambda x: x > 5., bounds=(0., 10.)) - 5. < 1e-8
>>> assert binary_search(lambda x: x > 5., bounds=(0., 10.)) - 5. > -1e-8
Parameters:
  • predicate (Callable[[float | int], bool]) – a monotonic unary function from a number to a boolean

  • bounds (Tuple[float, float] | Tuple[int, int]) – a 2-tuple of the lower and upper bounds to the input of predicate

  • tolerance – the discovered parameter differs by at most tolerance from the ideal parameter

Returns:

the discovered parameter within the bounds

Raises:

AssertionError – if the arguments are ill-formed (type issues, decision boundary not within bounds)

opendp.mod.binary_search_chain(make_chain, d_in, d_out, bounds=None, tolerance=None)[source]#

Optimizes a parameterized chain make_chain within float or integer bounds, subject to the chained relation being (d_in, d_out)-close.

bounds defaults to (0., MAX_FINITE_FLOAT). If bounds are float, tolerance defaults to 1e-8.

See binary_search_param to retrieve the discovered parameter instead of the complete computation chain.

Example:

Parameters:
  • make_chain (Callable[[float | int], Transformation | Measurement]) –

  • bounds (Tuple[float, float] | Tuple[int, int] | None) –

Return type:

Transformation | Measurement

>>> from opendp.mod import binary_search_chain
>>> from opendp.trans import make_clamp, make_bounded_resize, make_sized_bounded_mean
>>> from opendp.meas import make_base_laplace
>>>
>>> # The majority of the chain only needs to be defined once.
>>> pre = (
>>>     make_clamp(lower=0., upper=1.) >>
>>>     make_bounded_resize(size=10, lower=0., upper=1., constant=0.) >>
>>>     make_sized_bounded_mean(size=10, lower=0., upper=1.)
>>> )
>>> # Find a value in `bounds` that produces a (`d_in`, `d_out`)-chain within `tolerance` of the decision boundary.
>>> # The lambda function returns the complete computation chain when given a single numeric parameter.
>>> chain = binary_search_chain(lambda s: pre >> make_base_laplace(scale=s), d_in=1, d_out=1.)
>>> # The resulting computation chain is always (`d_in`, `d_out`)-close, but we can still double-check:
>>> assert chain.check(1, 1.)
Parameters:
  • make_chain (Callable[[float | int], Transformation | Measurement]) – a unary function that maps from a number to a Transformation or Measurement

  • d_in – desired input distance of the computation chain

  • d_out – desired output distance of the computation chain

  • bounds (Tuple[float, float] | Tuple[int, int] | None) – a 2-tuple of the lower and upper bounds to the input of make_chain

  • tolerance – the discovered parameter differs by at most tolerance from the ideal parameter

Returns:

a chain parameterized at the nearest passing value to the decision point of the relation

Raises:

AssertionError – if the arguments are ill-formed (type issues, decision boundary not within bounds)

Return type:

Transformation | Measurement

opendp.mod.binary_search_param(make_chain, d_in, d_out, bounds=None, tolerance=None)[source]#

Optimizes a parameterized chain make_chain within float or integer bounds, subject to the chained relation being (d_in, d_out)-close.

bounds defaults to (0., MAX_FINITE_FLOAT). If bounds are float, tolerance defaults to 1e-8.

Example:

Parameters:
  • make_chain (Callable[[float | int], Transformation | Measurement]) –

  • bounds (Tuple[float, float] | Tuple[int, int] | None) –

Return type:

float | int

>>> from opendp.mod import binary_search_param
>>> from opendp.meas import make_base_laplace
>>>
>>> # Find a value in `bounds` that produces a (`d_in`, `d_out`)-chain within `tolerance` of the decision boundary.
>>> # The first argument is any function that returns your complete computation chain
>>> #     when passed a single numeric parameter.
>>> scale = binary_search_param(make_base_laplace, d_in=0.1, d_out=1.)
>>> # The discovered scale differs by at most `tolerance` from the ideal scale (0.1).
>>> assert scale - 0.1 < 1e-8
>>> # Constructing the same chain with the discovered parameter will always be (0.1, 1.)-close.
>>> assert make_base_laplace(scale).check(0.1, 1.)
Parameters:
  • make_chain (Callable[[float | int], Transformation | Measurement]) – a unary function that maps from a number to a Transformation or Measurement

  • d_in – desired input distance of the computation chain

  • d_out – desired output distance of the computation chain

  • bounds (Tuple[float, float] | Tuple[int, int] | None) – a 2-tuple of the lower and upper bounds to the input of make_chain

  • tolerance – the discovered parameter differs by at most tolerance from the ideal parameter

Returns:

the nearest passing value to the decision point of the relation

Raises:

AssertionError – if the arguments are ill-formed (type issues, decision boundary not within bounds)

Return type:

float | int

opendp.mod.disable_features(*features)[source]#
Parameters:

features (str) –

Return type:

None

opendp.mod.enable_features(*features)[source]#
Parameters:

features (str) –

Return type:

None