From b467e944cfa081f1fa3a9b2329997550a6fa703e Mon Sep 17 00:00:00 2001 From: = Date: Tue, 28 Jun 2016 20:53:59 -0400 Subject: [PATCH] [TEST] Now includes a test with QPS ranges [FEATURE] Parser Reads but doesn't handle ranges in QPS files. --- gtsam_unstable/linear/QPSParser.cpp | 21 ++++++++++++++++---- gtsam_unstable/linear/RawQP.cpp | 13 ++++++++++++ gtsam_unstable/linear/RawQP.h | 16 ++++++++++++++- gtsam_unstable/linear/tests/testQPSolver.cpp | 12 +++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/gtsam_unstable/linear/QPSParser.cpp b/gtsam_unstable/linear/QPSParser.cpp index 748c4db38..1767cd18f 100644 --- a/gtsam_unstable/linear/QPSParser.cpp +++ b/gtsam_unstable/linear/QPSParser.cpp @@ -43,6 +43,12 @@ struct QPSParser::MPSGrammar: base_grammar { void( bf::vector)> rhsDouble; + boost::function< + void(bf::vector const &)> rangeSingle; + boost::function< + void( + bf::vector)> rangeDouble; boost::function< void(bf::vector)> colSingle; boost::function< @@ -61,7 +67,9 @@ struct QPSParser::MPSGrammar: base_grammar { boost::bind(&RawQP::setName, rqp, ::_1)), addRow( boost::bind(&RawQP::addRow, rqp, ::_1)), rhsSingle( boost::bind(&RawQP::addRHS, rqp, ::_1)), rhsDouble( - boost::bind(&RawQP::addRHSDouble, rqp, ::_1)), colSingle( + boost::bind(&RawQP::addRHSDouble, rqp, ::_1)), rangeSingle( + boost::bind(&RawQP::addRangeSingle, rqp, ::_1)), rangeDouble( + boost::bind(&RawQP::addRangeDouble, rqp, ::_1)), colSingle( boost::bind(&RawQP::addColumn, rqp, ::_1)), colDouble( boost::bind(&RawQP::addColumnDouble, rqp, ::_1)), addQuadTerm( boost::bind(&RawQP::addQuadTerm, rqp, ::_1)), addBound( @@ -78,6 +86,10 @@ struct QPSParser::MPSGrammar: base_grammar { >> *blank][rhsSingle]; rhs_double = lexeme[(*blank >> word >> +blank >> word >> +blank >> double_ >> +blank >> word >> +blank >> double_)[rhsDouble] >> *blank]; + range_single = lexeme[*blank >> word >> +blank >> word >> +blank >> double_ + >> *blank][rangeSingle]; + range_double = lexeme[(*blank >> word >> +blank >> word >> +blank >> double_ + >> +blank >> word >> +blank >> double_)[rangeDouble] >> *blank]; col_single = lexeme[*blank >> word >> +blank >> word >> +blank >> double_ >> *blank][colSingle]; col_double = lexeme[*blank @@ -96,7 +108,8 @@ struct QPSParser::MPSGrammar: base_grammar { >> +((col_double | col_single) >> eol)]; quad = lexeme[lit("QUADOBJ") >> *blank >> eol >> +(quad_l >> eol)]; bounds = lexeme[lit("BOUNDS") >> +space >> +((bound | bound_fr) >> eol)]; - ranges = lexeme[lit("RANGES") >> +space]; + ranges = lexeme[lit("RANGES") >> +space + >> *((range_double | range_single) >> eol)]; end = lexeme[lit("ENDATA") >> *space]; start = lexeme[name >> rows >> cols >> rhs >> -ranges >> bounds >> quad >> end]; @@ -105,8 +118,8 @@ struct QPSParser::MPSGrammar: base_grammar { qi::rule, char()> character; qi::rule, Chars()> word, title; qi::rule > row, end, col_single, - col_double, rhs_single, rhs_double, ranges, bound, bound_fr, bounds, quad, - quad_l, rows, cols, rhs, name, start; + col_double, rhs_single, rhs_double, range_single, range_double, ranges, + bound, bound_fr, bounds, quad, quad_l, rows, cols, rhs, name, start; }; QP QPSParser::Parse() { diff --git a/gtsam_unstable/linear/RawQP.cpp b/gtsam_unstable/linear/RawQP.cpp index d1b41900d..81bcbc5a1 100644 --- a/gtsam_unstable/linear/RawQP.cpp +++ b/gtsam_unstable/linear/RawQP.cpp @@ -77,6 +77,19 @@ void RawQP::addColumnDouble( (*row_to_constraint_v[row2_])[row2_][varname_to_key[var_]] = coefficient2; } +void RawQP::addRangeSingle( + boost::fusion::vector, std::vector, + std::vector, std::vector, std::vector, double, + std::vector> const & vars) { + std::cout << "SINGLE RANGE ADDED" << std::endl; +} +void RawQP::addRangeDouble( + boost::fusion::vector, std::vector, + std::vector, std::vector, std::vector, double, + std::vector, std::vector, std::vector, double> const & vars) { + std::cout << "DOUBLE RANGE ADDED" << std::endl; +} + void RawQP::addRHS( boost::fusion::vector, std::vector, std::vector, std::vector, std::vector, double, diff --git a/gtsam_unstable/linear/RawQP.h b/gtsam_unstable/linear/RawQP.h index aadf11e50..e8cb27dd5 100644 --- a/gtsam_unstable/linear/RawQP.h +++ b/gtsam_unstable/linear/RawQP.h @@ -30,6 +30,10 @@ #include namespace gtsam { +/** + * This class is responsible for collecting a QP problem as the parser parses a QPS file + * and then generating a QP problem. + */ class RawQP { private: typedef std::unordered_map coefficient_v; @@ -56,7 +60,7 @@ public: RawQP() : row_to_constraint_v(), E(), IG(), IL(), varNumber(1), b(), g(), varname_to_key(), H(), f(), obj_name(), name_(), up(), lo(), Free() { } - + void setName( boost::fusion::vector, std::vector, std::vector> const & name); @@ -81,6 +85,16 @@ public: std::vector, std::vector, std::vector, double, std::vector, std::vector, std::vector, double> const & vars); + void addRangeSingle( + boost::fusion::vector, std::vector, + std::vector, std::vector, std::vector, double, + std::vector> const & vars); + + void addRangeDouble( + boost::fusion::vector, std::vector, + std::vector, std::vector, std::vector, double, + std::vector, std::vector, std::vector, double> const & vars); + void addRow( boost::fusion::vector, char, std::vector, std::vector, std::vector> const & vars); diff --git a/gtsam_unstable/linear/tests/testQPSolver.cpp b/gtsam_unstable/linear/tests/testQPSolver.cpp index 0765cae44..47cfff6e2 100644 --- a/gtsam_unstable/linear/tests/testQPSolver.cpp +++ b/gtsam_unstable/linear/tests/testQPSolver.cpp @@ -281,6 +281,18 @@ TEST(QPSolver, HS21) { CHECK(assert_equal(expectedSolution, actualSolution)) } +TEST(QPSolver, HS118) { + QP problem = QPSParser("HS118.QPS").Parse(); + VectorValues actualSolution; + VectorValues expectedSolution; +// expectedSolution.insert(Symbol('X',1), 2.0*I_1x1); +// expectedSolution.insert(Symbol('X',2), 0.0*I_1x1); + boost::tie(actualSolution, boost::tuples::ignore) = QPSolver(problem).optimize(); + double error_actual = problem.cost.error(actualSolution); + CHECK(assert_equal(6.64820452e2,error_actual, 1e-7)) +// CHECK(assert_equal(expectedSolution, actualSolution)) +} + /* ************************************************************************* */ // Create Matlab's test graph as in http://www.mathworks.com/help/optim/ug/quadprog.html QP createTestMatlabQPEx() {