def updateoninsertion(self, node): """ Creates a new cell for the new node and updates the cells of its neighbors. The new inserted node does not split a jump. The nearby uninserted points are in the cells of nearby nodes from one level up to one level down. Parameters: ---------- node : Node The new inserted node. """ self.addnode(node) for point in self.rnn_out(rel(par(node)) | ch(rel(par(node))) | ch(rel(node))): self.trytochangernn(point, node)
def nnhelper(self, point, currentnodes, level): if point.distto(*[n.point for n in currentnodes ]) > self.tree.cr * self.tree.tau**level: return None nextnodes = { n if n.level == level - 1 else n.par for n in ch(currentnodes) if dist(n, point) <= self.tree.cr * self.tree.tau**level } nn = self.nnhelper(point, nextnodes, level - 1) return nn if nn else min(currentnodes, key=lambda n: point.distto(n.point))
def nn(self, point): currentnode = self.tree.root nextnode = self.tree.root.getchild() self.basictouchno += 1 while dist(nextnode, point) <= self.tree.cr * self.tree.tau**nextnode.level: currentnode = nextnode allnodes = ch(rel(currentnode)) nextlevel = max(n.level for n in allnodes) nextnode = min(allnodes, key=functools.partial(self.mincoveringdist, point=point, level=nextlevel)) return currentnode
def update_rel(self, node, closest): """ Updates the relative list of a given node. Parameters: ---------- node : Node The node that its relatives should be updated. closest : Node The node closest to `node` at the same level. """ for other in ch(rel(par(closest))): if self.isrel(node, other): if other.level < node.level: other = self.splitabove(other, node.level) node.addrel(other)
def nnhelper(self, point, currentnodes, level): if len(currentnodes) != 0: self.basictouchno += len(currentnodes) if len(currentnodes) == 0 or \ point.distto(*[n.point for n in currentnodes]) > self.tree.cr * self.tree.tau ** level: return None children = ch(currentnodes) nextlevel = max(n.level for n in children) nextnodes = { n if n.level == nextlevel else n.par for n in children if dist(n, point) <= self.tree.cr * self.tree.tau**nextlevel } self.basictouchno += len(children) nn = self.nnhelper(point, nextnodes, nextlevel) if nn: return nn self.basictouchno += len(currentnodes) return min(currentnodes, key=lambda n: point.distto(n.point))
def update_ch(self, node): """ Updates children of a given node. Parameters: ---------- node : Node The node that its relatives should be updated. """ for other in ch(rel(node)): if dist(node, other) < dist(other, other.par): oldpar = other.par node.addch(other) child = oldpar.getchild() # The old parent should not be removed from the tree because it is a relative of `node` # However, if it has only one child, then that child should be checked # against the semi-compressed condition if len(oldpar.ch) == 1 and len(child.ch) == 1 and len(child.rel) == 1: if hasattr(self, 'ploc'): self.ploc.updateonremoval(child) oldpar.addch(child.getchild()) oldpar.ch.discard(child)
def nn(self, point): currentnode = self.tree.root nextnode = self.tree.root.getchild() # closestdist = dist(nextnode, point) # while closestdist <= self.tree.cr * self.tree.tau ** nextnode.level: # currentnode = nextnode # allnodes = ch(rel(currentnode)) # nextnode = allnodes.pop() # closestdist = dist(nextnode, point) # for n in allnodes: # newdist = dist(n,point) # if newdist < closestdist and newdist <= self.tree.cr * self.tree.tau ** n.level: # nextnode, closestdist = n, newdist while dist(nextnode, point) <= self.tree.cr * self.tree.tau**nextnode.level: currentnode = nextnode allnodes = ch(rel(currentnode)) nextlevel = max(n.level for n in allnodes) nextnode = min(allnodes, key=functools.partial(self.mincoveringdist, point=point, level=nextlevel)) return currentnode