No more JacobianTA typedefs -> all use Jacobian<T,A> now.

release/4.3a0
dellaert 2014-10-13 09:25:06 +02:00
parent 7848d74928
commit 7fde47c48b
3 changed files with 35 additions and 45 deletions

View File

@ -277,9 +277,9 @@ public:
}; };
/// Primary template calls the generic Matrix reverseAD pipeline /// Primary template calls the generic Matrix reverseAD pipeline
template<size_t M, class A> template<size_t ROWS, class A>
struct Select { struct Select {
typedef Eigen::Matrix<double, M, A::dimension> Jacobian; typedef Eigen::Matrix<double, ROWS, A::dimension> Jacobian;
static void reverseAD(const ExecutionTrace<A>& trace, const Jacobian& dTdA, static void reverseAD(const ExecutionTrace<A>& trace, const Jacobian& dTdA,
JacobianMap& jacobians) { JacobianMap& jacobians) {
trace.reverseAD(dTdA, jacobians); trace.reverseAD(dTdA, jacobians);
@ -426,6 +426,13 @@ public:
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// meta-function to generate fixed-size JacobianTA type
template<class T, class A>
struct Jacobian {
typedef Eigen::Matrix<double, T::dimension, A::dimension> type;
typedef boost::optional<type&> optional;
};
/** /**
* Building block for Recursive Record Class * Building block for Recursive Record Class
* Records the evaluation of a single argument in a functional expression * Records the evaluation of a single argument in a functional expression
@ -434,9 +441,8 @@ public:
*/ */
template<class T, class A, size_t N> template<class T, class A, size_t N>
struct JacobianTrace { struct JacobianTrace {
typedef Eigen::Matrix<double, T::dimension, A::dimension> JacobianTA;
ExecutionTrace<A> trace; ExecutionTrace<A> trace;
JacobianTA dTdA; typename Jacobian<T, A>::type dTdA;
}; };
/** /**
@ -491,7 +497,7 @@ struct Record: public boost::mpl::fold<TYPES, CallRecord<T::dimension>,
/// Access Jacobian /// Access Jacobian
template<class A, size_t N> template<class A, size_t N>
Eigen::Matrix<double, T::dimension, A::dimension>& jacobian() { typename Jacobian<T, A>::type& jacobian() {
return static_cast<JacobianTrace<T, A, N>&>(*this).dTdA; return static_cast<JacobianTrace<T, A, N>&>(*this).dTdA;
} }
@ -535,19 +541,10 @@ struct Record: public boost::mpl::fold<TYPES, CallRecord<T::dimension>,
*/ */
template<class T, class A, size_t N> template<class T, class A, size_t N>
struct Argument { struct Argument {
/// Fixed size Jacobian type for the argument A
typedef Eigen::Matrix<double, T::dimension, A::dimension> JacobianTA;
/// Expression that will generate value/derivatives for argument /// Expression that will generate value/derivatives for argument
boost::shared_ptr<ExpressionNode<A> > expression; boost::shared_ptr<ExpressionNode<A> > expression;
}; };
/// meta-function to access JacobianTA type
template<class T, class A, size_t N>
struct Jacobian {
typedef typename Argument<T, A, N>::JacobianTA type;
};
/** /**
* Recursive Definition of Functional ExpressionNode * Recursive Definition of Functional ExpressionNode
*/ */
@ -599,8 +596,7 @@ class UnaryExpression: public FunctionalNode<T, boost::mpl::vector<A1> > {
public: public:
typedef typename Jacobian<T,A1,1>::type JacobianTA1; typedef boost::function<T(const A1&, typename Jacobian<T, A1>::optional)> Function;
typedef boost::function<T(const A1&, boost::optional<JacobianTA1&>)> Function;
private: private:
@ -625,11 +621,10 @@ public:
/// Return value and derivatives /// Return value and derivatives
virtual Augmented<T> forward(const Values& values) const { virtual Augmented<T> forward(const Values& values) const {
using boost::none; using boost::none;
Augmented<A1> argument = this->template expression<A1, 1>()->forward(values); Augmented<A1> a1 = this->template expression<A1, 1>()->forward(values);
JacobianTA1 dTdA; typename Jacobian<T, A1>::type dTdA1;
T t = function_(argument.value(), T t = function_(a1.value(), a1.constant() ? none : typename Jacobian<T,A1>::optional(dTdA1));
argument.constant() ? none : boost::optional<JacobianTA1&>(dTdA)); return Augmented<T>(t, dTdA1, a1.jacobians());
return Augmented<T>(t, dTdA, argument.jacobians());
} }
/// CallRecord structure for reverse AD /// CallRecord structure for reverse AD
@ -658,11 +653,9 @@ class BinaryExpression: public FunctionalNode<T, boost::mpl::vector<A1, A2> > {
public: public:
typedef typename Jacobian<T,A1,1>::type JacobianTA1;
typedef typename Jacobian<T,A2,2>::type JacobianTA2;
typedef boost::function< typedef boost::function<
T(const A1&, const A2&, boost::optional<JacobianTA1&>, T(const A1&, const A2&, typename Jacobian<T, A1>::optional,
boost::optional<JacobianTA2&>)> Function; typename Jacobian<T, A2>::optional)> Function;
private: private:
@ -696,11 +689,11 @@ public:
using boost::none; using boost::none;
Augmented<A1> a1 = this->template expression<A1, 1>()->forward(values); Augmented<A1> a1 = this->template expression<A1, 1>()->forward(values);
Augmented<A2> a2 = this->template expression<A2, 2>()->forward(values); Augmented<A2> a2 = this->template expression<A2, 2>()->forward(values);
JacobianTA1 dTdA1; typename Jacobian<T, A1>::type dTdA1;
JacobianTA2 dTdA2; typename Jacobian<T, A2>::type dTdA2;
T t = function_(a1.value(), a2.value(), T t = function_(a1.value(), a2.value(),
a1.constant() ? none : boost::optional<JacobianTA1&>(dTdA1), a1.constant() ? none : typename Jacobian<T, A1>::optional(dTdA1),
a2.constant() ? none : boost::optional<JacobianTA2&>(dTdA2)); a2.constant() ? none : typename Jacobian<T, A2>::optional(dTdA2));
return Augmented<T>(t, dTdA1, a1.jacobians(), dTdA2, a2.jacobians()); return Augmented<T>(t, dTdA1, a1.jacobians(), dTdA2, a2.jacobians());
} }
@ -734,12 +727,10 @@ class TernaryExpression: public FunctionalNode<T, boost::mpl::vector<A1, A2, A3>
public: public:
typedef typename Jacobian<T,A1,1>::type JacobianTA1;
typedef typename Jacobian<T,A2,2>::type JacobianTA2;
typedef typename Jacobian<T,A3,3>::type JacobianTA3;
typedef boost::function< typedef boost::function<
T(const A1&, const A2&, const A3&, boost::optional<JacobianTA1&>, T(const A1&, const A2&, const A3&, typename Jacobian<T, A1>::optional,
boost::optional<JacobianTA2&>, boost::optional<JacobianTA3&>)> Function; typename Jacobian<T, A2>::optional,
typename Jacobian<T, A3>::optional)> Function;
private: private:
@ -775,13 +766,13 @@ public:
Augmented<A1> a1 = this->template expression<A1, 1>()->forward(values); Augmented<A1> a1 = this->template expression<A1, 1>()->forward(values);
Augmented<A2> a2 = this->template expression<A2, 2>()->forward(values); Augmented<A2> a2 = this->template expression<A2, 2>()->forward(values);
Augmented<A3> a3 = this->template expression<A3, 3>()->forward(values); Augmented<A3> a3 = this->template expression<A3, 3>()->forward(values);
JacobianTA1 dTdA1; typename Jacobian<T, A1>::type dTdA1;
JacobianTA2 dTdA2; typename Jacobian<T, A2>::type dTdA2;
JacobianTA3 dTdA3; typename Jacobian<T, A3>::type dTdA3;
T t = function_(a1.value(), a2.value(), a3.value(), T t = function_(a1.value(), a2.value(), a3.value(),
a1.constant() ? none : boost::optional<JacobianTA1&>(dTdA1), a1.constant() ? none : typename Jacobian<T, A1>::optional(dTdA1),
a2.constant() ? none : boost::optional<JacobianTA2&>(dTdA2), a2.constant() ? none : typename Jacobian<T, A2>::optional(dTdA2),
a3.constant() ? none : boost::optional<JacobianTA3&>(dTdA3)); a3.constant() ? none : typename Jacobian<T, A3>::optional(dTdA3));
return Augmented<T>(t, dTdA1, a1.jacobians(), dTdA2, a2.jacobians(), dTdA3, return Augmented<T>(t, dTdA1, a1.jacobians(), dTdA2, a2.jacobians(), dTdA3,
a3.jacobians()); a3.jacobians());
} }

View File

@ -76,9 +76,8 @@ public:
/// Construct a unary method expression /// Construct a unary method expression
template<typename A1, typename A2> template<typename A1, typename A2>
Expression(const Expression<A1>& expression1, Expression(const Expression<A1>& expression1,
T (A1::*method)(const A2&, T (A1::*method)(const A2&, typename Jacobian<T, A1>::optional,
boost::optional<typename BinaryExpression<T, A1, A2>::JacobianTA1&>, typename Jacobian<T, A2>::optional) const,
boost::optional<typename BinaryExpression<T, A1, A2>::JacobianTA2&>) const,
const Expression<A2>& expression2) { const Expression<A2>& expression2) {
root_.reset( root_.reset(
new BinaryExpression<T, A1, A2>(boost::bind(method, _1, _2, _3, _4), new BinaryExpression<T, A1, A2>(boost::bind(method, _1, _2, _3, _4),

View File

@ -150,8 +150,8 @@ TEST(ExpressionFactor, binary) {
EXPECT_LONGS_EQUAL(8, sizeof(double)); EXPECT_LONGS_EQUAL(8, sizeof(double));
EXPECT_LONGS_EQUAL(16, sizeof(ExecutionTrace<Point2>)); EXPECT_LONGS_EQUAL(16, sizeof(ExecutionTrace<Point2>));
EXPECT_LONGS_EQUAL(16, sizeof(ExecutionTrace<Cal3_S2>)); EXPECT_LONGS_EQUAL(16, sizeof(ExecutionTrace<Cal3_S2>));
EXPECT_LONGS_EQUAL(2*5*8, sizeof(Binary::JacobianTA1)); EXPECT_LONGS_EQUAL(2*5*8, sizeof(Jacobian<Point2,Cal3_S2>::type));
EXPECT_LONGS_EQUAL(2*2*8, sizeof(Binary::JacobianTA2)); EXPECT_LONGS_EQUAL(2*2*8, sizeof(Jacobian<Point2,Point2>::type));
size_t expectedRecordSize = 16 + 2 * 16 + 80 + 32; size_t expectedRecordSize = 16 + 2 * 16 + 80 + 32;
EXPECT_LONGS_EQUAL(expectedRecordSize, sizeof(Binary::Record)); EXPECT_LONGS_EQUAL(expectedRecordSize, sizeof(Binary::Record));