[FEATURE] SQP Removed
[FEATURE] Test SQP for Infeasible [FEATURE] Test QP for Infeasible [FEATURE] LP Initialize Without Initial Values [FEATURE] QP Initialize Without Initial Values ** TESTS FAIL **release/4.3a0
parent
8926a1da91
commit
f42c4f6a92
|
@ -11,6 +11,7 @@
|
||||||
#include <gtsam_unstable/linear/LPState.h>
|
#include <gtsam_unstable/linear/LPState.h>
|
||||||
#include <gtsam_unstable/linear/LP.h>
|
#include <gtsam_unstable/linear/LP.h>
|
||||||
#include <gtsam_unstable/linear/ActiveSetSolver.h>
|
#include <gtsam_unstable/linear/ActiveSetSolver.h>
|
||||||
|
#include <gtsam_unstable/linear/LinearCost.h>
|
||||||
#include <gtsam/linear/VectorValues.h>
|
#include <gtsam/linear/VectorValues.h>
|
||||||
|
|
||||||
#include <boost/range/adaptor/map.hpp>
|
#include <boost/range/adaptor/map.hpp>
|
||||||
|
@ -113,21 +114,22 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimize without initial values
|
* Optimize without initial values
|
||||||
* TODO: Find a feasible initial solution wrt inequality constraints
|
* TODO: Find a feasible initial solution that doens't involve simplex method
|
||||||
|
* nor Solving another LP
|
||||||
*/
|
*/
|
||||||
// pair<VectorValues, VectorValues> optimize() const {
|
pair<VectorValues, VectorValues> optimize() const {
|
||||||
//
|
|
||||||
// // Initialize workingSet from the feasible initialValues
|
// Initialize workingSet from the feasible initialValues
|
||||||
// InequalityFactorGraph workingSet = identifyActiveConstraints(
|
// InequalityFactorGraph workingSet = identifyActiveConstraints(
|
||||||
// lp_.inequalities, initialValues, duals);
|
// lp_.inequalities, initialValues, duals);
|
||||||
// LPState state(initialValues, duals, workingSet, false, 0);
|
// LPState state(initialValues, duals, workingSet, false, 0);
|
||||||
//
|
|
||||||
// /// main loop of the solver
|
/// main loop of the solver
|
||||||
// while (!state.converged) {
|
// while (!state.converged) {
|
||||||
// state = iterate(state);
|
// state = iterate(state);
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// return make_pair(state.values, state.duals);
|
// return make_pair(state.values, state.duals);
|
||||||
// }
|
}
|
||||||
};
|
};
|
||||||
} // namespace gtsam
|
} // namespace gtsam
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <gtsam/inference/Symbol.h>
|
#include <gtsam/inference/Symbol.h>
|
||||||
#include <gtsam/inference/FactorGraph-inst.h>
|
#include <gtsam/inference/FactorGraph-inst.h>
|
||||||
#include <gtsam_unstable/linear/QPSolver.h>
|
#include <gtsam_unstable/linear/QPSolver.h>
|
||||||
|
#include <gtsam_unstable/linear/LPSolver.h>
|
||||||
#include <gtsam_unstable/linear/InfeasibleInitialValues.h>
|
#include <gtsam_unstable/linear/InfeasibleInitialValues.h>
|
||||||
#include <boost/range/adaptor/map.hpp>
|
#include <boost/range/adaptor/map.hpp>
|
||||||
|
|
||||||
|
@ -177,4 +178,19 @@ pair<VectorValues, VectorValues> QPSolver::optimize(
|
||||||
return make_pair(state.values, state.duals);
|
return make_pair(state.values, state.duals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pair<VectorValues, VectorValues> QPSolver::optimize() const {
|
||||||
|
LP initProblem;
|
||||||
|
|
||||||
|
initProblem.cost = LinearCost(2,ones(1,1)); // min gamma s.t.
|
||||||
|
initProblem.equalities = qp_.equalities; // s.t Ax = b from the original problem
|
||||||
|
//TODO: SLACK Variable needs to be added
|
||||||
|
initProblem.inequalities = qp_.inequalities; // s.t. Ax - gamma <= b Ax from the original problem
|
||||||
|
|
||||||
|
LPSolver solver(initProblem);
|
||||||
|
VectorValues result, duals;
|
||||||
|
boost::tie(result, duals) = solver.optimize();
|
||||||
|
|
||||||
|
return optimize(result);
|
||||||
|
};
|
||||||
|
|
||||||
} /* namespace gtsam */
|
} /* namespace gtsam */
|
||||||
|
|
|
@ -89,6 +89,15 @@ public:
|
||||||
const VectorValues& initialValues, const VectorValues& duals =
|
const VectorValues& initialValues, const VectorValues& duals =
|
||||||
VectorValues(), bool useWarmStart = true) const;
|
VectorValues(), bool useWarmStart = true) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For this version the caller will not have to provide an initial value
|
||||||
|
* Uses the matlab strategy for initialization
|
||||||
|
* See http://www.mathworks.com/help/optim/ug/quadratic-programming-algorithms.html#brrzwpf-22
|
||||||
|
* For details
|
||||||
|
* @return a pair of <primal, dual> solutions
|
||||||
|
*/
|
||||||
|
std::pair<VectorValues, VectorValues> optimize() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gtsam
|
} // namespace gtsam
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/**
|
|
||||||
* @file SQPSolver.h
|
|
||||||
* @brief This class is used to solve a Non-linear Problem
|
|
||||||
* (NP) and finds a local solution using SQP. See
|
|
||||||
* Nocedal Algorithm 18.3 for details.
|
|
||||||
* @author Ivan Dario Jimenez
|
|
||||||
* @date 2/2/16
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <gtsam_unstable/linear/NP.h>
|
|
||||||
#include <gtsam_unstable/linear/ActiveSetSolver.h>
|
|
||||||
#include <gtsam_unstable/linear/SQPState.h>
|
|
||||||
|
|
||||||
class SQPSolver : public ActiveSetSolver {
|
|
||||||
const NP& np_; //!< the nonlinear programming problem
|
|
||||||
public:
|
|
||||||
SQPSolver(const NP& np) : np_(np){}
|
|
||||||
|
|
||||||
NPState iterate(const NPState& state) const;
|
|
||||||
/*
|
|
||||||
* This function will optimize the Non-linear problem given a set of initial values
|
|
||||||
*/
|
|
||||||
pair<Vector, Vector> optimize(const Vector& initialValues) const;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function will attempt to optimize the Non-linear problem without the need
|
|
||||||
* of initial values.
|
|
||||||
*/
|
|
||||||
pair<Vector, Vector> optimize();
|
|
||||||
};
|
|
|
@ -1,30 +0,0 @@
|
||||||
/**
|
|
||||||
* @file SQPState.h
|
|
||||||
* @brief This class is used to store the current state of
|
|
||||||
* an SQPSolver iteration.
|
|
||||||
* @author Ivan Dario Jimenez
|
|
||||||
* @date 2/2/16
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <gtsam/base/Matrix.h>
|
|
||||||
|
|
||||||
namespace gtsam {
|
|
||||||
class SQPState {
|
|
||||||
Vector values;
|
|
||||||
Vector duals;
|
|
||||||
Vector workingSet;
|
|
||||||
|
|
||||||
bool converged;
|
|
||||||
size_t iterations;
|
|
||||||
|
|
||||||
SQPState() :
|
|
||||||
values(), duals(), workingSet(),converged(false), iterations(0) {}
|
|
||||||
|
|
||||||
SQPState(const Vector& initialValues, const Vector& initialDuals,
|
|
||||||
const Vector& initialWorkingSet, const bool _converged,
|
|
||||||
const size_t iterations) :
|
|
||||||
values(initialValues), duals(initialDuals), workingSet(initialWorkingSet),
|
|
||||||
converged(_converged), iterations(iterations) {}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
#include <gtsam/inference/Symbol.h>
|
#include <gtsam/inference/Symbol.h>
|
||||||
#include <gtsam/inference/FactorGraph-inst.h>
|
#include <gtsam/inference/FactorGraph-inst.h>
|
||||||
#include <gtsam_unstable/linear/LinearCost.h>
|
|
||||||
#include <gtsam/linear/VectorValues.h>
|
#include <gtsam/linear/VectorValues.h>
|
||||||
#include <gtsam/linear/GaussianFactorGraph.h>
|
#include <gtsam/linear/GaussianFactorGraph.h>
|
||||||
#include <gtsam_unstable/linear/EqualityFactorGraph.h>
|
#include <gtsam_unstable/linear/EqualityFactorGraph.h>
|
||||||
|
@ -61,6 +60,13 @@ LP simpleLP1() {
|
||||||
return lp;
|
return lp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LP infeasibleLP(){
|
||||||
|
LP lp;
|
||||||
|
|
||||||
|
lp.cost = LinearCost(1, Vector3(-1, -1, -2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
TEST(LPInitSolverMatlab, initialization) {
|
TEST(LPInitSolverMatlab, initialization) {
|
||||||
|
@ -159,6 +165,20 @@ TEST(LPSolver, simpleTest1) {
|
||||||
CHECK(assert_equal(expectedResult, result, 1e-10));
|
CHECK(assert_equal(expectedResult, result, 1e-10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST(LPSolver, testWithoutInitialValues) {
|
||||||
|
LP lp = simpleLP1();
|
||||||
|
|
||||||
|
LPSolver lpSolver(lp);
|
||||||
|
VectorValues result, duals;
|
||||||
|
boost::tie(result, duals) = lpSolver.optimize();
|
||||||
|
|
||||||
|
VectorValues expectedResult;
|
||||||
|
expectedResult.insert(1, Vector2(8./3., 2./3.));
|
||||||
|
CHECK(assert_equal(expectedResult, result, 1e-10));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: More TEST cases:
|
* TODO: More TEST cases:
|
||||||
* - Infeasible
|
* - Infeasible
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
#include <gtsam_unstable/linear/InfeasibleInitialValues.h>
|
#include <gtsam_unstable/linear/InfeasibleInitialValues.h>
|
||||||
|
#include <gtsam_unstable/linear/InfeasibleOrUnboundedProblem.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
@ -29,6 +30,7 @@ using namespace gtsam::symbol_shorthand;
|
||||||
|
|
||||||
const Matrix One = ones(1,1);
|
const Matrix One = ones(1,1);
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
// Create test graph according to Forst10book_pg171Ex5
|
// Create test graph according to Forst10book_pg171Ex5
|
||||||
QP createTestCase() {
|
QP createTestCase() {
|
||||||
|
@ -38,9 +40,11 @@ QP createTestCase() {
|
||||||
// Note the Hessian encodes:
|
// Note the Hessian encodes:
|
||||||
// 0.5*x1'*G11*x1 + x1'*G12*x2 + 0.5*x2'*G22*x2 - x1'*g1 - x2'*g2 + 0.5*f
|
// 0.5*x1'*G11*x1 + x1'*G12*x2 + 0.5*x2'*G22*x2 - x1'*g1 - x2'*g2 + 0.5*f
|
||||||
// Hence, we have G11=2, G12 = -1, g1 = +3, G22 = 2, g2 = 0, f = 10
|
// Hence, we have G11=2, G12 = -1, g1 = +3, G22 = 2, g2 = 0, f = 10
|
||||||
|
//TODO: THIS TEST MIGHT BE WRONG : the last parameter might be 5 instead of 10 because the form of the equation
|
||||||
|
// Should be 0.5x'Gx + gx + f : Nocedal 449
|
||||||
qp.cost.push_back(
|
qp.cost.push_back(
|
||||||
HessianFactor(X(1), X(2), 2.0 * ones(1, 1), -ones(1, 1), 3.0 * ones(1),
|
HessianFactor(X(1), X(2), 2.0 * ones(1, 1), -ones(1, 1), 3.0 * ones(1),
|
||||||
2.0 * ones(1, 1), zero(1), 10.0));
|
2.0 * ones(1, 1), zero(1), 10));
|
||||||
|
|
||||||
// Inequality constraints
|
// Inequality constraints
|
||||||
qp.inequalities.push_back(LinearInequality(X(1), ones(1,1), X(2), ones(1,1), 2, 0)); // x1 + x2 <= 2 --> x1 + x2 -2 <= 0, --> b=2
|
qp.inequalities.push_back(LinearInequality(X(1), ones(1,1), X(2), ones(1,1), 2, 0)); // x1 + x2 <= 2 --> x1 + x2 -2 <= 0, --> b=2
|
||||||
|
@ -246,6 +250,18 @@ TEST(QPSolver, optimizeMatlabEx) {
|
||||||
CHECK(assert_equal(expectedSolution, solution, 1e-7));
|
CHECK(assert_equal(expectedSolution, solution, 1e-7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST(QPSolver, optimizeMatlabExNoinitials) {
|
||||||
|
QP qp = createTestMatlabQPEx();
|
||||||
|
QPSolver solver(qp);
|
||||||
|
VectorValues solution;
|
||||||
|
boost::tie(solution, boost::tuples::ignore) = solver.optimize();
|
||||||
|
VectorValues expectedSolution;
|
||||||
|
expectedSolution.insert(X(1), (Vector(1) << 2.0 / 3.0).finished());
|
||||||
|
expectedSolution.insert(X(2), (Vector(1) << 4.0 / 3.0).finished());
|
||||||
|
CHECK(assert_equal(expectedSolution, solution, 1e-7));
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
// Create test graph as in Nocedal06book, Ex 16.4, pg. 475
|
// Create test graph as in Nocedal06book, Ex 16.4, pg. 475
|
||||||
QP createTestNocedal06bookEx16_4() {
|
QP createTestNocedal06bookEx16_4() {
|
||||||
|
@ -322,6 +338,31 @@ TEST(QPSolver, infeasibleInitial) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST(QPSolver, infeasibleConstraints) {
|
||||||
|
QP qp;
|
||||||
|
|
||||||
|
// Objective functions x1^2 - x1*x2 + x2^2 - 3*x1 + 5
|
||||||
|
// Note the Hessian encodes:
|
||||||
|
// 0.5*x1'*G11*x1 + x1'*G12*x2 + 0.5*x2'*G22*x2 - x1'*g1 - x2'*g2 + 0.5*f
|
||||||
|
// Hence, we have G11=2, G12 = -1, g1 = +3, G22 = 2, g2 = 0, f = 10
|
||||||
|
qp.cost.push_back(
|
||||||
|
HessianFactor(X(1), X(2), 2.0 * ones(1, 1), -ones(1, 1), 3.0 * ones(1),
|
||||||
|
2.0 * ones(1, 1), zero(1), 5));
|
||||||
|
|
||||||
|
qp.inequalities.push_back(LinearInequality(X(1), -1.0 * ones(1,1), X(2), -1.0 * ones(1,1), 32, 0)); // x1 + x2 >= 32
|
||||||
|
qp.inequalities.push_back(LinearInequality(X(1), ones(1,1), 0, 1)); // x1 <= 0
|
||||||
|
qp.inequalities.push_back(LinearInequality(X(2), ones(1,1), 0, 2)); // x2 <= 0
|
||||||
|
qp.inequalities.push_back(LinearInequality(X(1), -ones(1,1), 0, 1)); // -x1 <= 0
|
||||||
|
qp.inequalities.push_back(LinearInequality(X(2), -ones(1,1), 0, 2)); // -x2 <= 0
|
||||||
|
|
||||||
|
QPSolver solver(qp);
|
||||||
|
|
||||||
|
CHECK_EXCEPTION(
|
||||||
|
solver.optimize(),
|
||||||
|
InfeasibleOrUnboundedProblem);
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() {
|
int main() {
|
||||||
TestResult tr;
|
TestResult tr;
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#include <gtsam_unstable/linear/NP.h>
|
|
||||||
#include <gtsam_unstable/linear/SQPSolver.h>
|
|
||||||
#include <gtsam_unstable/linear/SQPState.h>
|
|
||||||
|
|
||||||
|
|
||||||
using namespace gtsam;
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
TestResult tr;
|
|
||||||
return TestRegistry::runAllTests(tr);
|
|
||||||
}
|
|
Loading…
Reference in New Issue