| 
									
										
										
										
											2016-06-18 03:24:55 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | 
					
						
							|  |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @file     RawQP.cpp | 
					
						
							|  |  |  |  * @brief     | 
					
						
							|  |  |  |  * @author   Ivan Dario Jimenez | 
					
						
							|  |  |  |  * @date     3/5/16 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-07 23:29:43 +08:00
										 |  |  | #include <gtsam_unstable/linear/RawQP.h>
 | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  | #include <iostream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using boost::fusion::at_c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::setName( | 
					
						
							|  |  |  |     boost::fusion::vector<std::vector<char>, std::vector<char>, | 
					
						
							|  |  |  |         std::vector<char>> const &name) { | 
					
						
							|  |  |  |   name_ = std::string(at_c < 1 > (name).begin(), at_c < 1 > (name).end()); | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     std::cout << "Parsing file: " << name_ << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::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_(at_c < 1 > (vars).begin(), at_c < 1 > (vars).end()); | 
					
						
							|  |  |  |   std::string row_(at_c < 3 > (vars).begin(), at_c < 3 > (vars).end()); | 
					
						
							| 
									
										
										
										
											2016-05-07 00:23:41 +08:00
										 |  |  |   Matrix11 coefficient = at_c < 5 > (vars) * I_1x1; | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!varname_to_key.count(var_)) | 
					
						
							|  |  |  |     varname_to_key[var_] = Symbol('X', varNumber++); | 
					
						
							|  |  |  |   if (row_ == obj_name) { | 
					
						
							|  |  |  |     g[varname_to_key[var_]] = coefficient; | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   (*row_to_constraint_v[row_])[row_][varname_to_key[var_]] = coefficient; | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     std::cout << "Added Column for Var: " << var_ << " Row: " << row_ | 
					
						
							|  |  |  |         << " Coefficient: " << coefficient << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::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_(at_c < 0 > (vars).begin(), at_c < 0 > (vars).end()); | 
					
						
							|  |  |  |   std::string row1_(at_c < 2 > (vars).begin(), at_c < 2 > (vars).end()); | 
					
						
							|  |  |  |   std::string row2_(at_c < 6 > (vars).begin(), at_c < 6 > (vars).end()); | 
					
						
							| 
									
										
										
										
											2016-05-07 00:23:41 +08:00
										 |  |  |   Matrix11 coefficient1 = at_c < 4 > (vars) * I_1x1; | 
					
						
							|  |  |  |   Matrix11 coefficient2 = at_c < 8 > (vars) * I_1x1; | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |   if (!varname_to_key.count(var_)) | 
					
						
							|  |  |  |     varname_to_key.insert( { var_, Symbol('X', varNumber++) }); | 
					
						
							|  |  |  |   if (row1_ == obj_name) | 
					
						
							|  |  |  |     g[varname_to_key[var_]] = coefficient1; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     (*row_to_constraint_v[row1_])[row1_][varname_to_key[var_]] = coefficient1; | 
					
						
							|  |  |  |   if (row2_ == obj_name) | 
					
						
							|  |  |  |     g[varname_to_key[var_]] = coefficient2; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     (*row_to_constraint_v[row2_])[row2_][varname_to_key[var_]] = coefficient2; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::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_(at_c < 1 > (vars).begin(), at_c < 1 > (vars).end()); | 
					
						
							|  |  |  |   std::string row_(at_c < 3 > (vars).begin(), at_c < 3 > (vars).end()); | 
					
						
							|  |  |  |   double coefficient = at_c < 5 > (vars); | 
					
						
							|  |  |  |   if (row_ == obj_name) | 
					
						
							|  |  |  |     f = -coefficient; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     b[row_] = coefficient; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     std::cout << "Added RHS for Var: " << var_ << " Row: " << row_ | 
					
						
							|  |  |  |         << " Coefficient: " << coefficient << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::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_(at_c < 1 > (vars).begin(), at_c < 1 > (vars).end()); | 
					
						
							|  |  |  |   std::string row1_(at_c < 3 > (vars).begin(), at_c < 3 > (vars).end()); | 
					
						
							|  |  |  |   std::string row2_(at_c < 7 > (vars).begin(), at_c < 7 > (vars).end()); | 
					
						
							|  |  |  |   double coefficient1 = at_c < 5 > (vars); | 
					
						
							|  |  |  |   double coefficient2 = at_c < 9 > (vars); | 
					
						
							|  |  |  |   if (row1_ == obj_name) | 
					
						
							|  |  |  |     f = -coefficient1; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     b[row1_] = coefficient1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (row2_ == obj_name) | 
					
						
							|  |  |  |     f = -coefficient2; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     b[row2_] = coefficient2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     std::cout << "Added RHS for Var: " << var_ << " Row: " << row1_ | 
					
						
							|  |  |  |         << " Coefficient: " << coefficient1 << std::endl; | 
					
						
							|  |  |  |     std::cout << "                      " << "Row: " << row2_ | 
					
						
							|  |  |  |         << " Coefficient: " << coefficient2 << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::addRow( | 
					
						
							|  |  |  |     boost::fusion::vector<std::vector<char>, char, std::vector<char>, | 
					
						
							|  |  |  |         std::vector<char>, std::vector<char>> const &vars) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   std::string name_(at_c < 3 > (vars).begin(), at_c < 3 > (vars).end()); | 
					
						
							|  |  |  |   char type = at_c < 1 > (vars); | 
					
						
							|  |  |  |   switch (type) { | 
					
						
							|  |  |  |   case 'N': | 
					
						
							|  |  |  |     obj_name = name_; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case 'L': | 
					
						
							|  |  |  |     row_to_constraint_v[name_] = &IL; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case 'G': | 
					
						
							|  |  |  |     row_to_constraint_v[name_] = &IG; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case 'E': | 
					
						
							|  |  |  |     row_to_constraint_v[name_] = &E; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |     std::cout << "invalid type: " << type << std::endl; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     std::cout << "Added Row Type: " << type << " Name: " << name_ << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::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_(at_c < 1 > (vars).begin(), at_c < 1 > (vars).end()); | 
					
						
							|  |  |  |   std::string var_(at_c < 5 > (vars).begin(), at_c < 5 > (vars).end()); | 
					
						
							|  |  |  |   double number = at_c < 7 > (vars); | 
					
						
							|  |  |  |   if (type_.compare(std::string("UP")) == 0) | 
					
						
							|  |  |  |     up[varname_to_key[var_]] = number; | 
					
						
							|  |  |  |   else if (type_.compare(std::string("LO")) == 0) | 
					
						
							|  |  |  |     lo[varname_to_key[var_]] = number; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     std::cout << "Invalid Bound Type: " << type_ << std::endl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     std::cout << "Added Bound Type: " << type_ << " Var: " << var_ | 
					
						
							|  |  |  |         << " Amount: " << number << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::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_(at_c < 1 > (vars).begin(), at_c < 1 > (vars).end()); | 
					
						
							|  |  |  |   std::string var_(at_c < 5 > (vars).begin(), at_c < 5 > (vars).end()); | 
					
						
							|  |  |  |   Free.push_back(varname_to_key[var_]); | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     std::cout << "Added Free Bound Type: " << type_ << " Var: " << var_ | 
					
						
							|  |  |  |         << " Amount: " << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RawQP::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_(at_c < 1 > (vars).begin(), at_c < 1 > (vars).end()); | 
					
						
							|  |  |  |   std::string var2_(at_c < 3 > (vars).begin(), at_c < 3 > (vars).end()); | 
					
						
							| 
									
										
										
										
											2016-05-07 00:23:41 +08:00
										 |  |  |   Matrix11 coefficient = at_c < 5 > (vars) * I_1x1; | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   H[varname_to_key[var1_]][varname_to_key[var2_]] = coefficient; | 
					
						
							|  |  |  |   H[varname_to_key[var2_]][varname_to_key[var1_]] = coefficient; | 
					
						
							|  |  |  |   if (debug) { | 
					
						
							|  |  |  |     std::cout << "Added QuadTerm for Var: " << var1_ << " Row: " << var2_ | 
					
						
							|  |  |  |         << " Coefficient: " << coefficient << std::endl; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QP RawQP::makeQP() { | 
					
						
							|  |  |  |   std::vector < Key > keys; | 
					
						
							|  |  |  |   std::vector < Matrix > Gs; | 
					
						
							|  |  |  |   std::vector < Vector > gs; | 
					
						
							|  |  |  |   for (auto kv : varname_to_key) { | 
					
						
							|  |  |  |     keys.push_back(kv.second); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   std::sort(keys.begin(), keys.end()); | 
					
						
							|  |  |  |   for (unsigned int i = 0; i < keys.size(); ++i) { | 
					
						
							|  |  |  |     for (unsigned int j = i; j < keys.size(); ++j) { | 
					
						
							|  |  |  |       Gs.push_back(H[keys[i]][keys[j]]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   for (Key key1 : keys) { | 
					
						
							| 
									
										
										
										
											2016-06-18 22:39:59 +08:00
										 |  |  |     gs.push_back(-g[key1]); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   int dual_key_num = keys.size() + 1; | 
					
						
							|  |  |  |   QP madeQP; | 
					
						
							|  |  |  |   auto obj = HessianFactor(keys, Gs, gs, f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   madeQP.cost.push_back(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (auto kv : E) { | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |     std::map<Key, Matrix11> keyMatrixMap; | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |     for (auto km : kv.second) { | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |       keyMatrixMap.insert(km); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     madeQP.equalities.push_back( | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |         LinearEquality(keyMatrixMap, b[kv.first] * I_1x1, dual_key_num++)); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (auto kv : IG) { | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |     std::map<Key, Matrix11> keyMatrixMap; | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |     for (auto km : kv.second) { | 
					
						
							|  |  |  |       km.second = -km.second; | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |       keyMatrixMap.insert(km); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     madeQP.inequalities.push_back( | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |         LinearInequality(keyMatrixMap, -b[kv.first], dual_key_num++)); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (auto kv : IL) { | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |     std::map<Key, Matrix11> keyMatrixMap; | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |     for (auto km : kv.second) { | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |       keyMatrixMap.insert(km); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     madeQP.inequalities.push_back( | 
					
						
							| 
									
										
										
										
											2016-06-18 12:40:23 +08:00
										 |  |  |         LinearInequality(keyMatrixMap, b[kv.first], dual_key_num++)); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (Key k : keys) { | 
					
						
							|  |  |  |     if (std::find(Free.begin(), Free.end(), k) != Free.end()) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     if (up.count(k) == 1) | 
					
						
							|  |  |  |       madeQP.inequalities.push_back( | 
					
						
							| 
									
										
										
										
											2016-05-07 00:23:41 +08:00
										 |  |  |           LinearInequality(k, I_1x1, up[k], dual_key_num++)); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |     if (lo.count(k) == 1) | 
					
						
							|  |  |  |       madeQP.inequalities.push_back( | 
					
						
							| 
									
										
										
										
											2016-05-07 00:23:41 +08:00
										 |  |  |           LinearInequality(k, -I_1x1, lo[k], dual_key_num++)); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |     else | 
					
						
							|  |  |  |       madeQP.inequalities.push_back( | 
					
						
							| 
									
										
										
										
											2016-05-07 00:23:41 +08:00
										 |  |  |           LinearInequality(k, -I_1x1, 0, dual_key_num++)); | 
					
						
							| 
									
										
										
										
											2016-04-26 07:00:22 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return madeQP; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |