multipers 2.0.0__cp310-cp310-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of multipers might be problematic. Click here for more details.

Files changed (78) hide show
  1. multipers/.dylibs/libc++.1.0.dylib +0 -0
  2. multipers/.dylibs/libtbb.12.12.dylib +0 -0
  3. multipers/.dylibs/libtbbmalloc.2.12.dylib +0 -0
  4. multipers/__init__.py +11 -0
  5. multipers/_signed_measure_meta.py +268 -0
  6. multipers/_slicer_meta.py +171 -0
  7. multipers/data/MOL2.py +350 -0
  8. multipers/data/UCR.py +18 -0
  9. multipers/data/__init__.py +1 -0
  10. multipers/data/graphs.py +466 -0
  11. multipers/data/immuno_regions.py +27 -0
  12. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  13. multipers/data/pytorch2simplextree.py +91 -0
  14. multipers/data/shape3d.py +101 -0
  15. multipers/data/synthetic.py +68 -0
  16. multipers/distances.py +198 -0
  17. multipers/euler_characteristic.pyx +132 -0
  18. multipers/filtration_conversions.pxd +229 -0
  19. multipers/filtrations.pxd +225 -0
  20. multipers/function_rips.cpython-310-darwin.so +0 -0
  21. multipers/function_rips.pyx +105 -0
  22. multipers/grids.cpython-310-darwin.so +0 -0
  23. multipers/grids.pyx +281 -0
  24. multipers/hilbert_function.pyi +46 -0
  25. multipers/hilbert_function.pyx +153 -0
  26. multipers/io.cpython-310-darwin.so +0 -0
  27. multipers/io.pyx +571 -0
  28. multipers/ml/__init__.py +0 -0
  29. multipers/ml/accuracies.py +90 -0
  30. multipers/ml/convolutions.py +532 -0
  31. multipers/ml/invariants_with_persistable.py +79 -0
  32. multipers/ml/kernels.py +176 -0
  33. multipers/ml/mma.py +659 -0
  34. multipers/ml/one.py +472 -0
  35. multipers/ml/point_clouds.py +238 -0
  36. multipers/ml/signed_betti.py +50 -0
  37. multipers/ml/signed_measures.py +1542 -0
  38. multipers/ml/sliced_wasserstein.py +461 -0
  39. multipers/ml/tools.py +113 -0
  40. multipers/mma_structures.cpython-310-darwin.so +0 -0
  41. multipers/mma_structures.pxd +127 -0
  42. multipers/mma_structures.pyx +2433 -0
  43. multipers/multiparameter_edge_collapse.py +41 -0
  44. multipers/multiparameter_module_approximation.cpython-310-darwin.so +0 -0
  45. multipers/multiparameter_module_approximation.pyx +211 -0
  46. multipers/pickle.py +53 -0
  47. multipers/plots.py +326 -0
  48. multipers/point_measure_integration.cpython-310-darwin.so +0 -0
  49. multipers/point_measure_integration.pyx +139 -0
  50. multipers/rank_invariant.cpython-310-darwin.so +0 -0
  51. multipers/rank_invariant.pyx +229 -0
  52. multipers/simplex_tree_multi.cpython-310-darwin.so +0 -0
  53. multipers/simplex_tree_multi.pxd +129 -0
  54. multipers/simplex_tree_multi.pyi +715 -0
  55. multipers/simplex_tree_multi.pyx +4655 -0
  56. multipers/slicer.cpython-310-darwin.so +0 -0
  57. multipers/slicer.pxd +781 -0
  58. multipers/slicer.pyx +3393 -0
  59. multipers/tensor.pxd +13 -0
  60. multipers/test.pyx +44 -0
  61. multipers/tests/__init__.py +40 -0
  62. multipers/tests/old_test_rank_invariant.py +91 -0
  63. multipers/tests/test_diff_helper.py +74 -0
  64. multipers/tests/test_hilbert_function.py +82 -0
  65. multipers/tests/test_mma.py +51 -0
  66. multipers/tests/test_point_clouds.py +59 -0
  67. multipers/tests/test_python-cpp_conversion.py +82 -0
  68. multipers/tests/test_signed_betti.py +181 -0
  69. multipers/tests/test_simplextreemulti.py +98 -0
  70. multipers/tests/test_slicer.py +63 -0
  71. multipers/torch/__init__.py +1 -0
  72. multipers/torch/diff_grids.py +217 -0
  73. multipers/torch/rips_density.py +257 -0
  74. multipers-2.0.0.dist-info/LICENSE +21 -0
  75. multipers-2.0.0.dist-info/METADATA +29 -0
  76. multipers-2.0.0.dist-info/RECORD +78 -0
  77. multipers-2.0.0.dist-info/WHEEL +5 -0
  78. multipers-2.0.0.dist-info/top_level.txt +1 -0
multipers/tensor.pxd ADDED
@@ -0,0 +1,13 @@
1
+ from libc.stdint cimport uint16_t
2
+ from libcpp.vector cimport vector
3
+ from libcpp cimport bool, float
4
+
5
+
6
+ ctypedef float dtype
7
+ ctypedef uint16_t index_type
8
+
9
+ cdef extern from "tensor/tensor.h" namespace "tensor":
10
+ cdef cppclass static_tensor_view[float, uint16_t]:
11
+ static_tensor_view() except + nogil
12
+ static_tensor_view(dtype*,const vector[index_type]&) except + nogil
13
+ const vector[index_type]& get_resolution()
multipers/test.pyx ADDED
@@ -0,0 +1,44 @@
1
+ # cimport multipers.tensor as mt
2
+ from libc.stdint cimport intptr_t, uint16_t
3
+ from libcpp.vector cimport vector
4
+ from libcpp cimport bool, int, float
5
+ from libcpp.utility cimport pair
6
+ from typing import Optional,Iterable,Callable
7
+
8
+
9
+ ctypedef float value_type
10
+ # ctypedef uint16_t index_type
11
+
12
+ import numpy as np
13
+ # cimport numpy as cnp
14
+ # cnp.import_array()
15
+
16
+ # cdef extern from "multi_parameter_rank_invariant/rank_invariant.h" namespace "Gudhi::rank_invariant":
17
+ # void get_hilbert_surface(const intptr_t, mt.static_tensor_view, const vector[index_type], const vector[index_type], index_type, index_type, const vector[index_type], bool, bool) except + nogil
18
+
19
+
20
+ from multipers.simplex_tree_multi import SimplexTreeMulti
21
+
22
+
23
+ def numpy_to_tensor(array:np.ndarray):
24
+ cdef vector[index_type] shape = array.shape
25
+ cdef dtype[::1] contigus_array_view = np.ascontiguousarray(array)
26
+ cdef dtype* dtype_ptr = &contigus_array_view[0]
27
+ cdef mt.static_tensor_view tensor
28
+ with nogil:
29
+ tensor = mt.static_tensor_view(dtype_ptr, shape)
30
+ return tensor.get_resolution()
31
+
32
+ # def hilbert2d(simplextree:SimplexTreeMulti, grid_shape:np.ndarray|list, vector[index_type] degrees, bool mobius_inversion):
33
+ # # assert simplextree.num_parameters == 2
34
+ # cdef intptr_t ptr = simplextree.thisptr
35
+ # cdef vector[index_type] c_grid_shape = grid_shape
36
+ # cdef dtype[::1] container = np.zeros(grid_shape, dtype=np.float32).flatten()
37
+ # cdef dtype* container_ptr = &container[0]
38
+ # cdef mt.static_tensor_view c_container = mt.static_tensor_view(container_ptr, c_grid_shape)
39
+ # cdef index_type i = 0
40
+ # cdef index_type j = 1
41
+ # cdef vector[index_type] fixed_values = [[],[]]
42
+ # # get_hilbert_surface(ptr, c_container, c_grid_shape, degrees,i,j,fixed_values, False, False)
43
+ # return container.reshape(grid_shape)
44
+
@@ -0,0 +1,40 @@
1
+ import numpy as np
2
+
3
+
4
+ def assert_st_simplices(st, dump):
5
+ """
6
+ Checks that the simplextree has the same
7
+ filtration as the dump.
8
+ """
9
+
10
+ assert np.all(
11
+ [
12
+ np.isclose(a, b).all()
13
+ for x, y in zip(st.get_simplices(), dump, strict=True)
14
+ for a, b in zip(x, y, strict=True)
15
+ ]
16
+ )
17
+
18
+
19
+ def sort_sm(sms):
20
+ idx = np.argsort([sm[0][:, 0] for sm in sms])
21
+ return tuple((sm[0][idx], sm[1][idx]) for sm in sms)
22
+
23
+
24
+ def assert_sm(sm1, sm2, exact=True, max_error=1e-5):
25
+ if not exact:
26
+ from multipers.distances import sm_distance
27
+
28
+ for sm1_, sm2_ in zip(sm1, sm2, strict=True):
29
+ d = sm_distance(sm1_, sm2_)
30
+ assert (
31
+ d < max_error
32
+ ), f"Failed comparison:\n{sm1_}\n{sm2_},\n with distance {d}."
33
+ return
34
+ assert np.all(
35
+ [
36
+ np.isclose(a, b).all()
37
+ for x, y in zip(sm1, sm2, strict=True)
38
+ for a, b in zip(x, y, strict=True)
39
+ ]
40
+ ), f"Failed comparison:\n-----------------\n{sm1}\n-----------------\n{sm2}"
@@ -0,0 +1,91 @@
1
+ import multipers as mp
2
+ import numpy as np
3
+ from multipers.ml.signed_betti import signed_betti
4
+ from multipers.hilbert_function import hilbert_surface
5
+ from multipers.euler_characteristic import euler_surface
6
+
7
+ def test_1():
8
+ st = mp.SimplexTreeMulti(num_parameters=3)
9
+ st.insert([0], [1,0,0])
10
+ st.insert([1], [0,1,0])
11
+ st.insert([2], [0,0,1])
12
+ st.insert([0,1,2], [2,2,2])
13
+ st.make_filtration_non_decreasing()
14
+ assert np.array_equal(mp.hilbert(st, grid_shape=[3,3,3], degrees=[0]),np.array(
15
+ [[
16
+ [[0, 1, 1],
17
+ [1, 2, 2],
18
+ [1, 2, 2]],
19
+
20
+ [[1, 2, 2],
21
+ [2, 3, 3],
22
+ [2, 3, 3]],
23
+
24
+ [[1, 2, 2],
25
+ [2, 3, 3],
26
+ [2, 3, 1]]
27
+ ]]
28
+ ))
29
+ assert np.array_equal(mp.hilbert(st, grid_shape=[3,3,3], degrees=[0])[0], mp.euler(st, grid_shape=[3,3,3]))
30
+
31
+ def test_2():
32
+ st = mp.SimplexTreeMulti(num_parameters=4)
33
+ st.insert([0], [1,0,0,0])
34
+ st.insert([1], [0,1,0,0])
35
+ st.insert([2], [0,0,1,0])
36
+ st.insert([3], [0,0,0,1])
37
+ st.insert([0,1,2,3], [2,2,2,2])
38
+ st.make_filtration_non_decreasing()
39
+ # list(st.get_simplices())
40
+ assert np.array_equal(hilbert_surface(st, grid_shape=[3,3,3,3], degrees=[0])[1][0],(mp.euler(st, grid_shape=[3,3,3,3], degree=0)))
41
+
42
+ def test_3():
43
+ st = mp.SimplexTreeMulti(num_parameters=2)
44
+ st.insert([0,1,2], [1]*st.num_parameters)
45
+ st.remove_maximal_simplex([0,1,2])
46
+ (a,b), = mp.signed_measure(st, degree=1, mass_default=None)
47
+ assert np.array_equal(a, [[1,1]]) and np.array_equal(b, [1])
48
+ assert mp.signed_measure(st, degree=1)[0][1].sum() == 0
49
+
50
+ def test_4():
51
+ st = mp.SimplexTreeMulti(num_parameters=3)
52
+ st.insert([0], [1,0,0])
53
+ st.insert([1], [0,1,0])
54
+ st.insert([2], [0,0,1])
55
+ st.insert([0,1,2], [2,2,2])
56
+ st.make_filtration_non_decreasing()
57
+ # list(st.get_simplices())
58
+ assert np.array_equal(signed_betti(mp.euler(st, grid_shape=[3,3,3], degree=0)), mp.euler(st, grid_shape=[3,3,3], degree=0, inverse=True))
59
+ assert np.array_equal(mp.signed_measure(st, grid_shape=[3,3,3], degree=0, unsparse=True)[0], mp.euler(st, grid_shape=[3,3,3], degree=0, inverse=True, zero_pad=True))
60
+ assert mp.signed_measure(st, degree=0)[0][1].sum() == 0
61
+
62
+
63
+ def test_5():
64
+ st = mp.SimplexTreeMulti(num_parameters=4)
65
+ st.insert([0], [1,0,0,0])
66
+ st.insert([1], [0,1,0,0])
67
+ st.insert([2], [0,0,1,0])
68
+ st.insert([3], [0,0,0,1])
69
+ st.insert([0,1,2,3], [2,2,2,2])
70
+ st.make_filtration_non_decreasing()
71
+ # list(st.get_simplices())
72
+ assert np.array_equal(signed_betti(mp.hilbert(st, grid_shape=[3,3,3,3], degrees=[0])[0]),mp.euler(st, grid_shape=[3,3,3,3], degree=0, inverse=True))
73
+ assert np.array_equal(mp.signed_measure(st, grid_shape=[3,3,3,3], degree=0, unsparse=True)[0], mp.euler(st, grid_shape=[3,3,3,3], degree=0, inverse=True, zero_pad=True))
74
+ assert mp.signed_measure(st, grid_shape=[3,3,3,3], degree=0)[0][1].sum() == 0
75
+
76
+ def test_6():
77
+ for num_parameters in range(2,4):
78
+ st = mp.SimplexTreeMulti(num_parameters=num_parameters)
79
+ f = np.random.randint(5,size=st.num_parameters)
80
+ st.insert([0,1], f)
81
+ st.insert([2,1], f)
82
+ st.insert([0,3], f)
83
+ st.insert([3,2], f)
84
+ tensor = mp.signed_measure(st, degree=1, unsparse=True, mass_default=None, infer_grid=False)[0]
85
+ print(tensor, f)
86
+ tensor[*f]-=1
87
+ assert np.all(tensor == 0), print(np.all(tensor==0))
88
+
89
+
90
+
91
+
@@ -0,0 +1,74 @@
1
+ import gudhi as gd
2
+ import numpy as np
3
+
4
+ import multipers as mp
5
+
6
+ mp.simplex_tree_multi.SAFE_CONVERSION = True
7
+
8
+
9
+ def test_h1_rips_density():
10
+ num_pts = 100
11
+ dim = 2
12
+ pts = np.random.uniform(size=(num_pts, dim))
13
+ weights = np.random.uniform(size=num_pts)
14
+ st = gd.RipsComplex(points=pts).create_simplex_tree()
15
+ st = mp.SimplexTreeMulti(st, num_parameters=2)
16
+ st.fill_lowerstar(weights, parameter=1)
17
+ st.collapse_edges(num=100)
18
+ st.expansion(2)
19
+ # F=st.get_filtration_grid()
20
+ # st.grid_squeeze(F, coordinate_values=True)
21
+ (sm,) = mp.signed_measure(st, degree=1, plot=True, mass_default=None)
22
+ pts, weights = sm
23
+ sm_indices, unmappable_points = st.pts_to_indices(pts, simplices_dimensions=[1, 0])
24
+ assert len(unmappable_points) == 0, "Found unmappable points in Rips edges ?"
25
+ filtration_values = np.array([f for _, f in st.get_simplices()])
26
+ reconstructed_measure = np.asarray(
27
+ [
28
+ [filtration_values[i][parameter] for parameter, i in enumerate(indices)]
29
+ for indices in sm_indices
30
+ ]
31
+ )
32
+ assert np.array_equal(
33
+ reconstructed_measure, pts
34
+ ), "Reconstructed measure is not equal to original measure ?"
35
+
36
+
37
+ def test_h0_rips_density():
38
+ num_pts = 100
39
+ dim = 2
40
+ pts = np.random.uniform(size=(num_pts, dim))
41
+ weights = np.random.uniform(size=num_pts)
42
+ st = gd.RipsComplex(points=pts).create_simplex_tree()
43
+ st = mp.SimplexTreeMulti(st, num_parameters=2)
44
+ st.fill_lowerstar(weights, parameter=1)
45
+ st.collapse_edges(full=True)
46
+ # F=st.get_filtration_grid()
47
+ # st.grid_squeeze(F, coordinate_values=True)
48
+ (sm,) = mp.signed_measure(st, degree=0, plot=True, mass_default=None)
49
+ pts, weights = sm
50
+ _, unmappable_points = st.pts_to_indices(pts, simplices_dimensions=[1, 0])
51
+ assert (
52
+ pts[unmappable_points[:, 0]][:, 0] == 0
53
+ ).all(), "Unmapped points of H0 have to be the nodes of the rips."
54
+
55
+
56
+ # def test_h1_rips_density_rank():
57
+ # num_pts = 100
58
+ # dim=2
59
+ # pts = np.random.uniform(size=(num_pts,dim))
60
+ # weights = np.random.uniform(size=num_pts)
61
+ # st = gd.RipsComplex(points=pts).create_simplex_tree()
62
+ # st = mp.SimplexTreeMulti(st, num_parameters=2)
63
+ # st.fill_lowerstar(weights, parameter=1)
64
+ # st.collapse_edges(full=True)
65
+ # st.expansion(2)
66
+ # # F=st.get_filtration_grid()
67
+ # # st.grid_squeeze(F, coordinate_values=True)
68
+ # sm, = mp.signed_measure(st, degree=1, plot=True, mass_default=None, invariant="rank_invariant", resolution=20, grid_strategy="quantile")
69
+ # pts, weights = sm
70
+ # sm_indices, unmappable_points = signed_measure_indices(st,pts, simplices_dimensions = [1,0])
71
+ # assert len(unmappable_points) == 0, 'Found unmappable points in Rips edges ?'
72
+ # filtration_values = np.array([f for _,f in st.get_simplices()])
73
+ # reconstructed_measure = np.asarray([[filtration_values[i][parameter%2] for parameter,i in enumerate(indices)] for indices in sm_indices])
74
+ # assert np.array_equal(reconstructed_measure, pts), 'Reconstructed measure is not equal to original measure ?'
@@ -0,0 +1,82 @@
1
+ import numpy as np
2
+
3
+ import multipers as mp
4
+ from multipers import signed_measure
5
+
6
+ mp.simplex_tree_multi.SAFE_CONVERSION = True
7
+
8
+
9
+ # def test_1(): # TODO: test integrate_measure instead
10
+ # st = mp.SimplexTreeMulti(num_parameters=3)
11
+ # st.insert([0], [1, 0, 0])
12
+ # st.insert([1], [0, 1, 0])
13
+ # st.insert([2], [0, 0, 1])
14
+ # st.insert([0, 1, 2], [2, 2, 2])
15
+ # st.make_filtration_non_decreasing()
16
+ # st = st.grid_squeeze(grid_strategy="exact")
17
+ # assert np.array_equal(
18
+ # hilbert_surface(st, degrees=[0])[1],
19
+ # np.array(
20
+ # [
21
+ # [
22
+ # [[0, 1, 1], [1, 2, 2], [1, 2, 2]],
23
+ # [[1, 2, 2], [2, 3, 3], [2, 3, 3]],
24
+ # [[1, 2, 2], [2, 3, 3], [2, 3, 1]],
25
+ # ]
26
+ # ]
27
+ # ),
28
+ # )
29
+ # assert np.array_equal(hilbert_surface(st, degrees=[0])[1][0], euler_surface(st)[1])
30
+
31
+
32
+ # def test_2():
33
+ # st = mp.SimplexTreeMulti(num_parameters=4)
34
+ # st.insert([0], [1, 0, 0, 0])
35
+ # st.insert([1], [0, 1, 0, 0])
36
+ # st.insert([2], [0, 0, 1, 0])
37
+ # st.insert([3], [0, 0, 0, 1])
38
+ # st.insert([0, 1, 2, 3], [2, 2, 2, 2])
39
+ # st.make_filtration_non_decreasing()
40
+ # # list(st.get_simplices())
41
+ # st.grid_squeeze(grid_strategy="exact")
42
+ # assert np.array_equal(
43
+ # hilbert_surface(st, degrees=[0])[1][0], (euler_surface(st)[1])
44
+ # )
45
+
46
+
47
+ def test_3():
48
+ st = mp.SimplexTreeMulti(num_parameters=2)
49
+ st.insert([0, 1, 2], [1] * st.num_parameters)
50
+ st.remove_maximal_simplex([0, 1, 2])
51
+ st = st.grid_squeeze(grid_strategy="exact")
52
+ ((a, b),) = mp.signed_measure(st, degrees=[1], mass_default=None)
53
+ assert np.array_equal(a, [[1, 1]]) and np.array_equal(b, [1])
54
+ assert mp.signed_measure(st, degrees=[1], mass_default="inf")[0][1].sum() == 0
55
+
56
+
57
+ def test_4():
58
+ st = mp.SimplexTreeMulti(num_parameters=3)
59
+ st.insert([0], [1, 0, 0])
60
+ st.insert([1], [0, 1, 0])
61
+ st.insert([2], [0, 0, 1])
62
+ st.insert([0, 1, 2], [2, 2, 2])
63
+ st.make_filtration_non_decreasing()
64
+ # list(st.get_simplices())
65
+ st.grid_squeeze(grid_strategy="exact")
66
+ assert signed_measure(st, degrees=[0], mass_default="inf")[0][1].sum() == 0
67
+
68
+
69
+ def test_5():
70
+ num_param = 7
71
+ st = mp.SimplexTreeMulti(num_parameters=num_param)
72
+ for i in range(num_param):
73
+ f = np.zeros(num_param)
74
+ f[i] = 1
75
+ st.insert([i], f)
76
+ st.insert(np.arange(num_param), [2] * num_param)
77
+ assert not st.make_filtration_non_decreasing()
78
+ st.grid_squeeze()
79
+ (a, b), (c, d) = signed_measure(st, degrees=[0, 1])
80
+ assert np.all(a[-1] == 2)
81
+ assert np.sum(b) == 1 and b[-1] == -(num_param - 1)
82
+ assert c.shape == (0, num_param)
@@ -0,0 +1,51 @@
1
+ import numpy as np
2
+
3
+ import multipers as mp
4
+
5
+ mp.simplex_tree_multi.SAFE_CONVERSION = True
6
+
7
+
8
+ def test_1():
9
+ st = mp.SimplexTreeMulti(num_parameters=2)
10
+ st.insert([0], [0, 1])
11
+ st.insert([1], [1, 0])
12
+ st.insert([0, 1], [1, 1])
13
+ mma_pymodule = st.persistence_approximation()
14
+ assert np.array_equal(mma_pymodule[0].get_birth_list(), [[1.0, 0.0], [0.0, 1.0]])
15
+ assert np.array_equal(mma_pymodule[0].get_death_list(), [[np.inf, np.inf]])
16
+
17
+
18
+ def test_img():
19
+ simplextree = mp.SimplexTreeMulti(num_parameters=4)
20
+ simplextree.insert([0], [1, 2, 3, 4])
21
+ mod = simplextree.persistence_approximation(
22
+ box=[[0, 0, 0, 0], [5, 5, 5, 5]], max_error=1.0
23
+ )
24
+ img = mod.representation(resolution=6, kernel="linear")
25
+ assert np.isclose(img[0, 2, 3, 4, 5], 0.5)
26
+ assert np.isclose(img[0, 1, 1, 1, 1], 0)
27
+ assert np.isclose(img[0, 3, 4, 5, 5], 1)
28
+
29
+
30
+ # def test_2():
31
+ # st = mp.SimplexTreeMulti(num_parameters=2)
32
+ # st.insert([0], [1, 2])
33
+ # st.insert([0, 1], [2, 2])
34
+ # mod = st.persistence_approximation(
35
+ # box=[[0, 0], [4, 4]], slicer_backend="graph", max_error=0.1
36
+ # )
37
+ # assert len(mod) == 1
38
+ # assert np.isclose(
39
+ # mod.representation(degrees=[0], plot=False, resolution=5, kernel="linear", p=1),
40
+ # np.array(
41
+ # [
42
+ # [
43
+ # [0, 0, 0, 0, 0],
44
+ # [0, 0, 0, 0, 0],
45
+ # [0, 1, 1, 1, 1],
46
+ # [0, 1, 2, 2, 2],
47
+ # [0, 1, 2, 2, 2],
48
+ # ]
49
+ # ]
50
+ # ),
51
+ # ).all()
@@ -0,0 +1,59 @@
1
+ import numpy as np
2
+
3
+ import multipers as mp
4
+ import multipers.ml.point_clouds as mmp
5
+ from multipers.tests import assert_sm
6
+
7
+ mp.simplex_tree_multi.SAFE_CONVERSION = True
8
+ np.random.seed(0)
9
+
10
+
11
+ def test_throw_test():
12
+ pts = np.array([[1, 1], [2, 2]], dtype=np.float32)
13
+ st = mmp.PointCloud2SimplexTree(masses=[0.1]).fit_transform([pts])[0][0]
14
+ assert isinstance(st, mp.simplex_tree_multi.SimplexTreeMulti_type)
15
+ st = mmp.PointCloud2SimplexTree(bandwidths=[-0.1], complex="alpha").fit_transform(
16
+ [pts]
17
+ )[0][0]
18
+ assert isinstance(st, mp.simplex_tree_multi.SimplexTreeMulti_type)
19
+ st1, st2 = mmp.PointCloud2SimplexTree(bandwidths=[0.1], masses=[0.1]).fit_transform(
20
+ [pts]
21
+ )[0]
22
+ assert isinstance(st1, mp.simplex_tree_multi.SimplexTreeMulti_type)
23
+ assert isinstance(st2, mp.simplex_tree_multi.SimplexTreeMulti_type)
24
+ ## ensures it doesn't throw
25
+ assert isinstance(
26
+ st.persistence_approximation(),
27
+ mp.multiparameter_module_approximation.PyModule_type,
28
+ )
29
+ assert mp.signed_measure(st, degree=None, invariant="euler")[0][0].ndim == 2
30
+ assert mp.signed_measure(st, degree=0, invariant="hilbert")[0][0].ndim == 2
31
+ assert mp.signed_measure(st, degree=0, invariant="rank")[0][0].ndim == 2
32
+ assert mp.signed_measure(st, degree=0, invariant="rank")[0][0].shape[1] == 4
33
+
34
+
35
+ # def test_1():
36
+ # import multipers.data
37
+ #
38
+ # pts = mp.data.noisy_annulus(20, 20)
39
+ # st = mmp.PointCloud2SimplexTree(bandwidths=[-0.5], expand_dim=2).fit_transform(
40
+ # [pts]
41
+ # )[0][0]
42
+ # F = st.get_filtration_grid()
43
+ # for invariant in ["hilbert", "rank"]:
44
+ # sm1 = mp.signed_measure(
45
+ # st.grid_squeeze(F), degree=1, invariant=invariant, mass_default=None
46
+ # )
47
+ # st.collapse_edges(-2, ignore_warning=True)
48
+ # s = mp.Slicer(st, dtype=np.float64)
49
+ # mp.io._init_external_softwares()
50
+ # if mp.io.pathes["mpfree"] is None:
51
+ # from warnings import warn
52
+ #
53
+ # warn("Could not find mpfree, skipping this test")
54
+ # else:
55
+ # s = s.minpres(degree=1).grid_squeeze(F)
56
+ # sm2 = mp.signed_measure(s, invariant=invariant, degree=1)
57
+ # assert_sm(
58
+ # sm1, sm2, exact=False, max_error=0.1
59
+ # ) ## TODO : Fix this. Error is too large (grid not the same ? )
@@ -0,0 +1,82 @@
1
+ import numpy as np
2
+ import multipers as mp
3
+ import gudhi as gd
4
+
5
+
6
+ mp.simplex_tree_multi.SAFE_CONVERSION = False
7
+
8
+
9
+ def test_random_alpha_safe_conversion():
10
+ x = np.random.uniform(size=(200, 2))
11
+ num_parameter = 4
12
+ st_gudhi = gd.AlphaComplex(points=x).create_simplex_tree()
13
+ st_multi = mp.SimplexTreeMulti(
14
+ st_gudhi, num_parameters=num_parameter, safe_conversion=True
15
+ )
16
+ assert (
17
+ np.all([s in st_multi for s, f in st_gudhi.get_simplices()])
18
+ and st_gudhi.num_simplices() == st_multi.num_simplices
19
+ ), "Simplices conversion failed."
20
+ assert np.all(
21
+ [f.shape[0] == num_parameter for _, f in st_multi.get_simplices()]
22
+ ), "Number of parameters is inconcistent"
23
+ assert np.all(
24
+ [np.isclose(st_multi.filtration(s)[0], f) for s, f in st_gudhi.get_simplices()]
25
+ ), "Filtration values conversion failed."
26
+
27
+
28
+ def test_random_alpha_unsafe_conversion():
29
+ x = np.random.uniform(size=(200, 2))
30
+ num_parameter = 4
31
+ st_gudhi = gd.AlphaComplex(points=x).create_simplex_tree()
32
+ st_multi = mp.SimplexTreeMulti(
33
+ st_gudhi, num_parameters=num_parameter, safe_conversion=False
34
+ )
35
+ assert (
36
+ np.all([s in st_multi for s, f in st_gudhi.get_simplices()])
37
+ and st_gudhi.num_simplices() == st_multi.num_simplices
38
+ ), "Simplices conversion failed."
39
+ assert np.all(
40
+ [f.shape[0] == num_parameter for _, f in st_multi.get_simplices()]
41
+ ), "Number of parameters is inconcistent"
42
+ assert np.all(
43
+ [np.isclose(st_multi.filtration(s)[0], f) for s, f in st_gudhi.get_simplices()]
44
+ ), "Filtration values conversion failed."
45
+
46
+
47
+ def test_random_rips_safe_conversion():
48
+ x = np.random.uniform(size=(100, 2))
49
+ num_parameter = 4
50
+ st_gudhi = gd.RipsComplex(points=x).create_simplex_tree()
51
+ st_multi = mp.SimplexTreeMulti(
52
+ st_gudhi, num_parameters=num_parameter, safe_conversion=True
53
+ )
54
+ assert (
55
+ np.all([s in st_multi for s, f in st_gudhi.get_simplices()])
56
+ and st_gudhi.num_simplices() == st_multi.num_simplices
57
+ ), "Simplices conversion failed."
58
+ assert np.all(
59
+ [f.shape[0] == num_parameter for _, f in st_multi.get_simplices()]
60
+ ), "Number of parameters is inconcistent"
61
+ assert np.all(
62
+ [np.isclose(st_multi.filtration(s)[0], f) for s, f in st_gudhi.get_simplices()]
63
+ ), "Filtration values conversion failed."
64
+
65
+
66
+ def test_random_alpha_unsafe_conversion():
67
+ x = np.random.uniform(size=(100, 2))
68
+ num_parameter = 4
69
+ st_gudhi = gd.RipsComplex(points=x).create_simplex_tree()
70
+ st_multi = mp.SimplexTreeMulti(
71
+ st_gudhi, num_parameters=num_parameter, safe_conversion=False
72
+ )
73
+ assert (
74
+ np.all([s in st_multi for s, f in st_gudhi.get_simplices()])
75
+ and st_gudhi.num_simplices() == st_multi.num_simplices
76
+ ), "Simplices conversion failed."
77
+ assert np.all(
78
+ [f.shape[0] == num_parameter for _, f in st_multi.get_simplices()]
79
+ ), "Number of parameters is inconcistent"
80
+ assert np.all(
81
+ [np.isclose(st_multi.filtration(s)[0], f) for s, f in st_gudhi.get_simplices()]
82
+ ), "Filtration values conversion failed."