The DTM-based (weighted Rips) filtration of Anai, Chazal, Glisse, Ike, Lecci, Rouvreau, Saulnier & Wasserman, "DTM-based filtrations" (arXiv:1811.04757, Prop. 3.5), checked byte-for-byte against GUDHI's own gudhi.dtm_rips_complex.DTMRipsComplex/gudhi.weighted_rips_complex.WeightedRipsComplex for p = 1 (DtmRipsStreamSpec; see .claude/WORKLOG-dtm-filtrations.md for the fetched source and every oracle value). Values are in the same "doubled"/diameter units every other VR stream in this codebase uses (GUDHI's own choice too, for the identical reason: consistency with plain, unweighted Rips, whose edge filtration is the raw pairwise distance, not half of it).
f(x) is the empirical distance-to-measure per ambient point (streams.DistanceToMeasure); at f = 0 everywhere (in particular at k = 1, DistanceToMeasure's own degenerate case) this reduces EXACTLY to plain Vietoris-Rips, threshold included -- DtmRipsStreamSpec checks this too.
p selects the ball-radius exponent of Def. 3.1 -- NOT DistanceToMeasure's own exponent q, a different knob entirely. Only p = 1 and p = 2 are implemented:
p = 1:t(f_x, f_y, d) = max(f_x, f_y, (d + f_x + f_y) / 2). The only variant GUDHI's own Python bindings implement, and the one every published worked example (including this class's own regression oracle) targets.p = 2: closed formt(f_x, f_y, d) = max(f_x, f_y, sqrt(u^2 + f_x^2))whereu = (d^2 + f_y^2 - f_x^2) / (2d), valid (and symmetric in x/y -- verified algebraically, not just numerically) whenever|f_y^2 - f_x^2| = 1-- the inherited default "max pairwise distance" filtration functional is already exactly the flag-complex extension this construction wants (same relationshipWitnessMetricSpacehas toLazyWitnessSimplexStream). The only override needed is at dimension 0: unlike plain VR (where every vertex is born at filtration 0, so the base class's hardcodeddim 0.0and its unsorted, unfilteredcase 0vertex emission are both harmless -- see.claude/WORKLOG-dtm-filtrations.mdfor why), THIS is the first coface stream in this codebase whose vertices have distinct, nonzero filtration values, socase 0MUST be sorted byfiltrationOrdering.reverseand filtered by threshold like every other dimension (ordering contract rule 2 in CLAUDE.md) -- silently violating that would corruptChain's pivot table exactly like the historical "no tie-break" bugs did, and would let vertices pastmaxFiltrationValueleak into the complex as spurious isolated components.
maxFiltrationValue defaults (via None) to the reified space's own minimumEnclosingRadius, the same convention every other flag-complex VR stream in this codebase uses (not GUDHI's own max_filtration = +Infinity default) -- valid here for a real, checked reason, not just by analogy: t(f_x, f_y, d) >= max(f_x, f_y) by construction for both p = 1 and p = 2 (immediate for p=1's outer max; for p=2, t^2 = u^2 + f_x^2 >= f_x^2 and the symmetric v = d - u form gives t^2 = v^2 + f_y^2 >= f_y^2 too), so taking x* = argmin_x max_y distance(x,y) and R = distance(x*,ยท)'s own max: for every vertex z, 2*f(z) = 2*f_z) -- every vertex's own birth is <= R, so truncating there cannot silently drop a vertex, and beyond R the complex is a cone from x* exactly as in the unweighted case. Refuses engine=ripser in matlab.TDA4j's dispatch (both Ripser engines assume vertex births at 0 and a diameter-only incremental formula); naive/chunks/cohomology all consume this like any other CofaceSimplexStream[Int, Double].
Attributes
- Companion
- object
- Experimental
- true
- Graph
-
- Supertypes