import numpy as np from point import * from function import * class Nnnar: def __init__(self, nbDimensions, minCoord, maxCoord, nbSubdivisions): self.nbDimensions = nbDimensions self.minCoord = minCoord self.maxCoord = maxCoord self.nbSubdivisions = nbSubdivisions self.delta = maxCoord - minCoord self.unit = self.delta / nbSubdivisions coord = np.zeros(nbDimensions,dtype=int) + self.nbSubdivisions self.space = np.zeros(coord) fillSpace = np.vectorize(lambda x: [], otypes=[object]) self.space = fillSpace(self.space) self.calculatedSpaceAroundIdx = [] def addPoint(self, coord, value): if len(coord) != self.nbDimensions: raise AttributeError("Error: wrong number of dimensions") self.space[*self.getSpaceIdxFromCoord(coord)].append(Point(coord, value)) def getValueOfPoint(self, coord,nbNearest): points, dists = self.getNNearest(coord, nbNearest) ttPart = 1/(dists[0]+1) value = [] for i in points[0].value: value.append(i * ttPart) for idx in range(1,len(points)): ttPart += 1/(dists[idx]+1) tvalue = points[idx].value for i in range(len(tvalue)): value[i] += tvalue[i] * (1/(dists[idx]+1)) for i in range(len(value)): value[i] = value[i] / ttPart return value def getNNearest(self, coord, nbNearest): idx = self.getSpaceIdxFromCoord(coord) nbAround = 0 selected = [] while len(selected) < nbNearest: selected = [] subSpaceIdxList = getSpaceIdxAround(idx, nbAround, self) for subSpaceIdx in subSpaceIdxList: selected += selectPointsInRange(self.space[tuple(subSpaceIdx)],coord,nbAround*self.unit,self.space) nbAround += 1 found = [] dist = [] i=0 while len(found) < nbNearest: found.append(selected[i]) dist.append(selected[i].getDistFromCoord(coord)) i+=1 maxDistIdx = foundMaxIndex(dist) maxDist = max(dist) while i != len(selected): if (selected[i].getDistFromCoord(coord) < maxDist): found.pop(maxDistIdx) dist.pop(maxDistIdx) found.append(selected[i]) dist.append(selected[i].getDistFromCoord(coord)) maxDistIdx = foundMaxIndex(dist) maxDist = max(dist) i+=1 return found, dist def getSpaceIdxFromCoord(self,coord): coord = coord - self.minCoord coord = coord / self.unit coord = np.floor(coord).astype(int) return coord