2016-03-07 23:29:43 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <gtsam_unstable/linear/QP.h>
|
|
|
|
#include <gtsam/base/Matrix.h>
|
|
|
|
#include <gtsam/inference/Key.h>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <utility>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <gtsam/inference/Symbol.h>
|
2016-03-08 23:34:31 +08:00
|
|
|
#include <boost/any.hpp>
|
|
|
|
#include <boost/fusion/sequence.hpp>
|
2016-03-07 23:29:43 +08:00
|
|
|
|
|
|
|
namespace gtsam {
|
|
|
|
class RawQP {
|
|
|
|
typedef std::vector<std::pair<Key, Matrix> > coefficient_v;
|
|
|
|
|
|
|
|
std::vector<std::pair<Key, Matrix> > g;
|
2016-03-08 23:34:31 +08:00
|
|
|
std::unordered_map<std::string, std::unordered_map<std::string, coefficient_v> > row_to_map;
|
2016-03-07 23:29:43 +08:00
|
|
|
std::unordered_map<std::string, Key> varname_to_key;
|
2016-03-08 23:34:31 +08:00
|
|
|
std::unordered_map<std::string, coefficient_v> IL;
|
|
|
|
std::unordered_map<std::string, coefficient_v> IG;
|
|
|
|
std::unordered_map<std::string, coefficient_v> E;
|
2016-03-07 23:29:43 +08:00
|
|
|
std::unordered_map<std::string, double> b;
|
|
|
|
std::unordered_map<std::string, std::unordered_map<std::string, double> > H;
|
|
|
|
unsigned int varNumber;
|
|
|
|
double f;
|
|
|
|
std::string obj_name;
|
|
|
|
std::string name_;
|
|
|
|
const bool debug = true;
|
|
|
|
public:
|
2016-03-08 23:34:31 +08:00
|
|
|
RawQP() :
|
|
|
|
g(), row_to_map(), varname_to_key(), IL(), IG(), E(), b(), H(), varNumber(
|
|
|
|
1) {
|
2016-03-07 23:29:43 +08:00
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
void setName(
|
|
|
|
boost::fusion::vector<std::vector<char>, std::vector<char>,
|
|
|
|
std::vector<char>> const & name) {
|
|
|
|
|
|
|
|
name_ = std::string(boost::fusion::at_c < 1 > (name).begin(),
|
|
|
|
boost::fusion::at_c < 1 > (name).end());
|
2016-03-07 23:29:43 +08:00
|
|
|
if (debug) {
|
|
|
|
std::cout << "Parsing file: " << name_ << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
// void addColumn(std::vector<char> var, std::vector<char> row,
|
|
|
|
// double coefficient) {
|
|
|
|
void addColumn(
|
|
|
|
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::string var_(boost::fusion::at_c < 1 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 1 > (vars).end()), row_(
|
|
|
|
boost::fusion::at_c < 3 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 3 > (vars).end());
|
|
|
|
double coefficient = boost::fusion::at_c < 5 > (vars);
|
|
|
|
if (!varname_to_key.count(var_))
|
|
|
|
varname_to_key.insert( { var_, Symbol('X', varNumber++) });
|
|
|
|
|
|
|
|
if (row_ == obj_name) {
|
|
|
|
g.push_back(
|
|
|
|
std::make_pair(varname_to_key[var_], coefficient * ones(1, 1)));
|
2016-03-07 23:29:43 +08:00
|
|
|
return;
|
|
|
|
}
|
2016-03-08 23:34:31 +08:00
|
|
|
row_to_map[row_][row_].push_back(
|
|
|
|
{ varname_to_key[var_], coefficient * ones(1, 1) });
|
2016-03-07 23:29:43 +08:00
|
|
|
|
|
|
|
if (debug) {
|
|
|
|
std::cout << "Added Column for Var: " << var_ << " Row: " << row_
|
|
|
|
<< " Coefficient: " << coefficient << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
// void addColumn(std::vector<char> var, std::vector<char> row1,
|
|
|
|
// double coefficient1, std::vector<char> row2, double coefficient2) {
|
|
|
|
void addColumnDouble(
|
|
|
|
boost::fusion::vector<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::string var_(boost::fusion::at_c < 0 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 0 > (vars).end()), row1_(
|
|
|
|
boost::fusion::at_c < 2 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 2 > (vars).end()), row2_(
|
|
|
|
boost::fusion::at_c < 6 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 6 > (vars).end());
|
|
|
|
double coefficient1 = boost::fusion::at_c < 4 > (vars);
|
|
|
|
double coefficient2 = boost::fusion::at_c < 8 > (vars);
|
|
|
|
if (!varname_to_key.count(var_))
|
|
|
|
varname_to_key.insert( { var_, Symbol('X', varNumber++) });
|
|
|
|
|
|
|
|
if (row1_ == obj_name)
|
|
|
|
row_to_map[row1_][row2_].push_back(
|
|
|
|
{ varname_to_key[var_], coefficient1 * ones(1, 1) });
|
2016-03-07 23:29:43 +08:00
|
|
|
else
|
2016-03-08 23:34:31 +08:00
|
|
|
row_to_map[row1_][row1_].push_back(
|
|
|
|
{ varname_to_key[var_], coefficient1 * ones(1, 1) });
|
2016-03-07 23:29:43 +08:00
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
if (row2_ == obj_name)
|
|
|
|
row_to_map[row2_][row2_].push_back(
|
|
|
|
{ varname_to_key[var_], coefficient2 * ones(1, 1) });
|
2016-03-07 23:29:43 +08:00
|
|
|
else
|
2016-03-08 23:34:31 +08:00
|
|
|
row_to_map[row2_][row2_].push_back(
|
|
|
|
{ varname_to_key[var_], coefficient2 * ones(1, 1) });
|
2016-03-07 23:29:43 +08:00
|
|
|
|
|
|
|
if (debug) {
|
|
|
|
std::cout << "Added Column for Var: " << var_ << " Row: " << row1_
|
|
|
|
<< " Coefficient: " << coefficient1 << std::endl;
|
|
|
|
std::cout << " " << "Row: " << row2_
|
|
|
|
<< " Coefficient: " << coefficient2 << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
void addRHS(
|
|
|
|
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::string var_(boost::fusion::at_c < 1 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 1 > (vars).end()), row_(
|
|
|
|
boost::fusion::at_c < 3 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 3 > (vars).end());
|
|
|
|
double coefficient = boost::fusion::at_c < 5 > (vars);
|
|
|
|
if (row_ == obj_name)
|
2016-03-07 23:29:43 +08:00
|
|
|
f = -coefficient;
|
|
|
|
else
|
2016-03-08 23:34:31 +08:00
|
|
|
b.insert( { row_, coefficient });
|
2016-03-07 23:29:43 +08:00
|
|
|
|
|
|
|
if (debug) {
|
|
|
|
std::cout << "Added RHS for Var: " << var_ << " Row: " << row_
|
|
|
|
<< " Coefficient: " << coefficient << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
// void addRHS(std::vector<char> var, std::vector<char> row1,
|
|
|
|
// double coefficient1, std::vector<char> row2, double coefficient2) {
|
|
|
|
void addRHSDouble(
|
|
|
|
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::string var_(boost::fusion::at_c < 1 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 1 > (vars).end()), row1_(
|
|
|
|
boost::fusion::at_c < 3 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 3 > (vars).end()), row2_(
|
|
|
|
boost::fusion::at_c < 7 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 7 > (vars).end());
|
|
|
|
double coefficient1 = boost::fusion::at_c < 5 > (vars);
|
|
|
|
double coefficient2 = boost::fusion::at_c < 9 > (vars);
|
|
|
|
if (row1_ == obj_name)
|
2016-03-07 23:29:43 +08:00
|
|
|
f = -coefficient1;
|
|
|
|
else
|
2016-03-08 23:34:31 +08:00
|
|
|
b.insert( { row1_, coefficient1 });
|
2016-03-07 23:29:43 +08:00
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
if (row2_ == obj_name)
|
2016-03-07 23:29:43 +08:00
|
|
|
f = -coefficient2;
|
|
|
|
else
|
2016-03-08 23:34:31 +08:00
|
|
|
b.insert( { row2_, coefficient2 });
|
2016-03-07 23:29:43 +08:00
|
|
|
|
|
|
|
if (debug) {
|
|
|
|
std::cout << "Added RHS for Var: " << var_ << " Row: " << row1_
|
|
|
|
<< " Coefficient: " << coefficient1 << std::endl;
|
|
|
|
std::cout << " " << "Row: " << row2_
|
|
|
|
<< " Coefficient: " << coefficient2 << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
void addRow(
|
|
|
|
boost::fusion::vector<std::vector<char>, char, std::vector<char>,
|
|
|
|
std::vector<char>, std::vector<char>> const & vars) {
|
|
|
|
std::string name_(boost::fusion::at_c < 3 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 3 > (vars).end());
|
|
|
|
char type = boost::fusion::at_c < 1 > (vars);
|
|
|
|
switch (type) {
|
|
|
|
case 'N':
|
|
|
|
obj_name = name_;
|
|
|
|
break;
|
|
|
|
case 'L':
|
|
|
|
row_to_map.insert( { name_, IL });
|
|
|
|
IL.insert( { name_, coefficient_v() });
|
|
|
|
break;
|
|
|
|
case 'G':
|
|
|
|
row_to_map.insert( { name_, IG });
|
|
|
|
IG.insert( { name_, coefficient_v() });
|
|
|
|
break;
|
|
|
|
case 'E':
|
|
|
|
row_to_map.insert( { name_, E });
|
|
|
|
E.insert( { name_, coefficient_v() });
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
std::cout << "invalid type: " << type << std::endl;
|
|
|
|
break;
|
2016-03-07 23:29:43 +08:00
|
|
|
}
|
|
|
|
if (debug) {
|
|
|
|
std::cout << "Added Row Type: " << type << " Name: " << name_
|
|
|
|
<< std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
void addBound(
|
|
|
|
boost::fusion::vector<std::vector<char>, std::vector<char>,
|
|
|
|
std::vector<char>, std::vector<char>, std::vector<char>,
|
|
|
|
std::vector<char>, std::vector<char>, double> const & vars) {
|
|
|
|
std::string type_(boost::fusion::at_c < 1 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 1 > (vars).end()), var_(
|
|
|
|
boost::fusion::at_c < 5 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 5 > (vars).end());
|
|
|
|
double number = boost::fusion::at_c < 7 > (vars);
|
2016-03-07 23:29:43 +08:00
|
|
|
|
|
|
|
if (debug) {
|
|
|
|
std::cout << "Added Bound Type: " << type_ << " Var: " << var_
|
|
|
|
<< " Amount: " << number << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
// void addBound(std::vector<char> type, std::vector<char> var) {
|
|
|
|
void addBoundFr(
|
|
|
|
boost::fusion::vector<std::vector<char>, std::vector<char>,
|
|
|
|
std::vector<char>, std::vector<char>, std::vector<char>,
|
|
|
|
std::vector<char>, std::vector<char>> const & vars) {
|
|
|
|
std::string type_(boost::fusion::at_c < 1 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 1 > (vars).end()), var_(
|
|
|
|
boost::fusion::at_c < 5 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 5 > (vars).end());
|
2016-03-07 23:29:43 +08:00
|
|
|
if (debug) {
|
|
|
|
std::cout << "Added Free Bound Type: " << type_ << " Var: " << var_
|
|
|
|
<< " Amount: " << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-08 23:34:31 +08:00
|
|
|
// void addQuadTerm(std::vector<char> var1, std::vector<char> var2,
|
|
|
|
// double coefficient) {
|
|
|
|
void addQuadTerm(
|
|
|
|
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::string var1_(boost::fusion::at_c < 1 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 1 > (vars).end()), var2_(
|
|
|
|
boost::fusion::at_c < 3 > (vars).begin(),
|
|
|
|
boost::fusion::at_c < 3 > (vars).end());
|
|
|
|
double coefficient = boost::fusion::at_c < 5 > (vars);
|
2016-03-07 23:29:43 +08:00
|
|
|
if (debug) {
|
|
|
|
std::cout << "Added QuadTerm for Var: " << var1_ << " Row: " << var2_
|
|
|
|
<< " Coefficient: " << coefficient << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QP makeQP() {
|
|
|
|
return QP();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|