[TEST] Now includes a test with QPS ranges
[FEATURE] Parser Reads but doesn't handle ranges in QPS files.release/4.3a0
parent
ab045edf07
commit
b467e944cf
|
|
@ -43,6 +43,12 @@ struct QPSParser::MPSGrammar: base_grammar {
|
|||
void(
|
||||
bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars, Chars,
|
||||
Chars, double>)> rhsDouble;
|
||||
boost::function<
|
||||
void(bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars> const &)> rangeSingle;
|
||||
boost::function<
|
||||
void(
|
||||
bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars, Chars,
|
||||
Chars, double>)> rangeDouble;
|
||||
boost::function<
|
||||
void(bf::vector<Chars, Chars, Chars, Chars, Chars, double, Chars>)> 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<boost::spirit::basic_istream_iterator<char>, char()> character;
|
||||
qi::rule<boost::spirit::basic_istream_iterator<char>, Chars()> word, title;
|
||||
qi::rule<boost::spirit::basic_istream_iterator<char> > 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() {
|
||||
|
|
|
|||
|
|
@ -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<char>, std::vector<char>,
|
||||
std::vector<char>, std::vector<char>, std::vector<char>, double,
|
||||
std::vector<char>> const & vars) {
|
||||
std::cout << "SINGLE RANGE ADDED" << std::endl;
|
||||
}
|
||||
void RawQP::addRangeDouble(
|
||||
boost::fusion::vector<std::vector<char>, std::vector<char>,
|
||||
std::vector<char>, std::vector<char>, std::vector<char>, double,
|
||||
std::vector<char>, std::vector<char>, std::vector<char>, double> const & vars) {
|
||||
std::cout << "DOUBLE RANGE ADDED" << std::endl;
|
||||
}
|
||||
|
||||
void RawQP::addRHS(
|
||||
boost::fusion::vector<std::vector<char>, std::vector<char>,
|
||||
std::vector<char>, std::vector<char>, std::vector<char>, double,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@
|
|||
#include <boost/fusion/include/vector.hpp>
|
||||
|
||||
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<Key, Matrix11> 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<char>, std::vector<char>,
|
||||
std::vector<char>> const & name);
|
||||
|
|
@ -81,6 +85,16 @@ public:
|
|||
std::vector<char>, std::vector<char>, std::vector<char>, double,
|
||||
std::vector<char>, std::vector<char>, std::vector<char>, double> const & vars);
|
||||
|
||||
void addRangeSingle(
|
||||
boost::fusion::vector<std::vector<char>, std::vector<char>,
|
||||
std::vector<char>, std::vector<char>, std::vector<char>, double,
|
||||
std::vector<char>> const & vars);
|
||||
|
||||
void addRangeDouble(
|
||||
boost::fusion::vector<std::vector<char>, std::vector<char>,
|
||||
std::vector<char>, std::vector<char>, std::vector<char>, double,
|
||||
std::vector<char>, std::vector<char>, std::vector<char>, double> const & vars);
|
||||
|
||||
void addRow(
|
||||
boost::fusion::vector<std::vector<char>, char, std::vector<char>,
|
||||
std::vector<char>, std::vector<char>> const & vars);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue