Vectorizers

The vectorizers module provides 8 different methods to convert persistence barcodes into fixed-length feature vectors.

Overview

Persistence barcodes are variable-length representations that need to be vectorized for machine learning. This module provides multiple vectorization strategies, each with different properties.

Available Methods:

  1. persistence_stats - Statistical summaries (fast, interpretable)

  2. betti_curve - Betti numbers over filtration values

  3. persistence_image - 2D histogram with Gaussian weighting

  4. persistence_landscape - Functional representation

  5. persistence_silhouette - Average persistence landscape

  6. entropy_summary - Information-theoretic features

  7. persistence_lifespan - Lifespan distribution

  8. persistence_tropical_coordinates - Tropical algebra representation

Quick Comparison

Method

Speed

Size

Best For

persistence_stats

Fast

dict (38 features)

Statistical summaries

betti_curve

Fast

Medium (100)

Betti number evolution

persistence_image

Medium

Large (400)

2D histogram representation

persistence_landscape

Medium

Large (500+)

Piecewise-linear landscape functions

persistence_silhouette

Medium

Medium (100)

Weighted average landscape

entropy_summary

Medium

Medium (100)

Entropy-based summary

persistence_lifespan

Fast

Medium (100)

Lifespan distribution

persistence_tropical_coordinates

Fast

7

Tropical polynomial invariants

Functions

persistence_stats

medtda.vectorizers.persistence_stats(barcode)[source]

Compute statistical summary of persistence diagram.

Computes comprehensive statistics including mean, std, median, IQR, percentiles for births, deaths, midpoints, and lifespans, plus total bar count and entropy.

Parameters:

barcode (numpy.ndarray) – Persistence diagram as n x 2 array (birth, death).

Returns:

Feature dictionary with 38 statistical features: [‘births_mean’, ‘births_std’, ‘births_median’, ‘births_iqr’, ‘births_range’, ‘births_p10’,

’births_p25’, ‘births_p75’, ‘births_p90’, ‘deaths_mean’, ‘deaths_std’, ‘deaths_median’, ‘deaths_iqr’, ‘deaths_range’, ‘deaths_p10’, ‘deaths_p25’, ‘deaths_p75’, ‘deaths_p90’, ‘midpoints_mean’, ‘midpoints_std’, ‘midpoints_median’, ‘midpoints_iqr’, ‘midpoints_range’, ‘midpoints_p10’, ‘midpoints_p25’, ‘midpoints_p75’, ‘midpoints_p90’, ‘lifespans_mean’, ‘lifespans_std’, ‘lifespans_median’, ‘lifespans_iqr’, ‘lifespans_range’, ‘lifespans_p10’, ‘lifespans_p25’, ‘lifespans_p75’, ‘lifespans_p90’, ‘count’, ‘entropy’]

Return type:

dict

Notes

Features include (in order): - Birth stats: mean, std, median, IQR, range, percentiles (10,25,75,90) - Death stats: mean, std, median, IQR, range, percentiles (10,25,75,90) - Midpoint stats: mean, std, median, IQR, range, percentiles (10,25,75,90) - Lifespan stats: mean, std, median, IQR, range, percentiles (10,25,75,90) - Bar count, persistence entropy

Compute statistical summaries of persistence values.

Signature:

def persistence_stats(barcode: np.ndarray) -> np.ndarray

Parameters:

  • barcode (np.ndarray) - Barcode array of shape (n, 2) with [birth, death] columns

Returns:

  • stats (dict) - Dictionary of 38 statistical features. Keys cover births, deaths, midpoints, and lifespans with statistics: mean, std, median, IQR, range, and percentiles (10, 25, 75, 90), plus count and entropy.

Example:

from medtda.vectorizers import persistence_stats

stats = persistence_stats(barcode)
print(f"Feature count: {len(stats)}")  # 38

# stats contains named features:
# - stats['births_mean'], stats['births_std'], ...
# - stats['lifespans_mean'], ...
# - stats['count'], stats['entropy']

betti_curve

medtda.vectorizers.betti_curve(barcode, resolution=100)[source]

Compute Betti curve vectorization.

The Betti curve represents the evolution of Betti numbers over the filtration.

Parameters:
  • barcode (numpy.ndarray) – Persistence diagram as n x 2 array (birth, death).

  • resolution (int, default=100) – Number of sample points for the curve.

Returns:

Feature vector of length resolution.

Return type:

numpy.ndarray

Compute Betti numbers as a function of filtration value.

Signature:

def betti_curve(
    barcode: np.ndarray,
    resolution: int = 100
) -> np.ndarray

Parameters:

  • barcode (np.ndarray) - Barcode array

  • resolution (int) - Number of sample points (default: 100)

Returns:

  • curve (np.ndarray) - 1D array of Betti numbers at each filtration value

Example:

from medtda.vectorizers import betti_curve

# Default resolution
curve = betti_curve(h1_barcode)
print(f"Curve shape: {curve.shape}")  # (100,)

# Higher resolution for more detail
curve_hires = betti_curve(h1_barcode, resolution=200)

persistence_image

medtda.vectorizers.persistence_image(barcode, bandwidth=0.2, resolution=20)[source]

Compute persistence image vectorization.

Converts the persistence diagram into a 2D image representation.

Parameters:
  • barcode (numpy.ndarray) – Persistence diagram as n x 2 array (birth, death).

  • bandwidth (float, default=0.2) – Bandwidth for Gaussian kernel.

  • resolution (int, default=20) – Resolution of the image (creates resolution x resolution grid).

Returns:

Flattened feature vector of length resolution^2.

Return type:

numpy.ndarray

Create a 2D histogram representation weighted by persistence.

Signature:

def persistence_image(
    barcode: np.ndarray,
    bandwidth: float = 0.2,
    resolution: int = 20
) -> np.ndarray

Parameters:

  • barcode (np.ndarray) - Barcode array

  • bandwidth (float) - Gaussian kernel bandwidth (default: 0.2)

  • resolution (int) - Grid resolution (default: 20)

Returns:

  • image (np.ndarray) - 2D array of shape (resolution, resolution)

Example:

from medtda.vectorizers import persistence_image

# Default parameters
pi = persistence_image(barcode)
print(f"Image shape: {pi.shape}")  # (20, 20)

# Higher resolution, smaller bandwidth
pi_hires = persistence_image(
    barcode,
    bandwidth=0.1,
    resolution=30
)

persistence_landscape

medtda.vectorizers.persistence_landscape(barcode, resolution=100, num_landscapes=5)[source]

Compute persistence landscape vectorization.

Represents the persistence diagram as a sequence of piecewise-linear functions.

Parameters:
  • barcode (numpy.ndarray) – Persistence diagram as n x 2 array (birth, death).

  • resolution (int, default=100) – Number of sample points per landscape.

  • num_landscapes (int, default=5) – Number of landscape functions to compute.

Returns:

Feature vector of length num_landscapes * resolution.

Return type:

numpy.ndarray

Compute persistence landscape representation.

Signature:

def persistence_landscape(
    barcode: np.ndarray,
    resolution: int = 100,
    num_landscapes: int = 5
) -> np.ndarray

Parameters:

  • barcode (np.ndarray) - Barcode array

  • resolution (int) - Number of sample points (default: 100)

  • num_landscapes (int) - Number of landscape functions (default: 5)

Returns:

  • landscape (np.ndarray) - 1D array of length num_landscapes * resolution

Example:

from medtda.vectorizers import persistence_landscape

landscape = persistence_landscape(barcode)
print(f"Shape: {landscape.shape}")  # (500,)

# Reshape for visualization
landscape_2d = landscape.reshape(5, 100)  # (num_landscapes, resolution)

persistence_silhouette

medtda.vectorizers.persistence_silhouette(barcode, resolution=100, weight=1)[source]

Compute persistence silhouette vectorization.

A weighted summary of the persistence diagram.

Parameters:
  • barcode (numpy.ndarray) – Persistence diagram as n x 2 array (birth, death).

  • resolution (int, default=100) – Number of sample points.

  • weight (float, default=1) – Weight parameter for silhouette computation.

Returns:

Feature vector of length resolution.

Return type:

numpy.ndarray

Compute persistence silhouette (average landscape).

Signature:

def persistence_silhouette(
    barcode: np.ndarray,
    resolution: int = 100,
    weight: float = 1.0
) -> np.ndarray

Parameters:

  • barcode (np.ndarray) - Barcode array

  • resolution (int) - Number of sample points (default: 100)

  • weight (float) - Weighting power (default: 1.0)

Returns:

  • silhouette (np.ndarray) - 1D array of length resolution

Example:

from medtda.vectorizers import persistence_silhouette

silhouette = persistence_silhouette(barcode, resolution=150)

entropy_summary

medtda.vectorizers.entropy_summary(barcode, resolution=100)[source]

Compute entropy summary function vectorization.

Based on persistence entropy, providing a statistical summary of the diagram.

Parameters:
  • barcode (numpy.ndarray) – Persistence diagram as n x 2 array (birth, death).

  • resolution (int, default=100) – Number of sample points.

Returns:

Feature vector of length resolution.

Return type:

numpy.ndarray

Compute entropy-based features.

Signature:

def entropy_summary(
    barcode: np.ndarray,
    resolution: int = 100
) -> np.ndarray

Parameters:

  • barcode (np.ndarray) - Barcode array

  • resolution (int) - Number of bins (default: 100)

Returns:

  • entropy_features (np.ndarray) - 1D array of entropy-based features

Example:

from medtda.vectorizers import entropy_summary

entropy_feats = entropy_summary(barcode)

persistence_lifespan

medtda.vectorizers.persistence_lifespan(barcode, resolution=100)[source]

Compute persistence lifespan curve vectorization.

Based on the normalized lifespan curve from persistence theory.

Parameters:
  • barcode (numpy.ndarray) – Persistence diagram as n x 2 array (birth, death).

  • resolution (int, default=100) – Number of sample points.

Returns:

Feature vector of length resolution.

Return type:

numpy.ndarray

Compute distribution of feature lifespans.

Signature:

def persistence_lifespan(
    barcode: np.ndarray,
    resolution: int = 100
) -> np.ndarray

Parameters:

  • barcode (np.ndarray) - Barcode array

  • resolution (int) - Number of bins (default: 100)

Returns:

  • lifespan_dist (np.ndarray) - 1D array of length resolution

Example:

from medtda.vectorizers import persistence_lifespan

lifespan = persistence_lifespan(barcode)

persistence_tropical_coordinates

medtda.vectorizers.persistence_tropical_coordinates(barcode, r=28)[source]

Compute tropical coordinate vectorization.

Uses tropical polynomial invariants to create a feature vector.

Parameters:
  • barcode (numpy.ndarray) – Persistence diagram as n x 2 array (birth, death).

  • r (float, default=28) – Parameter for tropical coordinate computation.

Returns:

Feature vector with 7 tropical coordinate features.

Return type:

numpy.ndarray

Compute tropical coordinates representation.

Signature:

def persistence_tropical_coordinates(
    barcode: np.ndarray,
    r: int = 28
) -> np.ndarray

Parameters:

  • barcode (np.ndarray) - Barcode array

  • r (int) - Parameter for tropical coordinate computation (default: 28)

Returns:

  • coords (np.ndarray) - 1D array of length 7

Example:

from medtda.vectorizers import persistence_tropical_coordinates

coords = persistence_tropical_coordinates(barcode, r=28)
print(f"Coordinate vector size: {len(coords)}")  # 7

Complete Examples

Example 1: Single Method

from medtda import FeatureExtractor
from medtda.vectorizers import persistence_image

# Extract barcodes
extractor = FeatureExtractor(return_barcodes=True)
features, barcodes = extractor.execute('image.nii.gz')

# Manually vectorize H1 barcode
h1_barcode = barcodes['H1']
pi_features = persistence_image(h1_barcode, bandwidth=0.15, resolution=25)

print(f"Persistence image size: {pi_features.shape}")

Example 2: Multiple Methods

from medtda.vectorizers import (
    persistence_stats,
    betti_curve,
    persistence_image
)
import numpy as np

# Get barcodes
h1 = barcodes['H1']

# Apply multiple vectorizations
stats = persistence_stats(h1)       # returns dict of 38 features
curve = betti_curve(h1, resolution=100)
image = persistence_image(h1, resolution=20)

# Concatenate for ML
features = np.concatenate([
    list(stats.values()),
    curve,
    image.flatten()
])

print(f"Combined feature vector size: {len(features)}")

Example 3: Comparing Methods

from medtda.vectorizers import *
import numpy as np

methods = {
    'stats': persistence_stats,
    'betti': lambda b: betti_curve(b, resolution=100),
    'pi': lambda b: persistence_image(b, resolution=20).flatten(),
    'landscape': lambda b: persistence_landscape(b).flatten(),
    'silhouette': lambda b: persistence_silhouette(b, resolution=100),
    'entropy': lambda b: entropy_summary(b, resolution=100),
    'lifespan': lambda b: persistence_lifespan(b, resolution=100),
    'tropical': lambda b: persistence_tropical_coordinates(b, r=28)
}

for name, method in methods.items():
    features = method(h1_barcode)
    print(f"{name:12s}: {len(features):4d} features")

Example 4: Custom Parameters

from medtda.vectorizers import persistence_image, betti_curve

# Experiment with different parameters

# Coarse persistence image (fast)
pi_coarse = persistence_image(barcode, resolution=15, bandwidth=0.3)

# Fine persistence image (detailed)
pi_fine = persistence_image(barcode, resolution=30, bandwidth=0.1)

# Low-resolution Betti curve
bc_low = betti_curve(barcode, resolution=50)

# High-resolution Betti curve
bc_high = betti_curve(barcode, resolution=200)

Example 5: Multi-Dimensional Barcodes

from medtda import BarcodeExtractor
from medtda.vectorizers import persistence_image
import numpy as np

# Extract all dimensions
extractor = BarcodeExtractor(max_dimension=2)
barcodes = extractor.execute(image_3d)

# Vectorize each dimension separately
features_by_dim = {}
for dim in [0, 1, 2]:
    if dim in barcodes and len(barcodes[dim]) > 0:
        features_by_dim[f'H{dim}'] = persistence_image(
            barcodes[dim],
            resolution=20
        ).flatten()

# Concatenate all dimensions
all_features = np.concatenate([
    features_by_dim['H0'],
    features_by_dim['H1'],
    features_by_dim['H2']
])

print(f"Total feature vector size: {len(all_features)}")

See Also