Made naming more suggestive of AD process rather than generic H1,H2...
parent
63d87e6497
commit
5c96b7f38d
|
@ -44,7 +44,7 @@ private:
|
|||
|
||||
typedef std::pair<Key, Matrix> Pair;
|
||||
|
||||
/// Insert terms into jacobians_, premultiplying by H, adding if already exists
|
||||
/// Insert terms into jacobians_, adding if already exists
|
||||
void add(const JacobianMap& terms) {
|
||||
BOOST_FOREACH(const Pair& term, terms) {
|
||||
JacobianMap::iterator it = jacobians_.find(term.first);
|
||||
|
@ -80,34 +80,28 @@ public:
|
|||
jacobians_[key] = Eigen::MatrixXd::Identity(n, n);
|
||||
}
|
||||
|
||||
/// Construct value dependent on a single key, with Jacobain H
|
||||
Augmented(const T& t, Key key, const Matrix& H) :
|
||||
/// Construct value, pre-multiply jacobians by dTdA
|
||||
Augmented(const T& t, const Matrix& dTdA, const JacobianMap& jacobians) :
|
||||
value_(t) {
|
||||
jacobians_[key] = H;
|
||||
add(dTdA, jacobians);
|
||||
}
|
||||
|
||||
/// Construct value, pre-multiply jacobians by H
|
||||
Augmented(const T& t, const Matrix& H, const JacobianMap& jacobians) :
|
||||
/// Construct value, pre-multiply jacobians
|
||||
Augmented(const T& t, const Matrix& dTdA1, const JacobianMap& jacobians1,
|
||||
const Matrix& dTdA2, const JacobianMap& jacobians2) :
|
||||
value_(t) {
|
||||
add(H, jacobians);
|
||||
add(dTdA1, jacobians1);
|
||||
add(dTdA2, jacobians2);
|
||||
}
|
||||
|
||||
/// Construct value, pre-multiply jacobians by H
|
||||
Augmented(const T& t, const Matrix& H1, const JacobianMap& jacobians1,
|
||||
const Matrix& H2, const JacobianMap& jacobians2) :
|
||||
/// Construct value, pre-multiply jacobians
|
||||
Augmented(const T& t, const Matrix& dTdA1, const JacobianMap& jacobians1,
|
||||
const Matrix& dTdA2, const JacobianMap& jacobians2, const Matrix& dTdA3,
|
||||
const JacobianMap& jacobians3) :
|
||||
value_(t) {
|
||||
add(H1, jacobians1);
|
||||
add(H2, jacobians2);
|
||||
}
|
||||
|
||||
/// Construct value, pre-multiply jacobians by H
|
||||
Augmented(const T& t, const Matrix& H1, const JacobianMap& jacobians1,
|
||||
const Matrix& H2, const JacobianMap& jacobians2,
|
||||
const Matrix& H3, const JacobianMap& jacobians3) :
|
||||
value_(t) {
|
||||
add(H2, jacobians2);
|
||||
add(H3, jacobians3);
|
||||
add(H1, jacobians1);
|
||||
add(dTdA1, jacobians1);
|
||||
add(dTdA2, jacobians2);
|
||||
add(dTdA3, jacobians3);
|
||||
}
|
||||
|
||||
/// Return value
|
||||
|
@ -147,7 +141,7 @@ struct JacobianTrace {
|
|||
return t;
|
||||
}
|
||||
virtual void reverseAD(JacobianMap& jacobians) const = 0;
|
||||
virtual void reverseAD(const Matrix& H, JacobianMap& jacobians) const = 0;
|
||||
virtual void reverseAD(const Matrix& dFdT, JacobianMap& jacobians) const = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -228,7 +222,7 @@ public:
|
|||
virtual void reverseAD(JacobianMap& jacobians) const {
|
||||
}
|
||||
/// Base case: we simply ignore the given df/dT
|
||||
virtual void reverseAD(const Matrix& H, JacobianMap& jacobians) const {
|
||||
virtual void reverseAD(const Matrix& dFdT, JacobianMap& jacobians) const {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -289,12 +283,12 @@ public:
|
|||
jacobians[key] = Eigen::MatrixXd::Identity(n, n);
|
||||
}
|
||||
/// Base case: given df/dT, add it jacobians with correct key and we are done
|
||||
virtual void reverseAD(const Matrix& H, JacobianMap& jacobians) const {
|
||||
virtual void reverseAD(const Matrix& dFdT, JacobianMap& jacobians) const {
|
||||
JacobianMap::iterator it = jacobians.find(key);
|
||||
if (it != jacobians.end())
|
||||
it->second += H;
|
||||
it->second += dFdT;
|
||||
else
|
||||
jacobians[key] = H;
|
||||
jacobians[key] = dFdT;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -350,23 +344,23 @@ public:
|
|||
virtual Augmented<T> forward(const Values& values) const {
|
||||
using boost::none;
|
||||
Augmented<A> argument = this->expressionA_->forward(values);
|
||||
Matrix H;
|
||||
Matrix dTdA;
|
||||
T t = function_(argument.value(),
|
||||
argument.constant() ? none : boost::optional<Matrix&>(H));
|
||||
return Augmented<T>(t, H, argument.jacobians());
|
||||
argument.constant() ? none : boost::optional<Matrix&>(dTdA));
|
||||
return Augmented<T>(t, dTdA, argument.jacobians());
|
||||
}
|
||||
|
||||
/// Trace structure for reverse AD
|
||||
struct Trace: public JacobianTrace<T> {
|
||||
boost::shared_ptr<JacobianTrace<A> > trace1;
|
||||
Matrix H1;
|
||||
Matrix dTdA;
|
||||
/// Start the reverse AD process
|
||||
virtual void reverseAD(JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(H1, jacobians);
|
||||
trace1->reverseAD(dTdA, jacobians);
|
||||
}
|
||||
/// Given df/dT, multiply in dT/dA and continue reverse AD process
|
||||
virtual void reverseAD(const Matrix& H, JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(H * H1, jacobians);
|
||||
virtual void reverseAD(const Matrix& dFdT, JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(dFdT * dTdA, jacobians);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -375,7 +369,7 @@ public:
|
|||
const Values& values) const {
|
||||
boost::shared_ptr<Trace> trace = boost::make_shared<Trace>();
|
||||
trace->trace1 = this->expressionA_->traceExecution(values);
|
||||
trace->t = function_(trace->trace1->value(), trace->H1);
|
||||
trace->t = function_(trace->trace1->value(), trace->dTdA);
|
||||
return trace;
|
||||
}
|
||||
};
|
||||
|
@ -430,29 +424,29 @@ public:
|
|||
/// Return value and derivatives
|
||||
virtual Augmented<T> forward(const Values& values) const {
|
||||
using boost::none;
|
||||
Augmented<A1> argument1 = this->expressionA1_->forward(values);
|
||||
Augmented<A2> argument2 = this->expressionA2_->forward(values);
|
||||
Matrix H1, H2;
|
||||
T t = function_(argument1.value(), argument2.value(),
|
||||
argument1.constant() ? none : boost::optional<Matrix&>(H1),
|
||||
argument2.constant() ? none : boost::optional<Matrix&>(H2));
|
||||
return Augmented<T>(t, H1, argument1.jacobians(), H2, argument2.jacobians());
|
||||
Augmented<A1> a1 = this->expressionA1_->forward(values);
|
||||
Augmented<A2> a2 = this->expressionA2_->forward(values);
|
||||
Matrix dTdA1, dTdA2;
|
||||
T t = function_(a1.value(), a2.value(),
|
||||
a1.constant() ? none : boost::optional<Matrix&>(dTdA1),
|
||||
a2.constant() ? none : boost::optional<Matrix&>(dTdA2));
|
||||
return Augmented<T>(t, dTdA1, a1.jacobians(), dTdA2, a2.jacobians());
|
||||
}
|
||||
|
||||
/// Trace structure for reverse AD
|
||||
struct Trace: public JacobianTrace<T> {
|
||||
boost::shared_ptr<JacobianTrace<A1> > trace1;
|
||||
boost::shared_ptr<JacobianTrace<A2> > trace2;
|
||||
Matrix H1, H2;
|
||||
Matrix dTdA1, dTdA2;
|
||||
/// Start the reverse AD process
|
||||
virtual void reverseAD(JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(H1, jacobians);
|
||||
trace2->reverseAD(H2, jacobians);
|
||||
trace1->reverseAD(dTdA1, jacobians);
|
||||
trace2->reverseAD(dTdA2, jacobians);
|
||||
}
|
||||
/// Given df/dT, multiply in dT/dA and continue reverse AD process
|
||||
virtual void reverseAD(const Matrix& H, JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(H * H1, jacobians);
|
||||
trace2->reverseAD(H * H2, jacobians);
|
||||
virtual void reverseAD(const Matrix& dFdT, JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(dFdT * dTdA1, jacobians);
|
||||
trace2->reverseAD(dFdT * dTdA2, jacobians);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -463,7 +457,7 @@ public:
|
|||
trace->trace1 = this->expressionA1_->traceExecution(values);
|
||||
trace->trace2 = this->expressionA2_->traceExecution(values);
|
||||
trace->t = function_(trace->trace1->value(), trace->trace2->value(),
|
||||
trace->H1, trace->H2);
|
||||
trace->dTdA1, trace->dTdA2);
|
||||
return trace;
|
||||
}
|
||||
|
||||
|
@ -489,9 +483,12 @@ private:
|
|||
boost::shared_ptr<ExpressionNode<A3> > expressionA3_;
|
||||
|
||||
/// Constructor with a ternary function f, and three input arguments
|
||||
TernaryExpression(Function f, //
|
||||
const Expression<A1>& e1, const Expression<A2>& e2, const Expression<A3>& e3) :
|
||||
function_(f), expressionA1_(e1.root()), expressionA2_(e2.root()), expressionA3_(e3.root()) {
|
||||
TernaryExpression(
|
||||
Function f, //
|
||||
const Expression<A1>& e1, const Expression<A2>& e2,
|
||||
const Expression<A3>& e3) :
|
||||
function_(f), expressionA1_(e1.root()), expressionA2_(e2.root()), expressionA3_(
|
||||
e3.root()) {
|
||||
}
|
||||
|
||||
friend class Expression<T> ;
|
||||
|
@ -516,21 +513,23 @@ public:
|
|||
virtual T value(const Values& values) const {
|
||||
using boost::none;
|
||||
return function_(this->expressionA1_->value(values),
|
||||
this->expressionA2_->value(values), this->expressionA3_->value(values), none, none, none);
|
||||
this->expressionA2_->value(values), this->expressionA3_->value(values),
|
||||
none, none, none);
|
||||
}
|
||||
|
||||
/// Return value and derivatives
|
||||
virtual Augmented<T> forward(const Values& values) const {
|
||||
using boost::none;
|
||||
Augmented<A1> argument1 = this->expressionA1_->forward(values);
|
||||
Augmented<A2> argument2 = this->expressionA2_->forward(values);
|
||||
Augmented<A3> argument3 = this->expressionA3_->forward(values);
|
||||
Matrix H1, H2, H3;
|
||||
T t = function_(argument1.value(), argument2.value(), argument3.value(),
|
||||
argument1.constant() ? none : boost::optional<Matrix&>(H1),
|
||||
argument2.constant() ? none : boost::optional<Matrix&>(H2),
|
||||
argument3.constant() ? none : boost::optional<Matrix&>(H3));
|
||||
return Augmented<T>(t, H1, argument1.jacobians(), H2, argument2.jacobians(), H3, argument3.jacobians());
|
||||
Augmented<A1> a1 = this->expressionA1_->forward(values);
|
||||
Augmented<A2> a2 = this->expressionA2_->forward(values);
|
||||
Augmented<A3> a3 = this->expressionA3_->forward(values);
|
||||
Matrix dTdA1, dTdA2, dTdA3;
|
||||
T t = function_(a1.value(), a2.value(), a3.value(),
|
||||
a1.constant() ? none : boost::optional<Matrix&>(dTdA1),
|
||||
a2.constant() ? none : boost::optional<Matrix&>(dTdA2),
|
||||
a3.constant() ? none : boost::optional<Matrix&>(dTdA3));
|
||||
return Augmented<T>(t, dTdA1, a1.jacobians(), dTdA2, a2.jacobians(), dTdA3,
|
||||
a3.jacobians());
|
||||
}
|
||||
|
||||
/// Trace structure for reverse AD
|
||||
|
@ -538,18 +537,18 @@ public:
|
|||
boost::shared_ptr<JacobianTrace<A1> > trace1;
|
||||
boost::shared_ptr<JacobianTrace<A2> > trace2;
|
||||
boost::shared_ptr<JacobianTrace<A3> > trace3;
|
||||
Matrix H1, H2, H3;
|
||||
Matrix dTdA1, dTdA2, dTdA3;
|
||||
/// Start the reverse AD process
|
||||
virtual void reverseAD(JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(H1, jacobians);
|
||||
trace2->reverseAD(H2, jacobians);
|
||||
trace3->reverseAD(H3, jacobians);
|
||||
trace1->reverseAD(dTdA1, jacobians);
|
||||
trace2->reverseAD(dTdA2, jacobians);
|
||||
trace3->reverseAD(dTdA3, jacobians);
|
||||
}
|
||||
/// Given df/dT, multiply in dT/dA and continue reverse AD process
|
||||
virtual void reverseAD(const Matrix& H, JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(H * H1, jacobians);
|
||||
trace2->reverseAD(H * H2, jacobians);
|
||||
trace3->reverseAD(H * H3, jacobians);
|
||||
virtual void reverseAD(const Matrix& dFdT, JacobianMap& jacobians) const {
|
||||
trace1->reverseAD(dFdT * dTdA1, jacobians);
|
||||
trace2->reverseAD(dFdT * dTdA2, jacobians);
|
||||
trace3->reverseAD(dFdT * dTdA3, jacobians);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -560,8 +559,8 @@ public:
|
|||
trace->trace1 = this->expressionA1_->traceExecution(values);
|
||||
trace->trace2 = this->expressionA2_->traceExecution(values);
|
||||
trace->trace3 = this->expressionA3_->traceExecution(values);
|
||||
trace->t = function_(trace->trace1->value(), trace->trace2->value(), trace->trace3->value(),
|
||||
trace->H1, trace->H2, trace->H3);
|
||||
trace->t = function_(trace->trace1->value(), trace->trace2->value(),
|
||||
trace->trace3->value(), trace->dTdA1, trace->dTdA2, trace->dTdA3);
|
||||
return trace;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue