humoto
hierarchy_level.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4  @author Jan Michalczyk
5  @copyright 2014-2017 INRIA. Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7 
8  @brief
9 */
10 
11 #pragma once
12 
13 namespace humoto
14 {
15  /**
16  * @brief This class represents one level of a hierarchy.
17  */
19  {
20  // This class needs access to some non-public methods
21  friend class OptimizationProblem;
22 
23  private:
26 
29 
30 
31  private:
32  /**
33  * @brief Reset variables.
34  */
35  void reset()
36  {
37  number_of_general_constraints_ = 0;
38  number_of_simple_constraints_ = 0;
39 
40  number_of_equality_constraints_ = 0;
41  number_of_twosided_constraints_ = 0;
42  }
43 
44 
45  protected:
46  /**
47  * @brief Form hierarchy.
48  *
49  * @param[in] sol_structure initialized solution structure
50  * @param[in] model model of the system
51  * @param[in] control_problem control problem associated with the model
52  * @param[in] is_active_set_guessing_enabled
53  */
54  void form( const humoto::SolutionStructure & sol_structure,
55  const humoto::Model & model,
56  const humoto::ControlProblem & control_problem,
57  const bool is_active_set_guessing_enabled)
58  {
59  reset();
60 
61  // loop over tasks
62  HUMOTO_ASSERT(tasks_.size() > 0, "No tasks on a hierarchy level.");
63 
64  for ( std::list<TaskInfo>::iterator it = tasks_.begin();
65  it != tasks_.end();
66  ++it)
67  {
68  it->ptr_->preForm(sol_structure.getNumberOfVariables());
69  it->ptr_->form(sol_structure, model, control_problem);
70  if (is_active_set_guessing_enabled)
71  {
72  it->ptr_->guessActiveSet(sol_structure, model, control_problem);
73  }
74  it->ptr_->postForm();
75 
76 
77  std::size_t num_ctr = it->ptr_->getNumberOfConstraints();
78 
79  if (it->ptr_->isEquality())
80  {
81  number_of_equality_constraints_ += num_ctr;
82  }
83 
84  if (it->ptr_->isTwoSidedInequality())
85  {
86  number_of_twosided_constraints_ += num_ctr;
87  }
88 
89  if (it->ptr_->isSimple())
90  {
91  // number_of_general_constraints_ is added since all
92  // simple constraints are added after general constraints
93  it->location_ = Location(number_of_simple_constraints_ + number_of_general_constraints_, num_ctr);
94  number_of_simple_constraints_ += num_ctr;
95  }
96  else
97  {
98  it->location_ = Location(number_of_general_constraints_, num_ctr);
99  number_of_general_constraints_ += num_ctr;
100  }
101  }
102 
103  HUMOTO_ASSERT(getNumberOfConstraints() > 0, "No constraints on a hierarchy level.");
104  }
105 
106 
107 
108  /**
109  * @brief Form active set guess
110  *
111  * @param[out] active_set active set guess
112  */
113  void guessActiveSet(ActiveSetConstraints &active_set) const
114  {
115  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
116  it != tasks_.end();
117  ++it)
118  {
119  it->ptr_->copyActiveSetGuessTo(active_set, it->location_);
120  }
121  }
122 
123 
124  /**
125  * @brief Process actual active set: extract active sets of
126  * individual tasks.
127  *
128  * @param[in] active_set
129  */
131  {
132  for ( std::list<TaskInfo>::iterator it = tasks_.begin();
133  it != tasks_.end();
134  ++it)
135  {
136  it->ptr_->copyActualActiveSetFrom(active_set, it->location_);
137  }
138  }
139 
140 
141 
142  /**
143  * @brief Determine active set based on the solution
144  *
145  * @param[out] active_set active set
146  * @param[in] solution solution
147  */
149  const Solution & solution) const
150  {
151  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
152  it != tasks_.end();
153  ++it)
154  {
155  it->ptr_->determineActiveSet(active_set, it->location_, solution);
156  }
157  }
158 
159 
160 
161  /**
162  * @brief Compute violations based on the solution
163  *
164  * @param[out] violations violations
165  * @param[in] solution solution
166  */
168  const Solution & solution) const
169  {
170  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
171  it != tasks_.end();
172  ++it)
173  {
174  it->ptr_->computeViolations(violations, it->location_, solution);
175  }
176  }
177 
178 
179  /**
180  * @brief Add task to the optimization problem.
181  *
182  * @param[in,out] task_pointer pointer to a task
183  */
184  void pushTask(TaskSharedPointer task_pointer)
185  {
186  if (task_pointer->isSimple())
187  {
188  tasks_.push_back(TaskInfo(task_pointer));
189  }
190  else
191  {
192  tasks_.push_front(TaskInfo(task_pointer));
193  }
194  }
195 
196 
197  public:
198  /**
199  * @brief Information about a task in a hierarchy
200  */
202  {
203  public:
204  /// task pointer
206 
207  /// location of the task constraints on a hierarchy level
209 
210 
211  public:
212  /**
213  * @brief Constructor
214  *
215  * @param[in] ptr pointer
216  * @param[in] offset
217  * @param[in] length
218  */
220  const std::size_t offset = 0,
221  const std::size_t length = 0)
222  : location_(offset, length)
223  {
224  ptr_ = ptr;
225  }
226  };
227 
228 
229  /**
230  * @brief General constraints are added in the beginning, simple --
231  * in the end. It is easier to process tasks this way and
232  * formulation of the Hessian can be slightly faster, if objective
233  * includes general and simple tasks.
234  */
235  std::list<TaskInfo> tasks_;
236 
237 
238 
239  public:
240  /**
241  * @brief Default constructor
242  */
244  {
245  reset();
246  }
247 
248 
249 
250  /**
251  * @brief Get total number of constraints
252  *
253  * @return total number of constraints
254  */
255  std::size_t getNumberOfConstraints() const
256  {
257  return (number_of_general_constraints_
258  +
259  number_of_simple_constraints_);
260  }
261 
262 
263  /**
264  * @brief Get number of simple constraints
265  *
266  * @return number of simple constraints
267  */
268  std::size_t getNumberOfSimpleConstraints() const
269  {
270  return (number_of_simple_constraints_);
271  }
272 
273 
274  /**
275  * @brief Get number of general constraints
276  *
277  * @return number of general constraints
278  */
279  std::size_t getNumberOfGeneralConstraints() const
280  {
281  return (number_of_general_constraints_);
282  }
283 
284 
285  /**
286  * @brief Get number of inequality constraints
287  *
288  * @return number of inequality constraints
289  */
290  std::size_t getNumberOfEqualityConstraints() const
291  {
292  return (number_of_equality_constraints_);
293  }
294 
295 
296  /**
297  * @brief Get number of inequality constraints
298  *
299  * @return number of inequality constraints
300  */
302  {
303  return (getNumberOfConstraints() - getNumberOfEqualityConstraints());
304  }
305 
306 
307  /**
308  * @brief Get number of inequality constraints, two-sided constraints counted twice.
309  *
310  * @return number of inequality constraints
311  */
313  {
314  return (getNumberOfInequalityConstraints() + number_of_twosided_constraints_);
315  }
316 
317 
318  /**
319  * @brief True if all constraints on this level are simple
320  *
321  * @return true/false
322  */
323  bool isSimple() const
324  {
325  return (getNumberOfConstraints() == number_of_simple_constraints_);
326  }
327 
328 
329  /**
330  * @brief True if all constraints on this level are equalitites
331  *
332  * @return true/false
333  */
334  bool isEquality() const
335  {
336  return (getNumberOfConstraints() == number_of_equality_constraints_);
337  }
338 
339 
340  /**
341  * @brief Generates (general) objective containing all equality constraints on this level
342  *
343  * @param[out] eq_constraints equality constraints
344  * @param[in] sol_structure structure of the solution
345  */
347  const humoto::SolutionStructure & sol_structure) const
348  {
349  eq_constraints.reset( getNumberOfEqualityConstraints(),
350  sol_structure.getNumberOfVariables());
351 
352  std::size_t eq_offset = 0;
353 
354  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
355  it != tasks_.end();
356  ++it)
357  {
358  if (it->ptr_->isEquality())
359  {
360  eq_offset = it->ptr_->copyTo(eq_constraints, eq_offset);
361  }
362  }
363  }
364 
365 
366  /**
367  * @brief Generates (general) objective containing all equality constraints on this level
368  *
369  * @param[out] ineq_constraints equality constraints
370  * @param[in] sol_structure structure of the solution
371  */
373  const humoto::SolutionStructure & sol_structure) const
374  {
375  ineq_constraints.reset( getNumberOfInequalityConstraintsOneSided(),
376  sol_structure.getNumberOfVariables());
377 
378  std::size_t offset = 0;
379 
380  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
381  it != tasks_.end();
382  ++it)
383  {
384  if ( ! (it->ptr_->isEquality()) )
385  {
386  offset = it->ptr_->copyTo(ineq_constraints, offset);
387  }
388  }
389  }
390 
391 
392  /**
393  * @brief Generates objective containing all constraints on this level
394  *
395  * @param[in] sol_structure structure of the solution
396  * @param[out] constraints constraints
397  */
399  const humoto::SolutionStructure & sol_structure) const
400  {
401  constraints.reset(getNumberOfConstraints(),
402  sol_structure.getNumberOfVariables());
403 
404  if (getNumberOfConstraints() > 0)
405  {
406  std::size_t offset = 0;
407  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
408  (it != tasks_.end());
409  ++it)
410  {
411  offset = it->ptr_->copyTo(constraints, offset);
412  }
413  }
414  }
415 
416 
417  /**
418  * @brief Generates objective containing all general constraints on this level
419  *
420  * @param[in] sol_structure structure of the solution
421  * @param[out] constraints constraints
422  */
424  const humoto::SolutionStructure & sol_structure) const
425  {
426  constraints.reset(getNumberOfGeneralConstraints(),
427  sol_structure.getNumberOfVariables());
428 
429  if (getNumberOfGeneralConstraints() > 0)
430  {
431  std::size_t offset = 0;
432  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
433  (it != tasks_.end()) && (!it->ptr_->isSimple());
434  ++it)
435  {
436  offset = it->ptr_->copyTo(constraints, offset);
437  }
438  }
439  }
440 
441 
442 
443  /**
444  * @brief Generates objective containing all simple constraints on
445  * this level
446  *
447  * @param[in] sol_structure structure of the solution
448  * @param[out] constraints constraints
449  */
451  const humoto::SolutionStructure & sol_structure) const
452  {
453  constraints.reset( getNumberOfSimpleConstraints(),
454  sol_structure.getNumberOfVariables());
455 
456  if (getNumberOfSimpleConstraints() > 0)
457  {
458  std::size_t offset = 0;
459  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
460  (it != tasks_.end());
461  ++it)
462  {
463  if (it->ptr_->isSimple())
464  {
465  offset = it->ptr_->copyTo(constraints, offset);
466  }
467  }
468  }
469  }
470 
471 
472 
473  /**
474  * @brief Form objective of a QP
475  *
476  * @param[out] H hessian
477  * @param[out] g gradient
478  */
479  void getObjective( Eigen::MatrixXd &H,
480  Eigen::VectorXd &g) const
481  {
482  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
483  it != tasks_.end();
484  ++it)
485  {
486  if (it == tasks_.begin())
487  {
488  it->ptr_->getATAandATb(H, g);
489  }
490  else
491  {
492  it->ptr_->addATAandATb(H, g);
493  }
494  }
495  }
496 
497 
498  /**
499  * @brief Log hierarchy as a set of tasks
500  *
501  * @param[in,out] logger logger
502  * @param[in] parent parent
503  * @param[in] name name
504  */
506  const LogEntryName & parent = LogEntryName(),
507  const std::string & name = "") const
508  {
509  std::size_t i = 0;
510 
511  LogEntryName subname = parent;
512  subname.add(name);
513  for ( std::list<TaskInfo>::const_iterator it = tasks_.begin();
514  it != tasks_.end();
515  ++it, ++i)
516  {
517  LogEntryName subname_loop = subname;
518  subname_loop.add(i);
519  it->location_.log(logger, subname_loop);
520  it->ptr_->log(logger, subname_loop, "");
521  }
522  }
523  };
524 }
Container for simple inequality constraints.
Abstract base class (for control problems)
std::size_t getNumberOfVariables() const
Get total number of variables in the solution vector.
Definition: solution.h:109
Violations corresponding to Constraints class.
Definition: violations.h:17
std::size_t number_of_equality_constraints_
void reset()
Reset variables.
#define HUMOTO_LOCAL
Definition: export_import.h:26
void guessActiveSet(ActiveSetConstraints &active_set) const
Form active set guess.
#define HUMOTO_GLOBAL_LOGGER_IF_DEFINED
Definition: logger.h:997
#define HUMOTO_ASSERT(condition, message)
void getGeneralConstraints(constraints::ContainerALU &constraints, const humoto::SolutionStructure &sol_structure) const
Generates objective containing all general constraints on this level.
Analog of &#39;sol_structure&#39; struct in Octave code. [determine_solution_structure.m].
Definition: solution.h:33
void getObjective(Eigen::MatrixXd &H, Eigen::VectorXd &g) const
Form objective of a QP.
std::size_t getNumberOfSimpleConstraints() const
Get number of simple constraints.
Container of the solution.
Definition: solution.h:176
Active set corresponding to Constraints class.
Definition: active_set.h:43
This class represents one level of a hierarchy.
Represents log entry name.
Definition: logger.h:169
void reset(const std::size_t number_of_constraints=0, const std::size_t number_of_variables=0, const bool initialize_matrices=false)
Initialize constraints.
Location location_
location of the task constraints on a hierarchy level
An optimization problem [initialize_stack.m, simulation_loop.m].
Definition: hierarchy.h:20
std::size_t getNumberOfInequalityConstraintsOneSided() const
Get number of inequality constraints, two-sided constraints counted twice.
std::size_t number_of_simple_constraints_
std::list< TaskInfo > tasks_
General constraints are added in the beginning, simple – in the end. It is easier to process tasks t...
std::size_t getNumberOfEqualityConstraints() const
Get number of inequality constraints.
HierarchyLevel()
Default constructor.
boost::shared_ptr< humoto::TaskBase > TaskSharedPointer
Definition: task.h:584
bool isEquality() const
True if all constraints on this level are equalitites.
Threaded logger: any data sent to this logger is wrapped in a message and pushed to a queue...
Definition: logger.h:555
Information about a task in a hierarchy.
TaskSharedPointer ptr_
task pointer
void processActiveSet(const humoto::ActiveSetConstraints &active_set)
Process actual active set: extract active sets of individual tasks.
void pushTask(TaskSharedPointer task_pointer)
Add task to the optimization problem.
void getEqualityConstraints(constraints::ContainerAB &eq_constraints, const humoto::SolutionStructure &sol_structure) const
Generates (general) objective containing all equality constraints on this level.
void getAllConstraints(constraints::ContainerALU &constraints, const humoto::SolutionStructure &sol_structure) const
Generates objective containing all constraints on this level.
void getSimpleConstraints(constraints::ContainerILU &constraints, const humoto::SolutionStructure &sol_structure) const
Generates objective containing all simple constraints on this level.
Container for general onesided inequality constraints.
The root namespace of HuMoTo.
Definition: config.h:12
void determineActiveSet(ActiveSetConstraints &active_set, const Solution &solution) const
Determine active set based on the solution.
void computeViolations(ViolationsConstraints &violations, const Solution &solution) const
Compute violations based on the solution.
Instances of this class are passed to a virtual method &#39;humoto::TaskBase::form()&#39;, so even though this class is basically useless in its present form we cannot avoid its definition using a template.
Definition: model.h:41
std::size_t getNumberOfConstraints() const
Get total number of constraints.
void form(const humoto::SolutionStructure &sol_structure, const humoto::Model &model, const humoto::ControlProblem &control_problem, const bool is_active_set_guessing_enabled)
Form hierarchy.
std::size_t number_of_general_constraints_
Container for general equality constraints.
bool isSimple() const
True if all constraints on this level are simple.
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="") const
Log hierarchy as a set of tasks.
LogEntryName & add(const char *name)
extends entry name with a subname
Definition: logger.h:232
Location of a data chunk (offset + length).
Definition: utility.h:146
std::size_t number_of_twosided_constraints_
void getInequalityConstraints(constraints::ContainerAL &ineq_constraints, const humoto::SolutionStructure &sol_structure) const
Generates (general) objective containing all equality constraints on this level.
std::size_t getNumberOfInequalityConstraints() const
Get number of inequality constraints.
TaskInfo(TaskSharedPointer ptr, const std::size_t offset=0, const std::size_t length=0)
Constructor.
std::size_t getNumberOfGeneralConstraints() const
Get number of general constraints.
Container for general inequality constraints.