multipers 2.3.2__cp312-cp312-win_amd64.whl → 2.3.3b1__cp312-cp312-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.

Binary file
Binary file
Binary file
multipers/plots.py CHANGED
@@ -2,13 +2,16 @@ from typing import Optional
2
2
 
3
3
  import matplotlib.pyplot as plt
4
4
  import numpy as np
5
+ from numpy.typing import ArrayLike
5
6
 
6
7
  try:
7
8
  import torch
9
+
8
10
  istensor = torch.is_tensor
9
11
  except ImportError:
10
12
  istensor = lambda x: False
11
13
 
14
+
12
15
  def _plot_rectangle(rectangle: np.ndarray, weight, **plt_kwargs):
13
16
  rectangle = np.asarray(rectangle)
14
17
  x_axis = rectangle[[0, 2]]
@@ -137,7 +140,9 @@ def plot_signed_measure(signed_measure, threshold=None, ax=None, **plt_kwargs):
137
140
  else:
138
141
  pts_ = pts
139
142
  threshold = np.max(np.ma.masked_invalid(pts_), axis=0)
140
- threshold = np.max([threshold, [plt.gca().get_xlim()[1], plt.gca().get_ylim()[1]]], axis=0)
143
+ threshold = np.max(
144
+ [threshold, [plt.gca().get_xlim()[1], plt.gca().get_ylim()[1]]], axis=0
145
+ )
141
146
  if isinstance(pts, np.ndarray):
142
147
  pass
143
148
  else:
@@ -255,7 +260,7 @@ def plot2d_PyModule(
255
260
  dimension=-1,
256
261
  separated=False,
257
262
  min_persistence=0,
258
- alpha=.8,
263
+ alpha=0.8,
259
264
  verbose=False,
260
265
  save=False,
261
266
  dpi=200,
@@ -341,3 +346,84 @@ def plot2d_PyModule(
341
346
  if dimension >= 0:
342
347
  plt.title(rf"$H_{dimension}$ $2$-persistence")
343
348
  return
349
+
350
+
351
+ def plot_simplicial_complex(
352
+ st, pts: ArrayLike, x: float, y: float, mma=None, degree=None
353
+ ):
354
+ """
355
+ Scatters the points, with the simplices in the filtration at coordinates (x,y).
356
+ if an mma module is given, plots it in a second axis
357
+ """
358
+ if mma is not None:
359
+ fig, (a, b) = plt.subplots(ncols=2, figsize=(15, 5))
360
+ plt.sca(a)
361
+ plot_simplicial_complex(st, pts, x, y)
362
+ plt.sca(b)
363
+ mma.plot(degree=degree)
364
+ box = mma.get_box()
365
+ a, b, c, d = box.ravel()
366
+ mma.plot(degree=1, min_persistence=0.01)
367
+ plt.vlines(x, b, d, color="k", linestyle="--")
368
+ plt.hlines(y, a, c, color="k", linestyle="--")
369
+ plt.scatter([x], [y], c="r", zorder=10)
370
+ plt.text(x + 0.01 * (b - a), y + 0.01 * (d - c), f"({x},{y})")
371
+ return
372
+
373
+ pts = np.asarray(pts)
374
+ values = np.array([-f[1] for s, f in st.get_skeleton(0)])
375
+ qs = np.quantile(values, np.linspace(0, 1, 100))
376
+ color_idx = lambda d: np.searchsorted(qs, d) / 100
377
+
378
+ from matplotlib.pyplot import get_cmap
379
+
380
+ color = lambda d: get_cmap("viridis")([0, color_idx(d), 1])[1]
381
+ cols_pc = np.asarray([color(v) for v in values])
382
+ ax = plt.gca()
383
+ for s, f in st: ## simplexe, filtration
384
+ density = -f[1]
385
+ if len(s) <= 1 or f[0] > x or density < -y: ## simplexe = point
386
+ continue
387
+ if len(s) == 2: ## simplexe = segment
388
+ xx = np.array([pts[a, 0] for a in s])
389
+ yy = np.array([pts[a, 1] for a in s])
390
+ plt.plot(xx, yy, c=color(density), alpha=1, zorder=10 * density, lw=1.5)
391
+ if len(s) == 3: ## simplexe = triangle
392
+ xx = np.array([pts[a, 0] for a in s])
393
+ yy = np.array([pts[a, 1] for a in s])
394
+ _c = color(density)
395
+ ax.fill(xx, yy, c=_c, alpha=0.3, zorder=0)
396
+ out = plt.scatter(pts[:, 0], pts[:, 1], c=cols_pc, zorder=10, s=10)
397
+ ax.set_aspect(1)
398
+ return out
399
+
400
+
401
+ def plot_point_cloud(pts, function, x, y, mma=None, degree=None):
402
+ if mma is not None:
403
+ fig, (a, b) = plt.subplots(ncols=2, figsize=(15, 5))
404
+ plt.sca(a)
405
+ plot_point_cloud(pts, function, x, y)
406
+ plt.sca(b)
407
+ mma.plot(degree=degree)
408
+ box = mma.get_box()
409
+ a, b, c, d = box.ravel()
410
+ mma.plot(degree=1, min_persistence=0.01)
411
+ plt.vlines(x, b, d, color="k", linestyle="--")
412
+ plt.hlines(y, a, c, color="k", linestyle="--")
413
+ plt.scatter([x], [y], c="r", zorder=10)
414
+ plt.text(x + 0.01 * (b - a), y + 0.01 * (d - c), f"({x},{y})")
415
+ return
416
+ values = 1 - function
417
+ qs = np.quantile(values, np.linspace(0, 1, 100))
418
+ color_idx = lambda d: np.searchsorted(qs, d) / 100
419
+ from matplotlib.pyplot import get_cmap
420
+ from matplotlib.collections import PatchCollection
421
+
422
+ color = lambda d: get_cmap("viridis")([0, color_idx(d), 1])[1]
423
+ ax = plt.gca()
424
+ idx = function <= y
425
+ circles = [plt.Circle(pt, x, color=color(c)) for pt, c in zip(pts[idx], function)]
426
+ pc = PatchCollection(circles, alpha=0.3)
427
+ ax.add_collection(pc)
428
+ plt.scatter(*pts.T, c=-function, s=20)
429
+ ax.set_aspect(1)
Binary file
Binary file
multipers/slicer.pyx CHANGED
@@ -19876,7 +19876,7 @@ cdef extern from "gudhi/cubical_to_boundary.h" namespace "":
19876
19876
  void _to_boundary(const vector[unsigned int]&, vector[vector[unsigned int]]&, vector[int]&) except + nogil
19877
19877
  void get_vertices(unsigned int, cset[unsigned int]&, const vector[vector[unsigned int]]&) nogil
19878
19878
 
19879
- def _from_bitmapf64(image, **slicer_kwargs):
19879
+ def _from_bitmapf32(image, **slicer_kwargs):
19880
19880
  from multipers import Slicer
19881
19881
  dtype = slicer_kwargs.get("dtype", image.dtype)
19882
19882
  slicer_kwargs["dtype"] = dtype
@@ -19894,9 +19894,9 @@ def _from_bitmapf64(image, **slicer_kwargs):
19894
19894
  cdef cset[unsigned int] vertices
19895
19895
 
19896
19896
  cdef unsigned int num_gens = gen_dims.size()
19897
- filtration_values = np.zeros(shape=(num_gens, num_parameters), dtype = np.float64) - _Slicer._inf_value()
19898
- cdef double[:,:] F = filtration_values
19899
- cdef double[:,:] c_img = image.reshape(-1,num_parameters)
19897
+ filtration_values = np.zeros(shape=(num_gens, num_parameters), dtype = np.float32) - _Slicer._inf_value()
19898
+ cdef float[:,:] F = filtration_values
19899
+ cdef float[:,:] c_img = image.reshape(-1,num_parameters)
19900
19900
  with nogil:
19901
19901
  for i in range(num_gens):
19902
19902
  # with gil:
@@ -19914,7 +19914,7 @@ def _from_bitmapf64(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_bitmapi64(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.int64) - _Slicer._inf_value()
19936
+ cdef int64_t[:,:] F = filtration_values
19937
+ cdef int64_t[:,:] 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_bitmapf32(image, **slicer_kwargs):
19993
+ def _from_bitmapf64(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_bitmapf32(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.float32) - _Slicer._inf_value()
20012
- cdef float[:,:] F = filtration_values
20013
- cdef float[:,:] c_img = image.reshape(-1,num_parameters)
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)
20014
20014
  with nogil:
20015
20015
  for i in range(num_gens):
20016
20016
  # with gil:
@@ -20031,14 +20031,14 @@ def _from_bitmapf32(image, **slicer_kwargs):
20031
20031
 
20032
20032
  def from_bitmap(img, **kwargs):
20033
20033
  img = np.asarray(img)
20034
- if img.dtype == np.float64:
20035
- return _from_bitmapf64(img, **kwargs)
20036
- if img.dtype == np.int32:
20037
- return _from_bitmapi32(img, **kwargs)
20038
- if img.dtype == np.int64:
20039
- return _from_bitmapi64(img, **kwargs)
20040
20034
  if img.dtype == np.float32:
20041
20035
  return _from_bitmapf32(img, **kwargs)
20036
+ if img.dtype == np.int64:
20037
+ return _from_bitmapi64(img, **kwargs)
20038
+ if img.dtype == np.int32:
20039
+ return _from_bitmapi32(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.2
3
+ Version: 2.3.3b1
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>
@@ -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.cp312-win_amd64.pyd,sha256=d2t6dH0Jndk-gctt7BBBpiJ-E5LAZ83P0vxV1cqoAIE,333312
8
+ multipers/function_rips.cp312-win_amd64.pyd,sha256=AJ0if5RRyDIX8WeUTfZC8G8Rnd-DdncUdWaOpVuABRw,333312
9
9
  multipers/function_rips.pyx,sha256=j5NjbK3YrAv_2s8YHB1JB0k6m9NC7RQCSFlJe-w_kgE,5252
10
- multipers/grids.cp312-win_amd64.pyd,sha256=diyjoFp5eUiqeYazRHmlVSC1v0FqwEKv7ElEvmW0rEw,480768
10
+ multipers/grids.cp312-win_amd64.pyd,sha256=NIc7-FDDODdTHkwYnTTxLcs_yNPjh6yyB6ETv1QXoWA,480768
11
11
  multipers/grids.pyx,sha256=ONN_RKkuxqwb9IaS9gd42FUGaiBLc8QWcd3L-ubZjKE,16575
12
- multipers/io.cp312-win_amd64.pyd,sha256=9H8IuoqgtL061DdbHv3kTwvFfvrAGX6NLy_1c1lC3XA,221184
12
+ multipers/io.cp312-win_amd64.pyd,sha256=ffxPHz9pKUpETris9JxRXEtbRzlzf4RlDgaBEQZ466g,221184
13
13
  multipers/io.pyx,sha256=pQBH_rSqaCZqDSxTLnhlyECP3fLbX2tR_RKJHydHm_0,22210
14
- multipers/mma_structures.cp312-win_amd64.pyd,sha256=bFGuedM1PdOMa9HT0OdkT-GGf2vJEQDvuV5Mmf_Xltw,1302528
14
+ multipers/mma_structures.cp312-win_amd64.pyd,sha256=SvgW2bSzaY5Wtnww1lslrFMUUlmewEI1GYKJaOlGA7Y,1302528
15
15
  multipers/mma_structures.pxd,sha256=jh1QnQRidt_VK0CK7losQi6rAl_1qG5DNuR23J42pUA,6595
16
16
  multipers/mma_structures.pyx,sha256=4zNC6ePfFKMvx0MrH-FqJVouyTMciRc49oevKDnsJhI,109530
17
17
  multipers/mma_structures.pyx.tp,sha256=hWuuk9USDFa8CbQVRHNjWSAdGgpkWKvSCNjTtVuSzwM,42299
18
18
  multipers/multiparameter_edge_collapse.py,sha256=MFt0eKQQSv2354omeIqOmzASYTKIMsYdxZHFZauQr8g,1229
19
- multipers/multiparameter_module_approximation.cp312-win_amd64.pyd,sha256=CzTAhHjOaJRfvaE7D8xKg24m7mb-AuiMY7t9LdBoJ24,457728
19
+ multipers/multiparameter_module_approximation.cp312-win_amd64.pyd,sha256=0hntlxYoA9drxAvAhluzh5rhuZMfNcI70wiJB6q4etE,457728
20
20
  multipers/multiparameter_module_approximation.pyx,sha256=wp7la7Z9wBngnfw6WOVddf93mPyXf4HfNT6dKW2Z0r0,9030
21
21
  multipers/pickle.py,sha256=YYVt4iHiD16E1x5Yn_4mX6P5P8rKi56pNGjJo5IzPhc,2579
22
- multipers/plots.py,sha256=qE08IhzCIDBUsqbxbuxDsMf2T1SBRCSeeys2dpn7I9U,11236
23
- multipers/point_measure.cp312-win_amd64.pyd,sha256=XbfvbxguUx7ix33TXGBJIuRc-LHurU0O7zBnFOh1WWc,585728
22
+ multipers/plots.py,sha256=9yLuNLJ3XefALKTbdtGu6cJfOt0faXyE0bMGDyFRL4g,14417
23
+ multipers/point_measure.cp312-win_amd64.pyd,sha256=HyJES-KCkQoUjpCE1DFYgECfLqpJ_BeqB6utd_kFAc0,585728
24
24
  multipers/point_measure.pyx,sha256=DVhal6HgCCuALSJMcHHKOW16CwDQCVTc2PpK8cGCqx8,12109
25
- multipers/simplex_tree_multi.cp312-win_amd64.pyd,sha256=P-iJpYtJwfyXkXgmc2aJ6tBf8eNCgGbuGIagDqvHfXk,3605504
25
+ multipers/simplex_tree_multi.cp312-win_amd64.pyd,sha256=YMrwGX2OzFFtgaxyrVUnSYdj8Qq47K3n8-FmAjNrgNU,3605504
26
26
  multipers/simplex_tree_multi.pxd,sha256=KpyDEQNPoMC2sOU9-d4LtrGXx_UVCJGxMJ1kk1AzHgU,6631
27
27
  multipers/simplex_tree_multi.pyx,sha256=reHyva5AR1lOQyiCs2_jQ2XfwHtktcQ1nmY_BNmyxhk,498156
28
28
  multipers/simplex_tree_multi.pyx.tp,sha256=fUTuIscfDlNjsImWU1YALVZ1Mf9OEkdl-IFKcRQqalI,89202
29
- multipers/slicer.cp312-win_amd64.pyd,sha256=LA5MNKgKfBxCFOwax_i4_7yeGDpMh4cSplovTHBN5MY,11771904
29
+ multipers/slicer.cp312-win_amd64.pyd,sha256=PmybWHUqg8z1Snw4xY1rr8mXdlh7-HxC3cwpGWjvlIY,11772416
30
30
  multipers/slicer.pxd,sha256=fzA-lL_QWyUMf9rRSpcKG35QNS9UXEmVC9r7kR0geho,185230
31
31
  multipers/slicer.pxd.tp,sha256=fLOUPtPGqiY9o1fPDyc_whBrgKLh_6HVfvl7OtE-34Y,10243
32
- multipers/slicer.pyx,sha256=aXwQ7HVF0cQ4a2PrmIcGl_a3N7h1UBSMl1wIrZs63WQ,894068
32
+ multipers/slicer.pyx,sha256=r_-8a-peMXe43r9OUgyKIDKxKgIq-U7hhSLYOn7Fka4,894068
33
33
  multipers/slicer.pyx.tp,sha256=0oSaqT6-traFiDW9R3IFRQ-u0kYle9Hum8xVzkVsa3c,44550
34
34
  multipers/tbb12.dll,sha256=6AsPR4GauU53hj2xqJNM0SfLkCKCDskjy-uKeS01tCk,338944
35
35
  multipers/tbbbind_2_5.dll,sha256=8TtH7JJZlCEKF0UwfyJoiyrFt9utOI_x5AFOxpP-pGw,23040
@@ -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.2.dist-info/licenses/LICENSE,sha256=UsQRnvlo_9wpQS9DNt52GEraERHwK2GIRwuqr2Yv5JI,1071
182
- multipers-2.3.2.dist-info/METADATA,sha256=mnYnepTC_P_J1PoIYU7rSkfEnylYH1O02xdXlOrz0QM,9670
183
- multipers-2.3.2.dist-info/WHEEL,sha256=RYNUKzg4pggqpqERKe4OLbPF4ZPP-Ng-rmq_sekLDXg,101
184
- multipers-2.3.2.dist-info/top_level.txt,sha256=L9e0AGmhRzrNw9FpuUx-zlqi5NcBOmrI9wYY8kYWr8A,10
185
- multipers-2.3.2.dist-info/RECORD,,
181
+ multipers-2.3.3b1.dist-info/licenses/LICENSE,sha256=UsQRnvlo_9wpQS9DNt52GEraERHwK2GIRwuqr2Yv5JI,1071
182
+ multipers-2.3.3b1.dist-info/METADATA,sha256=MU-U7yqOEIFamD8-E2ctFsjHx2xpWJXSpbV6JEiSPXQ,9672
183
+ multipers-2.3.3b1.dist-info/WHEEL,sha256=8UP9x9puWI0P1V_d7K2oMTBqfeLNm21CTzZ_Ptr0NXU,101
184
+ multipers-2.3.3b1.dist-info/top_level.txt,sha256=L9e0AGmhRzrNw9FpuUx-zlqi5NcBOmrI9wYY8kYWr8A,10
185
+ multipers-2.3.3b1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp312-cp312-win_amd64
5
5