Autoware.Auto
optimization_problem.hpp
Go to the documentation of this file.
1 // Copyright 2019 the Autoware Foundation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Co-developed by Tier IV, Inc. and Apex.AI, Inc.
16 
17 #ifndef OPTIMIZATION__OPTIMIZATION_PROBLEM_HPP_
18 #define OPTIMIZATION__OPTIMIZATION_PROBLEM_HPP_
19 
20 #include <common/types.hpp>
22 #include <optimization/utils.hpp>
24 #include <Eigen/Core>
25 #include <vector>
26 #include <cstddef>
27 #include <memory>
28 #include <tuple>
29 #include <utility>
30 
32 
33 namespace autoware
34 {
35 namespace common
36 {
37 namespace optimization
38 {
45 template<typename Derived, typename DomainValueT, int NumJacobianColsT, int NumVarsT>
46 class OPTIMIZATION_PUBLIC Expression : public common::helper_functions::crtp<Derived>
47 {
48 public:
49  static constexpr auto NumJacobianCols = NumJacobianColsT;
50  static constexpr auto NumVars = NumVarsT;
51  using DomainValue = DomainValueT;
53  using Jacobian = Eigen::Matrix<Value, NumVars, NumJacobianCols>;
54  using Hessian = Eigen::Matrix<Value, NumVars, NumVars>;
55  using JacobianRef = Eigen::Ref<Jacobian>;
56  using HessianRef = Eigen::Ref<Hessian>;
57 
62  {
63  return this->impl().score_(x);
64  }
65 
69  void jacobian(const DomainValue & x, JacobianRef out)
70  {
71  this->impl().jacobian_(x, out);
72  }
73 
77  void hessian(const DomainValue & x, HessianRef out)
78  {
79  this->impl().hessian_(x, out);
80  }
81 
90  void evaluate(const DomainValue & x, const ComputeMode & mode)
91  {
92  (void)x;
93  (void)mode;
94  }
95 };
96 
107 template<typename Derived, typename DomainValueT, int NumJacobianColsT, int NumVarsT,
108  typename ComparatorT>
109 class CachedExpression : public
110  Expression<CachedExpression<Derived, DomainValueT,
111  NumJacobianColsT, NumVarsT, ComparatorT>,
112  DomainValueT, NumJacobianColsT, NumVarsT>
113 {
114 public:
115  static constexpr auto NumJacobianCols = NumJacobianColsT;
116  static constexpr auto NumVars = NumVarsT;
117  using DomainValue = DomainValueT;
119  using Jacobian = Eigen::Matrix<Value, NumVars, NumJacobianCols>;
120  using Hessian = Eigen::Matrix<Value, NumVars, NumVars>;
121  using JacobianRef = Eigen::Ref<Eigen::Matrix<Value, NumVars, NumJacobianCols>>;
122  using HessianRef = Eigen::Ref<Eigen::Matrix<Value, NumVars, NumVars>>;
123 
124  explicit CachedExpression(const ComparatorT & comparator = ComparatorT())
125  : m_score{0.0}, m_jacobian(Jacobian::Zero()), m_hessian{Hessian::Zero()},
126  m_cache_state(comparator) {}
127 
129  {
130  if (!m_cache_state.is_cached(x, common::optimization::ExpressionTerm::SCORE)) {
131  evaluate(x, ComputeMode{}.set_score());
132  }
133  return m_score;
134  }
135 
136  void jacobian_(const DomainValue & x, JacobianRef out)
137  {
138  if (!m_cache_state.is_cached(x, common::optimization::ExpressionTerm::JACOBIAN)) {
139  evaluate(x, ComputeMode{}.set_jacobian());
140  }
141  out = m_jacobian;
142  }
143 
144  void hessian_(const DomainValue & x, HessianRef out)
145  {
146  if (!m_cache_state.is_cached(x, common::optimization::ExpressionTerm::SCORE)) {
147  evaluate(x, ComputeMode{}.set_hessian());
148  }
149  out = m_hessian;
150  }
151 
152  void evaluate(const DomainValue & x, const ComputeMode & mode)
153  {
154  if (!mode.score() && !mode.jacobian() && !mode.hessian()) {
155  return;
156  }
157  m_cache_state.update(x, mode);
158  // Call the implementation method.
159  static_cast<Derived *>(this)->evaluate_(x, mode);
160  }
161 
162 protected:
163  void set_score(Value score)
164  {
165  m_score = score;
166  }
167 
168  void set_jacobian(const JacobianRef & jacobian)
169  {
170  m_jacobian = jacobian;
171  }
172 
173  void set_hessian(const HessianRef & hessian)
174  {
175  m_hessian = hessian;
176  }
177 
178 private:
179  Value m_score;
180  Jacobian m_jacobian;
181  Hessian m_hessian;
183 };
184 
197 template<typename Derived, typename DomainValueT, int NumJacobianColsT, int NumVarsT,
198  typename ObjectiveT, typename EqualityConstraintsT, typename InequalityConstraintsT>
199 class OPTIMIZATION_PUBLIC OptimizationProblem;
200 
201 
202 // Definition of OptimizationProblem.
203 // Template specialization is used for type deduction and forwarding constraint parameter packs
204 // to the tuples. This way "std::tuple" is enforced to be used on the constrained
205 // OptimizationProblem implementations.
206 template<typename Derived,
207  typename ... EqualityConstraints,
208  typename ... InequalityConstraints,
209  typename ObjectiveT, typename DomainValueT, int NumJacobianColsT, int NumVarsT>
210 class OPTIMIZATION_PUBLIC OptimizationProblem<Derived, DomainValueT, NumJacobianColsT, NumVarsT,
211  ObjectiveT,
212  std::tuple<EqualityConstraints...>,
213  std::tuple<InequalityConstraints...>>
214  : public Expression<Derived, DomainValueT, NumJacobianColsT, NumVarsT>
215 {
216 public:
217  using EqualityConstraintsT = std::tuple<EqualityConstraints...>;
218  using InequalityConstraintsT = std::tuple<InequalityConstraints...>;
220  using Jacobian = Eigen::Matrix<Value, NumVarsT, NumJacobianColsT>;
221  using Hessian = Eigen::Matrix<Value, NumVarsT, NumVarsT>;
222  using JacobianRef = Eigen::Ref<Jacobian>;
223  using HessianRef = Eigen::Ref<Hessian>;
224  static constexpr bool8_t is_unconstrained{(std::tuple_size<EqualityConstraintsT>::value == 0U) &&
225  (std::tuple_size<InequalityConstraintsT>::value == 0U)};
226 
228  ObjectiveT && objective,
229  EqualityConstraintsT && eq_constraints,
230  InequalityConstraintsT && ineq_constraints
231  )
232  : m_objective(std::forward<ObjectiveT>(objective)),
233  m_equality_constraints(std::forward<EqualityConstraintsT>(eq_constraints)),
234  m_inequality_constraints(std::forward<InequalityConstraintsT>(ineq_constraints))
235  {
236  }
237 
238  template<typename ... Args, typename Dummy = void, typename = std::enable_if_t<
239  is_unconstrained, Dummy>>
241  Args && ... args
242  )
243  : m_objective(std::forward<Args>(args)...)
244  {
245  }
246 
247  template<bool8_t enabled = is_unconstrained>
248  typename std::enable_if_t<enabled, Value> score_(const DomainValueT & x)
249  {
250  return m_objective(x);
251  }
252 
253  template<bool8_t enabled = is_unconstrained>
254  typename std::enable_if_t<!enabled, Value> score_(const DomainValueT & x)
255  {
256  return opt_impl()->score_opt_(x);
257  }
258 
259  template<bool8_t enabled = is_unconstrained>
260  typename std::enable_if_t<enabled, void> jacobian_(const DomainValueT & x, JacobianRef out)
261  {
262  m_objective.jacobian(x, out);
263  }
264 
265  template<bool8_t enabled = is_unconstrained>
266  typename std::enable_if_t<!enabled, void> jacobian_(const DomainValueT & x, JacobianRef out)
267  {
268  opt_impl()->jacobian_opt_(x, out);
269  }
270 
271  template<bool8_t enabled = is_unconstrained>
272  typename std::enable_if_t<enabled, void> hessian_(const DomainValueT & x, HessianRef out)
273  {
274  m_objective.hessian(x, out);
275  }
276 
277  template<bool8_t enabled = is_unconstrained>
278  typename std::enable_if_t<!enabled, void> hessian_(const DomainValueT & x, HessianRef out)
279  {
280  opt_impl()->hessian_opt_(x, out);
281  }
282 
283  template<bool8_t enabled = is_unconstrained>
284  typename std::enable_if_t<enabled, void> evaluate(
285  const DomainValueT & x,
286  const ComputeMode & mode)
287  {
288  m_objective.evaluate(x, mode);
289  }
290 
291  template<bool8_t enabled = is_unconstrained>
292  typename std::enable_if_t<!enabled, void> evaluate(
293  const DomainValueT & x,
294  const ComputeMode & mode)
295  {
296  opt_impl()->evaluate_(x, mode);
297  }
298 
299 protected:
300  ObjectiveT & objective()
301  {
302  return m_objective;
303  }
304 
305  EqualityConstraintsT & equality_constraints()
306  {
307  return m_equality_constraints;
308  }
309 
311  {
312  return m_inequality_constraints;
313  }
314 
315 private:
316  Derived * opt_impl()
317  {
318  return static_cast<Derived *>(this);
319  }
320 
321  ObjectiveT m_objective;
322  EqualityConstraintsT m_equality_constraints;
323  InequalityConstraintsT m_inequality_constraints;
324 };
325 
331 template<typename ObjectiveT, typename DomainValueT, int NumVarsT>
333  OptimizationProblem<UnconstrainedOptimizationProblem<ObjectiveT, DomainValueT, NumVarsT>,
334  DomainValueT, 1U, NumVarsT, ObjectiveT, std::tuple<>, std::tuple<>>
335 {
336  using OptimizationProblem<UnconstrainedOptimizationProblem<ObjectiveT, DomainValueT, NumVarsT>,
337  DomainValueT, 1U, NumVarsT, ObjectiveT, std::tuple<>, std::tuple<>>::OptimizationProblem;
338 };
339 
340 } // namespace optimization
341 } // namespace common
342 } // namespace autoware
343 
344 #endif // OPTIMIZATION__OPTIMIZATION_PROBLEM_HPP_
Definition: common/optimization/include/optimization/utils.hpp:108
double float64_t
Definition: types.hpp:37
Definition: common/optimization/include/optimization/utils.hpp:38
ComputeMode & set_hessian() noexcept
Definition: utils.cpp:41
void evaluate(const DomainValue &x, const ComputeMode &mode)
Definition: optimization_problem.hpp:90
Definition: optimization_problem.hpp:46
void hessian_(const DomainValue &x, HessianRef out)
Definition: optimization_problem.hpp:144
class OPTIMIZATION_PUBLIC OptimizationProblem
Definition: optimization_problem.hpp:199
void jacobian(const DomainValue &x, JacobianRef out)
Definition: optimization_problem.hpp:69
bool bool8_t
Definition: types.hpp:33
CachedExpression(const ComparatorT &comparator=ComparatorT())
Definition: optimization_problem.hpp:124
void evaluate(const DomainValue &x, const ComputeMode &mode)
Definition: optimization_problem.hpp:152
This file includes common type definition.
bool8_t score() const noexcept
Definition: utils.cpp:47
Value score_(const DomainValue &x)
Definition: optimization_problem.hpp:128
This file includes common helper functions.
DifferentialState x
Definition: kinematic_bicycle.snippet.hpp:28
Definition: optimization_problem.hpp:109
ComputeMode & set_jacobian() noexcept
Definition: utils.cpp:36
void set_hessian(const HessianRef &hessian)
Definition: optimization_problem.hpp:173
bool8_t jacobian() const noexcept
Definition: utils.cpp:48
void set_score(Value score)
Definition: optimization_problem.hpp:163
OptimizationProblem(ObjectiveT &&objective, EqualityConstraintsT &&eq_constraints, InequalityConstraintsT &&ineq_constraints)
Definition: optimization_problem.hpp:227
bool8_t hessian() const noexcept
Definition: utils.cpp:49
void jacobian_(const DomainValue &x, JacobianRef out)
Definition: optimization_problem.hpp:136
ComputeMode & set_score() noexcept
Definition: utils.cpp:31
Value operator()(const DomainValue &x)
Definition: optimization_problem.hpp:61
void set_jacobian(const JacobianRef &jacobian)
Definition: optimization_problem.hpp:168
void hessian(const DomainValue &x, HessianRef out)
Definition: optimization_problem.hpp:77
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24