multipers 2.3.3b6__cp313-cp313-macosx_11_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 (183) hide show
  1. multipers/.dylibs/libc++.1.0.dylib +0 -0
  2. multipers/.dylibs/libtbb.12.16.dylib +0 -0
  3. multipers/__init__.py +33 -0
  4. multipers/_signed_measure_meta.py +453 -0
  5. multipers/_slicer_meta.py +211 -0
  6. multipers/array_api/__init__.py +45 -0
  7. multipers/array_api/numpy.py +41 -0
  8. multipers/array_api/torch.py +58 -0
  9. multipers/data/MOL2.py +458 -0
  10. multipers/data/UCR.py +18 -0
  11. multipers/data/__init__.py +1 -0
  12. multipers/data/graphs.py +466 -0
  13. multipers/data/immuno_regions.py +27 -0
  14. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  15. multipers/data/pytorch2simplextree.py +91 -0
  16. multipers/data/shape3d.py +101 -0
  17. multipers/data/synthetic.py +113 -0
  18. multipers/distances.py +202 -0
  19. multipers/filtration_conversions.pxd +229 -0
  20. multipers/filtration_conversions.pxd.tp +84 -0
  21. multipers/filtrations/__init__.py +18 -0
  22. multipers/filtrations/density.py +574 -0
  23. multipers/filtrations/filtrations.py +361 -0
  24. multipers/filtrations.pxd +224 -0
  25. multipers/function_rips.cpython-313-darwin.so +0 -0
  26. multipers/function_rips.pyx +105 -0
  27. multipers/grids.cpython-313-darwin.so +0 -0
  28. multipers/grids.pyx +433 -0
  29. multipers/gudhi/Persistence_slices_interface.h +132 -0
  30. multipers/gudhi/Simplex_tree_interface.h +239 -0
  31. multipers/gudhi/Simplex_tree_multi_interface.h +551 -0
  32. multipers/gudhi/cubical_to_boundary.h +59 -0
  33. multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -0
  34. multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -0
  35. multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -0
  36. multipers/gudhi/gudhi/Debug_utils.h +45 -0
  37. multipers/gudhi/gudhi/Fields/Multi_field.h +484 -0
  38. multipers/gudhi/gudhi/Fields/Multi_field_operators.h +455 -0
  39. multipers/gudhi/gudhi/Fields/Multi_field_shared.h +450 -0
  40. multipers/gudhi/gudhi/Fields/Multi_field_small.h +531 -0
  41. multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +507 -0
  42. multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +531 -0
  43. multipers/gudhi/gudhi/Fields/Z2_field.h +355 -0
  44. multipers/gudhi/gudhi/Fields/Z2_field_operators.h +376 -0
  45. multipers/gudhi/gudhi/Fields/Zp_field.h +420 -0
  46. multipers/gudhi/gudhi/Fields/Zp_field_operators.h +400 -0
  47. multipers/gudhi/gudhi/Fields/Zp_field_shared.h +418 -0
  48. multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
  49. multipers/gudhi/gudhi/Matrix.h +2107 -0
  50. multipers/gudhi/gudhi/Multi_critical_filtration.h +1038 -0
  51. multipers/gudhi/gudhi/Multi_persistence/Box.h +174 -0
  52. multipers/gudhi/gudhi/Multi_persistence/Line.h +282 -0
  53. multipers/gudhi/gudhi/Off_reader.h +173 -0
  54. multipers/gudhi/gudhi/One_critical_filtration.h +1441 -0
  55. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +769 -0
  56. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +686 -0
  57. multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +842 -0
  58. multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1350 -0
  59. multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1105 -0
  60. multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +859 -0
  61. multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +910 -0
  62. multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +139 -0
  63. multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +230 -0
  64. multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +211 -0
  65. multipers/gudhi/gudhi/Persistence_matrix/boundary_cell_position_to_id_mapper.h +60 -0
  66. multipers/gudhi/gudhi/Persistence_matrix/boundary_face_position_to_id_mapper.h +60 -0
  67. multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +136 -0
  68. multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +190 -0
  69. multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +616 -0
  70. multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +150 -0
  71. multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +106 -0
  72. multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +219 -0
  73. multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +327 -0
  74. multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1140 -0
  75. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +934 -0
  76. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +934 -0
  77. multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +980 -0
  78. multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1092 -0
  79. multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +192 -0
  80. multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +921 -0
  81. multipers/gudhi/gudhi/Persistence_matrix/columns/small_vector_column.h +1093 -0
  82. multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +1012 -0
  83. multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1244 -0
  84. multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +186 -0
  85. multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +164 -0
  86. multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +156 -0
  87. multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +376 -0
  88. multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +540 -0
  89. multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -0
  90. multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -0
  91. multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -0
  92. multipers/gudhi/gudhi/Persistent_cohomology.h +745 -0
  93. multipers/gudhi/gudhi/Points_off_io.h +171 -0
  94. multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
  95. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +463 -0
  96. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
  97. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +106 -0
  98. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
  99. multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -0
  100. multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -0
  101. multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +62 -0
  102. multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +157 -0
  103. multipers/gudhi/gudhi/Simplex_tree.h +2794 -0
  104. multipers/gudhi/gudhi/Simplex_tree_multi.h +152 -0
  105. multipers/gudhi/gudhi/distance_functions.h +62 -0
  106. multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
  107. multipers/gudhi/gudhi/persistence_interval.h +253 -0
  108. multipers/gudhi/gudhi/persistence_matrix_options.h +170 -0
  109. multipers/gudhi/gudhi/reader_utils.h +367 -0
  110. multipers/gudhi/mma_interface_coh.h +256 -0
  111. multipers/gudhi/mma_interface_h0.h +223 -0
  112. multipers/gudhi/mma_interface_matrix.h +293 -0
  113. multipers/gudhi/naive_merge_tree.h +536 -0
  114. multipers/gudhi/scc_io.h +310 -0
  115. multipers/gudhi/truc.h +1403 -0
  116. multipers/io.cpython-313-darwin.so +0 -0
  117. multipers/io.pyx +644 -0
  118. multipers/ml/__init__.py +0 -0
  119. multipers/ml/accuracies.py +90 -0
  120. multipers/ml/invariants_with_persistable.py +79 -0
  121. multipers/ml/kernels.py +176 -0
  122. multipers/ml/mma.py +713 -0
  123. multipers/ml/one.py +472 -0
  124. multipers/ml/point_clouds.py +352 -0
  125. multipers/ml/signed_measures.py +1589 -0
  126. multipers/ml/sliced_wasserstein.py +461 -0
  127. multipers/ml/tools.py +113 -0
  128. multipers/mma_structures.cpython-313-darwin.so +0 -0
  129. multipers/mma_structures.pxd +128 -0
  130. multipers/mma_structures.pyx +2786 -0
  131. multipers/mma_structures.pyx.tp +1094 -0
  132. multipers/multi_parameter_rank_invariant/diff_helpers.h +84 -0
  133. multipers/multi_parameter_rank_invariant/euler_characteristic.h +97 -0
  134. multipers/multi_parameter_rank_invariant/function_rips.h +322 -0
  135. multipers/multi_parameter_rank_invariant/hilbert_function.h +769 -0
  136. multipers/multi_parameter_rank_invariant/persistence_slices.h +148 -0
  137. multipers/multi_parameter_rank_invariant/rank_invariant.h +369 -0
  138. multipers/multiparameter_edge_collapse.py +41 -0
  139. multipers/multiparameter_module_approximation/approximation.h +2330 -0
  140. multipers/multiparameter_module_approximation/combinatory.h +129 -0
  141. multipers/multiparameter_module_approximation/debug.h +107 -0
  142. multipers/multiparameter_module_approximation/euler_curves.h +0 -0
  143. multipers/multiparameter_module_approximation/format_python-cpp.h +286 -0
  144. multipers/multiparameter_module_approximation/heap_column.h +238 -0
  145. multipers/multiparameter_module_approximation/images.h +79 -0
  146. multipers/multiparameter_module_approximation/list_column.h +174 -0
  147. multipers/multiparameter_module_approximation/list_column_2.h +232 -0
  148. multipers/multiparameter_module_approximation/ru_matrix.h +347 -0
  149. multipers/multiparameter_module_approximation/set_column.h +135 -0
  150. multipers/multiparameter_module_approximation/structure_higher_dim_barcode.h +36 -0
  151. multipers/multiparameter_module_approximation/unordered_set_column.h +166 -0
  152. multipers/multiparameter_module_approximation/utilities.h +403 -0
  153. multipers/multiparameter_module_approximation/vector_column.h +223 -0
  154. multipers/multiparameter_module_approximation/vector_matrix.h +331 -0
  155. multipers/multiparameter_module_approximation/vineyards.h +464 -0
  156. multipers/multiparameter_module_approximation/vineyards_trajectories.h +649 -0
  157. multipers/multiparameter_module_approximation.cpython-313-darwin.so +0 -0
  158. multipers/multiparameter_module_approximation.pyx +235 -0
  159. multipers/pickle.py +90 -0
  160. multipers/plots.py +456 -0
  161. multipers/point_measure.cpython-313-darwin.so +0 -0
  162. multipers/point_measure.pyx +395 -0
  163. multipers/simplex_tree_multi.cpython-313-darwin.so +0 -0
  164. multipers/simplex_tree_multi.pxd +134 -0
  165. multipers/simplex_tree_multi.pyx +10840 -0
  166. multipers/simplex_tree_multi.pyx.tp +2009 -0
  167. multipers/slicer.cpython-313-darwin.so +0 -0
  168. multipers/slicer.pxd +3034 -0
  169. multipers/slicer.pxd.tp +234 -0
  170. multipers/slicer.pyx +20481 -0
  171. multipers/slicer.pyx.tp +1088 -0
  172. multipers/tensor/tensor.h +672 -0
  173. multipers/tensor.pxd +13 -0
  174. multipers/test.pyx +44 -0
  175. multipers/tests/__init__.py +62 -0
  176. multipers/torch/__init__.py +1 -0
  177. multipers/torch/diff_grids.py +240 -0
  178. multipers/torch/rips_density.py +310 -0
  179. multipers-2.3.3b6.dist-info/METADATA +128 -0
  180. multipers-2.3.3b6.dist-info/RECORD +183 -0
  181. multipers-2.3.3b6.dist-info/WHEEL +6 -0
  182. multipers-2.3.3b6.dist-info/licenses/LICENSE +21 -0
  183. multipers-2.3.3b6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,113 @@
1
+ import numpy as np
2
+
3
+
4
+ def noisy_annulus(
5
+ n1: int = 1000,
6
+ n2: int = 200,
7
+ r1: float = 1,
8
+ r2: float = 2,
9
+ dim: int = 2,
10
+ center: np.ndarray | list | None = None,
11
+ **kwargs
12
+ ) -> np.ndarray:
13
+ """Generates a noisy annulus dataset.
14
+
15
+ Parameters
16
+ ----------
17
+ r1 : float.
18
+ Lower radius of the annulus.
19
+ r2 : float.
20
+ Upper radius of the annulus.
21
+ n1 : int
22
+ Number of points in the annulus.
23
+ n2 : int
24
+ Number of points in the square.
25
+ dim : int
26
+ Dimension of the annulus.
27
+ center: list or array
28
+ center of the annulus.
29
+
30
+ Returns
31
+ -------
32
+ numpy array
33
+ Dataset. size : (n1+n2) x dim
34
+
35
+ """
36
+ theta = np.random.normal(size=(n1, dim))
37
+ theta /= np.linalg.norm(theta, axis=1)[:, None]
38
+ rs = np.sqrt(np.random.uniform(low=r1**2, high=r2**2, size=n1))
39
+ annulus = rs[:, None] * theta
40
+ if center is not None:
41
+ annulus += np.array(center)
42
+ diffuse_noise = np.random.uniform(size=(n2, dim), low=-1.1 * r2, high=1.1 * r2)
43
+ if center is not None:
44
+ diffuse_noise += np.array(center)
45
+ return np.vstack([annulus, diffuse_noise])
46
+
47
+
48
+ def three_annulus(num_pts: int = 500, num_outliers: int = 500):
49
+ q, r = divmod(num_pts, 3)
50
+ num_pts_1, num_pts_2, num_pts_3 = q, q + (r > 0), q + (r > 1)
51
+ X = np.block(
52
+ [
53
+ [np.random.uniform(low=-2, high=2, size=(num_outliers, 2))],
54
+ [
55
+ np.array(
56
+ noisy_annulus(
57
+ r1=0.6,
58
+ r2=0.9,
59
+ n1=num_pts_1,
60
+ n2=0,
61
+ center=[1, -0.2],
62
+ )
63
+ )
64
+ ],
65
+ [
66
+ np.array(
67
+ noisy_annulus(
68
+ r1=0.4,
69
+ r2=0.55,
70
+ n1=num_pts_2,
71
+ n2=0,
72
+ center=[-1.2, -1],
73
+ )
74
+ )
75
+ ],
76
+ [
77
+ np.array(
78
+ noisy_annulus(
79
+ r1=0.3,
80
+ r2=0.4,
81
+ n1=num_pts_3,
82
+ n2=0,
83
+ center=[-0.7, 1.1],
84
+ )
85
+ )
86
+ ],
87
+ ]
88
+ )
89
+ return X
90
+
91
+
92
+ def orbit(n: int = 1000, r: float = 1.0, x0=[]):
93
+ point_list = []
94
+ if len(x0) != 2:
95
+ x, y = np.random.uniform(size=2)
96
+ else:
97
+ x, y = x0
98
+ point_list.append([x, y])
99
+ for _ in range(n - 1):
100
+ x = (x + r * y * (1 - y)) % 1
101
+ y = (y + r * x * (1 - x)) % 1
102
+ point_list.append([x, y])
103
+ return np.asarray(point_list, dtype=float)
104
+
105
+
106
+ def get_orbit5k(num_pts=1000, num_data=5000):
107
+ from sklearn.preprocessing import LabelEncoder
108
+
109
+ rs = [2.5, 3.5, 4, 4.1, 4.3]
110
+ labels = np.random.choice(rs, size=num_data, replace=True)
111
+ X = [orbit(n=num_pts, r=r) for r in labels]
112
+ labels = LabelEncoder().fit_transform(labels)
113
+ return X, labels
multipers/distances.py ADDED
@@ -0,0 +1,202 @@
1
+ import numpy as np
2
+ import ot
3
+
4
+ from multipers.mma_structures import PyMultiDiagrams_type
5
+ from multipers.multiparameter_module_approximation import PyModule_type
6
+ from multipers.simplex_tree_multi import SimplexTreeMulti_type
7
+
8
+
9
+ def sm2diff(sm1, sm2, threshold=None):
10
+ pts = sm1[0]
11
+ dtype = pts.dtype
12
+ if isinstance(pts, np.ndarray):
13
+
14
+ def backend_concatenate(a, b):
15
+ return np.concatenate([a, b], axis=0, dtype=dtype)
16
+
17
+ def backend_tensor(x):
18
+ return np.asarray(x, dtype=int)
19
+
20
+ else:
21
+ import torch
22
+
23
+ assert isinstance(pts, torch.Tensor), "Invalid backend. Numpy or torch."
24
+
25
+ def backend_concatenate(a, b):
26
+ return torch.concatenate([a, b], dim=0)
27
+
28
+ def backend_tensor(x):
29
+ return torch.tensor(x).type(torch.int)
30
+
31
+ pts1, w1 = sm1
32
+ pts2, w2 = sm2
33
+ ## TODO: optimize this
34
+ pos_indices1 = backend_tensor(
35
+ [i for i, w in enumerate(w1) for _ in range(w) if w > 0]
36
+ )
37
+ pos_indices2 = backend_tensor(
38
+ [i for i, w in enumerate(w2) for _ in range(w) if w > 0]
39
+ )
40
+ neg_indices1 = backend_tensor(
41
+ [i for i, w in enumerate(w1) for _ in range(-w) if w < 0]
42
+ )
43
+ neg_indices2 = backend_tensor(
44
+ [i for i, w in enumerate(w2) for _ in range(-w) if w < 0]
45
+ )
46
+ x = backend_concatenate(pts1[pos_indices1], pts2[neg_indices2])
47
+ y = backend_concatenate(pts1[neg_indices1], pts2[pos_indices2])
48
+ if threshold is not None:
49
+ x[x>threshold]=threshold
50
+ y[y>threshold]=threshold
51
+ return x, y
52
+
53
+
54
+ def sm_distance(
55
+ sm1: tuple,
56
+ sm2: tuple,
57
+ reg: float = 0,
58
+ reg_m: float = 0,
59
+ numItermax: int = 10000,
60
+ p: float = 1,
61
+ threshold=None,
62
+ ):
63
+ """
64
+ Computes the wasserstein distances between two signed measures,
65
+ of the form
66
+ - (pts,weights)
67
+ with
68
+ - pts : (num_pts, dim) float array
69
+ - weights : (num_pts,) int array
70
+
71
+ Regularisation:
72
+ - sinkhorn if reg != 0
73
+ - sinkhorn unbalanced if reg_m != 0
74
+ """
75
+ x, y = sm2diff(sm1, sm2, threshold=threshold)
76
+ loss = ot.dist(
77
+ x, y, metric="sqeuclidean", p=p
78
+ ) # only euc + sqeuclidian are implemented in pot for the moment with torch backend # TODO : check later
79
+ if isinstance(x, np.ndarray):
80
+ empty_tensor = np.array([]) # uniform weights
81
+ else:
82
+ import torch
83
+
84
+ assert isinstance(x, torch.Tensor), "Unimplemented backend."
85
+ empty_tensor = torch.tensor([]) # uniform weights
86
+
87
+ if reg == 0:
88
+ return ot.lp.emd2(empty_tensor, empty_tensor, M=loss) * len(x)
89
+ if reg_m == 0:
90
+ return ot.sinkhorn2(
91
+ a=empty_tensor, b=empty_tensor, M=loss, reg=reg, numItermax=numItermax
92
+ )
93
+ return ot.sinkhorn_unbalanced2(
94
+ a=empty_tensor,
95
+ b=empty_tensor,
96
+ M=loss,
97
+ reg=reg,
98
+ reg_m=reg_m,
99
+ numItermax=numItermax,
100
+ )
101
+ # return ot.sinkhorn2(a=onesx,b=onesy,M=loss,reg=reg, numItermax=numItermax)
102
+ # return ot.bregman.empirical_sinkhorn2(x,y,reg=reg)
103
+
104
+
105
+ def estimate_matching(b1: PyMultiDiagrams_type, b2: PyMultiDiagrams_type):
106
+ assert len(b1) == len(b2)
107
+ from gudhi.bottleneck import bottleneck_distance
108
+
109
+ def get_bc(b: PyMultiDiagrams_type, i: int) -> np.ndarray:
110
+ temp = b[i].get_points()
111
+ out = (
112
+ np.array(temp)[:, :, 0] if len(temp) > 0 else np.empty((0, 2))
113
+ ) # GUDHI FIX
114
+ return out
115
+
116
+ return max(
117
+ (bottleneck_distance(get_bc(b1, i), get_bc(b2, i)) for i in range(len(b1)))
118
+ )
119
+
120
+
121
+ # Functions to estimate precision
122
+ def estimate_error(
123
+ st: SimplexTreeMulti_type,
124
+ module: PyModule_type,
125
+ degree: int,
126
+ nlines: int = 100,
127
+ verbose: bool = False,
128
+ ):
129
+ """
130
+ Given an MMA SimplexTree and PyModule, estimates the bottleneck distance using barcodes given by gudhi.
131
+
132
+ Parameters
133
+ ----------
134
+ - st:SimplexTree
135
+ The simplextree representing the n-filtered complex. Used to define the gudhi simplextrees on different lines.
136
+ - module:PyModule
137
+ The module on which to estimate approximation error, w.r.t. the original simplextree st.
138
+ - degree:int
139
+ The homology degree to consider
140
+
141
+ Returns
142
+ -------
143
+ - float:The estimation of the matching distance, i.e., the maximum of the sampled bottleneck distances.
144
+
145
+ """
146
+ from time import perf_counter
147
+
148
+ parameter = 0
149
+
150
+ def _get_bc_ST(st, basepoint, degree: int):
151
+ """
152
+ Slices an mma simplextree to a gudhi simplextree, and compute its persistence on the diagonal line crossing the given basepoint.
153
+ """
154
+ gst = st.project_on_line(
155
+ basepoint=basepoint, parameter=parameter
156
+ ) # we consider only the 1rst coordinate (as )
157
+ gst.compute_persistence()
158
+ return gst.persistence_intervals_in_dimension(degree)
159
+
160
+ from gudhi.bottleneck import bottleneck_distance
161
+
162
+ low, high = module.get_box()
163
+ nfiltration = len(low)
164
+ basepoints = np.random.uniform(low=low, high=high, size=(nlines, nfiltration))
165
+ # barcodes from module
166
+ print("Computing mma barcodes...", flush=1, end="") if verbose else None
167
+ time = perf_counter()
168
+ bcs_from_mod = module.barcodes(degree=degree, basepoints=basepoints).get_points()
169
+ print(f"Done. {perf_counter() - time}s.") if verbose else None
170
+
171
+ def clean(dgm):
172
+ return np.array(
173
+ [
174
+ [birth[parameter], death[parameter]]
175
+ for birth, death in dgm
176
+ if len(birth) > 0 and birth[parameter] != np.inf
177
+ ]
178
+ )
179
+
180
+ bcs_from_mod = [
181
+ clean(dgm) for dgm in bcs_from_mod
182
+ ] # we only consider the 1st coordinate of the barcode
183
+ # Computes gudhi barcodes
184
+ from tqdm import tqdm
185
+
186
+ bcs_from_gudhi = [
187
+ _get_bc_ST(st, basepoint=basepoint, degree=degree)
188
+ for basepoint in tqdm(
189
+ basepoints, disable=not verbose, desc="Computing gudhi barcodes"
190
+ )
191
+ ]
192
+ return max(
193
+ (
194
+ bottleneck_distance(a, b)
195
+ for a, b in tqdm(
196
+ zip(bcs_from_mod, bcs_from_gudhi),
197
+ disable=not verbose,
198
+ total=nlines,
199
+ desc="Computing bottleneck distances",
200
+ )
201
+ )
202
+ )
@@ -0,0 +1,229 @@
1
+
2
+ # Python to C++ conversions
3
+ from multipers.filtrations cimport One_critical_filtration,Multi_critical_filtration
4
+ from libcpp.vector cimport vector
5
+ from libcpp cimport bool
6
+ cimport numpy as cnp
7
+ import numpy as np
8
+ from libc.stdint cimport int32_t, int64_t
9
+ from cython.operator cimport dereference
10
+ ###### ------------------- PY TO CPP
11
+ #### ----------
12
+
13
+ cdef inline Multi_critical_filtration[int32_t] _py2kc_i32(int32_t[:,:] filtrations) noexcept nogil:
14
+ # cdef int32_t[:,:] filtrations = np.asarray(filtrations_, dtype=np.int32)
15
+ cdef Multi_critical_filtration[int32_t] out
16
+ out.set_num_generators(filtrations.shape[0])
17
+ for i in range(filtrations.shape[0]):
18
+ out[i].resize(filtrations.shape[1])
19
+ for j in range(filtrations.shape[1]):
20
+ out[i][j] = filtrations[i,j]
21
+ out.simplify()
22
+ return out
23
+
24
+ cdef inline One_critical_filtration[int32_t] _py21c_i32(int32_t[:] filtration) noexcept nogil:
25
+ # cdef int32_t[:] filtration = np.asarray(filtration_, dtype=np.int32)
26
+ cdef One_critical_filtration[int32_t] out = One_critical_filtration[int32_t](0)
27
+ out.reserve(len(filtration))
28
+ for i in range(len(filtration)):
29
+ out.push_back(filtration[i])
30
+ return out
31
+
32
+
33
+ cdef inline vector[One_critical_filtration[int32_t]] _py2v1c_i32(int32_t[:,:] filtrations) noexcept nogil:
34
+ # cdef int32_t[:,:] filtrations = np.asarray(filtrations_, dtype=np.int32)
35
+ cdef vector[One_critical_filtration[int32_t]] out
36
+ out.reserve(filtrations.shape[0])
37
+ for i in range(filtrations.shape[0]):
38
+ out.push_back(_py21c_i32(filtrations[i,:]))
39
+ return out
40
+
41
+
42
+ ###### ------------------- CPP to PY
43
+
44
+
45
+ ## CYTHON BUG: using tuples here will cause some weird issues.
46
+ cdef inline _ff21cview_i32(One_critical_filtration[int32_t]* x, bool copy=False, int duplicate=0):
47
+ cdef Py_ssize_t num_parameters = dereference(x).num_parameters()
48
+ if copy and duplicate and not dereference(x).is_finite():
49
+ return np.full(shape=duplicate, fill_value=dereference(x)[0])
50
+ cdef int32_t[:] x_view = <int32_t[:num_parameters]>(&(dereference(x)[0]))
51
+ return np.array(x_view) if copy else np.asarray(x_view)
52
+
53
+ cdef inline _ff2kcview_i32(Multi_critical_filtration[int32_t]* x, bool copy=False, int duplicate=0):
54
+ cdef Py_ssize_t k = dereference(x).num_generators()
55
+ return [_ff21cview_i32(&(dereference(x)[i]), copy=copy, duplicate=duplicate) for i in range(k)]
56
+
57
+
58
+ cdef inline _vff21cview_i32(vector[One_critical_filtration[int32_t]]& x, bool copy = False, int duplicate=0):
59
+ cdef Py_ssize_t num_stuff = x.size()
60
+ return [_ff21cview_i32(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
61
+
62
+ cdef inline _vff2kcview_i32(vector[Multi_critical_filtration[int32_t]]& x, bool copy = False, int duplicate=0):
63
+ cdef Py_ssize_t num_stuff = x.size()
64
+ return [_ff2kcview_i32(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
65
+ ###### ------------------- PY TO CPP
66
+ #### ----------
67
+
68
+ cdef inline Multi_critical_filtration[int64_t] _py2kc_i64(int64_t[:,:] filtrations) noexcept nogil:
69
+ # cdef int64_t[:,:] filtrations = np.asarray(filtrations_, dtype=np.int64)
70
+ cdef Multi_critical_filtration[int64_t] out
71
+ out.set_num_generators(filtrations.shape[0])
72
+ for i in range(filtrations.shape[0]):
73
+ out[i].resize(filtrations.shape[1])
74
+ for j in range(filtrations.shape[1]):
75
+ out[i][j] = filtrations[i,j]
76
+ out.simplify()
77
+ return out
78
+
79
+ cdef inline One_critical_filtration[int64_t] _py21c_i64(int64_t[:] filtration) noexcept nogil:
80
+ # cdef int64_t[:] filtration = np.asarray(filtration_, dtype=np.int64)
81
+ cdef One_critical_filtration[int64_t] out = One_critical_filtration[int64_t](0)
82
+ out.reserve(len(filtration))
83
+ for i in range(len(filtration)):
84
+ out.push_back(filtration[i])
85
+ return out
86
+
87
+
88
+ cdef inline vector[One_critical_filtration[int64_t]] _py2v1c_i64(int64_t[:,:] filtrations) noexcept nogil:
89
+ # cdef int64_t[:,:] filtrations = np.asarray(filtrations_, dtype=np.int64)
90
+ cdef vector[One_critical_filtration[int64_t]] out
91
+ out.reserve(filtrations.shape[0])
92
+ for i in range(filtrations.shape[0]):
93
+ out.push_back(_py21c_i64(filtrations[i,:]))
94
+ return out
95
+
96
+
97
+ ###### ------------------- CPP to PY
98
+
99
+
100
+ ## CYTHON BUG: using tuples here will cause some weird issues.
101
+ cdef inline _ff21cview_i64(One_critical_filtration[int64_t]* x, bool copy=False, int duplicate=0):
102
+ cdef Py_ssize_t num_parameters = dereference(x).num_parameters()
103
+ if copy and duplicate and not dereference(x).is_finite():
104
+ return np.full(shape=duplicate, fill_value=dereference(x)[0])
105
+ cdef int64_t[:] x_view = <int64_t[:num_parameters]>(&(dereference(x)[0]))
106
+ return np.array(x_view) if copy else np.asarray(x_view)
107
+
108
+ cdef inline _ff2kcview_i64(Multi_critical_filtration[int64_t]* x, bool copy=False, int duplicate=0):
109
+ cdef Py_ssize_t k = dereference(x).num_generators()
110
+ return [_ff21cview_i64(&(dereference(x)[i]), copy=copy, duplicate=duplicate) for i in range(k)]
111
+
112
+
113
+ cdef inline _vff21cview_i64(vector[One_critical_filtration[int64_t]]& x, bool copy = False, int duplicate=0):
114
+ cdef Py_ssize_t num_stuff = x.size()
115
+ return [_ff21cview_i64(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
116
+
117
+ cdef inline _vff2kcview_i64(vector[Multi_critical_filtration[int64_t]]& x, bool copy = False, int duplicate=0):
118
+ cdef Py_ssize_t num_stuff = x.size()
119
+ return [_ff2kcview_i64(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
120
+ ###### ------------------- PY TO CPP
121
+ #### ----------
122
+
123
+ cdef inline Multi_critical_filtration[float] _py2kc_f32(float[:,:] filtrations) noexcept nogil:
124
+ # cdef float[:,:] filtrations = np.asarray(filtrations_, dtype=np.float32)
125
+ cdef Multi_critical_filtration[float] out
126
+ out.set_num_generators(filtrations.shape[0])
127
+ for i in range(filtrations.shape[0]):
128
+ out[i].resize(filtrations.shape[1])
129
+ for j in range(filtrations.shape[1]):
130
+ out[i][j] = filtrations[i,j]
131
+ out.simplify()
132
+ return out
133
+
134
+ cdef inline One_critical_filtration[float] _py21c_f32(float[:] filtration) noexcept nogil:
135
+ # cdef float[:] filtration = np.asarray(filtration_, dtype=np.float32)
136
+ cdef One_critical_filtration[float] out = One_critical_filtration[float](0)
137
+ out.reserve(len(filtration))
138
+ for i in range(len(filtration)):
139
+ out.push_back(filtration[i])
140
+ return out
141
+
142
+
143
+ cdef inline vector[One_critical_filtration[float]] _py2v1c_f32(float[:,:] filtrations) noexcept nogil:
144
+ # cdef float[:,:] filtrations = np.asarray(filtrations_, dtype=np.float32)
145
+ cdef vector[One_critical_filtration[float]] out
146
+ out.reserve(filtrations.shape[0])
147
+ for i in range(filtrations.shape[0]):
148
+ out.push_back(_py21c_f32(filtrations[i,:]))
149
+ return out
150
+
151
+
152
+ ###### ------------------- CPP to PY
153
+
154
+
155
+ ## CYTHON BUG: using tuples here will cause some weird issues.
156
+ cdef inline _ff21cview_f32(One_critical_filtration[float]* x, bool copy=False, int duplicate=0):
157
+ cdef Py_ssize_t num_parameters = dereference(x).num_parameters()
158
+ if copy and duplicate and not dereference(x).is_finite():
159
+ return np.full(shape=duplicate, fill_value=dereference(x)[0])
160
+ cdef float[:] x_view = <float[:num_parameters]>(&(dereference(x)[0]))
161
+ return np.array(x_view) if copy else np.asarray(x_view)
162
+
163
+ cdef inline _ff2kcview_f32(Multi_critical_filtration[float]* x, bool copy=False, int duplicate=0):
164
+ cdef Py_ssize_t k = dereference(x).num_generators()
165
+ return [_ff21cview_f32(&(dereference(x)[i]), copy=copy, duplicate=duplicate) for i in range(k)]
166
+
167
+
168
+ cdef inline _vff21cview_f32(vector[One_critical_filtration[float]]& x, bool copy = False, int duplicate=0):
169
+ cdef Py_ssize_t num_stuff = x.size()
170
+ return [_ff21cview_f32(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
171
+
172
+ cdef inline _vff2kcview_f32(vector[Multi_critical_filtration[float]]& x, bool copy = False, int duplicate=0):
173
+ cdef Py_ssize_t num_stuff = x.size()
174
+ return [_ff2kcview_f32(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
175
+ ###### ------------------- PY TO CPP
176
+ #### ----------
177
+
178
+ cdef inline Multi_critical_filtration[double] _py2kc_f64(double[:,:] filtrations) noexcept nogil:
179
+ # cdef double[:,:] filtrations = np.asarray(filtrations_, dtype=np.float64)
180
+ cdef Multi_critical_filtration[double] out
181
+ out.set_num_generators(filtrations.shape[0])
182
+ for i in range(filtrations.shape[0]):
183
+ out[i].resize(filtrations.shape[1])
184
+ for j in range(filtrations.shape[1]):
185
+ out[i][j] = filtrations[i,j]
186
+ out.simplify()
187
+ return out
188
+
189
+ cdef inline One_critical_filtration[double] _py21c_f64(double[:] filtration) noexcept nogil:
190
+ # cdef double[:] filtration = np.asarray(filtration_, dtype=np.float64)
191
+ cdef One_critical_filtration[double] out = One_critical_filtration[double](0)
192
+ out.reserve(len(filtration))
193
+ for i in range(len(filtration)):
194
+ out.push_back(filtration[i])
195
+ return out
196
+
197
+
198
+ cdef inline vector[One_critical_filtration[double]] _py2v1c_f64(double[:,:] filtrations) noexcept nogil:
199
+ # cdef double[:,:] filtrations = np.asarray(filtrations_, dtype=np.float64)
200
+ cdef vector[One_critical_filtration[double]] out
201
+ out.reserve(filtrations.shape[0])
202
+ for i in range(filtrations.shape[0]):
203
+ out.push_back(_py21c_f64(filtrations[i,:]))
204
+ return out
205
+
206
+
207
+ ###### ------------------- CPP to PY
208
+
209
+
210
+ ## CYTHON BUG: using tuples here will cause some weird issues.
211
+ cdef inline _ff21cview_f64(One_critical_filtration[double]* x, bool copy=False, int duplicate=0):
212
+ cdef Py_ssize_t num_parameters = dereference(x).num_parameters()
213
+ if copy and duplicate and not dereference(x).is_finite():
214
+ return np.full(shape=duplicate, fill_value=dereference(x)[0])
215
+ cdef double[:] x_view = <double[:num_parameters]>(&(dereference(x)[0]))
216
+ return np.array(x_view) if copy else np.asarray(x_view)
217
+
218
+ cdef inline _ff2kcview_f64(Multi_critical_filtration[double]* x, bool copy=False, int duplicate=0):
219
+ cdef Py_ssize_t k = dereference(x).num_generators()
220
+ return [_ff21cview_f64(&(dereference(x)[i]), copy=copy, duplicate=duplicate) for i in range(k)]
221
+
222
+
223
+ cdef inline _vff21cview_f64(vector[One_critical_filtration[double]]& x, bool copy = False, int duplicate=0):
224
+ cdef Py_ssize_t num_stuff = x.size()
225
+ return [_ff21cview_f64(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
226
+
227
+ cdef inline _vff2kcview_f64(vector[Multi_critical_filtration[double]]& x, bool copy = False, int duplicate=0):
228
+ cdef Py_ssize_t num_stuff = x.size()
229
+ return [_ff2kcview_f64(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
@@ -0,0 +1,84 @@
1
+ {{py:
2
+
3
+ """
4
+ Filtrations conversions between python and C++
5
+ """
6
+
7
+ ## Value types : CTYPE, PYTHON_TYPE, short
8
+ value_types = [
9
+ ("int32_t", "np.int32", "i32"),
10
+ ("int64_t", "np.int64", "i64"),
11
+ ("float", "np.float32", "f32"),
12
+ ("double", "np.float64", "f64"),
13
+ ]
14
+
15
+ }}
16
+
17
+ # Python to C++ conversions
18
+ from multipers.filtrations cimport One_critical_filtration,Multi_critical_filtration
19
+ from libcpp.vector cimport vector
20
+ from libcpp cimport bool
21
+ cimport numpy as cnp
22
+ import numpy as np
23
+ from libc.stdint cimport int32_t, int64_t
24
+ from cython.operator cimport dereference
25
+
26
+ {{for CTYPE, PYTYPE, SHORT in value_types}}
27
+ ###### ------------------- PY TO CPP
28
+ #### ----------
29
+
30
+ cdef inline Multi_critical_filtration[{{CTYPE}}] _py2kc_{{SHORT}}({{CTYPE}}[:,:] filtrations) noexcept nogil:
31
+ # cdef {{CTYPE}}[:,:] filtrations = np.asarray(filtrations_, dtype={{PYTYPE}})
32
+ cdef Multi_critical_filtration[{{CTYPE}}] out
33
+ out.set_num_generators(filtrations.shape[0])
34
+ for i in range(filtrations.shape[0]):
35
+ out[i].resize(filtrations.shape[1])
36
+ for j in range(filtrations.shape[1]):
37
+ out[i][j] = filtrations[i,j]
38
+ out.simplify()
39
+ return out
40
+
41
+ cdef inline One_critical_filtration[{{CTYPE}}] _py21c_{{SHORT}}({{CTYPE}}[:] filtration) noexcept nogil:
42
+ # cdef {{CTYPE}}[:] filtration = np.asarray(filtration_, dtype={{PYTYPE}})
43
+ cdef One_critical_filtration[{{CTYPE}}] out = One_critical_filtration[{{CTYPE}}](0)
44
+ out.reserve(len(filtration))
45
+ for i in range(len(filtration)):
46
+ out.push_back(filtration[i])
47
+ return out
48
+
49
+
50
+ cdef inline vector[One_critical_filtration[{{CTYPE}}]] _py2v1c_{{SHORT}}({{CTYPE}}[:,:] filtrations) noexcept nogil:
51
+ # cdef {{CTYPE}}[:,:] filtrations = np.asarray(filtrations_, dtype={{PYTYPE}})
52
+ cdef vector[One_critical_filtration[{{CTYPE}}]] out
53
+ out.reserve(filtrations.shape[0])
54
+ for i in range(filtrations.shape[0]):
55
+ out.push_back(_py21c_{{SHORT}}(filtrations[i,:]))
56
+ return out
57
+
58
+
59
+ ###### ------------------- CPP to PY
60
+
61
+
62
+ ## CYTHON BUG: using tuples here will cause some weird issues.
63
+ cdef inline _ff21cview_{{SHORT}}(One_critical_filtration[{{CTYPE}}]* x, bool copy=False, int duplicate=0):
64
+ cdef Py_ssize_t num_parameters = dereference(x).num_parameters()
65
+ if copy and duplicate and not dereference(x).is_finite():
66
+ return np.full(shape=duplicate, fill_value=dereference(x)[0])
67
+ cdef {{CTYPE}}[:] x_view = <{{CTYPE}}[:num_parameters]>(&(dereference(x)[0]))
68
+ return np.array(x_view) if copy else np.asarray(x_view)
69
+
70
+ cdef inline _ff2kcview_{{SHORT}}(Multi_critical_filtration[{{CTYPE}}]* x, bool copy=False, int duplicate=0):
71
+ cdef Py_ssize_t k = dereference(x).num_generators()
72
+ return [_ff21cview_{{SHORT}}(&(dereference(x)[i]), copy=copy, duplicate=duplicate) for i in range(k)]
73
+
74
+
75
+ cdef inline _vff21cview_{{SHORT}}(vector[One_critical_filtration[{{CTYPE}}]]& x, bool copy = False, int duplicate=0):
76
+ cdef Py_ssize_t num_stuff = x.size()
77
+ return [_ff21cview_{{SHORT}}(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
78
+
79
+ cdef inline _vff2kcview_{{SHORT}}(vector[Multi_critical_filtration[{{CTYPE}}]]& x, bool copy = False, int duplicate=0):
80
+ cdef Py_ssize_t num_stuff = x.size()
81
+ return [_ff2kcview_{{SHORT}}(&(x[i]), copy=copy, duplicate=duplicate) for i in range(num_stuff)]
82
+
83
+ {{endfor}}
84
+
@@ -0,0 +1,18 @@
1
+ from .filtrations import (
2
+ CoreDelaunay,
3
+ Cubical,
4
+ DegreeRips,
5
+ DelaunayCodensity,
6
+ DelaunayLowerstar,
7
+ RipsCodensity,
8
+ RipsLowerstar,
9
+ )
10
+ __all__ = [
11
+ "CoreDelaunay",
12
+ "Cubical",
13
+ "DegreeRips",
14
+ "DelaunayCodensity",
15
+ "DelaunayLowerstar",
16
+ "RipsCodensity",
17
+ "RipsLowerstar",
18
+ ]