### Add Examples Subdirectory (CMake) Source: https://github.com/mrzv/dionysus/blob/master/CMakeLists.txt Includes the 'examples' subdirectory for building project examples if the 'build_examples' option is enabled. ```cmake if (build_examples) add_subdirectory (examples) endif (build_examples) ``` -------------------------------- ### Pybind11 Setup and Module Compilation Source: https://github.com/mrzv/dionysus/blob/master/bindings/python/CMakeLists.txt This snippet configures Pybind11, finds the required package, and then adds a C++ module named '_dionysus'. It includes several C++ source files and installs the resulting target to the 'dionysus' directory. Dependencies include Pybind11 and potentially Hera for include directories. ```cmake set(PYBIND11_FINDPYTHON ON) find_package(pybind11 CONFIG REQUIRED) file(GLOB DIONYSUS_PYTHON "${CMAKE_CURRENT_SOURCE_DIR}/dionysus/*.py") install(FILES ${DIONYSUS_PYTHON} DESTINATION dionysus) # needed to make ext/hera compile include_directories(${PROJECT_SOURCE_DIR}/ext/hera/include) pybind11_add_module(_dionysus dionysus.cpp filtration.cpp simplex.cpp field.cpp rips.cpp freudenthal.cpp persistence.cpp boundary.cpp diagram.cpp omni-field-persistence.cpp cohomology-persistence.cpp zigzag-persistence.cpp bottleneck-distance.cpp wasserstein-distance.cpp) install(TARGETS _dionysus DESTINATION dionysus) ``` -------------------------------- ### Install Dionysus from PyPI (Python) Source: https://github.com/mrzv/dionysus/blob/master/doc/index.md Installs the Dionysus Python package from the Python Package Index (PyPI) using pip. This is the simplest method for installing the library. Use the --upgrade flag to update an existing installation. ```bash pip install --verbose dionysus ``` ```bash pip install --verbose --upgrade dionysus ``` -------------------------------- ### Setup Filtration for Zigzag Persistence - Python Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/fast-zigzag-apex.md Demonstrates how to define simplices and their appearance/disappearance times for setting up a filtration used in zigzag persistence. This is the initial step before computing the extended persistence cone. ```python # from __future__ import print_function # if you are using Python 2 import dionysus as d simplices = [[0], [1], [0,1], [2], [0,2], [1,2]] times = [[.4,.6,.7,1.], [.1,.2,.3,1.], [.8,.95], [.5], [.8,1.], [.9,1.]] ``` -------------------------------- ### Install Dionysus from Development Repository Source: https://github.com/mrzv/dionysus/blob/master/README.rst Installs the latest version of Dionysus directly from its GitHub development repository using pip. This ensures you have the most recent features and bug fixes. ```bash pip install --verbose `git+https://github.com/mrzv/dionysus.git `_ ``` -------------------------------- ### Install Dionysus from Development Repository (Python) Source: https://github.com/mrzv/dionysus/blob/master/doc/index.md Installs the latest version of the Dionysus Python package directly from its development repository on GitHub using pip. This is useful for accessing the most recent features and bug fixes. ```bash pip install --verbose git+https://github.com/mrzv/dionysus.git ``` -------------------------------- ### Install Dionysus via Pip Source: https://github.com/mrzv/dionysus/blob/master/README.rst Installs the Dionysus Python package from PyPI. Use --upgrade to update an existing installation. This is the simplest method for installing. ```bash pip install --verbose dionysus ``` ```bash pip install --verbose --upgrade dionysus ``` -------------------------------- ### Compute and Plot Persistence Diagrams with Dionysus Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/lower-star.md Shows how to compute the homology persistence and initialize the persistence diagrams from a filtration generated by Dionysus. It also includes examples of plotting the resulting diagrams. ```python >>> import dionysus as d >>> # Assuming f_lower_star is already computed as shown previously >>> p = d.homology_persistence(f_lower_star) >>> dgms = d.init_diagrams(p, f_lower_star) >>> d.plot.plot_diagram(dgms[0]) >>> d.plot.plot_diagram(dgms[1]) ``` -------------------------------- ### Compute Zigzag Persistence with Matrix Tracking (Python) Source: https://context7.com/mrzv/dionysus/llms.txt This example demonstrates computing zigzag persistence for filtrations that include both additions and removals of simplices over time. It uses the 'fast_zigzag' function to build the filtration and then 'homology_persistence' with 'matrix_v' method for computation. The output includes extracting zigzag diagrams and their representatives (apex, bottom, middle, top). ```python import dionysus as d # Define simplices and their appearance times simplices = [[0], [1], [0,1], [2], [0,2], [1,2]] times = [ [0.4, 0.6, 0.7, 1.0], # vertex 0: appears at 0.4, 0.6, 0.7, 1.0 [0.1, 0.2, 0.3, 1.0], # vertex 1 [0.8, 0.95], # edge [0,1] [0.5], # vertex 2 [0.8, 1.0], # edge [0,2] [0.9, 1.0] # edge [1,2] ] # Display input for s, ts in zip(simplices, times): print(f"Simplex {s}: times {ts}") # Compute fast zigzag (cone construction) cone = d.fast_zigzag(simplices, times) print(f"Cone filtration: {cone}") # Compute persistence with matrix tracking r, v = d.homology_persistence(cone, method='matrix_v', prime=2) # Extract zigzag diagrams dgms = d.init_zigzag_diagrams(r, cone) # Iterate over dimensions and diagram types max_t = max(max(t) for t in times) for dim, type_dgm in enumerate(dgms): print(f"Dimension {dim}:") for diagram_type, dgm in type_dgm.items(): print(f" Type {diagram_type}:") for pt in dgm: print(f" ({pt.birth:.2f}, {pt.death:.2f})") # Extract apex representative apex_rep = d.apex(pt, r, v, cone) apex_str = " + ".join(f"{cone[x]} × {time} ⋅ {c}" for (time, (x, c)) in apex_rep) print(f" Apex representative: {apex_str}") # Extract representatives at different times bottom = pt.birth top = pt.death if pt.death != float('inf') else max_t + 1 middle = (bottom + top) / 2 bottom_rep = d.point_representative(apex_rep, bottom) middle_rep = d.point_representative(apex_rep, middle) top_rep = d.point_representative(apex_rep, top) print(f" Bottom ({bottom:.2f}): " + " + ".join(f"{c}⋅{cone[i]}" for (i, c) in bottom_rep)) print(f" Middle ({middle:.2f}): " + " + ".join(f"{c}⋅{cone[i]}" for (i, c) in middle_rep)) print(f" Top ({top:.2f}): " + " + ".join(f"{c}⋅{cone[i]}" for (i, c) in top_rep)) ``` -------------------------------- ### Project Options Configuration (CMake) Source: https://github.com/mrzv/dionysus/blob/master/CMakeLists.txt Defines various build options for the Dionysus project, such as enabling trace logging, counters, debug routines, building examples, and Python bindings. These options can be toggled by the user during the CMake configuration step. ```cmake option (trace "Build Dionysus with trace logging" OFF) option (counters "Build Dionysus with counters" OFF) option (debug_zigzag "Turn on debug routines for zigzags" OFF) option (build_examples "Build examples" ON) option (build_python_bindings "Build Python bindings" ON) mark_as_advanced (debug_zigzag) ``` -------------------------------- ### Get Special Primes and Initialize Diagrams (Python) Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/omni-field.md This code snippet shows how to retrieve the list of primes for which the persistence diagram might exhibit special behavior, obtained from the `OmniFieldPersistence` object. It also demonstrates initializing persistence diagrams for a specific prime field (e.g., Z_2 and Z_3) using `dionysus.init_diagrams`. ```python import dionysus as d # Assuming 'ofp' and 'f' are already defined from previous step # ofp = d.omnifield_homology_persistence(f) print(ofp.primes()) # Initialize diagrams over Z_2 dgms_2 = d.init_diagrams(ofp, f, 2) for i, dgm in enumerate(dgms_2): print("Dimension:", i) for pt in dgm: print(pt) # Initialize diagrams over Z_3 dgms_3 = d.init_diagrams(ofp, f, 3) for i, dgm in enumerate(dgms_3): print("Dimension:", i) for pt in dgm: print(pt) ``` -------------------------------- ### Initialize Zigzag Persistence Diagrams - Python Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/fast-zigzag-apex.md Initializes the persistence diagrams from the computed homology persistence results (R and V matrices) and the extended persistence cone. The diagrams are categorized by dimension and diagram type (ordinary, relative, extended). ```python dgms = d.init_zigzag_diagrams(r, cone) ``` -------------------------------- ### Dionysus Simplex Creation and Properties Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Demonstrates how to create a Simplex object, access its dimension, iterate over its vertices, and work with its boundary. ```python s = d.Simplex([0,1,2]) print("Dimension:", s.dimension()) for v in s: print(v) for sb in s.boundary(): print(sb) ``` -------------------------------- ### Configure Python Path for Dionysus Bindings (Bash) Source: https://github.com/mrzv/dionysus/blob/master/doc/index.md Adds the directory containing the Dionysus Python bindings to the PYTHONPATH environment variable. This allows Python to find and import the Dionysus library when launched from a different directory. ```bash export PYTHONPATH=.../build/bindings/python:$PYTHONPATH ``` -------------------------------- ### Select Longest Bar and Get Cocycle (Python) Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/cohomology.md This code selects the longest bar from the 1-dimensional persistence diagram, which corresponds to the most persistent 1-dimensional cocycle. It then retrieves the actual cocycle object using the data from the selected persistence point. ```python >>> pt = max(dgms[1], key = lambda pt: pt.death - pt.birth) >>> print(pt) (0.405474,1.83973) >>> cocycle = p.cocycle(pt.data) ``` -------------------------------- ### Build Dionysus from Source Source: https://github.com/mrzv/dionysus/blob/master/README.rst Builds the Dionysus project from the cloned source code using CMake and Make. This process involves creating a build directory, configuring with CMake, and then compiling. ```bash mkdir build cd build cmake .. make ``` -------------------------------- ### Clone Dionysus Repository Source: https://github.com/mrzv/dionysus/blob/master/README.rst Clones the Dionysus source code from its GitHub repository to your local machine. This is the first step if you plan to build the project from source. ```bash git clone ``` -------------------------------- ### Build Dionysus from Source (CMake) Source: https://github.com/mrzv/dionysus/blob/master/doc/index.md Builds the Dionysus project from its source code using CMake and Make. This process involves creating a build directory, configuring the build with CMake, and then compiling the project. ```bash mkdir build cd build cmake .. make ``` -------------------------------- ### Find and Link Boost and Threads Libraries (CMake) Source: https://github.com/mrzv/dionysus/blob/master/ext/hera/wasserstein/CMakeLists.txt This snippet demonstrates how to locate the Boost and Threads libraries using CMake and link them to the project's targets. It includes setting up necessary include directories and compiler flags. ```cmake find_package(Boost REQUIRED) find_package(Threads) set (libraries ${libraries} ${CMAKE_THREAD_LIBS_INIT} hera) ``` -------------------------------- ### Add Executable and Set Compile Options (CMake) Source: https://github.com/mrzv/dionysus/blob/master/ext/hera/wasserstein/CMakeLists.txt This snippet shows how to define an executable target from a C++ source file, specify system and private include directories, link libraries, and set compiler options based on the build environment (MSVC or others). ```cmake foreach(wd wasserstein_dist wasserstein_dist_dipha wasserstein_dist_point_cloud) add_executable(${wd} "${wd}.cpp") target_include_directories(${wd} SYSTEM PRIVATE ${Boost_INCLUDE_DIR}) target_include_directories(${wd} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../extern/opts/include) target_link_libraries(${wd} PUBLIC ${libraries}) if(MSVC) target_compile_options(${wd} PRIVATE /W4 /WX) else() target_compile_options(${wd} PRIVATE -Wall -Wextra -Wpedantic) endif() endforeach() ``` -------------------------------- ### Compute Extended Persistence Cone and Homology - Python Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/fast-zigzag-apex.md This code snippet shows how to construct the cone for extended persistence using `d.fast_zigzag` and then compute the homology persistence with matrix V decomposition using `d.homology_persistence`. This is crucial for recovering apex representatives. ```python cone = d.fast_zigzag(simplices, times) r, v = d.homology_persistence(cone, method = 'matrix_v') ``` -------------------------------- ### Clone Dionysus Repository (Git) Source: https://github.com/mrzv/dionysus/blob/master/doc/index.md Clones the Dionysus Git repository from GitHub to obtain the source code. This allows for manual building and development. ```bash git clone https://github.com/mrzv/dionysus.git ``` -------------------------------- ### Dionysus Initializing Persistence Diagrams Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Initializes and prints persistence diagrams from the computed homology persistence matrix and filtration. This function utilizes the data stored in simplices for birth and death values. ```python dgms = d.init_diagrams(m, f) print(dgms) for i, dgm in enumerate(dgms): for pt in dgm: print(i, pt.birth, pt.death) ``` -------------------------------- ### Create Simplices and Filtrations in Python Source: https://context7.com/mrzv/dionysus/llms.txt This snippet demonstrates how to create individual simplices with optional data values, iterate over their boundaries, and construct a filtration from a list of simplices with associated time values. It also shows how to sort the filtration and find the index of a specific simplex. The `d.closure` function is used to generate k-skeletons. ```python import dionysus as d # Create individual simplices with optional data values s0 = d.Simplex([0]) # vertex s1 = d.Simplex([0,1]) # edge s2 = d.Simplex([0,1,2], 5.0) # triangle with data value 5.0 # Access simplex properties print(s2.dimension()) # 2 print(s2.data) # 5.0 # Iterate over boundary for boundary_simplex in s2.boundary(): print(boundary_simplex) # <1,2> 5.0, <0,2> 5.0, <0,1> 5.0 # Create filtration from simplices with time values simplices = [([0], 1), ([1], 2), ([0,1], 3), ([2], 4), ([1,2], 5), ([0,2], 6)] f = d.Filtration() for vertices, time in simplices: f.append(d.Simplex(vertices, time)) # Sort by data value (time), then dimension, then lexicographically f.sort() for s in f: print(s) # <0> 1, <1> 2, <0,1> 3, <2> 4, <1,2> 5, <0,2> 6 # Lookup simplex index in filtration idx = f.index(d.Simplex([1,2])) print(idx) # 4 # Generate k-skeleton closure simplex9 = d.Simplex([0,1,2,3,4,5,6,7,8,9]) sphere8 = d.closure([simplex9], 8) # 8-sphere print(len(sphere8)) # 1022 simplices ``` -------------------------------- ### Find and Configure Boost Dependency (CMake) Source: https://github.com/mrzv/dionysus/blob/master/CMakeLists.txt Locates the Boost library configuration, which is required for the project. This command searches for Boost components needed by Dionysus. ```cmake find_package (Boost CONFIG) ``` -------------------------------- ### Import Dionysus Library Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Imports the Dionysus library and the print_function for compatibility with Python 2. ```python from __future__ import print_function # if you are using Python 2 import dionysus as d ``` -------------------------------- ### Dionysus Filtration Creation and Sorting Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Illustrates how to create a Filtration object by appending simplices with associated data (time) and then sorting the filtration based on simplex data and dimension. ```python simplices = [([2], 4), ([1,2], 5), ([0,2], 6), ([0], 1), ([1], 2), ([0,1], 3)] f = d.Filtration() for vertices, time in simplices: f.append(d.Simplex(vertices, time)) f.sort() for s in f: print(s) ``` -------------------------------- ### Dionysus Homology Persistence with Column Method Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Demonstrates computing persistent homology using the 'column' method, specifying an alternative algorithm for the computation. ```python m = d.homology_persistence(f, method = 'column') ``` -------------------------------- ### Initialize and Print Persistence Diagrams (Python) Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/cohomology.md This snippet initializes persistence diagrams from the computed cohomology persistence object and the filtration. It then iterates through the diagrams and prints each point (birth, death) within them. ```python >>> dgms = d.init_diagrams(p, f) >>> for i,dgm in enumerate(dgms): ... print(i) ... for pt in dgm: ... print(pt) ``` -------------------------------- ### Construct Vietoris-Rips Complex and Analyze H1 in Python Source: https://context7.com/mrzv/dionysus/llms.txt This snippet demonstrates the construction of Vietoris-Rips complexes from point clouds and distance matrices using `dionysus.fill_rips`. It shows how to compute persistent homology for the generated filtration and analyze the resulting 1-dimensional homology features (loops) by filtering based on their persistence. The conversion between condensed and square distance matrices is also illustrated. ```python import dionysus as d import numpy as np from scipy.spatial.distance import pdist, squareform # From point cloud (rows are points) np.random.seed(42) points = np.random.random((100, 2)) # Build Rips complex up to dimension 2 and distance 0.3 f = d.fill_rips(points, k=2, r=0.3) print(f) # Filtration with N simplices # Iterate over simplices for s in f: print(s) # distance_value # From condensed distance matrix (linearized lower triangle) dists = pdist(points, metric='euclidean') f = d.fill_rips(dists, k=2, r=0.3) # Compute persistence and extract 1-dimensional features m = d.homology_persistence(f, prime=2) dgms = d.init_diagrams(m, f) # Analyze 1-dimensional homology (loops) print(f"Number of H1 features: {len(dgms[1])}") for pt in dgms[1]: persistence = pt.death - pt.birth if persistence > 0.05: # filter short-lived features print(f"Loop: birth={pt.birth:.3f}, death={pt.death:.3f}, pers={persistence:.3f}") # Convert between condensed and square distance matrices sq_dist = squareform(dists) print(sq_dist.shape) # (100, 100) condensed_again = squareform(sq_dist) print(condensed_again.shape) # (4950,) ``` -------------------------------- ### Extracting Representative Cycles (Python) Source: https://context7.com/mrzv/dionysus/llms.txt This snippet shows how to extract representative cycles corresponding to points in a persistence diagram. It involves computing homology persistence, selecting a point, retrieving its paired simplex index, and then reconstructing the cycle as a chain of simplices from the filtration. ```python import dionysus as d import numpy as np # Create filtration from point cloud np.random.seed(42) points = np.random.random((50, 3)) f = d.fill_rips(points, k=2, r=0.5) # Compute persistence m = d.homology_persistence(f, prime=2) dgms = d.init_diagrams(m, f) # Select a specific persistence point dim = 1 # dimension of interest if len(dgms[dim]) > 0: idx = 0 # index of the point in the diagram pt = dgms[dim][idx] print(f"Selected point: birth={pt.birth:.3f}, death={pt.death:.3f}") # Get the paired simplex index from the reduced matrix paired_idx = m.pair(pt.data) # Extract representative cycle as chain cycle = m[paired_idx] print(f"Representative cycle has {len(cycle)} simplices:") for simplex_entry in cycle: simplex = f[simplex_entry.index] coefficient = simplex_entry.element vertices = [v for v in simplex] print(f" Coefficient {coefficient}: simplex {vertices} at value {simplex.data:.3f}") # Access vertex coordinates if simplex.dimension() == 1: # edge v1, v2 = vertices coord1 = points[v1] coord2 = points[v2] print(f" Edge from {coord1} to {coord2}") # Check if filtration is simplicial (valid simplicial complex) is_valid = d.is_simplicial(f, report=True) if is_valid: print("Filtration is a valid simplicial complex") else: print("Filtration has issues (see output above)") # Relative homology: compute cycle relative to boundary triangle = d.closure([d.Simplex([0,1,2])], 2) f_full = d.Filtration(triangle) f_full.sort() # Define relative subcomplex (boundary) f_boundary = d.Filtration([s for s in f_full if s.dimension() <= 1]) # Compute relative homology m_rel = d.homology_persistence(f_full, relative=f_boundary, prime=2) dgms_rel = d.init_diagrams(m_rel, f_full) print("Relative homology (triangle mod boundary):") for dim, dgm in enumerate(dgms_rel): print(f"H_{dim}: {len([pt for pt in dgm if pt.death == float('inf')])} generators") ``` -------------------------------- ### Reconstruct Apex Representative from Matrix V - Python Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/fast-zigzag-apex.md This snippet demonstrates how to print the structure of an apex representative, which is an instance of `ApexRepresentative`. It shows the simplices and their coefficients contributing to the representative, along with their associated time intervals. ```python print("apex representative:", " + ".join(f"{cone[x]} × {time} ⋅ {c}" for (time, (x, c)) in apex_rep)) ``` -------------------------------- ### Extract and Print Apex Representatives - Python Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/fast-zigzag-apex.md Iterates through the computed persistence diagrams, extracts individual points (intervals), and uses the `d.apex` function to recover the apex representative for each point. It prints the dimension, type, and the point itself. ```python max_t = max(max(t) for t in times) for dim, type_dgm in enumerate(dgms): print("Dimension:", dim) for t, dgm in type_dgm.items(): print("Type:", t) for pt in dgm: print(pt) apex_rep = d.apex(pt, r, v, cone) ``` -------------------------------- ### Visualize Persistence Diagrams and Barcodes (Python) Source: https://context7.com/mrzv/dionysus/llms.txt This Python snippet shows how to visualize persistence diagrams and barcodes using the dionysus plotting module. It generates a persistence diagram from random points and then uses `plot_diagram` for a scatter plot and `plot_bars` for barcode representations, including ordering by death time. Requires matplotlib. ```python import dionysus as d import numpy as np import matplotlib.pyplot as plt # Generate data and compute persistence np.random.seed(42) points = np.random.random((100, 2)) f = d.fill_rips(points, k=2, r=1.0) p = d.homology_persistence(f, prime=2) dgms = d.init_diagrams(p, f) # Plot persistence diagram (scatter plot) d.plot.plot_diagram(dgms[1], show=True) # Plot barcode representation d.plot.plot_bars(dgms[1], show=True) # Plot barcode ordered by death time d.plot.plot_bars(dgms[1], order='death', show=True) ``` -------------------------------- ### Set Include Directories (CMake) Source: https://github.com/mrzv/dionysus/blob/master/CMakeLists.txt Configures the include paths for the project, including system include directories. This ensures that header files are found during compilation. ```cmake # Set includes set (CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem") include_directories (${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include SYSTEM ${Boost_INCLUDE_DIRS}) ``` -------------------------------- ### Omni-Field Persistence for Torsion Detection (Python) Source: https://context7.com/mrzv/dionysus/llms.txt Computes topological persistence simultaneously over all prime fields to detect torsion in the homology of a given filtration. Demonstrates how to access special primes and extract persistence diagrams over specific fields like Z_2 and Z_3. Requires dionysus. ```python import dionysus as d # Klein bottle triangulation klein_bottle = [ [0], [1], [2], [3], [4], [5], [6], [7], [8], [0,1], [1,2], [2,0], [0,3], [3,4], [4,0], [1,5], [5,6], [6,2], [2,7], [7,8], [8,1], [3,5], [5,7], [7,3], [4,6], [6,8], [8,4], [0,5], [1,7], [2,3], [3,6], [5,8], [7,4], [4,2], [6,1], [8,0], [0,3,5], [0,1,5], [1,5,7], [1,2,7], [2,7,3], [2,3,0], [3,4,6], [3,5,6], [5,6,8], [5,7,8], [7,8,4], [7,3,4], [4,0,2], [4,6,2], [6,2,1], [6,8,1], [8,1,0], [8,4,0] ] f = d.Filtration(klein_bottle) print(f) # Filtration with 54 simplices # Compute persistence over all fields simultaneously ofp = d.omnifield_homology_persistence(f) # Check which primes are special (produce different behavior) special_primes = ofp.primes() print(f"Special primes: {special_primes}") # [2] # Extract diagrams over Z_2 dgms_z2 = d.init_diagrams(ofp, f, prime=2) print("Homology over Z_2:") for dim, dgm in enumerate(dgms_z2): print(f"H_{dim}: {len([pt for pt in dgm if pt.death == float('inf')])} generators") # Output: H_0: 1, H_1: 2, H_2: 1 # Extract diagrams over Z_3 (or any other prime) dgms_z3 = d.init_diagrams(ofp, f, prime=3) print("Homology over Z_3:") for dim, dgm in enumerate(dgms_z3): print(f"H_{dim}: {len([pt for pt in dgm if pt.death == float('inf')])} generators") # Output: H_0: 1, H_1: 1, H_2: 0 ``` -------------------------------- ### Compute Wasserstein and Bottleneck Distances Between Persistence Diagrams (Python) Source: https://context7.com/mrzv/dionysus/llms.txt This code computes various distances (Wasserstein with different q-norms and bottleneck) between two persistence diagrams generated from random point clouds. It shows how to build filtrations, compute homology, initialize diagrams, and then calculate these distances. The diagrams can be filtered by persistence before distance computation. ```python import dionysus as d import numpy as np # Generate two random point clouds np.random.seed(42) points1 = np.random.random((50, 2)) points2 = np.random.random((50, 2)) # Build filtrations and compute diagrams f1 = d.fill_rips(points1, k=2, r=1.0) m1 = d.homology_persistence(f1, prime=2) dgms1 = d.init_diagrams(m1, f1) f2 = d.fill_rips(points2, k=2, r=1.0) m2 = d.homology_persistence(f2, prime=2) dgms2 = d.init_diagrams(m2, f2) # Compute Wasserstein distance (q-parameter specifies L^q norm) w1_dist = d.wasserstein_distance(dgms1[1], dgms2[1], q=1) w2_dist = d.wasserstein_distance(dgms1[1], dgms2[1], q=2) winf_dist = d.wasserstein_distance(dgms1[1], dgms2[1], q=float('inf')) print(f"1-Wasserstein distance (H1): {w1_dist:.6f}") print(f"2-Wasserstein distance (H1): {w2_dist:.6f}") print(f"∞-Wasserstein distance (H1): {winf_dist:.6f}") # Compute bottleneck distance (equivalent to W_∞) b_dist = d.bottleneck_distance(dgms1[1], dgms2[1]) print(f"Bottleneck distance (H1): {b_dist:.6f}") # Compare diagrams across all dimensions for dim in range(len(dgms1)): if dim < len(dgms2): wd = d.wasserstein_distance(dgms1[dim], dgms2[dim], q=2) bd = d.bottleneck_distance(dgms1[dim], dgms2[dim]) print(f"Dimension {dim}: W_2={wd:.4f}, bottleneck={bd:.4f}") # Filter points by persistence before computing distance def filter_diagram(dgm, min_persistence=0.01): return [pt for pt in dgm if pt.death - pt.birth > min_persistence] dgm1_filtered = filter_diagram(dgms1[1], 0.05) dgm2_filtered = filter_diagram(dgms2[1], 0.05) print(f"Filtered diagrams: {len(dgm1_filtered)} vs {len(dgm2_filtered)} points") ``` -------------------------------- ### Callback for Zigzag Persistence Intermediate Steps Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/zigzags.md Defines and uses a callback function to inspect intermediate steps during zigzag persistence computation. The callback receives simplex index, time, direction, and the current state of ZigzagPersistence. ```python def detail(i,t,d,zz,cells): print(i,t,d) for z in zz: print(z, ' -> ', ' + '.join("%d * (%s)" % (x.element, f[cells[x.index]]) for x in z)) zz, dgms, cells = d.zigzag_homology_persistence(f, times, callback = detail) ``` -------------------------------- ### Add Python Bindings Subdirectory (CMake) Source: https://github.com/mrzv/dionysus/blob/master/CMakeLists.txt Includes the 'bindings/python' subdirectory for building Python bindings if the 'build_python_bindings' option is enabled. ```cmake if (build_python_bindings) add_subdirectory (bindings/python) endif (build_python_bindings) ``` -------------------------------- ### Plotting Diagram Density and Customizing Persistence Diagrams/Barcodes (Python) Source: https://context7.com/mrzv/dionysus/llms.txt This snippet demonstrates how to plot the density of persistence diagrams and customize the visualization of persistence diagrams and barcodes using Matplotlib. It involves generating random data, computing homology persistence, and then plotting the results with custom labels and styles. ```python import numpy as np import matplotlib.pyplot as plt import dionysus as d # Assume 'd' is an initialized Dionysus object and 'dgms' is computed # Example placeholder for dgms, replace with actual computation # a = np.random.random((200, 200)) # f_lower = d.fill_freudenthal(a) # p_lower = d.homology_persistence(f_lower) # dgms_lower = d.init_diagrams(p_lower, f_lower) # d.plot.plot_diagram_density(dgms_lower[1], show=True) # Placeholder for dgms - replace with actual computed diagrams class MockPoint: def __init__(self, birth, death): self.birth = birth self.death = death self.data = None class MockDiagrams: def __getitem__(self, key): if key == 1: return [MockPoint(0.1, 0.5), MockPoint(0.2, 0.7), MockPoint(0.3, float('inf'))] return [] dgms = MockDiagrams() # Customize plots using matplotlib fig, axes = plt.subplots(1, 2, figsize=(12, 5)) # Custom diagram plot ax1 = axes[0] for pt in dgms[1]: if pt.death != float('inf'): ax1.plot(pt.birth, pt.death, 'ro', markersize=5) # Calculate diagonal based on actual data if available, otherwise use a placeholder max_death = 0 if dgms[1]: max_death = max(pt.death for pt in dgms[1] if pt.death != float('inf')) diagonal = np.linspace(0, max_death if max_death > 0 else 1, 100) # Ensure diagonal has a range ax1.plot(diagonal, diagonal, 'k--', alpha=0.3) ax1.set_xlabel('Birth') ax1.set_ylabel('Death') ax1.set_title('H1 Persistence Diagram') ax1.set_aspect('equal') # Custom barcode plot ax2 = axes[1] finite_bars = [(pt.birth, pt.death) for pt in dgms[1] if pt.death != float('inf')] finite_bars.sort(key=lambda x: x[1] - x[0], reverse=True) # sort by persistence for i, (birth, death) in enumerate(finite_bars): ax2.plot([birth, death], [i, i], 'b-', linewidth=2) ax2.set_xlabel('Filtration value') ax2.set_ylabel('Bar index') ax2.set_title('H1 Barcode') plt.tight_layout() plt.show() ``` -------------------------------- ### Dionysus Filtration Index Lookup Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Demonstrates how to find the index of a specific simplex within a sorted Dionysus Filtration object. ```python print(f.index(d.Simplex([1,2]))) ``` -------------------------------- ### Dionysus Simplex Data and Closure Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Shows how to assign data to a simplex and use the closure function to generate all faces of a set of simplices. This is useful for constructing higher-dimensional structures from lower-dimensional ones. ```python s.data = 5 print(s) simplex9 = d.Simplex([0,1,2,3,4,5,6,7,8,9]) sphere8 = d.closure([simplex9], 8) print(len(sphere8)) ``` -------------------------------- ### Dionysus Homology Persistence with Prime Field Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Computes persistent homology using a prime field (e.g., prime=2) and then initializes and prints the resulting persistence diagrams, showing dimensions and persistence intervals. ```python f = d.Filtration(sphere8) f.sort() m = d.homology_persistence(f, prime=2) dgms = d.init_diagrams(m, f) for i, dgm in enumerate(dgms): print("Dimension:", i) for p in dgm: print(p) ``` -------------------------------- ### Create and Sort Filtration (Python) Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/cohomology.md This snippet demonstrates how to create a filtration from a list of simplices and sort it. It initializes a Dionysus filtration object and appends simplices with their associated times. The filtration is then sorted based on the time values. ```python >>> simplices = [([2], 4), ([1,2], 5), ([0,2], 6), ... ([0], 1), ([1], 2), ([0,1], 3)] >>> f = d.Filtration() >>> for vertices, time in simplices: ... f.append(d.Simplex(vertices, time)) >>> f.sort() ``` -------------------------------- ### Calculate Wasserstein and Bottleneck Distances (Python) Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Computes the Wasserstein and bottleneck distances between two persistence diagrams. The Wasserstein distance requires a 'q' parameter specifying the order of the distance. These functions are essential for comparing the shapes of topological features captured by persistence diagrams. ```python import numpy as np import dionysus as d # Assuming f1, m1, dgms1 and f2, m2, dgms2 are previously computed # Example computation: f1 = d.fill_rips(np.random.random((20, 2)), 2, 1) m1 = d.homology_persistence(f1) dgms1 = d.init_diagrams(m1, f1) f2 = d.fill_rips(np.random.random((20, 2)), 2, 1) m2 = d.homology_persistence(f2) dgms2 = d.init_diagrams(m2, f2) # Wasserstein distance wdist = d.wasserstein_distance(dgms1[1], dgms2[1], q=2) print("2-Wasserstein distance between 1-dimensional persistence diagrams:", wdist) # Bottleneck distance bdist = d.bottleneck_distance(dgms1[1], dgms2[1]) print("Bottleneck distance between 1-dimensional persistence diagrams:", bdist) ``` -------------------------------- ### Compute Persistent Homology in Python Source: https://context7.com/mrzv/dionysus/llms.txt This snippet illustrates how to compute persistent homology for a given filtration. It covers calculating the persistence modules, initializing diagrams from these modules, and iterating through the diagrams to extract birth and death times of topological features. It also shows how to access the pairing information from the reduced matrix and check for homologous chains. ```python import dionysus as d import numpy as np # Build filtration simplices = [([0], 1), ([1], 2), ([0,1], 3), ([2], 4), ([1,2], 5), ([0,2], 6)] f = d.Filtration() for vertices, time in simplices: f.append(d.Simplex(vertices, time)) f.sort() # Compute persistent homology (default method is 'clearing') m = d.homology_persistence(f, prime=2, method='clearing') # Extract persistence diagrams dgms = d.init_diagrams(m, f) print(dgms) # [Diagram with 3 points, Diagram with 1 points] # Iterate over diagrams by dimension for dim, dgm in enumerate(dgms): print(f"Dimension {dim}:") for pt in dgm: print(f" Birth: {pt.birth}, Death: {pt.death}") # Output: # Dimension 0: (1.0, inf), (2.0, 3.0), (4.0, 5.0) # Dimension 1: (6.0, inf) # Manually access pairing from reduced matrix for i in range(len(m)): if m.pair(i) < i: # skip negative simplices continue dim = f[i].dimension() if m.pair(i) != m.unpaired: print(f"Dim {dim}: simplex {i} pairs with {m.pair(i)}") else: print(f"Dim {dim}: simplex {i} is unpaired (infinite)") # Check if chains are homologous chain1 = d.Chain([(1, 0)]) # coefficient 1 at index 0 chain2 = d.Chain([(1, 1)]) # coefficient 1 at index 1 print(m.homologous(chain1, chain2)) # True or False ``` -------------------------------- ### Examine Reduced Matrix Columns at Prime 2 (Python) Source: https://context7.com/mrzv/dionysus/llms.txt This snippet demonstrates how to iterate through the columns of a reduced matrix and check if a column is 'special' at a given prime (2 in this case). It then extracts and prints the column's representation modulo 2 and modulo 3. This is useful for analyzing the structure of the homology groups. ```python for i in range(len(ofp)): if ofp.special(i, 2): # check if column i is special at prime 2 col_z2 = ofp.column(i, 2) col_z3 = ofp.column(i, 3) print(f"Column {i} mod 2: {col_z2}") print(f"Column {i} mod 3: {col_z3}") ``` -------------------------------- ### Dionysus Extracting Persistence Pairing Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/basics.md Manually extracts the persistence pairing information (birth and death simplices) from the reduced boundary matrix returned by homology_persistence. ```python for i in range(len(m)): if m.pair(i) < i: continue # skip negative simplices dim = f[i].dimension() if m.pair(i) != m.unpaired: print(dim, i, m.pair(i)) else: print(dim, i) ``` -------------------------------- ### Generate Annulus Points (Python) Source: https://github.com/mrzv/dionysus/blob/master/doc/tutorial/cohomology.md This snippet generates 100 points on an annulus using NumPy. It first creates points from a normal distribution and then normalizes them to lie on a circle, with radii varying between 1 and 1.5. ```python >>> points = np.random.normal(size = (100,2)) >>> for i in range(points.shape[0]): ... points[i] = points[i] / np.linalg.norm(points[i], ord=2) * np.random.uniform(1,1.5) ``` -------------------------------- ### Compute Cohomology Persistence and Circular Coordinates (Python) Source: https://context7.com/mrzv/dionysus/llms.txt Generates points on an annulus, computes 1-dimensional cohomology persistence using a Rips filtration, and extracts circular coordinates from the most persistent cocycle. Visualizes the results with points colored by their circular coordinate. Requires numpy, matplotlib, and dionysus. ```python import dionysus as d import numpy as np import matplotlib.pyplot as plt # Generate points on an annulus np.random.seed(42) points = np.random.normal(size=(100, 2)) for i in range(points.shape[0]): points[i] = points[i] / np.linalg.norm(points[i]) * np.random.uniform(1, 1.5) # Build Rips filtration and compute cohomology prime = 11 f = d.fill_rips(points, k=2, r=2.0) p = d.cohomology_persistence(f, prime=prime, dualize=True) dgms = d.init_diagrams(p, f) # Examine 1-dimensional persistence diagram print(f"H1 features: {len(dgms[1])}") for pt in dgms[1]: print(f"({pt.birth:.3f}, {pt.death:.3f})") # Select longest bar (most persistent feature) pt = max(dgms[1], key=lambda pt: pt.death - pt.birth) print(f"Longest bar: ({pt.birth:.3f}, {pt.death:.3f})") # Extract corresponding cocycle cocycle = p.cocycle(pt.data) print(f"Cocycle: {cocycle}") # Restrict filtration to midpoint of persistence interval midvalue = (pt.death + pt.birth) / 2 f_restricted = d.Filtration([s for s in f if s.data <= midvalue]) # Smooth cocycle to get circular coordinates vertex_values = d.smooth(f_restricted, cocycle, prime) # Visualize with hue representing circular coordinate plt.figure(figsize=(8, 8)) plt.scatter(points[:, 0], points[:, 1], c=vertex_values, cmap='hsv', s=50) plt.colorbar(label='Circular coordinate') plt.title('Annulus with circular coordinates') plt.axis('equal') plt.show() # Access alive cocycles at end of filtration for c in p: print(f"Cocycle born at index {c.index}: {c.cocycle}") ```