- unrolled the reverseAD recursion
- MaxVirtualStaticRows is now a macro and some preprocessor derictives activate and deactivate the corresponding defintions. This could be of course removed at some point.release/4.3a0
parent
61666f22d6
commit
18a8de1f46
|
@ -36,7 +36,7 @@ class JacobianMap;
|
||||||
* MaxVirtualStaticRows defines how many separate virtual reverseAD with specific
|
* MaxVirtualStaticRows defines how many separate virtual reverseAD with specific
|
||||||
* static rows (1..MaxVirtualStaticRows) methods will be part of the CallRecord interface.
|
* static rows (1..MaxVirtualStaticRows) methods will be part of the CallRecord interface.
|
||||||
*/
|
*/
|
||||||
const int MaxVirtualStaticRows = 4;
|
#define MaxVirtualStaticRows 4
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
@ -69,65 +69,6 @@ struct ConvertToVirtualFunctionSupportedMatrixType<false> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursive definition of an interface having several purely
|
|
||||||
* virtual _reverseAD(const Eigen::Matrix<double, Rows, Cols> &, JacobianMap&)
|
|
||||||
* with Rows in 1..MaxSupportedStaticRows
|
|
||||||
*/
|
|
||||||
template<int MaxSupportedStaticRows, int Cols>
|
|
||||||
struct ReverseADInterface: ReverseADInterface<MaxSupportedStaticRows - 1, Cols> {
|
|
||||||
using ReverseADInterface<MaxSupportedStaticRows - 1, Cols>::_reverseAD;
|
|
||||||
virtual void _reverseAD(
|
|
||||||
const Eigen::Matrix<double, MaxSupportedStaticRows, Cols> & dFdT,
|
|
||||||
JacobianMap& jacobians) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int Cols>
|
|
||||||
struct ReverseADInterface<0, Cols> {
|
|
||||||
virtual void _reverseAD(
|
|
||||||
const Eigen::Matrix<double, Eigen::Dynamic, Cols> & dFdT,
|
|
||||||
JacobianMap& jacobians) const = 0;
|
|
||||||
virtual void _reverseAD(const Matrix & dFdT,
|
|
||||||
JacobianMap& jacobians) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ReverseADImplementor is a utility class used by CallRecordImplementor to
|
|
||||||
* implementing the recursive ReverseADInterface interface.
|
|
||||||
*/
|
|
||||||
template<typename Derived, int MaxSupportedStaticRows, int Cols>
|
|
||||||
struct ReverseADImplementor: ReverseADImplementor<Derived,
|
|
||||||
MaxSupportedStaticRows - 1, Cols> {
|
|
||||||
private:
|
|
||||||
using ReverseADImplementor<Derived, MaxSupportedStaticRows - 1, Cols>::_reverseAD;
|
|
||||||
virtual void _reverseAD(
|
|
||||||
const Eigen::Matrix<double, MaxSupportedStaticRows, Cols> & dFdT,
|
|
||||||
JacobianMap& jacobians) const {
|
|
||||||
static_cast<const Derived *>(this)->reverseAD(dFdT, jacobians);
|
|
||||||
}
|
|
||||||
friend struct internal::ReverseADImplementor<Derived,
|
|
||||||
MaxSupportedStaticRows + 1, Cols>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived, int Cols>
|
|
||||||
struct ReverseADImplementor<Derived, 0, Cols> : virtual internal::ReverseADInterface<
|
|
||||||
MaxVirtualStaticRows, Cols> {
|
|
||||||
private:
|
|
||||||
using internal::ReverseADInterface<MaxVirtualStaticRows, Cols>::_reverseAD;
|
|
||||||
const Derived & derived() const {
|
|
||||||
return static_cast<const Derived&>(*this);
|
|
||||||
}
|
|
||||||
virtual void _reverseAD(
|
|
||||||
const Eigen::Matrix<double, Eigen::Dynamic, Cols> & dFdT,
|
|
||||||
JacobianMap& jacobians) const {
|
|
||||||
derived().reverseAD(dFdT, jacobians);
|
|
||||||
}
|
|
||||||
virtual void _reverseAD(const Matrix & dFdT, JacobianMap& jacobians) const {
|
|
||||||
derived().reverseAD(dFdT, jacobians);
|
|
||||||
}
|
|
||||||
friend struct internal::ReverseADImplementor<Derived, 1, Cols>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,9 +79,7 @@ private:
|
||||||
* It is implemented in the function-style ExpressionNode's nested Record class below.
|
* It is implemented in the function-style ExpressionNode's nested Record class below.
|
||||||
*/
|
*/
|
||||||
template<int Cols>
|
template<int Cols>
|
||||||
struct CallRecord: virtual private internal::ReverseADInterface<
|
struct CallRecord {
|
||||||
MaxVirtualStaticRows, Cols> {
|
|
||||||
|
|
||||||
inline void print(const std::string& indent) const {
|
inline void print(const std::string& indent) const {
|
||||||
_print(indent);
|
_print(indent);
|
||||||
}
|
}
|
||||||
|
@ -153,8 +92,11 @@ struct CallRecord: virtual private internal::ReverseADInterface<
|
||||||
inline void reverseAD(const Eigen::MatrixBase<Derived> & dFdT,
|
inline void reverseAD(const Eigen::MatrixBase<Derived> & dFdT,
|
||||||
JacobianMap& jacobians) const {
|
JacobianMap& jacobians) const {
|
||||||
_reverseAD(
|
_reverseAD(
|
||||||
internal::ConvertToVirtualFunctionSupportedMatrixType<(Derived::RowsAtCompileTime > MaxVirtualStaticRows)>::convert(
|
internal::ConvertToVirtualFunctionSupportedMatrixType<
|
||||||
dFdT), jacobians);
|
(Derived::RowsAtCompileTime > MaxVirtualStaticRows)
|
||||||
|
>::convert(dFdT),
|
||||||
|
jacobians
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void reverseAD(const Matrix & dFdT, JacobianMap& jacobians) const {
|
inline void reverseAD(const Matrix & dFdT, JacobianMap& jacobians) const {
|
||||||
|
@ -167,7 +109,36 @@ struct CallRecord: virtual private internal::ReverseADInterface<
|
||||||
private:
|
private:
|
||||||
virtual void _print(const std::string& indent) const = 0;
|
virtual void _print(const std::string& indent) const = 0;
|
||||||
virtual void _startReverseAD(JacobianMap& jacobians) const = 0;
|
virtual void _startReverseAD(JacobianMap& jacobians) const = 0;
|
||||||
using internal::ReverseADInterface<MaxVirtualStaticRows, Cols>::_reverseAD;
|
|
||||||
|
virtual void _reverseAD(const Matrix & dFdT, JacobianMap& jacobians) const = 0;
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, Eigen::Dynamic, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const = 0;
|
||||||
|
#if MaxVirtualStaticRows >= 1
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 1, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const = 0;
|
||||||
|
#endif
|
||||||
|
#if MaxVirtualStaticRows >= 2
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 2, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const = 0;
|
||||||
|
#endif
|
||||||
|
#if MaxVirtualStaticRows >= 3
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 3, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const = 0;
|
||||||
|
#endif
|
||||||
|
#if MaxVirtualStaticRows >= 4
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 4, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const = 0;
|
||||||
|
#endif
|
||||||
|
#if MaxVirtualStaticRows >= 5
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 5, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const = 0;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -176,8 +147,7 @@ namespace internal {
|
||||||
* delegating to its corresponding (templated) non-virtual methods.
|
* delegating to its corresponding (templated) non-virtual methods.
|
||||||
*/
|
*/
|
||||||
template<typename Derived, int Cols>
|
template<typename Derived, int Cols>
|
||||||
struct CallRecordImplementor: public CallRecord<Cols>,
|
struct CallRecordImplementor: public CallRecord<Cols> {
|
||||||
private ReverseADImplementor<Derived, MaxVirtualStaticRows, Cols> {
|
|
||||||
private:
|
private:
|
||||||
const Derived & derived() const {
|
const Derived & derived() const {
|
||||||
return static_cast<const Derived&>(*this);
|
return static_cast<const Derived&>(*this);
|
||||||
|
@ -188,7 +158,50 @@ private:
|
||||||
virtual void _startReverseAD(JacobianMap& jacobians) const {
|
virtual void _startReverseAD(JacobianMap& jacobians) const {
|
||||||
derived().startReverseAD(jacobians);
|
derived().startReverseAD(jacobians);
|
||||||
}
|
}
|
||||||
template<typename D, int R, int C> friend struct ReverseADImplementor;
|
|
||||||
|
virtual void _reverseAD(const Matrix & dFdT, JacobianMap& jacobians) const {
|
||||||
|
derived().reverseAD(dFdT, jacobians);
|
||||||
|
}
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, Eigen::Dynamic, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const {
|
||||||
|
derived().reverseAD(dFdT, jacobians);
|
||||||
|
}
|
||||||
|
#if MaxVirtualStaticRows >= 1
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 1, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const {
|
||||||
|
derived().reverseAD(dFdT, jacobians);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if MaxVirtualStaticRows >= 2
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 2, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const {
|
||||||
|
derived().reverseAD(dFdT, jacobians);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if MaxVirtualStaticRows >= 3
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 3, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const {
|
||||||
|
derived().reverseAD(dFdT, jacobians);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if MaxVirtualStaticRows >= 4
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 4, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const {
|
||||||
|
derived().reverseAD(dFdT, jacobians);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if MaxVirtualStaticRows >= 5
|
||||||
|
virtual void _reverseAD(
|
||||||
|
const Eigen::Matrix<double, 5, Cols> & dFdT,
|
||||||
|
JacobianMap& jacobians) const {
|
||||||
|
derived().reverseAD(dFdT, jacobians);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
|
@ -90,7 +90,7 @@ struct Record: public internal::CallRecordImplementor<Record, Cols> {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived, int Rows, int OtherCols>
|
template<typename Derived, int Rows, int OtherCols>
|
||||||
friend struct internal::ReverseADImplementor;
|
friend struct internal::CallRecordImplementor;
|
||||||
};
|
};
|
||||||
|
|
||||||
JacobianMap & NJM= *static_cast<JacobianMap *>(NULL);
|
JacobianMap & NJM= *static_cast<JacobianMap *>(NULL);
|
||||||
|
|
Loading…
Reference in New Issue