gtsam
Loading...
Searching...
No Matches
ConstrainedSolverAdapter.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
17
18#pragma once
19
20#include <gtsam/config.h>
21
22#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V43
23
24#include <gtsam/constrained/ActiveSetSolver.h>
25#include <gtsam/constrained/LinearConstraint.h>
26#include <gtsam/constrained/LpProblem.h>
27#include <gtsam/constrained/QpProblem.h>
31
32#include <map>
33#include <stdexcept>
34
35namespace gtsam {
36namespace unstable_solver_adapter {
37
38using KeyDimMap = std::map<Key, size_t>;
39
40/* ************************************************************************* */
41inline void AddOrCheckDim(KeyDimMap* keyDims, Key key, size_t dim) {
42 const auto [it, inserted] = keyDims->emplace(key, dim);
43 if (!inserted && it->second != dim) {
44 throw std::invalid_argument(
45 "ConstrainedSolverAdapter: inconsistent key dimensions.");
46 }
47}
48
49/* ************************************************************************* */
50inline void AddFactorDims(KeyDimMap* keyDims, const GaussianFactor& factor) {
51 for (auto it = factor.begin(); it != factor.end(); ++it) {
52 AddOrCheckDim(keyDims, *it, static_cast<size_t>(factor.getDim(it)));
53 }
54}
55
56/* ************************************************************************* */
57template <typename GRAPH>
58inline void AddGraphDims(KeyDimMap* keyDims, const GRAPH& graph) {
59 for (const auto& factor : graph) {
60 if (factor) {
61 AddFactorDims(keyDims, *factor);
62 }
63 }
64}
65
66/* ************************************************************************* */
67inline KeyDimMap CollectKeyDims(const QP& qp) {
68 KeyDimMap keyDims;
69 AddGraphDims(&keyDims, qp.cost);
70 AddGraphDims(&keyDims, qp.equalities);
71 AddGraphDims(&keyDims, qp.inequalities);
72 return keyDims;
73}
74
75/* ************************************************************************* */
76inline KeyDimMap CollectKeyDims(const LP& lp) {
77 KeyDimMap keyDims;
78 AddFactorDims(&keyDims, lp.cost);
79 AddGraphDims(&keyDims, lp.equalities);
80 AddGraphDims(&keyDims, lp.inequalities);
81 return keyDims;
82}
83
84/* ************************************************************************* */
85inline Values ToValues(const VectorValues& vectorValues) {
86 Values values;
87 for (const auto& [key, vector] : vectorValues) {
88 values.insert(key, vector);
89 }
90 return values;
91}
92
93/* ************************************************************************* */
94inline VectorValues ToVectorValues(const Values& values,
95 const KeyDimMap& keyDims) {
96 VectorValues vectorValues;
97 for (const auto& [key, _] : keyDims) {
98 if (values.exists(key)) {
99 vectorValues.insert(key, values.at<Vector>(key));
100 }
101 }
102 return vectorValues;
103}
104
105/* ************************************************************************* */
106inline QpProblem ToConstrainedProblem(const QP& qp) {
107 QpProblem problem;
108 for (const auto& factor : qp.cost) {
109 if (factor) {
110 problem.addCost(*factor);
111 }
112 }
113 for (const auto& factor : qp.equalities) {
114 if (factor) {
115 problem.addConstraint(
116 LinearConstraint::Equal(static_cast<const JacobianFactor&>(*factor)));
117 }
118 }
119 for (const auto& factor : qp.inequalities) {
120 if (factor) {
121 problem.addConstraint(LinearConstraint::LessEqual(
122 static_cast<const JacobianFactor&>(*factor)));
123 }
124 }
125 return problem;
126}
127
128/* ************************************************************************* */
129inline LpProblem ToConstrainedProblem(const LP& lp) {
130 LpProblem problem;
131 problem.addCost(static_cast<const JacobianFactor&>(lp.cost));
132 for (const auto& factor : lp.equalities) {
133 if (factor) {
134 problem.addConstraint(
135 LinearConstraint::Equal(static_cast<const JacobianFactor&>(*factor)));
136 }
137 }
138 for (const auto& factor : lp.inequalities) {
139 if (factor) {
140 problem.addConstraint(LinearConstraint::LessEqual(
141 static_cast<const JacobianFactor&>(*factor)));
142 }
143 }
144 return problem;
145}
146
147/* ************************************************************************* */
148inline ActiveSetSolver::State WarmStartState(
149 const InequalityFactorGraph& inequalities, const VectorValues& duals) {
150 ActiveSetSolver::State state;
151 state.activeInequalityRows.reserve(inequalities.size());
152 for (const auto& factor : inequalities) {
153 state.activeInequalityRows.push_back(factor &&
154 duals.exists(factor->dualKey()));
155 }
156 return state;
157}
158
159/* ************************************************************************* */
160inline void AddEqualityDuals(VectorValues* duals,
161 const EqualityFactorGraph& equalities,
162 const std::vector<Vector>& multipliers) {
163 for (size_t index = 0;
164 index < equalities.size() && index < multipliers.size(); ++index) {
165 const auto& factor = equalities.at(index);
166 if (factor) {
167 duals->insert_or_assign(factor->dualKey(), multipliers[index]);
168 }
169 }
170}
171
172/* ************************************************************************* */
173inline void AddInequalityDuals(VectorValues* duals,
174 const InequalityFactorGraph& inequalities,
175 const std::vector<Vector>& multipliers,
176 const std::vector<bool>& activeRows) {
177 for (size_t index = 0;
178 index < inequalities.size() && index < multipliers.size() &&
179 index < activeRows.size();
180 ++index) {
181 const auto& factor = inequalities.at(index);
182 if (factor && activeRows[index]) {
183 duals->insert_or_assign(factor->dualKey(), multipliers[index]);
184 }
185 }
186}
187
188/* ************************************************************************* */
189inline VectorValues ToLegacyDuals(const QP& qp,
190 const ActiveSetSolver::State& state) {
191 VectorValues duals;
192 AddEqualityDuals(&duals, qp.equalities, state.equalityMultipliers);
193 AddInequalityDuals(&duals, qp.inequalities, state.inequalityMultipliers,
194 state.activeInequalityRows);
195 return duals;
196}
197
198/* ************************************************************************* */
199inline VectorValues ToLegacyDuals(const LP& lp,
200 const ActiveSetSolver::State& state) {
201 VectorValues duals;
202 AddEqualityDuals(&duals, lp.equalities, state.equalityMultipliers);
203 AddInequalityDuals(&duals, lp.inequalities, state.inequalityMultipliers,
204 state.activeInequalityRows);
205 return duals;
206}
207
208} // namespace unstable_solver_adapter
209} // namespace gtsam
210
211#endif // GTSAM_ALLOW_DEPRECATED_SINCE_V43
A non-templated config holding any types of Manifold-group elements.
Factor graphs of a Quadratic Programming problem.
Struct used to hold a Linear Programming Problem.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
std::map< Key, size_t > KeyDimMap
Map from variable key to dimension.
Definition MultifrontalClique.h:51