humoto
kktsolver.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4  @copyright 2014-2017 INRIA. Licensed under the Apache License, Version 2.0.
5  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
6 
7  @brief
8 */
9 
10 #pragma once
11 
12 namespace humoto
13 {
14  /**
15  * @brief A trivial solver for problems with equality constraints.
16  *
17  * @ingroup Solvers
18  * @{
19  * @defgroup kktsolver kktsolver
20  * @}
21  *
22  * @ingroup kktsolver
23  */
24  namespace kktsolver
25  {
26  }
27 }
28 
29 
30 namespace humoto
31 {
32  namespace kktsolver
33  {
34  /**
35  * @brief Parameters of the solver
36  *
37  * @attention @ref humoto::kktsolver::SolverParameters::CONSTRAINT_ELIMINATION_LLT
38  * works only with diagonal Hessians, i.e., the second level must
39  * contain simple objectives only.
40  */
42  {
43  #define HUMOTO_CONFIG_SECTION_ID "SolverParameters"
44  #define HUMOTO_CONFIG_CONSTRUCTOR SolverParameters
45  #define HUMOTO_CONFIG_ENTRIES \
46  HUMOTO_CONFIG_PARENT_CLASS(SolverParametersBase)
47  #include HUMOTO_CONFIG_DEFINE_ACCESSORS
48 
49 
50  public:
51  enum Method
52  {
53  UNDEFINED = 0,
54  LU = 1,
55  QR = 2,
56  CONSTRAINT_ELIMINATION_LLT = 3
57  };
58 
59 
60  public:
63 
64 
65 
66  public:
67  void setDefaults()
68  {
69  solution_method_ = LU;
70  elimination_regularization_factor_ = 1e-08;
71  }
72 
73 
74  /**
75  * @brief Default constructor
76  */
78  {
79  setDefaults();
80  }
81  };
82 
83 
84 
85  /**
86  * @brief QP solver.
87  */
88  class HUMOTO_LOCAL Solver : public humoto::Solver<SolverParameters>
89  {
90  private:
92 
93 
94 
95  private:
96  /// @copydoc humoto::Solver::initialize
97  void initialize( const humoto::OptimizationProblem &hierarchy,
98  const humoto::SolutionStructure &sol_structure)
99  {
100  hierarchy.getQPProblem(qp_problem_, sol_structure);
101  }
102 
103 
104 
105  /// @copydoc humoto::Solver::solveHierarchy
107  const humoto::OptimizationProblem &hierarchy)
108  {
109  switch(parameters_.solution_method_)
110  {
112  if (QPObjective::HESSIAN_DIAGONAL == qp_problem_.getHessianType())
113  {
114  solveWithElimination(solution, hierarchy);
115  }
116  else
117  {
118  HUMOTO_THROW_MSG("This solution method requires diagonal Hessian.");
119  }
120  break;
123  solveDirect(solution, hierarchy);
124  break;
125  default:
126  HUMOTO_THROW_MSG("Unknown solution method.");
127  }
128  }
129 
130 
131  /**
132  * @brief Eliminate constraints and solve (only diagonal Hessians are supported).
133  *
134  * @param[out] solution
135  * @param[in] hierarchy
136  */
138  const humoto::OptimizationProblem &hierarchy)
139  {
140  std::ptrdiff_t num_var = solution.getNumberOfVariables();
141 
142  Eigen::VectorXd inverted_H;
143  inverted_H.resize(num_var);
144  for (EigenIndex i = 0; i < inverted_H.size(); ++i)
145  {
146  inverted_H(i) = 1./(qp_problem_.getHessian()(i,i) + parameters_.elimination_regularization_factor_);
147  }
148 
149  Eigen::VectorXd iH_g = inverted_H.asDiagonal() * qp_problem_.getGradient();
150  Eigen::MatrixXd iH_At = inverted_H.asDiagonal() * qp_problem_.getEqualities().getA().transpose();
151 
152  solution.x_.noalias() = iH_At
153  *
154  // lambda
155  (qp_problem_.getEqualities().getA() * iH_At).llt().solve(
156  qp_problem_.getEqualities().getA()*iH_g + qp_problem_.getEqualities().getB())
157  -
158  iH_g;
159 
160  solution.return_status_ = SolverStatus::OK;
161  }
162 
163 
164  /**
165  * @brief Solve KKT system directly
166  *
167  * @param[out] solution
168  * @param[in] hierarchy
169  */
170  void solveDirect( humoto::Solution &solution,
171  const humoto::OptimizationProblem &hierarchy)
172  {
173  Eigen::MatrixXd kkt_matrix;
174  Eigen::VectorXd kkt_vector;
175 
176  std::ptrdiff_t num_var = solution.getNumberOfVariables();
177  std::ptrdiff_t num_ctr = qp_problem_.getEqualities().getNumberOfConstraints();
178 
179  kkt_matrix.resize(num_var+num_ctr, num_var+num_ctr);
180  kkt_vector.resize(num_var+num_ctr);
181 
182  kkt_matrix << qp_problem_.getHessian(), qp_problem_.getEqualities().getA().transpose(),
183  qp_problem_.getEqualities().getA(), Eigen::MatrixXd::Zero(num_ctr, num_ctr);
184 
185  kkt_vector << -qp_problem_.getGradient(),
186  qp_problem_.getEqualities().getB();
187 
188 
189  Eigen::VectorXd x;
190  switch(parameters_.solution_method_)
191  {
193  x = kkt_matrix.lu().solve(kkt_vector);
194  break;
196  x = kkt_matrix.colPivHouseholderQr().solve(kkt_vector);
197  break;
198  default:
199  HUMOTO_THROW_MSG("Unknown solution method.");
200  }
201 
202  solution.return_status_ = SolverStatus::OK;
203 
204  solution.x_ = x.segment(0, num_var);
205  }
206 
207 
208  public:
209  /**
210  * @brief Default constructor (with default parameters)
211  */
213  {
214  }
215 
216 
217  /**
218  * @brief Destructor
219  */
221  {
222  }
223 
224 
225  /**
226  * @brief Set parameters.
227  *
228  * @param[in] parameters parameters
229  */
230  explicit Solver(const SolverParameters &parameters)
231  {
232  setParameters(parameters);
233  }
234 
235 
236  /**
237  * @brief Log a QP problem
238  *
239  * @param[in,out] logger logger
240  * @param[in] parent parent
241  * @param[in] name name
242  */
244  const LogEntryName &parent = LogEntryName(),
245  const std::string &name = "kktsolver") const
246  {
247  LogEntryName subname = parent; subname.add(name);
248  qp_problem_.log(logger, subname);
249  }
250  };
251  }
252 }
std::size_t getNumberOfVariables() const
Get total number of variables in the solution vector.
Definition: solution.h:109
Base solver class.
Definition: solver.h:64
void initialize(const humoto::OptimizationProblem &hierarchy, const humoto::SolutionStructure &sol_structure)
Initialize solver.
Definition: kktsolver.h:97
Solver()
Default constructor (with default parameters)
Definition: kktsolver.h:212
Eigen::VectorXd & getB()
Get vector b from equalities: &#39;A*x = b&#39; or &#39;x = b&#39;.
#define HUMOTO_LOCAL
Definition: export_import.h:26
Eigen::VectorXd x_
Definition: solution.h:186
#define HUMOTO_GLOBAL_LOGGER_IF_DEFINED
Definition: logger.h:997
humoto::QPProblem_AB qp_problem_
Definition: kktsolver.h:91
Analog of &#39;sol_structure&#39; struct in Octave code. [determine_solution_structure.m].
Definition: solution.h:33
Parameters of the solver.
Definition: kktsolver.h:41
Container of the solution.
Definition: solution.h:176
#define HUMOTO_THROW_MSG(s)
HUMOTO_THROW_MSG throws an error message concatenated with the name of the function (if supported)...
Represents log entry name.
Definition: logger.h:169
EIGEN_DEFAULT_DENSE_INDEX_TYPE EigenIndex
Definition: utility.h:26
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="kktsolver") const
Log a QP problem.
Definition: kktsolver.h:243
const Eigen::VectorXd & getGradient() const
Const accessor.
Definition: qp_problem.h:108
~Solver()
Destructor.
Definition: kktsolver.h:220
SolverStatus::Status return_status_
Definition: solution.h:187
Eigen::MatrixXd & getA()
Get matrix A from general constraints: &#39;A*x = b&#39;, &#39;lb <= A*x <= ub&#39;.
An optimization problem [initialize_stack.m, simulation_loop.m].
Definition: hierarchy.h:20
std::size_t getNumberOfConstraints() const
Returns number of constraints in the task.
Threaded logger: any data sent to this logger is wrapped in a message and pushed to a queue...
Definition: logger.h:555
const humoto::constraints::ContainerAB & getEqualities() const
get container with equalities
Definition: qp_problem.h:394
HessianType getHessianType() const
Hessian type.
Definition: qp_problem.h:157
void setDefaults()
Set members to their default values.
Definition: kktsolver.h:67
Solver(const SolverParameters &parameters)
Set parameters.
Definition: kktsolver.h:230
The root namespace of HuMoTo.
Definition: config.h:12
void solveHierarchy(humoto::Solution &solution, const humoto::OptimizationProblem &hierarchy)
Solve the hierarchy.
Definition: kktsolver.h:106
Parameters of a solver.
Definition: solver.h:17
void solveWithElimination(humoto::Solution &solution, const humoto::OptimizationProblem &hierarchy)
Eliminate constraints and solve (only diagonal Hessians are supported).
Definition: kktsolver.h:137
A QP problem with constraints of a specific type.
Definition: qp_problem.h:464
LogEntryName & add(const char *name)
extends entry name with a subname
Definition: logger.h:232
void solveDirect(humoto::Solution &solution, const humoto::OptimizationProblem &hierarchy)
Solve KKT system directly.
Definition: kktsolver.h:170
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="qp_problem") const
Log a QP problem.
Definition: qp_problem.h:434
SolverParameters()
Default constructor.
Definition: kktsolver.h:77
const Eigen::MatrixXd & getHessian() const
Const accessor.
Definition: qp_problem.h:98
void getQPProblem(QPProblemBase< t_QPConstraints > &qp_problem, const humoto::SolutionStructure &sol_structure, const bool initialize_upper_triangular_part=true) const
Form a QP problem.
Definition: hierarchy.h:329