Esempio n. 1
0
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType>::
RectangleTree(
    const RectangleTree& other,
    const bool deepCopy) :
    maxNumChildren(other.MaxNumChildren()),
    minNumChildren(other.MinNumChildren()),
    numChildren(other.NumChildren()),
    children(maxNumChildren + 1),
    parent(other.Parent()),
    begin(other.Begin()),
    count(other.Count()),
    maxLeafSize(other.MaxLeafSize()),
    minLeafSize(other.MinLeafSize()),
    bound(other.bound),
    splitHistory(other.SplitHistory()),
    parentDistance(other.ParentDistance()),
    dataset(new MatType(*other.dataset)),
    ownsDataset(true),
    points(other.Points()),
    localDataset(NULL)
{
  if (deepCopy)
  {
    if (numChildren > 0)
    {
      for (size_t i = 0; i < numChildren; i++)
      {
        children[i] = new RectangleTree(*(other.Children()[i]));
      }
    }
    else
    {
      localDataset = new MatType(other.LocalDataset());
    }
  }
  else
  {
    children = other.Children();
    arma::mat& otherData = const_cast<arma::mat&>(other.LocalDataset());
    localDataset = &otherData;
  }
}
Esempio n. 2
0
size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
                     DescentType>::TreeDepth() const
{
  int n = 1;
  RectangleTree* currentNode = const_cast<RectangleTree*> (this);

  while (!currentNode->IsLeaf())
  {
    currentNode = currentNode->Children()[0];
    n++;
  }

  return n;
}
Esempio n. 3
0
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType>::
    CondenseTree(const arma::vec& point,
                 std::vector<bool>& relevels,
                 const bool usePoint)
{
  // First delete the node if we need to.  There's no point in shrinking the
  // bound first.
  if (IsLeaf() && count < minLeafSize && parent != NULL)
  {
    // We can't delete the root node.
    for (size_t i = 0; i < parent->NumChildren(); i++)
    {
      if (parent->Children()[i] == this)
      {
        // Decrement numChildren.
        parent->Children()[i] = parent->Children()[--parent->NumChildren()];

        // We find the root and shrink bounds at the same time.
        bool stillShrinking = true;
        RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType>* root =
            parent;
        while (root->Parent() != NULL)
        {
          if (stillShrinking)
            stillShrinking = root->ShrinkBoundForBound(bound);
          root = root->Parent();
        }
        if (stillShrinking)
          stillShrinking = root->ShrinkBoundForBound(bound);

        // Reinsert the points at the root node.
        for (size_t j = 0; j < count; j++)
          root->InsertPoint(points[j], relevels);

        // This will check the minFill of the parent.
        parent->CondenseTree(point, relevels, usePoint);
        // Now it should be safe to delete this node.
        SoftDelete();

        return;
      }
    }
    // Control should never reach here.
    assert(false);
  }
  else if (!IsLeaf() && numChildren < minNumChildren)
  {
    if (parent != NULL)
    {
      // The normal case.  We need to be careful with the root.
      for (size_t j = 0; j < parent->NumChildren(); j++)
      {
        if (parent->Children()[j] == this)
        {
          // Decrement numChildren.
          parent->Children()[j] = parent->Children()[--parent->NumChildren()];
          size_t level = TreeDepth();

          // We find the root and shrink bounds at the same time.
          bool stillShrinking = true;
          RectangleTree* root = parent;
          while (root->Parent() != NULL)
          {
            if (stillShrinking)
              stillShrinking = root->ShrinkBoundForBound(bound);
            root = root->Parent();
          }
          if (stillShrinking)
            stillShrinking = root->ShrinkBoundForBound(bound);

          // Reinsert the nodes at the root node.
          for (size_t i = 0; i < numChildren; i++)
            root->InsertNode(children[i], level, relevels);

          // This will check the minFill of the point.
          parent->CondenseTree(point, relevels, usePoint);
          // Now it should be safe to delete this node.
          SoftDelete();

          return;
        }
      }
    }
    else if (numChildren == 1)
    {
      // If there are multiple children, we can't do anything to the root.
      RectangleTree* child = children[0];
      for (size_t i = 0; i < child->NumChildren(); i++) {
        children[i] = child->Children()[i];
        children[i]->Parent() = this;
      }

      numChildren = child->NumChildren();

      for (size_t i = 0; i < child->Count(); i++)
      {
        // In case the tree has a height of two.
        points[i] = child->Points()[i];
        localDataset->col(i) = child->LocalDataset().col(i);
      }

      count = child->Count();
      maxNumChildren = child->MaxNumChildren(); // Required for the X tree.
      child->SoftDelete();
      return;
    }
  }

  // If we didn't delete it, shrink the bound if we need to.
  if (usePoint && ShrinkBoundForPoint(point) && parent != NULL)
    parent->CondenseTree(point, relevels, usePoint);
  else if (!usePoint && ShrinkBoundForBound(bound) && parent != NULL)
    parent->CondenseTree(point, relevels, usePoint);
}