multipers 2.0.0__cp312-cp312-macosx_13_0_arm64.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.

Files changed (78) hide show
  1. multipers/.dylibs/libc++.1.0.dylib +0 -0
  2. multipers/.dylibs/libtbb.12.12.dylib +0 -0
  3. multipers/.dylibs/libtbbmalloc.2.12.dylib +0 -0
  4. multipers/__init__.py +11 -0
  5. multipers/_signed_measure_meta.py +268 -0
  6. multipers/_slicer_meta.py +171 -0
  7. multipers/data/MOL2.py +350 -0
  8. multipers/data/UCR.py +18 -0
  9. multipers/data/__init__.py +1 -0
  10. multipers/data/graphs.py +466 -0
  11. multipers/data/immuno_regions.py +27 -0
  12. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  13. multipers/data/pytorch2simplextree.py +91 -0
  14. multipers/data/shape3d.py +101 -0
  15. multipers/data/synthetic.py +68 -0
  16. multipers/distances.py +198 -0
  17. multipers/euler_characteristic.pyx +132 -0
  18. multipers/filtration_conversions.pxd +229 -0
  19. multipers/filtrations.pxd +225 -0
  20. multipers/function_rips.cpython-312-darwin.so +0 -0
  21. multipers/function_rips.pyx +105 -0
  22. multipers/grids.cpython-312-darwin.so +0 -0
  23. multipers/grids.pyx +281 -0
  24. multipers/hilbert_function.pyi +46 -0
  25. multipers/hilbert_function.pyx +153 -0
  26. multipers/io.cpython-312-darwin.so +0 -0
  27. multipers/io.pyx +571 -0
  28. multipers/ml/__init__.py +0 -0
  29. multipers/ml/accuracies.py +90 -0
  30. multipers/ml/convolutions.py +532 -0
  31. multipers/ml/invariants_with_persistable.py +79 -0
  32. multipers/ml/kernels.py +176 -0
  33. multipers/ml/mma.py +659 -0
  34. multipers/ml/one.py +472 -0
  35. multipers/ml/point_clouds.py +238 -0
  36. multipers/ml/signed_betti.py +50 -0
  37. multipers/ml/signed_measures.py +1542 -0
  38. multipers/ml/sliced_wasserstein.py +461 -0
  39. multipers/ml/tools.py +113 -0
  40. multipers/mma_structures.cpython-312-darwin.so +0 -0
  41. multipers/mma_structures.pxd +127 -0
  42. multipers/mma_structures.pyx +2433 -0
  43. multipers/multiparameter_edge_collapse.py +41 -0
  44. multipers/multiparameter_module_approximation.cpython-312-darwin.so +0 -0
  45. multipers/multiparameter_module_approximation.pyx +211 -0
  46. multipers/pickle.py +53 -0
  47. multipers/plots.py +326 -0
  48. multipers/point_measure_integration.cpython-312-darwin.so +0 -0
  49. multipers/point_measure_integration.pyx +139 -0
  50. multipers/rank_invariant.cpython-312-darwin.so +0 -0
  51. multipers/rank_invariant.pyx +229 -0
  52. multipers/simplex_tree_multi.cpython-312-darwin.so +0 -0
  53. multipers/simplex_tree_multi.pxd +129 -0
  54. multipers/simplex_tree_multi.pyi +715 -0
  55. multipers/simplex_tree_multi.pyx +4655 -0
  56. multipers/slicer.cpython-312-darwin.so +0 -0
  57. multipers/slicer.pxd +781 -0
  58. multipers/slicer.pyx +3393 -0
  59. multipers/tensor.pxd +13 -0
  60. multipers/test.pyx +44 -0
  61. multipers/tests/__init__.py +40 -0
  62. multipers/tests/old_test_rank_invariant.py +91 -0
  63. multipers/tests/test_diff_helper.py +74 -0
  64. multipers/tests/test_hilbert_function.py +82 -0
  65. multipers/tests/test_mma.py +51 -0
  66. multipers/tests/test_point_clouds.py +59 -0
  67. multipers/tests/test_python-cpp_conversion.py +82 -0
  68. multipers/tests/test_signed_betti.py +181 -0
  69. multipers/tests/test_simplextreemulti.py +98 -0
  70. multipers/tests/test_slicer.py +63 -0
  71. multipers/torch/__init__.py +1 -0
  72. multipers/torch/diff_grids.py +217 -0
  73. multipers/torch/rips_density.py +257 -0
  74. multipers-2.0.0.dist-info/LICENSE +21 -0
  75. multipers-2.0.0.dist-info/METADATA +29 -0
  76. multipers-2.0.0.dist-info/RECORD +78 -0
  77. multipers-2.0.0.dist-info/WHEEL +5 -0
  78. multipers-2.0.0.dist-info/top_level.txt +1 -0
multipers/slicer.pyx ADDED
@@ -0,0 +1,3393 @@
1
+ # WARNING: Do not edit this file directly.
2
+ # It is automatically generated from 'multipers/slicer.pyx.tp'.
3
+ # Changes must be made there.
4
+
5
+
6
+ from multipers.simplex_tree_multi import SimplexTreeMulti
7
+ import multipers
8
+ from typing import Optional,Literal
9
+ import multipers.io as mio
10
+ import multipers.grids as mpg
11
+ import threading
12
+ import os
13
+
14
+ from multipers.slicer cimport *
15
+ from multipers.filtrations cimport *
16
+ from multipers.filtration_conversions cimport *
17
+ import numpy as np
18
+ cimport cython
19
+ # python_value_type = np.float32
20
+ from typing import Union
21
+
22
+ global available_slicers
23
+ available_slicers = tuple((
24
+ _SlicerClement,
25
+ _SlicerVineGraph,
26
+ _SlicerVineSimplicial,
27
+ _SlicerNoVineSimplicial,
28
+ _KSlicer0_vine_i32,
29
+ _KSlicer0_vine_f32,
30
+ _KSlicer0_vine_f64,
31
+ _Slicer0_vine_i32,
32
+ _Slicer0_vine_f32,
33
+ _Slicer0_vine_f64,
34
+ _KSlicer0_i32,
35
+ _KSlicer0_f32,
36
+ _KSlicer0_f64,
37
+ _Slicer0_i32,
38
+ _Slicer0_f32,
39
+ _Slicer0_f64,
40
+ ))
41
+ global _slicers_type
42
+ Slicer_type = Union[
43
+ _SlicerClement,
44
+ _SlicerVineGraph,
45
+ _SlicerVineSimplicial,
46
+ _SlicerNoVineSimplicial,
47
+ _KSlicer0_vine_i32,
48
+ _KSlicer0_vine_f32,
49
+ _KSlicer0_vine_f64,
50
+ _Slicer0_vine_i32,
51
+ _Slicer0_vine_f32,
52
+ _Slicer0_vine_f64,
53
+ _KSlicer0_i32,
54
+ _KSlicer0_f32,
55
+ _KSlicer0_f64,
56
+ _Slicer0_i32,
57
+ _Slicer0_f32,
58
+ _Slicer0_f64,
59
+
60
+ ]
61
+
62
+
63
+ #------------------------------------------------------------------------------
64
+ cdef class _SlicerClement:
65
+ cdef GeneralVineClementTruc truc
66
+ cdef public vector[vector[double]] filtration_grid
67
+ @property
68
+ def is_squeezed(self)->bool:
69
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
70
+
71
+ def get_ptr(self):
72
+ """
73
+ Returns a pointer to the underlying C++ slicer.
74
+ """
75
+ return <intptr_t>(&self.truc)
76
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
77
+ """
78
+ Constructs a slicer from
79
+ - generator maps (Iterable of list of ints)
80
+ - generator dimensions (Iterable of int)
81
+ - filtration values (Iterable of filtration values)
82
+ """
83
+ pass
84
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
85
+ """
86
+ Cython constructor
87
+ """
88
+ cdef uint32_t num_generators = len(generator_maps)
89
+ cdef vector[vector[uint32_t]] c_generator_maps
90
+ cdef vector[Finitely_critical_multi_filtration[float]] c_filtration_values
91
+ for stuff in generator_maps:
92
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
93
+ for f in filtration_values:
94
+ # cf.clear()
95
+ # for truc in f:
96
+ # cf.push_back(truc)
97
+ c_filtration_values.push_back(_py21c_f32(f))
98
+ cdef vector[int] c_generator_dimensions = generator_dimensions
99
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
100
+ self.truc = GeneralVineClementTruc(c_generator_maps,c_generator_dimensions, c_filtration_values)
101
+ def copy(self):
102
+ """
103
+ Returns a copy of the slicer.
104
+ """
105
+ copy_ = _SlicerClement()
106
+ copy_.truc = self.truc
107
+ return copy_
108
+ def get_barcode(self):
109
+ """
110
+ Returns the current barcode.
111
+ """
112
+ return self.truc.get_barcode()
113
+ def push_to_line(self, basepoint, direction=None):
114
+ """
115
+ Pushes the current slicer to the line
116
+ """
117
+ cdef Line[float] line
118
+ if direction is None:
119
+ line = Line[float](_py21c_f32(basepoint))
120
+ else:
121
+ line = Line[float](_py21c_f32(basepoint),_py21c_f32(direction))
122
+ self.truc.push_to(line)
123
+ return self
124
+
125
+ def persistence_on_line(self,basepoint,direction=None):
126
+ """
127
+ Computes the persistence on a line L defined by
128
+ - a basepoint (num_parameters,) array
129
+ - an optional direction (num_parameters,) array
130
+ """
131
+ self.push_to_line(basepoint,direction)
132
+ self.truc.compute_persistence()
133
+ return self.truc.get_barcode()
134
+ def compute_persistence(self,one_filtration=None):
135
+ """
136
+ Computes the current persistence, or the persistence
137
+ given by the filtration one_filtration (num_generators,).
138
+ """
139
+ if one_filtration is not None:
140
+ self.truc.set_one_filtration(one_filtration)
141
+ self.truc.compute_persistence()
142
+ # return self.truc.get_barcode()
143
+ def get_barcode(self):
144
+ """
145
+ Returns the barcode of the current 1d-persistence.
146
+ """
147
+ return self.truc.get_barcode()
148
+ def sliced_filtration(self,basepoint, direction=None):
149
+ """
150
+ Computes the filtration on a line L defined by
151
+ - a basepoint (num_parameters,) array
152
+ - an optional direction (num_parameters,) array
153
+ """
154
+ self.push_to_line(basepoint,direction)
155
+ return np.asarray(self.truc.get_one_filtration())
156
+ def __len__(self):
157
+ return self.truc.num_generators()
158
+ @property
159
+ def num_generators(self):
160
+ return self.truc.num_generators()
161
+ @property
162
+ def num_parameters(self):
163
+ return self.truc.num_parameters()
164
+ def info(self):
165
+ return self.truc.to_str().decode()
166
+ def compute_box(self):
167
+ """
168
+ Computes the bounding box of the current persistence.
169
+ """
170
+ cdef pair[Finitely_critical_multi_filtration[float],Finitely_critical_multi_filtration[float]] box = self.truc.get_bounding_box()
171
+ cdef cnp.ndarray[float, ndim=1] a = _ff21cview_f32(&box.first)
172
+ cdef cnp.ndarray[float, ndim=1] b = _ff21cview_f32(&box.second)
173
+ return np.asarray([a,b])
174
+ def get_filtrations_values(self):
175
+ """
176
+ Returns the current filtration values of the slicer.
177
+ """
178
+ cdef vector[Finitely_critical_multi_filtration[float]] v = self.truc.get_filtration_values()
179
+ out = _vff21cview_f32(v, copy=True)
180
+ return np.asarray(out)
181
+ def get_filtrations(self):
182
+ return _vff21cview_f32(self.truc.get_filtrations(), copy=True)
183
+
184
+ def get_dimensions(self):
185
+ """
186
+ Returns the ordered dimensions of the generators.
187
+ """
188
+ return np.asarray(self.truc.get_dimensions())
189
+ def get_boundaries(self):
190
+ """
191
+ Returns the boundaries of the generators.
192
+ """
193
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
194
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
195
+ """
196
+ Squeeze the filtration values on a grid.
197
+ """
198
+ if force and self.is_squeezed:
199
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
200
+ if filtration_grid is None:
201
+ filtration_grid = mpg.compute_grid(
202
+ self.get_filtrations_values().T,
203
+ strategy=grid_strategy,
204
+ resolution=resolution)
205
+ cdef vector[vector[float]] grid = filtration_grid
206
+ if inplace or not coordinates:
207
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
208
+ self.filtration_grid = filtration_grid
209
+ else:
210
+ raise ValueError("WIP")
211
+ return self
212
+ def minpres(self,
213
+ int degree = 1,
214
+ list[int] degrees=[],
215
+ str backend:Literal["mpfree", "2pac"]="mpfree",
216
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
217
+ bool vineyard=True,
218
+ id :Optional[str] = None,
219
+ dtype = np.float32,
220
+ **minpres_kwargs
221
+ ):
222
+ """
223
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
224
+ """
225
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
226
+ return new_slicer
227
+
228
+ @property
229
+ def dtype(self)->type:
230
+ return np.float32
231
+ @property
232
+ def col_type(self)->str:
233
+ return ""
234
+ @property
235
+ def is_vine(self)->bool:
236
+ return True
237
+ @property
238
+ def is_kcritical(self)->bool:
239
+ return False
240
+
241
+
242
+ def vine_update(self,basepoint,direction=None):
243
+ """
244
+ Updates the barcode, on a line, using the vineyard algorithm.
245
+ """
246
+ self.push_to_line(basepoint,direction)
247
+ self.truc.vineyard_update()
248
+ return self
249
+ def get_representative_cycles(self, bool update=True):
250
+ """
251
+ Returns the representative cycles of the current barcode.
252
+ Recomputes the generators if update=True
253
+ """
254
+ return self.truc.get_representative_cycles(update)
255
+ def get_permutation(self):
256
+ """
257
+ Returns the current generator permutation (w.r.t. vineyard).
258
+ """
259
+ return self.truc.get_current_order()
260
+
261
+ @staticmethod
262
+ def from_bitmap(self):
263
+ raise ValueError("Not implemented.")
264
+
265
+ #------------------------------------------------------------------------------
266
+ cdef class _SlicerVineGraph:
267
+ cdef SimplicialVineGraphTruc truc
268
+ cdef public vector[vector[double]] filtration_grid
269
+ @property
270
+ def is_squeezed(self)->bool:
271
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
272
+
273
+ def get_ptr(self):
274
+ """
275
+ Returns a pointer to the underlying C++ slicer.
276
+ """
277
+ return <intptr_t>(&self.truc)
278
+ def __init__(self, st=None):
279
+ """
280
+ Constructs a slicer from a simplex tree.
281
+ """
282
+ pass
283
+ def __cinit__(self, st=None):
284
+ if st is None:
285
+ return
286
+ cdef intptr_t ptr = st.thisptr
287
+ cdef Simplex_tree_multi_interface[Finitely_critical_multi_filtration[float],float]* st_ptr = <Simplex_tree_multi_interface[Finitely_critical_multi_filtration[float],float]*>(ptr)
288
+ self.truc = SimplicialVineGraphTruc(st_ptr)
289
+ def copy(self):
290
+ """
291
+ Returns a copy of the slicer.
292
+ """
293
+ copy_ = _SlicerVineGraph()
294
+ copy_.truc = self.truc
295
+ return copy_
296
+ def get_barcode(self):
297
+ """
298
+ Returns the current barcode.
299
+ """
300
+ return self.truc.get_barcode()
301
+ def push_to_line(self, basepoint, direction=None):
302
+ """
303
+ Pushes the current slicer to the line
304
+ """
305
+ cdef Line[float] line
306
+ if direction is None:
307
+ line = Line[float](_py21c_f32(basepoint))
308
+ else:
309
+ line = Line[float](_py21c_f32(basepoint),_py21c_f32(direction))
310
+ self.truc.push_to(line)
311
+ return self
312
+
313
+ def persistence_on_line(self,basepoint,direction=None):
314
+ """
315
+ Computes the persistence on a line L defined by
316
+ - a basepoint (num_parameters,) array
317
+ - an optional direction (num_parameters,) array
318
+ """
319
+ self.push_to_line(basepoint,direction)
320
+ self.truc.compute_persistence()
321
+ return self.truc.get_barcode()
322
+ def compute_persistence(self,one_filtration=None):
323
+ """
324
+ Computes the current persistence, or the persistence
325
+ given by the filtration one_filtration (num_generators,).
326
+ """
327
+ if one_filtration is not None:
328
+ self.truc.set_one_filtration(one_filtration)
329
+ self.truc.compute_persistence()
330
+ # return self.truc.get_barcode()
331
+ def get_barcode(self):
332
+ """
333
+ Returns the barcode of the current 1d-persistence.
334
+ """
335
+ return self.truc.get_barcode()
336
+ def sliced_filtration(self,basepoint, direction=None):
337
+ """
338
+ Computes the filtration on a line L defined by
339
+ - a basepoint (num_parameters,) array
340
+ - an optional direction (num_parameters,) array
341
+ """
342
+ self.push_to_line(basepoint,direction)
343
+ return np.asarray(self.truc.get_one_filtration())
344
+ def __len__(self):
345
+ return self.truc.num_generators()
346
+ @property
347
+ def num_generators(self):
348
+ return self.truc.num_generators()
349
+ @property
350
+ def num_parameters(self):
351
+ return self.truc.num_parameters()
352
+ def info(self):
353
+ return self.truc.to_str().decode()
354
+ def compute_box(self):
355
+ """
356
+ Computes the bounding box of the current persistence.
357
+ """
358
+ cdef pair[Finitely_critical_multi_filtration[float],Finitely_critical_multi_filtration[float]] box = self.truc.get_bounding_box()
359
+ cdef cnp.ndarray[float, ndim=1] a = _ff21cview_f32(&box.first)
360
+ cdef cnp.ndarray[float, ndim=1] b = _ff21cview_f32(&box.second)
361
+ return np.asarray([a,b])
362
+ def get_filtrations_values(self):
363
+ """
364
+ Returns the current filtration values of the slicer.
365
+ """
366
+ cdef vector[Finitely_critical_multi_filtration[float]] v = self.truc.get_filtration_values()
367
+ out = _vff21cview_f32(v, copy=True)
368
+ return np.asarray(out)
369
+ def get_filtrations(self):
370
+ return _vff21cview_f32(self.truc.get_filtrations(), copy=True)
371
+
372
+ def get_dimensions(self):
373
+ """
374
+ Returns the ordered dimensions of the generators.
375
+ """
376
+ return np.asarray(self.truc.get_dimensions())
377
+ def get_boundaries(self):
378
+ """
379
+ Returns the boundaries of the generators.
380
+ """
381
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
382
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
383
+ """
384
+ Squeeze the filtration values on a grid.
385
+ """
386
+ if force and self.is_squeezed:
387
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
388
+ if filtration_grid is None:
389
+ filtration_grid = mpg.compute_grid(
390
+ self.get_filtrations_values().T,
391
+ strategy=grid_strategy,
392
+ resolution=resolution)
393
+ cdef vector[vector[float]] grid = filtration_grid
394
+ if inplace or not coordinates:
395
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
396
+ self.filtration_grid = filtration_grid
397
+ else:
398
+ raise ValueError("WIP")
399
+ return self
400
+ def minpres(self,
401
+ int degree = 1,
402
+ list[int] degrees=[],
403
+ str backend:Literal["mpfree", "2pac"]="mpfree",
404
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
405
+ bool vineyard=True,
406
+ id :Optional[str] = None,
407
+ dtype = np.float32,
408
+ **minpres_kwargs
409
+ ):
410
+ """
411
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
412
+ """
413
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
414
+ return new_slicer
415
+
416
+ @property
417
+ def dtype(self)->type:
418
+ return np.float32
419
+ @property
420
+ def col_type(self)->str:
421
+ return ""
422
+ @property
423
+ def is_vine(self)->bool:
424
+ return True
425
+ @property
426
+ def is_kcritical(self)->bool:
427
+ return False
428
+
429
+
430
+ def vine_update(self,basepoint,direction=None):
431
+ """
432
+ Updates the barcode, on a line, using the vineyard algorithm.
433
+ """
434
+ self.push_to_line(basepoint,direction)
435
+ self.truc.vineyard_update()
436
+ return self
437
+ def get_representative_cycles(self, bool update=True):
438
+ """
439
+ Returns the representative cycles of the current barcode.
440
+ Recomputes the generators if update=True
441
+ """
442
+ return self.truc.get_representative_cycles(update)
443
+ def get_permutation(self):
444
+ """
445
+ Returns the current generator permutation (w.r.t. vineyard).
446
+ """
447
+ return self.truc.get_current_order()
448
+
449
+ @staticmethod
450
+ def from_bitmap(self):
451
+ raise ValueError("Not implemented.")
452
+
453
+ #------------------------------------------------------------------------------
454
+ cdef class _SlicerVineSimplicial:
455
+ cdef SimplicialVineMatrixTruc truc
456
+ cdef public vector[vector[double]] filtration_grid
457
+ @property
458
+ def is_squeezed(self)->bool:
459
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
460
+
461
+ def get_ptr(self):
462
+ """
463
+ Returns a pointer to the underlying C++ slicer.
464
+ """
465
+ return <intptr_t>(&self.truc)
466
+ def __init__(self, st=None):
467
+ """
468
+ Constructs a slicer from a simplex tree.
469
+ """
470
+ pass
471
+ def __cinit__(self, st=None):
472
+ if st is None:
473
+ return
474
+ cdef intptr_t ptr = st.thisptr
475
+ cdef Simplex_tree_multi_interface[Finitely_critical_multi_filtration[float],float]* st_ptr = <Simplex_tree_multi_interface[Finitely_critical_multi_filtration[float],float]*>(ptr)
476
+ self.truc = SimplicialVineMatrixTruc(st_ptr)
477
+ def copy(self):
478
+ """
479
+ Returns a copy of the slicer.
480
+ """
481
+ copy_ = _SlicerVineSimplicial()
482
+ copy_.truc = self.truc
483
+ return copy_
484
+ def get_barcode(self):
485
+ """
486
+ Returns the current barcode.
487
+ """
488
+ return self.truc.get_barcode()
489
+ def push_to_line(self, basepoint, direction=None):
490
+ """
491
+ Pushes the current slicer to the line
492
+ """
493
+ cdef Line[float] line
494
+ if direction is None:
495
+ line = Line[float](_py21c_f32(basepoint))
496
+ else:
497
+ line = Line[float](_py21c_f32(basepoint),_py21c_f32(direction))
498
+ self.truc.push_to(line)
499
+ return self
500
+
501
+ def persistence_on_line(self,basepoint,direction=None):
502
+ """
503
+ Computes the persistence on a line L defined by
504
+ - a basepoint (num_parameters,) array
505
+ - an optional direction (num_parameters,) array
506
+ """
507
+ self.push_to_line(basepoint,direction)
508
+ self.truc.compute_persistence()
509
+ return self.truc.get_barcode()
510
+ def compute_persistence(self,one_filtration=None):
511
+ """
512
+ Computes the current persistence, or the persistence
513
+ given by the filtration one_filtration (num_generators,).
514
+ """
515
+ if one_filtration is not None:
516
+ self.truc.set_one_filtration(one_filtration)
517
+ self.truc.compute_persistence()
518
+ # return self.truc.get_barcode()
519
+ def get_barcode(self):
520
+ """
521
+ Returns the barcode of the current 1d-persistence.
522
+ """
523
+ return self.truc.get_barcode()
524
+ def sliced_filtration(self,basepoint, direction=None):
525
+ """
526
+ Computes the filtration on a line L defined by
527
+ - a basepoint (num_parameters,) array
528
+ - an optional direction (num_parameters,) array
529
+ """
530
+ self.push_to_line(basepoint,direction)
531
+ return np.asarray(self.truc.get_one_filtration())
532
+ def __len__(self):
533
+ return self.truc.num_generators()
534
+ @property
535
+ def num_generators(self):
536
+ return self.truc.num_generators()
537
+ @property
538
+ def num_parameters(self):
539
+ return self.truc.num_parameters()
540
+ def info(self):
541
+ return self.truc.to_str().decode()
542
+ def compute_box(self):
543
+ """
544
+ Computes the bounding box of the current persistence.
545
+ """
546
+ cdef pair[Finitely_critical_multi_filtration[float],Finitely_critical_multi_filtration[float]] box = self.truc.get_bounding_box()
547
+ cdef cnp.ndarray[float, ndim=1] a = _ff21cview_f32(&box.first)
548
+ cdef cnp.ndarray[float, ndim=1] b = _ff21cview_f32(&box.second)
549
+ return np.asarray([a,b])
550
+ def get_filtrations_values(self):
551
+ """
552
+ Returns the current filtration values of the slicer.
553
+ """
554
+ cdef vector[Finitely_critical_multi_filtration[float]] v = self.truc.get_filtration_values()
555
+ out = _vff21cview_f32(v, copy=True)
556
+ return np.asarray(out)
557
+ def get_filtrations(self):
558
+ return _vff21cview_f32(self.truc.get_filtrations(), copy=True)
559
+
560
+ def get_dimensions(self):
561
+ """
562
+ Returns the ordered dimensions of the generators.
563
+ """
564
+ return np.asarray(self.truc.get_dimensions())
565
+ def get_boundaries(self):
566
+ """
567
+ Returns the boundaries of the generators.
568
+ """
569
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
570
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
571
+ """
572
+ Squeeze the filtration values on a grid.
573
+ """
574
+ if force and self.is_squeezed:
575
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
576
+ if filtration_grid is None:
577
+ filtration_grid = mpg.compute_grid(
578
+ self.get_filtrations_values().T,
579
+ strategy=grid_strategy,
580
+ resolution=resolution)
581
+ cdef vector[vector[float]] grid = filtration_grid
582
+ if inplace or not coordinates:
583
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
584
+ self.filtration_grid = filtration_grid
585
+ else:
586
+ raise ValueError("WIP")
587
+ return self
588
+ def minpres(self,
589
+ int degree = 1,
590
+ list[int] degrees=[],
591
+ str backend:Literal["mpfree", "2pac"]="mpfree",
592
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
593
+ bool vineyard=True,
594
+ id :Optional[str] = None,
595
+ dtype = np.float32,
596
+ **minpres_kwargs
597
+ ):
598
+ """
599
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
600
+ """
601
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
602
+ return new_slicer
603
+
604
+ @property
605
+ def dtype(self)->type:
606
+ return np.float32
607
+ @property
608
+ def col_type(self)->str:
609
+ return ""
610
+ @property
611
+ def is_vine(self)->bool:
612
+ return True
613
+ @property
614
+ def is_kcritical(self)->bool:
615
+ return False
616
+
617
+
618
+ def vine_update(self,basepoint,direction=None):
619
+ """
620
+ Updates the barcode, on a line, using the vineyard algorithm.
621
+ """
622
+ self.push_to_line(basepoint,direction)
623
+ self.truc.vineyard_update()
624
+ return self
625
+ def get_representative_cycles(self, bool update=True):
626
+ """
627
+ Returns the representative cycles of the current barcode.
628
+ Recomputes the generators if update=True
629
+ """
630
+ return self.truc.get_representative_cycles(update)
631
+ def get_permutation(self):
632
+ """
633
+ Returns the current generator permutation (w.r.t. vineyard).
634
+ """
635
+ return self.truc.get_current_order()
636
+
637
+ @staticmethod
638
+ def from_bitmap(self):
639
+ raise ValueError("Not implemented.")
640
+
641
+ #------------------------------------------------------------------------------
642
+ cdef class _SlicerNoVineSimplicial:
643
+ cdef SimplicialNoVineMatrixTruc truc
644
+ cdef public vector[vector[double]] filtration_grid
645
+ @property
646
+ def is_squeezed(self)->bool:
647
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
648
+
649
+ def get_ptr(self):
650
+ """
651
+ Returns a pointer to the underlying C++ slicer.
652
+ """
653
+ return <intptr_t>(&self.truc)
654
+ def __init__(self, st=None):
655
+ """
656
+ Constructs a slicer from a simplex tree.
657
+ """
658
+ pass
659
+ def __cinit__(self, st=None):
660
+ if st is None:
661
+ return
662
+ cdef intptr_t ptr = st.thisptr
663
+ cdef Simplex_tree_multi_interface[Finitely_critical_multi_filtration[float],float]* st_ptr = <Simplex_tree_multi_interface[Finitely_critical_multi_filtration[float],float]*>(ptr)
664
+ self.truc = SimplicialNoVineMatrixTruc(st_ptr)
665
+ def copy(self):
666
+ """
667
+ Returns a copy of the slicer.
668
+ """
669
+ copy_ = _SlicerNoVineSimplicial()
670
+ copy_.truc = self.truc
671
+ return copy_
672
+ def get_barcode(self):
673
+ """
674
+ Returns the current barcode.
675
+ """
676
+ return self.truc.get_barcode()
677
+ def push_to_line(self, basepoint, direction=None):
678
+ """
679
+ Pushes the current slicer to the line
680
+ """
681
+ cdef Line[float] line
682
+ if direction is None:
683
+ line = Line[float](_py21c_f32(basepoint))
684
+ else:
685
+ line = Line[float](_py21c_f32(basepoint),_py21c_f32(direction))
686
+ self.truc.push_to(line)
687
+ return self
688
+
689
+ def persistence_on_line(self,basepoint,direction=None):
690
+ """
691
+ Computes the persistence on a line L defined by
692
+ - a basepoint (num_parameters,) array
693
+ - an optional direction (num_parameters,) array
694
+ """
695
+ self.push_to_line(basepoint,direction)
696
+ self.truc.compute_persistence()
697
+ return self.truc.get_barcode()
698
+ def compute_persistence(self,one_filtration=None):
699
+ """
700
+ Computes the current persistence, or the persistence
701
+ given by the filtration one_filtration (num_generators,).
702
+ """
703
+ if one_filtration is not None:
704
+ self.truc.set_one_filtration(one_filtration)
705
+ self.truc.compute_persistence()
706
+ # return self.truc.get_barcode()
707
+ def get_barcode(self):
708
+ """
709
+ Returns the barcode of the current 1d-persistence.
710
+ """
711
+ return self.truc.get_barcode()
712
+ def sliced_filtration(self,basepoint, direction=None):
713
+ """
714
+ Computes the filtration on a line L defined by
715
+ - a basepoint (num_parameters,) array
716
+ - an optional direction (num_parameters,) array
717
+ """
718
+ self.push_to_line(basepoint,direction)
719
+ return np.asarray(self.truc.get_one_filtration())
720
+ def __len__(self):
721
+ return self.truc.num_generators()
722
+ @property
723
+ def num_generators(self):
724
+ return self.truc.num_generators()
725
+ @property
726
+ def num_parameters(self):
727
+ return self.truc.num_parameters()
728
+ def info(self):
729
+ return self.truc.to_str().decode()
730
+ def compute_box(self):
731
+ """
732
+ Computes the bounding box of the current persistence.
733
+ """
734
+ cdef pair[Finitely_critical_multi_filtration[float],Finitely_critical_multi_filtration[float]] box = self.truc.get_bounding_box()
735
+ cdef cnp.ndarray[float, ndim=1] a = _ff21cview_f32(&box.first)
736
+ cdef cnp.ndarray[float, ndim=1] b = _ff21cview_f32(&box.second)
737
+ return np.asarray([a,b])
738
+ def get_filtrations_values(self):
739
+ """
740
+ Returns the current filtration values of the slicer.
741
+ """
742
+ cdef vector[Finitely_critical_multi_filtration[float]] v = self.truc.get_filtration_values()
743
+ out = _vff21cview_f32(v, copy=True)
744
+ return np.asarray(out)
745
+ def get_filtrations(self):
746
+ return _vff21cview_f32(self.truc.get_filtrations(), copy=True)
747
+
748
+ def get_dimensions(self):
749
+ """
750
+ Returns the ordered dimensions of the generators.
751
+ """
752
+ return np.asarray(self.truc.get_dimensions())
753
+ def get_boundaries(self):
754
+ """
755
+ Returns the boundaries of the generators.
756
+ """
757
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
758
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
759
+ """
760
+ Squeeze the filtration values on a grid.
761
+ """
762
+ if force and self.is_squeezed:
763
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
764
+ if filtration_grid is None:
765
+ filtration_grid = mpg.compute_grid(
766
+ self.get_filtrations_values().T,
767
+ strategy=grid_strategy,
768
+ resolution=resolution)
769
+ cdef vector[vector[float]] grid = filtration_grid
770
+ if inplace or not coordinates:
771
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
772
+ self.filtration_grid = filtration_grid
773
+ else:
774
+ raise ValueError("WIP")
775
+ return self
776
+ def minpres(self,
777
+ int degree = 1,
778
+ list[int] degrees=[],
779
+ str backend:Literal["mpfree", "2pac"]="mpfree",
780
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
781
+ bool vineyard=False,
782
+ id :Optional[str] = None,
783
+ dtype = np.float32,
784
+ **minpres_kwargs
785
+ ):
786
+ """
787
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
788
+ """
789
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
790
+ return new_slicer
791
+
792
+ @property
793
+ def dtype(self)->type:
794
+ return np.float32
795
+ @property
796
+ def col_type(self)->str:
797
+ return ""
798
+ @property
799
+ def is_vine(self)->bool:
800
+ return False
801
+ @property
802
+ def is_kcritical(self)->bool:
803
+ return False
804
+
805
+
806
+
807
+ @staticmethod
808
+ def from_bitmap(self):
809
+ raise ValueError("Not implemented.")
810
+
811
+ #------------------------------------------------------------------------------
812
+ cdef class _KSlicer0_vine_i32:
813
+ cdef C_KSlicer0_vine_i32 truc
814
+ cdef public vector[vector[double]] filtration_grid
815
+ @property
816
+ def is_squeezed(self)->bool:
817
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
818
+
819
+ def get_ptr(self):
820
+ """
821
+ Returns a pointer to the underlying C++ slicer.
822
+ """
823
+ return <intptr_t>(&self.truc)
824
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
825
+ """
826
+ Constructs a slicer from
827
+ - scc-like blocks
828
+ or
829
+ - generator maps (Iterable of list of ints)
830
+ - generator dimensions (Iterable of int)
831
+ - filtration values (Iterable of filtration values)
832
+ """
833
+ pass
834
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
835
+ """
836
+ Cython constructor
837
+ """
838
+ if len(generator_maps)>0 and len(generator_dimensions) == 0 and len(filtration_values) == 0:
839
+ from multipers._slicer_meta import _blocks2boundary_dimension_grades
840
+ generator_maps, generator_dimensions, filtration_values = _blocks2boundary_dimension_grades(
841
+ generator_maps,
842
+ inplace=False,
843
+ )
844
+ cdef uint32_t num_generators = len(generator_maps)
845
+ cdef vector[vector[uint32_t]] c_generator_maps
846
+ cdef vector[KCriticalFiltration[int32_t]] c_filtration_values
847
+ for stuff in generator_maps:
848
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
849
+ cdef KCriticalFiltration[int32_t] cf
850
+ for F in filtration_values:
851
+ cf.clear()
852
+ for f in F:
853
+ cf.add_point(_py21c_i32(f))
854
+ c_filtration_values.push_back(cf)
855
+ cdef vector[int] c_generator_dimensions = generator_dimensions
856
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
857
+ self.truc = C_KSlicer0_vine_i32(c_generator_maps,c_generator_dimensions, c_filtration_values)
858
+ def copy(self):
859
+ """
860
+ Returns a copy of the slicer.
861
+ """
862
+ copy_ = _KSlicer0_vine_i32()
863
+ copy_.truc = self.truc
864
+ return copy_
865
+ def get_barcode(self):
866
+ """
867
+ Returns the current barcode.
868
+ """
869
+ return self.truc.get_barcode()
870
+ def push_to_line(self, basepoint, direction=None):
871
+ """
872
+ Pushes the current slicer to the line
873
+ """
874
+ cdef Line[int32_t] line
875
+ if direction is None:
876
+ line = Line[int32_t](_py21c_i32(basepoint))
877
+ else:
878
+ line = Line[int32_t](_py21c_i32(basepoint),_py21c_i32(direction))
879
+ self.truc.push_to(line)
880
+ return self
881
+
882
+ def persistence_on_line(self,basepoint,direction=None):
883
+ """
884
+ Computes the persistence on a line L defined by
885
+ - a basepoint (num_parameters,) array
886
+ - an optional direction (num_parameters,) array
887
+ """
888
+ self.push_to_line(basepoint,direction)
889
+ self.truc.compute_persistence()
890
+ return self.truc.get_barcode()
891
+ def compute_persistence(self,one_filtration=None):
892
+ """
893
+ Computes the current persistence, or the persistence
894
+ given by the filtration one_filtration (num_generators,).
895
+ """
896
+ if one_filtration is not None:
897
+ self.truc.set_one_filtration(one_filtration)
898
+ self.truc.compute_persistence()
899
+ # return self.truc.get_barcode()
900
+ def get_barcode(self):
901
+ """
902
+ Returns the barcode of the current 1d-persistence.
903
+ """
904
+ return self.truc.get_barcode()
905
+ def sliced_filtration(self,basepoint, direction=None):
906
+ """
907
+ Computes the filtration on a line L defined by
908
+ - a basepoint (num_parameters,) array
909
+ - an optional direction (num_parameters,) array
910
+ """
911
+ self.push_to_line(basepoint,direction)
912
+ return np.asarray(self.truc.get_one_filtration())
913
+ def __len__(self):
914
+ return self.truc.num_generators()
915
+ @property
916
+ def num_generators(self):
917
+ return self.truc.num_generators()
918
+ @property
919
+ def num_parameters(self):
920
+ return self.truc.num_parameters()
921
+ def info(self):
922
+ return self.truc.to_str().decode()
923
+ def compute_box(self):
924
+ """
925
+ Computes the bounding box of the current persistence.
926
+ """
927
+ cdef pair[Finitely_critical_multi_filtration[int32_t],Finitely_critical_multi_filtration[int32_t]] box = self.truc.get_bounding_box()
928
+ cdef cnp.ndarray[int32_t, ndim=1] a = _ff21cview_i32(&box.first)
929
+ cdef cnp.ndarray[int32_t, ndim=1] b = _ff21cview_i32(&box.second)
930
+ return np.asarray([a,b])
931
+ def get_filtrations_values(self):
932
+ """
933
+ Returns the current filtration values of the slicer.
934
+ """
935
+ cdef vector[Finitely_critical_multi_filtration[int32_t]] v = self.truc.get_filtration_values()
936
+ out = _vff21cview_i32(v, copy=True)
937
+ return np.asarray(out)
938
+ def get_filtrations(self):
939
+ return _vff2kcview_i32(self.truc.get_filtrations(), copy=True)
940
+
941
+ def get_dimensions(self):
942
+ """
943
+ Returns the ordered dimensions of the generators.
944
+ """
945
+ return np.asarray(self.truc.get_dimensions())
946
+ def get_boundaries(self):
947
+ """
948
+ Returns the boundaries of the generators.
949
+ """
950
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
951
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
952
+ """
953
+ Squeeze the filtration values on a grid.
954
+ """
955
+ if force and self.is_squeezed:
956
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
957
+ if filtration_grid is None:
958
+ filtration_grid = mpg.compute_grid(
959
+ self.get_filtrations_values().T,
960
+ strategy=grid_strategy,
961
+ resolution=resolution)
962
+ cdef vector[vector[int32_t]] grid = filtration_grid
963
+ if inplace or not coordinates:
964
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
965
+ self.filtration_grid = filtration_grid
966
+ else:
967
+ out = _KSlicer0_vine_i32()
968
+ out.truc = self.truc.coarsen_on_grid(grid)
969
+ out.filtration_grid = filtration_grid
970
+ return out
971
+ return self
972
+ def minpres(self,
973
+ int degree = 1,
974
+ list[int] degrees=[],
975
+ str backend:Literal["mpfree", "2pac"]="mpfree",
976
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
977
+ bool vineyard=True,
978
+ id :Optional[str] = None,
979
+ dtype = np.int32,
980
+ **minpres_kwargs
981
+ ):
982
+ """
983
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
984
+ """
985
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
986
+ return new_slicer
987
+
988
+ @property
989
+ def dtype(self)->type:
990
+ return np.int32
991
+ @property
992
+ def col_type(self)->str:
993
+ return "INTRUSIVE_SET"
994
+ @property
995
+ def is_vine(self)->bool:
996
+ return True
997
+ @property
998
+ def is_kcritical(self)->bool:
999
+ return True
1000
+
1001
+
1002
+ def vine_update(self,basepoint,direction=None):
1003
+ """
1004
+ Updates the barcode, on a line, using the vineyard algorithm.
1005
+ """
1006
+ self.push_to_line(basepoint,direction)
1007
+ self.truc.vineyard_update()
1008
+ return self
1009
+ def get_representative_cycles(self, bool update=True):
1010
+ """
1011
+ Returns the representative cycles of the current barcode.
1012
+ Recomputes the generators if update=True
1013
+ """
1014
+ return self.truc.get_representative_cycles(update)
1015
+ def get_permutation(self):
1016
+ """
1017
+ Returns the current generator permutation (w.r.t. vineyard).
1018
+ """
1019
+ return self.truc.get_current_order()
1020
+
1021
+ @staticmethod
1022
+ def from_bitmap(self):
1023
+ raise ValueError("Not implemented.")
1024
+
1025
+ #------------------------------------------------------------------------------
1026
+ cdef class _KSlicer0_vine_f32:
1027
+ cdef C_KSlicer0_vine_f32 truc
1028
+ cdef public vector[vector[double]] filtration_grid
1029
+ @property
1030
+ def is_squeezed(self)->bool:
1031
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
1032
+
1033
+ def get_ptr(self):
1034
+ """
1035
+ Returns a pointer to the underlying C++ slicer.
1036
+ """
1037
+ return <intptr_t>(&self.truc)
1038
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1039
+ """
1040
+ Constructs a slicer from
1041
+ - scc-like blocks
1042
+ or
1043
+ - generator maps (Iterable of list of ints)
1044
+ - generator dimensions (Iterable of int)
1045
+ - filtration values (Iterable of filtration values)
1046
+ """
1047
+ pass
1048
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1049
+ """
1050
+ Cython constructor
1051
+ """
1052
+ if len(generator_maps)>0 and len(generator_dimensions) == 0 and len(filtration_values) == 0:
1053
+ from multipers._slicer_meta import _blocks2boundary_dimension_grades
1054
+ generator_maps, generator_dimensions, filtration_values = _blocks2boundary_dimension_grades(
1055
+ generator_maps,
1056
+ inplace=False,
1057
+ )
1058
+ cdef uint32_t num_generators = len(generator_maps)
1059
+ cdef vector[vector[uint32_t]] c_generator_maps
1060
+ cdef vector[KCriticalFiltration[float]] c_filtration_values
1061
+ for stuff in generator_maps:
1062
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
1063
+ cdef KCriticalFiltration[float] cf
1064
+ for F in filtration_values:
1065
+ cf.clear()
1066
+ for f in F:
1067
+ cf.add_point(_py21c_f32(f))
1068
+ c_filtration_values.push_back(cf)
1069
+ cdef vector[int] c_generator_dimensions = generator_dimensions
1070
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
1071
+ self.truc = C_KSlicer0_vine_f32(c_generator_maps,c_generator_dimensions, c_filtration_values)
1072
+ def copy(self):
1073
+ """
1074
+ Returns a copy of the slicer.
1075
+ """
1076
+ copy_ = _KSlicer0_vine_f32()
1077
+ copy_.truc = self.truc
1078
+ return copy_
1079
+ def get_barcode(self):
1080
+ """
1081
+ Returns the current barcode.
1082
+ """
1083
+ return self.truc.get_barcode()
1084
+ def push_to_line(self, basepoint, direction=None):
1085
+ """
1086
+ Pushes the current slicer to the line
1087
+ """
1088
+ cdef Line[float] line
1089
+ if direction is None:
1090
+ line = Line[float](_py21c_f32(basepoint))
1091
+ else:
1092
+ line = Line[float](_py21c_f32(basepoint),_py21c_f32(direction))
1093
+ self.truc.push_to(line)
1094
+ return self
1095
+
1096
+ def persistence_on_line(self,basepoint,direction=None):
1097
+ """
1098
+ Computes the persistence on a line L defined by
1099
+ - a basepoint (num_parameters,) array
1100
+ - an optional direction (num_parameters,) array
1101
+ """
1102
+ self.push_to_line(basepoint,direction)
1103
+ self.truc.compute_persistence()
1104
+ return self.truc.get_barcode()
1105
+ def compute_persistence(self,one_filtration=None):
1106
+ """
1107
+ Computes the current persistence, or the persistence
1108
+ given by the filtration one_filtration (num_generators,).
1109
+ """
1110
+ if one_filtration is not None:
1111
+ self.truc.set_one_filtration(one_filtration)
1112
+ self.truc.compute_persistence()
1113
+ # return self.truc.get_barcode()
1114
+ def get_barcode(self):
1115
+ """
1116
+ Returns the barcode of the current 1d-persistence.
1117
+ """
1118
+ return self.truc.get_barcode()
1119
+ def sliced_filtration(self,basepoint, direction=None):
1120
+ """
1121
+ Computes the filtration on a line L defined by
1122
+ - a basepoint (num_parameters,) array
1123
+ - an optional direction (num_parameters,) array
1124
+ """
1125
+ self.push_to_line(basepoint,direction)
1126
+ return np.asarray(self.truc.get_one_filtration())
1127
+ def __len__(self):
1128
+ return self.truc.num_generators()
1129
+ @property
1130
+ def num_generators(self):
1131
+ return self.truc.num_generators()
1132
+ @property
1133
+ def num_parameters(self):
1134
+ return self.truc.num_parameters()
1135
+ def info(self):
1136
+ return self.truc.to_str().decode()
1137
+ def compute_box(self):
1138
+ """
1139
+ Computes the bounding box of the current persistence.
1140
+ """
1141
+ cdef pair[Finitely_critical_multi_filtration[float],Finitely_critical_multi_filtration[float]] box = self.truc.get_bounding_box()
1142
+ cdef cnp.ndarray[float, ndim=1] a = _ff21cview_f32(&box.first)
1143
+ cdef cnp.ndarray[float, ndim=1] b = _ff21cview_f32(&box.second)
1144
+ return np.asarray([a,b])
1145
+ def get_filtrations_values(self):
1146
+ """
1147
+ Returns the current filtration values of the slicer.
1148
+ """
1149
+ cdef vector[Finitely_critical_multi_filtration[float]] v = self.truc.get_filtration_values()
1150
+ out = _vff21cview_f32(v, copy=True)
1151
+ return np.asarray(out)
1152
+ def get_filtrations(self):
1153
+ return _vff2kcview_f32(self.truc.get_filtrations(), copy=True)
1154
+
1155
+ def get_dimensions(self):
1156
+ """
1157
+ Returns the ordered dimensions of the generators.
1158
+ """
1159
+ return np.asarray(self.truc.get_dimensions())
1160
+ def get_boundaries(self):
1161
+ """
1162
+ Returns the boundaries of the generators.
1163
+ """
1164
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
1165
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
1166
+ """
1167
+ Squeeze the filtration values on a grid.
1168
+ """
1169
+ if force and self.is_squeezed:
1170
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
1171
+ if filtration_grid is None:
1172
+ filtration_grid = mpg.compute_grid(
1173
+ self.get_filtrations_values().T,
1174
+ strategy=grid_strategy,
1175
+ resolution=resolution)
1176
+ cdef vector[vector[float]] grid = filtration_grid
1177
+ if inplace or not coordinates:
1178
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
1179
+ self.filtration_grid = filtration_grid
1180
+ else:
1181
+ out = _KSlicer0_vine_i32()
1182
+ out.truc = self.truc.coarsen_on_grid(grid)
1183
+ out.filtration_grid = filtration_grid
1184
+ return out
1185
+ return self
1186
+ def minpres(self,
1187
+ int degree = 1,
1188
+ list[int] degrees=[],
1189
+ str backend:Literal["mpfree", "2pac"]="mpfree",
1190
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
1191
+ bool vineyard=True,
1192
+ id :Optional[str] = None,
1193
+ dtype = np.float32,
1194
+ **minpres_kwargs
1195
+ ):
1196
+ """
1197
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
1198
+ """
1199
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
1200
+ return new_slicer
1201
+
1202
+ @property
1203
+ def dtype(self)->type:
1204
+ return np.float32
1205
+ @property
1206
+ def col_type(self)->str:
1207
+ return "INTRUSIVE_SET"
1208
+ @property
1209
+ def is_vine(self)->bool:
1210
+ return True
1211
+ @property
1212
+ def is_kcritical(self)->bool:
1213
+ return True
1214
+
1215
+
1216
+ def vine_update(self,basepoint,direction=None):
1217
+ """
1218
+ Updates the barcode, on a line, using the vineyard algorithm.
1219
+ """
1220
+ self.push_to_line(basepoint,direction)
1221
+ self.truc.vineyard_update()
1222
+ return self
1223
+ def get_representative_cycles(self, bool update=True):
1224
+ """
1225
+ Returns the representative cycles of the current barcode.
1226
+ Recomputes the generators if update=True
1227
+ """
1228
+ return self.truc.get_representative_cycles(update)
1229
+ def get_permutation(self):
1230
+ """
1231
+ Returns the current generator permutation (w.r.t. vineyard).
1232
+ """
1233
+ return self.truc.get_current_order()
1234
+
1235
+ @staticmethod
1236
+ def from_bitmap(self):
1237
+ raise ValueError("Not implemented.")
1238
+
1239
+ #------------------------------------------------------------------------------
1240
+ cdef class _KSlicer0_vine_f64:
1241
+ cdef C_KSlicer0_vine_f64 truc
1242
+ cdef public vector[vector[double]] filtration_grid
1243
+ @property
1244
+ def is_squeezed(self)->bool:
1245
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
1246
+
1247
+ def get_ptr(self):
1248
+ """
1249
+ Returns a pointer to the underlying C++ slicer.
1250
+ """
1251
+ return <intptr_t>(&self.truc)
1252
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1253
+ """
1254
+ Constructs a slicer from
1255
+ - scc-like blocks
1256
+ or
1257
+ - generator maps (Iterable of list of ints)
1258
+ - generator dimensions (Iterable of int)
1259
+ - filtration values (Iterable of filtration values)
1260
+ """
1261
+ pass
1262
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1263
+ """
1264
+ Cython constructor
1265
+ """
1266
+ if len(generator_maps)>0 and len(generator_dimensions) == 0 and len(filtration_values) == 0:
1267
+ from multipers._slicer_meta import _blocks2boundary_dimension_grades
1268
+ generator_maps, generator_dimensions, filtration_values = _blocks2boundary_dimension_grades(
1269
+ generator_maps,
1270
+ inplace=False,
1271
+ )
1272
+ cdef uint32_t num_generators = len(generator_maps)
1273
+ cdef vector[vector[uint32_t]] c_generator_maps
1274
+ cdef vector[KCriticalFiltration[double]] c_filtration_values
1275
+ for stuff in generator_maps:
1276
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
1277
+ cdef KCriticalFiltration[double] cf
1278
+ for F in filtration_values:
1279
+ cf.clear()
1280
+ for f in F:
1281
+ cf.add_point(_py21c_f64(f))
1282
+ c_filtration_values.push_back(cf)
1283
+ cdef vector[int] c_generator_dimensions = generator_dimensions
1284
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
1285
+ self.truc = C_KSlicer0_vine_f64(c_generator_maps,c_generator_dimensions, c_filtration_values)
1286
+ def copy(self):
1287
+ """
1288
+ Returns a copy of the slicer.
1289
+ """
1290
+ copy_ = _KSlicer0_vine_f64()
1291
+ copy_.truc = self.truc
1292
+ return copy_
1293
+ def get_barcode(self):
1294
+ """
1295
+ Returns the current barcode.
1296
+ """
1297
+ return self.truc.get_barcode()
1298
+ def push_to_line(self, basepoint, direction=None):
1299
+ """
1300
+ Pushes the current slicer to the line
1301
+ """
1302
+ cdef Line[double] line
1303
+ if direction is None:
1304
+ line = Line[double](_py21c_f64(basepoint))
1305
+ else:
1306
+ line = Line[double](_py21c_f64(basepoint),_py21c_f64(direction))
1307
+ self.truc.push_to(line)
1308
+ return self
1309
+
1310
+ def persistence_on_line(self,basepoint,direction=None):
1311
+ """
1312
+ Computes the persistence on a line L defined by
1313
+ - a basepoint (num_parameters,) array
1314
+ - an optional direction (num_parameters,) array
1315
+ """
1316
+ self.push_to_line(basepoint,direction)
1317
+ self.truc.compute_persistence()
1318
+ return self.truc.get_barcode()
1319
+ def compute_persistence(self,one_filtration=None):
1320
+ """
1321
+ Computes the current persistence, or the persistence
1322
+ given by the filtration one_filtration (num_generators,).
1323
+ """
1324
+ if one_filtration is not None:
1325
+ self.truc.set_one_filtration(one_filtration)
1326
+ self.truc.compute_persistence()
1327
+ # return self.truc.get_barcode()
1328
+ def get_barcode(self):
1329
+ """
1330
+ Returns the barcode of the current 1d-persistence.
1331
+ """
1332
+ return self.truc.get_barcode()
1333
+ def sliced_filtration(self,basepoint, direction=None):
1334
+ """
1335
+ Computes the filtration on a line L defined by
1336
+ - a basepoint (num_parameters,) array
1337
+ - an optional direction (num_parameters,) array
1338
+ """
1339
+ self.push_to_line(basepoint,direction)
1340
+ return np.asarray(self.truc.get_one_filtration())
1341
+ def __len__(self):
1342
+ return self.truc.num_generators()
1343
+ @property
1344
+ def num_generators(self):
1345
+ return self.truc.num_generators()
1346
+ @property
1347
+ def num_parameters(self):
1348
+ return self.truc.num_parameters()
1349
+ def info(self):
1350
+ return self.truc.to_str().decode()
1351
+ def compute_box(self):
1352
+ """
1353
+ Computes the bounding box of the current persistence.
1354
+ """
1355
+ cdef pair[Finitely_critical_multi_filtration[double],Finitely_critical_multi_filtration[double]] box = self.truc.get_bounding_box()
1356
+ cdef cnp.ndarray[double, ndim=1] a = _ff21cview_f64(&box.first)
1357
+ cdef cnp.ndarray[double, ndim=1] b = _ff21cview_f64(&box.second)
1358
+ return np.asarray([a,b])
1359
+ def get_filtrations_values(self):
1360
+ """
1361
+ Returns the current filtration values of the slicer.
1362
+ """
1363
+ cdef vector[Finitely_critical_multi_filtration[double]] v = self.truc.get_filtration_values()
1364
+ out = _vff21cview_f64(v, copy=True)
1365
+ return np.asarray(out)
1366
+ def get_filtrations(self):
1367
+ return _vff2kcview_f64(self.truc.get_filtrations(), copy=True)
1368
+
1369
+ def get_dimensions(self):
1370
+ """
1371
+ Returns the ordered dimensions of the generators.
1372
+ """
1373
+ return np.asarray(self.truc.get_dimensions())
1374
+ def get_boundaries(self):
1375
+ """
1376
+ Returns the boundaries of the generators.
1377
+ """
1378
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
1379
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
1380
+ """
1381
+ Squeeze the filtration values on a grid.
1382
+ """
1383
+ if force and self.is_squeezed:
1384
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
1385
+ if filtration_grid is None:
1386
+ filtration_grid = mpg.compute_grid(
1387
+ self.get_filtrations_values().T,
1388
+ strategy=grid_strategy,
1389
+ resolution=resolution)
1390
+ cdef vector[vector[double]] grid = filtration_grid
1391
+ if inplace or not coordinates:
1392
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
1393
+ self.filtration_grid = filtration_grid
1394
+ else:
1395
+ out = _KSlicer0_vine_i32()
1396
+ out.truc = self.truc.coarsen_on_grid(grid)
1397
+ out.filtration_grid = filtration_grid
1398
+ return out
1399
+ return self
1400
+ def minpres(self,
1401
+ int degree = 1,
1402
+ list[int] degrees=[],
1403
+ str backend:Literal["mpfree", "2pac"]="mpfree",
1404
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
1405
+ bool vineyard=True,
1406
+ id :Optional[str] = None,
1407
+ dtype = np.float64,
1408
+ **minpres_kwargs
1409
+ ):
1410
+ """
1411
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
1412
+ """
1413
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
1414
+ return new_slicer
1415
+
1416
+ @property
1417
+ def dtype(self)->type:
1418
+ return np.float64
1419
+ @property
1420
+ def col_type(self)->str:
1421
+ return "INTRUSIVE_SET"
1422
+ @property
1423
+ def is_vine(self)->bool:
1424
+ return True
1425
+ @property
1426
+ def is_kcritical(self)->bool:
1427
+ return True
1428
+
1429
+
1430
+ def vine_update(self,basepoint,direction=None):
1431
+ """
1432
+ Updates the barcode, on a line, using the vineyard algorithm.
1433
+ """
1434
+ self.push_to_line(basepoint,direction)
1435
+ self.truc.vineyard_update()
1436
+ return self
1437
+ def get_representative_cycles(self, bool update=True):
1438
+ """
1439
+ Returns the representative cycles of the current barcode.
1440
+ Recomputes the generators if update=True
1441
+ """
1442
+ return self.truc.get_representative_cycles(update)
1443
+ def get_permutation(self):
1444
+ """
1445
+ Returns the current generator permutation (w.r.t. vineyard).
1446
+ """
1447
+ return self.truc.get_current_order()
1448
+
1449
+ @staticmethod
1450
+ def from_bitmap(self):
1451
+ raise ValueError("Not implemented.")
1452
+
1453
+ #------------------------------------------------------------------------------
1454
+ cdef class _Slicer0_vine_i32:
1455
+ cdef C_Slicer0_vine_i32 truc
1456
+ cdef public vector[vector[double]] filtration_grid
1457
+ @property
1458
+ def is_squeezed(self)->bool:
1459
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
1460
+
1461
+ def get_ptr(self):
1462
+ """
1463
+ Returns a pointer to the underlying C++ slicer.
1464
+ """
1465
+ return <intptr_t>(&self.truc)
1466
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1467
+ """
1468
+ Constructs a slicer from
1469
+ - generator maps (Iterable of list of ints)
1470
+ - generator dimensions (Iterable of int)
1471
+ - filtration values (Iterable of filtration values)
1472
+ """
1473
+ pass
1474
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1475
+ """
1476
+ Cython constructor
1477
+ """
1478
+ cdef uint32_t num_generators = len(generator_maps)
1479
+ cdef vector[vector[uint32_t]] c_generator_maps
1480
+ cdef vector[Finitely_critical_multi_filtration[int32_t]] c_filtration_values
1481
+ for stuff in generator_maps:
1482
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
1483
+ for f in filtration_values:
1484
+ # cf.clear()
1485
+ # for truc in f:
1486
+ # cf.push_back(truc)
1487
+ c_filtration_values.push_back(_py21c_i32(f))
1488
+ cdef vector[int] c_generator_dimensions = generator_dimensions
1489
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
1490
+ self.truc = C_Slicer0_vine_i32(c_generator_maps,c_generator_dimensions, c_filtration_values)
1491
+ def copy(self):
1492
+ """
1493
+ Returns a copy of the slicer.
1494
+ """
1495
+ copy_ = _Slicer0_vine_i32()
1496
+ copy_.truc = self.truc
1497
+ return copy_
1498
+ def get_barcode(self):
1499
+ """
1500
+ Returns the current barcode.
1501
+ """
1502
+ return self.truc.get_barcode()
1503
+ def push_to_line(self, basepoint, direction=None):
1504
+ """
1505
+ Pushes the current slicer to the line
1506
+ """
1507
+ cdef Line[int32_t] line
1508
+ if direction is None:
1509
+ line = Line[int32_t](_py21c_i32(basepoint))
1510
+ else:
1511
+ line = Line[int32_t](_py21c_i32(basepoint),_py21c_i32(direction))
1512
+ self.truc.push_to(line)
1513
+ return self
1514
+
1515
+ def persistence_on_line(self,basepoint,direction=None):
1516
+ """
1517
+ Computes the persistence on a line L defined by
1518
+ - a basepoint (num_parameters,) array
1519
+ - an optional direction (num_parameters,) array
1520
+ """
1521
+ self.push_to_line(basepoint,direction)
1522
+ self.truc.compute_persistence()
1523
+ return self.truc.get_barcode()
1524
+ def compute_persistence(self,one_filtration=None):
1525
+ """
1526
+ Computes the current persistence, or the persistence
1527
+ given by the filtration one_filtration (num_generators,).
1528
+ """
1529
+ if one_filtration is not None:
1530
+ self.truc.set_one_filtration(one_filtration)
1531
+ self.truc.compute_persistence()
1532
+ # return self.truc.get_barcode()
1533
+ def get_barcode(self):
1534
+ """
1535
+ Returns the barcode of the current 1d-persistence.
1536
+ """
1537
+ return self.truc.get_barcode()
1538
+ def sliced_filtration(self,basepoint, direction=None):
1539
+ """
1540
+ Computes the filtration on a line L defined by
1541
+ - a basepoint (num_parameters,) array
1542
+ - an optional direction (num_parameters,) array
1543
+ """
1544
+ self.push_to_line(basepoint,direction)
1545
+ return np.asarray(self.truc.get_one_filtration())
1546
+ def __len__(self):
1547
+ return self.truc.num_generators()
1548
+ @property
1549
+ def num_generators(self):
1550
+ return self.truc.num_generators()
1551
+ @property
1552
+ def num_parameters(self):
1553
+ return self.truc.num_parameters()
1554
+ def info(self):
1555
+ return self.truc.to_str().decode()
1556
+ def compute_box(self):
1557
+ """
1558
+ Computes the bounding box of the current persistence.
1559
+ """
1560
+ cdef pair[Finitely_critical_multi_filtration[int32_t],Finitely_critical_multi_filtration[int32_t]] box = self.truc.get_bounding_box()
1561
+ cdef cnp.ndarray[int32_t, ndim=1] a = _ff21cview_i32(&box.first)
1562
+ cdef cnp.ndarray[int32_t, ndim=1] b = _ff21cview_i32(&box.second)
1563
+ return np.asarray([a,b])
1564
+ def get_filtrations_values(self):
1565
+ """
1566
+ Returns the current filtration values of the slicer.
1567
+ """
1568
+ cdef vector[Finitely_critical_multi_filtration[int32_t]] v = self.truc.get_filtration_values()
1569
+ out = _vff21cview_i32(v, copy=True)
1570
+ return np.asarray(out)
1571
+ def get_filtrations(self):
1572
+ return _vff21cview_i32(self.truc.get_filtrations(), copy=True)
1573
+
1574
+ def get_dimensions(self):
1575
+ """
1576
+ Returns the ordered dimensions of the generators.
1577
+ """
1578
+ return np.asarray(self.truc.get_dimensions())
1579
+ def get_boundaries(self):
1580
+ """
1581
+ Returns the boundaries of the generators.
1582
+ """
1583
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
1584
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
1585
+ """
1586
+ Squeeze the filtration values on a grid.
1587
+ """
1588
+ if force and self.is_squeezed:
1589
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
1590
+ if filtration_grid is None:
1591
+ filtration_grid = mpg.compute_grid(
1592
+ self.get_filtrations_values().T,
1593
+ strategy=grid_strategy,
1594
+ resolution=resolution)
1595
+ cdef vector[vector[int32_t]] grid = filtration_grid
1596
+ if inplace or not coordinates:
1597
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
1598
+ self.filtration_grid = filtration_grid
1599
+ else:
1600
+ out = _Slicer0_vine_i32()
1601
+ out.truc = self.truc.coarsen_on_grid(grid)
1602
+ out.filtration_grid = filtration_grid
1603
+ return out
1604
+ return self
1605
+ def minpres(self,
1606
+ int degree = 1,
1607
+ list[int] degrees=[],
1608
+ str backend:Literal["mpfree", "2pac"]="mpfree",
1609
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
1610
+ bool vineyard=True,
1611
+ id :Optional[str] = None,
1612
+ dtype = np.int32,
1613
+ **minpres_kwargs
1614
+ ):
1615
+ """
1616
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
1617
+ """
1618
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
1619
+ return new_slicer
1620
+
1621
+ @property
1622
+ def dtype(self)->type:
1623
+ return np.int32
1624
+ @property
1625
+ def col_type(self)->str:
1626
+ return "INTRUSIVE_SET"
1627
+ @property
1628
+ def is_vine(self)->bool:
1629
+ return True
1630
+ @property
1631
+ def is_kcritical(self)->bool:
1632
+ return False
1633
+
1634
+
1635
+ def vine_update(self,basepoint,direction=None):
1636
+ """
1637
+ Updates the barcode, on a line, using the vineyard algorithm.
1638
+ """
1639
+ self.push_to_line(basepoint,direction)
1640
+ self.truc.vineyard_update()
1641
+ return self
1642
+ def get_representative_cycles(self, bool update=True):
1643
+ """
1644
+ Returns the representative cycles of the current barcode.
1645
+ Recomputes the generators if update=True
1646
+ """
1647
+ return self.truc.get_representative_cycles(update)
1648
+ def get_permutation(self):
1649
+ """
1650
+ Returns the current generator permutation (w.r.t. vineyard).
1651
+ """
1652
+ return self.truc.get_current_order()
1653
+
1654
+ @staticmethod
1655
+ def from_bitmap(self):
1656
+ raise ValueError("Not implemented.")
1657
+
1658
+ #------------------------------------------------------------------------------
1659
+ cdef class _Slicer0_vine_f32:
1660
+ cdef C_Slicer0_vine_f32 truc
1661
+ cdef public vector[vector[double]] filtration_grid
1662
+ @property
1663
+ def is_squeezed(self)->bool:
1664
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
1665
+
1666
+ def get_ptr(self):
1667
+ """
1668
+ Returns a pointer to the underlying C++ slicer.
1669
+ """
1670
+ return <intptr_t>(&self.truc)
1671
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1672
+ """
1673
+ Constructs a slicer from
1674
+ - generator maps (Iterable of list of ints)
1675
+ - generator dimensions (Iterable of int)
1676
+ - filtration values (Iterable of filtration values)
1677
+ """
1678
+ pass
1679
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1680
+ """
1681
+ Cython constructor
1682
+ """
1683
+ cdef uint32_t num_generators = len(generator_maps)
1684
+ cdef vector[vector[uint32_t]] c_generator_maps
1685
+ cdef vector[Finitely_critical_multi_filtration[float]] c_filtration_values
1686
+ for stuff in generator_maps:
1687
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
1688
+ for f in filtration_values:
1689
+ # cf.clear()
1690
+ # for truc in f:
1691
+ # cf.push_back(truc)
1692
+ c_filtration_values.push_back(_py21c_f32(f))
1693
+ cdef vector[int] c_generator_dimensions = generator_dimensions
1694
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
1695
+ self.truc = C_Slicer0_vine_f32(c_generator_maps,c_generator_dimensions, c_filtration_values)
1696
+ def copy(self):
1697
+ """
1698
+ Returns a copy of the slicer.
1699
+ """
1700
+ copy_ = _Slicer0_vine_f32()
1701
+ copy_.truc = self.truc
1702
+ return copy_
1703
+ def get_barcode(self):
1704
+ """
1705
+ Returns the current barcode.
1706
+ """
1707
+ return self.truc.get_barcode()
1708
+ def push_to_line(self, basepoint, direction=None):
1709
+ """
1710
+ Pushes the current slicer to the line
1711
+ """
1712
+ cdef Line[float] line
1713
+ if direction is None:
1714
+ line = Line[float](_py21c_f32(basepoint))
1715
+ else:
1716
+ line = Line[float](_py21c_f32(basepoint),_py21c_f32(direction))
1717
+ self.truc.push_to(line)
1718
+ return self
1719
+
1720
+ def persistence_on_line(self,basepoint,direction=None):
1721
+ """
1722
+ Computes the persistence on a line L defined by
1723
+ - a basepoint (num_parameters,) array
1724
+ - an optional direction (num_parameters,) array
1725
+ """
1726
+ self.push_to_line(basepoint,direction)
1727
+ self.truc.compute_persistence()
1728
+ return self.truc.get_barcode()
1729
+ def compute_persistence(self,one_filtration=None):
1730
+ """
1731
+ Computes the current persistence, or the persistence
1732
+ given by the filtration one_filtration (num_generators,).
1733
+ """
1734
+ if one_filtration is not None:
1735
+ self.truc.set_one_filtration(one_filtration)
1736
+ self.truc.compute_persistence()
1737
+ # return self.truc.get_barcode()
1738
+ def get_barcode(self):
1739
+ """
1740
+ Returns the barcode of the current 1d-persistence.
1741
+ """
1742
+ return self.truc.get_barcode()
1743
+ def sliced_filtration(self,basepoint, direction=None):
1744
+ """
1745
+ Computes the filtration on a line L defined by
1746
+ - a basepoint (num_parameters,) array
1747
+ - an optional direction (num_parameters,) array
1748
+ """
1749
+ self.push_to_line(basepoint,direction)
1750
+ return np.asarray(self.truc.get_one_filtration())
1751
+ def __len__(self):
1752
+ return self.truc.num_generators()
1753
+ @property
1754
+ def num_generators(self):
1755
+ return self.truc.num_generators()
1756
+ @property
1757
+ def num_parameters(self):
1758
+ return self.truc.num_parameters()
1759
+ def info(self):
1760
+ return self.truc.to_str().decode()
1761
+ def compute_box(self):
1762
+ """
1763
+ Computes the bounding box of the current persistence.
1764
+ """
1765
+ cdef pair[Finitely_critical_multi_filtration[float],Finitely_critical_multi_filtration[float]] box = self.truc.get_bounding_box()
1766
+ cdef cnp.ndarray[float, ndim=1] a = _ff21cview_f32(&box.first)
1767
+ cdef cnp.ndarray[float, ndim=1] b = _ff21cview_f32(&box.second)
1768
+ return np.asarray([a,b])
1769
+ def get_filtrations_values(self):
1770
+ """
1771
+ Returns the current filtration values of the slicer.
1772
+ """
1773
+ cdef vector[Finitely_critical_multi_filtration[float]] v = self.truc.get_filtration_values()
1774
+ out = _vff21cview_f32(v, copy=True)
1775
+ return np.asarray(out)
1776
+ def get_filtrations(self):
1777
+ return _vff21cview_f32(self.truc.get_filtrations(), copy=True)
1778
+
1779
+ def get_dimensions(self):
1780
+ """
1781
+ Returns the ordered dimensions of the generators.
1782
+ """
1783
+ return np.asarray(self.truc.get_dimensions())
1784
+ def get_boundaries(self):
1785
+ """
1786
+ Returns the boundaries of the generators.
1787
+ """
1788
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
1789
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
1790
+ """
1791
+ Squeeze the filtration values on a grid.
1792
+ """
1793
+ if force and self.is_squeezed:
1794
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
1795
+ if filtration_grid is None:
1796
+ filtration_grid = mpg.compute_grid(
1797
+ self.get_filtrations_values().T,
1798
+ strategy=grid_strategy,
1799
+ resolution=resolution)
1800
+ cdef vector[vector[float]] grid = filtration_grid
1801
+ if inplace or not coordinates:
1802
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
1803
+ self.filtration_grid = filtration_grid
1804
+ else:
1805
+ out = _Slicer0_vine_i32()
1806
+ out.truc = self.truc.coarsen_on_grid(grid)
1807
+ out.filtration_grid = filtration_grid
1808
+ return out
1809
+ return self
1810
+ def minpres(self,
1811
+ int degree = 1,
1812
+ list[int] degrees=[],
1813
+ str backend:Literal["mpfree", "2pac"]="mpfree",
1814
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
1815
+ bool vineyard=True,
1816
+ id :Optional[str] = None,
1817
+ dtype = np.float32,
1818
+ **minpres_kwargs
1819
+ ):
1820
+ """
1821
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
1822
+ """
1823
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
1824
+ return new_slicer
1825
+
1826
+ @property
1827
+ def dtype(self)->type:
1828
+ return np.float32
1829
+ @property
1830
+ def col_type(self)->str:
1831
+ return "INTRUSIVE_SET"
1832
+ @property
1833
+ def is_vine(self)->bool:
1834
+ return True
1835
+ @property
1836
+ def is_kcritical(self)->bool:
1837
+ return False
1838
+
1839
+
1840
+ def vine_update(self,basepoint,direction=None):
1841
+ """
1842
+ Updates the barcode, on a line, using the vineyard algorithm.
1843
+ """
1844
+ self.push_to_line(basepoint,direction)
1845
+ self.truc.vineyard_update()
1846
+ return self
1847
+ def get_representative_cycles(self, bool update=True):
1848
+ """
1849
+ Returns the representative cycles of the current barcode.
1850
+ Recomputes the generators if update=True
1851
+ """
1852
+ return self.truc.get_representative_cycles(update)
1853
+ def get_permutation(self):
1854
+ """
1855
+ Returns the current generator permutation (w.r.t. vineyard).
1856
+ """
1857
+ return self.truc.get_current_order()
1858
+
1859
+ @staticmethod
1860
+ def from_bitmap(self):
1861
+ raise ValueError("Not implemented.")
1862
+
1863
+ #------------------------------------------------------------------------------
1864
+ cdef class _Slicer0_vine_f64:
1865
+ cdef C_Slicer0_vine_f64 truc
1866
+ cdef public vector[vector[double]] filtration_grid
1867
+ @property
1868
+ def is_squeezed(self)->bool:
1869
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
1870
+
1871
+ def get_ptr(self):
1872
+ """
1873
+ Returns a pointer to the underlying C++ slicer.
1874
+ """
1875
+ return <intptr_t>(&self.truc)
1876
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1877
+ """
1878
+ Constructs a slicer from
1879
+ - generator maps (Iterable of list of ints)
1880
+ - generator dimensions (Iterable of int)
1881
+ - filtration values (Iterable of filtration values)
1882
+ """
1883
+ pass
1884
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
1885
+ """
1886
+ Cython constructor
1887
+ """
1888
+ cdef uint32_t num_generators = len(generator_maps)
1889
+ cdef vector[vector[uint32_t]] c_generator_maps
1890
+ cdef vector[Finitely_critical_multi_filtration[double]] c_filtration_values
1891
+ for stuff in generator_maps:
1892
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
1893
+ for f in filtration_values:
1894
+ # cf.clear()
1895
+ # for truc in f:
1896
+ # cf.push_back(truc)
1897
+ c_filtration_values.push_back(_py21c_f64(f))
1898
+ cdef vector[int] c_generator_dimensions = generator_dimensions
1899
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
1900
+ self.truc = C_Slicer0_vine_f64(c_generator_maps,c_generator_dimensions, c_filtration_values)
1901
+ def copy(self):
1902
+ """
1903
+ Returns a copy of the slicer.
1904
+ """
1905
+ copy_ = _Slicer0_vine_f64()
1906
+ copy_.truc = self.truc
1907
+ return copy_
1908
+ def get_barcode(self):
1909
+ """
1910
+ Returns the current barcode.
1911
+ """
1912
+ return self.truc.get_barcode()
1913
+ def push_to_line(self, basepoint, direction=None):
1914
+ """
1915
+ Pushes the current slicer to the line
1916
+ """
1917
+ cdef Line[double] line
1918
+ if direction is None:
1919
+ line = Line[double](_py21c_f64(basepoint))
1920
+ else:
1921
+ line = Line[double](_py21c_f64(basepoint),_py21c_f64(direction))
1922
+ self.truc.push_to(line)
1923
+ return self
1924
+
1925
+ def persistence_on_line(self,basepoint,direction=None):
1926
+ """
1927
+ Computes the persistence on a line L defined by
1928
+ - a basepoint (num_parameters,) array
1929
+ - an optional direction (num_parameters,) array
1930
+ """
1931
+ self.push_to_line(basepoint,direction)
1932
+ self.truc.compute_persistence()
1933
+ return self.truc.get_barcode()
1934
+ def compute_persistence(self,one_filtration=None):
1935
+ """
1936
+ Computes the current persistence, or the persistence
1937
+ given by the filtration one_filtration (num_generators,).
1938
+ """
1939
+ if one_filtration is not None:
1940
+ self.truc.set_one_filtration(one_filtration)
1941
+ self.truc.compute_persistence()
1942
+ # return self.truc.get_barcode()
1943
+ def get_barcode(self):
1944
+ """
1945
+ Returns the barcode of the current 1d-persistence.
1946
+ """
1947
+ return self.truc.get_barcode()
1948
+ def sliced_filtration(self,basepoint, direction=None):
1949
+ """
1950
+ Computes the filtration on a line L defined by
1951
+ - a basepoint (num_parameters,) array
1952
+ - an optional direction (num_parameters,) array
1953
+ """
1954
+ self.push_to_line(basepoint,direction)
1955
+ return np.asarray(self.truc.get_one_filtration())
1956
+ def __len__(self):
1957
+ return self.truc.num_generators()
1958
+ @property
1959
+ def num_generators(self):
1960
+ return self.truc.num_generators()
1961
+ @property
1962
+ def num_parameters(self):
1963
+ return self.truc.num_parameters()
1964
+ def info(self):
1965
+ return self.truc.to_str().decode()
1966
+ def compute_box(self):
1967
+ """
1968
+ Computes the bounding box of the current persistence.
1969
+ """
1970
+ cdef pair[Finitely_critical_multi_filtration[double],Finitely_critical_multi_filtration[double]] box = self.truc.get_bounding_box()
1971
+ cdef cnp.ndarray[double, ndim=1] a = _ff21cview_f64(&box.first)
1972
+ cdef cnp.ndarray[double, ndim=1] b = _ff21cview_f64(&box.second)
1973
+ return np.asarray([a,b])
1974
+ def get_filtrations_values(self):
1975
+ """
1976
+ Returns the current filtration values of the slicer.
1977
+ """
1978
+ cdef vector[Finitely_critical_multi_filtration[double]] v = self.truc.get_filtration_values()
1979
+ out = _vff21cview_f64(v, copy=True)
1980
+ return np.asarray(out)
1981
+ def get_filtrations(self):
1982
+ return _vff21cview_f64(self.truc.get_filtrations(), copy=True)
1983
+
1984
+ def get_dimensions(self):
1985
+ """
1986
+ Returns the ordered dimensions of the generators.
1987
+ """
1988
+ return np.asarray(self.truc.get_dimensions())
1989
+ def get_boundaries(self):
1990
+ """
1991
+ Returns the boundaries of the generators.
1992
+ """
1993
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
1994
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
1995
+ """
1996
+ Squeeze the filtration values on a grid.
1997
+ """
1998
+ if force and self.is_squeezed:
1999
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
2000
+ if filtration_grid is None:
2001
+ filtration_grid = mpg.compute_grid(
2002
+ self.get_filtrations_values().T,
2003
+ strategy=grid_strategy,
2004
+ resolution=resolution)
2005
+ cdef vector[vector[double]] grid = filtration_grid
2006
+ if inplace or not coordinates:
2007
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
2008
+ self.filtration_grid = filtration_grid
2009
+ else:
2010
+ out = _Slicer0_vine_i32()
2011
+ out.truc = self.truc.coarsen_on_grid(grid)
2012
+ out.filtration_grid = filtration_grid
2013
+ return out
2014
+ return self
2015
+ def minpres(self,
2016
+ int degree = 1,
2017
+ list[int] degrees=[],
2018
+ str backend:Literal["mpfree", "2pac"]="mpfree",
2019
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
2020
+ bool vineyard=True,
2021
+ id :Optional[str] = None,
2022
+ dtype = np.float64,
2023
+ **minpres_kwargs
2024
+ ):
2025
+ """
2026
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
2027
+ """
2028
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
2029
+ return new_slicer
2030
+
2031
+ @property
2032
+ def dtype(self)->type:
2033
+ return np.float64
2034
+ @property
2035
+ def col_type(self)->str:
2036
+ return "INTRUSIVE_SET"
2037
+ @property
2038
+ def is_vine(self)->bool:
2039
+ return True
2040
+ @property
2041
+ def is_kcritical(self)->bool:
2042
+ return False
2043
+
2044
+
2045
+ def vine_update(self,basepoint,direction=None):
2046
+ """
2047
+ Updates the barcode, on a line, using the vineyard algorithm.
2048
+ """
2049
+ self.push_to_line(basepoint,direction)
2050
+ self.truc.vineyard_update()
2051
+ return self
2052
+ def get_representative_cycles(self, bool update=True):
2053
+ """
2054
+ Returns the representative cycles of the current barcode.
2055
+ Recomputes the generators if update=True
2056
+ """
2057
+ return self.truc.get_representative_cycles(update)
2058
+ def get_permutation(self):
2059
+ """
2060
+ Returns the current generator permutation (w.r.t. vineyard).
2061
+ """
2062
+ return self.truc.get_current_order()
2063
+
2064
+ @staticmethod
2065
+ def from_bitmap(self):
2066
+ raise ValueError("Not implemented.")
2067
+
2068
+ #------------------------------------------------------------------------------
2069
+ cdef class _KSlicer0_i32:
2070
+ cdef C_KSlicer0_i32 truc
2071
+ cdef public vector[vector[double]] filtration_grid
2072
+ @property
2073
+ def is_squeezed(self)->bool:
2074
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
2075
+
2076
+ def get_ptr(self):
2077
+ """
2078
+ Returns a pointer to the underlying C++ slicer.
2079
+ """
2080
+ return <intptr_t>(&self.truc)
2081
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2082
+ """
2083
+ Constructs a slicer from
2084
+ - scc-like blocks
2085
+ or
2086
+ - generator maps (Iterable of list of ints)
2087
+ - generator dimensions (Iterable of int)
2088
+ - filtration values (Iterable of filtration values)
2089
+ """
2090
+ pass
2091
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2092
+ """
2093
+ Cython constructor
2094
+ """
2095
+ if len(generator_maps)>0 and len(generator_dimensions) == 0 and len(filtration_values) == 0:
2096
+ from multipers._slicer_meta import _blocks2boundary_dimension_grades
2097
+ generator_maps, generator_dimensions, filtration_values = _blocks2boundary_dimension_grades(
2098
+ generator_maps,
2099
+ inplace=False,
2100
+ )
2101
+ cdef uint32_t num_generators = len(generator_maps)
2102
+ cdef vector[vector[uint32_t]] c_generator_maps
2103
+ cdef vector[KCriticalFiltration[int32_t]] c_filtration_values
2104
+ for stuff in generator_maps:
2105
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
2106
+ cdef KCriticalFiltration[int32_t] cf
2107
+ for F in filtration_values:
2108
+ cf.clear()
2109
+ for f in F:
2110
+ cf.add_point(_py21c_i32(f))
2111
+ c_filtration_values.push_back(cf)
2112
+ cdef vector[int] c_generator_dimensions = generator_dimensions
2113
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
2114
+ self.truc = C_KSlicer0_i32(c_generator_maps,c_generator_dimensions, c_filtration_values)
2115
+ def copy(self):
2116
+ """
2117
+ Returns a copy of the slicer.
2118
+ """
2119
+ copy_ = _KSlicer0_i32()
2120
+ copy_.truc = self.truc
2121
+ return copy_
2122
+ def get_barcode(self):
2123
+ """
2124
+ Returns the current barcode.
2125
+ """
2126
+ return self.truc.get_barcode()
2127
+ def push_to_line(self, basepoint, direction=None):
2128
+ """
2129
+ Pushes the current slicer to the line
2130
+ """
2131
+ cdef Line[int32_t] line
2132
+ if direction is None:
2133
+ line = Line[int32_t](_py21c_i32(basepoint))
2134
+ else:
2135
+ line = Line[int32_t](_py21c_i32(basepoint),_py21c_i32(direction))
2136
+ self.truc.push_to(line)
2137
+ return self
2138
+
2139
+ def persistence_on_line(self,basepoint,direction=None):
2140
+ """
2141
+ Computes the persistence on a line L defined by
2142
+ - a basepoint (num_parameters,) array
2143
+ - an optional direction (num_parameters,) array
2144
+ """
2145
+ self.push_to_line(basepoint,direction)
2146
+ self.truc.compute_persistence()
2147
+ return self.truc.get_barcode()
2148
+ def compute_persistence(self,one_filtration=None):
2149
+ """
2150
+ Computes the current persistence, or the persistence
2151
+ given by the filtration one_filtration (num_generators,).
2152
+ """
2153
+ if one_filtration is not None:
2154
+ self.truc.set_one_filtration(one_filtration)
2155
+ self.truc.compute_persistence()
2156
+ # return self.truc.get_barcode()
2157
+ def get_barcode(self):
2158
+ """
2159
+ Returns the barcode of the current 1d-persistence.
2160
+ """
2161
+ return self.truc.get_barcode()
2162
+ def sliced_filtration(self,basepoint, direction=None):
2163
+ """
2164
+ Computes the filtration on a line L defined by
2165
+ - a basepoint (num_parameters,) array
2166
+ - an optional direction (num_parameters,) array
2167
+ """
2168
+ self.push_to_line(basepoint,direction)
2169
+ return np.asarray(self.truc.get_one_filtration())
2170
+ def __len__(self):
2171
+ return self.truc.num_generators()
2172
+ @property
2173
+ def num_generators(self):
2174
+ return self.truc.num_generators()
2175
+ @property
2176
+ def num_parameters(self):
2177
+ return self.truc.num_parameters()
2178
+ def info(self):
2179
+ return self.truc.to_str().decode()
2180
+ def compute_box(self):
2181
+ """
2182
+ Computes the bounding box of the current persistence.
2183
+ """
2184
+ cdef pair[Finitely_critical_multi_filtration[int32_t],Finitely_critical_multi_filtration[int32_t]] box = self.truc.get_bounding_box()
2185
+ cdef cnp.ndarray[int32_t, ndim=1] a = _ff21cview_i32(&box.first)
2186
+ cdef cnp.ndarray[int32_t, ndim=1] b = _ff21cview_i32(&box.second)
2187
+ return np.asarray([a,b])
2188
+ def get_filtrations_values(self):
2189
+ """
2190
+ Returns the current filtration values of the slicer.
2191
+ """
2192
+ cdef vector[Finitely_critical_multi_filtration[int32_t]] v = self.truc.get_filtration_values()
2193
+ out = _vff21cview_i32(v, copy=True)
2194
+ return np.asarray(out)
2195
+ def get_filtrations(self):
2196
+ return _vff2kcview_i32(self.truc.get_filtrations(), copy=True)
2197
+
2198
+ def get_dimensions(self):
2199
+ """
2200
+ Returns the ordered dimensions of the generators.
2201
+ """
2202
+ return np.asarray(self.truc.get_dimensions())
2203
+ def get_boundaries(self):
2204
+ """
2205
+ Returns the boundaries of the generators.
2206
+ """
2207
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
2208
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
2209
+ """
2210
+ Squeeze the filtration values on a grid.
2211
+ """
2212
+ if force and self.is_squeezed:
2213
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
2214
+ if filtration_grid is None:
2215
+ filtration_grid = mpg.compute_grid(
2216
+ self.get_filtrations_values().T,
2217
+ strategy=grid_strategy,
2218
+ resolution=resolution)
2219
+ cdef vector[vector[int32_t]] grid = filtration_grid
2220
+ if inplace or not coordinates:
2221
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
2222
+ self.filtration_grid = filtration_grid
2223
+ else:
2224
+ out = _KSlicer0_i32()
2225
+ out.truc = self.truc.coarsen_on_grid(grid)
2226
+ out.filtration_grid = filtration_grid
2227
+ return out
2228
+ return self
2229
+ def minpres(self,
2230
+ int degree = 1,
2231
+ list[int] degrees=[],
2232
+ str backend:Literal["mpfree", "2pac"]="mpfree",
2233
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
2234
+ bool vineyard=False,
2235
+ id :Optional[str] = None,
2236
+ dtype = np.int32,
2237
+ **minpres_kwargs
2238
+ ):
2239
+ """
2240
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
2241
+ """
2242
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
2243
+ return new_slicer
2244
+
2245
+ @property
2246
+ def dtype(self)->type:
2247
+ return np.int32
2248
+ @property
2249
+ def col_type(self)->str:
2250
+ return "INTRUSIVE_SET"
2251
+ @property
2252
+ def is_vine(self)->bool:
2253
+ return False
2254
+ @property
2255
+ def is_kcritical(self)->bool:
2256
+ return True
2257
+
2258
+
2259
+
2260
+ @staticmethod
2261
+ def from_bitmap(self):
2262
+ raise ValueError("Not implemented.")
2263
+
2264
+ #------------------------------------------------------------------------------
2265
+ cdef class _KSlicer0_f32:
2266
+ cdef C_KSlicer0_f32 truc
2267
+ cdef public vector[vector[double]] filtration_grid
2268
+ @property
2269
+ def is_squeezed(self)->bool:
2270
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
2271
+
2272
+ def get_ptr(self):
2273
+ """
2274
+ Returns a pointer to the underlying C++ slicer.
2275
+ """
2276
+ return <intptr_t>(&self.truc)
2277
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2278
+ """
2279
+ Constructs a slicer from
2280
+ - scc-like blocks
2281
+ or
2282
+ - generator maps (Iterable of list of ints)
2283
+ - generator dimensions (Iterable of int)
2284
+ - filtration values (Iterable of filtration values)
2285
+ """
2286
+ pass
2287
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2288
+ """
2289
+ Cython constructor
2290
+ """
2291
+ if len(generator_maps)>0 and len(generator_dimensions) == 0 and len(filtration_values) == 0:
2292
+ from multipers._slicer_meta import _blocks2boundary_dimension_grades
2293
+ generator_maps, generator_dimensions, filtration_values = _blocks2boundary_dimension_grades(
2294
+ generator_maps,
2295
+ inplace=False,
2296
+ )
2297
+ cdef uint32_t num_generators = len(generator_maps)
2298
+ cdef vector[vector[uint32_t]] c_generator_maps
2299
+ cdef vector[KCriticalFiltration[float]] c_filtration_values
2300
+ for stuff in generator_maps:
2301
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
2302
+ cdef KCriticalFiltration[float] cf
2303
+ for F in filtration_values:
2304
+ cf.clear()
2305
+ for f in F:
2306
+ cf.add_point(_py21c_f32(f))
2307
+ c_filtration_values.push_back(cf)
2308
+ cdef vector[int] c_generator_dimensions = generator_dimensions
2309
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
2310
+ self.truc = C_KSlicer0_f32(c_generator_maps,c_generator_dimensions, c_filtration_values)
2311
+ def copy(self):
2312
+ """
2313
+ Returns a copy of the slicer.
2314
+ """
2315
+ copy_ = _KSlicer0_f32()
2316
+ copy_.truc = self.truc
2317
+ return copy_
2318
+ def get_barcode(self):
2319
+ """
2320
+ Returns the current barcode.
2321
+ """
2322
+ return self.truc.get_barcode()
2323
+ def push_to_line(self, basepoint, direction=None):
2324
+ """
2325
+ Pushes the current slicer to the line
2326
+ """
2327
+ cdef Line[float] line
2328
+ if direction is None:
2329
+ line = Line[float](_py21c_f32(basepoint))
2330
+ else:
2331
+ line = Line[float](_py21c_f32(basepoint),_py21c_f32(direction))
2332
+ self.truc.push_to(line)
2333
+ return self
2334
+
2335
+ def persistence_on_line(self,basepoint,direction=None):
2336
+ """
2337
+ Computes the persistence on a line L defined by
2338
+ - a basepoint (num_parameters,) array
2339
+ - an optional direction (num_parameters,) array
2340
+ """
2341
+ self.push_to_line(basepoint,direction)
2342
+ self.truc.compute_persistence()
2343
+ return self.truc.get_barcode()
2344
+ def compute_persistence(self,one_filtration=None):
2345
+ """
2346
+ Computes the current persistence, or the persistence
2347
+ given by the filtration one_filtration (num_generators,).
2348
+ """
2349
+ if one_filtration is not None:
2350
+ self.truc.set_one_filtration(one_filtration)
2351
+ self.truc.compute_persistence()
2352
+ # return self.truc.get_barcode()
2353
+ def get_barcode(self):
2354
+ """
2355
+ Returns the barcode of the current 1d-persistence.
2356
+ """
2357
+ return self.truc.get_barcode()
2358
+ def sliced_filtration(self,basepoint, direction=None):
2359
+ """
2360
+ Computes the filtration on a line L defined by
2361
+ - a basepoint (num_parameters,) array
2362
+ - an optional direction (num_parameters,) array
2363
+ """
2364
+ self.push_to_line(basepoint,direction)
2365
+ return np.asarray(self.truc.get_one_filtration())
2366
+ def __len__(self):
2367
+ return self.truc.num_generators()
2368
+ @property
2369
+ def num_generators(self):
2370
+ return self.truc.num_generators()
2371
+ @property
2372
+ def num_parameters(self):
2373
+ return self.truc.num_parameters()
2374
+ def info(self):
2375
+ return self.truc.to_str().decode()
2376
+ def compute_box(self):
2377
+ """
2378
+ Computes the bounding box of the current persistence.
2379
+ """
2380
+ cdef pair[Finitely_critical_multi_filtration[float],Finitely_critical_multi_filtration[float]] box = self.truc.get_bounding_box()
2381
+ cdef cnp.ndarray[float, ndim=1] a = _ff21cview_f32(&box.first)
2382
+ cdef cnp.ndarray[float, ndim=1] b = _ff21cview_f32(&box.second)
2383
+ return np.asarray([a,b])
2384
+ def get_filtrations_values(self):
2385
+ """
2386
+ Returns the current filtration values of the slicer.
2387
+ """
2388
+ cdef vector[Finitely_critical_multi_filtration[float]] v = self.truc.get_filtration_values()
2389
+ out = _vff21cview_f32(v, copy=True)
2390
+ return np.asarray(out)
2391
+ def get_filtrations(self):
2392
+ return _vff2kcview_f32(self.truc.get_filtrations(), copy=True)
2393
+
2394
+ def get_dimensions(self):
2395
+ """
2396
+ Returns the ordered dimensions of the generators.
2397
+ """
2398
+ return np.asarray(self.truc.get_dimensions())
2399
+ def get_boundaries(self):
2400
+ """
2401
+ Returns the boundaries of the generators.
2402
+ """
2403
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
2404
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
2405
+ """
2406
+ Squeeze the filtration values on a grid.
2407
+ """
2408
+ if force and self.is_squeezed:
2409
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
2410
+ if filtration_grid is None:
2411
+ filtration_grid = mpg.compute_grid(
2412
+ self.get_filtrations_values().T,
2413
+ strategy=grid_strategy,
2414
+ resolution=resolution)
2415
+ cdef vector[vector[float]] grid = filtration_grid
2416
+ if inplace or not coordinates:
2417
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
2418
+ self.filtration_grid = filtration_grid
2419
+ else:
2420
+ out = _KSlicer0_i32()
2421
+ out.truc = self.truc.coarsen_on_grid(grid)
2422
+ out.filtration_grid = filtration_grid
2423
+ return out
2424
+ return self
2425
+ def minpres(self,
2426
+ int degree = 1,
2427
+ list[int] degrees=[],
2428
+ str backend:Literal["mpfree", "2pac"]="mpfree",
2429
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
2430
+ bool vineyard=False,
2431
+ id :Optional[str] = None,
2432
+ dtype = np.float32,
2433
+ **minpres_kwargs
2434
+ ):
2435
+ """
2436
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
2437
+ """
2438
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
2439
+ return new_slicer
2440
+
2441
+ @property
2442
+ def dtype(self)->type:
2443
+ return np.float32
2444
+ @property
2445
+ def col_type(self)->str:
2446
+ return "INTRUSIVE_SET"
2447
+ @property
2448
+ def is_vine(self)->bool:
2449
+ return False
2450
+ @property
2451
+ def is_kcritical(self)->bool:
2452
+ return True
2453
+
2454
+
2455
+
2456
+ @staticmethod
2457
+ def from_bitmap(self):
2458
+ raise ValueError("Not implemented.")
2459
+
2460
+ #------------------------------------------------------------------------------
2461
+ cdef class _KSlicer0_f64:
2462
+ cdef C_KSlicer0_f64 truc
2463
+ cdef public vector[vector[double]] filtration_grid
2464
+ @property
2465
+ def is_squeezed(self)->bool:
2466
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
2467
+
2468
+ def get_ptr(self):
2469
+ """
2470
+ Returns a pointer to the underlying C++ slicer.
2471
+ """
2472
+ return <intptr_t>(&self.truc)
2473
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2474
+ """
2475
+ Constructs a slicer from
2476
+ - scc-like blocks
2477
+ or
2478
+ - generator maps (Iterable of list of ints)
2479
+ - generator dimensions (Iterable of int)
2480
+ - filtration values (Iterable of filtration values)
2481
+ """
2482
+ pass
2483
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2484
+ """
2485
+ Cython constructor
2486
+ """
2487
+ if len(generator_maps)>0 and len(generator_dimensions) == 0 and len(filtration_values) == 0:
2488
+ from multipers._slicer_meta import _blocks2boundary_dimension_grades
2489
+ generator_maps, generator_dimensions, filtration_values = _blocks2boundary_dimension_grades(
2490
+ generator_maps,
2491
+ inplace=False,
2492
+ )
2493
+ cdef uint32_t num_generators = len(generator_maps)
2494
+ cdef vector[vector[uint32_t]] c_generator_maps
2495
+ cdef vector[KCriticalFiltration[double]] c_filtration_values
2496
+ for stuff in generator_maps:
2497
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
2498
+ cdef KCriticalFiltration[double] cf
2499
+ for F in filtration_values:
2500
+ cf.clear()
2501
+ for f in F:
2502
+ cf.add_point(_py21c_f64(f))
2503
+ c_filtration_values.push_back(cf)
2504
+ cdef vector[int] c_generator_dimensions = generator_dimensions
2505
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
2506
+ self.truc = C_KSlicer0_f64(c_generator_maps,c_generator_dimensions, c_filtration_values)
2507
+ def copy(self):
2508
+ """
2509
+ Returns a copy of the slicer.
2510
+ """
2511
+ copy_ = _KSlicer0_f64()
2512
+ copy_.truc = self.truc
2513
+ return copy_
2514
+ def get_barcode(self):
2515
+ """
2516
+ Returns the current barcode.
2517
+ """
2518
+ return self.truc.get_barcode()
2519
+ def push_to_line(self, basepoint, direction=None):
2520
+ """
2521
+ Pushes the current slicer to the line
2522
+ """
2523
+ cdef Line[double] line
2524
+ if direction is None:
2525
+ line = Line[double](_py21c_f64(basepoint))
2526
+ else:
2527
+ line = Line[double](_py21c_f64(basepoint),_py21c_f64(direction))
2528
+ self.truc.push_to(line)
2529
+ return self
2530
+
2531
+ def persistence_on_line(self,basepoint,direction=None):
2532
+ """
2533
+ Computes the persistence on a line L defined by
2534
+ - a basepoint (num_parameters,) array
2535
+ - an optional direction (num_parameters,) array
2536
+ """
2537
+ self.push_to_line(basepoint,direction)
2538
+ self.truc.compute_persistence()
2539
+ return self.truc.get_barcode()
2540
+ def compute_persistence(self,one_filtration=None):
2541
+ """
2542
+ Computes the current persistence, or the persistence
2543
+ given by the filtration one_filtration (num_generators,).
2544
+ """
2545
+ if one_filtration is not None:
2546
+ self.truc.set_one_filtration(one_filtration)
2547
+ self.truc.compute_persistence()
2548
+ # return self.truc.get_barcode()
2549
+ def get_barcode(self):
2550
+ """
2551
+ Returns the barcode of the current 1d-persistence.
2552
+ """
2553
+ return self.truc.get_barcode()
2554
+ def sliced_filtration(self,basepoint, direction=None):
2555
+ """
2556
+ Computes the filtration on a line L defined by
2557
+ - a basepoint (num_parameters,) array
2558
+ - an optional direction (num_parameters,) array
2559
+ """
2560
+ self.push_to_line(basepoint,direction)
2561
+ return np.asarray(self.truc.get_one_filtration())
2562
+ def __len__(self):
2563
+ return self.truc.num_generators()
2564
+ @property
2565
+ def num_generators(self):
2566
+ return self.truc.num_generators()
2567
+ @property
2568
+ def num_parameters(self):
2569
+ return self.truc.num_parameters()
2570
+ def info(self):
2571
+ return self.truc.to_str().decode()
2572
+ def compute_box(self):
2573
+ """
2574
+ Computes the bounding box of the current persistence.
2575
+ """
2576
+ cdef pair[Finitely_critical_multi_filtration[double],Finitely_critical_multi_filtration[double]] box = self.truc.get_bounding_box()
2577
+ cdef cnp.ndarray[double, ndim=1] a = _ff21cview_f64(&box.first)
2578
+ cdef cnp.ndarray[double, ndim=1] b = _ff21cview_f64(&box.second)
2579
+ return np.asarray([a,b])
2580
+ def get_filtrations_values(self):
2581
+ """
2582
+ Returns the current filtration values of the slicer.
2583
+ """
2584
+ cdef vector[Finitely_critical_multi_filtration[double]] v = self.truc.get_filtration_values()
2585
+ out = _vff21cview_f64(v, copy=True)
2586
+ return np.asarray(out)
2587
+ def get_filtrations(self):
2588
+ return _vff2kcview_f64(self.truc.get_filtrations(), copy=True)
2589
+
2590
+ def get_dimensions(self):
2591
+ """
2592
+ Returns the ordered dimensions of the generators.
2593
+ """
2594
+ return np.asarray(self.truc.get_dimensions())
2595
+ def get_boundaries(self):
2596
+ """
2597
+ Returns the boundaries of the generators.
2598
+ """
2599
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
2600
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
2601
+ """
2602
+ Squeeze the filtration values on a grid.
2603
+ """
2604
+ if force and self.is_squeezed:
2605
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
2606
+ if filtration_grid is None:
2607
+ filtration_grid = mpg.compute_grid(
2608
+ self.get_filtrations_values().T,
2609
+ strategy=grid_strategy,
2610
+ resolution=resolution)
2611
+ cdef vector[vector[double]] grid = filtration_grid
2612
+ if inplace or not coordinates:
2613
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
2614
+ self.filtration_grid = filtration_grid
2615
+ else:
2616
+ out = _KSlicer0_i32()
2617
+ out.truc = self.truc.coarsen_on_grid(grid)
2618
+ out.filtration_grid = filtration_grid
2619
+ return out
2620
+ return self
2621
+ def minpres(self,
2622
+ int degree = 1,
2623
+ list[int] degrees=[],
2624
+ str backend:Literal["mpfree", "2pac"]="mpfree",
2625
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
2626
+ bool vineyard=False,
2627
+ id :Optional[str] = None,
2628
+ dtype = np.float64,
2629
+ **minpres_kwargs
2630
+ ):
2631
+ """
2632
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
2633
+ """
2634
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
2635
+ return new_slicer
2636
+
2637
+ @property
2638
+ def dtype(self)->type:
2639
+ return np.float64
2640
+ @property
2641
+ def col_type(self)->str:
2642
+ return "INTRUSIVE_SET"
2643
+ @property
2644
+ def is_vine(self)->bool:
2645
+ return False
2646
+ @property
2647
+ def is_kcritical(self)->bool:
2648
+ return True
2649
+
2650
+
2651
+
2652
+ @staticmethod
2653
+ def from_bitmap(self):
2654
+ raise ValueError("Not implemented.")
2655
+
2656
+ #------------------------------------------------------------------------------
2657
+ cdef class _Slicer0_i32:
2658
+ cdef C_Slicer0_i32 truc
2659
+ cdef public vector[vector[double]] filtration_grid
2660
+ @property
2661
+ def is_squeezed(self)->bool:
2662
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
2663
+
2664
+ def get_ptr(self):
2665
+ """
2666
+ Returns a pointer to the underlying C++ slicer.
2667
+ """
2668
+ return <intptr_t>(&self.truc)
2669
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2670
+ """
2671
+ Constructs a slicer from
2672
+ - generator maps (Iterable of list of ints)
2673
+ - generator dimensions (Iterable of int)
2674
+ - filtration values (Iterable of filtration values)
2675
+ """
2676
+ pass
2677
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2678
+ """
2679
+ Cython constructor
2680
+ """
2681
+ cdef uint32_t num_generators = len(generator_maps)
2682
+ cdef vector[vector[uint32_t]] c_generator_maps
2683
+ cdef vector[Finitely_critical_multi_filtration[int32_t]] c_filtration_values
2684
+ for stuff in generator_maps:
2685
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
2686
+ for f in filtration_values:
2687
+ # cf.clear()
2688
+ # for truc in f:
2689
+ # cf.push_back(truc)
2690
+ c_filtration_values.push_back(_py21c_i32(f))
2691
+ cdef vector[int] c_generator_dimensions = generator_dimensions
2692
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
2693
+ self.truc = C_Slicer0_i32(c_generator_maps,c_generator_dimensions, c_filtration_values)
2694
+ def copy(self):
2695
+ """
2696
+ Returns a copy of the slicer.
2697
+ """
2698
+ copy_ = _Slicer0_i32()
2699
+ copy_.truc = self.truc
2700
+ return copy_
2701
+ def get_barcode(self):
2702
+ """
2703
+ Returns the current barcode.
2704
+ """
2705
+ return self.truc.get_barcode()
2706
+ def push_to_line(self, basepoint, direction=None):
2707
+ """
2708
+ Pushes the current slicer to the line
2709
+ """
2710
+ cdef Line[int32_t] line
2711
+ if direction is None:
2712
+ line = Line[int32_t](_py21c_i32(basepoint))
2713
+ else:
2714
+ line = Line[int32_t](_py21c_i32(basepoint),_py21c_i32(direction))
2715
+ self.truc.push_to(line)
2716
+ return self
2717
+
2718
+ def persistence_on_line(self,basepoint,direction=None):
2719
+ """
2720
+ Computes the persistence on a line L defined by
2721
+ - a basepoint (num_parameters,) array
2722
+ - an optional direction (num_parameters,) array
2723
+ """
2724
+ self.push_to_line(basepoint,direction)
2725
+ self.truc.compute_persistence()
2726
+ return self.truc.get_barcode()
2727
+ def compute_persistence(self,one_filtration=None):
2728
+ """
2729
+ Computes the current persistence, or the persistence
2730
+ given by the filtration one_filtration (num_generators,).
2731
+ """
2732
+ if one_filtration is not None:
2733
+ self.truc.set_one_filtration(one_filtration)
2734
+ self.truc.compute_persistence()
2735
+ # return self.truc.get_barcode()
2736
+ def get_barcode(self):
2737
+ """
2738
+ Returns the barcode of the current 1d-persistence.
2739
+ """
2740
+ return self.truc.get_barcode()
2741
+ def sliced_filtration(self,basepoint, direction=None):
2742
+ """
2743
+ Computes the filtration on a line L defined by
2744
+ - a basepoint (num_parameters,) array
2745
+ - an optional direction (num_parameters,) array
2746
+ """
2747
+ self.push_to_line(basepoint,direction)
2748
+ return np.asarray(self.truc.get_one_filtration())
2749
+ def __len__(self):
2750
+ return self.truc.num_generators()
2751
+ @property
2752
+ def num_generators(self):
2753
+ return self.truc.num_generators()
2754
+ @property
2755
+ def num_parameters(self):
2756
+ return self.truc.num_parameters()
2757
+ def info(self):
2758
+ return self.truc.to_str().decode()
2759
+ def compute_box(self):
2760
+ """
2761
+ Computes the bounding box of the current persistence.
2762
+ """
2763
+ cdef pair[Finitely_critical_multi_filtration[int32_t],Finitely_critical_multi_filtration[int32_t]] box = self.truc.get_bounding_box()
2764
+ cdef cnp.ndarray[int32_t, ndim=1] a = _ff21cview_i32(&box.first)
2765
+ cdef cnp.ndarray[int32_t, ndim=1] b = _ff21cview_i32(&box.second)
2766
+ return np.asarray([a,b])
2767
+ def get_filtrations_values(self):
2768
+ """
2769
+ Returns the current filtration values of the slicer.
2770
+ """
2771
+ cdef vector[Finitely_critical_multi_filtration[int32_t]] v = self.truc.get_filtration_values()
2772
+ out = _vff21cview_i32(v, copy=True)
2773
+ return np.asarray(out)
2774
+ def get_filtrations(self):
2775
+ return _vff21cview_i32(self.truc.get_filtrations(), copy=True)
2776
+
2777
+ def get_dimensions(self):
2778
+ """
2779
+ Returns the ordered dimensions of the generators.
2780
+ """
2781
+ return np.asarray(self.truc.get_dimensions())
2782
+ def get_boundaries(self):
2783
+ """
2784
+ Returns the boundaries of the generators.
2785
+ """
2786
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
2787
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
2788
+ """
2789
+ Squeeze the filtration values on a grid.
2790
+ """
2791
+ if force and self.is_squeezed:
2792
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
2793
+ if filtration_grid is None:
2794
+ filtration_grid = mpg.compute_grid(
2795
+ self.get_filtrations_values().T,
2796
+ strategy=grid_strategy,
2797
+ resolution=resolution)
2798
+ cdef vector[vector[int32_t]] grid = filtration_grid
2799
+ if inplace or not coordinates:
2800
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
2801
+ self.filtration_grid = filtration_grid
2802
+ else:
2803
+ out = _Slicer0_i32()
2804
+ out.truc = self.truc.coarsen_on_grid(grid)
2805
+ out.filtration_grid = filtration_grid
2806
+ return out
2807
+ return self
2808
+ def minpres(self,
2809
+ int degree = 1,
2810
+ list[int] degrees=[],
2811
+ str backend:Literal["mpfree", "2pac"]="mpfree",
2812
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
2813
+ bool vineyard=False,
2814
+ id :Optional[str] = None,
2815
+ dtype = np.int32,
2816
+ **minpres_kwargs
2817
+ ):
2818
+ """
2819
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
2820
+ """
2821
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
2822
+ return new_slicer
2823
+
2824
+ @property
2825
+ def dtype(self)->type:
2826
+ return np.int32
2827
+ @property
2828
+ def col_type(self)->str:
2829
+ return "INTRUSIVE_SET"
2830
+ @property
2831
+ def is_vine(self)->bool:
2832
+ return False
2833
+ @property
2834
+ def is_kcritical(self)->bool:
2835
+ return False
2836
+
2837
+
2838
+
2839
+ @staticmethod
2840
+ def from_bitmap(self):
2841
+ raise ValueError("Not implemented.")
2842
+
2843
+ #------------------------------------------------------------------------------
2844
+ cdef class _Slicer0_f32:
2845
+ cdef C_Slicer0_f32 truc
2846
+ cdef public vector[vector[double]] filtration_grid
2847
+ @property
2848
+ def is_squeezed(self)->bool:
2849
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
2850
+
2851
+ def get_ptr(self):
2852
+ """
2853
+ Returns a pointer to the underlying C++ slicer.
2854
+ """
2855
+ return <intptr_t>(&self.truc)
2856
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2857
+ """
2858
+ Constructs a slicer from
2859
+ - generator maps (Iterable of list of ints)
2860
+ - generator dimensions (Iterable of int)
2861
+ - filtration values (Iterable of filtration values)
2862
+ """
2863
+ pass
2864
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
2865
+ """
2866
+ Cython constructor
2867
+ """
2868
+ cdef uint32_t num_generators = len(generator_maps)
2869
+ cdef vector[vector[uint32_t]] c_generator_maps
2870
+ cdef vector[Finitely_critical_multi_filtration[float]] c_filtration_values
2871
+ for stuff in generator_maps:
2872
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
2873
+ for f in filtration_values:
2874
+ # cf.clear()
2875
+ # for truc in f:
2876
+ # cf.push_back(truc)
2877
+ c_filtration_values.push_back(_py21c_f32(f))
2878
+ cdef vector[int] c_generator_dimensions = generator_dimensions
2879
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
2880
+ self.truc = C_Slicer0_f32(c_generator_maps,c_generator_dimensions, c_filtration_values)
2881
+ def copy(self):
2882
+ """
2883
+ Returns a copy of the slicer.
2884
+ """
2885
+ copy_ = _Slicer0_f32()
2886
+ copy_.truc = self.truc
2887
+ return copy_
2888
+ def get_barcode(self):
2889
+ """
2890
+ Returns the current barcode.
2891
+ """
2892
+ return self.truc.get_barcode()
2893
+ def push_to_line(self, basepoint, direction=None):
2894
+ """
2895
+ Pushes the current slicer to the line
2896
+ """
2897
+ cdef Line[float] line
2898
+ if direction is None:
2899
+ line = Line[float](_py21c_f32(basepoint))
2900
+ else:
2901
+ line = Line[float](_py21c_f32(basepoint),_py21c_f32(direction))
2902
+ self.truc.push_to(line)
2903
+ return self
2904
+
2905
+ def persistence_on_line(self,basepoint,direction=None):
2906
+ """
2907
+ Computes the persistence on a line L defined by
2908
+ - a basepoint (num_parameters,) array
2909
+ - an optional direction (num_parameters,) array
2910
+ """
2911
+ self.push_to_line(basepoint,direction)
2912
+ self.truc.compute_persistence()
2913
+ return self.truc.get_barcode()
2914
+ def compute_persistence(self,one_filtration=None):
2915
+ """
2916
+ Computes the current persistence, or the persistence
2917
+ given by the filtration one_filtration (num_generators,).
2918
+ """
2919
+ if one_filtration is not None:
2920
+ self.truc.set_one_filtration(one_filtration)
2921
+ self.truc.compute_persistence()
2922
+ # return self.truc.get_barcode()
2923
+ def get_barcode(self):
2924
+ """
2925
+ Returns the barcode of the current 1d-persistence.
2926
+ """
2927
+ return self.truc.get_barcode()
2928
+ def sliced_filtration(self,basepoint, direction=None):
2929
+ """
2930
+ Computes the filtration on a line L defined by
2931
+ - a basepoint (num_parameters,) array
2932
+ - an optional direction (num_parameters,) array
2933
+ """
2934
+ self.push_to_line(basepoint,direction)
2935
+ return np.asarray(self.truc.get_one_filtration())
2936
+ def __len__(self):
2937
+ return self.truc.num_generators()
2938
+ @property
2939
+ def num_generators(self):
2940
+ return self.truc.num_generators()
2941
+ @property
2942
+ def num_parameters(self):
2943
+ return self.truc.num_parameters()
2944
+ def info(self):
2945
+ return self.truc.to_str().decode()
2946
+ def compute_box(self):
2947
+ """
2948
+ Computes the bounding box of the current persistence.
2949
+ """
2950
+ cdef pair[Finitely_critical_multi_filtration[float],Finitely_critical_multi_filtration[float]] box = self.truc.get_bounding_box()
2951
+ cdef cnp.ndarray[float, ndim=1] a = _ff21cview_f32(&box.first)
2952
+ cdef cnp.ndarray[float, ndim=1] b = _ff21cview_f32(&box.second)
2953
+ return np.asarray([a,b])
2954
+ def get_filtrations_values(self):
2955
+ """
2956
+ Returns the current filtration values of the slicer.
2957
+ """
2958
+ cdef vector[Finitely_critical_multi_filtration[float]] v = self.truc.get_filtration_values()
2959
+ out = _vff21cview_f32(v, copy=True)
2960
+ return np.asarray(out)
2961
+ def get_filtrations(self):
2962
+ return _vff21cview_f32(self.truc.get_filtrations(), copy=True)
2963
+
2964
+ def get_dimensions(self):
2965
+ """
2966
+ Returns the ordered dimensions of the generators.
2967
+ """
2968
+ return np.asarray(self.truc.get_dimensions())
2969
+ def get_boundaries(self):
2970
+ """
2971
+ Returns the boundaries of the generators.
2972
+ """
2973
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
2974
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
2975
+ """
2976
+ Squeeze the filtration values on a grid.
2977
+ """
2978
+ if force and self.is_squeezed:
2979
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
2980
+ if filtration_grid is None:
2981
+ filtration_grid = mpg.compute_grid(
2982
+ self.get_filtrations_values().T,
2983
+ strategy=grid_strategy,
2984
+ resolution=resolution)
2985
+ cdef vector[vector[float]] grid = filtration_grid
2986
+ if inplace or not coordinates:
2987
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
2988
+ self.filtration_grid = filtration_grid
2989
+ else:
2990
+ out = _Slicer0_i32()
2991
+ out.truc = self.truc.coarsen_on_grid(grid)
2992
+ out.filtration_grid = filtration_grid
2993
+ return out
2994
+ return self
2995
+ def minpres(self,
2996
+ int degree = 1,
2997
+ list[int] degrees=[],
2998
+ str backend:Literal["mpfree", "2pac"]="mpfree",
2999
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
3000
+ bool vineyard=False,
3001
+ id :Optional[str] = None,
3002
+ dtype = np.float32,
3003
+ **minpres_kwargs
3004
+ ):
3005
+ """
3006
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
3007
+ """
3008
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
3009
+ return new_slicer
3010
+
3011
+ @property
3012
+ def dtype(self)->type:
3013
+ return np.float32
3014
+ @property
3015
+ def col_type(self)->str:
3016
+ return "INTRUSIVE_SET"
3017
+ @property
3018
+ def is_vine(self)->bool:
3019
+ return False
3020
+ @property
3021
+ def is_kcritical(self)->bool:
3022
+ return False
3023
+
3024
+
3025
+
3026
+ @staticmethod
3027
+ def from_bitmap(self):
3028
+ raise ValueError("Not implemented.")
3029
+
3030
+ #------------------------------------------------------------------------------
3031
+ cdef class _Slicer0_f64:
3032
+ cdef C_Slicer0_f64 truc
3033
+ cdef public vector[vector[double]] filtration_grid
3034
+ @property
3035
+ def is_squeezed(self)->bool:
3036
+ return self.filtration_grid.size() > 0 and self.filtration_grid[0].size() > 0
3037
+
3038
+ def get_ptr(self):
3039
+ """
3040
+ Returns a pointer to the underlying C++ slicer.
3041
+ """
3042
+ return <intptr_t>(&self.truc)
3043
+ def __init__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
3044
+ """
3045
+ Constructs a slicer from
3046
+ - generator maps (Iterable of list of ints)
3047
+ - generator dimensions (Iterable of int)
3048
+ - filtration values (Iterable of filtration values)
3049
+ """
3050
+ pass
3051
+ def __cinit__(self, generator_maps=[], generator_dimensions=[], filtration_values=[]):
3052
+ """
3053
+ Cython constructor
3054
+ """
3055
+ cdef uint32_t num_generators = len(generator_maps)
3056
+ cdef vector[vector[uint32_t]] c_generator_maps
3057
+ cdef vector[Finitely_critical_multi_filtration[double]] c_filtration_values
3058
+ for stuff in generator_maps:
3059
+ c_generator_maps.push_back(<vector[uint32_t]>(stuff))
3060
+ for f in filtration_values:
3061
+ # cf.clear()
3062
+ # for truc in f:
3063
+ # cf.push_back(truc)
3064
+ c_filtration_values.push_back(_py21c_f64(f))
3065
+ cdef vector[int] c_generator_dimensions = generator_dimensions
3066
+ assert num_generators == c_generator_maps.size() == c_filtration_values.size(), "Invalid input, shape do not coincide."
3067
+ self.truc = C_Slicer0_f64(c_generator_maps,c_generator_dimensions, c_filtration_values)
3068
+ def copy(self):
3069
+ """
3070
+ Returns a copy of the slicer.
3071
+ """
3072
+ copy_ = _Slicer0_f64()
3073
+ copy_.truc = self.truc
3074
+ return copy_
3075
+ def get_barcode(self):
3076
+ """
3077
+ Returns the current barcode.
3078
+ """
3079
+ return self.truc.get_barcode()
3080
+ def push_to_line(self, basepoint, direction=None):
3081
+ """
3082
+ Pushes the current slicer to the line
3083
+ """
3084
+ cdef Line[double] line
3085
+ if direction is None:
3086
+ line = Line[double](_py21c_f64(basepoint))
3087
+ else:
3088
+ line = Line[double](_py21c_f64(basepoint),_py21c_f64(direction))
3089
+ self.truc.push_to(line)
3090
+ return self
3091
+
3092
+ def persistence_on_line(self,basepoint,direction=None):
3093
+ """
3094
+ Computes the persistence on a line L defined by
3095
+ - a basepoint (num_parameters,) array
3096
+ - an optional direction (num_parameters,) array
3097
+ """
3098
+ self.push_to_line(basepoint,direction)
3099
+ self.truc.compute_persistence()
3100
+ return self.truc.get_barcode()
3101
+ def compute_persistence(self,one_filtration=None):
3102
+ """
3103
+ Computes the current persistence, or the persistence
3104
+ given by the filtration one_filtration (num_generators,).
3105
+ """
3106
+ if one_filtration is not None:
3107
+ self.truc.set_one_filtration(one_filtration)
3108
+ self.truc.compute_persistence()
3109
+ # return self.truc.get_barcode()
3110
+ def get_barcode(self):
3111
+ """
3112
+ Returns the barcode of the current 1d-persistence.
3113
+ """
3114
+ return self.truc.get_barcode()
3115
+ def sliced_filtration(self,basepoint, direction=None):
3116
+ """
3117
+ Computes the filtration on a line L defined by
3118
+ - a basepoint (num_parameters,) array
3119
+ - an optional direction (num_parameters,) array
3120
+ """
3121
+ self.push_to_line(basepoint,direction)
3122
+ return np.asarray(self.truc.get_one_filtration())
3123
+ def __len__(self):
3124
+ return self.truc.num_generators()
3125
+ @property
3126
+ def num_generators(self):
3127
+ return self.truc.num_generators()
3128
+ @property
3129
+ def num_parameters(self):
3130
+ return self.truc.num_parameters()
3131
+ def info(self):
3132
+ return self.truc.to_str().decode()
3133
+ def compute_box(self):
3134
+ """
3135
+ Computes the bounding box of the current persistence.
3136
+ """
3137
+ cdef pair[Finitely_critical_multi_filtration[double],Finitely_critical_multi_filtration[double]] box = self.truc.get_bounding_box()
3138
+ cdef cnp.ndarray[double, ndim=1] a = _ff21cview_f64(&box.first)
3139
+ cdef cnp.ndarray[double, ndim=1] b = _ff21cview_f64(&box.second)
3140
+ return np.asarray([a,b])
3141
+ def get_filtrations_values(self):
3142
+ """
3143
+ Returns the current filtration values of the slicer.
3144
+ """
3145
+ cdef vector[Finitely_critical_multi_filtration[double]] v = self.truc.get_filtration_values()
3146
+ out = _vff21cview_f64(v, copy=True)
3147
+ return np.asarray(out)
3148
+ def get_filtrations(self):
3149
+ return _vff21cview_f64(self.truc.get_filtrations(), copy=True)
3150
+
3151
+ def get_dimensions(self):
3152
+ """
3153
+ Returns the ordered dimensions of the generators.
3154
+ """
3155
+ return np.asarray(self.truc.get_dimensions())
3156
+ def get_boundaries(self):
3157
+ """
3158
+ Returns the boundaries of the generators.
3159
+ """
3160
+ return tuple(tuple(b) for b in self.truc.get_boundaries())
3161
+ def grid_squeeze(self, filtration_grid=None, grid_strategy="exact", resolution=-1, bool coordinates=True, bool inplace = False, bool force=False):
3162
+ """
3163
+ Squeeze the filtration values on a grid.
3164
+ """
3165
+ if force and self.is_squeezed:
3166
+ raise ValueError("The slicer seems to be already squeezed. Use force=True to resqueeze.")
3167
+ if filtration_grid is None:
3168
+ filtration_grid = mpg.compute_grid(
3169
+ self.get_filtrations_values().T,
3170
+ strategy=grid_strategy,
3171
+ resolution=resolution)
3172
+ cdef vector[vector[double]] grid = filtration_grid
3173
+ if inplace or not coordinates:
3174
+ self.truc.coarsen_on_grid_inplace(grid, coordinates)
3175
+ self.filtration_grid = filtration_grid
3176
+ else:
3177
+ out = _Slicer0_i32()
3178
+ out.truc = self.truc.coarsen_on_grid(grid)
3179
+ out.filtration_grid = filtration_grid
3180
+ return out
3181
+ return self
3182
+ def minpres(self,
3183
+ int degree = 1,
3184
+ list[int] degrees=[],
3185
+ str backend:Literal["mpfree", "2pac"]="mpfree",
3186
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
3187
+ bool vineyard=False,
3188
+ id :Optional[str] = None,
3189
+ dtype = np.float64,
3190
+ **minpres_kwargs
3191
+ ):
3192
+ """
3193
+ Computes the minimal presentation of the slicer, and returns it as a new slicer.
3194
+ """
3195
+ new_slicer = minimal_presentation(self, degree=degree, degrees=degrees, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs)
3196
+ return new_slicer
3197
+
3198
+ @property
3199
+ def dtype(self)->type:
3200
+ return np.float64
3201
+ @property
3202
+ def col_type(self)->str:
3203
+ return "INTRUSIVE_SET"
3204
+ @property
3205
+ def is_vine(self)->bool:
3206
+ return False
3207
+ @property
3208
+ def is_kcritical(self)->bool:
3209
+ return False
3210
+
3211
+
3212
+
3213
+ @staticmethod
3214
+ def from_bitmap(self):
3215
+ raise ValueError("Not implemented.")
3216
+
3217
+
3218
+ def from_function_delaunay(
3219
+ points,
3220
+ grades,
3221
+ int degree=-1,
3222
+ str backend: Literal["matrix", "clement"] = "matrix",
3223
+ bool vineyard=True,
3224
+ bool verbose = False,
3225
+ bool clear = True,
3226
+ ):
3227
+ """
3228
+ Given points in $\mathbb R^n$ and function grades, compute the function-delaunay
3229
+ bifiltration as a in an scc format, and converts it into a slicer.
3230
+
3231
+ points : (num_pts, n) float array
3232
+ grades : (num_pts,) float array
3233
+ degree (opt) : if given, computes a minimal presentation of this homological degree first
3234
+ backend : slicer backend, e.g. "matrix", "clement"
3235
+ vineyard : bool, use a vineyard-compatible backend
3236
+ """
3237
+ blocks = mio.function_delaunay_presentation(points, grades, degree=degree, verbose=verbose,clear=clear)
3238
+ return multipers.Slicer(blocks, backend=backend, vineyard=vineyard)
3239
+
3240
+ def slicer2blocks(slicer, int degree = -1, bool reverse=True):
3241
+ """
3242
+ Convert any slicer to the block format a.k.a. scc format for python
3243
+ """
3244
+ dims = slicer.get_dimensions()
3245
+ num_empty_blocks_to_add = 1 if degree == -1 else dims.min()-degree +1
3246
+ _,counts = np.unique(dims, return_counts=True, )
3247
+ indices = np.concatenate([[0],counts], dtype=np.int32).cumsum()
3248
+ filtration_values = slicer.get_filtrations()
3249
+ filtration_values = [filtration_values[indices[i]:indices[i+1]] for i in range(len(indices)-1)]
3250
+ boundaries = slicer.get_boundaries()
3251
+ boundaries = [boundaries[indices[i]:indices[i+1]] for i in range(len(indices)-1)]
3252
+ shift = np.concatenate([[0], indices], dtype=np.int32)
3253
+ boundaries = [tuple(np.asarray(x-s, dtype=np.int32) for x in block) for s,block in zip(shift,boundaries)]
3254
+ blocks = [tuple((f,tuple(b))) for b,f in zip(boundaries,filtration_values)]
3255
+ blocks = ([(np.empty((0,)),[])]*num_empty_blocks_to_add) + blocks
3256
+ if reverse:
3257
+ blocks.reverse()
3258
+ return blocks
3259
+
3260
+ def minimal_presentation(
3261
+ slicer,
3262
+ int degree = 1,
3263
+ list[int] degrees=[],
3264
+ str backend:Literal["mpfree", "2pac"]="mpfree",
3265
+ str slicer_backend:Literal["matrix","clement","graph"]="matrix",
3266
+ bool vineyard=True,
3267
+ id :Optional[str] =None,
3268
+ dtype=None,
3269
+ **minpres_kwargs
3270
+ ):
3271
+ """
3272
+ Computes a minimal presentation of the multifiltered complex given by the slicer,
3273
+ and returns it as a slicer.
3274
+ Only works for mpfree for the moment.
3275
+ """
3276
+ if len(degrees)>0:
3277
+ return tuple(minimal_presentation(slicer, degree=d, backend=backend, slicer_backend=slicer_backend, vineyard=vineyard, id=id, **minpres_kwargs) for d in degrees)
3278
+ filtration_grid = slicer.filtration_grid if slicer.is_squeezed else None
3279
+ blocks = to_blocks(slicer)
3280
+ if id is None:
3281
+ id = str(threading.get_native_id())
3282
+ if dtype is None:
3283
+ dtype = slicer.dtype
3284
+ mio._init_external_softwares(requires=[backend])
3285
+ mio.scc2disk(blocks,path=mio.input_path+id, strip_comments=True)
3286
+ dimension = len(blocks) -2 - degree # latest = L-1, which is empty, -1 for degree 0, -2 for degree 1 etc.
3287
+ new_blocks = mio.scc_reduce_from_str(path=mio.input_path+id,dimension=dimension, backend=backend, **minpres_kwargs)
3288
+ new_slicer = multipers.Slicer(new_blocks,backend=slicer_backend, vineyard=vineyard, dtype=dtype)
3289
+ if filtration_grid is not None:
3290
+ new_slicer.filtration_grid = filtration_grid
3291
+ return new_slicer
3292
+
3293
+
3294
+ def to_simplextree(s:Slicer_type, max_dim:int=-1):
3295
+ """
3296
+ Turns a --simplicial-- slicer into a simplextree.
3297
+
3298
+ Warning: Won't work for non-simplicial complexes,
3299
+ i.e., complexes $K$ not satisfying
3300
+ $\forall \sigma \in K,\, \mathrm{dim}(\sigma) = |\partial \sigma|-1$
3301
+ """
3302
+ dims = s.get_dimensions()
3303
+ assert np.all(dims[:-1] <= dims[1:]), "Dims is not sorted."
3304
+ idx = np.searchsorted(dims, np.unique(dims))
3305
+ idx = np.concatenate([idx, [dims.shape[0]]])
3306
+ if max_dim>=0:
3307
+ idx = idx[:max_dim+2]
3308
+
3309
+ cdef vector[vector[int]] boundaries_ = s.get_boundaries()
3310
+ cdef int a
3311
+ cdef int b
3312
+ if len(idx)>2:
3313
+ a = idx[2]
3314
+ b = idx[-1]
3315
+ for i in range(a, b):
3316
+ boundaries_[i] = np.unique(np.concatenate([boundaries_[k] for k in boundaries_[i]]))
3317
+ boundaries = [np.asarray(boundaries_[idx[i]:idx[i+1]]).T for i in range(len(idx)-1)]
3318
+ boundaries[0] = np.arange(boundaries[0].shape[1])[None,:]
3319
+ filtrations = s.get_filtrations()
3320
+ num_parameters = s.num_parameters
3321
+ filtrations=tuple(filtrations[idx[i]:idx[i+1]] for i in range(len(idx)-1)) # TODO : optimize ?
3322
+ st = SimplexTreeMulti(num_parameters = num_parameters, dtype = s.dtype)
3323
+ for i in range(len(filtrations)):
3324
+ if s.is_kcritical:
3325
+ for f in filtrations[i]:
3326
+ st.insert(np.asarray(boundaries[i], dtype = np.int32),np.asarray(f, dtype=s.dtype))
3327
+ else:
3328
+ st.insert_batch(np.asarray(boundaries[i], dtype= np.int32),np.asarray(filtrations[i], dtype=s.dtype))
3329
+ return st
3330
+
3331
+
3332
+ def is_slicer(object input)->bool:
3333
+ return (False
3334
+ or isinstance(input, _SlicerClement)
3335
+ or isinstance(input, _SlicerVineGraph)
3336
+ or isinstance(input, _SlicerVineSimplicial)
3337
+ or isinstance(input, _SlicerNoVineSimplicial)
3338
+ or isinstance(input, _KSlicer0_vine_i32)
3339
+ or isinstance(input, _KSlicer0_vine_f32)
3340
+ or isinstance(input, _KSlicer0_vine_f64)
3341
+ or isinstance(input, _Slicer0_vine_i32)
3342
+ or isinstance(input, _Slicer0_vine_f32)
3343
+ or isinstance(input, _Slicer0_vine_f64)
3344
+ or isinstance(input, _KSlicer0_i32)
3345
+ or isinstance(input, _KSlicer0_f32)
3346
+ or isinstance(input, _KSlicer0_f64)
3347
+ or isinstance(input, _Slicer0_i32)
3348
+ or isinstance(input, _Slicer0_f32)
3349
+ or isinstance(input, _Slicer0_f64)
3350
+ )
3351
+
3352
+
3353
+ def to_blocks(input):
3354
+ """
3355
+ Converts input to blocks, if possible.
3356
+ """
3357
+ if is_slicer(input):
3358
+ return slicer2blocks(input)
3359
+ if isinstance(input, list) or isinstance(input, tuple):
3360
+ return input
3361
+ if isinstance(input, multipers.simplex_tree_multi.SimplexTreeMulti):
3362
+ return mio.simplextree2scc(input)
3363
+ if isinstance(input, str) or isinstance(input, os.PathLike):
3364
+ return mio.scc_parser(input)
3365
+ raise ValueError("Input cannot be converted to blocks.")
3366
+
3367
+
3368
+
3369
+ cdef dict[tuple[bool,bool,type],object] slicer_dict = {
3370
+ (True, False, np.dtype(np.float32), ""): _SlicerClement,
3371
+ (True, True, np.dtype(np.int32), "INTRUSIVE_SET"): _KSlicer0_vine_i32,
3372
+ (True, True, np.dtype(np.float32), "INTRUSIVE_SET"): _KSlicer0_vine_f32,
3373
+ (True, True, np.dtype(np.float64), "INTRUSIVE_SET"): _KSlicer0_vine_f64,
3374
+ (True, False, np.dtype(np.int32), "INTRUSIVE_SET"): _Slicer0_vine_i32,
3375
+ (True, False, np.dtype(np.float32), "INTRUSIVE_SET"): _Slicer0_vine_f32,
3376
+ (True, False, np.dtype(np.float64), "INTRUSIVE_SET"): _Slicer0_vine_f64,
3377
+ (False, True, np.dtype(np.int32), "INTRUSIVE_SET"): _KSlicer0_i32,
3378
+ (False, True, np.dtype(np.float32), "INTRUSIVE_SET"): _KSlicer0_f32,
3379
+ (False, True, np.dtype(np.float64), "INTRUSIVE_SET"): _KSlicer0_f64,
3380
+ (False, False, np.dtype(np.int32), "INTRUSIVE_SET"): _Slicer0_i32,
3381
+ (False, False, np.dtype(np.float32), "INTRUSIVE_SET"): _Slicer0_f32,
3382
+ (False, False, np.dtype(np.float64), "INTRUSIVE_SET"): _Slicer0_f64,
3383
+ }
3384
+
3385
+ def get_matrix_slicer(bool is_vineyard, bool is_k_critical, type dtype, str col):
3386
+ slicer = slicer_dict.get((is_vineyard, is_k_critical, np.dtype(dtype), col), None)
3387
+ if slicer is None:
3388
+ raise ValueError(f"Unimplemented combo for Matrix : {is_vineyard=}, {is_k_critical=}, {dtype=}")
3389
+ return slicer
3390
+
3391
+
3392
+
3393
+