multipers 2.0.0__cp312-cp312-macosx_13_0_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of multipers might be problematic. Click here for more details.
- multipers/.dylibs/libc++.1.0.dylib +0 -0
- multipers/.dylibs/libtbb.12.12.dylib +0 -0
- multipers/.dylibs/libtbbmalloc.2.12.dylib +0 -0
- multipers/__init__.py +11 -0
- multipers/_signed_measure_meta.py +268 -0
- multipers/_slicer_meta.py +171 -0
- multipers/data/MOL2.py +350 -0
- multipers/data/UCR.py +18 -0
- multipers/data/__init__.py +1 -0
- multipers/data/graphs.py +466 -0
- multipers/data/immuno_regions.py +27 -0
- multipers/data/minimal_presentation_to_st_bf.py +0 -0
- multipers/data/pytorch2simplextree.py +91 -0
- multipers/data/shape3d.py +101 -0
- multipers/data/synthetic.py +68 -0
- multipers/distances.py +198 -0
- multipers/euler_characteristic.pyx +132 -0
- multipers/filtration_conversions.pxd +229 -0
- multipers/filtrations.pxd +225 -0
- multipers/function_rips.cpython-312-darwin.so +0 -0
- multipers/function_rips.pyx +105 -0
- multipers/grids.cpython-312-darwin.so +0 -0
- multipers/grids.pyx +281 -0
- multipers/hilbert_function.pyi +46 -0
- multipers/hilbert_function.pyx +153 -0
- multipers/io.cpython-312-darwin.so +0 -0
- multipers/io.pyx +571 -0
- multipers/ml/__init__.py +0 -0
- multipers/ml/accuracies.py +90 -0
- multipers/ml/convolutions.py +532 -0
- multipers/ml/invariants_with_persistable.py +79 -0
- multipers/ml/kernels.py +176 -0
- multipers/ml/mma.py +659 -0
- multipers/ml/one.py +472 -0
- multipers/ml/point_clouds.py +238 -0
- multipers/ml/signed_betti.py +50 -0
- multipers/ml/signed_measures.py +1542 -0
- multipers/ml/sliced_wasserstein.py +461 -0
- multipers/ml/tools.py +113 -0
- multipers/mma_structures.cpython-312-darwin.so +0 -0
- multipers/mma_structures.pxd +127 -0
- multipers/mma_structures.pyx +2433 -0
- multipers/multiparameter_edge_collapse.py +41 -0
- multipers/multiparameter_module_approximation.cpython-312-darwin.so +0 -0
- multipers/multiparameter_module_approximation.pyx +211 -0
- multipers/pickle.py +53 -0
- multipers/plots.py +326 -0
- multipers/point_measure_integration.cpython-312-darwin.so +0 -0
- multipers/point_measure_integration.pyx +139 -0
- multipers/rank_invariant.cpython-312-darwin.so +0 -0
- multipers/rank_invariant.pyx +229 -0
- multipers/simplex_tree_multi.cpython-312-darwin.so +0 -0
- multipers/simplex_tree_multi.pxd +129 -0
- multipers/simplex_tree_multi.pyi +715 -0
- multipers/simplex_tree_multi.pyx +4655 -0
- multipers/slicer.cpython-312-darwin.so +0 -0
- multipers/slicer.pxd +781 -0
- multipers/slicer.pyx +3393 -0
- multipers/tensor.pxd +13 -0
- multipers/test.pyx +44 -0
- multipers/tests/__init__.py +40 -0
- multipers/tests/old_test_rank_invariant.py +91 -0
- multipers/tests/test_diff_helper.py +74 -0
- multipers/tests/test_hilbert_function.py +82 -0
- multipers/tests/test_mma.py +51 -0
- multipers/tests/test_point_clouds.py +59 -0
- multipers/tests/test_python-cpp_conversion.py +82 -0
- multipers/tests/test_signed_betti.py +181 -0
- multipers/tests/test_simplextreemulti.py +98 -0
- multipers/tests/test_slicer.py +63 -0
- multipers/torch/__init__.py +1 -0
- multipers/torch/diff_grids.py +217 -0
- multipers/torch/rips_density.py +257 -0
- multipers-2.0.0.dist-info/LICENSE +21 -0
- multipers-2.0.0.dist-info/METADATA +29 -0
- multipers-2.0.0.dist-info/RECORD +78 -0
- multipers-2.0.0.dist-info/WHEEL +5 -0
- multipers-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from gudhi.simplex_tree import SimplexTree ## Small hack for typing
|
|
3
|
+
from typing import Iterable
|
|
4
|
+
from tqdm import tqdm
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# SimplexTree python interface
|
|
8
|
+
class SimplexTreeMulti:
|
|
9
|
+
"""The simplex tree is an efficient and flexible data structure for
|
|
10
|
+
representing general (filtered) simplicial complexes. The data structure
|
|
11
|
+
is described in Jean-Daniel Boissonnat and Clément Maria. The Simplex
|
|
12
|
+
Tree: An Efficient Data Structure for General Simplicial Complexes.
|
|
13
|
+
Algorithmica, pages 1–22, 2014.
|
|
14
|
+
|
|
15
|
+
This class is a multi-filtered, with keys, and non contiguous vertices version
|
|
16
|
+
of the simplex tree.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, other = None, num_parameters:int=2,default_values=[]):
|
|
20
|
+
"""SimplexTreeMulti constructor.
|
|
21
|
+
|
|
22
|
+
:param other: If `other` is `None` (default value), an empty `SimplexTreeMulti` is created.
|
|
23
|
+
If `other` is a `SimplexTree`, the `SimplexTreeMulti` is constructed from a deep copy of `other`.
|
|
24
|
+
If `other` is a `SimplexTreeMulti`, the `SimplexTreeMulti` is constructed from a deep copy of `other`.
|
|
25
|
+
:type other: SimplexTree or SimplexTreeMulti (Optional)
|
|
26
|
+
:param num_parameters: The number of parameter of the multi-parameter filtration.
|
|
27
|
+
:type num_parameters: int
|
|
28
|
+
:returns: An empty or a copy simplex tree.
|
|
29
|
+
:rtype: SimplexTreeMulti
|
|
30
|
+
|
|
31
|
+
:raises TypeError: In case `other` is neither `None`, nor a `SimplexTree`, nor a `SimplexTreeMulti`.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def __is_defined(self):
|
|
37
|
+
"""Returns true if SimplexTree pointer is not NULL.
|
|
38
|
+
"""
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
# def __is_persistence_defined(self):
|
|
42
|
+
# """Returns true if Persistence pointer is not NULL.
|
|
43
|
+
# """
|
|
44
|
+
# return self.pcohptr != NULL
|
|
45
|
+
|
|
46
|
+
def copy(self)->SimplexTreeMulti:
|
|
47
|
+
"""
|
|
48
|
+
:returns: A simplex tree that is a deep copy of itself.
|
|
49
|
+
:rtype: SimplexTreeMulti
|
|
50
|
+
|
|
51
|
+
:note: The persistence information is not copied. If you need it in the clone, you have to call
|
|
52
|
+
:func:`compute_persistence` on it even if you had already computed it in the original.
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
def __deepcopy__(self):
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
def filtration(self, simplex:list|np.ndarray)->np.ndarray:
|
|
60
|
+
"""This function returns the filtration value for a given N-simplex in
|
|
61
|
+
this simplicial complex, or +infinity if it is not in the complex.
|
|
62
|
+
|
|
63
|
+
:param simplex: The N-simplex, represented by a list of vertex.
|
|
64
|
+
:type simplex: list of int
|
|
65
|
+
:returns: The simplicial complex multi-critical filtration value.
|
|
66
|
+
:rtype: numpy array of shape (-1, num_parameters)
|
|
67
|
+
"""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
def assign_filtration(self, simplex:list|np.ndarray, filtration:list|np.ndarray)->None:
|
|
71
|
+
"""This function assigns a new multi-critical filtration value to a
|
|
72
|
+
given N-simplex.
|
|
73
|
+
|
|
74
|
+
:param simplex: The N-simplex, represented by a list of vertex.
|
|
75
|
+
:type simplex: list of int
|
|
76
|
+
:param filtration: The new filtration(s) value(s), concatenated.
|
|
77
|
+
:type filtration: list[float] or np.ndarray[float, ndim=1]
|
|
78
|
+
|
|
79
|
+
.. note::
|
|
80
|
+
Beware that after this operation, the structure may not be a valid
|
|
81
|
+
filtration anymore, a simplex could have a lower filtration value
|
|
82
|
+
than one of its faces. Callers are responsible for fixing this
|
|
83
|
+
(with more :meth:`assign_filtration` or
|
|
84
|
+
:meth:`make_filtration_non_decreasing` for instance) before calling
|
|
85
|
+
any function that relies on the filtration property, like
|
|
86
|
+
:meth:`persistence`.
|
|
87
|
+
"""
|
|
88
|
+
...
|
|
89
|
+
|
|
90
|
+
def __getitem__(self, simplex):
|
|
91
|
+
...
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def num_vertices(self)->int:
|
|
96
|
+
"""This function returns the number of vertices of the simplicial
|
|
97
|
+
complex.
|
|
98
|
+
|
|
99
|
+
:returns: The simplicial complex number of vertices.
|
|
100
|
+
:rtype: int
|
|
101
|
+
"""
|
|
102
|
+
...
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def num_simplices(self)->int:
|
|
106
|
+
"""This function returns the number of simplices of the simplicial
|
|
107
|
+
complex.
|
|
108
|
+
|
|
109
|
+
:returns: the simplicial complex number of simplices.
|
|
110
|
+
:rtype: int
|
|
111
|
+
"""
|
|
112
|
+
...
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def dimension(self)->int:
|
|
116
|
+
"""This function returns the dimension of the simplicial complex.
|
|
117
|
+
|
|
118
|
+
:returns: the simplicial complex dimension.
|
|
119
|
+
:rtype: int
|
|
120
|
+
|
|
121
|
+
.. note::
|
|
122
|
+
|
|
123
|
+
This function is not constant time because it can recompute
|
|
124
|
+
dimension if required (can be triggered by
|
|
125
|
+
:func:`remove_maximal_simplex`
|
|
126
|
+
or
|
|
127
|
+
:func:`prune_above_filtration`
|
|
128
|
+
methods).
|
|
129
|
+
"""
|
|
130
|
+
...
|
|
131
|
+
def upper_bound_dimension(self)->int:
|
|
132
|
+
"""This function returns a valid dimension upper bound of the
|
|
133
|
+
simplicial complex.
|
|
134
|
+
|
|
135
|
+
:returns: an upper bound on the dimension of the simplicial complex.
|
|
136
|
+
:rtype: int
|
|
137
|
+
"""
|
|
138
|
+
return self.get_ptr().upper_bound_dimension()
|
|
139
|
+
|
|
140
|
+
def set_dimension(self, dimension)->None:
|
|
141
|
+
"""This function sets the dimension of the simplicial complex.
|
|
142
|
+
|
|
143
|
+
:param dimension: The new dimension value.
|
|
144
|
+
:type dimension: int
|
|
145
|
+
|
|
146
|
+
.. note::
|
|
147
|
+
|
|
148
|
+
This function must be used with caution because it disables
|
|
149
|
+
dimension recomputation when required
|
|
150
|
+
(this recomputation can be triggered by
|
|
151
|
+
:func:`remove_maximal_simplex`
|
|
152
|
+
or
|
|
153
|
+
:func:`prune_above_filtration`
|
|
154
|
+
).
|
|
155
|
+
"""
|
|
156
|
+
...
|
|
157
|
+
|
|
158
|
+
# def find(self, simplex)->bool:
|
|
159
|
+
# """This function returns if the N-simplex was found in the simplicial
|
|
160
|
+
# complex or not.
|
|
161
|
+
|
|
162
|
+
# :param simplex: The N-simplex to find, represented by a list of vertex.
|
|
163
|
+
# :type simplex: list of int
|
|
164
|
+
# :returns: true if the simplex was found, false otherwise.
|
|
165
|
+
# :rtype: bool
|
|
166
|
+
# """
|
|
167
|
+
# return self.get_ptr().find_simplex(simplex)
|
|
168
|
+
def __contains__(self, simplex)->bool:
|
|
169
|
+
"""This function returns if the N-simplex was found in the simplicial
|
|
170
|
+
complex or not.
|
|
171
|
+
|
|
172
|
+
:param simplex: The N-simplex to find, represented by a list of vertex.
|
|
173
|
+
:type simplex: list of int
|
|
174
|
+
:returns: true if the simplex was found, false otherwise.
|
|
175
|
+
:rtype: bool
|
|
176
|
+
"""
|
|
177
|
+
...
|
|
178
|
+
|
|
179
|
+
def insert(self, simplex, filtration:list|np.ndarray|None=None)->bool:
|
|
180
|
+
"""This function inserts the given N-simplex and its subfaces with the
|
|
181
|
+
given filtration value (default value is '0.0'). If some of those
|
|
182
|
+
simplices are already present with a higher filtration value, their
|
|
183
|
+
filtration value is lowered.
|
|
184
|
+
|
|
185
|
+
:param simplex: The N-simplex to insert, represented by a list of
|
|
186
|
+
vertex.
|
|
187
|
+
:type simplex: list of int
|
|
188
|
+
:param filtration: The filtration value of the simplex.
|
|
189
|
+
:type filtration: float
|
|
190
|
+
:returns: true if the simplex was not yet in the complex, false
|
|
191
|
+
otherwise (whatever its original filtration value).
|
|
192
|
+
:rtype: bool
|
|
193
|
+
"""
|
|
194
|
+
...
|
|
195
|
+
|
|
196
|
+
@cython.boundscheck(False)
|
|
197
|
+
@cython.wraparound(False)
|
|
198
|
+
def insert_batch(self, some_int[:,:] vertex_array, some_float[:,:] filtrations)->SimplexTreeMulti:
|
|
199
|
+
"""Inserts k-simplices given by a sparse array in a format similar
|
|
200
|
+
to `torch.sparse <https://pytorch.org/docs/stable/sparse.html>`_.
|
|
201
|
+
The n-th simplex has vertices `vertex_array[0,n]`, ...,
|
|
202
|
+
`vertex_array[k,n]` and filtration value `filtrations[n,num_parameters]`.
|
|
203
|
+
/!\ Only compatible with 1-critical filtrations. If a simplex is repeated,
|
|
204
|
+
only one filtration value will be taken into account.
|
|
205
|
+
|
|
206
|
+
:param vertex_array: the k-simplices to insert.
|
|
207
|
+
:type vertex_array: numpy.array of shape (k+1,n)
|
|
208
|
+
:param filtrations: the filtration values.
|
|
209
|
+
:type filtrations: numpy.array of shape (n,num_parameters)
|
|
210
|
+
"""
|
|
211
|
+
# TODO : multi-critical
|
|
212
|
+
# cdef vector[int] vertices = np.unique(vertex_array)
|
|
213
|
+
...
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@cython.boundscheck(False)
|
|
217
|
+
@cython.wraparound(False)
|
|
218
|
+
def assign_batch_filtration(self, some_int[:,:] vertex_array, some_float[:,:] filtrations, bool propagate=True)->SimplexTreeMulti:
|
|
219
|
+
"""Assign k-simplices given by a sparse array in a format similar
|
|
220
|
+
to `torch.sparse <https://pytorch.org/docs/stable/sparse.html>`_.
|
|
221
|
+
The n-th simplex has vertices `vertex_array[0,n]`, ...,
|
|
222
|
+
`vertex_array[k,n]` and filtration value `filtrations[n,num_parameters]`.
|
|
223
|
+
/!\ Only compatible with 1-critical filtrations. If a simplex is repeated,
|
|
224
|
+
only one filtration value will be taken into account.
|
|
225
|
+
|
|
226
|
+
:param vertex_array: the k-simplices to assign.
|
|
227
|
+
:type vertex_array: numpy.array of shape (k+1,n)
|
|
228
|
+
:param filtrations: the filtration values.
|
|
229
|
+
:type filtrations: numpy.array of shape (n,num_parameters)
|
|
230
|
+
"""
|
|
231
|
+
...
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def get_simplices(self):
|
|
236
|
+
"""This function returns a generator with simplices and their given
|
|
237
|
+
filtration values.
|
|
238
|
+
|
|
239
|
+
:returns: The simplices.
|
|
240
|
+
:rtype: generator with tuples(simplex, filtration)
|
|
241
|
+
"""
|
|
242
|
+
...
|
|
243
|
+
|
|
244
|
+
def get_filtration(self):
|
|
245
|
+
"""This function returns a generator with simplices and their given
|
|
246
|
+
filtration values sorted by increasing filtration values.
|
|
247
|
+
|
|
248
|
+
:returns: The simplices sorted by increasing filtration values.
|
|
249
|
+
:rtype: generator with tuples(simplex, filtration)
|
|
250
|
+
"""
|
|
251
|
+
...
|
|
252
|
+
|
|
253
|
+
def get_skeleton(self, dimension):
|
|
254
|
+
"""This function returns a generator with the (simplices of the) skeleton of a maximum given dimension.
|
|
255
|
+
|
|
256
|
+
:param dimension: The skeleton dimension value.
|
|
257
|
+
:type dimension: int
|
|
258
|
+
:returns: The (simplices of the) skeleton of a maximum dimension.
|
|
259
|
+
:rtype: generator with tuples(simplex, filtration)
|
|
260
|
+
"""
|
|
261
|
+
...
|
|
262
|
+
|
|
263
|
+
def get_star(self, simplex):
|
|
264
|
+
"""This function returns the star of a given N-simplex.
|
|
265
|
+
|
|
266
|
+
:param simplex: The N-simplex, represented by a list of vertex.
|
|
267
|
+
:type simplex: list of int
|
|
268
|
+
:returns: The (simplices of the) star of a simplex.
|
|
269
|
+
:rtype: list of tuples(simplex, filtration)
|
|
270
|
+
"""
|
|
271
|
+
...
|
|
272
|
+
|
|
273
|
+
def get_cofaces(self, simplex, codimension):
|
|
274
|
+
"""This function returns the cofaces of a given N-simplex with a
|
|
275
|
+
given codimension.
|
|
276
|
+
|
|
277
|
+
:param simplex: The N-simplex, represented by a list of vertex.
|
|
278
|
+
:type simplex: list of int
|
|
279
|
+
:param codimension: The codimension. If codimension = 0, all cofaces
|
|
280
|
+
are returned (equivalent of get_star function)
|
|
281
|
+
:type codimension: int
|
|
282
|
+
:returns: The (simplices of the) cofaces of a simplex
|
|
283
|
+
:rtype: list of tuples(simplex, filtration)
|
|
284
|
+
"""
|
|
285
|
+
...
|
|
286
|
+
|
|
287
|
+
def get_boundaries(self, simplex):
|
|
288
|
+
"""This function returns a generator with the boundaries of a given N-simplex.
|
|
289
|
+
If you do not need the filtration values, the boundary can also be obtained as
|
|
290
|
+
:code:`itertools.combinations(simplex,len(simplex)-1)`.
|
|
291
|
+
|
|
292
|
+
:param simplex: The N-simplex, represented by a list of vertex.
|
|
293
|
+
:type simplex: list of int.
|
|
294
|
+
:returns: The (simplices of the) boundary of a simplex
|
|
295
|
+
:rtype: generator with tuples(simplex, filtration)
|
|
296
|
+
"""
|
|
297
|
+
...
|
|
298
|
+
|
|
299
|
+
def remove_maximal_simplex(self, simplex):
|
|
300
|
+
"""This function removes a given maximal N-simplex from the simplicial
|
|
301
|
+
complex.
|
|
302
|
+
|
|
303
|
+
:param simplex: The N-simplex, represented by a list of vertex.
|
|
304
|
+
:type simplex: list of int
|
|
305
|
+
|
|
306
|
+
.. note::
|
|
307
|
+
|
|
308
|
+
The dimension of the simplicial complex may be lower after calling
|
|
309
|
+
remove_maximal_simplex than it was before. However,
|
|
310
|
+
:func:`upper_bound_dimension`
|
|
311
|
+
method will return the old value, which
|
|
312
|
+
remains a valid upper bound. If you care, you can call
|
|
313
|
+
:func:`dimension`
|
|
314
|
+
to recompute the exact dimension.
|
|
315
|
+
"""
|
|
316
|
+
...
|
|
317
|
+
|
|
318
|
+
# def prune_above_filtration(self, filtration)->bool:
|
|
319
|
+
# """Prune above filtration value given as parameter.
|
|
320
|
+
|
|
321
|
+
# :param filtration: Maximum threshold value.
|
|
322
|
+
# :type filtration: float
|
|
323
|
+
# :returns: The filtration modification information.
|
|
324
|
+
# :rtype: bool
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
# .. note::
|
|
328
|
+
|
|
329
|
+
# Note that the dimension of the simplicial complex may be lower
|
|
330
|
+
# after calling
|
|
331
|
+
# :func:`prune_above_filtration`
|
|
332
|
+
# than it was before. However,
|
|
333
|
+
# :func:`upper_bound_dimension`
|
|
334
|
+
# will return the old value, which remains a
|
|
335
|
+
# valid upper bound. If you care, you can call
|
|
336
|
+
# :func:`dimension`
|
|
337
|
+
# method to recompute the exact dimension.
|
|
338
|
+
# """
|
|
339
|
+
# return self.get_ptr().prune_above_filtration(filtration)
|
|
340
|
+
|
|
341
|
+
def expansion(self, int max_dim)->SimplexTreeMulti:
|
|
342
|
+
"""Expands the simplex tree containing only its one skeleton
|
|
343
|
+
until dimension max_dim.
|
|
344
|
+
|
|
345
|
+
The expanded simplicial complex until dimension :math:`d`
|
|
346
|
+
attached to a graph :math:`G` is the maximal simplicial complex of
|
|
347
|
+
dimension at most :math:`d` admitting the graph :math:`G` as
|
|
348
|
+
:math:`1`-skeleton.
|
|
349
|
+
The filtration value assigned to a simplex is the maximal filtration
|
|
350
|
+
value of one of its edges.
|
|
351
|
+
|
|
352
|
+
The simplex tree must contain no simplex of dimension bigger than
|
|
353
|
+
1 when calling the method.
|
|
354
|
+
|
|
355
|
+
:param max_dim: The maximal dimension.
|
|
356
|
+
:type max_dim: int
|
|
357
|
+
"""
|
|
358
|
+
...
|
|
359
|
+
|
|
360
|
+
def make_filtration_non_decreasing(self)->bool:
|
|
361
|
+
"""This function ensures that each simplex has a higher filtration
|
|
362
|
+
value than its faces by increasing the filtration values.
|
|
363
|
+
|
|
364
|
+
:returns: True if any filtration value was modified,
|
|
365
|
+
False if the filtration was already non-decreasing.
|
|
366
|
+
:rtype: bool
|
|
367
|
+
"""
|
|
368
|
+
...
|
|
369
|
+
|
|
370
|
+
def reset_filtration(self, filtration, min_dim = 0):
|
|
371
|
+
"""This function resets the filtration value of all the simplices of dimension at least min_dim. Resets all the
|
|
372
|
+
simplex tree when `min_dim = 0`.
|
|
373
|
+
`reset_filtration` may break the filtration property with `min_dim > 0`, and it is the user's responsibility to
|
|
374
|
+
make it a valid filtration (using a large enough `filt_value`, or calling `make_filtration_non_decreasing`
|
|
375
|
+
afterwards for instance).
|
|
376
|
+
|
|
377
|
+
:param filtration: New threshold value.
|
|
378
|
+
:type filtration: float.
|
|
379
|
+
:param min_dim: The minimal dimension. Default value is 0.
|
|
380
|
+
:type min_dim: int.
|
|
381
|
+
"""
|
|
382
|
+
...
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
# def extend_filtration(self):
|
|
387
|
+
# """ Extend filtration for computing extended persistence. This function only uses the filtration values at the
|
|
388
|
+
# 0-dimensional simplices, and computes the extended persistence diagram induced by the lower-star filtration
|
|
389
|
+
# computed with these values.
|
|
390
|
+
#
|
|
391
|
+
# .. note::
|
|
392
|
+
#
|
|
393
|
+
# Note that after calling this function, the filtration values are actually modified within the simplex tree.
|
|
394
|
+
# The function :func:`extended_persistence` retrieves the original values.
|
|
395
|
+
#
|
|
396
|
+
# .. note::
|
|
397
|
+
#
|
|
398
|
+
# Note that this code creates an extra vertex internally, so you should make sure that the simplex tree does
|
|
399
|
+
# not contain a vertex with the largest possible value (i.e., 4294967295).
|
|
400
|
+
#
|
|
401
|
+
# This `notebook <https://github.com/GUDHI/TDA-tutorial/blob/master/Tuto-GUDHI-extended-persistence.ipynb>`_
|
|
402
|
+
# explains how to compute an extension of persistence called extended persistence.
|
|
403
|
+
# """
|
|
404
|
+
# self.get_ptr().compute_extended_filtration()
|
|
405
|
+
|
|
406
|
+
# def extended_persistence(self, homology_coeff_field=11, min_persistence=0):
|
|
407
|
+
# """This function retrieves good values for extended persistence, and separate the diagrams into the Ordinary,
|
|
408
|
+
# Relative, Extended+ and Extended- subdiagrams.
|
|
409
|
+
#
|
|
410
|
+
# :param homology_coeff_field: The homology coefficient field. Must be a prime number. Default value is 11. Max is 46337.
|
|
411
|
+
# :type homology_coeff_field: int
|
|
412
|
+
# :param min_persistence: The minimum persistence value (i.e., the absolute value of the difference between the
|
|
413
|
+
# persistence diagram point coordinates) to take into account (strictly greater than min_persistence).
|
|
414
|
+
# Default value is 0.0. Sets min_persistence to -1.0 to see all values.
|
|
415
|
+
# :type min_persistence: float
|
|
416
|
+
# :returns: A list of four persistence diagrams in the format described in :func:`persistence`. The first one is
|
|
417
|
+
# Ordinary, the second one is Relative, the third one is Extended+ and the fourth one is Extended-.
|
|
418
|
+
# See https://link.springer.com/article/10.1007/s10208-008-9027-z and/or section 2.2 in
|
|
419
|
+
# https://link.springer.com/article/10.1007/s10208-017-9370-z for a description of these subtypes.
|
|
420
|
+
#
|
|
421
|
+
# .. note::
|
|
422
|
+
#
|
|
423
|
+
# This function should be called only if :func:`extend_filtration` has been called first!
|
|
424
|
+
#
|
|
425
|
+
# .. note::
|
|
426
|
+
#
|
|
427
|
+
# The coordinates of the persistence diagram points might be a little different than the
|
|
428
|
+
# original filtration values due to the internal transformation (scaling to [-2,-1]) that is
|
|
429
|
+
# performed on these values during the computation of extended persistence.
|
|
430
|
+
#
|
|
431
|
+
# This `notebook <https://github.com/GUDHI/TDA-tutorial/blob/master/Tuto-GUDHI-extended-persistence.ipynb>`_
|
|
432
|
+
# explains how to compute an extension of persistence called extended persistence.
|
|
433
|
+
# """
|
|
434
|
+
# cdef vector[pair[int, pair[value_type, value_type]]] persistence_result
|
|
435
|
+
# if self.pcohptr != NULL:
|
|
436
|
+
# del self.pcohptr
|
|
437
|
+
# self.pcohptr = new Simplex_tree_persistence_interface(self.get_ptr(), False)
|
|
438
|
+
# self.pcohptr.compute_persistence(homology_coeff_field, -1.)
|
|
439
|
+
# return self.pcohptr.compute_extended_persistence_subdiagrams(min_persistence)
|
|
440
|
+
|
|
441
|
+
# TODO : cython3
|
|
442
|
+
# def expansion_with_blocker(self, max_dim, blocker_func):
|
|
443
|
+
# """Expands the Simplex_tree containing only a graph. Simplices corresponding to cliques in the graph are added
|
|
444
|
+
# incrementally, faces before cofaces, unless the simplex has dimension larger than `max_dim` or `blocker_func`
|
|
445
|
+
# returns `True` for this simplex.
|
|
446
|
+
|
|
447
|
+
# The function identifies a candidate simplex whose faces are all already in the complex, inserts it with a
|
|
448
|
+
# filtration value corresponding to the maximum of the filtration values of the faces, then calls `blocker_func`
|
|
449
|
+
# with this new simplex (represented as a list of int). If `blocker_func` returns `True`, the simplex is removed,
|
|
450
|
+
# otherwise it is kept. The algorithm then proceeds with the next candidate.
|
|
451
|
+
|
|
452
|
+
# .. warning::
|
|
453
|
+
# Several candidates of the same dimension may be inserted simultaneously before calling `blocker_func`, so
|
|
454
|
+
# if you examine the complex in `blocker_func`, you may hit a few simplices of the same dimension that have
|
|
455
|
+
# not been vetted by `blocker_func` yet, or have already been rejected but not yet removed.
|
|
456
|
+
|
|
457
|
+
# :param max_dim: Expansion maximal dimension value.
|
|
458
|
+
# :type max_dim: int
|
|
459
|
+
# :param blocker_func: Blocker oracle.
|
|
460
|
+
# :type blocker_func: Callable[[List[int]], bool]
|
|
461
|
+
# """
|
|
462
|
+
# self.get_ptr().expansion_with_blockers_callback(max_dim, callback, <void*>blocker_func)
|
|
463
|
+
|
|
464
|
+
# def persistence(self, homology_coeff_field=11, min_persistence=0, persistence_dim_max = False):
|
|
465
|
+
# """This function computes and returns the persistence of the simplicial complex.
|
|
466
|
+
#
|
|
467
|
+
# :param homology_coeff_field: The homology coefficient field. Must be a
|
|
468
|
+
# prime number. Default value is 11. Max is 46337.
|
|
469
|
+
# :type homology_coeff_field: int
|
|
470
|
+
# :param min_persistence: The minimum persistence value to take into
|
|
471
|
+
# account (strictly greater than min_persistence). Default value is
|
|
472
|
+
# 0.0.
|
|
473
|
+
# Set min_persistence to -1.0 to see all values.
|
|
474
|
+
# :type min_persistence: float
|
|
475
|
+
# :param persistence_dim_max: If true, the persistent homology for the
|
|
476
|
+
# maximal dimension in the complex is computed. If false, it is
|
|
477
|
+
# ignored. Default is false.
|
|
478
|
+
# :type persistence_dim_max: bool
|
|
479
|
+
# :returns: The persistence of the simplicial complex.
|
|
480
|
+
# :rtype: list of pairs(dimension, pair(birth, death))
|
|
481
|
+
# """
|
|
482
|
+
# self.compute_persistence(homology_coeff_field, min_persistence, persistence_dim_max)
|
|
483
|
+
# return self.pcohptr.get_persistence()
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
## This function is only meant for the edge collapse interface.
|
|
488
|
+
def get_edge_list(self):
|
|
489
|
+
...
|
|
490
|
+
|
|
491
|
+
def collapse_edges(self, max_dimension:int=None, num:int=1, progress:bool=False, strong:bool=True, full:bool=False, ignore_warning:bool=False)->SimplexTreeMulti:
|
|
492
|
+
"""Edge collapse for 1-critical 2-parameter clique complex (see https://arxiv.org/abs/2211.05574).
|
|
493
|
+
It uses the code from the github repository https://github.com/aj-alonso/filtration_domination .
|
|
494
|
+
|
|
495
|
+
Parameters
|
|
496
|
+
----------
|
|
497
|
+
max_dimension:int
|
|
498
|
+
Max simplicial dimension of the complex. Unless specified, keeps the same dimension.
|
|
499
|
+
num:int
|
|
500
|
+
The number of collapses to do.
|
|
501
|
+
strong:bool
|
|
502
|
+
Whether to use strong collapses or standard collapses (slower, but may remove more edges)
|
|
503
|
+
full:bool
|
|
504
|
+
Collapses the maximum number of edges if true, i.e., will do (at most) 100 strong collapses and (at most) 100 non-strong collapses afterward.
|
|
505
|
+
progress:bool
|
|
506
|
+
If true, shows the progress of the number of collapses.
|
|
507
|
+
|
|
508
|
+
WARNING
|
|
509
|
+
-------
|
|
510
|
+
- This will destroy all of the k-simplices, with k>=2. Be sure to use this with a clique complex, if you want to preserve the homology >= dimension 1.
|
|
511
|
+
- This is for 1 critical simplices, with 2 parameter persistence.
|
|
512
|
+
Returns
|
|
513
|
+
-------
|
|
514
|
+
self:SimplexTreeMulti
|
|
515
|
+
A (smaller) simplex tree that has the same homology over this bifiltration.
|
|
516
|
+
|
|
517
|
+
"""
|
|
518
|
+
# TODO : find a way to do multiple edge collapses without python conversions.
|
|
519
|
+
...
|
|
520
|
+
|
|
521
|
+
def _reconstruct_from_edge_list(self, edges, swap:bool=True, expand_dimension:int=None)->SimplexTreeMulti:
|
|
522
|
+
"""
|
|
523
|
+
Generates a 1-dimensional copy of self, with the edges given as input. Useful for edge collapses
|
|
524
|
+
|
|
525
|
+
Input
|
|
526
|
+
-----
|
|
527
|
+
- edges : Iterable[(int,int),(float,float)] ## This is the format of the rust library filtration-domination
|
|
528
|
+
- swap : bool
|
|
529
|
+
If true, will swap self and the collapsed simplextrees.
|
|
530
|
+
- expand_dim : int
|
|
531
|
+
expands back the simplextree to this dimension
|
|
532
|
+
Ouput
|
|
533
|
+
-----
|
|
534
|
+
The reduced SimplexTreeMulti having only these edges.
|
|
535
|
+
"""
|
|
536
|
+
...
|
|
537
|
+
|
|
538
|
+
@property
|
|
539
|
+
def num_parameters(self)->int:
|
|
540
|
+
...
|
|
541
|
+
def get_simplices_of_dimension(self, dim:int)->np.ndarray:
|
|
542
|
+
...
|
|
543
|
+
def key(self, simplex:list|np.ndarray):
|
|
544
|
+
...
|
|
545
|
+
def set_keys_to_enumerate(self)->None:
|
|
546
|
+
...
|
|
547
|
+
def set_key(self,simplex:list|np.ndarray, key:int)->None:
|
|
548
|
+
...
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def to_scc(self, path="scc_dataset.txt", progress:bool=True, overwrite:bool=False, ignore_last_generators:bool=True, strip_comments:bool=False, reverse_block:bool=True, rivet_compatible=False)->None:
|
|
552
|
+
""" Create a file with the scc2020 standard, representing the n-filtration of the simplextree.
|
|
553
|
+
Link : https://bitbucket.org/mkerber/chain_complex_format/src/master/
|
|
554
|
+
|
|
555
|
+
Parameters
|
|
556
|
+
----------
|
|
557
|
+
path:str
|
|
558
|
+
path of the file.
|
|
559
|
+
ignore_last_generators:bool = True
|
|
560
|
+
If false, will include the filtration values of the last free persistence module.
|
|
561
|
+
progress:bool = True
|
|
562
|
+
Shows the progress bar.
|
|
563
|
+
overwrite:bool = False
|
|
564
|
+
If true, will overwrite the previous file if it already exists.
|
|
565
|
+
ignore_last_generators:bool=True
|
|
566
|
+
If true, does not write the final generators to the file. Rivet ignores them.
|
|
567
|
+
reverse_block:bool=True
|
|
568
|
+
Some obscure programs reverse the inside-block order.
|
|
569
|
+
rivet_compatible:bool=False
|
|
570
|
+
Returns a firep (old scc2020) format instead. Only Rivet uses this.
|
|
571
|
+
|
|
572
|
+
Returns
|
|
573
|
+
-------
|
|
574
|
+
Nothing
|
|
575
|
+
"""
|
|
576
|
+
...
|
|
577
|
+
|
|
578
|
+
def to_rivet(self, path="rivet_dataset.txt", degree:int|None = None, progress:bool=False, overwrite:bool=False, xbins:int|None=None, ybins:int|None=None)->None:
|
|
579
|
+
""" Create a file that can be imported by rivet, representing the filtration of the simplextree.
|
|
580
|
+
|
|
581
|
+
Parameters
|
|
582
|
+
----------
|
|
583
|
+
path:str
|
|
584
|
+
path of the file.
|
|
585
|
+
degree:int
|
|
586
|
+
The homological degree to ask rivet to compute.
|
|
587
|
+
progress:bool = True
|
|
588
|
+
Shows the progress bar.
|
|
589
|
+
overwrite:bool = False
|
|
590
|
+
If true, will overwrite the previous file if it already exists.
|
|
591
|
+
Returns
|
|
592
|
+
-------
|
|
593
|
+
Nothing
|
|
594
|
+
"""
|
|
595
|
+
...
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
def _get_filtration_values(self, vector[int] degrees, bool inf_to_nan:bool=False)->Iterable[np.ndarray]:
|
|
600
|
+
# cdef vector[int] c_degrees = degrees
|
|
601
|
+
...
|
|
602
|
+
|
|
603
|
+
@staticmethod
|
|
604
|
+
def _reduce_grid(filtrations_values,resolutions=None, strategy:str="exact", bool unique=True, some_float _q_factor=1., drop_quantiles=[0,0]):
|
|
605
|
+
...
|
|
606
|
+
|
|
607
|
+
def get_filtration_grid(self, resolution:Iterable[int]|None=None, degrees:Iterable[int]|None=None, drop_quantiles:float|tuple=0, grid_strategy:str="exact")->Iterable[np.ndarray]:
|
|
608
|
+
"""
|
|
609
|
+
Returns a grid over the n-filtration, from the simplextree. Usefull for grid_squeeze. TODO : multicritical
|
|
610
|
+
|
|
611
|
+
Parameters
|
|
612
|
+
----------
|
|
613
|
+
resolution: list[int]
|
|
614
|
+
resolution of the grid, for each parameter
|
|
615
|
+
box=None : pair[list[float]]
|
|
616
|
+
Grid bounds. format : [low bound, high bound]
|
|
617
|
+
If None is given, will use the filtration bounds of the simplextree.
|
|
618
|
+
grid_strategy="regular" : string
|
|
619
|
+
Either "regular", "quantile", or "exact".
|
|
620
|
+
Returns
|
|
621
|
+
-------
|
|
622
|
+
List of filtration values, for each parameter, defining the grid.
|
|
623
|
+
"""
|
|
624
|
+
...
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
def grid_squeeze(self, filtration_grid:np.ndarray|list|None=None, coordinate_values:bool=True, force=False, **filtration_grid_kwargs)->SimplexTreeMulti:
|
|
629
|
+
"""
|
|
630
|
+
Fit the filtration of the simplextree to a grid.
|
|
631
|
+
|
|
632
|
+
:param filtration_grid: The grid on which to squeeze. An example of grid can be given by the `get_filtration_grid` method.
|
|
633
|
+
:type filtration_grid: list[list[float]]
|
|
634
|
+
:param coordinate_values: If true, the filtrations values of the simplices will be set to the coordinate of the filtration grid.
|
|
635
|
+
:type coordinate_values: bool
|
|
636
|
+
"""
|
|
637
|
+
...
|
|
638
|
+
|
|
639
|
+
@property
|
|
640
|
+
def _is_squeezed(self)->bool:
|
|
641
|
+
...
|
|
642
|
+
|
|
643
|
+
def filtration_bounds(self, degrees:Iterable[int]|None=None, q:float|tuple=0, split_dimension:bool=False)->np.ndarray:
|
|
644
|
+
"""
|
|
645
|
+
Returns the filtrations bounds of the finite filtration values.
|
|
646
|
+
"""
|
|
647
|
+
...
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
def fill_lowerstar(self, F, parameter:int)->SimplexTreeMulti:
|
|
653
|
+
""" Fills the `dimension`th filtration by the lower-star filtration defined by F.
|
|
654
|
+
|
|
655
|
+
Parameters
|
|
656
|
+
----------
|
|
657
|
+
F:1d array
|
|
658
|
+
The density over the vertices, that induces a lowerstar filtration.
|
|
659
|
+
parameter:int
|
|
660
|
+
Which filtration parameter to fill. /!\ python starts at 0.
|
|
661
|
+
|
|
662
|
+
Returns
|
|
663
|
+
-------
|
|
664
|
+
self:SimplexTreeMulti
|
|
665
|
+
"""
|
|
666
|
+
# for s, sf in self.get_simplices():
|
|
667
|
+
# self.assign_filtration(s, [f if i != dimension else np.max(np.array(F)[s]) for i,f in enumerate(sf)])
|
|
668
|
+
...
|
|
669
|
+
|
|
670
|
+
def project_on_line(self, parameter:int=0, basepoint:None|list|np.ndarray= None)->SimplexTree:
|
|
671
|
+
"""Converts an multi simplextree to a gudhi simplextree.
|
|
672
|
+
Parameters
|
|
673
|
+
----------
|
|
674
|
+
parameter:int = 0
|
|
675
|
+
The parameter to keep. WARNING will crash if the multi simplextree is not well filled.
|
|
676
|
+
basepoint:None
|
|
677
|
+
Instead of keeping a single parameter, will consider the filtration defined by the diagonal line crossing the basepoint.
|
|
678
|
+
WARNING
|
|
679
|
+
-------
|
|
680
|
+
There are no safeguard yet, it WILL crash if asking for a parameter that is not filled.
|
|
681
|
+
Returns
|
|
682
|
+
-------
|
|
683
|
+
A SimplexTree with chosen 1D filtration.
|
|
684
|
+
"""
|
|
685
|
+
...
|
|
686
|
+
|
|
687
|
+
def linear_projections(self, linear_forms:np.ndarray)->Iterable[SimplexTree]:
|
|
688
|
+
"""
|
|
689
|
+
Compute the 1-parameter projections, w.r.t. given the linear forms, of this simplextree.
|
|
690
|
+
|
|
691
|
+
Input
|
|
692
|
+
-----
|
|
693
|
+
- Array of shape (num_linear_forms, num_parameters)
|
|
694
|
+
|
|
695
|
+
Output
|
|
696
|
+
------
|
|
697
|
+
- List of projected (gudhi) simplextrees.
|
|
698
|
+
"""
|
|
699
|
+
...
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
def set_num_parameter(self, num:int):
|
|
703
|
+
"""
|
|
704
|
+
Sets the numbers of parameters.
|
|
705
|
+
WARNING : it will resize all the filtrations to this size.
|
|
706
|
+
"""
|
|
707
|
+
...
|
|
708
|
+
|
|
709
|
+
def __eq__(self, other:SimplexTreeMulti):
|
|
710
|
+
"""Test for structural equality
|
|
711
|
+
:returns: True if the 2 simplex trees are equal, False otherwise.
|
|
712
|
+
:rtype: bool
|
|
713
|
+
"""
|
|
714
|
+
...
|
|
715
|
+
|