.. _theory_persistent_homology:

====================
Persistent Homology
====================

.. contents:: Contents
   :local:
   :depth: 2

Introduction
============

**Persistent Homology (PH)** is the core technique in topological data analysis that tracks topological features across multiple scales. Unlike traditional homology that analyzes a single space, persistent homology studies how features evolve as we vary a parameter.

For medical images, this parameter is typically the **intensity threshold**, allowing us to analyze structures that persist across different intensity levels.

Key Idea
--------

As we sweep through intensity values (from dark to bright or vice versa), topological features:

* **Appear** (are born) at certain thresholds
* **Persist** across a range of thresholds
* **Disappear** (die) at other thresholds

Features that persist for a long time are considered significant, while short-lived features are often noise.

Homology Groups
===============

Persistent homology computes **Betti numbers** at each dimension:

H0: Connected Components (:math:`\beta_0`)
------------------------------

**Dimension 0 homology** counts the number of connected components.

**Intuitive Definition:**

* H0 features are separate, disconnected regions
* Birth: When a new component appears
* Death: When two components merge together

**In Medical Images:**

::

    Example: Tumor Detection
    
    As we threshold a CT scan at increasing intensity values:
    1. Individual bright spots appear (H0 births)
    2. Spots grow larger
    3. Spots merge together (H0 deaths)
    
    Persistent H0 features → Significant bright regions

**Properties:**

* Number of H0 features = number of connected components
* Exactly one H0 feature has infinite persistence (the entire image)
* Short-lived H0 features often represent noise or small artifacts

H1: Loops and Holes (:math:`\beta_1`)
-------------------------

**Dimension 1 homology** detects loops and circular structures.

**Intuitive Definition:**

* H1 features are 1-dimensional cycles or holes
* Birth: When a loop first forms
* Death: When the loop gets filled in

**In Medical Images:**

::

    Example: Blood Vessel Networks
    
    As we threshold vessel images:
    1. Individual vessels appear (H0)
    2. Vessels connect into branching networks
    3. Loops form where vessels create circuits (H1 birth)
    4. Loops fill in at higher thresholds (H1 death)
    
    Persistent H1 features → Significant vascular loops

**Properties:**

* H1 counts the number of independent loops
* Robust to small perturbations
* Captures network connectivity

H2: Voids and Cavities (:math:`\beta_2`)
----------------------------

**Dimension 2 homology** identifies enclosed 3D voids (only for 3D images).

**Intuitive Definition:**

* H2 features are enclosed volumes or cavities
* Birth: When a cavity is fully enclosed
* Death: When the cavity gets filled

**In Medical Images:**

::

    Example: Lung Cysts
    
    In a 3D lung CT scan:
    1. Air-filled regions appear as low intensity
    2. Cysts (enclosed air pockets) form H2 features
    3. Larger cysts have higher persistence
    
    Persistent H2 features → Significant cavities or cysts

**Properties:**

* H2 counts enclosed voids
* Relevant for 3D volumetric images
* Detects hollow structures

Birth and Death Times
======================

Birth Time
----------

The **birth time** of a feature is the filtration value (intensity threshold) at which it first appears.

**Mathematical Formulation:**

Persistent homology tracks features through a **persistence module** - a sequence of vector spaces :math:`V = \{V_i \mid 0 \leq i \leq n\}` connected by linear maps :math:`a = \{a_i : V_{i-1} \to V_i\}`:

.. math::

   V_0 \xrightarrow{a_1} V_1 \xrightarrow{a_2} \cdots \xrightarrow{a_n} V_n

where :math:`V_i = H_d(X_i)` is the d-th homology group at filtration step i.

**Birth Identification:** A homology class is born at index p if it first appears in :math:`V_p` but is not in the image of :math:`a_p` (i.e., it's a new feature not inherited from :math:`V_{p-1}`).

**Death Identification:** A feature born at p dies at index q if the homology class becomes part of the image of some map at step q (merging with an older feature or being filled in).

**Index to Value:** The filtration indices are typically mapped to real-valued parameters (intensity thresholds, distance scales, etc.) to obtain birth and death times as real numbers.

**Practical Interpretation:**

* Lower birth time means feature appears early in filtration
* Higher birth time means feature appears late in filtration

**In sublevel filtration:**

* Birth time = intensity at which feature begins

**In superlevel filtration:**

* Birth time = intensity at which feature begins (from high to low)

Death Time
----------

The **death time** of a feature is the filtration value at which it disappears.

**Practical Interpretation:**

* Death - Birth = Persistence (lifespan)
* Features never dying have infinite persistence

**In sublevel filtration:**

* Death time = intensity at which feature merges or fills

**In superlevel filtration:**

* Death time = intensity at which feature merges or fills

Persistence
-----------

The **persistence** of a feature is its lifespan:

.. math::

   \text{Persistence} = \text{Death} - \text{Birth}

**Significance:**

* **High persistence** means stable, significant feature
* **Low persistence** means unstable, possibly noise
* **Infinite persistence** means feature never disappears

**Filtering Strategy:**

Most applications filter features by persistence:

::

    # Keep only significant features
    threshold = 0.1
    significant_features = barcode[barcode[:, 1] - barcode[:, 0] > threshold]

Persistence Computation
========================

Computing persistent homology involves:

1. **Build a filtration** from the image (see :doc:`filtrations`)
2. **Compute homology** at each filtration step
3. **Track features** as filtration parameter varies
4. **Record birth and death** events

MedTDA uses **cubical complex** filtrations built directly from image voxels.

**Computational Algorithm:**

MedTDA uses the **standard persistence algorithm** based on boundary matrix reduction:

**Key Steps:**

1. **Build filtered complex:** Construct cubical cells from image voxels, ordered by filtration value
2. **Construct boundary matrix:** Each column represents a cell, entries encode the boundary operator
3. **Reduce matrix:** Apply column operations to achieve reduced echelon form
4. **Extract pairings:** Each zero column pairs with its lowest-one column, encoding birth-death pairs
5. **Generate barcodes:** Convert matrix pairings to interval representation

**Complexity:** For an n-voxel image:

* Time: O(n³) worst case, often much faster in practice
* Space: O(n²) for storing boundary matrix

**Optimizations:**

* **Clearing optimization:** Skip columns that can't produce new features
* **Compression:** Exploit cubical structure to reduce memory
* **Parallel computation:** Process multiple dimensions simultaneously

**Libraries:** MedTDA uses GUDHI (for general complexes) and cripser (optimized for cubical complexes from images).

Multi-Scale Analysis
====================

Persistent homology naturally provides multi-scale analysis:

Scale Invariance
----------------

Features are characterized by their persistence, not absolute scale:

* Same topological feature at different image resolutions
* Robust to imaging parameters
* Consistent across different scanners/protocols

Hierarchical Structure
----------------------

Barcodes reveal hierarchical organization:

::

    Long bars = Global, dominant structures
    Medium bars = Secondary features
    Short bars = Fine details or noise

Feature Selection by Scale
---------------------------

Choose features at relevant scales:

::

    # Focus on medium-scale features
    min_persistence = 0.05
    max_persistence = 0.5
    
    medium_scale = barcode[
        (barcode[:, 1] - barcode[:, 0] >= min_persistence) &
        (barcode[:, 1] - barcode[:, 0] <= max_persistence)
    ]

Practical Examples
==================

Example 1: Tumor Heterogeneity
-------------------------------

Using H0 and H1 to characterize tumor internal structure::

    from medtda import BarcodeExtractor
    
    extractor = BarcodeExtractor(
        filtration_type='sublevel',
        max_dimension=1
    )
    
    barcodes = extractor.execute(tumor_image)
    
    # H0: Number of distinct bright regions
    h0_persistence = barcodes['H0'][:, 1] - barcodes['H0'][:, 0]
    n_regions = np.sum(h0_persistence > 0.1)
    
    # H1: Number of loop structures
    h1_persistence = barcodes['H1'][:, 1] - barcodes['H1'][:, 0]
    n_loops = np.sum(h1_persistence > 0.1)
    
    print(f"Tumor has {n_regions} distinct regions and {n_loops} loop structures")

Example 2: Vessel Network Complexity
-------------------------------------

Analyzing vascular topology::

    # Extract vessels (bright on dark background)
    barcodes = extractor.execute(vessel_image)
    
    # H1 features represent loops in vessel network
    h1_barcode = barcodes['H1']
    
    # Network complexity metrics
    total_loops = len(h1_barcode)
    persistent_loops = np.sum((h1_barcode[:, 1] - h1_barcode[:, 0]) > 0.15)
    
    print(f"Total loops: {total_loops}")
    print(f"Significant loops: {persistent_loops}")

Example 3: Multi-Dimensional Analysis
--------------------------------------

Complete topological characterization::

    extractor = BarcodeExtractor(max_dimension=2)
    barcodes = extractor.execute(image_3d)
    
    for dim in [0, 1, 2]:
        barcode = barcodes[f'H{dim}']
        persistence = barcode[:, 1] - barcode[:, 0]
        
        print(f"\nH{dim}:")
        print(f"  Total features: {len(barcode)}")
        print(f"  Mean persistence: {persistence.mean():.3f}")
        print(f"  Max persistence: {persistence.max():.3f}")

Mathematical Formulation
========================

**Homology Theory:**

* Chain complexes and boundary operators
* Homology groups: :math:`H_k(X) = \ker(\partial_k) / \text{im}(\partial_{k+1})`
* Betti numbers: :math:`\beta_k = \text{rank}(H_k(X))`

**Persistence Modules:**

* Functors :math:`F: \mathbb{R} \to \text{Vec}`
* Persistence diagrams and barcodes
* Interleaving distance and stability

**Computational Topology:**

* Boundary matrix reduction algorithm
* Persistent homology computation
* Complexity analysis

See :doc:`../../references` for recommended reading on these topics.

Connection to Medical Imaging
==============================

Intensity-Based Filtrations
----------------------------

Medical images naturally define filtrations:

* **CT scans:** Hounsfield units define natural thresholds
* **MRI:** Signal intensities vary with tissue properties
* **Microscopy:** Cell/nuclear staining intensities

Feature Interpretation
----------------------

Persistent features correspond to anatomical structures:

* **H0:** Separate organs, lesions, cells
* **H1:** Vessel loops, glandular structures, airways
* **H2:** Cysts, ventricles, air spaces

Quantitative Biomarkers
------------------------

Persistence-based features as biomarkers:

* Number of persistent features = Structural complexity
* Maximum persistence = Dominant feature size
* Persistence distribution = Heterogeneity measure

See Also
========

* :doc:`filtrations` - How filtrations are constructed
* :doc:`barcodes_diagrams` - Visualizing and interpreting results
* :doc:`vectorization_methods` - Converting to feature vectors
* :doc:`../user_guide/persistent_homology` - Practical usage guide
* :doc:`../api/ph_computer` - PH computation API
