void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>:: SplitNode(std::vector<size_t>& oldFromNew, const size_t maxLeafSize, SplitType<BoundType<MetricType>, MatType>& splitter) { // We need to expand the bounds of this node properly. UpdateBound(bound); // Calculate the furthest descendant distance. furthestDescendantDistance = 0.5 * bound.Diameter(); // First, check if we need to split at all. if (count <= maxLeafSize) return; // We can't split this. // splitCol denotes the two partitions of the dataset after the split. The // points on its left go to the left child and the others go to the right // child. size_t splitCol; // Find the partition of the node. This method does not perform the split. typename Split::SplitInfo splitInfo; const bool split = splitter.SplitNode(bound, *dataset, begin, count, splitInfo); // The node may not be always split. For instance, if all the points are the // same, we can't split them. if (!split) return; // Perform the actual splitting. This will order the dataset such that // points that belong to the left subtree are on the left of splitCol, and // points from the right subtree are on the right side of splitCol. splitCol = splitter.PerformSplit(*dataset, begin, count, splitInfo, oldFromNew); assert(splitCol > begin); assert(splitCol < begin + count); // Now that we know the split column, we will recursively split the children // by calling their constructors (which perform this splitting process). left = new BinarySpaceTree(this, begin, splitCol - begin, oldFromNew, splitter, maxLeafSize); right = new BinarySpaceTree(this, splitCol, begin + count - splitCol, oldFromNew, splitter, maxLeafSize); // Calculate parent distances for those two nodes. arma::vec center, leftCenter, rightCenter; Center(center); left->Center(leftCenter); right->Center(rightCenter); const ElemType leftParentDistance = MetricType::Evaluate(center, leftCenter); const ElemType rightParentDistance = MetricType::Evaluate(center, rightCenter); left->ParentDistance() = leftParentDistance; right->ParentDistance() = rightParentDistance; }
void BinarySpaceTree<BoundType, StatisticType, MatType, SplitType>::SplitNode( MatType& data, std::vector<size_t>& oldFromNew, const size_t maxLeafSize, SplitType& splitter) { // This should be a single function for Bound. // We need to expand the bounds of this node properly. bound |= data.cols(begin, begin + count - 1); // Calculate the furthest descendant distance. furthestDescendantDistance = 0.5 * bound.Diameter(); // First, check if we need to split at all. if (count <= maxLeafSize) return; // We can't split this. // splitCol denotes the two partitions of the dataset after the split. The // points on its left go to the left child and the others go to the right // child. size_t splitCol; // Split the node. The elements of 'data' are reordered by the splitting // algorithm. This function call updates splitCol and oldFromNew. const bool split = splitter.SplitNode(bound, data, begin, count, splitCol, oldFromNew); // The node may not be always split. For instance, if all the points are the // same, we can't split them. if (!split) return; // Now that we know the split column, we will recursively split the children // by calling their constructors (which perform this splitting process). left = new BinarySpaceTree<BoundType, StatisticType, MatType>(data, begin, splitCol - begin, oldFromNew, splitter, this, maxLeafSize); right = new BinarySpaceTree<BoundType, StatisticType, MatType>(data, splitCol, begin + count - splitCol, oldFromNew, splitter, this, maxLeafSize); // Calculate parent distances for those two nodes. arma::vec centroid, leftCentroid, rightCentroid; Centroid(centroid); left->Centroid(leftCentroid); right->Centroid(rightCentroid); const double leftParentDistance = bound.Metric().Evaluate(centroid, leftCentroid); const double rightParentDistance = bound.Metric().Evaluate(centroid, rightCentroid); left->ParentDistance() = leftParentDistance; right->ParentDistance() = rightParentDistance; }