Passing JacobianMap as an argument now..

release/4.3a0
dellaert 2014-10-12 20:16:08 +02:00
parent dc541f1051
commit 4d1eb05c7d
4 changed files with 48 additions and 31 deletions

View File

@ -45,6 +45,16 @@ class Expression;
typedef std::map<Key, Matrix> JacobianMap; typedef std::map<Key, Matrix> JacobianMap;
/// Move terms to array, destroys content
void move(JacobianMap& jacobians, std::vector<Matrix>& H) {
assert(H.size()==jacobians.size());
size_t j = 0;
JacobianMap::iterator it = jacobians.begin();
for (; it != jacobians.end(); ++it)
it->second.swap(H[j++]);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** /**
* The CallRecord class stores the Jacobians of applying a function * The CallRecord class stores the Jacobians of applying a function
@ -370,11 +380,7 @@ public:
/// Move terms to array, destroys content /// Move terms to array, destroys content
void move(std::vector<Matrix>& H) { void move(std::vector<Matrix>& H) {
assert(H.size()==jacobians_.size()); move(jacobians_, H);
size_t j = 0;
JacobianMap::iterator it = jacobians_.begin();
for (; it != jacobians_.end(); ++it)
it->second.swap(H[j++]);
} }
}; };

View File

@ -108,14 +108,11 @@ public:
return root_->keys(); return root_->keys();
} }
/// Return value and optional derivatives
T value(const Values& values) const {
return root_->value(values);
}
/// Return value and derivatives, forward AD version /// Return value and derivatives, forward AD version
Augmented<T> forward(const Values& values) const { T forward(const Values& values, JacobianMap& jacobians) const {
return root_->forward(values); Augmented<T> augmented = root_->forward(values);
jacobians = augmented.jacobians();
return augmented.value();
} }
// Return size needed for memory buffer in traceExecution // Return size needed for memory buffer in traceExecution
@ -130,22 +127,26 @@ public:
} }
/// Return value and derivatives, reverse AD version /// Return value and derivatives, reverse AD version
Augmented<T> reverse(const Values& values) const { T reverse(const Values& values, JacobianMap& jacobians) const {
size_t size = traceSize(); size_t size = traceSize();
char raw[size]; char raw[size];
ExecutionTrace<T> trace; ExecutionTrace<T> trace;
T value(traceExecution(values, trace, raw)); T value(traceExecution(values, trace, raw));
Augmented<T> augmented(value); trace.startReverseAD(jacobians);
trace.startReverseAD(augmented.jacobians()); return value;
return augmented; }
/// Return value
T value(const Values& values) const {
return root_->value(values);
} }
/// Return value and derivatives /// Return value and derivatives
Augmented<T> augmented(const Values& values) const { T value(const Values& values, JacobianMap& jacobians) const {
#ifdef EXPRESSION_FORWARD_AD #ifdef EXPRESSION_FORWARD_AD
return forward(values); return forward(values, jacobians);
#else #else
return reverse(values); return reverse(values, jacobians);
#endif #endif
} }

View File

@ -50,10 +50,11 @@ public:
boost::optional<std::vector<Matrix>&> H = boost::none) const { boost::optional<std::vector<Matrix>&> H = boost::none) const {
if (H) { if (H) {
assert(H->size()==size()); assert(H->size()==size());
Augmented<T> augmented = expression_.augmented(x); JacobianMap jacobians;
T value = expression_.value(x, jacobians);
// move terms to H, which is pre-allocated to correct size // move terms to H, which is pre-allocated to correct size
augmented.move(*H); move(jacobians, *H);
return measurement_.localCoordinates(augmented.value()); return measurement_.localCoordinates(value);
} else { } else {
const T& value = expression_.value(x); const T& value = expression_.value(x);
return measurement_.localCoordinates(value); return measurement_.localCoordinates(value);
@ -67,15 +68,15 @@ public:
return boost::shared_ptr<JacobianFactor>(); return boost::shared_ptr<JacobianFactor>();
// Evaluate error to get Jacobians and RHS vector b // Evaluate error to get Jacobians and RHS vector b
Augmented<T> augmented = expression_.augmented(x); JacobianMap terms;
Vector b = -measurement_.localCoordinates(augmented.value()); T value = expression_.value(x, terms);
Vector b = -measurement_.localCoordinates(value);
// check(noiseModel_, b); // TODO: use, but defined in NonlinearFactor.cpp // check(noiseModel_, b); // TODO: use, but defined in NonlinearFactor.cpp
// Whiten the corresponding system now // Whiten the corresponding system now
// TODO ! this->noiseModel_->WhitenSystem(A, b); // TODO ! this->noiseModel_->WhitenSystem(A, b);
// Terms, needed to create JacobianFactor below, are already here! // Terms, needed to create JacobianFactor below, are already here!
const JacobianMap& terms = augmented.jacobians();
size_t n = terms.size(); size_t n = terms.size();
// Get dimensions of matrices // Get dimensions of matrices

View File

@ -44,10 +44,11 @@ static const Rot3 someR = Rot3::RzRyRx(1, 2, 3);
TEST(Expression, constant) { TEST(Expression, constant) {
Expression<Rot3> R(someR); Expression<Rot3> R(someR);
Values values; Values values;
Augmented<Rot3> a = R.augmented(values); JacobianMap actualMap;
EXPECT(assert_equal(someR, a.value())); Rot3 actual = R.value(values, actualMap);
EXPECT(assert_equal(someR, actual));
JacobianMap expected; JacobianMap expected;
EXPECT(a.jacobians() == expected); EXPECT(actualMap == expected);
} }
/* ************************************************************************* */ /* ************************************************************************* */
@ -56,11 +57,19 @@ TEST(Expression, leaf) {
Expression<Rot3> R(100); Expression<Rot3> R(100);
Values values; Values values;
values.insert(100, someR); values.insert(100, someR);
Augmented<Rot3> a = R.augmented(values);
EXPECT(assert_equal(someR, a.value()));
JacobianMap expected; JacobianMap expected;
expected[100] = eye(3); expected[100] = eye(3);
EXPECT(a.jacobians() == expected);
JacobianMap actualMap1;
Rot3 actual1 = R.forward(values, actualMap1);
EXPECT(assert_equal(someR, actual1));
EXPECT(actualMap1 == expected);
JacobianMap actualMap2;
Rot3 actual2 = R.reverse(values, actualMap2);
EXPECT(assert_equal(someR, actual2));
EXPECT(actualMap2 == expected);
} }
/* ************************************************************************* */ /* ************************************************************************* */