==============
Vectorization
==============

Vectorization converts variable-length persistence barcodes into fixed-length feature vectors suitable for machine learning. This guide covers all 8 vectorization methods available in MedTDA.

Overview
========

Persistence barcodes are sets of (birth, death) pairs with varying sizes across images. Machine learning requires fixed-length feature vectors. **Vectorization methods** solve this problem by summarizing barcodes into consistent-length representations.

.. code-block:: python

   from medtda import FeatureExtractor
   
   extractor = FeatureExtractor(
       normalize=True,
       vectorization_method='PersStats'
   )
   features = extractor.execute('image.nii.gz', 'mask.nii.gz')
   
   # features is a dictionary with fixed-length vectors for each homology dimension

Available Methods
=================

MedTDA provides 8 vectorization methods:

1. **Persistence Statistics** (``PersStats``) - Statistical summaries
2. **Betti Curves** (``BettiCurve``) - Betti numbers over filtration
3. **Persistence Images** (``PersImage``) - 2D histogram representation
4. **Persistence Landscapes** (``PersLandscape``) - Functional representation
5. **Persistence Silhouettes** (``PersSilhouette``) - Average landscape
6. **Entropy Summary** (``EntropySummary``) - Information-theoretic features
7. **Lifespan Curves** (``PersLifespan``) - Distribution of lifespans
8. **Tropical Coordinates** (``PersTropicalCoordinates``) - Tropical algebra

Method Comparison
-----------------

.. list-table::
   :header-rows: 1
   :widths: 30 20 50

   * - Method
     - Speed
     - Features
   * - Persistence Stats
     - Fast
     - 38/dim (named dict)
   * - Betti Curves
     - Medium
     - resolution/dim (default: 100)
   * - Persistence Images
     - Medium
     - resolution²/dim (default: 400)
   * - Persistence Landscapes
     - Medium
     - num_landscapes × resolution/dim (default: 500)
   * - Persistence Silhouettes
     - Medium
     - resolution/dim (default: 100)
   * - Entropy Summary
     - Fast
     - resolution/dim (default: 100)
   * - Lifespan Curves
     - Medium
     - resolution/dim (default: 100)
   * - Tropical Coordinates
     - Slow
     - 7/dim

Persistence Statistics
======================

Statistical summaries of persistence values, birth/death times, and midpoints.

Usage
-----

.. code-block:: python

   extractor = FeatureExtractor(
       vectorization_method='PersStats'
   )
   
   features = extractor.execute(image, mask)

Features Extracted
------------------

For each homology dimension (H₀, H₁, H₂), computes **38 features**:

**Birth time statistics (8):**
   * Mean, std, min, max, median, 25th percentile, 75th percentile, IQR

**Death time statistics (8):**
   * Mean, std, min, max, median, 25th percentile, 75th percentile, IQR

**Lifespan statistics (8):**
   * Mean, std, min, max, median, 25th percentile, 75th percentile, IQR

**Midpoint statistics (8):**
   * Mean, std, min, max, median, 25th percentile, 75th percentile, IQR
   * Midpoint = (birth + death) / 2

**Count (1):** Number of persistence pairs

**Entropy (1):** Persistent entropy

**Additional statistics (4):** Mean/std of 2nd birth and 2nd death

**Example output:**

.. code-block:: python

   {
       'PersStats_H0_mean': 0.523,
       'PersStats_H0_std': 0.142,
       'PersStats_H0_min': 0.001,
       'PersStats_H0_max': 0.987,
       # ... 24 more features for H0
       'PersStats_H1_mean': 0.234,
       # ... 28 features for H1
       # ... 28 features for H2 (if max_dimension=2)
   }

Betti Curves
============

Betti number (count of features) as a function of filtration value.

Usage
-----

.. code-block:: python

   extractor = FeatureExtractor(
       vectorization_method='BettiCurve'
   )
   
   # Configure resolution
   extractor.set_vectorization_params(
       'BettiCurve',
       resolution=100  # Number of points (default=100)
   )
   
   features = extractor.execute(image, mask)

Features Extracted
------------------

For each homology dimension, creates a curve with ``resolution`` points.

* 3 dimensions × 100 points = **300 features** (default)
* Captures how the number of topological features evolves

**Example:** With resolution=100:

.. code-block:: python

   {
       'BettiCurve_H0_f0': 0.0,
       'BettiCurve_H0_f1': 1.2,
       'BettiCurve_H0_f2': 2.5,
       # ... 97 more points for H0
       'BettiCurve_H1_f0': 0.0,
       # ... 100 points for H1
       # ... 100 points for H2
   }

Parameters
----------

.. code-block:: python

   extractor.set_vectorization_params(
       'BettiCurve',
       resolution=200  # More points for smoother curve
   )

Persistence Images
==================

2D histogram representation of persistence diagrams.

Usage
-----

.. code-block:: python

   extractor = FeatureExtractor(
       vectorization_method='PersImage'
   )
   
   # Configure parameters
   extractor.set_vectorization_params(
       'PersImage',
       resolution=20,        # Grid size (default)
       bandwidth=0.1         # Gaussian smoothing (default)
   )
   
   features = extractor.execute(image, mask)

Features Extracted
------------------

Each persistence diagram → 2D image → flattened vector.

* Grid size 20×20 = **400 features per dimension** (default)
* 3 dimensions × 400 = **1200 total features**

Parameters
----------

.. code-block:: python

   # Higher resolution (more features)
   extractor.set_vectorization_params(
       'PersImage',
       resolution=50,        # 2500 features/dim
       bandwidth=0.05        # Less smoothing
   )

   # Lower resolution (fewer features)
   extractor.set_vectorization_params(
       'PersImage',
       resolution=10,        # 100 features/dim
       bandwidth=0.2         # More smoothing
   )

Persistence Landscapes
======================

Functional representation based on landscape functions.

Usage
-----

.. code-block:: python

   extractor = FeatureExtractor(
       vectorization_method='PersLandscape'
   )
   
   # Configure parameters
   extractor.set_vectorization_params(
       'PersLandscape',
       num_landscapes=5,     # Number of landscape functions (default)
       resolution=100        # Points per landscape (default)
   )
   
   features = extractor.execute(image, mask)

Features Extracted
------------------

Multiple landscape functions sampled at regular intervals.

* 5 landscapes × 100 points = **500 features per dimension**
* 3 dimensions × 500 = **1500 total features**

Parameters
----------

.. code-block:: python

   # More landscapes (capture more detail)
   extractor.set_vectorization_params(
       'PersLandscape',
       num_landscapes=10,
       resolution=100
   )

   # Fewer features
   extractor.set_vectorization_params(
       'PersLandscape',
       num_landscapes=3,
       resolution=50
   )

Persistence Silhouettes
=======================

Weighted average of persistence landscapes (simpler than full landscapes).

Usage
-----

.. code-block:: python

   extractor = FeatureExtractor(
       vectorization_method='PersSilhouette'
   )
   
   # Configure resolution
   extractor.set_vectorization_params(
       'PersSilhouette',
       resolution=100
   )
   
   features = extractor.execute(image, mask)

Features Extracted
------------------

Single silhouette function per dimension.

* **100 features per dimension** (default resolution)
* 3 dimensions × 100 = **300 total features**

Entropy Summary
===============

Information-theoretic measures of barcode complexity.

Usage
-----

.. code-block:: python

   extractor = FeatureExtractor(
       vectorization_method='EntropySummary'
   )
   
   features = extractor.execute(image, mask)

Features Extracted
------------------

For each homology dimension, computes ``resolution`` features (default: 100).

**Small feature vector** per dimension.

Lifespan Curves
===============

Distribution of persistence values (lifespans).

Usage
-----

.. code-block:: python

   extractor = FeatureExtractor(
       vectorization_method='PersLifespan'
   )
   
   extractor.set_vectorization_params(
       'PersLifespan',
       resolution=100
   )
   
   features = extractor.execute(image, mask)

Features Extracted
------------------

Histogram of persistence values.

* **100 features per dimension** (default resolution)

Tropical Coordinates
====================

Tropical algebra representation (advanced).

Usage
-----

.. code-block:: python

   extractor = FeatureExtractor(
       vectorization_method='PersTropicalCoordinates'
   )
   
   features = extractor.execute(image, mask)

**Note:** Slower computation, specialized use.

Using Multiple Methods
=======================

Combine methods for comprehensive feature sets:

.. code-block:: python

   extractor = FeatureExtractor(
       normalize=True,
       vectorization_method=[
           'PersStats',
           'BettiCurve',
           'EntropySummary'
       ]
   )
   
   features = extractor.execute(image, mask)
   print(f"Total features: {len(features)}")

Features are combined with prefixes indicating method and dimension.

Example Workflow
================

.. code-block:: python

   from medtda import FeatureExtractor
   from sklearn.preprocessing import StandardScaler
   from sklearn.ensemble import RandomForestClassifier
   import pandas as pd
   
   # 1. Extract features with multiple methods
   extractor = FeatureExtractor(
       normalize=True,
       spacing=(1.0, 1.0, 1.0),
       vectorization_method=[
           'PersStats',
           'BettiCurve',
           'EntropySummary'
       ]
   )
   
   # 2. Process dataset
   results = []
   for case in dataset:
       features = extractor.execute(case['image'], case['mask'])
       features['label'] = case['label']
       results.append(features)
   
   # 3. Prepare for ML
   df = pd.DataFrame(results)
   X = df.drop('label', axis=1)
   y = df['label']
   
   # 4. Standardize
   scaler = StandardScaler()
   X_scaled = scaler.fit_transform(X)
   
   # 5. Train classifier
   clf = RandomForestClassifier()
   clf.fit(X_scaled, y)

Next Steps
==========

* :doc:`batch_processing` - Process multiple images
* :doc:`../theory/vectorization_methods` - Mathematical background
* :doc:`../api/vectorizers` - Vectorizer API reference
