More initialization routines completed
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user