-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Hello,
First of all, thank you so much for making this amazing header-only library (without complicated dependencies!). I have enjoyed it a lot and learned many things from you.
Lately, I have been trying to benchmark my algorithm and seem to find a corner case. I have attached the following code, debugging print, and numbers for your reference.
It seems like he tiny negative dual_step_length: dual_step_length = -dual_i / dual_step_direction_i is expected ≥ 0. A value like -1.28e-22 is effectively numerical zero with a sign blip (round-off).
I wonder if you could kindly take a look and confirm a root cause? I would really appreciate your help.
Thank you.
I added the following debug under implementation.h before qpmad_utils_assert :
if (!((step_length >= 0.0) && (dual_step_length >= 0.0)))
{
std::cerr << "QPMAD DEBUG >>> Negative step length condition detected before assert" << std::endl;
std::cerr << " step_length = " << step_length << std::endl;
std::cerr << " dual_step_length = " << dual_step_length << std::endl;
std::cerr << " chosen_ctr_.violation_ = " << chosen_ctr_.violation_ << std::endl;
std::cerr << " chosen_ctr_dot_primal_step_direction = " << chosen_ctr_dot_primal_step_direction << std::endl;
std::cerr << " active_set size = " << active_set_.size_ << " (eq: " << active_set_.num_equalities_ << ", ineq: " << active_set_.num_inequalities_ << ")" << std::endl;
std::cerr << " primal (x): " << primal.transpose() << std::endl;
std::cerr << " Hessian (H):\n" << H << std::endl;
std::cerr << " gradient (h / g): " << h.transpose() << std::endl;
std::cerr << " lower bounds (lb): " << lb.transpose() << std::endl;
std::cerr << " upper bounds (ub): " << ub.transpose() << std::endl;
std::cerr << " Alb: " << Alb.transpose() << std::endl;
std::cerr << " Aub: " << Aub.transpose() << std::endl;
std::cerr << " dual (active) : "
<< dual_.segment(active_set_.num_equalities_, active_set_.num_inequalities_).transpose() << std::endl;
std::cerr << " dual_step_direction(active): "
<< dual_step_direction_.segment(active_set_.num_equalities_, active_set_.num_inequalities_).transpose() << std::endl;
std::cerr << "QPMAD DEBUG <<<" << std::endl;
}
QPMAD_UTILS_ASSERT(
(step_length >= 0.0) && (dual_step_length >= 0.0),
"Non-negative step lengths expected.");
Numbers look like this:
QPMAD DEBUG >>> Negative step length condition detected before assert
step_length = 3.35488e-05
dual_step_length = -1.28019e-22
chosen_ctr_.violation_ = -0.000328939
chosen_ctr_dot_primal_step_direction = 9.80479
active_set size = 2 (eq: 0, ineq: 2)
primal (x): 0.00019995 0.000202092 -7.02563e-05 -0.000628889 0.000249061 0.000382164
Hessian (H):
1.00184 -0.393342 -0.00349583 0.902814 0.429755 0.86361
-0.392617 0.927425 0.00487066 -0.172921 -0.586867 0.0854407
-0.00348939 0.00377461 1.00049 2.1684e-19 -0.00791189 0
0.901151 0.195042 0.00240709 0.388512 1.01644e-20 0.948668
0.428964 -0.451194 -0.00470969 -0.768439 0.151534 -4.44089e-16
0.86202 0.457056 0.00128209 0.212887 0.000276681 0.0608161
gradient (h / g): 9.25123e-06 -0.000125174 7.20117e-05 0.000121439 -0.000217211 2.41149e-05
lower bounds (lb): -0.004 -0.004 -0.0003 -0.00029995 -0.0045 -0.0045
upper bounds (ub): 0.00019995 0.00019995 0.0005 0.006 0.00029995 0.00012495
Alb:
Aub:
dual (active) : -1.05879e-22 3.95437e-06
dual_step_direction(active): -0.82706 2.48939
QPMAD DEBUG <<<