private void init(SpTree parent, INDArray data, INDArray corner, INDArray width, Set<INDArray> indices, String similarityFunction) { this.parent = parent; D = data.columns(); N = data.rows(); this.similarityFunction = similarityFunction; nodeCapacity = N % NODE_RATIO; index = new int[nodeCapacity]; for (int d = 1; d < this.D; d++) numChildren *= 2; this.indices = indices; isLeaf = true; size = 0; cumSize = 0; children = new SpTree[numChildren]; this.data = data; boundary = new Cell(D); boundary.setCorner(corner.dup()); boundary.setWidth(width.dup()); centerOfMass = Nd4j.create(D); buf = Nd4j.create(D); }
/** * Verifies the structure of the tree (does bounds checking on each node) * @return true if the structure of the tree * is correct. */ public boolean isCorrect() { for (int n = 0; n < size; n++) { INDArray point = data.slice(index[n]); if (!boundary.contains(point)) return false; } if (!isLeaf()) { boolean correct = true; for (int i = 0; i < numChildren; i++) correct = correct && children[i].isCorrect(); return correct; } return true; }
double maxWidth = boundary.width().max(Integer.MAX_VALUE).getDouble(0);
private boolean insert(int index) { INDArray point = data.slice(index); if (!boundary.contains(point)) return false; cumSize++; double mult1 = (double) (cumSize - 1) / (double) cumSize; double mult2 = 1.0 / (double) cumSize; centerOfMass.muli(mult1); centerOfMass.addi(point.mul(mult2)); // If there is space in this quad tree and it is a leaf, add the object here if (isLeaf() && size < nodeCapacity) { this.index[size] = index; indices.add(point); size++; return true; } for (int i = 0; i < size; i++) { INDArray compPoint = data.slice(this.index[i]); if (compPoint.equals(point)) return true; } if (isLeaf()) subDivide(); // Find out where the point can be inserted for (int i = 0; i < numChildren; i++) { if (children[i].insert(index)) return true; } throw new IllegalStateException("Shouldn't reach this state"); }