Calculate gradient of factor graph objective function.
parent
67e1897e47
commit
e7a912bd3b
|
@ -358,6 +358,24 @@ GaussianFactor::eliminate(const string& key) const
|
|||
return make_pair(conditional, factor);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void GaussianFactor::addGradientContribution(const VectorConfig& x, VectorConfig& g) const {
|
||||
// calculate the value of the factor
|
||||
Vector e = -b_;
|
||||
string j; Matrix Aj;
|
||||
FOREACH_PAIR(j, Aj, As_) e += Vector(Aj * x[j]);
|
||||
|
||||
// transpose
|
||||
Vector et = trans(e);
|
||||
|
||||
// contribute to gradient for each connected variable
|
||||
FOREACH_PAIR(j, Aj, As_) {
|
||||
Vector dj = trans(et*Aj); // this factor's contribution to gradient on j
|
||||
Vector wdj = ediv(dj,emul(sigmas_,sigmas_)); // properly weight by sigmas
|
||||
g.add(j,wdj);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
namespace gtsam {
|
||||
|
||||
|
|
|
@ -241,7 +241,14 @@ public:
|
|||
* @param m final number of rows of f, needs to be known in advance
|
||||
* @param pos where to insert in the m-sized matrices
|
||||
*/
|
||||
inline void append_factor(GaussianFactor::shared_ptr f, size_t m, size_t pos);
|
||||
void append_factor(GaussianFactor::shared_ptr f, size_t m, size_t pos);
|
||||
|
||||
/**
|
||||
* Add gradient contribution to gradient config g
|
||||
* @param x: confif at which to evaluate gradient
|
||||
* @param g: I/O parameter, evolving gradient
|
||||
*/
|
||||
void addGradientContribution(const VectorConfig& x, VectorConfig& g) const;
|
||||
|
||||
}; // GaussianFactor
|
||||
|
||||
|
|
|
@ -200,3 +200,12 @@ Matrix GaussianFactorGraph::sparse(const Ordering& ordering) const {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
VectorConfig GaussianFactorGraph::gradient(const VectorConfig& x) const {
|
||||
VectorConfig g;
|
||||
// For each factor add the gradient contribution
|
||||
BOOST_FOREACH(sharedFactor factor,factors_)
|
||||
factor->addGradientContribution(x,g);
|
||||
return g;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -159,6 +159,11 @@ namespace gtsam {
|
|||
* @param ordering of variables needed for matrix column order
|
||||
*/
|
||||
Matrix sparse(const Ordering& ordering) const;
|
||||
|
||||
/**
|
||||
* Calculate Gradient of 0.5*|Ax-b| for a given config
|
||||
*/
|
||||
VectorConfig gradient(const VectorConfig& x) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -537,6 +537,28 @@ TEST( GaussianFactorGraph, involves )
|
|||
CHECK(!fg.involves("x3"));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( GaussianFactorGraph, gradient )
|
||||
{
|
||||
GaussianFactorGraph fg = createGaussianFactorGraph();
|
||||
|
||||
// Construct expected gradient
|
||||
VectorConfig expected;
|
||||
|
||||
// 2*f(x) = 100*(x1+c["x1"])^2 + 100*(x2-x1-[0.2;-0.1])^2 + 25*(l1-x1-[0.0;0.2])^2 + 25*(l1-x2-[-0.2;0.3])^2
|
||||
// worked out: df/dx1 = 100*[0.1;0.1] + 100*[0.2;-0.1]) + 25*[0.0;0.2] = [10+20;10-10+5] = [30;5]
|
||||
expected.insert("x1",Vector_(2,30.0,5.0));
|
||||
// from working implementation:
|
||||
expected.insert("x2",Vector_(2,-25.0, 17.5));
|
||||
expected.insert("l1",Vector_(2, 5.0,-12.5));
|
||||
|
||||
// calculate the gradient at delta=0
|
||||
VectorConfig delta = createZeroDelta();
|
||||
VectorConfig actual = fg.gradient(delta);
|
||||
|
||||
CHECK(assert_equal(expected,actual));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// Tests ported from ConstrainedGaussianFactorGraph
|
||||
/* ************************************************************************* */
|
||||
|
@ -554,7 +576,7 @@ TEST( GaussianFactorGraph, constrained_simple )
|
|||
|
||||
// verify
|
||||
VectorConfig expected = createSimpleConstraintConfig();
|
||||
CHECK(assert_equal(actual, expected));
|
||||
CHECK(assert_equal(expected, actual));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -570,7 +592,7 @@ TEST( GaussianFactorGraph, constrained_single )
|
|||
|
||||
// verify
|
||||
VectorConfig expected = createSingleConstraintConfig();
|
||||
CHECK(assert_equal(actual, expected));
|
||||
CHECK(assert_equal(expected, actual));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -586,7 +608,7 @@ TEST( GaussianFactorGraph, constrained_single2 )
|
|||
|
||||
// verify
|
||||
VectorConfig expected = createSingleConstraintConfig();
|
||||
CHECK(assert_equal(actual, expected));
|
||||
CHECK(assert_equal(expected, actual));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -602,7 +624,7 @@ TEST( GaussianFactorGraph, constrained_multi1 )
|
|||
|
||||
// verify
|
||||
VectorConfig expected = createMultiConstraintConfig();
|
||||
CHECK(assert_equal(actual, expected));
|
||||
CHECK(assert_equal(expected, actual));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -618,7 +640,7 @@ TEST( GaussianFactorGraph, constrained_multi2 )
|
|||
|
||||
// verify
|
||||
VectorConfig expected = createMultiConstraintConfig();
|
||||
CHECK(assert_equal(actual, expected));
|
||||
CHECK(assert_equal(expected, actual));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
Loading…
Reference in New Issue