diff --git a/fastlib2/contrib/dongryel/regression/local_linear_krylov.h b/fastlib2/contrib/dongryel/regression/local_linear_krylov.h index 293694059d..c9c0ae84ac 100644 --- a/fastlib2/contrib/dongryel/regression/local_linear_krylov.h +++ b/fastlib2/contrib/dongryel/regression/local_linear_krylov.h @@ -191,11 +191,21 @@ class LocalLinearKrylov { * are solving for each query point. (i.e. B^T W(q) Y) */ Matrix right_hand_sides_u_; - - /** @brief The solution vector of (B^T W(q) B)^+ (B^T W(q) Y) for - * each query point. + + /** @brief The coordinatewise lower bound on the solution vector of + * (B^T W(q) B)^+ (B^T W(q) Y) for each query point. */ - Matrix solution_vectors_; + Matrix solution_vectors_l_; + + /** @brief The estimate of the solution vector of (B^T W(q) B)^+ + * (B^T W(q) Y) for each query point. + */ + Matrix solution_vectors_e_; + + /** @brief The coordinatewise upper bound on the solution vector of + * (B^T W(q) B)^+ (B^T W(q) Y) for each query point + */ + Matrix solution_vectors_u_; /** @brief The final regression estimate for each query point. */ @@ -262,6 +272,11 @@ class LocalLinearKrylov { } } + /** @brief Compute the maximum dot product possible for a pair of + * point lying in each of the two given regions. + */ + double MaxDotProductBetweenTwoBounds_(Tree *qnode, Tree *rnode); + /** @brief Initialize the bound statistics relevant to the right * hand side computation. */ @@ -322,9 +337,7 @@ class LocalLinearKrylov { */ void InitializeQueryTreeSolver_(Tree *qnode); - void SolveLeastSquaresByKrylov_() { - - } + void SolveLeastSquaresByKrylov_(); /** @brief Finalize the regression estimate for each query point by * taking the dot-product between [1; q^T] and the final @@ -339,7 +352,7 @@ class LocalLinearKrylov { // solution vector. Vector query_pt, query_pt_solution; qset_.MakeColumnVector(i, &query_pt); - solution_vectors_.MakeColumnVector(i, &query_pt_solution); + solution_vectors_e_.MakeColumnVector(i, &query_pt_solution); // Set the first component of the dot-product. regression_estimates_[i] = query_pt_solution[0]; @@ -379,12 +392,7 @@ class LocalLinearKrylov { void Compute() { - // Zero out computation results. - right_hand_sides_l_.SetZero(); - right_hand_sides_e_.SetZero(); - right_hand_sides_u_.SetZero(); - solution_vectors_.SetZero(); - regression_estimates_.SetZero(); + // Zero out statistics. num_finite_difference_prunes_ = 0; // Set relative error. @@ -462,7 +470,9 @@ class LocalLinearKrylov { right_hand_sides_l_.Init(row_length_, qset_.n_cols()); right_hand_sides_e_.Init(row_length_, qset_.n_cols()); right_hand_sides_u_.Init(row_length_, qset_.n_cols()); - solution_vectors_.Init(row_length_, qset_.n_cols()); + solution_vectors_l_.Init(row_length_, qset_.n_cols()); + solution_vectors_e_.Init(row_length_, qset_.n_cols()); + solution_vectors_u_.Init(row_length_, qset_.n_cols()); regression_estimates_.Init(qset_.n_cols()); new_right_hand_sides_l_.Init(row_length_); right_hand_sides_l_change_.Init(row_length_); diff --git a/fastlib2/contrib/dongryel/regression/local_linear_krylov_setup_impl.h b/fastlib2/contrib/dongryel/regression/local_linear_krylov_setup_impl.h index 9748347760..68a2f8e1d9 100644 --- a/fastlib2/contrib/dongryel/regression/local_linear_krylov_setup_impl.h +++ b/fastlib2/contrib/dongryel/regression/local_linear_krylov_setup_impl.h @@ -16,9 +16,26 @@ void LocalLinearKrylov::InitializeQueryTreeRightHandSides_ (qnode->stat().postponed_ll_vector_e_).SetZero(); (qnode->stat().postponed_ll_vector_u_).SetZero(); - // If the query node is not a leaf node, then traverse to the left - // and the right. - if(!qnode->is_leaf()) { + // If the query node is a leaf, then initialize the corresponding + // bound quantities for each query point. + if(qnode->is_leaf()) { + for(index_t q = qnode->begin(); q < qnode->end(); q++) { + + Vector q_right_hand_sides_l, q_right_hand_sides_e, q_right_hand_sides_u; + + right_hand_sides_l_.MakeColumnVector(q, &q_right_hand_sides_l); + right_hand_sides_e_.MakeColumnVector(q, &q_right_hand_sides_e); + right_hand_sides_u_.MakeColumnVector(q, &q_right_hand_sides_u); + + q_right_hand_sides_l.SetZero(); + q_right_hand_sides_e.SetZero(); + q_right_hand_sides_u.CopyValues + (rroot_->stat().sum_targets_weighted_by_data_); + } + } + + // Otherwise, then traverse to the left and the right. + else { InitializeQueryTreeRightHandSides_(qnode->left()); InitializeQueryTreeRightHandSides_(qnode->right()); } 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 d84afe918f..8a1dac0d68 100644 --- a/fastlib2/contrib/dongryel/regression/local_linear_krylov_solver_impl.h +++ b/fastlib2/contrib/dongryel/regression/local_linear_krylov_solver_impl.h @@ -4,8 +4,66 @@ #error "This file is not a public header file!" #endif +template +double LocalLinearKrylov::MaxDotProductBetweenTwoBounds_ +(Tree *qnode, Tree *rnode) { + + DHrectBound<2> bound_for_solutions = qnode->stat().bound_for_solutions_; + double max_dot_product = bound_for_solutions.get(0).hi; + + 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; +} + 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(); + + // If the query node is a leaf, then exhaustively iterate over and + // form bounding boxes of the current solution. + if(qnode->is_leaf()) { + for(index_t q = qnode->begin(); q < qnode->end(); q++) { + } + } + + // 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()); + + } +} + +template +void LocalLinearKrylov::SolveLeastSquaresByKrylov_() { + + // Initialize the query tree bounds. + InitializeQueryTreeSolver_(qroot_); }