26 using namespace Eigen;
31 SolverHQpmad::SolverHQpmad(
const std::string&
name)
39 std::cout <<
"[SolverHQpmad." <<
m_name <<
"] " <<
s << std::endl;
43 unsigned int nc =
neq +
nin;
45 const bool resizeVar =
n !=
m_n;
46 const bool resizeEqIn = (resizeVar || nc !=
m_nc);
77 if (problemData.size() > 2) {
79 false,
"Solver not implemented for more than 2 hierarchical levels.");
84 unsigned int nin = 0,
neq = 0;
87 const unsigned int n = cl0[0].second->cols();
88 for (ConstraintLevel::const_iterator
it = cl0.begin();
it != cl0.end();
90 auto constr =
it->second;
91 assert(
n == constr->cols());
92 if (constr->isEquality())
93 neq += constr->rows();
94 else if (constr->isInequality())
95 nin += constr->rows();
96 else if (constr->isBound())
103 m_lb.setConstant(std::numeric_limits<double>::min());
104 m_ub.setConstant(std::numeric_limits<double>::max());
108 for (ConstraintLevel::const_iterator
it = cl0.begin();
it != cl0.end();
110 auto constr =
it->second;
111 if (constr->isEquality()) {
112 m_C.middleRows(i_eq_in, constr->rows()) = constr->matrix();
113 m_cl.segment(i_eq_in, constr->rows()) = constr->vector();
114 m_cu.segment(i_eq_in, constr->rows()) = constr->vector();
115 i_eq_in += constr->rows();
116 }
else if (constr->isInequality()) {
117 m_C.middleRows(i_eq_in, constr->rows()) = constr->matrix();
118 m_cl.segment(i_eq_in, constr->rows()) = constr->lowerBound();
119 m_cu.segment(i_eq_in, constr->rows()) = constr->upperBound();
120 i_eq_in += constr->rows();
121 }
else if (constr->isBound()) {
123 m_lb =
m_lb.cwiseMax(constr->lowerBound());
124 m_ub =
m_ub.cwiseMin(constr->upperBound());
130 if (problemData.size() > 1) {
134 for (ConstraintLevel::const_iterator
it = cl1.begin();
it != cl1.end();
136 const double&
w =
it->first;
137 auto constr =
it->second;
138 if (!constr->isEquality())
140 false,
"Inequalities in the cost function are not implemented yet");
142 m_H.noalias() +=
w * constr->matrix().transpose() * constr->matrix();
143 m_g.noalias() -=
w * (constr->matrix().transpose() * constr->vector());
157 qpmad::Solver::ReturnStatus solve_status;
167 if (solve_status != qpmad::Solver::OK)
176 if (cl0.size() > 0) {
177 for (ConstraintLevel::const_iterator
it = cl0.begin();
it != cl0.end();
179 auto constr =
it->second;
180 if (constr->checkConstraint(
x) ==
false) {
181 if (constr->isEquality()) {
182 sendMsg(
"Equality " + constr->name() +
" violated: " +
183 toString((constr->matrix() *
x - constr->vector()).norm()));
184 }
else if (constr->isInequality()) {
186 "Inequality " + constr->name() +
" violated: " +
188 (constr->matrix() *
x - constr->lowerBound()).minCoeff()) +
191 (constr->upperBound() - constr->matrix() *
x).minCoeff()));
192 }
else if (constr->isBound()) {
193 sendMsg(
"Bound " + constr->name() +
" violated: " +
194 toString((
x - constr->lowerBound()).minCoeff()) +
"\n" +
195 toString((constr->upperBound() -
x).minCoeff()));
208 return std::numeric_limits<double>::infinity();