Skip to content

Non-negative step lengths expected (code and numbers attached) #12

@TJBetter

Description

@TJBetter

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 <<<

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions