13 #include <Eigen/Sparse>
25 static const double DIAG_CONSTANT = 1e-4;
31 inline void fillQC(
const std::vector<Task *> &
tasks,
int nrVars, Eigen::MatrixXd & Q, Eigen::VectorXd & C)
33 for(std::size_t i = 0; i <
tasks.size(); ++i)
35 const Eigen::MatrixXd & Qi =
tasks[i]->Q();
36 const Eigen::VectorXd & Ci =
tasks[i]->C();
37 std::pair<int, int> b =
tasks[i]->begin();
39 int r =
static_cast<int>(Qi.rows());
40 int c =
static_cast<int>(Qi.cols());
42 Q.block(b.first, b.second, r, c) +=
tasks[i]->weight() * Qi;
43 C.segment(b.first, r) +=
tasks[i]->weight() * Ci;
53 for(
int i = 0; i < nrVars; ++i)
55 if(std::abs(Q(i, i)) < DIAG_CONSTANT) { Q(i, i) += DIAG_CONSTANT; }
78 inline void reduceQC(
const Eigen::MatrixXd & QFull,
79 const Eigen::VectorXd & CFull,
82 const Eigen::SparseMatrix<double> & M)
84 Q.noalias() = M.transpose() * QFull * M;
85 C.noalias() = M.transpose() * CFull;
94 inline int fillEq(
const std::vector<Equality *> & eq,
101 for(std::size_t i = 0; i < eq.size(); ++i)
105 int nrConstr = eq[i]->nrEq();
106 const Eigen::MatrixXd & Ai = eq[i]->AEq();
107 const Eigen::VectorXd & bi = eq[i]->bEq();
109 A.block(nrALines, 0, nrConstr, nrVars) = Ai.block(0, 0, nrConstr, nrVars);
110 AL.segment(nrALines, nrConstr) = bi.head(nrConstr);
111 AU.segment(nrALines, nrConstr) = bi.head(nrConstr);
113 nrALines += nrConstr;
123 inline int fillInEq(
const std::vector<Inequality *> & inEq,
127 Eigen::VectorXd & AL,
128 Eigen::VectorXd & AU)
130 for(std::size_t i = 0; i < inEq.size(); ++i)
134 int nrConstr = inEq[i]->nrInEq();
135 const Eigen::MatrixXd & Ai = inEq[i]->AInEq();
136 const Eigen::VectorXd & bi = inEq[i]->bInEq();
138 A.block(nrALines, 0, nrConstr, nrVars) = Ai.block(0, 0, nrConstr, nrVars);
139 AL.segment(nrALines, nrConstr).fill(-std::numeric_limits<double>::infinity());
140 AU.segment(nrALines, nrConstr) = bi.head(nrConstr);
142 nrALines += nrConstr;
152 inline int fillGenInEq(
const std::vector<GenInequality *> & genInEq,
156 Eigen::VectorXd & AL,
157 Eigen::VectorXd & AU)
159 for(std::size_t i = 0; i < genInEq.size(); ++i)
163 int nrConstr = genInEq[i]->nrGenInEq();
164 const Eigen::MatrixXd & Ai = genInEq[i]->AGenInEq();
165 const Eigen::VectorXd & ALi = genInEq[i]->LowerGenInEq();
166 const Eigen::VectorXd & AUi = genInEq[i]->UpperGenInEq();
168 A.block(nrALines, 0, nrConstr, nrVars) = Ai.block(0, 0, nrConstr, nrVars);
169 AL.segment(nrALines, nrConstr) = ALi.head(nrConstr);
170 AU.segment(nrALines, nrConstr) = AUi.head(nrConstr);
172 nrALines += nrConstr;
184 inline int fillEq(
const std::vector<Equality *> & eq,
int nrVars,
int nrALines, Eigen::MatrixXd & A, Eigen::VectorXd & b)
186 for(std::size_t i = 0; i < eq.size(); ++i)
190 int nrConstr = eq[i]->nrEq();
191 const Eigen::MatrixXd & Ai = eq[i]->AEq();
192 const Eigen::VectorXd & bi = eq[i]->bEq();
194 A.block(nrALines, 0, nrConstr, nrVars) = Ai.block(0, 0, nrConstr, nrVars);
195 b.segment(nrALines, nrConstr) = bi.head(nrConstr);
197 nrALines += nrConstr;
207 inline int fillInEq(
const std::vector<Inequality *> & inEq,
213 for(std::size_t i = 0; i < inEq.size(); ++i)
217 int nrConstr = inEq[i]->nrInEq();
218 const Eigen::MatrixXd & Ai = inEq[i]->AInEq();
219 const Eigen::VectorXd & bi = inEq[i]->bInEq();
221 A.block(nrALines, 0, nrConstr, nrVars) = Ai.block(0, 0, nrConstr, nrVars);
222 b.segment(nrALines, nrConstr) = bi.head(nrConstr);
224 nrALines += nrConstr;
234 inline int fillGenInEq(
const std::vector<GenInequality *> & genInEq,
240 for(std::size_t i = 0; i < genInEq.size(); ++i)
244 int nrConstr = genInEq[i]->nrGenInEq();
245 const Eigen::MatrixXd & Ai = genInEq[i]->AGenInEq();
246 const Eigen::VectorXd & ALi = genInEq[i]->LowerGenInEq();
247 const Eigen::VectorXd & AUi = genInEq[i]->UpperGenInEq();
249 A.block(nrALines, 0, nrConstr, nrVars) = -Ai.block(0, 0, nrConstr, nrVars);
250 b.segment(nrALines, nrConstr) = -ALi.head(nrConstr);
252 nrALines += nrConstr;
254 A.block(nrALines, 0, nrConstr, nrVars) = Ai.block(0, 0, nrConstr, nrVars);
255 b.segment(nrALines, nrConstr) = AUi.head(nrConstr);
257 nrALines += nrConstr;
267 inline void fillBound(
const std::vector<Bound *> & bounds, Eigen::VectorXd & XL, Eigen::VectorXd & XU)
269 for(std::size_t i = 0; i < bounds.size(); ++i)
271 const Eigen::VectorXd & XLi = bounds[i]->Lower();
272 const Eigen::VectorXd & XUi = bounds[i]->Upper();
273 int bv = bounds[i]->beginVar();
275 XL.segment(bv, XLi.size()) = XLi;
276 XU.segment(bv, XUi.size()) = XUi;
297 inline void reduceA(
const Eigen::MatrixXd & AFull, Eigen::MatrixXd & A,
const Eigen::SparseMatrix<double> & M)
299 A.noalias() = AFull * M;
306 Eigen::VectorXd & XL,
307 const Eigen::VectorXd & XUFull,
308 Eigen::VectorXd & XU,
309 const std::vector<int> & fullToReduced,
310 const std::vector<int> & reducedToFull,
311 const std::vector<std::tuple<int, int, double>> & dependencies)
313 for(
size_t i = 0; i < static_cast<size_t>(XL.rows()); ++i)
315 XL(
static_cast<Eigen::DenseIndex
>(i)) = XLFull(reducedToFull[i]);
316 XU(
static_cast<Eigen::DenseIndex
>(i)) = XUFull(reducedToFull[i]);
318 for(
const auto & d : dependencies)
320 const int & primaryFullI = std::get<0>(d);
321 const int & primaryReducedI = fullToReduced[
static_cast<size_t>(primaryFullI)];
322 const int & replicaFullI = std::get<1>(d);
323 const double & alpha = std::get<2>(d);
329 XL(primaryReducedI) = std::max(XL(primaryReducedI), XUFull(replicaFullI) / alpha);
330 XU(primaryReducedI) = std::min(XU(primaryReducedI), XLFull(replicaFullI) / alpha);
334 XL(primaryReducedI) = std::max(XL(primaryReducedI), XLFull(replicaFullI) / alpha);
335 XU(primaryReducedI) = std::min(XU(primaryReducedI), XUFull(replicaFullI) / alpha);
345 Eigen::VectorXd & resultFull,
346 const Eigen::SparseMatrix<double> & multipliers)
348 resultFull.noalias() = multipliers * result;
353 std::ostream &
printConstr(
const Eigen::VectorXd & result, T * constr,
int line, std::ostream & out);
356 inline std::ostream &
printConstr(
const Eigen::VectorXd & result,
Equality * constr,
int line, std::ostream & out)
358 out << constr->
AEq().row(line) * result <<
" = " << constr->
bEq()(line);
363 inline std::ostream &
printConstr(
const Eigen::VectorXd & result,
Inequality * constr,
int line, std::ostream & out)
365 out << constr->
AInEq().row(line) * result <<
" <= " << constr->
bInEq()(line);
379 const Eigen::VectorXd & result,
381 const std::vector<T *> & constr,
389 if(ALine >= start && ALine < end)
391 int line = ALine - start;
392 out << constr_traits<T>::name(e) <<
" violated at line: " << line << std::endl;
393 out << constr_traits<T>::desc(e, mbs, line) << std::endl;