<commit_before>#ifndef GEN_HYPERCUBE_TREE_H
#define GEN_HYPERCUBE_TREE_H

#include "fastlib/fastlib.h"
#include "fastlib/tree/statistic.h"

namespace proximity {

  template<class TStatistic>
  class GenHypercubeTree {

   public:

    typedef DHrectBound<2> Bound;
    typedef Matrix Dataset;
    typedef TStatistic Statistic;
    
    Bound bound_;
    ArrayList<GenHypercubeTree *> children_;
    index_t num_children_;
    ArrayList<index_t> begin_;
    ArrayList<index_t> count_;
    index_t total_count_;
    index_t level_;
    unsigned int node_index_;
    Statistic stat_;
    
    
   public:

    GenHypercubeTree() {
    }

    ~GenHypercubeTree() {
      if(children_.size() > 0) {
	for(index_t i = 0; i < children_.size(); i++) {
	  delete children_[i];
	}
      }      
    }

    const Statistic& stat() const {
      return stat_;
    }
    
    Statistic& stat() {
      return stat_;
    }

    /** @brief Tests whether the current node is a leaf node
     *         (childless).
     *
     *  @return true if childless, false otherwise.
     */
    bool is_leaf() const {
      return num_children_ == 0;
    }

    void Init(index_t number_of_particle_sets, index_t dimension) {
      begin_.Init(number_of_particle_sets);
      count_.Init(number_of_particle_sets);
      total_count_ = 0;
      node_index_ = 0;
      children_.Init();
      num_children_ = 0;
    }

    void Init(index_t particle_set_number, index_t begin_in, 
	      index_t count_in) {

      begin_[particle_set_number] = begin_in;
      count_[particle_set_number] = count_in;
      total_count_ += count_in;
    }

    double side_length() const {
      const DRange &range = bound_.get(0);
      return range.hi - range.lo;
    }

    const Bound& bound() const {
      return bound_;
    }
    
    Bound& bound() {
      return bound_;
    }

    GenHypercubeTree *get_child(int index) const {
      return children_[index];
    }

    void set_level(index_t level) {
      level_ = level;
    }

    GenHypercubeTree *AllocateNewChild(index_t number_of_particle_sets,
				       index_t dimension,
				       unsigned int node_index_in) {
      
      GenHypercubeTree *new_node = new GenHypercubeTree();
      *(children_.PushBackRaw()) = new_node;
      num_children_++;

      new_node->Init(number_of_particle_sets, dimension);
      new_node->node_index_ = node_index_in;

      return new_node;
    }

    /**
     * Gets the index of the begin point of this subset.
     */
    index_t begin(index_t particle_set_number) const {
      return begin_[particle_set_number];
    }
    
    /**
     * Gets the index one beyond the last index in the series.
     */
    index_t end(index_t particle_set_number) const {
      return begin_[particle_set_number] + count_[particle_set_number];
    }
    
    unsigned int node_index() const {
      return node_index_;
    }

    /**
     * Gets the number of points in this subset.
     */
    index_t count(index_t particle_set_number) const {
      return count_[particle_set_number];
    }

    index_t count() const {
      return total_count_;
    }

    index_t level() const {
      return level_;
    }

    /**
     * Gets the number of children.
     */
    index_t num_children() const {
      return num_children_;
    }

    void Print() const {
      if (!is_leaf()) {
	printf("internal node: %d points total on level %d\n", total_count_,
	       level_);
	for(index_t i = 0; i < begin_.size(); i++) {
	  printf("   set %d: %d to %d: %d points total\n", i, 
		 begin_[i], begin_[i] + count_[i] - 1, count_[i]);	  
	}
	for(index_t c = 0; c < num_children_; c++) {
	  children_[c]->Print();
	}
      }
      else {
	printf("leaf node: %d points total on level %d\n", total_count_,
	       level_);
	for(index_t i = 0; i < begin_.size(); i++) {
	  printf("   set %d: %d to %d: %d points total\n", i, 
		 begin_[i], begin_[i] + count_[i] - 1, count_[i]);	  
	}
      }
    }

  };

#include "gen_hypercube_tree_impl.h"

  /** @brief Creates a generalized hypercube tree (high-dimensional
   * generalization of quad-tree, octree) from data.
   *
   * @experimental
   *
   * This requires you to pass in two unitialized ArrayLists which
   * will contain index mappings so you can account for the
   * re-ordering of the matrix.  (By unitialized I mean don't call
   * Init on it)
   *
   * @param matrix data where each column is a point, WHICH WILL BE
   * RE-ORDERED<commit_msg>Added the bounding box printing<commit_after>#ifndef GEN_HYPERCUBE_TREE_H
#define GEN_HYPERCUBE_TREE_H

#include "fastlib/fastlib.h"
#include "fastlib/tree/statistic.h"

namespace proximity {

  template<class TStatistic>
  class GenHypercubeTree {

   public:

    typedef DHrectBound<2> Bound;
    typedef Matrix Dataset;
    typedef TStatistic Statistic;
    
    Bound bound_;
    ArrayList<GenHypercubeTree *> children_;
    ArrayList<index_t> begin_;
    ArrayList<index_t> count_;
    index_t total_count_;
    index_t level_;
    unsigned int node_index_;
    Statistic stat_;
    
    
   public:

    GenHypercubeTree() {
    }

    ~GenHypercubeTree() {
      if(children_.size() > 0) {
	for(index_t i = 0; i < children_.size(); i++) {
	  delete children_[i];
	}
      }      
    }

    const Statistic& stat() const {
      return stat_;
    }
    
    Statistic& stat() {
      return stat_;
    }

    /** @brief Tests whether the current node is a leaf node
     *         (childless).
     *
     *  @return true if childless, false otherwise.
     */
    bool is_leaf() const {
      return children_.size() == 0;
    }

    void Init(index_t number_of_particle_sets, index_t dimension) {
      begin_.Init(number_of_particle_sets);
      count_.Init(number_of_particle_sets);
      total_count_ = 0;
      node_index_ = 0;
      children_.Init();
    }

    void Init(index_t particle_set_number, index_t begin_in, 
	      index_t count_in) {

      begin_[particle_set_number] = begin_in;
      count_[particle_set_number] = count_in;
      total_count_ += count_in;
    }

    double side_length() const {
      const DRange &range = bound_.get(0);
      return range.hi - range.lo;
    }

    const Bound& bound() const {
      return bound_;
    }
    
    Bound& bound() {
      return bound_;
    }

    GenHypercubeTree *get_child(int index) const {
      return children_[index];
    }

    void set_level(index_t level) {
      level_ = level;
    }

    GenHypercubeTree *AllocateNewChild(index_t number_of_particle_sets,
				       index_t dimension,
				       unsigned int node_index_in) {
      
      GenHypercubeTree *new_node = new GenHypercubeTree();
      *(children_.PushBackRaw()) = new_node;

      new_node->Init(number_of_particle_sets, dimension);
      new_node->node_index_ = node_index_in;

      return new_node;
    }

    /**
     * Gets the index of the begin point of this subset.
     */
    index_t begin(index_t particle_set_number) const {
      return begin_[particle_set_number];
    }
    
    /**
     * Gets the index one beyond the last index in the series.
     */
    index_t end(index_t particle_set_number) const {
      return begin_[particle_set_number] + count_[particle_set_number];
    }
    
    unsigned int node_index() const {
      return node_index_;
    }

    /**
     * Gets the number of points in this subset.
     */
    index_t count(index_t particle_set_number) const {
      return count_[particle_set_number];
    }

    index_t count() const {
      return total_count_;
    }

    index_t level() const {
      return level_;
    }

    /**
     * Gets the number of children.
     */
    index_t num_children() const {
      return children_.size();
    }

    void Print() const {
      if (!is_leaf()) {
	printf("internal node: %d points total on level %d\n", total_count_,
	       level_);
	printf("  bound:\n");
	for(index_t i = 0; i < bound_.dim(); i++) {
	  printf("%g %g\n", bound_.get(i).lo, bound_.get(i).hi);
	}
	for(index_t i = 0; i < begin_.size(); i++) {
	  printf("   set %d: %d to %d: %d points total\n", i, 
		 begin_[i], begin_[i] + count_[i] - 1, count_[i]);	  
	}
	for(index_t c = 0; c < children_.size(); c++) {
	  children_[c]->Print();
	}
      }
      else {
	printf("leaf node: %d points total on level %d\n", total_count_,
	       level_);
	printf("  bound:\n");
	for(index_t i = 0; i < bound_.dim(); i++) {
	  printf("%g %g\n", bound_.get(i).lo, bound_.get(i).hi);
	}
	for(index_t i = 0; i < begin_.size(); i++) {
	  printf("   set %d: %d to %d: %d points total\n", i, 
		 begin_[i], begin_[i] + count_[i] - 1, count_[i]);	  
	}
      }
    }

  };

#include "gen_hypercube_tree_impl.h"

  /** @brief Creates a generalized hypercube tree (high-dimensional
   * generalization of quad-tree, octree) from data.
   *
   * @experimental
   *
   * This requires you to pass in two unitialized ArrayLists which
   * will contain index mappings so you can account for the
   * re-ordering of the matrix.  (By unitialized I mean don't call
   * Init on it)
   *
   * @param matrix data where each column is a point, WHICH WILL BE
   * RE-ORDERED
{'fraction_non_alphanumeric': 0.11026824978012313, 'fraction_numerical': 0.002968337730870712, 'mean_word_length': 2.4881134969325154, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1115115', 'n_tokens_mistral': 3166, 'n_tokens_neox': 2987, 'n_words': 780}