Source code for oineus.diff.min_filtration

import numpy as np
import eagerpy as epy

from .. import _oineus
from .diff_filtration import DiffFiltration


[docs] def min_filtration(fil_1: DiffFiltration, fil_2: DiffFiltration) -> DiffFiltration: fil_1_under = fil_1.under_fil fil_2_under = fil_2.under_fil if fil_1_under.negate != fil_2_under.negate: raise ValueError("min_filtration: fil_1 and fil_2 must agree on negate") min_fil_under, _, _ = _oineus._min_filtration_with_indices(fil_1_under, fil_2_under) # The indices returned by _min_filtration_with_indices reflect the # pre-sort order used inside the C++ helper, not the final sort order # imposed by the Filtration constructor on the result. Re-derive the # source positions via uid so that vals_*[i] aligns with min_fil_under # at sorted_id i. n = min_fil_under.size() inds_1 = np.empty(n, dtype=np.int64) inds_2 = np.empty(n, dtype=np.int64) for i in range(n): uid = min_fil_under.cell(i).uid inds_1[i] = fil_1_under.sorted_id_by_uid(uid) inds_2[i] = fil_2_under.sorted_id_by_uid(uid) vals_1 = epy.astensor(fil_1.values)[inds_1] vals_2 = epy.astensor(fil_2.values)[inds_2] # C++ uses filtration order: with negate=True, "earlier" means larger value, # so the filtration min is max(v1, v2) in the original scale. if fil_1_under.negate: min_fil_values = epy.max(epy.stack((vals_1, vals_2)), axis=0).raw else: min_fil_values = epy.min(epy.stack((vals_1, vals_2)), axis=0).raw return DiffFiltration(min_fil_under, min_fil_values)