Questions or feedback?

Source code for opendp.metrics

# Auto-generated. Do not edit!
'''
The ``metrics`` module provides fuctions that measure the distance between two elements of a domain.
For more context, see :ref:`metrics in the User Guide <metrics-user-guide>`.

For convenience, all the functions of this module are also available from :py:mod:`opendp.prelude`.
We suggest importing under the conventional name ``dp``:

.. code:: pycon

    >>> import opendp.prelude as dp
'''
from deprecated.sphinx import deprecated # noqa: F401 (Not every file actually has deprecated functions.)

from opendp._convert import *
from opendp._lib import *
from opendp.mod import *
from opendp.typing import *
from opendp.typing import _substitute # noqa: F401

__all__ = [
    "_change_one_id_distance_get_identifier",
    "_extrinsic_metric_descriptor",
    "_frame_distance_get_inner_metric",
    "_get_bound",
    "_metric_equal",
    "_metric_free",
    "_symmetric_id_distance_get_identifier",
    "absolute_distance",
    "change_one_distance",
    "change_one_id_distance",
    "discrete_distance",
    "frame_distance",
    "hamming_distance",
    "insert_delete_distance",
    "l01inf_distance",
    "l02inf_distance",
    "l1_distance",
    "l2_distance",
    "linf_distance",
    "metric_debug",
    "metric_distance_type",
    "metric_type",
    "symmetric_distance",
    "symmetric_id_distance",
    "user_distance"
]


def _change_one_id_distance_get_identifier(
    metric: Metric
):
    r"""Retrieve the identifier of a `ChangeOneIdDistance` metric.

    .. end-markdown

    :param metric: 
    :type metric: Metric
    :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
    """
    # No type arguments to standardize.
    # Convert arguments to c types.
    c_metric = py_to_c(metric, c_type=Metric, type_name="AnyMetric")

    # Call library function.
    lib_function = lib.opendp_metrics___change_one_id_distance_get_identifier
    lib_function.argtypes = [Metric]
    lib_function.restype = FfiResult

    output = c_to_py(unwrap(lib_function(c_metric), AnyObjectPtr))
    try:
        output.__opendp_dict__ = {
            '__function__': '_change_one_id_distance_get_identifier',
            '__module__': 'metrics',
            '__kwargs__': {
                'metric': metric
            },
        }
    except AttributeError:  # pragma: no cover
        pass
    return output


def _extrinsic_metric_descriptor(
    metric: Metric
):
    r"""Retrieve the descriptor value stored in an extrinsic metric.

    .. end-markdown

    :param metric: The ExtrinsicDistance to extract the descriptor from
    :type metric: Metric
    :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
    """
    # No type arguments to standardize.
    # Convert arguments to c types.
    c_metric = py_to_c(metric, c_type=Metric, type_name="AnyMetric")

    # Call library function.
    lib_function = lib.opendp_metrics___extrinsic_metric_descriptor
    lib_function.argtypes = [Metric]
    lib_function.restype = FfiResult

    output = c_to_py(unwrap(lib_function(c_metric), ExtrinsicObjectPtr))
    try:
        output.__opendp_dict__ = {
            '__function__': '_extrinsic_metric_descriptor',
            '__module__': 'metrics',
            '__kwargs__': {
                'metric': metric
            },
        }
    except AttributeError:  # pragma: no cover
        pass
    return output


def _frame_distance_get_inner_metric(
    metric: Metric
) -> Metric:
    r"""Retrieve the inner metric of a `FrameDistance` metric.

    .. end-markdown

    :param metric: 
    :type metric: Metric
    :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
    """
    # No type arguments to standardize.
    # Convert arguments to c types.
    c_metric = py_to_c(metric, c_type=Metric, type_name="AnyMetric")

    # Call library function.
    lib_function = lib.opendp_metrics___frame_distance_get_inner_metric
    lib_function.argtypes = [Metric]
    lib_function.restype = FfiResult

    output = c_to_py(unwrap(lib_function(c_metric), Metric))
    try:
        output.__opendp_dict__ = {
            '__function__': '_frame_distance_get_inner_metric',
            '__module__': 'metrics',
            '__kwargs__': {
                'metric': metric
            },
        }
    except AttributeError:  # pragma: no cover
        pass
    return output


def _get_bound(
    bounds,
    by
):
    r"""Infer a bound when grouping by `by`.

    .. end-markdown

    :param bounds: 
    :param by: 
    :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
    """
    # No type arguments to standardize.
    # Convert arguments to c types.
    c_bounds = py_to_c(bounds, c_type=AnyObjectPtr, type_name="Bounds")
    c_by = py_to_c(by, c_type=AnyObjectPtr, type_name=RuntimeType(origin='Vec', args=["Expr"]))

    # Call library function.
    lib_function = lib.opendp_metrics___get_bound
    lib_function.argtypes = [AnyObjectPtr, AnyObjectPtr]
    lib_function.restype = FfiResult

    output = c_to_py(unwrap(lib_function(c_bounds, c_by), AnyObjectPtr))
    try:
        output.__opendp_dict__ = {
            '__function__': '_get_bound',
            '__module__': 'metrics',
            '__kwargs__': {
                'bounds': bounds, 'by': by
            },
        }
    except AttributeError:  # pragma: no cover
        pass
    return output


def _metric_equal(
    left: Metric,
    right: Metric
) -> bool:
    r"""Check whether two metrics are equal.

    .. end-markdown

    :param left: Metric to compare.
    :type left: Metric
    :param right: Metric to compare.
    :type right: Metric
    :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
    """
    # No type arguments to standardize.
    # Convert arguments to c types.
    c_left = py_to_c(left, c_type=Metric, type_name="AnyMetric")
    c_right = py_to_c(right, c_type=Metric, type_name="AnyMetric")

    # Call library function.
    lib_function = lib.opendp_metrics___metric_equal
    lib_function.argtypes = [Metric, Metric]
    lib_function.restype = FfiResult

    output = c_to_py(unwrap(lib_function(c_left, c_right), BoolPtr))
    try:
        output.__opendp_dict__ = {
            '__function__': '_metric_equal',
            '__module__': 'metrics',
            '__kwargs__': {
                'left': left, 'right': right
            },
        }
    except AttributeError:  # pragma: no cover
        pass
    return output


def _metric_free(
    this
):
    r"""Internal function. Free the memory associated with `this`.

    .. end-markdown

    :param this: 
    :type this: Metric
    :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
    """
    # No type arguments to standardize.
    # Convert arguments to c types.
    c_this = this

    # Call library function.
    lib_function = lib.opendp_metrics___metric_free
    lib_function.argtypes = [Metric]
    lib_function.restype = FfiResult

    output = c_to_py(unwrap(lib_function(c_this), ctypes.c_void_p))
    try:
        output.__opendp_dict__ = {
            '__function__': '_metric_free',
            '__module__': 'metrics',
            '__kwargs__': {
                'this': this
            },
        }
    except AttributeError:  # pragma: no cover
        pass
    return output


def _symmetric_id_distance_get_identifier(
    metric: Metric
):
    r"""Retrieve the identifier of a `SymmetricIdDistance` metric.

    .. end-markdown

    :param metric: 
    :type metric: Metric
    :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
    """
    # No type arguments to standardize.
    # Convert arguments to c types.
    c_metric = py_to_c(metric, c_type=Metric, type_name="AnyMetric")

    # Call library function.
    lib_function = lib.opendp_metrics___symmetric_id_distance_get_identifier
    lib_function.argtypes = [Metric]
    lib_function.restype = FfiResult

    output = c_to_py(unwrap(lib_function(c_metric), AnyObjectPtr))
    try:
        output.__opendp_dict__ = {
            '__function__': '_symmetric_id_distance_get_identifier',
            '__module__': 'metrics',
            '__kwargs__': {
                'metric': metric
            },
        }
    except AttributeError:  # pragma: no cover
        pass
    return output


[docs] def absolute_distance( T: RuntimeTypeDescriptor ) -> Metric: r"""Construct an instance of the `AbsoluteDistance` metric. [absolute_distance in Rust documentation.](https://docs.rs/opendp/0.14.0/opendp/metrics/fn.absolute_distance.html) .. end-markdown :param T: :type T: :py:ref:`RuntimeTypeDescriptor` :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 """ # Standardize type arguments. T = RuntimeType.parse(type_name=T) # Convert arguments to c types. c_T = py_to_c(T, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_metrics__absolute_distance lib_function.argtypes = [ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_T), Metric)) try: output.__opendp_dict__ = { '__function__': 'absolute_distance', '__module__': 'metrics', '__kwargs__': { 'T': T }, } except AttributeError: # pragma: no cover pass return output
[docs] def change_one_distance( ) -> Metric: r"""Construct an instance of the `ChangeOneDistance` metric. .. end-markdown :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 """ # No type arguments to standardize. # No arguments to convert to c types. # Call library function. lib_function = lib.opendp_metrics__change_one_distance lib_function.argtypes = [] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(), Metric)) try: output.__opendp_dict__ = { '__function__': 'change_one_distance', '__module__': 'metrics', '__kwargs__': { }, } except AttributeError: # pragma: no cover pass return output
[docs] def change_one_id_distance( identifier ) -> ChangeOneIdDistance: r"""Construct an instance of the `ChangeOneIdDistance` metric. .. end-markdown :param identifier: :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 """ # No type arguments to standardize. # Convert arguments to c types. c_identifier = py_to_c(identifier, c_type=AnyObjectPtr, type_name="Expr") # Call library function. lib_function = lib.opendp_metrics__change_one_id_distance lib_function.argtypes = [AnyObjectPtr] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_identifier), Metric)) try: output.__opendp_dict__ = { '__function__': 'change_one_id_distance', '__module__': 'metrics', '__kwargs__': { 'identifier': identifier }, } except AttributeError: # pragma: no cover pass return output
[docs] def discrete_distance( ) -> Metric: r"""Construct an instance of the `DiscreteDistance` metric. .. end-markdown :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 """ # No type arguments to standardize. # No arguments to convert to c types. # Call library function. lib_function = lib.opendp_metrics__discrete_distance lib_function.argtypes = [] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(), Metric)) try: output.__opendp_dict__ = { '__function__': 'discrete_distance', '__module__': 'metrics', '__kwargs__': { }, } except AttributeError: # pragma: no cover pass return output
[docs] def frame_distance( inner_metric: Metric ) -> Metric: r"""`frame_distance` is a higher-order metric that contains multiple distance bounds for different groupings of data. .. end-markdown :param inner_metric: :type inner_metric: Metric :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 """ # No type arguments to standardize. # Convert arguments to c types. c_inner_metric = py_to_c(inner_metric, c_type=Metric, type_name="AnyMetric") # Call library function. lib_function = lib.opendp_metrics__frame_distance lib_function.argtypes = [Metric] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_inner_metric), Metric)) try: output.__opendp_dict__ = { '__function__': 'frame_distance', '__module__': 'metrics', '__kwargs__': { 'inner_metric': inner_metric }, } except AttributeError: # pragma: no cover pass return output
[docs] def hamming_distance( ) -> Metric: r"""Construct an instance of the `HammingDistance` metric. .. end-markdown :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 """ # No type arguments to standardize. # No arguments to convert to c types. # Call library function. lib_function = lib.opendp_metrics__hamming_distance lib_function.argtypes = [] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(), Metric)) try: output.__opendp_dict__ = { '__function__': 'hamming_distance', '__module__': 'metrics', '__kwargs__': { }, } except AttributeError: # pragma: no cover pass return output
[docs] def insert_delete_distance( ) -> Metric: r"""Construct an instance of the `InsertDeleteDistance` metric. .. end-markdown :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 """ # No type arguments to standardize. # No arguments to convert to c types. # Call library function. lib_function = lib.opendp_metrics__insert_delete_distance lib_function.argtypes = [] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(), Metric)) try: output.__opendp_dict__ = { '__function__': 'insert_delete_distance', '__module__': 'metrics', '__kwargs__': { }, } except AttributeError: # pragma: no cover pass return output
[docs] def l01inf_distance( metric: Metric ) -> Metric: r"""Construct an instance of the `L01InfDistance` metric. [l01inf_distance in Rust documentation.](https://docs.rs/opendp/0.14.0/opendp/metrics/fn.l01inf_distance.html) .. end-markdown :param metric: The metric used to compute distance between partitions. :type metric: Metric :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 """ # No type arguments to standardize. # Convert arguments to c types. c_metric = py_to_c(metric, c_type=Metric, type_name=None) # Call library function. lib_function = lib.opendp_metrics__l01inf_distance lib_function.argtypes = [Metric] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_metric), Metric)) try: output.__opendp_dict__ = { '__function__': 'l01inf_distance', '__module__': 'metrics', '__kwargs__': { 'metric': metric }, } except AttributeError: # pragma: no cover pass return output
[docs] def l02inf_distance( metric: Metric ) -> Metric: r"""Construct an instance of the `L02InfDistance` metric. [l02inf_distance in Rust documentation.](https://docs.rs/opendp/0.14.0/opendp/metrics/fn.l02inf_distance.html) .. end-markdown :param metric: The metric used to compute distance between partitions. :type metric: Metric :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 """ # No type arguments to standardize. # Convert arguments to c types. c_metric = py_to_c(metric, c_type=Metric, type_name=None) # Call library function. lib_function = lib.opendp_metrics__l02inf_distance lib_function.argtypes = [Metric] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_metric), Metric)) try: output.__opendp_dict__ = { '__function__': 'l02inf_distance', '__module__': 'metrics', '__kwargs__': { 'metric': metric }, } except AttributeError: # pragma: no cover pass return output
[docs] def l1_distance( T: RuntimeTypeDescriptor ) -> Metric: r"""Construct an instance of the `L1Distance` metric. [l1_distance in Rust documentation.](https://docs.rs/opendp/0.14.0/opendp/metrics/fn.l1_distance.html) .. end-markdown :param T: :type T: :py:ref:`RuntimeTypeDescriptor` :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 """ # Standardize type arguments. T = RuntimeType.parse(type_name=T) # Convert arguments to c types. c_T = py_to_c(T, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_metrics__l1_distance lib_function.argtypes = [ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_T), Metric)) try: output.__opendp_dict__ = { '__function__': 'l1_distance', '__module__': 'metrics', '__kwargs__': { 'T': T }, } except AttributeError: # pragma: no cover pass return output
[docs] def l2_distance( T: RuntimeTypeDescriptor ) -> Metric: r"""Construct an instance of the `L2Distance` metric. [l2_distance in Rust documentation.](https://docs.rs/opendp/0.14.0/opendp/metrics/fn.l2_distance.html) .. end-markdown :param T: :type T: :py:ref:`RuntimeTypeDescriptor` :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 """ # Standardize type arguments. T = RuntimeType.parse(type_name=T) # Convert arguments to c types. c_T = py_to_c(T, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_metrics__l2_distance lib_function.argtypes = [ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_T), Metric)) try: output.__opendp_dict__ = { '__function__': 'l2_distance', '__module__': 'metrics', '__kwargs__': { 'T': T }, } except AttributeError: # pragma: no cover pass return output
[docs] def linf_distance( T: RuntimeTypeDescriptor, monotonic: bool = False ) -> Metric: r"""Construct an instance of the `LInfDistance` metric. [linf_distance in Rust documentation.](https://docs.rs/opendp/0.14.0/opendp/metrics/fn.linf_distance.html) .. end-markdown :param monotonic: set to true if non-monotonicity implies infinite distance :type monotonic: bool :param T: The type of the distance. :type T: :py:ref:`RuntimeTypeDescriptor` :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 """ # Standardize type arguments. T = RuntimeType.parse(type_name=T) # Convert arguments to c types. c_monotonic = py_to_c(monotonic, c_type=ctypes.c_bool, type_name="bool") c_T = py_to_c(T, c_type=ctypes.c_char_p) # Call library function. lib_function = lib.opendp_metrics__linf_distance lib_function.argtypes = [ctypes.c_bool, ctypes.c_char_p] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_monotonic, c_T), Metric)) try: output.__opendp_dict__ = { '__function__': 'linf_distance', '__module__': 'metrics', '__kwargs__': { 'monotonic': monotonic, 'T': T }, } except AttributeError: # pragma: no cover pass return output
[docs] def metric_debug( this: Metric ) -> str: r"""Debug a `metric`. .. end-markdown :param this: The metric to debug (stringify). :type this: Metric :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 """ # No type arguments to standardize. # Convert arguments to c types. c_this = py_to_c(this, c_type=Metric, type_name=None) # Call library function. lib_function = lib.opendp_metrics__metric_debug lib_function.argtypes = [Metric] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_this), ctypes.c_char_p)) try: output.__opendp_dict__ = { '__function__': 'metric_debug', '__module__': 'metrics', '__kwargs__': { 'this': this }, } except AttributeError: # pragma: no cover pass return output
[docs] def metric_distance_type( this: Metric ) -> str: r"""Get the distance type of a `metric`. .. end-markdown :param this: The metric to retrieve the distance type from. :type this: Metric :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 """ # No type arguments to standardize. # Convert arguments to c types. c_this = py_to_c(this, c_type=Metric, type_name=None) # Call library function. lib_function = lib.opendp_metrics__metric_distance_type lib_function.argtypes = [Metric] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_this), ctypes.c_char_p)) try: output.__opendp_dict__ = { '__function__': 'metric_distance_type', '__module__': 'metrics', '__kwargs__': { 'this': this }, } except AttributeError: # pragma: no cover pass return output
[docs] def metric_type( this: Metric ) -> str: r"""Get the type of a `metric`. .. end-markdown :param this: The metric to retrieve the type from. :type this: Metric :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 """ # No type arguments to standardize. # Convert arguments to c types. c_this = py_to_c(this, c_type=Metric, type_name=None) # Call library function. lib_function = lib.opendp_metrics__metric_type lib_function.argtypes = [Metric] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_this), ctypes.c_char_p)) try: output.__opendp_dict__ = { '__function__': 'metric_type', '__module__': 'metrics', '__kwargs__': { 'this': this }, } except AttributeError: # pragma: no cover pass return output
[docs] def symmetric_distance( ) -> Metric: r"""Construct an instance of the `SymmetricDistance` metric. .. end-markdown :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 """ # No type arguments to standardize. # No arguments to convert to c types. # Call library function. lib_function = lib.opendp_metrics__symmetric_distance lib_function.argtypes = [] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(), Metric)) try: output.__opendp_dict__ = { '__function__': 'symmetric_distance', '__module__': 'metrics', '__kwargs__': { }, } except AttributeError: # pragma: no cover pass return output
[docs] def symmetric_id_distance( identifier ) -> SymmetricIdDistance: r"""Construct an instance of the `SymmetricIdDistance` metric. .. end-markdown :param identifier: :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 """ # No type arguments to standardize. # Convert arguments to c types. c_identifier = py_to_c(identifier, c_type=AnyObjectPtr, type_name="Expr") # Call library function. lib_function = lib.opendp_metrics__symmetric_id_distance lib_function.argtypes = [AnyObjectPtr] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_identifier), Metric)) try: output.__opendp_dict__ = { '__function__': 'symmetric_id_distance', '__module__': 'metrics', '__kwargs__': { 'identifier': identifier }, } except AttributeError: # pragma: no cover pass return output
[docs] def user_distance( identifier: str, descriptor = None ) -> Metric: r"""Construct a new UserDistance. Any two instances of an UserDistance are equal if their string descriptors are equal. Required features: `honest-but-curious` **Why honest-but-curious?:** Your definition of `d` must satisfy the requirements of a pseudo-metric: 1. for any $x$, $d(x, x) = 0$ 2. for any $x, y$, $d(x, y) \ge 0$ (non-negativity) 3. for any $x, y$, $d(x, y) = d(y, x)$ (symmetry) 4. for any $x, y, z$, $d(x, z) \le d(x, y) + d(y, z)$ (triangle inequality) .. end-markdown :param identifier: A string description of the metric. :type identifier: str :param descriptor: Additional constraints on the domain. :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("honest-but-curious") # No type arguments to standardize. # Convert arguments to c types. c_identifier = py_to_c(identifier, c_type=ctypes.c_char_p, type_name=None) c_descriptor = py_to_c(descriptor, c_type=ExtrinsicObjectPtr, type_name="ExtrinsicObject") # Call library function. lib_function = lib.opendp_metrics__user_distance lib_function.argtypes = [ctypes.c_char_p, ExtrinsicObjectPtr] lib_function.restype = FfiResult output = c_to_py(unwrap(lib_function(c_identifier, c_descriptor), Metric)) try: output.__opendp_dict__ = { '__function__': 'user_distance', '__module__': 'metrics', '__kwargs__': { 'identifier': identifier, 'descriptor': descriptor }, } except AttributeError: # pragma: no cover pass return output