71 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
		
		
			
		
	
	
			71 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @file ConstraintOptimizer.cpp
							 | 
						||
| 
								 | 
							
								 * @author Alex Cunningham
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <ConstraintOptimizer.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using namespace std;
							 | 
						||
| 
								 | 
							
								using namespace gtsam;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ************************************************************************* */
							 | 
						||
| 
								 | 
							
								void gtsam::BFGSEstimator::update(const Vector& dfx, const boost::optional<Vector&> step) {
							 | 
						||
| 
								 | 
							
									if (step) {
							 | 
						||
| 
								 | 
							
										Vector Bis = B_ * *step,
							 | 
						||
| 
								 | 
							
												y = dfx - prev_dfx_;
							 | 
						||
| 
								 | 
							
										B_ = B_ + outer_prod(y, y) / inner_prod(y, *step)
							 | 
						||
| 
								 | 
							
								                - outer_prod(Bis, Bis) / inner_prod(*step, Bis);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									prev_dfx_ = dfx;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ************************************************************************* */
							 | 
						||
| 
								 | 
							
								pair<Vector, Vector> gtsam::solveCQP(const Matrix& B, const Matrix& A,
							 | 
						||
| 
								 | 
							
																     const Vector& g, const Vector& h) {
							 | 
						||
| 
								 | 
							
									// find the dimensions
							 | 
						||
| 
								 | 
							
									size_t n = B.size1(), p = A.size2();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// verify matrices
							 | 
						||
| 
								 | 
							
									if (n != B.size2())
							 | 
						||
| 
								 | 
							
										throw invalid_argument("solveCQP: B matrix is not square!");
							 | 
						||
| 
								 | 
							
									if (A.size1() != n)
							 | 
						||
| 
								 | 
							
										throw invalid_argument("solveCQP: A matrix needs m = B.size1()");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// construct G matrix
							 | 
						||
| 
								 | 
							
									Matrix G = zeros(n+p, n+p);
							 | 
						||
| 
								 | 
							
									insertSub(G, B, 0, 0);
							 | 
						||
| 
								 | 
							
									insertSub(G, A, 0, n);
							 | 
						||
| 
								 | 
							
									insertSub(G, trans(A), n, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Vector rhs = zero(n+p);
							 | 
						||
| 
								 | 
							
									subInsert(rhs, -1.0*g, 0);
							 | 
						||
| 
								 | 
							
									subInsert(rhs, -1.0*h, n);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// solve the system with the LDL solver
							 | 
						||
| 
								 | 
							
									Vector fullResult = solve_ldl(G, rhs);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return make_pair(sub(fullResult, 0, n), sub(fullResult, n, n+p));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ************************************************************************* */
							 | 
						||
| 
								 | 
							
								Vector gtsam::linesearch(const Vector& x0, const Vector& delta,
							 | 
						||
| 
								 | 
							
										double (*penalty)(const Vector&), size_t maxIt) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// calculate the initial error
							 | 
						||
| 
								 | 
							
									double init_error = penalty(x0);
							 | 
						||
| 
								 | 
							
									Vector step = delta;
							 | 
						||
| 
								 | 
							
									for (size_t i=0; i<maxIt; ++i) {
							 | 
						||
| 
								 | 
							
										Vector x = x0 + step;
							 | 
						||
| 
								 | 
							
										double cur_error = penalty(x);
							 | 
						||
| 
								 | 
							
										if (cur_error < init_error) // if we have improved, return the step
							 | 
						||
| 
								 | 
							
											return step;
							 | 
						||
| 
								 | 
							
										else { // otherwise, make a smaller step
							 | 
						||
| 
								 | 
							
											step = 0.5 * step;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// TODO: should do something clever here
							 | 
						||
| 
								 | 
							
									return step;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 |