Current version: 0.2.1
Software for computing the Skyscraper invariant of persistence modules over
Author: Jan Jendrysiak
Developed at: TU Graz and University of Oxford
Theoretical development: Jan Jendrysiak and Marc Fersztand
License: GNU GPL v3
Contact: github.com/JanJend
If you use this software in your research, please cite the SoCG 2026 and arXiv/journal version of the accompanying paper: "Computing the Skyscraper Invariant" by Marc Fersztand and Jan Jendrysiak.
The Skyscraper invariant is a filtration of the classical rank invariant introduced by Jacquard, Fersztand, Nanda, and Tillmann in [arXiv:2303.16075].
Main programs:
hnf_main: Computes the Skyscraper invariant from persistence module presentationsfilt_landscape_from_sky: Generates filtered landscapes from.skyfiles
Additional tools:
pres_to_quiver: Converts module presentations to quiver representationsarrangement_test: Tests arrangement computationshnf_at_origin: Computes indecomposables at the originlarge_induced_indecomposables: Extracts large induced indecomposablesrandom_uni_B1: Generates random uniquely generated modules
- C++17 or later
- CMake 3.15+
- AIDA — Must be built and installed as a library
- Persistence-Algebra — Header-only library
- Boost (timer, chrono, system components)
- HDF5
- CGAL
# Ubuntu/Debian
sudo apt-get install libboost-all-dev libhdf5-dev libcgal-dev cmake
# macOS
brew install boost hdf5 cgal cmakegit clone https://github.com/JanJend/AIDA.git
cd AIDA
mkdir build && cd build
cmake ..
make
sudo make install # Or install to a custom locationgit clone https://github.com/JanJend/Persistence-Algebra.gitgit clone <this-repository>
cd skyscraper
mkdir build && cd build
# Configure paths to dependencies
cmake .. \
-DAIDA_DIR=../../AIDA \
-DPERSISTENCE_ALGEBRA_DIR=../../Persistence-Algebra
# Build
make
# Install (optional)
sudo make installBuild options:
-DCMAKE_BUILD_TYPE=Release(default) orDebug-DBUILD_EXP=ON— Build only experimental executables (hnf_at_origin,random_uni_B1,large_induced_indecomposables)
Debug builds append a _debug suffix to executables.
The C++ entry points accept CoordGradedSparseMatrix<Scalar, Dimension, Index>,
GridGradedSparseMatrix<Scalar, Dimension, Index>,
R2GradedSparseMatrix<Index, Storage>, and modules over these types.
R2CSCMat is R2GradedSparseMatrix<int, CSCStorage<int>>.
CSC entries are copied into editable vector columns before computation. Direct
coordinates are embedded in a grid; grid inputs retain their unused coordinates.
Both fixed and smart grid computations keep one working copy for the entire run.
The caller's matrices and stored resolutions are preserved.
The invariant requires two grading parameters. Its existing geometry uses
double and its combinatorial core uses int: coordinates must be exactly
representable as doubles, and ranks and grid-axis sizes must fit int.
Conversion fails explicitly rather than merging distinct coordinates.
Computes the Skyscraper invariant for persistence modules.
Syntax:
hnf_main [OPTIONS] INPUT_FILEInput formats:
.firep— Finitely presented persistence module.scc— Single chain complex (from AIDA).sccsum— Sum of chain complexes (from AIDA)
Input must be a (sequence of) .scc or .firep presentations that are minimised.
Output:
A .sky file containing endpoints of staircase intervals with
General:
-h, --help Display this help message
-v, --version Display version information
Input:
-d, --is_decomposed Treat input as already decomposed (skip AIDA step)
-x, --test_files Run on built-in test files instead of an input file
Computation:
-e, --exhaustive Always iterate over all decompositions in a batch
-r, --resolution <x,y> Set grid resolution (default: 200,200)
-y, --dynamic_grid Disable dynamic grid (use fixed resolution)
-k, --grassmann <n> Set Grassmann value for the computation
-u, --subdivision Enable subdivision mode
-f, --alpha Enable computation of alpha-homs
-j, --no_hom_opt Disable optimised hom-space calculation
Output:
-o, --output [file] Write output to file
Defaults to <input_file>.sky if no path is given
-g, --diagonal Also save a diagonal-restricted copy (for landscapes)
-c, --basechange Save the base change alongside the decomposition
Diagnostics:
-s, --statistics Show statistics about indecomposable summands
-t, --runtime Show runtime statistics and timers
-p, --progress Suppress the progress bar
-l, --less_console Suppress most console output
Basic computation:
hnf_main -o example_files/presentations/torus1.sccHigh-resolution output with statistics:
hnf_main -r 500,500 -s -t -o output.sky input.sccsumAlready decomposed input:
hnf_main -d -o decomposed.sccsumGenerates filtered Hilbert function landscapes from .sky files.
Syntax:
filt_landscape_from_sky <input.sky> [theta] [k] [diff] [theta_prime]Arguments:
<input.sky> Path to the input skyscraper file
[theta] double Filtration parameter (default: 0.0)
[k] int Landscape level (default: 1)
[diff] bool 'true' to compute a difference landscape (default: false)
[theta_prime] double Second filtration parameter for difference landscape (default: 0.0)
Output:
A PNG image named <input>_landscape_<theta>[_diff<theta_prime>].png.
# Generate landscape at default theta
filt_landscape_from_sky example_files/sky/two_circles.sky
# Landscape at theta=0.4, level k=2
filt_landscape_from_sky example_files/sky/two_circles.sky 0.4 2
# Difference landscape between theta=0.2 and theta=0.6
filt_landscape_from_sky example_files/sky/two_circles.sky 0.2 1 true 0.6Visualization scripts (Python):
visualisation/filtered_hilbert_function.py— Filtered Hilbert function plotsvisualisation/hnf_landscape.py— HNF landscape visualizationvisualisation/visualise_sky_landscape.py— Sky file visualizationvisualisation/hnf_visualise_highslope.py— High-slope regionsvisualisation/hnf_visualise_lowslope.py— Low-slope regions
.scc — Single chain complex from AIDA decomposition; contains a graded module presentation.
.sccsum — Sum of chain complexes; multiple .scc presentations combined.
.firep — Finitely presented persistence module; direct module presentation.
.sky — Skyscraper invariant. Grid-based representation where each grid point contains a list of staircase intervals; each staircase has a minimal element, corners, and
Converts module presentations to quiver representations for external analysis.
pres_to_quiver input.sccTests subdivision and arrangement computations.
arrangement_test [options] input_fileComputes indecomposable summands at the origin point.
hnf_at_origin input.sccExtracts large induced indecomposable modules from decompositions.
large_induced_indecomposables input_directoryGenerates random uni-B1 type modules for testing.
random_uni_B1 dimension count# 1. Compute the skyscraper invariant
hnf_main -r 300,300 -s -t -o example_files/presentations/torus1.scc
# 2. Generate a filtered landscape
filt_landscape_from_sky example_files/sky/torus1.sky 0.4 1
# 3. Visualize with Python
python visualisation/visualise_sky_landscape.py example_files/sky/torus1.skyShell scripts for batch processing are in tests/:
run_sky_on_folder.sh— Runhnf_mainon multiple filesrun_at_origin_on_folder.sh— Batch origin computationrun_quiver_on_folder.sh— Batch quiver conversionrun_arrangement_on_folder.sh— Batch arrangement testsrun_cheng_on_folder.sh— Batch Cheng algorithm runssky_increasing_grid.sh— Run on increasing grid resolutionsrandom_uni_B1.sh— Batch random module generationextract_times.sh— Extract timing information from output
skyscraper/
├── src/ # Implementation files
├── include/ # Header files
├── example_files/ # Example inputs and outputs
│ ├── presentations/ # .scc and .sccsum input examples
│ ├── indecomps_at/ # Indecomposable summands at grid points
│ ├── sky/ # Precomputed .sky files and landscape PNGs
│ └── quiver_reps/ # Quiver representation outputs
├── visualisation/ # Python visualization scripts
└── tests/ # Batch processing shell scripts
- Default resolution (200×200) balances accuracy and speed.
- Large resolutions (>500×500) may require significant memory.
- Use
-dwhen input is pre-decomposed to skip the AIDA step. - Use
-sand-tfor performance profiling. - Debug builds (
_debugsuffix) are slower but provide better error information.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- AIDA — Persistence module decomposition
- Persistence-Algebra — Algorithmic Algebra for finitely presented R^2-modules.
For issues, questions, or contributions, open an issue on the repository or contact github.com/JanJend.