Git Product home page Git Product logo

ripser's Introduction

Ripser

Copyright © 2015–2021 Ulrich Bauer.

Description

Ripser is a lean C++ code for the computation of Vietoris–Rips persistence barcodes. It can do just this one thing, but does it extremely well.

To see a live demo of Ripser's capabilities, go to live.ripser.org. The computation happens inside the browser (using Emscripten to compile Ripser to WebAssembly, supported on recent browsers).

The main features of Ripser:

  • time- and memory-efficient
  • only about 1000 lines of code in a single C++ file
  • support for coefficients in prime finite fields
  • no external dependencies (optional support for Google's [sparsehash])

Currently, Ripser outperforms other codes (Dionysus, DIPHA, GUDHI, Perseus, PHAT) by a factor of more than 40 in computation time and a factor of more than 15 in memory efficiency (for the example linked at live.ripser.org). (Note that PHAT does not contain code for generating Vietoris–Rips filtrations).

Input formats currently supported by Ripser:

  • comma-separated values lower triangular distance matrix
  • comma-separated values upper triangular distance matrix (MATLAB output from the function pdist)
  • comma-separated values full distance matrix
  • DIPHA distance matrix data
  • sparse distance matrix in sparse triplet format
  • binary lower triangular distance matrix
  • point cloud data

Ripser's efficiency is based on a few important concepts and principles, building on key previous and concurrent developments by other researchers in computational topology:

  • Compute persistent cohomology (as suggested by Vin de Silva, Dmitriy Morozov, and Mikael Vejdemo-Johansson)
  • Use the chain complex property that boundaries are cycles (employ the clearing optimization, aka persistence with a twist, as suggested by Chao Chen and Michael Kerber)
  • If no threshold is specified, choose the enclosing radius as the threshold, from which on homology is guaranteed to be trivial (as suggested by Greg Henselman-Petrusek)
  • Don't store information that can be readily recomputed (in particular, the original and the reduced boundary matrix)
  • Take computational shortcuts (apparent and emergent persistence pairs)

Version

Latest release: 1.2.1 (March 2021)

Building

Ripser requires a C++11 compiler. Here is how to obtain, build, and run Ripser:

git clone https://github.com/Ripser/ripser.git
cd ripser
make
./ripser examples/sphere_3_192.lower_distance_matrix

Options

Ripser supports several compile-time options. They are switched on by defining the C preprocessor macros listed below, either using #define in the code or by passing an argument to the compiler. The following options are supported:

  • USE_COEFFICIENTS: enable support for coefficients in a prime field
  • INDICATE_PROGRESS: indicate the current progress in the console
  • PRINT_PERSISTENCE_PAIRS: output the computed persistence pairs (enabled by default in the code; comment out to disable)
  • USE_ROBINHOOD_HASHMAP: enable support for Martin Ankerl's robinhoodhash data structure; may further reduce memory footprint

For example, to build Ripser with support for Martin Ankerl's robin hood hashmap:

$ c++ -std=c++11 ripser.cpp -o ripser -O3 -D NDEBUG -D USE_ROBINHOOD_HASHMAP

A Makefile is provided with some variants of the above options. Use make all to build them. The default make builds a binary with the default options.

The input is given either in a file whose name is passed as an argument, or through stdin. The following options are supported at the command line:

  • --format: use the specified file format for the input. The following formats are supported:
    • lower-distance: lower triangular distance matrix; a comma (or whitespace, or other non-numerical character) separated list of the distance matrix entries below the diagonal, sorted lexicographically by row index, then column index.
    • upper-distance: upper triangular distance matrix; similar to the previous, but for the entries above the diagonal; suitable for output from the MATLAB functions pdist or seqpdist, exported to a CSV file.
    • distance (default if no format is specified): full distance matrix; similar to the above, but for all entries of the distance matrix. One line per row of the matrix; only the part below the diagonal is actually read.
    • dipha: DIPHA distance matrix as described on the DIPHA website.
    • point-cloud: point cloud; a comma (or whitespace, or other non-numerical character) separated list of coordinates of the points in some Euclidean space, one point per line.
    • binary: lower distance matrix in binary file format; a sequence of the distance matrix entries below the diagonal in 32 bit float format (IEEE 754, single, little endian).
    • sparse: sparse triplet format; a whitespace separated list of entries of a sparse distance matrix, one entry per line, each of the form i j d(i,j) specifying the distance between points i and j. Each pair of points should appear in the file at most once.
  • --dim k: compute persistent homology up to dimension k.
  • --threshold t: compute Rips complexes up to diameter t.
  • --modulus p: compute homology with coefficients in the prime field Z/pZ (only available when built with the option USE_COEFFICIENTS).
  • --ratio r: only show persistence pairs with death/birth ratio > r.

Experimental features

The following experimental features are currently available in separate branches:

  • representative-cocycles: output of representative cocycles for persistent cohomology.
  • representative-cycles: computation and output of representative cycles for persistent homology (in the standard version, only cocycles are computed).
  • simple: a simplified version of Ripser, without support for sparse distance matrices and coefficients. This might be a good starting point for exploring the code.

Citing

If you use Ripser in your research or if you want to give a reference to Ripser in a paper, you may use the following bibtex entry (will be updated with complete publication data):

@article{Bauer2021Ripser,
    AUTHOR = {Bauer, Ulrich},
     TITLE = {Ripser: efficient computation of {V}ietoris-{R}ips persistence
              barcodes},
   JOURNAL = {J. Appl. Comput. Topol.},
  FJOURNAL = {Journal of Applied and Computational Topology},
    VOLUME = {5},
      YEAR = {2021},
    NUMBER = {3},
     PAGES = {391--423},
      ISSN = {2367-1726},
   MRCLASS = {55N31 (55-04)},
  MRNUMBER = {4298669},
       DOI = {10.1007/s41468-021-00071-5},
       URL = {https://doi.org/10.1007/s41468-021-00071-5},
}

License

Ripser is licensed under the MIT license (COPYING.txt), with an extra clause (CONTRIBUTING.txt) clarifying the license for modifications released without an explicit written license agreement. Please contact the author if you want to use Ripser in your software under a different license.

ripser's People

Contributors

ubauer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ripser's Issues

#include <algorithm> ?

Hi Uli,
To get this to work, I had to add #include at the top. Am I missing something?
Thanks,
Chris
P.S. Amazing code!!

Typo on line 1125

I think it is missing a pair of () in line 1125 to right compute the number of elements above the diagonal of the matrix.

I should be

(dist.size() * (dist.size() - 1)) / 2

Failed building wheel for ripser

Dear developers,

I have been having this error (under this paragraph) for quite sometime now, whenever I try to install ripser via command prompt using "pip install ripser" or via jupyter notebook using "!pip install ripser".

Note that, I have downloaded and installed "MSVC v143- VS 2022 C++ x64/x86 build tools (v14.35-17.5)" then restarted my laptop but the error message keep coming back. I would be glad if you could help me resolve this issue. Thank you.

"""
Defaulting to user installation because normal site-packages is not writeable
WARNING: Ignoring invalid distribution -cipy (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
WARNING: Ignoring invalid distribution -atplotlib (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
WARNING: Ignoring invalid distribution -cipy (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
WARNING: Ignoring invalid distribution -atplotlib (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
Collecting ripser
Using cached ripser-0.6.4.tar.gz (74 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: Cython in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from ripser) (0.29.32)
Requirement already satisfied: persim in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from ripser) (0.3.1)
Requirement already satisfied: scikit-learn in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from ripser) (1.1.2)
Requirement already satisfied: numpy in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from ripser) (1.23.5)
Requirement already satisfied: scipy in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from ripser) (1.10.1)
Requirement already satisfied: deprecated in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from persim->ripser) (1.2.13)
Requirement already satisfied: hopcroftkarp in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from persim->ripser) (1.2.5)
Requirement already satisfied: matplotlib in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from persim->ripser) (3.7.1)
Requirement already satisfied: joblib in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from persim->ripser) (1.2.0)
Requirement already satisfied: threadpoolctl>=2.0.0 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from scikit-learn->ripser) (3.1.0)
Requirement already satisfied: wrapt<2,>=1.10 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from deprecated->persim->ripser) (1.14.1)
Requirement already satisfied: cycler>=0.10 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from matplotlib->persim->ripser) (0.11.0)
Requirement already satisfied: fonttools>=4.22.0 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from matplotlib->persim->ripser) (4.37.3)
Requirement already satisfied: pillow>=6.2.0 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from matplotlib->persim->ripser) (9.2.0)
Requirement already satisfied: contourpy>=1.0.1 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from matplotlib->persim->ripser) (1.0.5)
Requirement already satisfied: python-dateutil>=2.7 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from matplotlib->persim->ripser) (2.8.2)
Requirement already satisfied: pyparsing>=2.3.1 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from matplotlib->persim->ripser) (3.0.9)
Requirement already satisfied: packaging>=20.0 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from matplotlib->persim->ripser) (21.3)
Requirement already satisfied: kiwisolver>=1.0.1 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from matplotlib->persim->ripser) (1.4.4)
Requirement already satisfied: six>=1.5 in c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages (from python-dateutil>=2.7->matplotlib->persim->ripser) (1.16.0)
Building wheels for collected packages: ripser
Building wheel for ripser (pyproject.toml) ... error
error: subprocess-exited-with-error

× Building wheel for ripser (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [12 lines of output]
running bdist_wheel
running build
running build_py
creating build
creating build\lib.win-amd64-cpython-310
creating build\lib.win-amd64-cpython-310\ripser
copying ripser\ripser.py -> build\lib.win-amd64-cpython-310\ripser
copying ripser_version.py -> build\lib.win-amd64-cpython-310\ripser
copying ripser_init_.py -> build\lib.win-amd64-cpython-310\ripser
running build_ext
building 'pyRipser' extension
error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
[end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for ripser
Failed to build ripser
ERROR: Could not build wheels for ripser, which is required to install pyproject.toml-based projects
WARNING: Ignoring invalid distribution -cipy (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
WARNING: Ignoring invalid distribution -atplotlib (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
WARNING: Ignoring invalid distribution -cipy (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
WARNING: Ignoring invalid distribution -atplotlib (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
WARNING: Ignoring invalid distribution -cipy (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
WARNING: Ignoring invalid distribution -atplotlib (c:\users\muhammad siraj\appdata\roaming\python\python310\site-packages)
"""

Speed up get_pivot

Hello,
I notice that a common behavior is that get_pivot calls pop_pivot and thus column.pop, just to call column.push on that same value immediately after. This seems like a waste. As an experiment, I inlined the code for pop_pivot in get_pivot, and replaced the test column.empty() with column.size()==1 before pop(). It is possible that I did it wrong, but it gave me a 5% speed-up on the first dataset I tried (o3_2048.txt), which makes it look like a small low-hanging fruit. With a bit more work, it should also be possible to peek at the second "smallest" element without any pop, although I haven't tried it so I don't want to claim that it really helps.

error: no matching function for call when

I'm trying to build ripser with g++ -Wall ripser.cpp -o ripser -g but i get the following error:

ripser.cpp: In constructor 'ripser<compressed_distance_matrix<(compressed_matrix_layout)0u> >::simplex_coboundary_enumerator::simplex_coboundary_enumerator(diameter_entry_t, index_t, const ripser<compressed_distance_matrix<(compressed_matrix_layout)0u> >&)': ripser.cpp:845:62: error: no matching function for call to 'diameter_entry_t::diameter_entry_t()' binomial_coeff(_parent.binomial_coeff), parent(_parent) { ^ ripser.cpp:182:37: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_ConstructiblePair<_U1, _U2>() && _ImplicitlyConvertiblePair<_U1, _U2>()), bool>::type <anonymous> > constexpr diameter_entry_t::diameter_entry_t(const float&, const entry_t&) using std::pair<value_t, entry_t>::pair; ^~~~ ripser.cpp:182:37: note: template argument deduction/substitution failed: ripser.cpp:845:62: note: candidate expects 2 arguments, 0 provided binomial_coeff(_parent.binomial_coeff), parent(_parent) { ^ ripser.cpp:182:37: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_ConstructiblePair<_U1, _U2>() && (! _ImplicitlyConvertiblePair<_U1, _U2>())), bool>::type <anonymous> > constexpr diameter_entry_t::diameter_entry_t(const float&, const entry_t&) using std::pair<value_t, entry_t>::pair; ^~~~

Assertion failure

If I take the master branch and compile with g++ -Wall ripser.cpp -o ripser -g (note: no NDEBUG), running ./ripser --format point-cloud examples/o3_1024.txt produces

ripser: ripser.cpp:115: index_t binomial_coeff_table::operator()(index_t, index_t) const: Assertion `n < B.size() && k < B[n].size() && n >= k - 1' failed.

Did I get the options wrong again? ./ripser --format lower-distance examples/projective_plane.lower_distance_matrix produces the same error.

Make error

Hello,

While following the ripser installation I am facing the error:

Makefile:11: recipe for target 'ripser-coeff' failed
mingw32-make: *** [ripser-coeff] Error 1

Is there something that I am doing wrong. Any help is highly appreciated.

Regards,

How to output the components of certain homology group?

Dear Dr. Bauer

I have calculated barcodes, and I found a particular persistent homology in the 2-dim, which is more persistent than all other 2-dim homology groups found in the same calculation, How to output the components in that special 2-dim homology group? Are there any options I can use while running Ripser, or do you suggest any example codes on doing this?

Thanks!

Best Regards,
Peter

On the representative_cycles branch

First of all, thank you @ubauer for the amazing work done with ripser! (Opening an issue gives me a good excuse to finally say this directly!)

It seems to me that the quantum leap in computational runtimes made possible by ripser is an important piece in the history of making TDA more appealing and accessible to non-topologists. As you know, this is true in particular in the Python community (that I am most familiar with) thanks to the great effort by you, @ctralie, @sauln (and others maybe?) in making solid bindings in ripser.py. It is now much less esoteric to suggest that persistent-homology--derived feature extraction can be made an integral part of machine learning pipelines. Several projects are now exploring how to provide "regular data scientists" with plug-in topological components which can be used alongside more conventional machine learning toolkits. scikit-tda, GUDHI and giotto-tda (the latter of which I am involved with) are some such examples.

When interacting with non-topologists who are data science practitioners, I find that arguing in favour of TDA based on its ability to describe geometric structures that are in principle "there to see" tends to be successful. It brings the field very close to, say, clustering and other data-viz techniques which everyone would agree are useful!

Persistence diagrams/barcodes are great of course, but they are to the full persistent homology calculation a bit (or a lot, for H_0) as returning a cut dendrogram in single-linkage clustering would be to returning an actual clustering of the data. Representative (persistent) cycles, if visualized, could make (Vietoris-Rips) persistent homology a much more "immediate" concept to grapple with for many, not to mention the actual insight into the data that they would bring.

Sorry for the long spiel which contains little new information to you (mostly there to provide context for other readers), but I hope it helps me segue effectively into the real questions. I noticed that you mention the experimental representative_cycles branch, which is great! I am wondering: What would be your quick assessment on the status of progress there? Is there a hoped-for release date, or is work there still in a research phase? Do you expect that final runtimes will compare favourably with Eirene?

I doubt I could contribute much to the C++ codebase, but would love to eventually help the Python community integrate these developments.

Thanks for the patience in reading!

Example for loading upper triangular matrix to ripser

Please provide an example file on how to provide an upper triangular matrix that has unit diagonal. I have a (symmetric) correlation matirx with unit diagonal. I have extracted the upper triangular portion of this and written to a csv file. It has 264 columns at the max and 264 rows.

Rips not working when I change maxdim

I've been using Rips to make persistence diagrams. It works fine with the default maxdim=1. However, when I change to maxdim=2, I get no output and the stored variables I had disappear. I'm using Spyder to run my code, and all the variables in my variable explorer window disappear when I run maxdim=2. What is happening?

For example, this works fine:
rips=Rips()
dgms_X = rips.fit_transform(data)
plot_diagrams(dgms_X, show=True)

This dies:
rips=Rips(maxdim=2)
dgms_X = rips.fit_transform(data)
plot_diagrams(dgms_X, show=True)

Thank you!!

default format of input files

Hi !

First, thank you for the great library.

I was testing ripser and looking into the help, it says that the default format used is lower-distance.
But, looking into the code, it seems that the default format is DISTANCE_MATRIX .

Am I misunderstanding something ?

PS: The help documentation:

--format         use the specified file format for the input. Options are:
                     lower-distance (lower triangular distance matrix; default)
                     upper-distance (upper triangular distance matrix)
                     distance       (full distance matrix)
                     point-cloud    (point cloud in Euclidean space)
                     dipha          (distance matrix in DIPHA file format)
                     sparse         (sparse distance matrix in sparse triplet format)
                     binary         (lower triangular distance matrix in binary format)

Homology of a cube

Dear Ripser developers,

While trying to compute the persistent homology of a cube, expecting results similar to a 2-sphere, I get the following results:

point cloud
--------------
0.25 0.25 0.25
0.75 0.25 0.25
0.25 0.75 0.25
0.75 0.75 0.25
0.25 0.25 0.75
0.75 0.25 0.75
0.25 0.75 0.75
0.75 0.75 0.75

Results:
sneky_riipser_bug

The issues are the following:

1.There are only 5 generators of dimension 1.
2.There are no generators in dimension 2.
3.There is a generator in dimension 3 that should ideally be in dimension 2.

Could you please shed some light to this issue?

Thank you in advance,
Alexandros

Overflow error on 3D datasets

Hello and thank you for your work!

I am trying to use Ripser to compute persistence diagrams of rather large 3D datasets, coming from the Open-SciVis-Datasets website.

However, Ripser throws a std::overflow_error when I try to compute persistence pairs up to the dimension 2. If I understand correctly the C++ code, this exception is related to the computation of binomial coefficients which depend on the size of the input distance matrix and the maximum dimension requested.

This issue might be related to #25 and #32 since they feature similar problems. I already opened an issue in the scikit-tda Python wrapper (I wanted to use Ripser via this Python API) but since this is more related to the C++ code, this issue seems better to belong here.

Below, you will find a Python script I used to trigger this overflow error. It takes a raw file from Open-Scivis-Datasets and iterates over the edges of the cubical complex to generate a sparse matrix in sparse triplet format that is fed to the Ripser executable. Although the diagram is computed as expected with the smallest datasets (nucleon, marschner_lobb, silicium, up to 120k vertices), the error occurs with fuel, neghip (more than 250k vertices) and every larger dataset.

It there a way to circumvent this computation of these binomial coefficients to handle large datasets (up to 1M vertices)?

Thanks in advance for your help,
Best regards,
Pierre Guillou

import argparse
import subprocess
import time

import numpy as np


def load_raw(input_raw):
    extension = input_raw.split(".")[-1]
    if extension != "raw":
        print("Need a .raw file")
        raise TypeError

    # detect extent and data type from file name
    extent, dtype = input_raw.split(".")[0].split("_")[-2:]
    extent = [int(dim) for dim in extent.split("x")]

    dtype_np = {
        "uint8": np.uint8,
        "int16": np.int16,
        "uint16": np.uint16,
        "float32": np.float32,
        "float64": np.float64,
    }
    dtype = dtype_np[dtype]

    with open(input_raw) as src:
        data = np.fromfile(src, dtype=dtype)
        return data.reshape(extent)


def compute_persistence(sparse_triplets, output_diagram, ripser_executable):
    proc = subprocess.Popen(
        [ripser_executable, "--format", "sparse", "--dim", "2"],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        universal_newlines=True,
    )
    out, _ = proc.communicate(sparse_triplets)

    with open(output_diagram, "w") as dst:
        dst.write(out)


def build_sparse_triplets(data):
    triplets = list()
    # loop over every edge of the cubical complex to get the sparse matrix triplets
    with np.nditer(data, flags=["multi_index"]) as it:
        for v in it:
            i = np.ravel_multi_index(it.multi_index, data.shape)
            for d in range(data.ndim):
                for s in [-1, 1]:
                    coords = list(it.multi_index)
                    s = coords[d] + s
                    if s < 0 or s >= data.shape[d]:
                        continue
                    coords[d] = s
                    j = np.ravel_multi_index(coords, data.shape)
                    if i < j:  # upper triangle distance matrix
                        triplets.append([i, j, max(data.flat[j], v)])

    return "\n".join([f"{i} {j} {v}" for i, j, v in triplets])


def main(input_raw, output_diagram, ripser_executable):
    data = load_raw(input_raw)
    start = time.time()
    sparse_triplets = build_sparse_triplets(data)
    print(f"Build sparse triplets in {time.time() - start:.2f}s")
    compute_persistence(sparse_triplets, output_diagram, ripser_executable)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Wrapper around Ripser C++")
    parser.add_argument("input_raw", help="Input raw file from OpenSciVis datasets")
    parser.add_argument(
        "-o",
        "--output_diagram",
        help="Output diagram in Ripser format",
        default="out.ripser",
    )
    parser.add_argument(
        "-e",
        "--ripser_executable",
        help="Path to the Ripser executable",
        default="ripser/ripser",
    )
    args = parser.parse_args()

    main(args.input_raw, args.output_diagram, args.ripser_executable)

"distances" or "distances"?

In the ReadMe, it says to use the flag "distances"; however, this doesn't work when I run Ripser. It does, however, work if I use the flag "distance". So, I believe either the documentation should be changed or the code...

Haskell wrapper

Not an issue, per se, but just so you know it exists. I made a Haskell wrapper for ripser.

It takes a container of items and a distance function, produces a lower-distance-matrix, opens a ripser process, sends the LDM on stdin and then parses the result into a list of Barcodes (using a data structure from https://hackage.haskell.org/package/Persistence-2.0.3/docs/Persistence-Filtration.html).

The wrapper can be found on github here: https://github.com/adamConnerSax/ripser-haskell.

sparse distance matrix in terminal

Hi all,

I would like to use the sparse distance matrix implementation of RIPSER in the terminal. However, I cannot find the handle for calling this ability. Anyone knows how can I use it?

Thanks a lot!
Mohamad

Unexpected homology of boundary of a cube

When a regular grid of the boundary of the 3-cube is fed into ripser, the expected 2-dimensional homology class does not appear.

Sample code: (Python interface)

from ripser import ripser, plot_dgms
n=3
segment = [np.linspace(0,1,20)]
endpoints = [np.linspace(0,1,2)]
face = segment * (n - 1) + endpoints
corners = []
for k in range(n):
corners.extend(itertools.product(*(face[k:] + face[:k])))
coords = np.array(corners)

rips = ripser(coords, maxdim=2, thresh=.4)
plot_dgms(rips['dgms'])

Metric defined in Rispser

Hi
Can we use any metric other than "Euclidean", "Manhattan" and "Cosine" while computing distance between rows of data.
Thanks a lot.

ripser-image for different point clouds

Hi, @ubauer

First: thank you very much for this incredible package!!

My name is Inés García-Redondo, I’m writing this message with my collaborator @annasongmaths (Anna Song). We’ve been working with your new package ripser-image and we have two questions. Let us assume that we have X and Z rips filtrations coming from two different point clouds P and P’ respectively, with the same metric.

  1. Would it be possible to use ripser-image in this situation? Currently, we think that the code only admits one single point cloud with two different metrics. We managed a way to do this indirectly: we take P’ as the base point cloud for both filtrations, compute the pairwise distance matrix for Z and then obtain the pairwise distance matrix for X by inflating the distance between any point in P’ \ P (the excluded points) and any point in P’. This trick prevents edges from forming on excluded points before the full complex has finished growing in the smaller point cloud P.

  2. However this trick is computationally expensive because we are still computing all those steps of the filtration, even though they don’t affect the final result. We tried using thresholding to stop the computation before reaching those steps, but we have found that this feature makes some bars disappear, instead of simply truncating the bars as we expected. Is this expectation of ours wrong in the framework of image persistence?

Thanks in advance for your help!

Best,
Inés and Anna

Multithreading support

Hi! Very neat project. This is not really an issue, but asking out of interest more than anything -- is there any apparent reason multithreading is not part of the core algorithm? Seems there are a few nested loops (sparse dist matrix, for example), where this could be beneficial. Thanks for clarification!

MemoryError: std::bad_alloc

Dear

When I am using Ripser to do calculations on distance matrices, I encountered the error message
"MemoryError: std::bad_alloc"

Could you help by providing any solutions, e.g. adding more memory or changing the source codes?

Thank!

Peter

Include ripser as c++ library

Hi. Thanks for the great work.

Is there a chance to include ripser in a c++ project using a header file?

Thanks and cheers
Conrad

Question about apparent pairs

This may be a simple question, but how does ripser manage to find all H1 pairs without enumerating all 2-simplices (< threshold)?

In the code, it appears Ripser first finds positive edges lacking apparent zero cofacets, and then enumerates each edge's cofacets, reducing as it goes along.

I may be missing something obvious, but how does this compute all H1 pairs? While it is clear that a negative 2-simplex of an apparent H1 pair must indeed be a cofacet of its positive counterpart (by definition of an AP), this isn't true in general.

Python bindings

Update - bindings complete

Python bindings and documentation on how to use them can be found at ctralie/ripser or on Pypi:

pip install Cython
pip install ripser

terminate called after throwing an instance of 'std::bad_alloc'

I am using Ripser to perform dimension 0 and 1 calculations on a point cloud with between 15k and 20k points in 9-d (the input file is 15 000 x 9 dimensional). However, I've received the error message :

terminate called after throwing an instance of 'std::bad_alloc'

If I try with less points ( 10k points ), I do not get this error. Is it that Ripser has a limit of the number of data point in the point cloud it can handle? Could you please provide an idea of how to go around this, and can it be fixed?

Thank you!

Reduced number of 0-dim features

Hi! I am using the package TDAstats with the function calculate_homology that takes ripser functions. I realized that I am always obtaining one feature less in dimension 0 than expected. For example, when I use calculate_homology over a graph with 7 vertices I only obtain 6 features at dimension 0 and that start with a filtration weight 0, why is that? Shouldn't be 7 features? Is it related to the concept of "reduced homology"?
Thanks a lot!

Ripser output intervals to file

Is it possible to save all intervals computed by Ripser to an external file?

I am trying to edit the code to do this, but some intervals are not inserted in the file.

I was using fopen() and fprintf (eg. fprintf(ripser_out, "%lu %.8f %.8f\n",dim,diameter,death);) but for some random data set the output on screen is not the same as the one created in output file.

I have been working on this for more than 1 week but no progress.

It would be good to have an output file to be used within other programs. So a good output could have the format: dim birth death for intervals as [a,b) and dim birth -1 for [a, ).

I have no idea why my code does not work. Maybe because some limitation with fopen.

I appreciate any help.
Thanks in advance.

Image persistence with sparse distance matrices

Hello,
we wanted to compute the persistence diagram of the image between 2 filtrations, and the branch https://github.com/Ripser/ripser/tree/image-persistence-simple looked promising. However, it looks like it is based on an old version of Ripser before sparse distance matrices were introduced, and our (very sparse) matrices are too large for a dense representation.
Do you think it is mostly a matter of merging the 2 branches (which may be much more work than git merge but should remain relatively straightforward), or is there something in the image algorithm that is likely to behave badly with sparse distance matrices?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.