More initialization routines completed

This commit is contained in:
Dongryeol Lee
2008-02-05 19:22:15 +00:00
parent e2f98f309b
commit ed983bbeeb
2 changed files with 165 additions and 43 deletions
@@ -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_();
@@ -5,68 +5,123 @@
#endif
template<typename TKernel>
double LocalLinearKrylov<TKernel>::MaxDotProductBetweenTwoBounds_
(Tree *qnode, Tree *rnode) {
void LocalLinearKrylov<TKernel>::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<typename TKernel>
void LocalLinearKrylov<TKernel>::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<TKernel>::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<typename TKernel>
void LocalLinearKrylov<TKernel>::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<typename TKernel>
void LocalLinearKrylov<TKernel>::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);
}