Inputs, duplicates, and essential points

中文

Accepted array-like inputs

Every diagram must contain real values and convert to a float64 array of shape (n, 2):

import numpy as np
import topp

topp.bottleneck_distance([[0, 1], [1, 3]], np.array([[0.0, 2.0]]))

Lists, tuples, NumPy arrays, integer arrays, and non-contiguous views are accepted. Elements may be Python/NumPy real numbers, Decimal, or Fraction. Topp validates and copies them into C-contiguous float64 storage; finite values outside the float64 range are not converted to infinity.

Empty diagrams

Both common spellings are accepted:

empty_a = []
empty_b = np.empty((0, 2))

assert topp.bottleneck_distance(empty_a, empty_b) == 0.0

Diagonal and duplicate points

Finite diagonal points (a, a) contribute zero and are ignored by the distance calculation. Duplicate off-diagonal rows retain multiplicity:

duplicates = [[0.0, 1.0], [0.0, 1.0], [0.0, 1.0]]
assert topp.bottleneck_distance(duplicates, duplicates) == 0.0

Essential points

Three forms are supported:

import math

positive = [1.0, math.inf]
negative = [-math.inf, 2.0]
fully = [-math.inf, math.inf]

Essential points match only the same type:

a = [[1.0, math.inf], [-math.inf, 2.0], [-math.inf, math.inf]]
b = [[2.0, math.inf], [-math.inf, 4.0], [-math.inf, math.inf]]

assert topp.bottleneck_distance(a, b) == 2.0
assert topp.wasserstein_distance(a, b) == 3.0

If the multiplicity of any essential type differs, the result is inf.

Invalid inputs

Topp raises TypeError for complex values, masked arrays, booleans, numeric strings, and other non-real inputs. It raises ValueError for finite values that cannot be represented as float64, NaN, birth > death, birth=+inf, death=-inf, and other invalid infinity forms. It never drops imaginary parts or masks, swaps coordinates, or silently deletes invalid rows.

>>> topp.prepare_diagram([[2.0, 1.0]])
Traceback (most recent call last):
...
ValueError: diagram points must satisfy birth <= death

See Mathematical conventions for the matching rules.