Now phase 2 does relative error
This commit is contained in:
@@ -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 ¤t_lanczos_vectors);
|
||||
void TestKrylovComputation_
|
||||
(const Matrix &approximated, const Matrix ¤t_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 ¤t_lanczos_vectors) {
|
||||
(const Matrix &approximated, const Matrix ¤t_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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user