From ed983bbeeb08c57a539b6403d73c8b7242564cf7 Mon Sep 17 00:00:00 2001 From: Dongryeol Lee Date: Tue, 5 Feb 2008 19:22:15 +0000 Subject: [PATCH] More initialization routines completed --- .../dongryel/regression/local_linear_krylov.h | 81 ++++++++++- .../local_linear_krylov_solver_impl.h | 127 +++++++++++++----- 2 files changed, 165 insertions(+), 43 deletions(-) diff --git a/fastlib2/contrib/dongryel/regression/local_linear_krylov.h b/fastlib2/contrib/dongryel/regression/local_linear_krylov.h index 032accf5a4..47524657b2 100644 --- a/fastlib2/contrib/dongryel/regression/local_linear_krylov.h +++ b/fastlib2/contrib/dongryel/regression/local_linear_krylov.h @@ -47,22 +47,48 @@ class LocalLinearKrylov { */ Vector ll_vector_u_; + /** @brief The general purpose lower bound on each negative sum + * component for the local linear computation. + */ + Vector neg_ll_vector_l_; + + /** @brief The general purpose upper bound on each negative sum + * component for the local linear computation. + */ + Vector neg_ll_vector_u_; + /** @brief The lower bound vector offset passed from the above on * each sum component of the vector owned by this node. */ Vector postponed_ll_vector_l_; /** @brief This stores the portion pruned by finite difference for - * the right hand sides. + * each sum component. */ Vector postponed_ll_vector_e_; /** @brief The upper bound vector offset passed from above on each - * sum component of the right hand sides owned by this - * node. + * sum component owned by this node. */ Vector postponed_ll_vector_u_; + /** @brief The lower bound vector offset passed from the above on + * each negative sum component owned by this node. + */ + Vector neg_postponed_ll_vector_l_; + + /** @brief This stores the portion pruned by finite difference for + * each negative sum component of the vector owned by this + * node. + */ + Vector neg_postponed_ll_vector_e_; + + /** @brief The upper bound vector offset passed from above on each + * negative sum component of the right hand sides owned by + * this node. + */ + Vector neg_postponed_ll_vector_u_; + /** @brief The data weighted by the target values. */ Vector sum_targets_weighted_by_data_; @@ -71,6 +97,13 @@ class LocalLinearKrylov { */ double l1_norm_sum_targets_weighted_by_data_; + /** @brief For local linear regression, this is the sum of the + * coordinates of the points owned by this node (with the + * first coordinate denoting the number of points, and the + * remaining D coordinates being the sum). + */ + Vector sum_coordinates_; + /** @brief The bounding box for the solution vectors. */ DHrectBound<2> bound_for_solutions_; @@ -94,10 +127,18 @@ class LocalLinearKrylov { // numbers. ll_vector_l_.Init(dimension + 1); ll_vector_u_.Init(dimension + 1); + neg_ll_vector_l_.Init(dimension + 1); + neg_ll_vector_u_.Init(dimension + 1); + postponed_ll_vector_l_.Init(dimension + 1); postponed_ll_vector_e_.Init(dimension + 1); postponed_ll_vector_u_.Init(dimension + 1); + neg_postponed_ll_vector_l_.Init(dimension + 1); + neg_postponed_ll_vector_e_.Init(dimension + 1); + neg_postponed_ll_vector_u_.Init(dimension + 1); + sum_targets_weighted_by_data_.Init(dimension + 1); + sum_coordinates_.Init(dimension + 1); bound_for_solutions_.Init(dimension + 1); l1_norm_sum_targets_weighted_by_data_ = 0; @@ -112,6 +153,17 @@ class LocalLinearKrylov { // Allocate all memory required for the statistics. AllocateMemory(dataset.n_rows()); + + // Here, run over each point and compute the coordinate sums. + sum_coordinates_.SetZero(); + for(index_t i = 0; i < count; i++) { + const double *point = dataset.GetColumnPtr(i + start); + + for(index_t j = 1; j <= dataset.n_rows(); j++) { + sum_coordinates_[j] += point[j - 1]; + } + } + sum_coordinates_[0] = count; } void Init(const Matrix &dataset, index_t start, index_t count, @@ -120,6 +172,10 @@ class LocalLinearKrylov { // Allocate all memory required for the statatistics. AllocateMemory(dataset.n_rows()); + + // Combine the two coordinate sums. + la::AddOverwrite(left_stat.sum_coordinates_, + right_stat.sum_coordinates_, &sum_coordinates_); } }; @@ -277,10 +333,12 @@ class LocalLinearKrylov { } } - /** @brief Compute the maximum dot product possible for a pair of + /** @brief Compute the dot-product bounds possible for a pair of * point lying in each of the two given regions. */ - double MaxDotProductBetweenTwoBounds_(Tree *qnode, Tree *rnode); + void DotProductBetweenTwoBounds_(Tree *qnode, Tree *rnode, + DRange &negative_dot_product_range, + DRange &positive_dot_product_range); /** @brief Initialize the bound statistics relevant to the right * hand side computation. @@ -336,11 +394,20 @@ class LocalLinearKrylov { } /** @brief Initialize the query tree for an iteration inside a - * Krylov solver. + * Krylov solver. This forms the bounds for the solution + * vectors owned by the query points for a given query node. * * @param qnode The current query node. */ - void InitializeQueryTreeSolver_(Tree *qnode); + void InitializeQueryTreeSolutionBound_(Tree *qnode); + + /** @brief Initialize the query tree for an iteration inside a + * Krylov solver. This resets the required vector bound + * statistics to default. + */ + void InitializeQueryTreeSumBound_ + (Tree *qnode, DRange &root_negative_dot_product_range, + DRange &root_posistive_dot_product_range); void SolveLeastSquaresByKrylov_(); diff --git a/fastlib2/contrib/dongryel/regression/local_linear_krylov_solver_impl.h b/fastlib2/contrib/dongryel/regression/local_linear_krylov_solver_impl.h index 2f08809e5c..185006bd17 100644 --- a/fastlib2/contrib/dongryel/regression/local_linear_krylov_solver_impl.h +++ b/fastlib2/contrib/dongryel/regression/local_linear_krylov_solver_impl.h @@ -5,68 +5,123 @@ #endif template -double LocalLinearKrylov::MaxDotProductBetweenTwoBounds_ -(Tree *qnode, Tree *rnode) { +void LocalLinearKrylov::DotProductBetweenTwoBounds_ +(Tree *qnode, Tree *rnode, DRange &negative_dot_product_range, + DRange &positive_dot_product_range) { DHrectBound<2> bound_for_solutions = qnode->stat().bound_for_solutions_; - double max_dot_product = bound_for_solutions.get(0).hi; + + // Initialize the dot-product ranges. + negative_dot_product_range.lo = negative_dot_product_range.hi = 0; + positive_dot_product_range.lo = positive_dot_product_range.hi = 0; for(index_t d = 1; d <= dimension_; d++) { - DRange &solution_directional_bound = bound_for_solutions.get(d); - DRange &reference_node_directional_bound = rnode->bound().get(d - 1); - double prod_solution_min_reference_min = - solution_directional_bound.lo * reference_node_directional_bound.lo; - double prod_solution_min_reference_max = - solution_directional_bound.lo * reference_node_directional_bound.hi; - double prod_solution_max_reference_min = - solution_directional_bound.hi * reference_node_directional_bound.lo; - double prod_solution_max_reference_max = - solution_directional_bound.hi * reference_node_directional_bound.hi; - - max_dot_product += - std::max(prod_solution_min_reference_min, - std::max(prod_solution_min_reference_max, - std::max(prod_solution_max_reference_min, - prod_solution_max_reference_max))); - } - return max_dot_product; + const DRange &solution_directional_bound = bound_for_solutions.get(d); + const DRange &reference_node_directional_bound = rnode->bound().get(d - 1); + + if(solution_directional_bound.lo > 0) { + positive_dot_product_range.hi += solution_directional_bound.hi * + reference_node_directional_bound.hi; + } + else if(solution_directional_bound.Contains(0)) { + positive_dot_product_range.hi += solution_directional_bound.hi * + reference_node_directional_bound.hi; + negative_dot_product_range.lo += solution_directional_bound.lo * + reference_node_directional_bound.hi; + } + else { + negative_dot_product_range.lo += solution_directional_bound.lo * + reference_node_directional_bound.hi; + negative_dot_product_range.hi += solution_directional_bound.hi * + reference_node_directional_bound.lo; + } + } // End of looping over each component... } template -void LocalLinearKrylov::InitializeQueryTreeSolver_(Tree *qnode) { - - // Set the bounds to default values. - (qnode->stat().ll_vector_l_).SetZero(); - (qnode->stat().ll_vector_u_).CopyValues - (rroot_->stat().sum_targets_weighted_by_data_); - (qnode->stat().postponed_ll_vector_l_).SetZero(); - (qnode->stat().postponed_ll_vector_e_).SetZero(); - (qnode->stat().postponed_ll_vector_u_).SetZero(); +void LocalLinearKrylov::InitializeQueryTreeSolutionBound_ +(Tree *qnode) { // If the query node is a leaf, then exhaustively iterate over and // form bounding boxes of the current solution. if(qnode->is_leaf()) { + (qnode->stat().bound_for_solutions_).Reset(); for(index_t q = qnode->begin(); q < qnode->end(); q++) { + Vector solution_vector; + solution_vectors_e_.MakeColumnVector(q, &solution_vector); + qnode->stat().bound_for_solutions_ |= solution_vector; } } // Otherwise, traverse the left and the right and combine the // bounding boxes of the solutions for the two children. - else { - InitializeQueryTreeSolver_(qnode->left()); - InitializeQueryTreeSolver_(qnode->right()); + else { + InitializeQueryTreeSolutionBound_(qnode->left()); + InitializeQueryTreeSolutionBound_(qnode->right()); + (qnode->stat().bound_for_solutions_).Reset(); + qnode->stat().bound_for_solutions_ |= + (qnode->left()->stat()).bound_for_solutions_; + qnode->stat().bound_for_solutions_ |= + (qnode->right()->stat()).bound_for_solutions_; + } +} + +template +void LocalLinearKrylov::InitializeQueryTreeSumBound_ +(Tree *qnode, DRange &root_negative_dot_product_range, + DRange &root_positive_dot_product_range) { + + // Set the bounds to default values. + (qnode->stat().ll_vector_l_).SetZero(); + la::ScaleOverwrite(root_positive_dot_product_range.hi, + rroot_->stat().sum_coordinates_, + &(qnode->stat().ll_vector_u_)); + + la::ScaleOverwrite(root_negative_dot_product_range.lo, + rroot_->stat().sum_coordinates_, + &(qnode->stat().neg_ll_vector_l_)); + (qnode->stat().neg_ll_vector_u_).SetZero(); + + // Set the postponed quantities to zero. + (qnode->stat().postponed_ll_vector_l_).SetZero(); + (qnode->stat().postponed_ll_vector_e_).SetZero(); + (qnode->stat().postponed_ll_vector_u_).SetZero(); + (qnode->stat().postponed_ll_vector_l_).SetZero(); + (qnode->stat().postponed_ll_vector_e_).SetZero(); + (qnode->stat().postponed_ll_vector_u_).SetZero(); + + if(!qnode->is_leaf()) { + + InitializeQueryTreeSumBound_(qnode->left(), + root_negative_dot_product_range, + root_positive_dot_product_range); + InitializeQueryTreeSumBound_(qnode->right(), + root_negative_dot_product_range, + root_positive_dot_product_range); } } template void LocalLinearKrylov::SolveLeastSquaresByKrylov_() { + // Temporary variables to hold dot product ranges for the root nodes + // of the two trees. + DRange root_negative_dot_product_range, root_positive_dot_product_range; + // Initialize the initial solutions to zero vectors. solution_vectors_e_.SetZero(); - // Initialize the query tree bounds. - InitializeQueryTreeSolver_(qroot_); - + // Initialize the query tree solution bounds. + InitializeQueryTreeSolutionBound_(qroot_); + + // Compute the dot product bounds. + DotProductBetweenTwoBounds_(qroot_, rroot_, root_negative_dot_product_range, + root_positive_dot_product_range); + + // Initialize the query tree bound statistics. + InitializeQueryTreeSumBound_(qroot_, root_negative_dot_product_range, + root_positive_dot_product_range); + }