24 #define Template template <class PROBLEM, class POLICY, class INITSOLVER> 25 #define This ActiveSetSolver<PROBLEM, POLICY, INITSOLVER> 46 Template boost::tuple<double, int> This::computeStepSize(
47 const InequalityFactorGraph& workingSet,
const VectorValues& xk,
48 const VectorValues& p,
const double& maxAlpha)
const {
49 double minAlpha = maxAlpha;
50 int closestFactorIx = -1;
51 for (
size_t factorIx = 0; factorIx < workingSet.size(); ++factorIx) {
53 double b = factor->getb()[0];
55 if (!factor->active()) {
57 double aTp = factor->dotProductRow(p);
64 double aTx = factor->dotProductRow(xk);
67 double alpha = (b - aTx) / aTp;
69 if (alpha < minAlpha) {
70 closestFactorIx = factorIx;
75 return boost::make_tuple(minAlpha, closestFactorIx);
113 Template
int This::identifyLeavingConstraint(
114 const InequalityFactorGraph& workingSet,
115 const VectorValues& lambdas)
const {
116 int worstFactorIx = -1;
119 double maxLambda = 0.0;
120 for (
size_t factorIx = 0; factorIx < workingSet.size(); ++factorIx) {
122 if (factor->active()) {
123 double lambda = lambdas.at(factor->dualKey())[0];
124 if (lambda > maxLambda) {
125 worstFactorIx = factorIx;
130 return worstFactorIx;
135 Key key,
const InequalityFactorGraph& workingSet,
136 const VectorValues& delta)
const {
139 TermsContainer Aterms = collectDualJacobians<LinearEquality>(
140 key, problem_.equalities, equalityVariableIndex_);
141 TermsContainer AtermsInequalities = collectDualJacobians<LinearInequality>(
142 key, workingSet, inequalityVariableIndex_);
143 Aterms.insert(Aterms.end(), AtermsInequalities.begin(),
144 AtermsInequalities.end());
147 if (Aterms.size() > 0) {
148 Vector b = problem_.costGradient(key, delta);
150 return boost::make_shared<JacobianFactor>(Aterms, b);
152 return boost::make_shared<JacobianFactor>();
169 const InequalityFactorGraph& workingSet,
const VectorValues& delta)
const {
171 for (
Key key : constrainedKeys_) {
174 createDualFactor(key, workingSet, delta);
175 if (!dualFactor->empty()) dualGraph->push_back(dualFactor);
181 Template GaussianFactorGraph
182 This::buildWorkingGraph(
const InequalityFactorGraph& workingSet,
183 const VectorValues& xk)
const {
184 GaussianFactorGraph workingGraph;
185 workingGraph.push_back(POLICY::buildCostFunction(problem_, xk));
186 workingGraph.push_back(problem_.equalities);
188 if (factor->active()) workingGraph.push_back(factor);
193 Template
typename This::State This::iterate(
194 const typename This::State& state)
const {
198 GaussianFactorGraph workingGraph =
199 buildWorkingGraph(state.workingSet, state.values);
200 VectorValues newValues = workingGraph.optimize();
204 if (newValues.equals(state.values, 1e-7)) {
208 VectorValues duals = dualGraph->optimize();
209 int leavingFactor = identifyLeavingConstraint(state.workingSet, duals);
211 if (leavingFactor < 0) {
212 return State(newValues, duals, state.workingSet,
true,
213 state.iterations + 1);
216 InequalityFactorGraph newWorkingSet = state.workingSet;
217 newWorkingSet.at(leavingFactor)->inactivate();
218 return State(newValues, duals, newWorkingSet,
false,
219 state.iterations + 1);
226 VectorValues p = newValues - state.values;
227 boost::tie(alpha, factorIx) =
228 computeStepSize(state.workingSet, state.values, p, POLICY::maxAlpha);
230 InequalityFactorGraph newWorkingSet = state.workingSet;
232 newWorkingSet.at(factorIx)->activate();
234 newValues = state.values + alpha * p;
235 return State(newValues, state.duals, newWorkingSet,
false,
236 state.iterations + 1);
241 Template InequalityFactorGraph This::identifyActiveConstraints(
242 const InequalityFactorGraph& inequalities,
243 const VectorValues& initialValues,
const VectorValues& duals,
244 bool useWarmStart)
const {
245 InequalityFactorGraph workingSet;
248 if (useWarmStart && duals.size() > 0) {
249 if (duals.exists(workingFactor->dualKey())) workingFactor->activate();
250 else workingFactor->inactivate();
252 double error = workingFactor->error(initialValues);
254 if (error > 0)
throw InfeasibleInitialValues();
255 if (fabs(error) < 1e-7)
256 workingFactor->activate();
258 workingFactor->inactivate();
260 workingSet.push_back(workingFactor);
266 Template std::pair<VectorValues, VectorValues> This::optimize(
267 const VectorValues& initialValues,
const VectorValues& duals,
268 bool useWarmStart)
const {
270 InequalityFactorGraph workingSet = identifyActiveConstraints(
271 problem_.inequalities, initialValues, duals, useWarmStart);
272 State state(initialValues, duals, workingSet,
false, 0);
275 while (!state.converged) state = iterate(state);
277 return std::make_pair(state.values, state.duals);
281 Template std::pair<VectorValues, VectorValues> This::optimize()
const {
282 INITSOLVER initSolver(problem_);
283 VectorValues initValues = initSolver.solve();
Point3 optimize(const NonlinearFactorGraph &graph, const Values &values, Key landmarkKey)
Optimize for triangulation.
Definition: triangulation.cpp:73
boost::shared_ptr< This > shared_ptr
shared_ptr to this class
Definition: JacobianFactor.h:93
boost::shared_ptr< This > shared_ptr
shared_ptr to this class
Definition: GaussianFactorGraph.h:74
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:57
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
boost::shared_ptr< This > shared_ptr
shared_ptr to this class
Definition: LinearInequality.h:37
Exception thrown when given Infeasible Initial Values.