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;
|
|
}
|
|
|