Now phase 2 does relative error

This commit is contained in:
Dongryeol Lee
2008-02-08 02:02:29 +00:00
parent 7d19797dca
commit f1c1bcd3d6
3 changed files with 72 additions and 12 deletions
@@ -296,6 +296,10 @@ class LocalLinearKrylov {
*/
Vector new_vector_l_;
Vector new_vector_u_;
Vector new_neg_vector_l_;
/** @brief Temporary variables for holding newly refined upper bound
* on the negative components.
*/
@@ -332,7 +336,8 @@ class LocalLinearKrylov {
////////// Private Member Functions //////////
void LocalLinearKrylov<TKernel>::MaximumRelativeErrorInL1Norm_
(const Matrix &exact_vector_e, const Matrix &approximated);
(const Matrix &exact_vector_e, const Matrix &approximated,
const ArrayList<bool> *query_should_exit_the_loop);
/** @brief This function tests the first phase computation (i.e.,
* the computation of B^T W(q) Y vectors for each query
@@ -343,8 +348,9 @@ class LocalLinearKrylov {
/** @brief This function test the second phase computation (i.e.
* the computation of the product of B^T W(q) B and z(q).
*/
void TestKrylovComputation_(const Matrix &approximated,
const Matrix &current_lanczos_vectors);
void TestKrylovComputation_
(const Matrix &approximated, const Matrix &current_lanczos_vectors,
const ArrayList<bool> &query_should_exit_the_loop);
void NormalizeMatrixColumnVectors_(Matrix &m, Vector &lengths) {
@@ -358,6 +364,34 @@ class LocalLinearKrylov {
}
}
/** @brief Computes the minimum L1 norm.
*/
double MinL1Norm_(const Vector &negative_lower_limit,
const Vector &negative_upper_limit,
const Vector &positive_lower_limit,
const Vector &positive_upper_limit) {
double norm = 0;
for(index_t i = 0; i < negative_lower_limit.length(); i++) {
double upper_limit = negative_upper_limit[i] +
positive_upper_limit[i];
double lower_limit = negative_lower_limit[i] +
positive_lower_limit[i];
DEBUG_ASSERT(upper_limit >= lower_limit);
if(lower_limit > 0) {
norm += lower_limit;
}
else if(upper_limit < 0) {
norm += (-upper_limit);
}
}
DEBUG_ASSERT(norm >= 0);
return norm;
}
/** @brief Compute the L1 norm of the given vector.
*
* @param v The vector for which we want to compute the L1 norm.
@@ -696,6 +730,8 @@ class LocalLinearKrylov {
regression_estimates_.Init(qset_.n_cols());
new_vector_l_.Init(row_length_);
new_vector_u_.Init(row_length_);
new_neg_vector_l_.Init(row_length_);
new_neg_vector_u_.Init(row_length_);
vector_l_change_.Init(row_length_);
vector_e_change_.Init(row_length_);
@@ -185,22 +185,30 @@ bool LocalLinearKrylov<TKernel>::PrunableSolver_
qnode->stat().postponed_ll_vector_l_,
&new_vector_l_);
la::AddTo(vector_l_change_, &new_vector_l_);
la::AddOverwrite(qnode->stat().ll_vector_u_,
qnode->stat().postponed_ll_vector_u_,
&new_vector_u_);
la::AddTo(vector_u_change_, &new_vector_u_);
la::AddOverwrite(qnode->stat().neg_ll_vector_l_,
qnode->stat().postponed_neg_ll_vector_l_,
&new_neg_vector_l_);
la::AddTo(neg_vector_l_change_, &new_neg_vector_l_);
la::AddOverwrite(qnode->stat().neg_ll_vector_u_,
qnode->stat().postponed_neg_ll_vector_u_,
&new_neg_vector_u_);
la::AddTo(neg_vector_u_change_, &new_neg_vector_u_);
// Compute the L1 norm of the most refined lower bound.
double l1_norm_vector_l = L1Norm_(new_vector_l_);
double l1_norm_neg_vector_u = L1Norm_(new_neg_vector_u_);
double min_l1_norm = MinL1Norm_(new_neg_vector_l_, new_neg_vector_u_,
new_vector_l_, new_vector_u_);
// Compute the allowed amount of error for pruning the given query
// and reference pair.
double allowed_err =
(relative_error_ * (rnode->stat().l1_norm_sum_coordinates_) *
(l1_norm_vector_l + l1_norm_neg_vector_u)) /
min_l1_norm) /
(rroot_->stat().l1_norm_sum_coordinates_);
used_error = 0.5 * ((positive_dot_product_range.hi *
kernel_value_range.hi -
positive_dot_product_range.lo *
@@ -706,6 +714,9 @@ void LocalLinearKrylov<TKernel>::SolveLeastSquaresByKrylov_() {
// operator the current Lanczos vector).
la::AddOverwrite(vector_e_, neg_vector_e_, &v_tilde_mat);
TestKrylovComputation_(v_tilde_mat, current_lanczos_vectors,
query_should_exit_the_loop);
for(index_t q = 0; q < qset_.n_cols(); q++) {
// If the current query is not in the Krylov loop, skip it.
@@ -6,12 +6,17 @@
template<typename TKernel>
void LocalLinearKrylov<TKernel>::MaximumRelativeErrorInL1Norm_
(const Matrix &exact_vector_e, const Matrix &approximated) {
(const Matrix &exact_vector_e, const Matrix &approximated,
const ArrayList<bool> *query_should_exit_the_loop) {
double max_relative_error = 0;
for(index_t q = 0; q < qset_.n_cols(); q++) {
if((*query_should_exit_the_loop)[q]) {
continue;
}
// get the column vector containing the approximation.
const double *approx_column = approximated.GetColumnPtr(q);
@@ -75,12 +80,14 @@ void LocalLinearKrylov<TKernel>::TestRightHandSideComputation_
} // end of iterating over each query point.
MaximumRelativeErrorInL1Norm_(exact_vector_e, approximated);
MaximumRelativeErrorInL1Norm_(exact_vector_e, approximated,
NULL);
}
template<typename TKernel>
void LocalLinearKrylov<TKernel>::TestKrylovComputation_
(const Matrix &approximated, const Matrix &current_lanczos_vectors) {
(const Matrix &approximated, const Matrix &current_lanczos_vectors,
const ArrayList<bool> &query_should_exit_the_loop) {
Matrix exact_vector_e;
exact_vector_e.Init(approximated.n_rows(), approximated.n_cols());
@@ -88,6 +95,11 @@ void LocalLinearKrylov<TKernel>::TestKrylovComputation_
for(index_t q = 0; q < qset_.n_cols(); q++) {
// If the current query should not be computed, then skip it.
if(query_should_exit_the_loop[q]) {
continue;
}
// get the column vector corresponding to the current query point.
const double *q_col = qset_.GetColumnPtr(q);
@@ -124,8 +136,9 @@ void LocalLinearKrylov<TKernel>::TestKrylovComputation_
} // end of iterating over each vector component.
} // end of iterating over each reference point.
} // end of iterating over each query point.
MaximumRelativeErrorInL1Norm_(exact_vector_e, approximated);
MaximumRelativeErrorInL1Norm_(exact_vector_e, approximated,
&query_should_exit_the_loop);
}