Skip to content

Commit a868d02

Browse files
authored
Merge pull request #272 from fabinsch/fix-is-valid
Check model is_valid up to eps
2 parents b56b920 + f0927b3 commit a868d02

File tree

4 files changed

+38
-9
lines changed

4 files changed

+38
-9
lines changed

include/proxsuite/proxqp/dense/helpers.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,10 @@ estimate_minimal_eigen_value_of_symmetric_matrix(
112112
T power_iteration_accuracy,
113113
isize nb_power_iteration)
114114
{
115-
PROXSUITE_THROW_PRETTY((!H.isApprox(H.transpose(), 0.0)),
116-
std::invalid_argument,
117-
"H is not symmetric.");
115+
PROXSUITE_THROW_PRETTY(
116+
(!H.isApprox(H.transpose(), std::numeric_limits<T>::epsilon())),
117+
std::invalid_argument,
118+
"H is not symmetric.");
118119
if (H.size()) {
119120
PROXSUITE_CHECK_ARGUMENT_SIZE(
120121
H.rows(),

include/proxsuite/proxqp/dense/model.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,12 @@ struct Model
120120
H.rows(), dim, "H has not the expected number of rows.");
121121
PROXSUITE_CHECK_ARGUMENT_SIZE(
122122
H.cols(), dim, "H has not the expected number of cols.");
123-
PROXSUITE_THROW_PRETTY((!H.isApprox(H.transpose(), 0.0)),
124-
std::invalid_argument,
125-
"H is not symmetric.");
123+
PROXSUITE_THROW_PRETTY(
124+
(!H.isApprox(
125+
H.transpose(),
126+
std::numeric_limits<typename decltype(H)::Scalar>::epsilon())),
127+
std::invalid_argument,
128+
"H is not symmetric.");
126129
}
127130
if (A.size()) {
128131
PROXSUITE_CHECK_ARGUMENT_SIZE(

include/proxsuite/proxqp/sparse/helpers.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,10 @@ estimate_minimal_eigen_value_of_symmetric_matrix(SparseMat<T, I>& H,
119119
T power_iteration_accuracy,
120120
isize nb_power_iteration)
121121
{
122-
PROXSUITE_THROW_PRETTY((!H.isApprox(H.transpose(), 0.0)),
123-
std::invalid_argument,
124-
"H is not symmetric.");
122+
PROXSUITE_THROW_PRETTY(
123+
(!H.isApprox(H.transpose(), std::numeric_limits<T>::epsilon())),
124+
std::invalid_argument,
125+
"H is not symmetric.");
125126
PROXSUITE_CHECK_ARGUMENT_SIZE(
126127
H.rows(),
127128
H.cols(),

test/src/dense_qp_wrapper.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7564,3 +7564,27 @@ TEST_CASE(
75647564
minimal_eigenvalue) <= tol);
75657565
}
75667566
}
7567+
7568+
DOCTEST_TEST_CASE("check that model.is_valid function for symmetric matrices "
7569+
"works for epsilon precision")
7570+
{
7571+
Eigen::Matrix<T, 3, 3> matrix = Eigen::Matrix<T, 3, 3>::Random();
7572+
Eigen::Matrix<T, 3, 3> symmetric_mat = matrix + matrix.transpose();
7573+
7574+
symmetric_mat(0, 1) =
7575+
symmetric_mat(1, 0) + std::numeric_limits<double>::epsilon();
7576+
7577+
// compare the two checks for symmetry with and without tolerance
7578+
bool is_symmetric_without_tolerance =
7579+
symmetric_mat.isApprox(symmetric_mat.transpose(), 0.0);
7580+
bool is_symmetric_with_tolerance = symmetric_mat.isApprox(
7581+
symmetric_mat.transpose(),
7582+
std::numeric_limits<typename decltype(symmetric_mat)::Scalar>::epsilon());
7583+
DOCTEST_CHECK(is_symmetric_without_tolerance == false);
7584+
DOCTEST_CHECK(is_symmetric_with_tolerance == true);
7585+
7586+
// initialize a model with a symmetric matrix as Hessian, this runs
7587+
// model.is_valid() that performs the check above
7588+
proxqp::dense::QP<T> qp(3, 0, 0);
7589+
qp.init(symmetric_mat, nullopt, nullopt, nullopt, nullopt, nullopt, nullopt);
7590+
}

0 commit comments

Comments
 (0)