summaryrefslogtreecommitdiff
path: root/phstuff/simplicial.py
diff options
context:
space:
mode:
Diffstat (limited to 'phstuff/simplicial.py')
-rw-r--r--phstuff/simplicial.py144
1 files changed, 144 insertions, 0 deletions
diff --git a/phstuff/simplicial.py b/phstuff/simplicial.py
new file mode 100644
index 0000000..884a543
--- /dev/null
+++ b/phstuff/simplicial.py
@@ -0,0 +1,144 @@
+class Node:
+ def __init__(self, x, i, w, parent):
+ self.x = x
+ self.i = i
+ self.w = w
+ self.parent = parent
+ self.children = dict()
+
+ def is_root(self):
+ return self.parent is None
+
+ def simplex(self):
+ s = []
+ node = self
+ if node.is_root():
+ return None
+
+ while True:
+ s.append(node.x)
+ node = node.parent
+ if node.is_root():
+ break
+
+ s.reverse()
+ return s
+
+ def boundary_nodes(self):
+ if self.is_root():
+ return None
+ if self.parent.is_root():
+ return []
+
+ ret = []
+ up = []
+ skip = self
+
+ while not skip.is_root():
+ down = list(up)
+ node = skip.parent
+ while len(down) != 0:
+ node = node.children[down.pop()]
+ ret.append(node)
+ up.append(skip.x)
+ skip = skip.parent
+
+ assert(len(ret) == self.dimension() + 1)
+ return ret
+
+ def boundary_simplices(self):
+ ret = []
+ for node in self.boundary_nodes():
+ ret.append(node.simplex())
+ return ret
+
+ def dimension(self):
+ ret = 0
+ if self.is_root():
+ return None
+
+ node = self
+ while not node.parent.is_root():
+ ret += 1
+ node = node.parent
+ return ret
+
+class ComplexIterator:
+ def __init__(self, start):
+ self.__to_go = start.children.values()
+
+ def next(self):
+ if len(self.__to_go) == 0:
+ raise StopIteration
+ else:
+ ret = self.__to_go.pop(0)
+ self.__to_go.extend(ret.children.values())
+ return ret
+
+class Complex:
+ def __init__(self):
+ self.__root = Node(None, None, None, None)
+ self.__count = 0
+ self.__top_dim = -1
+ self.__ordered = False
+
+ def size(self):
+ return self.__count
+
+ def top_dim(self):
+ return self.__top_dim
+
+ def is_ordered(self):
+ return self.__ordered
+
+ def order(self):
+ i = 0
+ for node in self:
+ node.i = i
+ i += 1
+ self.__ordered = True
+
+ def find(self, simplex): # The simplex must be sorted!
+ p = len(simplex) - 1
+
+ if p < -1:
+ return None
+
+ node = self.__root
+
+ for v in simplex:
+ if v in node.children:
+ node = node.children[v]
+ else:
+ return None
+ return node
+
+ def add(self, simplex, weight):
+ self.__ordered = False
+ simplex = sorted(simplex)
+
+ p = len(simplex) - 1
+ if p < 0:
+ return None
+
+ last = simplex[-1]
+ pre = simplex[0:p]
+
+ parent = self.find(pre)
+
+ node = Node(last, None, weight, parent)
+ self.__count += 1
+ self.__top_dim = max(self.__top_dim, p)
+
+ return parent.children.setdefault(last, node)
+
+
+ def __contains__(self, simplex):
+ return self.find(simplex) is not None
+
+ def __iter__(self):
+ return ComplexIterator(self.__root)
+
+
+
+