30 class ExpressionFactorBinaryTest;
37 T & upAlign(T & value,
unsigned requiredAlignment = TraceAlignment) {
41 static_assert(
sizeof(T) ==
sizeof(
size_t));
42 size_t & uiValue =
reinterpret_cast<size_t &
>(value);
43 size_t misAlignment = uiValue % requiredAlignment;
45 uiValue += requiredAlignment - misAlignment;
50 T upAligned(T value,
unsigned requiredAlignment = TraceAlignment) {
51 return upAlign(value, requiredAlignment);
64 class ExpressionNode {
72 traceSize_(traceSize) {
82 virtual void print(
const std::string& indent =
"")
const = 0;
87 os <<
"Expression of type " <<
demangle(
typeid(T).name());
88 if (node.traceSize_ > 0) os <<
", trace size = " << node.traceSize_;
94 virtual std::set<Key>
keys()
const {
100 virtual void dims(std::map<Key, int>& map)
const {
104 size_t traceSize()
const {
113 char* traceStorage)
const = 0;
138 void print(
const std::string& indent =
"")
const override {
139 std::cout << indent <<
"Constant" << std::endl;
149 char* traceStorage)
const override {
160 typedef T value_type;
179 void print(
const std::string& indent =
"")
const override {
180 std::cout << indent <<
"Leaf, key = " << DefaultKeyFormatter(key_) << std::endl;
184 std::set<Key>
keys()
const override {
191 void dims(std::map<Key, int>& map)
const override {
197 return values.
at<T>(key_);
202 char* traceStorage)
const override {
204 return values.
at<T>(key_);
211 template<
class T,
class A>
217 template <
class T,
class A>
218 static void PrintJacobianAndTrace(
const std::string& indent,
219 const typename Jacobian<T, A>::type& dTdA,
221 static const Eigen::IOFormat kMatlabFormat(0, 1,
" ",
"; ",
"",
"",
"[",
"]");
222 std::cout << indent <<
"D(" <<
demangle(
typeid(T).name()) <<
")/D(" <<
demangle(
typeid(A).name())
223 <<
") = " << dTdA.format(kMatlabFormat) << std::endl;
229 template<
class T,
class A1>
233 std::shared_ptr<ExpressionNode<A1> > expression1_;
238 expression1_(e1.
root()), function_(f) {
251 void print(
const std::string& indent =
"")
const override {
252 std::cout << indent <<
"UnaryExpression" << std::endl;
253 expression1_->print(indent +
" ");
258 return function_(expression1_->value(values), {});
262 std::set<Key>
keys()
const override {
263 return expression1_->keys();
267 void dims(std::map<Key, int>& map)
const override {
268 expression1_->dims(map);
283 void print(
const std::string& indent)
const {
284 std::cout << indent <<
"UnaryExpression::Record {" << std::endl;
285 PrintJacobianAndTrace<T,A1>(indent, dTdA1, trace1);
286 std::cout << indent <<
"}" << std::endl;
303 template<
typename MatrixType>
311 char* ptr)
const override {
312 assert(reinterpret_cast<size_t>(ptr) % TraceAlignment == 0);
322 Record* record =
new (ptr)
Record(values, *expression1_, ptr);
328 return function_(record->value1, record->dTdA1);
334 template<
class T,
class A1,
class A2>
338 std::shared_ptr<ExpressionNode<A1> > expression1_;
339 std::shared_ptr<ExpressionNode<A2> > expression2_;
345 expression1_(e1.
root()), expression2_(e2.
root()), function_(f) {
351 friend class ::ExpressionFactorBinaryTest;
360 void print(
const std::string& indent =
"")
const override {
361 std::cout << indent <<
"BinaryExpression" << std::endl;
362 expression1_->print(indent +
" ");
363 expression2_->print(indent +
" ");
369 return function_(expression1_->value(values), expression2_->value(values),
374 std::set<Key>
keys()
const override {
375 std::set<Key>
keys = expression1_->keys();
376 std::set<Key> myKeys = expression2_->keys();
377 keys.insert(myKeys.begin(), myKeys.end());
382 void dims(std::map<Key, int>& map)
const override {
383 expression1_->dims(map);
384 expression2_->dims(map);
404 value2(expression2.
traceExecution(values, trace2, ptr += expression1.traceSize())) {}
407 void print(
const std::string& indent)
const {
408 std::cout << indent <<
"BinaryExpression::Record {" << std::endl;
409 PrintJacobianAndTrace<T,A1>(indent, dTdA1, trace1);
410 PrintJacobianAndTrace<T,A2>(indent, dTdA2, trace2);
411 std::cout << indent <<
"}" << std::endl;
421 template<
typename MatrixType>
430 char* ptr)
const override {
431 assert(reinterpret_cast<size_t>(ptr) % TraceAlignment == 0);
432 Record* record =
new (ptr)
Record(values, *expression1_, *expression2_, ptr);
434 return function_(record->value1, record->value2, record->dTdA1, record->dTdA2);
440 template<
class T,
class A1,
class A2,
class A3>
444 std::shared_ptr<ExpressionNode<A1> > expression1_;
445 std::shared_ptr<ExpressionNode<A2> > expression2_;
446 std::shared_ptr<ExpressionNode<A3> > expression3_;
452 expression1_(e1.
root()), expression2_(e2.
root()), expression3_(e3.
root()),
454 this->traceSize_ = upAligned(
sizeof(
Record)) +
467 void print(
const std::string& indent =
"")
const override {
468 std::cout << indent <<
"TernaryExpression" << std::endl;
469 expression1_->print(indent +
" ");
470 expression2_->print(indent +
" ");
471 expression3_->print(indent +
" ");
477 return function_(expression1_->value(values), expression2_->value(values),
478 expression3_->value(values), {}, {}, {});
482 std::set<Key>
keys()
const override {
483 std::set<Key>
keys = expression1_->keys();
484 std::set<Key> myKeys = expression2_->keys();
485 keys.insert(myKeys.begin(), myKeys.end());
486 myKeys = expression3_->keys();
487 keys.insert(myKeys.begin(), myKeys.end());
492 void dims(std::map<Key, int>& map)
const override {
493 expression1_->dims(map);
494 expression2_->dims(map);
495 expression3_->dims(map);
501 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
520 value2(expression2.
traceExecution(values, trace2, ptr += expression1.traceSize())),
521 value3(expression3.
traceExecution(values, trace3, ptr += expression2.traceSize())) {}
524 void print(
const std::string& indent)
const {
525 std::cout << indent <<
"TernaryExpression::Record {" << std::endl;
526 PrintJacobianAndTrace<T,A1>(indent, dTdA1, trace1);
527 PrintJacobianAndTrace<T,A2>(indent, dTdA2, trace2);
528 PrintJacobianAndTrace<T,A3>(indent, dTdA3, trace3);
529 std::cout << indent <<
"}" << std::endl;
540 template<
typename MatrixType>
550 char* ptr)
const override {
551 assert(reinterpret_cast<size_t>(ptr) % TraceAlignment == 0);
552 Record* record =
new (ptr)
Record(values, *expression1_, *expression2_, *expression3_, ptr);
554 return function_(record->value1, record->value2, record->value3,
555 record->dTdA1, record->dTdA2, record->dTdA3);
567 std::shared_ptr<ExpressionNode<T> > expression_;
579 void print(
const std::string& indent =
"")
const override {
580 std::cout << indent <<
"ScalarMultiplyNode" << std::endl;
581 expression_->print(indent +
" ");
586 return scalar_ * expression_->value(values);
590 std::set<Key>
keys()
const override {
591 return expression_->keys();
595 void dims(std::map<Key, int>& map)
const override {
596 expression_->dims(map);
602 typedef Eigen::Matrix<double, Dim, Dim> JacobianTT;
608 void print(
const std::string& indent)
const {
609 std::cout << indent <<
"ScalarMultiplyNode::Record {" << std::endl;
610 std::cout << indent <<
"D(" <<
demangle(
typeid(T).name()) <<
")/D(" <<
demangle(
typeid(T).name())
611 <<
") = " << scalar_dTdA << std::endl;
613 std::cout << indent <<
"}" << std::endl;
618 trace.
reverseAD1(scalar_dTdA * JacobianTT::Identity(), jacobians);
622 template <
typename MatrixType>
624 trace.
reverseAD1(dFdT * scalar_dTdA, jacobians);
630 char* ptr)
const override {
631 assert(reinterpret_cast<size_t>(ptr) % TraceAlignment == 0);
633 ptr += upAligned(
sizeof(
Record));
634 T value = expression_->traceExecution(values, record->trace, ptr);
635 ptr += expression_->traceSize();
637 record->scalar_dTdA = scalar_;
638 return scalar_ *
value;
648 std::shared_ptr<ExpressionNode<T> > expression1_;
649 std::shared_ptr<ExpressionNode<T> > expression2_;
653 this->traceSize_ = upAligned(
sizeof(
Record));
658 : expression1_(e1.root()), expression2_(e2.root()) {
667 void print(
const std::string& indent =
"")
const override {
668 std::cout << indent <<
"BinarySumNode" << std::endl;
669 expression1_->print(indent +
" ");
670 expression2_->print(indent +
" ");
675 return expression1_->value(values) + expression2_->value(values);
679 std::set<Key>
keys()
const override {
680 std::set<Key>
keys = expression1_->keys();
681 std::set<Key> myKeys = expression2_->keys();
682 keys.insert(myKeys.begin(), myKeys.end());
687 void dims(std::map<Key, int>& map)
const override {
688 expression1_->dims(map);
689 expression2_->dims(map);
698 void print(
const std::string& indent)
const {
699 std::cout << indent <<
"BinarySumNode::Record {" << std::endl;
700 trace1.
print(indent);
701 trace2.
print(indent);
702 std::cout << indent <<
"}" << std::endl;
713 template <
typename MatrixType>
723 char* ptr)
const override {
724 assert(reinterpret_cast<size_t>(ptr) % TraceAlignment == 0);
728 auto ptr1 = ptr + upAligned(
sizeof(
Record));
729 auto ptr2 = ptr1 + expression1_->traceSize();
730 return expression1_->traceExecution(values, record->trace1, ptr1) +
731 expression2_->traceExecution(values, record->trace2, ptr2);
ExpressionNode(size_t traceSize=0)
Constructor, traceSize is size of the execution trace of expression rooted here.
Definition: ExpressionNode.h:71
void print(const std::string &indent="") const override
Print.
Definition: ExpressionNode.h:138
void reverseAD4(const MatrixType &dFdT, JacobianMap &jacobians) const
Given df/dT, multiply in dT/dA and continue reverse AD process.
Definition: ExpressionNode.h:541
std::set< Key > keys() const override
Return keys that play in this expression.
Definition: ExpressionNode.h:262
void dims(std::map< Key, int > &map) const override
Return dimensions for each argument.
Definition: ExpressionNode.h:267
T value(const Values &values) const override
Return value.
Definition: ExpressionNode.h:367
meta-function to generate fixed-size JacobianTA type
Definition: ExpressionNode.h:212
T value(const Values &values) const override
Return value.
Definition: ExpressionNode.h:257
void print(const std::string &indent="") const override
Print.
Definition: ExpressionNode.h:179
void dims(std::map< Key, int > &map) const override
Return dimensions for each argument.
Definition: ExpressionNode.h:191
A non-templated config holding any types of Manifold-group elements.
Binary Expression.
Definition: ExpressionNode.h:335
const ValueType at(Key j) const
Definition: Values-inl.h:204
const std::shared_ptr< internal::ExpressionNode< T > > & root() const
Return root.
Definition: Expression-inl.h:155
ScalarMultiplyNode(double s, const Expression< T > &e)
Constructor with a unary function f, and input argument e1.
Definition: ExpressionNode.h:571
BinarySumNode(const Expression< T > &e1, const Expression< T > &e2)
Constructor with a binary function f, and two input arguments.
Definition: ExpressionNode.h:657
T traceExecution(const Values &values, ExecutionTrace< T > &trace, char *ptr) const override
Construct an execution trace for reverse AD.
Definition: ExpressionNode.h:310
void print(const std::string &indent="") const override
Print.
Definition: ExpressionNode.h:667
virtual T traceExecution(const Values &values, ExecutionTrace< T > &trace, char *traceStorage) const =0
Construct an execution trace for reverse AD.
~UnaryExpression() override
Destructor.
Definition: ExpressionNode.h:247
void print(const std::string &indent) const
Print to std::cout.
Definition: ExpressionNode.h:608
Definition: Expression.h:47
virtual void dims(std::map< Key, int > &map) const
Return dimensions for each argument, as a map.
Definition: ExpressionNode.h:100
void print(const std::string &indent="") const override
Print.
Definition: ExpressionNode.h:360
T value(const Values &values) const override
Return value.
Definition: ExpressionNode.h:585
void startReverseAD4(JacobianMap &jacobians) const
Start the reverse AD process, see comments in UnaryExpression.
Definition: ExpressionNode.h:415
Binary Sum Expression.
Definition: ExpressionNode.h:646
virtual ~ExpressionNode()
Destructor.
Definition: ExpressionNode.h:78
Vector Space concept.
Definition: VectorSpace.h:470
void print(const std::string &indent="") const override
Print.
Definition: ExpressionNode.h:579
void reverseAD1(const Eigen::MatrixBase< DerivedMatrix > &dTdA, JacobianMap &jacobians) const
Either add to Jacobians (Leaf) or propagate (Function)
Definition: ExecutionTrace.h:174
Definition: ExpressionNode.h:693
void print(const std::string &indent) const
Print to std::cout.
Definition: ExpressionNode.h:698
Definition: ExpressionNode.h:600
Definition: JacobianMap.h:32
~ConstantExpression() override
Destructor.
Definition: ExpressionNode.h:134
Definition: ExpressionNode.h:388
GTSAM_EXPORT friend std::ostream & operator<<(std::ostream &os, const ExpressionNode &node)
Streaming.
Definition: ExpressionNode.h:86
std::set< Key > keys() const override
Return keys that play in this expression.
Definition: ExpressionNode.h:679
Expression for scalar multiplication.
Definition: ExpressionNode.h:562
Record(const Values &values, const ExpressionNode< A1 > &expression1, const ExpressionNode< A2 > &expression2, char *ptr)
Construct record by calling argument expressions.
Definition: ExpressionNode.h:401
void startReverseAD1(JacobianMap &jacobians) const
Definition: ExecutionTrace.h:157
Record(const Values &values, const ExpressionNode< A1 > &expression1, char *ptr)
Construct record by calling argument expression.
Definition: ExpressionNode.h:279
~BinaryExpression() override
Destructor.
Definition: ExpressionNode.h:356
T traceExecution(const Values &values, ExecutionTrace< T > &trace, char *ptr) const override
Construct an execution trace for reverse AD.
Definition: ExpressionNode.h:722
std::string GTSAM_EXPORT demangle(const char *name)
Function to demangle type name of variable, e.g. demangle(typeid(x).name())
Unary Function Expression.
Definition: ExpressionNode.h:230
Internals for Expression.h, not for general consumption.
void dims(std::map< Key, int > &map) const override
Return dimensions for each argument.
Definition: ExpressionNode.h:492
T value(const Values &values) const override
Return value.
Definition: ExpressionNode.h:196
Record(const Values &values, const ExpressionNode< A1 > &expression1, const ExpressionNode< A2 > &expression2, const ExpressionNode< A3 > &expression3, char *ptr)
Construct record by calling 3 argument expressions.
Definition: ExpressionNode.h:516
Definition: Expression.h:40
void print(const std::string &indent) const
Print to std::cout.
Definition: ExpressionNode.h:407
T value(const Values &values) const override
Return value.
Definition: ExpressionNode.h:143
Leaf Expression, if no chart is given, assume default chart and value_type is just the plain value...
Definition: ExpressionNode.h:159
void startReverseAD4(JacobianMap &jacobians) const
Start the reverse AD process.
Definition: ExpressionNode.h:290
Definition: ExpressionNode.h:272
void dims(std::map< Key, int > &map) const override
Return dimensions for each argument.
Definition: ExpressionNode.h:382
void print(const std::string &indent) const
Print to std::cout.
Definition: ExpressionNode.h:524
virtual void print(const std::string &indent="") const =0
Print.
void startReverseAD4(JacobianMap &jacobians) const
If the BinarySumExpression is the root, we just start as many pipelines as there are terms...
Definition: ExpressionNode.h:706
void dims(std::map< Key, int > &map) const override
Return dimensions for each argument.
Definition: ExpressionNode.h:687
void print(const std::string &indent="") const override
Print.
Definition: ExpressionNode.h:467
Definition: chartTesting.h:28
T traceExecution(const Values &values, ExecutionTrace< T > &trace, char *ptr) const override
Construct an execution trace for reverse AD, see UnaryExpression for explanation. ...
Definition: ExpressionNode.h:549
T traceExecution(const Values &values, ExecutionTrace< T > &trace, char *ptr) const override
Construct an execution trace for reverse AD.
Definition: ExpressionNode.h:629
void print(const std::string &indent="") const
Print.
Definition: ExecutionTrace.h:132
Definition: ExpressionNode.h:499
void setFunction(CallRecord< Dim > *record)
Take ownership of pointer to a Function Record.
Definition: ExecutionTrace.h:126
Ternary Expression.
Definition: ExpressionNode.h:441
void reverseAD4(const MatrixType &dFdT, JacobianMap &jacobians) const
If we are not the root, we simply pass on the adjoint matrix dFdT to all terms.
Definition: ExpressionNode.h:714
std::set< Key > keys() const override
Return keys that play in this expression.
Definition: ExpressionNode.h:374
T traceExecution(const Values &values, ExecutionTrace< T > &trace, char *ptr) const override
Construct an execution trace for reverse AD, see UnaryExpression for explanation. ...
Definition: ExpressionNode.h:429
~BinarySumNode() override
Destructor.
Definition: ExpressionNode.h:664
~LeafExpression() override
Destructor.
Definition: ExpressionNode.h:175
T traceExecution(const Values &values, ExecutionTrace< T > &trace, char *traceStorage) const override
Construct an execution trace for reverse AD.
Definition: ExpressionNode.h:201
~TernaryExpression() override
Destructor.
Definition: ExpressionNode.h:463
virtual std::set< Key > keys() const
Return keys that play in this expression as a set.
Definition: ExpressionNode.h:94
void reverseAD4(const MatrixType &dFdT, JacobianMap &jacobians) const
Given df/dT, multiply in dT/dA and continue reverse AD process.
Definition: ExpressionNode.h:422
std::set< Key > keys() const override
Return keys that play in this expression.
Definition: ExpressionNode.h:590
virtual T value(const Values &values) const =0
Return value.
T value(const Values &values) const override
Return value.
Definition: ExpressionNode.h:475
void startReverseAD4(JacobianMap &jacobians) const
Start the reverse AD process.
Definition: ExpressionNode.h:617
void dims(std::map< Key, int > &map) const override
Return dimensions for each argument.
Definition: ExpressionNode.h:595
#define GTSAM_MAKE_ALIGNED_OPERATOR_NEW
Definition: types.h:284
Execution trace for expressions.
~ScalarMultiplyNode() override
Destructor.
Definition: ExpressionNode.h:576
void startReverseAD4(JacobianMap &jacobians) const
Start the reverse AD process, see comments in Base.
Definition: ExpressionNode.h:533
void print(const std::string &indent) const
Print to std::cout.
Definition: ExpressionNode.h:283
T traceExecution(const Values &values, ExecutionTrace< T > &trace, char *traceStorage) const override
Construct an execution trace for reverse AD.
Definition: ExpressionNode.h:148
std::set< Key > keys() const override
Return keys that play in this expression.
Definition: ExpressionNode.h:184
void setLeaf(Key key)
Change pointer to a Leaf Record.
Definition: ExecutionTrace.h:120
std::set< Key > keys() const override
Return keys that play in this expression.
Definition: ExpressionNode.h:482
Definition: Expression.h:39
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:102
void print(const std::string &indent="") const override
Print.
Definition: ExpressionNode.h:251
T value(const Values &values) const override
Return value.
Definition: ExpressionNode.h:674
size_t traceSize() const
Return size needed for memory buffer in traceExecution.
Definition: Expression-inl.h:160
void reverseAD4(const MatrixType &dFdT, JacobianMap &jacobians) const
Given df/dT, multiply in dT/dA and continue reverse AD process.
Definition: ExpressionNode.h:304
void reverseAD4(const MatrixType &dFdT, JacobianMap &jacobians) const
Given df/dT, multiply in dT/dA and continue reverse AD process.
Definition: ExpressionNode.h:623
Definition: CallRecord.h:140
Constant Expression.
Definition: ExpressionNode.h:119