17 CmlQuadraticSolver::CmlQuadraticSolver(
int type)
18 :QuadraticSolver(
"CmlQuadraticSolver"), _solverType(type)
22 case CMLQPSOLVER_LEMKE:
23 _solver = cmlQPSolver::New(cmlQPSolver::LEMKE_SOLVER);
25 case CMLQPSOLVER_GAUSS_SEIDEL:
26 _solver = cmlQPSolver::New(cmlQPSolver::GAUSS_SEIDEL_SOLVER);
29 throw std::runtime_error(
"[CmlQuadraticSolver::CmlQuadraticSolver] Invalid solver type");
33 void CmlQuadraticSolver::setTolerance(
double epsilon)
35 _solver->setTolerance(epsilon);
38 void CmlQuadraticSolver::setMaxIteration(cfl_size_t maxIter)
42 case CMLQPSOLVER_LEMKE:
43 _solver->setNumberOfLemkeLoopsMax(maxIter);
45 case CMLQPSOLVER_GAUSS_SEIDEL:
46 throw std::runtime_error(
"[CmlQuadraticSolver::setMaxIteration] There is no method to set the maximum iteration number with this type of solver");
55 cfl_size_t CmlQuadraticSolver::getMaxIteration(
void)
const 59 case CMLQPSOLVER_LEMKE:
60 return _solver->getNumberOfLemkeLoops();
61 case CMLQPSOLVER_GAUSS_SEIDEL:
62 throw std::runtime_error(
"[CmlQuadraticSolver::getMaxIteration] There is no method to get the maximum iteration number with this type of solver");
67 const std::string& CmlQuadraticSolver::getMoreInfo(
void)
const 74 void CmlQuadraticSolver::addLinearEqualityConstraint(
LinearConstraint* constraint)
76 if (constraint->isInequality())
77 throw std::runtime_error(
"[CmlQuadraticSolver::addLinearEqualityConstraint] added Constraint is not an equality" );
79 _equalityConstraints.push_back(constraint);
80 _m += constraint->getDimension();
81 constraint->attach(*
this);
82 addVariable(constraint->getVariable());
85 void CmlQuadraticSolver::addLinearInequalityConstraint(
LinearConstraint* constraint)
87 if (constraint->isEquality())
88 throw std::runtime_error(
"[CmlQuadraticSolver::addLinearEqualityConstraint] added Constraint is not an inequality" );
90 _inequalityConstraints.push_back(constraint);
91 _p += constraint->getDimension();
92 constraint->attach(*
this);
93 addVariable(constraint->getVariable());
98 std::vector<LinearConstraint*>* v;
99 if (constraint->isEquality())
100 v = &_equalityConstraints;
102 v = &_inequalityConstraints;
104 std::vector<LinearConstraint*>::iterator it = std::find(v->begin(), v->end(), constraint);
107 removeVariable((*it)->getVariable());
109 constraint->completelyDetach(*
this);
110 if (constraint->isEquality())
111 _m -= constraint->getDimension();
113 _p -= constraint->getDimension();
118 void CmlQuadraticSolver::setObjective(QuadraticFunction* obj,
real weight)
121 if (obj->getDimension() != 1)
122 throw std::runtime_error(
"[QLDSolver::setObjective] dimension of objective function is not 1. Multidimensionnal objectives are not handled by this solver");
125 WeightedObjective wo;
128 _objectives.push_back(wo);
131 addVariable(obj->getVariable());
134 void CmlQuadraticSolver::addObjective(QuadraticFunction* obj,
real weight)
136 if (obj->getDimension() != 1)
137 throw std::runtime_error(
"[CmlQuadraticSolver::setObjective] dimension of objective function is not 1. Multidimensionnal objectives are not handled by this solver");
140 if (_objectives.size() == 0)
142 setObjective(obj, weight);
146 addVariable(obj->getVariable());
147 WeightedObjective wo;
150 _objectives.push_back(wo);
156 void CmlQuadraticSolver::removeObjective(QuadraticFunction* obj)
158 std::vector<WeightedObjective>::iterator it;
160 for (it = _objectives.begin(); it != _objectives.end(); ++it)
162 if (it->objective == obj)
166 if (it != _objectives.end())
168 obj->completelyDetach(*
this);
169 _objectives.erase(it);
174 void CmlQuadraticSolver::printValuesAtSolution(
void)
176 _variable->setValue(_result.solution);
177 std::cout <<
"objective(s):" <<std::endl;
178 for (
unsigned int i=0; i<_objectives.size(); ++i)
179 std::cout << _objectives[i].objective->getValues() << std::endl;
180 std::cout <<
"equalities:" <<std::endl;
181 for (
unsigned int i=0; i<_equalityConstraints.size(); ++i)
182 std::cout << _equalityConstraints[i]->getValues() << std::endl;
183 std::cout <<
"inequalities:" <<std::endl;
184 for (
unsigned int i=0; i<_inequalityConstraints.size(); ++i)
185 std::cout << _inequalityConstraints[i]->getValues() << std::endl;
189 bool CmlQuadraticSolver::checkConstraints(
void)
191 _variable->setValue(_result.solution);
193 for (
unsigned int i=0; i<_equalityConstraints.size(); ++i)
195 const Vector& v =_equalityConstraints[i]->getValues();
196 for (cfl_size_t j=0; j<v.getSize(); ++j)
198 if (fabs(v[j]) > 1.e-8)
202 std::cout <<
"equalities : " << std::endl;
205 std::cout <<
"(" << i <<
"," << j <<
"): " << v[j] << std::endl;
210 for (
unsigned int i=0; i<_inequalityConstraints.size(); ++i)
212 const Vector& v =_inequalityConstraints[i]->getValues();
213 for (cfl_size_t j=0; j<v.getSize(); ++j)
219 std::cout <<
"inequalities : " << std::endl;
222 std::cout <<
"(" << i <<
"," << j <<
"): " << v[j] << std::endl;
231 const MatrixBase& CmlQuadraticSolver::getP(
void)
const 236 const MatrixBase& CmlQuadraticSolver::getA(
void)
const 241 const MatrixBase& CmlQuadraticSolver::getC(
void)
const 243 _minus_G.resize(_G.get_nrows(), _G.get_ncols());
244 _minus_G.setToZero();
245 CML_axpy(-1,_G, _minus_G);
249 const VectorBase& CmlQuadraticSolver::getq(
void)
const 251 _minus_k.resize(_k.getSize());
252 _minus_k.copyValuesFrom(_k);
257 const VectorBase& CmlQuadraticSolver::getb(
void)
const 262 const VectorBase& CmlQuadraticSolver::getd(
void)
const 264 _minus_c.resize(_c.getSize());
265 _minus_c.copyValuesFrom(_c);
270 const VectorBase& CmlQuadraticSolver::getu(
void)
const 272 _u.resize(_k.getSize());
277 const VectorBase& CmlQuadraticSolver::getl(
void)
const 279 _l.resize(_k.getSize());
287 const Solver::Result& CmlQuadraticSolver::doSolve(
void)
294 #ifdef OCRA_REAL_IS_DOUBLE 295 cmlDDenseVector& res = _result.solution;
298 cmlDDenseVector& res = &r;
314 int info = _solver->solveQP(_Q, _k, _H, _a, _G, _c, res);
339 _result.inform = info;
344 void CmlQuadraticSolver::doPrepare(
void)
346 updateMatrixDimension();
350 void CmlQuadraticSolver::recomputeVariable(
void)
353 for (
unsigned int i=0; i<_objectives.size(); ++i)
355 addVariable(_objectives[i].objective->getVariable());
357 for (
unsigned int i=0; i<_equalityConstraints.size(); ++i)
359 addVariable(_equalityConstraints[i]->getVariable());
361 for (
unsigned int i=0; i<_inequalityConstraints.size(); ++i)
363 addVariable(_inequalityConstraints[i]->getVariable());
370 void CmlQuadraticSolver::updateMatrixDimension(
void)
389 void CmlQuadraticSolver::updateSize(
void)
395 for (
unsigned int i=0; i<_equalityConstraints.size(); ++i)
396 _m += _equalityConstraints[i]->getDimension();
397 for (
unsigned int i=0; i<_inequalityConstraints.size(); ++i)
398 _p += _inequalityConstraints[i]->getDimension();
404 void CmlQuadraticSolver::updateMatrices(
void)
409 updateEqualityEquations(_workingMapping);
410 updateInequalityEquations(_workingMapping);
411 updateObjectiveEquations(_workingMapping);
498 printEquation(_G, _c,
false, 9);
504 void CmlQuadraticSolver::updateEqualityEquations(std::vector<cfl_size_t>& workingMapping)
510 for (
unsigned int i=0; i<_equalityConstraints.size(); ++i)
512 Constraint<LinearFunction>* cstr = _equalityConstraints[i];
513 cfl_size_t dim = cstr->getDimension();
514 sA.rescope(dim, _n, m, 0);
517 workingMapping.resize(cstr->getVariable().getSize());
518 uncompressMatrix(*_variable, cstr->getVariable(), cstr->getGradients(), sA, workingMapping);
520 sb.copyValuesFrom(cstr->getFunction()->getb());
561 void CmlQuadraticSolver::updateInequalityEquations(std::vector<cfl_size_t>& workingMapping)
567 for (
unsigned int i=0; i<_inequalityConstraints.size(); ++i)
569 Constraint<LinearFunction>* cstr = _inequalityConstraints[i];
570 cfl_size_t dim = cstr->getDimension();
571 sC.rescope(dim, _n, m, 0);
574 workingMapping.resize(cstr->getVariable().getSize());
575 uncompressMatrixWithScaling(*_variable, cstr->getVariable(), cstr->getGradients(), sC, workingMapping, -1);
576 sd.copyValuesFrom(cstr->getFunction()->getb());
579 if (cstr->isSlacked())
582 _variable->getRelativeMappingOf(*cstr->getSlackVariable(), workingMapping);
583 for (cfl_size_t j=0; j<dim; ++j)
584 sC(j, workingMapping[j]) = 1;
592 void CmlQuadraticSolver::updateObjectiveEquations(std::vector<cfl_size_t>& workingMapping)
599 for (
unsigned int i=0; i<_objectives.size(); ++i)
611 Variable& v = _objectives[i].objective->getVariable();
612 workingMapping.resize(v.getSize());
613 addCompressedMatrix(*_variable, v, _objectives[i].objective->getPi(), _Q, workingMapping, _objectives[i].weight);
614 addCompressedVector(_objectives[i].objective->getqi(), _k, workingMapping, _objectives[i].weight);
621 #include "ocra/optim/BaseVariable.h" 622 #include "ocra/optim/CompositeVariable.h" 629 BaseVariable x(
"x", 1, m);
630 BaseVariable y(
"y", 1, m);
631 BaseVariable z(
"z", 1, m);
633 CompositeVariable xy(
"xy", m);
635 CompositeVariable xz(
"xz", m);
637 CompositeVariable yz(
"yz", m);
639 CompositeVariable
X(
"X", m);
640 X.add(x).add(y).add(z);
647 LinearFunction f1(xy, A1, b1);
651 A2(0,0) = 1; A2(0,1) = -1; A2(0,2) = 1;
652 A2(1,0) = 2; A2(1,1) = 1; A2(1,2) = 1;
654 b2[0] = -1; b2[1] = 2;
655 LinearFunction f2(
X, A2, b2);
663 QuadraticFunction o1(x, P1, q1, 0);
666 P2(0,0) = 1; P2(0,1) = 0;
667 P2(1,0) = 0; P2(1,1) = 1;
669 q2[0] = 0; q2[1] = 0;
670 QuadraticFunction o2(yz, P2, q2, 0);
673 CmlQuadraticSolver solver;
674 solver.setObjective(&o1);
675 solver.addObjective(&o2);
676 solver.addLinearEqualityConstraint(&e);
677 solver.addLinearInequalityConstraint(&i);
678 std::cout << solver.solve().solution << std::endl;
684 BaseVariable x(
"x", 1, m);
690 QuadraticFunction o1(x, P1, q1, 0);
698 LinearFunction f(x, A1, b1);
701 CmlQuadraticSolver solver;
702 solver.addObjective(&o1);
703 solver.addLinearInequalityConstraint(&inequality);
void testSolveCmlQPWithNonFeasiblePb(void)
Constraint< LinearFunction > LinearConstraint
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
Declaration file of the CmlQuadraticSolver class.
void testSolveCmlQP(void)