multipers 2.3.3b7__cp311-cp311-win_amd64.whl → 2.3.4__cp311-cp311-win_amd64.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.

@@ -31,17 +31,19 @@ def check_keops():
31
31
  global _is_keops_available, LazyTensor
32
32
  if _is_keops_available is not None:
33
33
  return _is_keops_available
34
- import pykeops.numpy as pknp
35
- from pykeops.numpy import LazyTensor as LT
36
-
37
- formula = "SqNorm2(x - y)"
38
- var = ["x = Vi(3)", "y = Vj(3)"]
39
- expected_res = _np.array([63.0, 90.0])
40
- x = _np.arange(1, 10).reshape(-1, 3).astype("float32")
41
- y = _np.arange(3, 9).reshape(-1, 3).astype("float32")
42
-
43
- my_conv = pknp.Genred(formula, var)
44
34
  try:
35
+ if _is_keops_available is not None:
36
+ return _is_keops_available
37
+ import pykeops.numpy as pknp
38
+ from pykeops.numpy import LazyTensor as LT
39
+
40
+ formula = "SqNorm2(x - y)"
41
+ var = ["x = Vi(3)", "y = Vj(3)"]
42
+ expected_res = _np.array([63.0, 90.0])
43
+ x = _np.arange(1, 10).reshape(-1, 3).astype("float32")
44
+ y = _np.arange(3, 9).reshape(-1, 3).astype("float32")
45
+
46
+ my_conv = pknp.Genred(formula, var)
45
47
  _is_keops_available = _np.allclose(my_conv(x, y).flatten(), expected_res)
46
48
  LazyTensor = LT
47
49
  except:
@@ -41,7 +41,7 @@ def check_keops():
41
41
 
42
42
  my_conv = pknp.Genred(formula, var)
43
43
  _is_keops_available = _t.allclose(
44
- my_conv(x, y).view(-1), _t.tensor(expected_res).type(_t.float32)
44
+ my_conv(x, y).view(-1), expected_res.type(_t.float32)
45
45
  )
46
46
  LazyTensor = LT
47
47
 
@@ -53,6 +53,7 @@ def check_keops():
53
53
  _is_keops_available = False
54
54
 
55
55
  return _is_keops_available
56
+ check_keops()
56
57
 
57
58
 
58
59
  def from_numpy(x):
@@ -76,8 +76,8 @@ def RipsLowerstar(
76
76
  st.fill_lowerstar(api.asnumpy(function[:, i]), parameter=1 + i)
77
77
  if api.has_grad(D) or api.has_grad(function):
78
78
  from multipers.grids import compute_grid
79
-
80
- grid = compute_grid([D.ravel(), *[f for f in function.T]])
79
+ filtration_values = [D.ravel(), *[f for f in function.T]]
80
+ grid = compute_grid(filtration_values)
81
81
  st = st.grid_squeeze(grid)
82
82
  return st
83
83
 
Binary file
Binary file
multipers/grids.pyx CHANGED
@@ -124,8 +124,7 @@ def compute_grid(
124
124
  except TypeError:
125
125
  pass
126
126
 
127
- if api is npapi:
128
- return _compute_grid_numpy(
127
+ grid = _compute_grid_numpy(
129
128
  initial_grid,
130
129
  resolution=resolution,
131
130
  strategy = strategy,
@@ -133,9 +132,9 @@ def compute_grid(
133
132
  _q_factor=_q_factor,
134
133
  drop_quantiles=drop_quantiles,
135
134
  dense = dense,
136
- )
137
- from multipers.torch.diff_grids import get_grid
138
- grid = get_grid(strategy)(initial_grid,resolution)
135
+ )
136
+ # from multipers.torch.diff_grids import get_grid
137
+ # grid = get_grid(strategy)(initial_grid,resolution)
139
138
  if dense:
140
139
  grid = todense(grid)
141
140
  return grid
@@ -169,7 +168,7 @@ def _compute_grid_numpy(
169
168
  Iterable[array[float, ndim=1]] : the 1d-grid for each parameter.
170
169
  """
171
170
  num_parameters = len(filtrations_values)
172
- api = api_from_tensors(filtrations_values)
171
+ api = api_from_tensors(*filtrations_values)
173
172
  try:
174
173
  a,b=drop_quantiles
175
174
  except:
@@ -189,7 +188,7 @@ def _compute_grid_numpy(
189
188
  elif strategy == "quantile":
190
189
  F = tuple(api.unique(f) for f in filtrations_values)
191
190
  max_resolution = [min(len(f),r) for f,r in zip(F,resolution)]
192
- F = tuple( api.quantile_closest(f, q=np.linspace(0,1,num=int(r*_q_factor)), axis=0) for f,r in zip(F, resolution) )
191
+ F = tuple( api.quantile_closest(f, q=api.linspace(0,1,int(r*_q_factor)), axis=0) for f,r in zip(F, resolution) )
193
192
  if unique:
194
193
  F = tuple(api.unique(f) for f in F)
195
194
  if np.all(np.asarray(max_resolution) > np.asarray([len(f) for f in F])):
@@ -203,7 +202,7 @@ def _compute_grid_numpy(
203
202
  # elif strategy == "torch_regular_closest":
204
203
  # F = tuple(_torch_regular_closest(f,r, unique) for f,r in zip(filtrations_values, resolution))
205
204
  elif strategy == "partition":
206
- F = tuple(_todo_partition(f,r, unique) for f,r in zip(filtrations_values, resolution))
205
+ F = tuple(_todo_partition(f,r, unique, api) for f,r in zip(filtrations_values, resolution))
207
206
  elif strategy == "precomputed":
208
207
  F=filtrations_values
209
208
  else:
@@ -215,7 +214,7 @@ def _compute_grid_numpy(
215
214
  def todense(grid, bool product_order=False):
216
215
  if len(grid) == 0:
217
216
  return np.empty(0)
218
- api = api_from_tensors(grid)
217
+ api = api_from_tensors(*grid)
219
218
  # if product_order:
220
219
  # if not api.backend ==np:
221
220
  # raise NotImplementedError("only numpy here.")
@@ -235,8 +234,10 @@ def todense(grid, bool product_order=False):
235
234
 
236
235
 
237
236
 
238
- ## TODO : optimize. Pykeops ?
239
237
  def _todo_regular(f, int r, api):
238
+ if api.has_grad(f):
239
+ from warnings import warn
240
+ warn("`strategy=regular` is not differentiable. Removing grad.")
240
241
  with api.no_grad():
241
242
  return api.linspace(api.min(f), api.max(f), r)
242
243
 
@@ -284,8 +285,14 @@ def _todo_regular_left_old(some_float[:] f, int r, bool unique):
284
285
  if unique: f_regular_closest = np.unique(f_regular_closest)
285
286
  return f_regular_closest
286
287
 
288
+ def _todo_partition(x, int resolution, bool unique, api):
289
+ if api.has_grad(x):
290
+ from warnings import warn
291
+ warn("`strategy=partition` is not differentiable. Removing grad.")
292
+ out = _todo_partition_(api.asnumpy(x), resolution, unique)
293
+ return api.from_numpy(out)
287
294
 
288
- def _todo_partition(some_float[:] data,int resolution, bool unique):
295
+ def _todo_partition_(some_float[:] data,int resolution, bool unique):
289
296
  if data.shape[0] < resolution: resolution=data.shape[0]
290
297
  k = data.shape[0] // resolution
291
298
  partitions = np.partition(data, k)
@@ -805,7 +805,7 @@ class Multi_critical_filtration {
805
805
  res.add_generator(nf);
806
806
  }
807
807
  }
808
- swap(f1, res);
808
+ std::swap(f1, res);
809
809
 
810
810
  return f1 != res;
811
811
  }
Binary file
multipers/plots.py CHANGED
@@ -81,7 +81,8 @@ def _plot_signed_measure_4(
81
81
  **plt_kwargs, # ignored ftm
82
82
  ):
83
83
  # compute the maximal rectangle area
84
- pts = np.clip(pts, a_min=-np.inf, a_max=np.array((*threshold, *threshold))[None, :])
84
+ pts = np.clip(pts, a_min=-np.inf,
85
+ a_max=np.array((*threshold, *threshold))[None, :])
85
86
  alpha_rescaling = 0
86
87
  for rectangle, weight in zip(pts, weights):
87
88
  if rectangle[2] >= x_smoothing * rectangle[0]:
@@ -170,7 +171,8 @@ def plot_signed_measures(signed_measures, threshold=None, size=4):
170
171
  nrows=1, ncols=num_degrees, figsize=(num_degrees * size, size)
171
172
  )
172
173
  for ax, signed_measure in zip(axes, signed_measures):
173
- plot_signed_measure(signed_measure=signed_measure, ax=ax, threshold=threshold)
174
+ plot_signed_measure(signed_measure=signed_measure,
175
+ ax=ax, threshold=threshold)
174
176
  plt.tight_layout()
175
177
 
176
178
 
@@ -200,13 +202,17 @@ def plot_surface(
200
202
  cmap = matplotlib.colormaps["gray_r"]
201
203
  else:
202
204
  cmap = _cmap
205
+ if discrete_surface or not contour:
206
+ # for shading="flat"
207
+ grid = [np.concatenate([g, [g[-1]*1.1 - .1*g[0]]]) for g in grid]
203
208
  if discrete_surface:
204
209
  if has_negative_values:
205
210
  bounds = np.arange(-5, 6, 1, dtype=int)
206
211
  else:
207
212
  bounds = np.arange(0, 11, 1, dtype=int)
208
213
  norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N, extend="max")
209
- im = ax.pcolormesh(grid[0], grid[1], hf.T, cmap=cmap, norm=norm, **plt_args)
214
+ im = ax.pcolormesh(grid[0], grid[1], hf.T, cmap=cmap,
215
+ norm=norm, shading="flat", **plt_args)
210
216
  cbar = fig.colorbar(
211
217
  matplotlib.cm.ScalarMappable(cmap=cmap, norm=norm),
212
218
  spacing="proportional",
@@ -217,9 +223,11 @@ def plot_surface(
217
223
 
218
224
  if contour:
219
225
  levels = plt_args.pop("levels", 50)
220
- im = ax.contourf(grid[0], grid[1], hf.T, cmap=cmap, levels=levels, **plt_args)
226
+ im = ax.contourf(grid[0], grid[1], hf.T,
227
+ cmap=cmap, levels=levels, **plt_args)
221
228
  else:
222
- im = ax.pcolormesh(grid[0], grid[1], hf.T, cmap=cmap, **plt_args)
229
+ im = ax.pcolormesh(grid[0], grid[1], hf.T,
230
+ cmap=cmap, shading="flat", **plt_args)
223
231
  return im
224
232
 
225
233
 
@@ -314,25 +322,30 @@ def plot2d_PyModule(
314
322
  trivial_summand = False
315
323
  if shapely:
316
324
  list_of_rect.append(
317
- _rectangle_box(birth[0], birth[1], death[0], death[1])
325
+ _rectangle_box(
326
+ birth[0], birth[1], death[0], death[1])
318
327
  )
319
328
  else:
320
329
  list_of_rect.append(
321
- _rectangle(birth, death, cmap(i / n_summands), alpha)
330
+ _rectangle(birth, death, cmap(
331
+ i / n_summands), alpha)
322
332
  )
323
333
  if not (trivial_summand):
324
334
  if separated:
325
335
  fig, ax = plt.subplots()
326
- ax.set(xlim=[box[0][0], box[1][0]], ylim=[box[0][1], box[1][1]])
336
+ ax.set(xlim=[box[0][0], box[1][0]],
337
+ ylim=[box[0][1], box[1][1]])
327
338
  if shapely:
328
339
  summand_shape = union_all(list_of_rect)
329
340
  if type(summand_shape) is _Polygon:
330
341
  xs, ys = summand_shape.exterior.xy
331
- ax.fill(xs, ys, alpha=alpha, fc=cmap(i / n_summands), ec="None")
342
+ ax.fill(xs, ys, alpha=alpha, fc=cmap(
343
+ i / n_summands), ec="None")
332
344
  else:
333
345
  for polygon in summand_shape.geoms:
334
346
  xs, ys = polygon.exterior.xy
335
- ax.fill(xs, ys, alpha=alpha, fc=cmap(i / n_summands), ec="None")
347
+ ax.fill(xs, ys, alpha=alpha, fc=cmap(
348
+ i / n_summands), ec="None")
336
349
  else:
337
350
  for rectangle in list_of_rect:
338
351
  ax.add_patch(rectangle)
@@ -396,7 +409,8 @@ def plot_simplicial_complex(
396
409
  if len(s) == 2: # simplexe = segment
397
410
  xx = np.array([pts[a, 0] for a in s])
398
411
  yy = np.array([pts[a, 1] for a in s])
399
- plt.plot(xx, yy, c=color(density), alpha=1, zorder=10 * density, lw=1.5)
412
+ plt.plot(xx, yy, c=color(density), alpha=1,
413
+ zorder=10 * density, lw=1.5)
400
414
  if len(s) == 3: # simplexe = triangle
401
415
  xx = np.array([pts[a, 0] for a in s])
402
416
  yy = np.array([pts[a, 1] for a in s])
Binary file
@@ -117,8 +117,8 @@ cdef extern from "Simplex_tree_multi_interface.h" namespace "Gudhi::multiparamet
117
117
  void to_std(intptr_t, Line[double],int ) nogil
118
118
  void to_std_linear_projection(intptr_t, vector[double]) nogil
119
119
  void squeeze_filtration_inplace(vector[vector[double]] &, bool) nogil
120
- void squeeze_filtration(intptr_t, vector[vector[double]] &) nogil
121
- void unsqueeze_filtration(intptr_t, vector[vector[double]] &) nogil
120
+ void squeeze_filtration(intptr_t, vector[vector[double]] &) except + nogil
121
+ void unsqueeze_filtration(intptr_t, vector[vector[double]] &) except + nogil
122
122
  vector[vector[vector[value_type]]] get_filtration_values(const vector[int]&) nogil
123
123
 
124
124
 
@@ -625,6 +625,41 @@ cdef class SimplexTreeMulti_KFi32:
625
625
  """
626
626
  return self.get_ptr().prune_above_dimension(dimension)
627
627
 
628
+ def expansion(self, int max_dim)->SimplexTreeMulti_KFi32:
629
+ """Expands the simplex tree containing only its one skeleton
630
+ until dimension max_dim.
631
+
632
+ The expanded simplicial complex until dimension :math:`d`
633
+ attached to a graph :math:`G` is the maximal simplicial complex of
634
+ dimension at most :math:`d` admitting the graph :math:`G` as
635
+ :math:`1`-skeleton.
636
+ The filtration value assigned to a simplex is the maximal filtration
637
+ value of one of its edges.
638
+
639
+ The simplex tree must contain no simplex of dimension bigger than
640
+ 1 when calling the method.
641
+
642
+ :param max_dim: The maximal dimension.
643
+ :type max_dim: int
644
+ """
645
+ with nogil:
646
+ self.get_ptr().expansion(max_dim)
647
+ # This is a fix for multipersistence. FIXME expansion in c++
648
+ self.get_ptr().make_filtration_non_decreasing()
649
+ return self
650
+
651
+ def make_filtration_non_decreasing(self)->bool:
652
+ """This function ensures that each simplex has a higher filtration
653
+ value than its faces by increasing the filtration values.
654
+
655
+ :returns: True if any filtration value was modified,
656
+ False if the filtration was already non-decreasing.
657
+ :rtype: bool
658
+ """
659
+ cdef bool out
660
+ with nogil:
661
+ out = self.get_ptr().make_filtration_non_decreasing()
662
+ return out
628
663
 
629
664
  def reset_filtration(self, filtration, min_dim = 0)->SimplexTreeMulti_KFi32:
630
665
  """This function resets the filtration value of all the simplices of dimension at least min_dim. Resets all the
@@ -3217,6 +3252,41 @@ cdef class SimplexTreeMulti_KFi64:
3217
3252
  """
3218
3253
  return self.get_ptr().prune_above_dimension(dimension)
3219
3254
 
3255
+ def expansion(self, int max_dim)->SimplexTreeMulti_KFi64:
3256
+ """Expands the simplex tree containing only its one skeleton
3257
+ until dimension max_dim.
3258
+
3259
+ The expanded simplicial complex until dimension :math:`d`
3260
+ attached to a graph :math:`G` is the maximal simplicial complex of
3261
+ dimension at most :math:`d` admitting the graph :math:`G` as
3262
+ :math:`1`-skeleton.
3263
+ The filtration value assigned to a simplex is the maximal filtration
3264
+ value of one of its edges.
3265
+
3266
+ The simplex tree must contain no simplex of dimension bigger than
3267
+ 1 when calling the method.
3268
+
3269
+ :param max_dim: The maximal dimension.
3270
+ :type max_dim: int
3271
+ """
3272
+ with nogil:
3273
+ self.get_ptr().expansion(max_dim)
3274
+ # This is a fix for multipersistence. FIXME expansion in c++
3275
+ self.get_ptr().make_filtration_non_decreasing()
3276
+ return self
3277
+
3278
+ def make_filtration_non_decreasing(self)->bool:
3279
+ """This function ensures that each simplex has a higher filtration
3280
+ value than its faces by increasing the filtration values.
3281
+
3282
+ :returns: True if any filtration value was modified,
3283
+ False if the filtration was already non-decreasing.
3284
+ :rtype: bool
3285
+ """
3286
+ cdef bool out
3287
+ with nogil:
3288
+ out = self.get_ptr().make_filtration_non_decreasing()
3289
+ return out
3220
3290
 
3221
3291
  def reset_filtration(self, filtration, min_dim = 0)->SimplexTreeMulti_KFi64:
3222
3292
  """This function resets the filtration value of all the simplices of dimension at least min_dim. Resets all the
@@ -5809,6 +5879,41 @@ cdef class SimplexTreeMulti_KFf32:
5809
5879
  """
5810
5880
  return self.get_ptr().prune_above_dimension(dimension)
5811
5881
 
5882
+ def expansion(self, int max_dim)->SimplexTreeMulti_KFf32:
5883
+ """Expands the simplex tree containing only its one skeleton
5884
+ until dimension max_dim.
5885
+
5886
+ The expanded simplicial complex until dimension :math:`d`
5887
+ attached to a graph :math:`G` is the maximal simplicial complex of
5888
+ dimension at most :math:`d` admitting the graph :math:`G` as
5889
+ :math:`1`-skeleton.
5890
+ The filtration value assigned to a simplex is the maximal filtration
5891
+ value of one of its edges.
5892
+
5893
+ The simplex tree must contain no simplex of dimension bigger than
5894
+ 1 when calling the method.
5895
+
5896
+ :param max_dim: The maximal dimension.
5897
+ :type max_dim: int
5898
+ """
5899
+ with nogil:
5900
+ self.get_ptr().expansion(max_dim)
5901
+ # This is a fix for multipersistence. FIXME expansion in c++
5902
+ self.get_ptr().make_filtration_non_decreasing()
5903
+ return self
5904
+
5905
+ def make_filtration_non_decreasing(self)->bool:
5906
+ """This function ensures that each simplex has a higher filtration
5907
+ value than its faces by increasing the filtration values.
5908
+
5909
+ :returns: True if any filtration value was modified,
5910
+ False if the filtration was already non-decreasing.
5911
+ :rtype: bool
5912
+ """
5913
+ cdef bool out
5914
+ with nogil:
5915
+ out = self.get_ptr().make_filtration_non_decreasing()
5916
+ return out
5812
5917
 
5813
5918
  def reset_filtration(self, filtration, min_dim = 0)->SimplexTreeMulti_KFf32:
5814
5919
  """This function resets the filtration value of all the simplices of dimension at least min_dim. Resets all the
@@ -8401,6 +8506,41 @@ cdef class SimplexTreeMulti_KFf64:
8401
8506
  """
8402
8507
  return self.get_ptr().prune_above_dimension(dimension)
8403
8508
 
8509
+ def expansion(self, int max_dim)->SimplexTreeMulti_KFf64:
8510
+ """Expands the simplex tree containing only its one skeleton
8511
+ until dimension max_dim.
8512
+
8513
+ The expanded simplicial complex until dimension :math:`d`
8514
+ attached to a graph :math:`G` is the maximal simplicial complex of
8515
+ dimension at most :math:`d` admitting the graph :math:`G` as
8516
+ :math:`1`-skeleton.
8517
+ The filtration value assigned to a simplex is the maximal filtration
8518
+ value of one of its edges.
8519
+
8520
+ The simplex tree must contain no simplex of dimension bigger than
8521
+ 1 when calling the method.
8522
+
8523
+ :param max_dim: The maximal dimension.
8524
+ :type max_dim: int
8525
+ """
8526
+ with nogil:
8527
+ self.get_ptr().expansion(max_dim)
8528
+ # This is a fix for multipersistence. FIXME expansion in c++
8529
+ self.get_ptr().make_filtration_non_decreasing()
8530
+ return self
8531
+
8532
+ def make_filtration_non_decreasing(self)->bool:
8533
+ """This function ensures that each simplex has a higher filtration
8534
+ value than its faces by increasing the filtration values.
8535
+
8536
+ :returns: True if any filtration value was modified,
8537
+ False if the filtration was already non-decreasing.
8538
+ :rtype: bool
8539
+ """
8540
+ cdef bool out
8541
+ with nogil:
8542
+ out = self.get_ptr().make_filtration_non_decreasing()
8543
+ return out
8404
8544
 
8405
8545
  def reset_filtration(self, filtration, min_dim = 0)->SimplexTreeMulti_KFf64:
8406
8546
  """This function resets the filtration value of all the simplices of dimension at least min_dim. Resets all the
@@ -869,7 +869,6 @@ cdef class SimplexTreeMulti_{{FSHORT}}:
869
869
  """
870
870
  return self.get_ptr().prune_above_dimension(dimension)
871
871
 
872
- {{if not is_kcritical}}
873
872
  def expansion(self, int max_dim)->SimplexTreeMulti_{{FSHORT}}:
874
873
  """Expands the simplex tree containing only its one skeleton
875
874
  until dimension max_dim.
@@ -905,7 +904,6 @@ cdef class SimplexTreeMulti_{{FSHORT}}:
905
904
  with nogil:
906
905
  out = self.get_ptr().make_filtration_non_decreasing()
907
906
  return out
908
- {{endif}}
909
907
 
910
908
  def reset_filtration(self, filtration, min_dim = 0)->SimplexTreeMulti_{{FSHORT}}:
911
909
  """This function resets the filtration value of all the simplices of dimension at least min_dim. Resets all the
Binary file
multipers/slicer.pyx CHANGED
@@ -19914,7 +19914,7 @@ def _from_bitmapf32(image, **slicer_kwargs):
19914
19914
  # print(f"F = {np.asarray(F[i])}")
19915
19915
  slicer = _Slicer(gen_maps, gen_dims, filtration_values)
19916
19916
  return slicer
19917
- def _from_bitmapi32(image, **slicer_kwargs):
19917
+ def _from_bitmapf64(image, **slicer_kwargs):
19918
19918
  from multipers import Slicer
19919
19919
  dtype = slicer_kwargs.get("dtype", image.dtype)
19920
19920
  slicer_kwargs["dtype"] = dtype
@@ -19932,9 +19932,9 @@ def _from_bitmapi32(image, **slicer_kwargs):
19932
19932
  cdef cset[unsigned int] vertices
19933
19933
 
19934
19934
  cdef unsigned int num_gens = gen_dims.size()
19935
- filtration_values = np.zeros(shape=(num_gens, num_parameters), dtype = np.int32) - _Slicer._inf_value()
19936
- cdef int32_t[:,:] F = filtration_values
19937
- cdef int32_t[:,:] c_img = image.reshape(-1,num_parameters)
19935
+ filtration_values = np.zeros(shape=(num_gens, num_parameters), dtype = np.float64) - _Slicer._inf_value()
19936
+ cdef double[:,:] F = filtration_values
19937
+ cdef double[:,:] c_img = image.reshape(-1,num_parameters)
19938
19938
  with nogil:
19939
19939
  for i in range(num_gens):
19940
19940
  # with gil:
@@ -19952,7 +19952,7 @@ def _from_bitmapi32(image, **slicer_kwargs):
19952
19952
  # print(f"F = {np.asarray(F[i])}")
19953
19953
  slicer = _Slicer(gen_maps, gen_dims, filtration_values)
19954
19954
  return slicer
19955
- def _from_bitmapi64(image, **slicer_kwargs):
19955
+ def _from_bitmapi32(image, **slicer_kwargs):
19956
19956
  from multipers import Slicer
19957
19957
  dtype = slicer_kwargs.get("dtype", image.dtype)
19958
19958
  slicer_kwargs["dtype"] = dtype
@@ -19970,9 +19970,9 @@ def _from_bitmapi64(image, **slicer_kwargs):
19970
19970
  cdef cset[unsigned int] vertices
19971
19971
 
19972
19972
  cdef unsigned int num_gens = gen_dims.size()
19973
- filtration_values = np.zeros(shape=(num_gens, num_parameters), dtype = np.int64) - _Slicer._inf_value()
19974
- cdef int64_t[:,:] F = filtration_values
19975
- cdef int64_t[:,:] c_img = image.reshape(-1,num_parameters)
19973
+ filtration_values = np.zeros(shape=(num_gens, num_parameters), dtype = np.int32) - _Slicer._inf_value()
19974
+ cdef int32_t[:,:] F = filtration_values
19975
+ cdef int32_t[:,:] c_img = image.reshape(-1,num_parameters)
19976
19976
  with nogil:
19977
19977
  for i in range(num_gens):
19978
19978
  # with gil:
@@ -19990,7 +19990,7 @@ def _from_bitmapi64(image, **slicer_kwargs):
19990
19990
  # print(f"F = {np.asarray(F[i])}")
19991
19991
  slicer = _Slicer(gen_maps, gen_dims, filtration_values)
19992
19992
  return slicer
19993
- def _from_bitmapf64(image, **slicer_kwargs):
19993
+ def _from_bitmapi64(image, **slicer_kwargs):
19994
19994
  from multipers import Slicer
19995
19995
  dtype = slicer_kwargs.get("dtype", image.dtype)
19996
19996
  slicer_kwargs["dtype"] = dtype
@@ -20008,9 +20008,9 @@ def _from_bitmapf64(image, **slicer_kwargs):
20008
20008
  cdef cset[unsigned int] vertices
20009
20009
 
20010
20010
  cdef unsigned int num_gens = gen_dims.size()
20011
- filtration_values = np.zeros(shape=(num_gens, num_parameters), dtype = np.float64) - _Slicer._inf_value()
20012
- cdef double[:,:] F = filtration_values
20013
- cdef double[:,:] c_img = image.reshape(-1,num_parameters)
20011
+ filtration_values = np.zeros(shape=(num_gens, num_parameters), dtype = np.int64) - _Slicer._inf_value()
20012
+ cdef int64_t[:,:] F = filtration_values
20013
+ cdef int64_t[:,:] c_img = image.reshape(-1,num_parameters)
20014
20014
  with nogil:
20015
20015
  for i in range(num_gens):
20016
20016
  # with gil:
@@ -20033,12 +20033,12 @@ def from_bitmap(img, **kwargs):
20033
20033
  img = np.asarray(img)
20034
20034
  if img.dtype == np.float32:
20035
20035
  return _from_bitmapf32(img, **kwargs)
20036
+ if img.dtype == np.float64:
20037
+ return _from_bitmapf64(img, **kwargs)
20036
20038
  if img.dtype == np.int32:
20037
20039
  return _from_bitmapi32(img, **kwargs)
20038
20040
  if img.dtype == np.int64:
20039
20041
  return _from_bitmapi64(img, **kwargs)
20040
- if img.dtype == np.float64:
20041
- return _from_bitmapf64(img, **kwargs)
20042
20042
  raise ValueError(f"Invalid dtype. Got {img.dtype=}, was expecting {available_dtype=}.")
20043
20043
 
20044
20044
  def from_function_delaunay(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multipers
3
- Version: 2.3.3b7
3
+ Version: 2.3.4
4
4
  Summary: Multiparameter Topological Persistence for Machine Learning
5
5
  Author-email: David Loiseaux <david.lapous@proton.me>, Hannah Schreiber <hannah.schreiber@inria.fr>
6
6
  Maintainer-email: David Loiseaux <david.lapous@proton.me>
@@ -44,7 +44,7 @@ This library aims to provide easy to use and performant strategies for applied m
44
44
  ## Compiled packages
45
45
  | Source | Version | Downloads | Platforms |
46
46
  | --- | --- | --- | --- |
47
- | [![Conda Recipe](https://img.shields.io/badge/conda-recipe-green.svg)](https://anaconda.org/conda-forge/multipers)| [![Conda Version](https://img.shields.io/conda/vn/conda-forge/multipers.svg)](https://anaconda.org/conda-forge/multipers) | [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/multipers.svg)](https://anaconda.org/conda-forge/multipers) |[![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/multipers.svg)](https://anaconda.org/conda-forge/multipers) |
47
+ | [![Conda Recipe](https://img.shields.io/badge/conda-recipe-green.svg)](https://github.com/conda-forge/multipers-feedstock)| [![Conda Version](https://img.shields.io/conda/vn/conda-forge/multipers.svg)](https://anaconda.org/conda-forge/multipers) | [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/multipers.svg)](https://anaconda.org/conda-forge/multipers) |[![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/multipers.svg)](https://anaconda.org/conda-forge/multipers) |
48
48
  | [![pip Recipe](https://img.shields.io/badge/pip-package-green.svg)](https:///pypi.org/project/multipers) | [![PyPI](https://img.shields.io/pypi/v/multipers?color=green)](https://pypi.org/project/multipers) | [![ pip downloads](https://static.pepy.tech/badge/multipers)](https://pepy.tech/project/multipers) | |
49
49
 
50
50
 
@@ -5,31 +5,31 @@ multipers/distances.py,sha256=uAZj2GtUQp50OxN2qU7sl2JqsmJ74IG9j5tZapLO2Us,6220
5
5
  multipers/filtration_conversions.pxd,sha256=Je7a3F4zS1PQn6Ul1YCXgA6p39X2FouStru-XtN-aOw,10800
6
6
  multipers/filtration_conversions.pxd.tp,sha256=_9tUvZVUA7J_RUM3q7BxY48fYgDHCUA7Xhy4nBfLLs0,3309
7
7
  multipers/filtrations.pxd,sha256=08ONkZNCjs8Nme8lcD9myPz-K662sA-EDpSwzgC2_ts,9461
8
- multipers/function_rips.cp311-win_amd64.pyd,sha256=RWFxbTW_UMnbUyBvLvKpgHKnwA2SwOGh0O3pBGRLe_M,329216
8
+ multipers/function_rips.cp311-win_amd64.pyd,sha256=H-hLVIEsjBDHcLWrdIb8OP4Ou2we8seQLFyYb2Z8u0w,329216
9
9
  multipers/function_rips.pyx,sha256=j5NjbK3YrAv_2s8YHB1JB0k6m9NC7RQCSFlJe-w_kgE,5252
10
- multipers/grids.cp311-win_amd64.pyd,sha256=40ECu2BZwiZ94rquHskEAoDKY6VZ130U8-J7if8GVZ8,471040
11
- multipers/grids.pyx,sha256=4329-4IwlvZKEsmVXrG91kNl1pi-q5RzSrl8EHo2EKk,17981
12
- multipers/io.cp311-win_amd64.pyd,sha256=4DJhyZoKJVdEHTnYTiQqHSHd9-9dhjnlQgxJJX9V07M,223232
10
+ multipers/grids.cp311-win_amd64.pyd,sha256=ZcqWM80HdwoweLREhvKfL6wHaQhTuwkDEd8bjPJAoEk,472576
11
+ multipers/grids.pyx,sha256=ezPMhBKlo9uVGKl5czzoSfOrByThUNup9f8l7ed_poM,18347
12
+ multipers/io.cp311-win_amd64.pyd,sha256=vDwTPsCA7ahWOTPXdwoaeXWsWiyWvd2hiEvb_0EMaXU,223232
13
13
  multipers/io.pyx,sha256=pQBH_rSqaCZqDSxTLnhlyECP3fLbX2tR_RKJHydHm_0,22210
14
- multipers/mma_structures.cp311-win_amd64.pyd,sha256=IzaPaYbSsrTsBlRbuOI2lx6YujikJqSxhs5GS_gdWYM,1325056
14
+ multipers/mma_structures.cp311-win_amd64.pyd,sha256=cuWqpQM9hS8vQraIXXAEqp_0fROGr1U-FgQy3R1HKDU,1325056
15
15
  multipers/mma_structures.pxd,sha256=jh1QnQRidt_VK0CK7losQi6rAl_1qG5DNuR23J42pUA,6595
16
16
  multipers/mma_structures.pyx,sha256=1FQ_sqkpHHkCyCLLKkR9lUgZKDZFt-YgjnDd8NGmw6Q,109526
17
17
  multipers/mma_structures.pyx.tp,sha256=QLo4ZZDnFuWNot771jYkYHc9ZQq6CJIpkRkeRwGi7XA,42297
18
18
  multipers/multiparameter_edge_collapse.py,sha256=MFt0eKQQSv2354omeIqOmzASYTKIMsYdxZHFZauQr8g,1229
19
- multipers/multiparameter_module_approximation.cp311-win_amd64.pyd,sha256=T-6dMmP8-h5cI6NbIYkXirhPYfDdltMkZle81TsURY4,446976
19
+ multipers/multiparameter_module_approximation.cp311-win_amd64.pyd,sha256=V97xdna4tP9kyfa5rIXevVIjEpTj0oCA3TiJab12168,446976
20
20
  multipers/multiparameter_module_approximation.pyx,sha256=wp7la7Z9wBngnfw6WOVddf93mPyXf4HfNT6dKW2Z0r0,9030
21
21
  multipers/pickle.py,sha256=YYVt4iHiD16E1x5Yn_4mX6P5P8rKi56pNGjJo5IzPhc,2579
22
- multipers/plots.py,sha256=ZJmOD5fgy0y_U-rjhR6pZ2WD8HFndpKMh5IKlU62QkI,14918
23
- multipers/point_measure.cp311-win_amd64.pyd,sha256=N_jua2uY_3XL50p4YGewUuekiJxSw2fk8ep9DjcXtH8,621056
22
+ multipers/plots.py,sha256=E1_O6A8335pr87nFkwgKD0DesEw94hk3iIih1Eh5Cxk,15383
23
+ multipers/point_measure.cp311-win_amd64.pyd,sha256=KkMI1OhURBgt0okLVFWeRp-7Jx9CvifCa63Vbwit1T4,621056
24
24
  multipers/point_measure.pyx,sha256=ovpyvjMdOPBOK_0TT0VoK4b2t8m5InFdKmRBB6biTts,14077
25
- multipers/simplex_tree_multi.cp311-win_amd64.pyd,sha256=pn-P5okSW4rivKaHAqI-K4A57N9ggSYsJwLxLYN8JG4,3756032
26
- multipers/simplex_tree_multi.pxd,sha256=KpyDEQNPoMC2sOU9-d4LtrGXx_UVCJGxMJ1kk1AzHgU,6631
27
- multipers/simplex_tree_multi.pyx,sha256=13x2WFMExcukd_2CrLOJa3Edex3WNqaSSrGBmPhYoDM,499100
28
- multipers/simplex_tree_multi.pyx.tp,sha256=YFzVUJPWNOOpRiyOgaYlFR_DJ_57rAQLsOp2W0l71_s,89318
29
- multipers/slicer.cp311-win_amd64.pyd,sha256=9B_z0W4s3mL-4tg8nnuEMliJ2StcvI7VriXFI4Eh7Fo,11618816
25
+ multipers/simplex_tree_multi.cp311-win_amd64.pyd,sha256=QFA6MKVWcZQlAQEftzZXlSJ36k-X1y3l6Qe6uQCSmF8,3798528
26
+ multipers/simplex_tree_multi.pxd,sha256=KBX_vcNgtBjNHThUUOXp0r4HWj3EX1DGa6cX9mDi6aI,6649
27
+ multipers/simplex_tree_multi.pyx,sha256=hUNgepiG0Dw6f2_9oPZm8YUcyDtB4P_Wk_ChuzvIOOY,504888
28
+ multipers/simplex_tree_multi.pyx.tp,sha256=HYxL1AmtsS-HRpBJa5JtPqX73k2Xkqopn8OYZRb397Q,89276
29
+ multipers/slicer.cp311-win_amd64.pyd,sha256=Me-BkTwV0hF_c3yePnNRQ53IrOb1_0sarrR5W-2kfgg,11618816
30
30
  multipers/slicer.pxd,sha256=bHcV5COzDcjhaVcL3bWSHivUYtdkSx4bdj24fVOe_DU,185230
31
31
  multipers/slicer.pxd.tp,sha256=fLOUPtPGqiY9o1fPDyc_whBrgKLh_6HVfvl7OtE-34Y,10243
32
- multipers/slicer.pyx,sha256=fQ0zZwgwWZPXWw_rKvMCwbHXw2RQTJFSLkxiEHrrzVE,894493
32
+ multipers/slicer.pyx,sha256=I0pqvRIJqCj326lcTlSHBHhEiV0lXxaIOgQCQCowJKM,894493
33
33
  multipers/slicer.pyx.tp,sha256=GCL7xUZccfmnIoY4bk05L5ODkSNzEzXgodp0VkH-xT8,44584
34
34
  multipers/tbb12.dll,sha256=flSoIAkNVECA5vNkh5jLn1jcZNxTw3yb2tuTtxn6oEE,344576
35
35
  multipers/tbbbind_2_5.dll,sha256=4JWlgl4aJJ3m5NIE85AgQi46REU3UkIJwNsKnh9aK_c,23552
@@ -38,8 +38,8 @@ multipers/tbbmalloc_proxy.dll,sha256=5vcuiOpM9KTAY7daWxCsAc2MU_l8K3TWpw0kz-Xh0sk
38
38
  multipers/tensor.pxd,sha256=MSmaMU0sOP9CHLmg4dym7nOGaI1S4cOdM01TQ9flI54,417
39
39
  multipers/test.pyx,sha256=-g7WU-jKrZK8H0c-6eAPsfrApjvTKrUoswVYFu8LoV4,1798
40
40
  multipers/array_api/__init__.py,sha256=jyvi7Gzd7Si_imgaodz80fcA-68MikAGk8g79_vj6yo,1545
41
- multipers/array_api/numpy.py,sha256=HZHJitXSb2Y3f-JNg47afmYoExgqT6dOx7sfcM9vvaA,2324
42
- multipers/array_api/torch.py,sha256=7PKiSgA4TCaTspsC7wiMXUtHgSiTfSFyNtuMYU31xNo,2550
41
+ multipers/array_api/numpy.py,sha256=5XfqM4_ykFtCsn0Rel0qPceEXyzhu-6ekkbsM_94kM8,2439
42
+ multipers/array_api/torch.py,sha256=cTtwOhZXT-UWYnQJe3rVPcs0f0jm6saxdMmWEmr9I5Q,2553
43
43
  multipers/data/MOL2.py,sha256=nLZHy2OSFN9Z2uJKsbqWOEG2R7G-uH6dCLHG48UjvR4,15428
44
44
  multipers/data/UCR.py,sha256=PuT8l3i26y0goBzIESwdgJAe6YFCyDiWSoxECcP5rhs,798
45
45
  multipers/data/__init__.py,sha256=w7uUe4LOHbdbKU4R8MNs7em65wZJN0v5ukoG1otFanQ,24
@@ -51,7 +51,7 @@ multipers/data/shape3d.py,sha256=AE-vvjKrhKxOwMo-lurUsFqqLjIg5obo-RTbRZF_5Mk,389
51
51
  multipers/data/synthetic.py,sha256=RvLWIBE5j99kJSt-D7cnPGI3c7skD4p8_qofJbMIXM0,3078
52
52
  multipers/filtrations/__init__.py,sha256=Lg0EHe2cxT32UQAg0kr_Vpua-xPBZxGol8VIfz8UwWk,319
53
53
  multipers/filtrations/density.py,sha256=XNPHCwyC8FwAdSfNp1ofxcxfP5ZFGZ6K-DUeXsfM4eg,18155
54
- multipers/filtrations/filtrations.py,sha256=r3WS4GMBvcJ0ryIMbNHFgep0FCtl3h404V_SbMM8hN0,13333
54
+ multipers/filtrations/filtrations.py,sha256=O2WK3KBmClYvQH4Hr-9rsq3RJqcPjP8Q3Sjsi7Un6jU,13378
55
55
  multipers/gudhi/Persistence_slices_interface.h,sha256=QnUeCCKi9K8CfqI3W5i3Ra1Jy2Z1IIivr3MIpnBsnYU,6562
56
56
  multipers/gudhi/Simplex_tree_interface.h,sha256=kkq8pE3jKGLY1dK7sYpb_uERHaWGurrRXfaw_ygs-mY,10217
57
57
  multipers/gudhi/Simplex_tree_multi_interface.h,sha256=7D9EqyO9dgi-VMTf-O8SR2UMQL95q_TL9ApmmN4ggFw,25484
@@ -68,7 +68,7 @@ multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h
68
68
  multipers/gudhi/gudhi/Debug_utils.h,sha256=aps-ljywN_mfNSVmx2LB1lMJ7-RrzfMr5LScXBTFZ5M,1590
69
69
  multipers/gudhi/gudhi/Flag_complex_edge_collapser.h,sha256=DQ_wyOG3z09jX6sq_79oTxZM_Z5Hi_zIZ_LL1EFMLAw,13247
70
70
  multipers/gudhi/gudhi/Matrix.h,sha256=bxCmhdWbxATmrw36GgKkIgZZM9xkCZPz4cJNNDG8qoI,115997
71
- multipers/gudhi/gudhi/Multi_critical_filtration.h,sha256=RDbMBMJtccxX1EtM59bVgL7uucjUUvFZhYb23kphpV8,42589
71
+ multipers/gudhi/gudhi/Multi_critical_filtration.h,sha256=-8zy7lucCRqAD8Wv3ztmVhvHEzW4vkatfKqXDyqWi9k,42594
72
72
  multipers/gudhi/gudhi/Off_reader.h,sha256=Owwc7wgQzOgq4URfA3V5c9v_8IY6ODKXeZefjFk8Kok,4871
73
73
  multipers/gudhi/gudhi/One_critical_filtration.h,sha256=p7XLYfWtOqwxtoj9GnlYOQ-DuuP1O9SWp4Qz6BqMv10,53638
74
74
  multipers/gudhi/gudhi/Persistent_cohomology.h,sha256=UEy1ae9YBamWICDwA120lolIYlt14ExZjr7VFJZaCzI,30725
@@ -178,8 +178,8 @@ multipers/tests/__init__.py,sha256=-7Fj-zFAfBJv18trg0CPglQTmYu_ehySZGqtJzPlN8U,1
178
178
  multipers/torch/__init__.py,sha256=OLxIiZ389uCqehpUxBPUI_x1SYu531onc4tiTscAuIw,27
179
179
  multipers/torch/diff_grids.py,sha256=2YK-c351tBpj8sfzjf26fbE1l0xlWse7oVVfDHD3zwM,7492
180
180
  multipers/torch/rips_density.py,sha256=H-kmSzY8hXhmVn15Oltc71DHs1IUHg5oPRgNyWW8L4Q,11706
181
- multipers-2.3.3b7.dist-info/licenses/LICENSE,sha256=UsQRnvlo_9wpQS9DNt52GEraERHwK2GIRwuqr2Yv5JI,1071
182
- multipers-2.3.3b7.dist-info/METADATA,sha256=rWZTaAJnyv6X11zYE1N_EMCUrmhHZ4bmaK_uG4E7Ma8,9817
183
- multipers-2.3.3b7.dist-info/WHEEL,sha256=JLOMsP7F5qtkAkINx5UnzbFguf8CqZeraV8o04b0I8I,101
184
- multipers-2.3.3b7.dist-info/top_level.txt,sha256=L9e0AGmhRzrNw9FpuUx-zlqi5NcBOmrI9wYY8kYWr8A,10
185
- multipers-2.3.3b7.dist-info/RECORD,,
181
+ multipers-2.3.4.dist-info/licenses/LICENSE,sha256=UsQRnvlo_9wpQS9DNt52GEraERHwK2GIRwuqr2Yv5JI,1071
182
+ multipers-2.3.4.dist-info/METADATA,sha256=yKi_0X_lBr3ivsS1mxPrZzR-lpR3myBPemRiMBAadOg,9823
183
+ multipers-2.3.4.dist-info/WHEEL,sha256=JLOMsP7F5qtkAkINx5UnzbFguf8CqZeraV8o04b0I8I,101
184
+ multipers-2.3.4.dist-info/top_level.txt,sha256=L9e0AGmhRzrNw9FpuUx-zlqi5NcBOmrI9wYY8kYWr8A,10
185
+ multipers-2.3.4.dist-info/RECORD,,