mogutda 0.4.3__py3-none-any.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.
- mogutda/__init__.py +5 -0
- mogutda/abssimcomplex.py +131 -0
- mogutda/alphacomplex.py +71 -0
- mogutda/utils.py +27 -0
- mogutda/vrcomplex.py +38 -0
- mogutda-0.4.3.dist-info/LICENSE +19 -0
- mogutda-0.4.3.dist-info/METADATA +182 -0
- mogutda-0.4.3.dist-info/RECORD +10 -0
- mogutda-0.4.3.dist-info/WHEEL +5 -0
- mogutda-0.4.3.dist-info/top_level.txt +1 -0
mogutda/__init__.py
ADDED
mogutda/abssimcomplex.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
|
|
2
|
+
from itertools import combinations
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
from scipy.sparse import dok_matrix
|
|
7
|
+
from scipy.sparse.linalg import aslinearoperator
|
|
8
|
+
from scipy.linalg.interpolative import estimate_rank
|
|
9
|
+
import networkx as nx
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
|
|
12
|
+
from .utils import faces
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SimplicialComplex:
|
|
16
|
+
def __init__(self, simplices=[]):
|
|
17
|
+
self.import_simplices(simplices=simplices)
|
|
18
|
+
|
|
19
|
+
def import_simplices(self, simplices=[]):
|
|
20
|
+
# self.simplices = list(map(lambda simplex: tuple(sorted(simplex)), simplices))
|
|
21
|
+
self.simplices = [tuple(sorted(simplex)) for simplex in simplices]
|
|
22
|
+
self.face_set = faces(self.simplices)
|
|
23
|
+
|
|
24
|
+
def n_faces(self, n):
|
|
25
|
+
# return list(filter(lambda face: len(face) == n + 1, self.face_set))
|
|
26
|
+
return [face for face in self.face_set if len(face) == n+1]
|
|
27
|
+
|
|
28
|
+
def boundary_operator(self, i):
|
|
29
|
+
source_simplices = self.n_faces(i)
|
|
30
|
+
target_simplices = self.n_faces(i - 1)
|
|
31
|
+
|
|
32
|
+
if len(target_simplices) == 0:
|
|
33
|
+
S = dok_matrix((1, len(source_simplices)), dtype=np.float64)
|
|
34
|
+
S[0, 0:len(source_simplices)] = 1
|
|
35
|
+
else:
|
|
36
|
+
source_simplices_dict = {
|
|
37
|
+
source_simplices[j]: j for j in range(len(source_simplices))
|
|
38
|
+
}
|
|
39
|
+
target_simplices_dict = {
|
|
40
|
+
target_simplices[i]: i for i in range(len(target_simplices))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
S = dok_matrix(
|
|
44
|
+
(len(target_simplices), len(source_simplices)), dtype=np.float64
|
|
45
|
+
)
|
|
46
|
+
for source_simplex in source_simplices:
|
|
47
|
+
for a in range(len(source_simplex)):
|
|
48
|
+
target_simplex = source_simplex[:a] + source_simplex[(a + 1) :]
|
|
49
|
+
i = target_simplices_dict[target_simplex]
|
|
50
|
+
j = source_simplices_dict[source_simplex]
|
|
51
|
+
S[i, j] = -1 if a % 2 == 1 else 1 # S[i, j] = (-1)**a
|
|
52
|
+
return S
|
|
53
|
+
|
|
54
|
+
def betti_number(self, i, eps=None):
|
|
55
|
+
boundop_i = self.boundary_operator(i)
|
|
56
|
+
boundop_ip1 = self.boundary_operator(i + 1)
|
|
57
|
+
|
|
58
|
+
if i == 0:
|
|
59
|
+
boundop_i_rank = 0
|
|
60
|
+
else:
|
|
61
|
+
if eps is None:
|
|
62
|
+
try:
|
|
63
|
+
boundop_i_rank = np.linalg.matrix_rank(boundop_i.toarray())
|
|
64
|
+
except (np.linalg.LinAlgError, ValueError):
|
|
65
|
+
boundop_i_rank = boundop_i.shape[1]
|
|
66
|
+
else:
|
|
67
|
+
boundop_i_rank = estimate_rank(aslinearoperator(boundop_i), eps)
|
|
68
|
+
|
|
69
|
+
if eps is None:
|
|
70
|
+
try:
|
|
71
|
+
boundop_ip1_rank = np.linalg.matrix_rank(boundop_ip1.toarray())
|
|
72
|
+
except (np.linalg.LinAlgError, ValueError):
|
|
73
|
+
boundop_ip1_rank = boundop_ip1.shape[1]
|
|
74
|
+
else:
|
|
75
|
+
boundop_ip1_rank = estimate_rank(aslinearoperator(boundop_ip1), eps)
|
|
76
|
+
|
|
77
|
+
return (boundop_i.shape[1] - boundop_i_rank) - boundop_ip1_rank
|
|
78
|
+
|
|
79
|
+
def euler_characteristics(self):
|
|
80
|
+
max_n = max(map(len, self.simplices))
|
|
81
|
+
return sum(
|
|
82
|
+
[(-1 if a % 2 == 1 else 1) * self.betti_number(a) for a in range(max_n)]
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def generate_graph(self, simplices=None):
|
|
86
|
+
""" Generate edges and vertices in sets """
|
|
87
|
+
if len(self.simplices) == 0 and simplices is None:
|
|
88
|
+
raise Exception("No simplices to create a graph from. Please specify one.")
|
|
89
|
+
elif simplices is not None:
|
|
90
|
+
self.import_simplices(simplices=simplices)
|
|
91
|
+
|
|
92
|
+
vertices = set()
|
|
93
|
+
edges = set()
|
|
94
|
+
|
|
95
|
+
for simplex in self.simplices:
|
|
96
|
+
for vertex1, vertex2 in combinations(simplex, 2):
|
|
97
|
+
vertices.add(vertex1)
|
|
98
|
+
vertices.add(vertex2)
|
|
99
|
+
edges.add(tuple(sorted([vertex1, vertex2])))
|
|
100
|
+
return vertices, edges
|
|
101
|
+
|
|
102
|
+
def draw(self, vertex_labels=True, edge_labels=False):
|
|
103
|
+
""" Draw the Simplicial Complex """
|
|
104
|
+
vertices, edges = self.generate_graph()
|
|
105
|
+
|
|
106
|
+
if len(vertices) + len(edges) > 1000:
|
|
107
|
+
warnings.warn(
|
|
108
|
+
"The number of elements to draw exceeds 100. To still draw the plot, call the function with override_100_limit = True. "
|
|
109
|
+
)
|
|
110
|
+
else:
|
|
111
|
+
G = nx.Graph()
|
|
112
|
+
for vertex in vertices:
|
|
113
|
+
G.add_node(vertex)
|
|
114
|
+
for edge in edges:
|
|
115
|
+
G.add_edge(edge[0], edge[1])
|
|
116
|
+
pos = nx.spring_layout(G)
|
|
117
|
+
|
|
118
|
+
nx.draw(G, pos)
|
|
119
|
+
|
|
120
|
+
labels = {}
|
|
121
|
+
if vertex_labels is True:
|
|
122
|
+
for vertex in vertices:
|
|
123
|
+
labels[vertex] = str(vertex)
|
|
124
|
+
nx.draw_networkx_labels(G, pos, labels, font_size=16)
|
|
125
|
+
|
|
126
|
+
if edge_labels is True:
|
|
127
|
+
edge_labels = {}
|
|
128
|
+
for edge in edges:
|
|
129
|
+
edge_labels[edge] = "{}:{}".format(edge[0], edge[1])
|
|
130
|
+
nx.draw_networkx_edge_labels(G, pos, edge_labels, font_size=3)
|
|
131
|
+
plt.plot()
|
mogutda/alphacomplex.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
|
|
2
|
+
from scipy.spatial import Delaunay, distance
|
|
3
|
+
|
|
4
|
+
from .abssimcomplex import SimplicialComplex
|
|
5
|
+
from .utils import facesiter, get_allpoints
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def calculate_distmatrix(points, labels, distfcn):
|
|
9
|
+
return {
|
|
10
|
+
(labels[i], labels[j]): distfcn(points[i], points[j])
|
|
11
|
+
for i in range(len(labels)) for j in range(len(labels))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def contain_detachededges(simplex, distdict, epsilon):
|
|
16
|
+
if len(simplex) == 2:
|
|
17
|
+
return distdict[simplex[0], simplex[1]] > 2*epsilon
|
|
18
|
+
else:
|
|
19
|
+
for face in facesiter(simplex):
|
|
20
|
+
contained = contain_detachededges(face, distdict, epsilon)
|
|
21
|
+
if contained:
|
|
22
|
+
return True
|
|
23
|
+
return False
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class AlphaComplex(SimplicialComplex):
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
points,
|
|
30
|
+
epsilon,
|
|
31
|
+
labels=None,
|
|
32
|
+
distfcn=distance.euclidean
|
|
33
|
+
):
|
|
34
|
+
super(AlphaComplex, self).__init__()
|
|
35
|
+
self.pts = points
|
|
36
|
+
self.labels = (range(len(self.pts))
|
|
37
|
+
if (labels is None or len(labels) != len(self.pts))
|
|
38
|
+
else labels)
|
|
39
|
+
self.epsilon = epsilon
|
|
40
|
+
self.distfcn = distfcn
|
|
41
|
+
self.import_simplices(
|
|
42
|
+
self.construct_simplices(self.pts, self.labels, self.epsilon, self.distfcn)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def construct_simplices(self, points, labels, epsilon, distfcn):
|
|
46
|
+
distdict = calculate_distmatrix(points, labels, distfcn)
|
|
47
|
+
|
|
48
|
+
delaunayobj = Delaunay(points)
|
|
49
|
+
|
|
50
|
+
simplices = []
|
|
51
|
+
for simplexnda in delaunayobj.simplices:
|
|
52
|
+
simplex = tuple(simplexnda)
|
|
53
|
+
|
|
54
|
+
detached = [contain_detachededges(face, distdict, epsilon) for face in facesiter(simplex)]
|
|
55
|
+
|
|
56
|
+
if True in detached and len(simplex) > 2:
|
|
57
|
+
simplices += [
|
|
58
|
+
face
|
|
59
|
+
for face, notkeep in zip(facesiter(simplex), detached)
|
|
60
|
+
if not notkeep
|
|
61
|
+
]
|
|
62
|
+
else:
|
|
63
|
+
simplices.append(simplex)
|
|
64
|
+
# simplices = map(lambda simplex: tuple(sorted(simplex)), simplices)
|
|
65
|
+
simplices = [tuple(sorted(simplex)) for simplex in simplices]
|
|
66
|
+
simplices = list(set(simplices))
|
|
67
|
+
|
|
68
|
+
allpts = get_allpoints(simplices)
|
|
69
|
+
simplices += [(point,) for point in (set(labels)-allpts)]
|
|
70
|
+
|
|
71
|
+
return simplices
|
mogutda/utils.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
from itertools import combinations
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def facesiter(simplex):
|
|
6
|
+
for i in range(len(simplex)):
|
|
7
|
+
yield simplex[:i] + simplex[(i + 1):]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def flattening_simplex(simplices):
|
|
11
|
+
for simplex in simplices:
|
|
12
|
+
for point in simplex:
|
|
13
|
+
yield point
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_allpoints(simplices):
|
|
17
|
+
return set(flattening_simplex(simplices))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def faces(simplices):
|
|
21
|
+
faceset = set()
|
|
22
|
+
for simplex in simplices:
|
|
23
|
+
numnodes = len(simplex)
|
|
24
|
+
for r in range(numnodes, 0, -1):
|
|
25
|
+
for face in combinations(simplex, r):
|
|
26
|
+
faceset.add(tuple(sorted(face)))
|
|
27
|
+
return faceset
|
mogutda/vrcomplex.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
from itertools import product
|
|
3
|
+
|
|
4
|
+
import networkx as nx
|
|
5
|
+
from scipy.spatial import distance
|
|
6
|
+
|
|
7
|
+
from .abssimcomplex import SimplicialComplex
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class VietorisRipsComplex(SimplicialComplex):
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
points,
|
|
14
|
+
epsilon,
|
|
15
|
+
labels=None,
|
|
16
|
+
distfcn=distance.euclidean
|
|
17
|
+
):
|
|
18
|
+
super(VietorisRipsComplex, self).__init__()
|
|
19
|
+
self.pts = points
|
|
20
|
+
self.labels = (list(range(len(self.pts)))
|
|
21
|
+
if labels is None or len(labels) != len(self.pts)
|
|
22
|
+
else labels)
|
|
23
|
+
self.epsilon = epsilon
|
|
24
|
+
self.distfcn = distfcn
|
|
25
|
+
self.network = self.construct_network(
|
|
26
|
+
self.pts, self.labels, self.epsilon, self.distfcn
|
|
27
|
+
)
|
|
28
|
+
self.import_simplices(map(tuple, nx.find_cliques(self.network)))
|
|
29
|
+
|
|
30
|
+
def construct_network(self, points, labels, epsilon, distfcn):
|
|
31
|
+
g = nx.Graph()
|
|
32
|
+
g.add_nodes_from(labels)
|
|
33
|
+
for pair in product(zip(points, labels), zip(points, labels)):
|
|
34
|
+
if pair[0][1] != pair[1][1]:
|
|
35
|
+
dist = distfcn(pair[0][0], pair[1][0])
|
|
36
|
+
if dist < epsilon:
|
|
37
|
+
g.add_edge(pair[0][1], pair[1][1])
|
|
38
|
+
return g
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 Kwan Yuet Stephen Ho
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: mogutda
|
|
3
|
+
Version: 0.4.3
|
|
4
|
+
Summary: Topological Data Analysis in Python
|
|
5
|
+
Author-email: Kwan Yuet Stephen Ho <stephenhky@yahoo.com.hk>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Documentation, https://mogutda.readthedocs.io
|
|
8
|
+
Project-URL: Repository, https://github.com/stephenhky/MoguTDA
|
|
9
|
+
Project-URL: Issues, https://github.com/stephenhky/MoguTDA/issues
|
|
10
|
+
Keywords: mogutda,numerical methods,topology,data,algebraic topology
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Classifier: Intended Audience :: Developers
|
|
20
|
+
Classifier: Intended Audience :: Education
|
|
21
|
+
Classifier: Intended Audience :: Information Technology
|
|
22
|
+
Classifier: Intended Audience :: Science/Research
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: numpy>=1.16.0
|
|
27
|
+
Requires-Dist: scipy>=1.10.0
|
|
28
|
+
Requires-Dist: networkx>=2.0
|
|
29
|
+
Requires-Dist: matplotlib>=3.3.0
|
|
30
|
+
Provides-Extra: test
|
|
31
|
+
Requires-Dist: unittest; extra == "test"
|
|
32
|
+
|
|
33
|
+
# `mogutda`: Topological Data Analysis in Python
|
|
34
|
+
|
|
35
|
+
[](https://circleci.com/gh/stephenhky/MoguTDA.svg)
|
|
36
|
+
[](https://github.com/stephenhky/MoguTDA/releases)
|
|
37
|
+
[](https://mogutda.readthedocs.io/en/latest/?badge=latest)
|
|
38
|
+
[](https://pyup.io/repos/github/stephenhky/MoguTDA/)
|
|
39
|
+
[](https://pyup.io/repos/github/stephenhky/MoguTDA/)
|
|
40
|
+
[](https://pypi.org/project/mogutda/)
|
|
41
|
+
[](https://pypi.org/project/mogutda/)
|
|
42
|
+
[](https://github.com/stephenhky/MoguTDA)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Introduction
|
|
46
|
+
|
|
47
|
+
`mogutda` contains Python codes that demonstrate the numerical calculation
|
|
48
|
+
of algebraic topology in an application to topological data analysis
|
|
49
|
+
(TDA). Its core code is the numerical methods concerning implicial complex,
|
|
50
|
+
and the estimation of homology and Betti numbers.
|
|
51
|
+
|
|
52
|
+
Topological data analysis aims at studying the shapes of the data, and
|
|
53
|
+
draw some insights from them. A lot of machine learning algorithms deal
|
|
54
|
+
with distances, which are extremely useful, but they miss the
|
|
55
|
+
information the data may carry from their geometry.
|
|
56
|
+
|
|
57
|
+
## History
|
|
58
|
+
|
|
59
|
+
The codes in this package were developed as a demonstration of a few posts of my blog.
|
|
60
|
+
It was not designed to be a Python package but a pedagogical collection of codes.
|
|
61
|
+
(See: [PyTDA](https://github.com/stephenhky/PyTDA).)
|
|
62
|
+
However, the codes and the blog posts have been unexpectedly popular. Therefore,
|
|
63
|
+
I modularized the code into the package [`mogu`](https://pypi.org/project/mogu/).
|
|
64
|
+
(or corresponding repository: [MoguNumerics](https://github.com/stephenhky/MoguNumerics))
|
|
65
|
+
However, `mogu` is simply a collection of unrelated numerical routines with a lot of
|
|
66
|
+
dependencies, but the part of TDA can be quite independent.
|
|
67
|
+
|
|
68
|
+
In order to provide other researchers and developers an independent package, which is compact (without
|
|
69
|
+
unecessary alternative packages to load), and efficient, I decided to modularize
|
|
70
|
+
the codes of TDA separately, and name this package `mogutda`.
|
|
71
|
+
|
|
72
|
+
## Prerequisite
|
|
73
|
+
|
|
74
|
+
It runs under Python 3.8, 3.9, 3.10, and 3.11.
|
|
75
|
+
|
|
76
|
+
## Simple Tutorial: Simplicial Complex
|
|
77
|
+
|
|
78
|
+
You can install by:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
pip install mogutda
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
To establish a simplicial complex for a torus, type
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
import numpy as np
|
|
88
|
+
from mogutda import SimplicialComplex
|
|
89
|
+
|
|
90
|
+
torus_sc = [(1,2,4), (4,2,5), (2,3,5), (3,5,6), (5,6,1), (1,6,2), (6,7,2), (7,3,2),
|
|
91
|
+
(1,3,4), (3,4,6), (4,6,7), (4,5,7), (5,7,1), (7,3,1)]
|
|
92
|
+
torus_c = SimplicialComplex(simplices=torus_sc)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
To retrieve its Betti numbers, type:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
print(torus_c.betti_number(0)) # print 1
|
|
99
|
+
print(torus_c.betti_number(1)) # print 2
|
|
100
|
+
print(torus_c.betti_number(2)) # print 1
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Demo Codes and Blog Entries
|
|
104
|
+
|
|
105
|
+
Codes in this repository are demo codes for a few entries of my blog,
|
|
106
|
+
[Everything about Data Analytics](https://datawarrior.wordpress.com/),
|
|
107
|
+
and the corresponding entries are:
|
|
108
|
+
|
|
109
|
+
* [Starting the Journey of Topological Data Analysis (TDA)](https://datawarrior.wordpress.com/2015/08/03/tda-1-starting-the-journey-of-topological-data-analysis-tda/) (August 3, 2015)
|
|
110
|
+
* [Constructing Connectivities](https://datawarrior.wordpress.com/2015/09/14/tda-2-constructing-connectivities/) (September 14, 2015)
|
|
111
|
+
* [Homology and Betti Numbers](https://datawarrior.wordpress.com/2015/11/03/tda-3-homology-and-betti-numbers/) (November 3, 2015)
|
|
112
|
+
* [Topology in Physics and Computing](https://datawarrior.wordpress.com/2015/11/10/mathanalytics-6-topology-in-physics-and-computing/) (November 10, 2015)
|
|
113
|
+
* [Persistence](https://datawarrior.wordpress.com/2015/12/20/tda-4-persistence/) (December 20, 2015)
|
|
114
|
+
* [Topological Phases](https://datawarrior.wordpress.com/2016/10/06/topological-phases/) (October 6, 2016)
|
|
115
|
+
* [moguTDA: Python package for Simplicial Complex](https://datawarrior.wordpress.com/2018/07/02/mogutda-python-package-for-simplicial-complex/) (July 2, 2018)
|
|
116
|
+
|
|
117
|
+
## Wolfram Demonstration
|
|
118
|
+
Richard Hennigan put a nice Wolfram Demonstration online explaining what
|
|
119
|
+
the simplicial complexes are, and how homologies are defined:
|
|
120
|
+
|
|
121
|
+
* [Simplicial Homology of the Alpha Complex](http://demonstrations.wolfram.com/SimplicialHomologyOfTheAlphaComplex/)
|
|
122
|
+
|
|
123
|
+
## News
|
|
124
|
+
|
|
125
|
+
* 09/19/2024: `mogutda` 0.4.3 released.
|
|
126
|
+
* 07/16/2024: `mogutsa` 0.4.2 released.
|
|
127
|
+
* 11/23/2023: `mogutda` 0.4.1 released.
|
|
128
|
+
* 08/18/2023: `mogutda` 0.4.0 released.
|
|
129
|
+
* 06/20/2023: `mogutda` 0.3.5 released.
|
|
130
|
+
* 09/09/2022: `mogutda` 0.3.4 released.
|
|
131
|
+
* 07/15/2021: `mogutda` 0.3.3 released.
|
|
132
|
+
* 04/10/2021: `mogutda` 0.3.2 released.
|
|
133
|
+
* 11/28/2020: `mogutda` 0.3.1 released.
|
|
134
|
+
* 08/16/2020: `mogutda` 0.3.0 released.
|
|
135
|
+
* 04/28/2020: `mogutda` 0.2.1 released.
|
|
136
|
+
* 01/16/2020: `mogutda` 0.2.0 released.
|
|
137
|
+
* 02/20/2019: `mogutda` 0.1.5 released.
|
|
138
|
+
* 12/31/2018: `mogutda` 0.1.4 released.
|
|
139
|
+
* 07/18/2018: `mogutda` 0.1.3 released.
|
|
140
|
+
* 07/02/2018: `mogutda` 0.1.2 released.
|
|
141
|
+
* 06/13/2018: `mogutda` 0.1.1 released.
|
|
142
|
+
* 06/11/2018: `mogutda` 0.1.0 released.
|
|
143
|
+
|
|
144
|
+
## Other TDA Packages
|
|
145
|
+
|
|
146
|
+
It is recommended that for real application, you should use the following packages
|
|
147
|
+
for efficiency, because my codes serve the pedagogical purpose only.
|
|
148
|
+
|
|
149
|
+
### C++
|
|
150
|
+
* [Dionysus](http://www.mrzv.org/software/dionysus/)
|
|
151
|
+
* [PHAT](https://bitbucket.org/phat-code/phat)
|
|
152
|
+
|
|
153
|
+
### Python
|
|
154
|
+
* [Dionysus](http://www.mrzv.org/software/dionysus/python/overview.html)
|
|
155
|
+
|
|
156
|
+
### R
|
|
157
|
+
* [TDA](https://cran.r-project.org/web/packages/TDA/index.html) (article: [\[arXiv\]](http://arxiv.org/abs/1411.1830))
|
|
158
|
+
|
|
159
|
+
## Contributions
|
|
160
|
+
|
|
161
|
+
If you want to contribute, feel free to fork the repository, and submit
|
|
162
|
+
a pull request whenever you are ready.
|
|
163
|
+
|
|
164
|
+
If you spot any bugs or issues, go to the [Issue](https://github.com/stephenhky/MoguTDA) page.
|
|
165
|
+
|
|
166
|
+
I may not approve pull request immediately if your suggested change is big.
|
|
167
|
+
If you want to incorporate something big, please discuss with me first.
|
|
168
|
+
|
|
169
|
+
## References
|
|
170
|
+
* Afra J. Zomorodian. *Topology for Computing* (New York, NY: Cambridge University Press, 2009). [\[Amazon\]](https://www.amazon.com/Computing-Cambridge-Monographs-Computational-Mathematics/dp/0521136091)
|
|
171
|
+
* Afra J. Zomorodian. "Topological Data Analysis," *Proceedings of Symposia in Applied Mathematics* (2011). [\[link\]](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.261.1298)
|
|
172
|
+
* Afra Zomorodian, Gunnar Carlsson, “Computing Persistent Homology,” *Discrete Comput. Geom.* 33, 249-274 (2005). [\[pdf\]](http://geometry.stanford.edu/papers/zc-cph-05/zc-cph-05.pdf)
|
|
173
|
+
* Gunnar Carlsson, “Topology and Data”, *Bull. Amer. Math. Soc.* 46, 255-308 (2009). [\[link\]](http://www.ams.org/journals/bull/2009-46-02/S0273-0979-09-01249-X/)
|
|
174
|
+
* Jeffrey Ray, Marcello Trovati, "A Survey of Topological Data Analysis (TDA) Methods Implemented in Python," in *Advances in Intelligent Networking and Collaborative Systems*, Springer (2018).
|
|
175
|
+
* P. Y. Lum, G. Singh, A. Lehman, T. Ishkanov, M. Vejdemo-Johansson, M. Alagappan, J. Carlsson, G. Carlsson, “Extracting insights from the shape of complex data using topology”, *Sci. Rep.* 3, 1236 (2013). [\[link\]](http://www.nature.com/srep/2013/130207/srep01236/full/srep01236.html)
|
|
176
|
+
* Robert Ghrist, “Barcodes: The persistent topology of data,” *Bull. Amer. Math. Soc.* 45, 1-15 (2008). [\[pdf\]](http://www.ams.org/journals/bull/2008-45-01/S0273-0979-07-01191-3/S0273-0979-07-01191-3.pdf)
|
|
177
|
+
|
|
178
|
+
## Links
|
|
179
|
+
|
|
180
|
+
* PyPI: [https://pypi.org/project/mogutda/](https://pypi.org/project/mogutda/)
|
|
181
|
+
* Documentation: [https://mogutda.readthedocs.io/](https://mogutda.readthedocs.io/)
|
|
182
|
+
* Bug Reports: [https://github.com/stephenhky/MoguTDA/issues](https://github.com/stephenhky/MoguTDA/issues)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
mogutda/__init__.py,sha256=vKhNOC6bE6kRNh-dAEb0GWnmvbpf75TFLHadBLd3Bno,149
|
|
2
|
+
mogutda/abssimcomplex.py,sha256=3_E5SbQMf1kBXtS4vwRGLV5sin-Slv64URbnCfUaJEo,4857
|
|
3
|
+
mogutda/alphacomplex.py,sha256=eBGv-ZgcfAJnVCaMKfBQ-PV-Mk7gK34yYM13dWj-tTc,2293
|
|
4
|
+
mogutda/utils.py,sha256=1KDTfo8ClLueGPLXn-l1rxWTfLqxsjtDMsX0nQGK89E,606
|
|
5
|
+
mogutda/vrcomplex.py,sha256=0FE9h4yRbf1DgdQtYvfm-J5j7oeO0JlZPmp0L06le24,1220
|
|
6
|
+
mogutda-0.4.3.dist-info/LICENSE,sha256=3paJBNa5qA0n3pWiu0x3NMUOpzN_ypGIWKQ3YImmz_o,1063
|
|
7
|
+
mogutda-0.4.3.dist-info/METADATA,sha256=npkQgBI5dewlRCx2Wg-yRrJ4eQacovAno6ps8B3_AR8,9279
|
|
8
|
+
mogutda-0.4.3.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
9
|
+
mogutda-0.4.3.dist-info/top_level.txt,sha256=K_S8S2ArTcepp_xCda5D_91jTHd04raVcOt7dX6vmHw,8
|
|
10
|
+
mogutda-0.4.3.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mogutda
|