multipers 2.4.0b1__cp312-cp312-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.
Files changed (184) hide show
  1. multipers/.dylibs/libboost_timer.dylib +0 -0
  2. multipers/.dylibs/libc++.1.0.dylib +0 -0
  3. multipers/.dylibs/libtbb.12.17.dylib +0 -0
  4. multipers/__init__.py +33 -0
  5. multipers/_signed_measure_meta.py +426 -0
  6. multipers/_slicer_meta.py +231 -0
  7. multipers/array_api/__init__.py +62 -0
  8. multipers/array_api/numpy.py +124 -0
  9. multipers/array_api/torch.py +133 -0
  10. multipers/data/MOL2.py +458 -0
  11. multipers/data/UCR.py +18 -0
  12. multipers/data/__init__.py +1 -0
  13. multipers/data/graphs.py +466 -0
  14. multipers/data/immuno_regions.py +27 -0
  15. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  16. multipers/data/pytorch2simplextree.py +91 -0
  17. multipers/data/shape3d.py +101 -0
  18. multipers/data/synthetic.py +113 -0
  19. multipers/distances.py +202 -0
  20. multipers/filtration_conversions.pxd +736 -0
  21. multipers/filtration_conversions.pxd.tp +226 -0
  22. multipers/filtrations/__init__.py +21 -0
  23. multipers/filtrations/density.py +529 -0
  24. multipers/filtrations/filtrations.py +480 -0
  25. multipers/filtrations.pxd +534 -0
  26. multipers/filtrations.pxd.tp +332 -0
  27. multipers/function_rips.cpython-312-darwin.so +0 -0
  28. multipers/function_rips.pyx +104 -0
  29. multipers/grids.cpython-312-darwin.so +0 -0
  30. multipers/grids.pyx +538 -0
  31. multipers/gudhi/Persistence_slices_interface.h +213 -0
  32. multipers/gudhi/Simplex_tree_interface.h +274 -0
  33. multipers/gudhi/Simplex_tree_multi_interface.h +648 -0
  34. multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -0
  35. multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -0
  36. multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -0
  37. multipers/gudhi/gudhi/Debug_utils.h +52 -0
  38. multipers/gudhi/gudhi/Degree_rips_bifiltration.h +2307 -0
  39. multipers/gudhi/gudhi/Dynamic_multi_parameter_filtration.h +2524 -0
  40. multipers/gudhi/gudhi/Fields/Multi_field.h +453 -0
  41. multipers/gudhi/gudhi/Fields/Multi_field_operators.h +460 -0
  42. multipers/gudhi/gudhi/Fields/Multi_field_shared.h +444 -0
  43. multipers/gudhi/gudhi/Fields/Multi_field_small.h +584 -0
  44. multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +490 -0
  45. multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +580 -0
  46. multipers/gudhi/gudhi/Fields/Z2_field.h +391 -0
  47. multipers/gudhi/gudhi/Fields/Z2_field_operators.h +389 -0
  48. multipers/gudhi/gudhi/Fields/Zp_field.h +493 -0
  49. multipers/gudhi/gudhi/Fields/Zp_field_operators.h +384 -0
  50. multipers/gudhi/gudhi/Fields/Zp_field_shared.h +492 -0
  51. multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
  52. multipers/gudhi/gudhi/Matrix.h +2200 -0
  53. multipers/gudhi/gudhi/Multi_filtration/Multi_parameter_generator.h +1712 -0
  54. multipers/gudhi/gudhi/Multi_filtration/multi_filtration_conversions.h +237 -0
  55. multipers/gudhi/gudhi/Multi_filtration/multi_filtration_utils.h +225 -0
  56. multipers/gudhi/gudhi/Multi_parameter_filtered_complex.h +485 -0
  57. multipers/gudhi/gudhi/Multi_parameter_filtration.h +2643 -0
  58. multipers/gudhi/gudhi/Multi_persistence/Box.h +233 -0
  59. multipers/gudhi/gudhi/Multi_persistence/Line.h +309 -0
  60. multipers/gudhi/gudhi/Multi_persistence/Multi_parameter_filtered_complex_pcoh_interface.h +268 -0
  61. multipers/gudhi/gudhi/Multi_persistence/Persistence_interface_cohomology.h +159 -0
  62. multipers/gudhi/gudhi/Multi_persistence/Persistence_interface_matrix.h +463 -0
  63. multipers/gudhi/gudhi/Multi_persistence/Point.h +853 -0
  64. multipers/gudhi/gudhi/Off_reader.h +173 -0
  65. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +834 -0
  66. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +838 -0
  67. multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +833 -0
  68. multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1367 -0
  69. multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1157 -0
  70. multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +869 -0
  71. multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +905 -0
  72. multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +122 -0
  73. multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +260 -0
  74. multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +288 -0
  75. multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +170 -0
  76. multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +247 -0
  77. multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +571 -0
  78. multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +182 -0
  79. multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +130 -0
  80. multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +235 -0
  81. multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +312 -0
  82. multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1092 -0
  83. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +923 -0
  84. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +914 -0
  85. multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +930 -0
  86. multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1071 -0
  87. multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +203 -0
  88. multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +886 -0
  89. multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +984 -0
  90. multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1213 -0
  91. multipers/gudhi/gudhi/Persistence_matrix/index_mapper.h +58 -0
  92. multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +227 -0
  93. multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +200 -0
  94. multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +166 -0
  95. multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +319 -0
  96. multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +562 -0
  97. multipers/gudhi/gudhi/Persistence_on_a_line.h +152 -0
  98. multipers/gudhi/gudhi/Persistence_on_rectangle.h +617 -0
  99. multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -0
  100. multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -0
  101. multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -0
  102. multipers/gudhi/gudhi/Persistent_cohomology.h +769 -0
  103. multipers/gudhi/gudhi/Points_off_io.h +171 -0
  104. multipers/gudhi/gudhi/Projective_cover_kernel.h +379 -0
  105. multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
  106. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +559 -0
  107. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
  108. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +121 -0
  109. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
  110. multipers/gudhi/gudhi/Simplex_tree/filtration_value_utils.h +155 -0
  111. multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -0
  112. multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -0
  113. multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +60 -0
  114. multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +105 -0
  115. multipers/gudhi/gudhi/Simplex_tree.h +3170 -0
  116. multipers/gudhi/gudhi/Slicer.h +848 -0
  117. multipers/gudhi/gudhi/Thread_safe_slicer.h +393 -0
  118. multipers/gudhi/gudhi/distance_functions.h +62 -0
  119. multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
  120. multipers/gudhi/gudhi/multi_simplex_tree_helpers.h +147 -0
  121. multipers/gudhi/gudhi/persistence_interval.h +263 -0
  122. multipers/gudhi/gudhi/persistence_matrix_options.h +188 -0
  123. multipers/gudhi/gudhi/reader_utils.h +367 -0
  124. multipers/gudhi/gudhi/simple_mdspan.h +484 -0
  125. multipers/gudhi/gudhi/slicer_helpers.h +779 -0
  126. multipers/gudhi/tmp_h0_pers/mma_interface_h0.h +223 -0
  127. multipers/gudhi/tmp_h0_pers/naive_merge_tree.h +536 -0
  128. multipers/io.cpython-312-darwin.so +0 -0
  129. multipers/io.pyx +472 -0
  130. multipers/ml/__init__.py +0 -0
  131. multipers/ml/accuracies.py +90 -0
  132. multipers/ml/invariants_with_persistable.py +79 -0
  133. multipers/ml/kernels.py +176 -0
  134. multipers/ml/mma.py +713 -0
  135. multipers/ml/one.py +472 -0
  136. multipers/ml/point_clouds.py +352 -0
  137. multipers/ml/signed_measures.py +1667 -0
  138. multipers/ml/sliced_wasserstein.py +461 -0
  139. multipers/ml/tools.py +113 -0
  140. multipers/mma_structures.cpython-312-darwin.so +0 -0
  141. multipers/mma_structures.pxd +134 -0
  142. multipers/mma_structures.pyx +1483 -0
  143. multipers/mma_structures.pyx.tp +1126 -0
  144. multipers/multi_parameter_rank_invariant/diff_helpers.h +85 -0
  145. multipers/multi_parameter_rank_invariant/euler_characteristic.h +95 -0
  146. multipers/multi_parameter_rank_invariant/function_rips.h +317 -0
  147. multipers/multi_parameter_rank_invariant/hilbert_function.h +761 -0
  148. multipers/multi_parameter_rank_invariant/persistence_slices.h +149 -0
  149. multipers/multi_parameter_rank_invariant/rank_invariant.h +350 -0
  150. multipers/multiparameter_edge_collapse.py +41 -0
  151. multipers/multiparameter_module_approximation/approximation.h +2541 -0
  152. multipers/multiparameter_module_approximation/debug.h +107 -0
  153. multipers/multiparameter_module_approximation/format_python-cpp.h +292 -0
  154. multipers/multiparameter_module_approximation/utilities.h +428 -0
  155. multipers/multiparameter_module_approximation.cpython-312-darwin.so +0 -0
  156. multipers/multiparameter_module_approximation.pyx +286 -0
  157. multipers/ops.cpython-312-darwin.so +0 -0
  158. multipers/ops.pyx +231 -0
  159. multipers/pickle.py +89 -0
  160. multipers/plots.py +550 -0
  161. multipers/point_measure.cpython-312-darwin.so +0 -0
  162. multipers/point_measure.pyx +409 -0
  163. multipers/simplex_tree_multi.cpython-312-darwin.so +0 -0
  164. multipers/simplex_tree_multi.pxd +136 -0
  165. multipers/simplex_tree_multi.pyx +11719 -0
  166. multipers/simplex_tree_multi.pyx.tp +2102 -0
  167. multipers/slicer.cpython-312-darwin.so +0 -0
  168. multipers/slicer.pxd +2097 -0
  169. multipers/slicer.pxd.tp +263 -0
  170. multipers/slicer.pyx +13042 -0
  171. multipers/slicer.pyx.tp +1259 -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 +70 -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/vector_interface.pxd +46 -0
  180. multipers-2.4.0b1.dist-info/METADATA +131 -0
  181. multipers-2.4.0b1.dist-info/RECORD +184 -0
  182. multipers-2.4.0b1.dist-info/WHEEL +6 -0
  183. multipers-2.4.0b1.dist-info/licenses/LICENSE +21 -0
  184. multipers-2.4.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,409 @@
1
+ # cimport multipers.tensor as mt
2
+ from libc.stdint cimport intptr_t, uint16_t, uint32_t, int32_t, int64_t
3
+ from libcpp.vector cimport vector
4
+ from libcpp cimport bool, int, float
5
+ import numpy as np
6
+ cimport numpy as cnp
7
+ import itertools
8
+ from typing import Optional,Iterable
9
+
10
+ from collections import defaultdict
11
+ cnp.import_array()
12
+ from scipy import sparse
13
+
14
+ from multipers.array_api import api_from_tensor, api_from_tensors
15
+
16
+ import multipers.grids as mpg
17
+
18
+ ctypedef fused some_int:
19
+ int32_t
20
+ int64_t
21
+ int
22
+
23
+ ctypedef fused some_float:
24
+ int32_t
25
+ int64_t
26
+ int
27
+ float
28
+ double
29
+
30
+
31
+ import cython
32
+ cimport cython
33
+
34
+
35
+ # from scipy.sparse import coo_array
36
+ # from scipy.ndimage import convolve1d
37
+
38
+ def signed_betti(hilbert_function:np.ndarray, bool threshold=False):
39
+ cdef int n = hilbert_function.ndim
40
+ # zero out the "end" of the Hilbert function
41
+ if threshold:
42
+ for dimension in range(n):
43
+ slicer = tuple([slice(None) if i != dimension else -1 for i in range(n)])
44
+ hilbert_function[slicer] = 0
45
+ for i in range(n):
46
+ minus = tuple([slice(None) if j!=i else slice(0,-1) for j in range(n)])
47
+ plus = tuple([slice(None) if j!=i else slice(1,None) for j in range(n)])
48
+ hilbert_function[plus] -= hilbert_function[minus]
49
+ return hilbert_function
50
+
51
+ def rank_decomposition_by_rectangles(rank_invariant:np.ndarray, bool threshold=False):
52
+ # takes as input the rank invariant of an n-parameter persistence module
53
+ # M : [0, ..., s_1 - 1] x ... x [0, ..., s_n - 1] ---> Vec
54
+ # on a grid with dimensions of sizes s_1, ..., s_n. The input is assumed to be
55
+ # given as a tensor of dimensions (s_1, ..., s_n, s_1, ..., s_n), so that,
56
+ # at index [i_1, ..., i_n, j_1, ..., j_n] we have the rank of the structure
57
+ # map M(i) -> M(j), where i = (i_1, ..., i_n) and j = (j_1, ..., j_n), and
58
+ # i <= j, meaning that i_1 <= j_1, ..., i_n <= j_n.
59
+ # NOTE :
60
+ # - About the input, we assume that, if not( i <= j ), then at index
61
+ # [i_1, ..., i_n, j_1, ..., j_n] we have a zero.
62
+ # - Similarly, the output at index [i_1, ..., i_n, j_1, ..., j_n] only
63
+ # makes sense when i <= j. For indices where not( i <= j ) the output
64
+ # may take arbitrary values and they should be ignored.
65
+ cdef int n = rank_invariant.ndim // 2
66
+ if threshold:
67
+ # zero out the "end"
68
+ for dimension in range(n):
69
+ slicer = tuple(
70
+ [slice(None) for _ in range(n)]
71
+ + [slice(None) if i != dimension else -1 for i in range(n)]
72
+ )
73
+ rank_invariant[slicer] = 0
74
+ to_flip = tuple(range(n, 2 * n))
75
+ return np.flip(signed_betti(np.flip(rank_invariant, to_flip)), to_flip)
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+ @cython.boundscheck(False)
84
+ @cython.wraparound(False)
85
+ def integrate_measure(
86
+ some_float[:,:] pts,
87
+ some_int[:] weights,
88
+ filtration_grid:Optional[Iterable[np.ndarray]]=None,
89
+ grid_strategy:str="regular",
90
+ resolution:int|list[int]=100,
91
+ bool return_grid=False,
92
+ bool plot=False,
93
+ **get_fitration_kwargs,
94
+ ):
95
+ """
96
+ Integrate a point measure on a grid.
97
+ Measure is a sum of diracs, based on points `pts` and weights `weights`.
98
+ For instance, if the signed measure comes from the hilbert signed measure,
99
+ this integration will return the hilbert function on this grid.
100
+ - pts : array of points (num_pts, D)
101
+ - weights : array of weights (num_pts,)
102
+ - filtration_grid (optional) : list of 1d arrays
103
+ - resolution : int or list of int
104
+ - return_grid : return the grid of the measure
105
+ - **get_fitration_kwargs : arguments to compute the grid,
106
+ if the grid is not given.
107
+ """
108
+ if filtration_grid is None:
109
+ import multipers.simplex_tree_multi
110
+ filtration_grid = mpg.compute_grid(
111
+ np.asarray(pts).T,
112
+ strategy=grid_strategy,
113
+ resolution=resolution,
114
+ **get_fitration_kwargs
115
+ )
116
+ if pts.size == 0:
117
+ return np.empty()
118
+ resolution = np.asarray([len(f) for f in filtration_grid])
119
+ cdef int num_pts = pts.shape[0]
120
+ cdef int num_parameters = pts.shape[1]
121
+ assert weights.shape[0] == num_pts
122
+ out = np.zeros(shape=resolution, dtype=np.int32) ## dim cannot be known at compiletime
123
+ # cdef some_float[:] filtration_of_parameter
124
+ # cdef cnp.ndarray indices = np.zeros(shape=num_parameters, dtype=int)
125
+ #
126
+ pts_coords = np.empty((num_parameters, num_pts), dtype=np.int64)
127
+ for parameter in range(num_parameters):
128
+ pts_coords[parameter] = np.searchsorted(filtration_grid[parameter], pts[:,parameter])
129
+ for i in range(num_pts):
130
+ cone = tuple(slice(c,r) for r,c in zip(resolution,pts_coords[:,i]))
131
+ out[cone] += weights[i]
132
+ if plot:
133
+ from multipers.plots import plot_surface
134
+ plot_surface(filtration_grid, out, discrete_surface=True)
135
+ if return_grid:
136
+ return out,filtration_grid
137
+ return out
138
+
139
+ ## for benchmark purposes
140
+ def integrate_measure_python(pts, weights, filtrations):
141
+ resolution = tuple([len(f) for f in filtrations])
142
+ out = np.zeros(shape=resolution, dtype=pts.dtype)
143
+ num_pts = pts.shape[0]
144
+ num_parameters = pts.shape[1]
145
+ for i in range(num_pts): #this is slow.
146
+ indices = (filtrations[parameter]>=pts[i][parameter] for parameter in range(num_parameters))
147
+ out[np.ix_(*indices)] += weights[i]
148
+ return out
149
+
150
+
151
+ @cython.boundscheck(False)
152
+ @cython.wraparound(False)
153
+ def sparsify(x):
154
+ """
155
+ Given an arbitrary dimensional numpy array, returns (coordinates,data).
156
+ --
157
+ cost : scipy sparse + num_points*num_parameters^2 divisions
158
+ """
159
+ num_parameters = x.ndim
160
+ sx = sparse.coo_array(x.ravel())
161
+ idx = sx.col
162
+ data = sx.data
163
+ coords = np.empty((data.shape[0], num_parameters), dtype=np.int64)
164
+ for parameter in range(num_parameters-1,-1,-1):
165
+ idx,coord_of_parameter = np.divmod(idx, x.shape[parameter])
166
+ coords[:, parameter] = coord_of_parameter
167
+ return coords,data
168
+
169
+
170
+
171
+
172
+ @cython.boundscheck(False)
173
+ @cython.wraparound(False)
174
+ def clean_signed_measure_old(some_float[:,:] pts, some_int[:] weights, dtype = np.float32):
175
+ """
176
+ Sum the diracs at the same locations. i.e.,
177
+ returns the minimal sized measure to represent the input.
178
+ Mostly useful for, e.g., euler_characteristic from simplical complexes.
179
+ """
180
+ cdef dict[tuple, int] out = {}
181
+ cdef int num_diracs
182
+ cdef int num_parameters
183
+ num_diracs, num_parameters = pts.shape[:2]
184
+ for i in range(num_diracs):
185
+ key = tuple(pts[i]) # size cannot be known at compiletime
186
+ out[key] = out.get(key,0)+ weights[i]
187
+ num_keys = len(out)
188
+ new_pts = np.fromiter(out.keys(), dtype=np.dtype((dtype,num_parameters)), count=num_keys)
189
+ new_weights = np.fromiter(out.values(), dtype=np.int32, count=num_keys)
190
+ idx = np.nonzero(new_weights)
191
+ new_pts = new_pts[idx]
192
+ new_weights = new_weights[idx]
193
+ return (new_pts, new_weights)
194
+
195
+ def clean_signed_measure(pts, w, dtype=np.int32):
196
+ api = api_from_tensor(pts)
197
+ _, idx, inv = np.unique(api.asnumpy(pts), return_index=True, return_inverse=True, axis=0)
198
+ new_w = np.bincount(inv, weights=w).astype(w.dtype)
199
+ pts, w = pts[idx], new_w
200
+ idx = w!=0
201
+ return pts[idx],w[idx]
202
+
203
+ def clean_sms(sms):
204
+ """
205
+ Sum the diracs at the same locations. i.e.,
206
+ returns the minimal sized measure to represent the input.
207
+ Mostly useful for, e.g., euler_characteristic from simplical complexes.
208
+ """
209
+ return tuple(clean_signed_measure(pts,weights) for pts,weights in sms)
210
+
211
+ def zero_out_sm(pts,weights, mass_default):
212
+ """
213
+ Zeros out the modules outside of \f$ \{ x\in \mathbb R^n \mid x \le \mathrm{mass_default}\}\f$.
214
+ """
215
+ from itertools import product
216
+ # merge pts, weights
217
+ PTS = np.concatenate([pts,weights[:,None]], axis=1)[None]
218
+
219
+ num_diracs, num_parameters=pts.shape
220
+
221
+ # corners of the square of dim num_parameters. shape : (num_corners,num_parameters)
222
+ C = np.fromiter(product(*([[1,0]]*num_parameters)), dtype=np.dtype((np.bool_, num_parameters)),)
223
+ Cw = 1-2*((~C).sum(axis=1)%2)
224
+ # add 1 in the end to copy the shape
225
+ C = np.concatenate([C, np.ones((C.shape[0],1))], axis=1).astype(np.bool_)
226
+
227
+ # signs of each corner
228
+ Cw = 1-2*((~C).sum(axis=1) & 1)
229
+
230
+ # something useless in the end to ensure that the shape is correct (as we added 1 in pts)
231
+ mass_default = np.concatenate([mass_default,[np.nan]])
232
+ mass_default = mass_default[None,None,:] ## num c, num_pts, num_params
233
+ # each point `pt` becomes a corner of the square [`pt`, `mass_default`]
234
+ new= np.where(C[:,None,:], PTS,mass_default).reshape(-1,(num_parameters+1))
235
+ new_pts = new[:,:-1]
236
+ new_masses = new[:,-1]*np.repeat(Cw,num_diracs)
237
+ ## a bunch of stuff are in the same place, better clean it
238
+ return clean_signed_measure(new_pts.astype(np.float64), new_masses.astype(np.int64), dtype=np.float64)
239
+
240
+ def zero_out_sms(sms, mass_default):
241
+ """
242
+ Zeros out the modules outside of \f$ \{ x\in \mathbb R^n \mid x \le \mathrm{mass_default}\}\f$.
243
+ """
244
+ return tuple(zero_out_sm(pts,weights, mass_default) for pts,weights in sms)
245
+ def add_sms(sms):
246
+ if len(sms) == 0:
247
+ return (np.empty((0,2)), np.empty())
248
+ pts = tuple(sm[0][:] for sm in sms)
249
+ api = api_from_tensor(pts[0])
250
+ pts = api.cat(pts)
251
+
252
+ weights = tuple(sm[1][:] for sm in sms)
253
+ api = api_from_tensor(weights[0])
254
+ weights = api.cat(weights)
255
+
256
+ return (pts,weights)
257
+
258
+ @cython.boundscheck(False)
259
+ @cython.wraparound(False)
260
+ def barcode_from_rank_sm(
261
+ sm: tuple[np.ndarray, np.ndarray],
262
+ basepoint: np.ndarray,
263
+ direction: Optional[np.ndarray] = None,
264
+ bool full = False,
265
+ ):
266
+ """
267
+ Given a rank signed measure `sm` and a line with basepoint `basepoint` (1darray) and
268
+ direction `direction` (1darray), projects the rank signed measure on the given line,
269
+ and returns the associated estimated barcode.
270
+ If full is True, the barcode is given as coordinates in R^{`num_parameters`} instead
271
+ of coordinates w.r.t. the line.
272
+ """
273
+ basepoint = np.asarray(basepoint)
274
+ num_parameters = basepoint.shape[0]
275
+ x, w = sm
276
+ assert (
277
+ x.shape[1] // 2 == num_parameters
278
+ ), f"Incoherent number of parameters. sm:{x.shape[1]//2} vs {num_parameters}"
279
+ x, y = x[:, :num_parameters], x[:, num_parameters:]
280
+ if direction is not None:
281
+ direction = np.asarray(direction)
282
+ ok_idx = direction > 0
283
+ if ok_idx.sum() == 0:
284
+ raise ValueError(f"Got invalid direction {direction}")
285
+ zero_idx = None if np.all(ok_idx) else direction == 0
286
+ else:
287
+ direction = np.asarray([1], dtype=int)
288
+ ok_idx = slice(None)
289
+ zero_idx = None
290
+ xa = np.max(
291
+ (x[:, ok_idx] - basepoint[ok_idx]) / direction[ok_idx], axis=1, keepdims=1
292
+ )
293
+ ya = np.min(
294
+ (y[:, ok_idx] - basepoint[ok_idx]) / direction[ok_idx], axis=1, keepdims=1
295
+ )
296
+ if zero_idx is not None:
297
+ xb = np.where(x[:, zero_idx] <= basepoint[zero_idx], -np.inf, np.inf)
298
+ yb = np.where(y[:, zero_idx] <= basepoint[zero_idx], -np.inf, np.inf)
299
+ xs = np.max(np.concatenate([xa, xb], axis=1), axis=1, keepdims=1)
300
+ ys = np.min(np.concatenate([ya, yb], axis=1), axis=1, keepdims=1)
301
+ else:
302
+ xs = xa
303
+ ys = ya
304
+ out = np.concatenate([xs, ys], axis=1,dtype=np.float64)
305
+
306
+ ## TODO: check if this is faster than doing a np.repeat on x ?
307
+ cdef dict[dict,tuple] d = {}
308
+ cdef double[:,:] c_out = out # view
309
+ cdef int64_t[:] c_w = np.asarray(w,dtype=np.int64)
310
+ cdef int num_pts = out.shape[0]
311
+ # for i, stuff in enumerate(out):
312
+ # if stuff[0] < np.inf:
313
+ # d[tuple(stuff)] = d.get(tuple(stuff), 0) + w[i]
314
+ for i in range(num_pts):
315
+ if c_out[i][0] < np.inf:
316
+ machin = tuple(c_out[i])
317
+ d[machin] = d.get(machin, 0) + c_w[i]
318
+
319
+ out = np.fromiter(
320
+ itertools.chain.from_iterable(([x] * w for x, w in d.items() if x[0] < x[1])),
321
+ dtype=np.dtype((np.float64, 2)),
322
+ )
323
+ if full:
324
+ out = basepoint[None, None] + out[..., None] * direction[None, None]
325
+ return out
326
+
327
+
328
+ def estimate_rank_from_rank_sm(sm:tuple, a, b)->np.int64:
329
+ """
330
+ Given a rank signed measure (sm) and two points (a) and (b),
331
+ estimates the rank between these two points.
332
+ """
333
+ a = np.asarray(a)
334
+ b = np.asarray(b)
335
+ if not (a <= b).all():
336
+ return 0
337
+ x, w = sm
338
+ num_parameters = x.shape[1] // 2
339
+ assert (
340
+ a.shape[0] == b.shape[0] == num_parameters
341
+ ), f"Incoherent number of parameters. sm:{num_parameters} vs {a.shape[0]} and {b.shape[0]}"
342
+ idx = (
343
+ (x[:, :num_parameters] <= a[None]).all(1)
344
+ * (x[:, num_parameters:] >= b[None]).all(1)
345
+ ).ravel()
346
+ return w[idx].sum()
347
+
348
+
349
+ def rectangle_to_hook_minimal_signed_barcode(pts,w,):
350
+ if pts.shape[1] != 4:
351
+ raise NotImplementedError(
352
+ "Only works for 2-parameter persistence modules for the moment."
353
+ )
354
+ api = api_from_tensor(pts)
355
+ pts = api.astensor(pts)
356
+ w = np.asarray(w)
357
+ ## [a,b], [a, a0b1], [a,b0a1], proj, V,H
358
+
359
+ projectives_idx = (pts[:,3] == np.inf) * (pts[:,2] == np.inf)
360
+ pts_proj = pts[projectives_idx]
361
+ w_proj = w[projectives_idx]
362
+ pts = pts[~projectives_idx]
363
+ w = w[~projectives_idx]
364
+ # print("projectives:", pts_proj)
365
+
366
+ vert_blocks_idx = pts[:,3] == np.inf
367
+ pts_V = pts[vert_blocks_idx]
368
+ w_V = w[vert_blocks_idx]
369
+ pts_V[:,3] = pts_V[:,1]
370
+ pts = pts[~vert_blocks_idx]
371
+ w = w[~vert_blocks_idx]
372
+ # print("vertical:", pts_V)
373
+
374
+ h_idx = pts[:,2] == np.inf
375
+ pts_H = pts[h_idx]
376
+ w_H = w[h_idx]
377
+ pts_H[:,2] = pts_H[:,0]
378
+ pts = pts[~h_idx]
379
+ w = w[~h_idx]
380
+ # print("horizontal:", pts_H)
381
+
382
+
383
+ new_w = np.concatenate([-w, w, w, w_proj,w_V,w_H])
384
+
385
+ pts_b0a1 = api.tensor(pts)
386
+ pts_b0a1[:,3] = pts[:,1]
387
+ pts_a0b1 = api.tensor(pts)
388
+ pts_a0b1[:,2] = pts[:,0]
389
+
390
+ new_pts = api.cat([
391
+ pts,
392
+ pts_b0a1,
393
+ pts_a0b1,
394
+ pts_proj,
395
+ pts_V,
396
+ pts_H
397
+ ], axis=0)
398
+ # pts,w = new_pts,new_w
399
+ pts,w = clean_signed_measure(new_pts,new_w)
400
+
401
+ # Everything infinite is handled separately anyway
402
+ # inf0 = pts[:,2] == np.inf
403
+ # inf1 = pts[:,3] == np.inf
404
+ # pts[inf0,3] = pts[inf0,1]
405
+ # pts[inf1,2] = pts[inf1,0]
406
+ # pts,w = clean_signed_measure(pts,w)
407
+
408
+ return pts,w
409
+
@@ -0,0 +1,136 @@
1
+ # This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2
+ # See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3
+ # Author(s): Vincent Rouvreau
4
+ #
5
+ # Copyright (C) 2016 Inria
6
+ #
7
+ # Modification(s):
8
+ # - 2022 David Loiseaux, Hannah Schreiber: adapt for multipersistence.
9
+ # - YYYY/MM Author: Description of the modification
10
+
11
+ from cython cimport numeric
12
+ from libcpp.vector cimport vector
13
+ from libcpp.utility cimport pair
14
+ from libcpp cimport bool
15
+ from libcpp.string cimport string
16
+ from libcpp.map cimport map
17
+
18
+ from libc.stdint cimport intptr_t, int32_t
19
+
20
+ __author__ = "Vincent Rouvreau"
21
+ __copyright__ = "Copyright (C) 2016 Inria"
22
+ __license__ = "MIT"
23
+
24
+
25
+ from multipers.filtrations cimport *
26
+
27
+
28
+ ctypedef int dimension_type
29
+ ctypedef vector[int] simplex_type
30
+ ctypedef vector[int] simplex_list
31
+ ctypedef vector[pair[pair[int,int], pair[double, double]]] edge_list
32
+ ctypedef vector[int] euler_char_list
33
+
34
+ ctypedef vector[unsigned int] boundary_type
35
+ ctypedef vector[boundary_type] boundary_matrix
36
+
37
+ cdef extern from "Simplex_tree_multi_interface.h" namespace "Gudhi::multiparameter::python_interface":
38
+
39
+ cdef cppclass Simplex_tree_multi_simplex_handle[F=*]:
40
+ pass
41
+
42
+ cdef cppclass Simplex_tree_multi_simplices_iterator[F=*]:
43
+ Simplex_tree_multi_simplices_iterator() nogil
44
+ Simplex_tree_multi_simplex_handle& operator*() nogil
45
+ Simplex_tree_multi_simplices_iterator operator++() nogil
46
+ bint operator!=(Simplex_tree_multi_simplices_iterator) nogil
47
+
48
+ cdef cppclass Simplex_tree_multi_skeleton_iterator[F=*]:
49
+ Simplex_tree_multi_skeleton_iterator() nogil
50
+ Simplex_tree_multi_simplex_handle& operator*() nogil
51
+ Simplex_tree_multi_skeleton_iterator operator++() nogil
52
+ bint operator!=(Simplex_tree_multi_skeleton_iterator) nogil
53
+
54
+ cdef cppclass Simplex_tree_multi_boundary_iterator[F=*]:
55
+ Simplex_tree_multi_boundary_iterator() nogil
56
+ Simplex_tree_multi_simplex_handle& operator*() nogil
57
+ Simplex_tree_multi_boundary_iterator operator++() nogil
58
+ bint operator!=(Simplex_tree_multi_boundary_iterator) nogil
59
+
60
+
61
+ cdef cppclass Simplex_tree_multi_interface[F=*, value_type=*]:
62
+ ctypedef pair[simplex_type, F*] simplex_filtration_type
63
+ Simplex_tree_multi_interface() nogil
64
+ Simplex_tree_multi_interface(Simplex_tree_multi_interface&) nogil
65
+ F* simplex_filtration(const vector[int]& simplex) except + nogil
66
+ void assign_simplex_filtration(vector[int]& simplex, const F& filtration) noexcept nogil
67
+ void initialize_filtration() nogil
68
+ int num_vertices() nogil
69
+ int num_simplices() nogil
70
+ void set_dimension(int dimension) nogil
71
+ dimension_type dimension() nogil
72
+ dimension_type upper_bound_dimension() nogil
73
+ bool find_simplex(vector[int]& simplex) nogil
74
+ bool insert(vector[int]& simplex, F& filtration) noexcept nogil
75
+ bool insert_force(vector[int]& simplex, F& filtration) noexcept nogil
76
+ # vector[simplex_filtration_type] get_star(const vector[int]& simplex) nogil
77
+ # vector[simplex_filtration_type] get_cofaces(const vector[int]& simplex, int dimension) nogil
78
+ void expansion(int max_dim) except + nogil
79
+ void remove_maximal_simplex(simplex_type simplex) nogil
80
+ # bool prune_above_filtration(filtration_type filtration) nogil
81
+ bool prune_above_dimension(int dimension) nogil
82
+ bool make_filtration_non_decreasing() except + nogil
83
+ # void compute_extended_filtration() nogil
84
+ # Simplex_tree_multi_interface* collapse_edges(int nb_collapse_iteration) except + nogil
85
+ void reset_filtration(const F& filtration, int dimension) nogil
86
+ bint operator==(Simplex_tree_multi_interface) nogil
87
+ # Iterators over Simplex tree
88
+ pair[simplex_type,F*] get_simplex_and_filtration(Simplex_tree_multi_simplex_handle f_simplex) nogil
89
+ Simplex_tree_multi_simplices_iterator[F] get_simplices_iterator_begin() nogil
90
+ Simplex_tree_multi_simplices_iterator[F] get_simplices_iterator_end() nogil
91
+ vector[Simplex_tree_multi_simplex_handle[F]].const_iterator get_filtration_iterator_begin() nogil
92
+ vector[Simplex_tree_multi_simplex_handle[F]].const_iterator get_filtration_iterator_end() nogil
93
+ Simplex_tree_multi_skeleton_iterator get_skeleton_iterator_begin(int dimension) nogil
94
+ Simplex_tree_multi_skeleton_iterator get_skeleton_iterator_end(int dimension) nogil
95
+ pair[Simplex_tree_multi_boundary_iterator, Simplex_tree_multi_boundary_iterator] get_boundary_iterators(vector[int] simplex) except + nogil
96
+ # Expansion with blockers
97
+ ctypedef bool (*blocker_func_t)(vector[int], void *user_data)
98
+ void expansion_with_blockers_callback(int dimension, blocker_func_t user_func, void *user_data)
99
+
100
+ ## MULTIPERS STUFF
101
+ void set_keys_to_enumerate() nogil const
102
+ int get_key(const simplex_type) nogil
103
+ void set_key(simplex_type, int) nogil
104
+ void fill_lowerstar(vector[value_type]&, int) except+ nogil
105
+ simplex_list get_simplices_of_dimension(int) nogil
106
+ edge_list get_edge_list() nogil
107
+ # euler_char_list euler_char(const vector[filtration_type]&) nogil
108
+ void resize_all_filtrations(int) nogil
109
+ void set_num_parameters(int) nogil
110
+ int num_parameters() nogil
111
+ void serialize(char* buffer, const size_t buffer_size) except + nogil
112
+ void deserialize(const char* buffer, const size_t buffer_size) except + nogil
113
+ size_t get_serialization_size() nogil
114
+ void clear() nogil
115
+
116
+ dimension_type simplex_dimension(const simplex_type&) nogil
117
+
118
+ void from_std(char*, size_t, int, vector[value_type]&) nogil
119
+ void to_std(intptr_t, Line[double],int ) nogil
120
+ void to_std_linear_projection(intptr_t, vector[double]) nogil
121
+ void squeeze_filtration_inplace(vector[vector[double]] &, bool) nogil
122
+ void squeeze_filtration(intptr_t, vector[vector[double]] &) except + nogil
123
+ void unsqueeze_filtration(intptr_t, vector[vector[double]] &) except + nogil
124
+ vector[vector[vector[value_type]]] get_filtration_values(const vector[int]&) nogil
125
+
126
+
127
+ pair[boundary_matrix, vector[One_critical_filtration[value_type]]] simplextree_to_boundary_filtration()
128
+ vector[pair[ vector[vector[value_type]],boundary_matrix]] simplextree_to_scc()
129
+ vector[pair[ vector[vector[vector[value_type]]],boundary_matrix]] kcritical_simplextree_to_scc()
130
+
131
+ vector[pair[ vector[vector[vector[value_type]]],boundary_matrix]] function_simplextree_to_scc()
132
+ pair[vector[vector[value_type]],boundary_matrix ] simplextree_to_ordered_bf()
133
+ # vector[map[value_type,int32_t]] build_idx_map(const vector[int]&) nogil
134
+ # pair[vector[vector[int32_t]],vector[vector[int32_t]]] get_pts_indices(const vector[map[value_type,int32_t]]&, const vector[vector[value_type]]&) nogil
135
+ pair[vector[vector[int32_t]],vector[vector[int32_t]]] pts_to_indices(vector[vector[value_type]]&, vector[int]&) nogil
136
+