Esempio n. 1
0
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;
}