This forum has been archived. All content is frozen. Please use KDE Discuss instead.

AutoDiff module: Matrix * Matrix does not compile

Tags: None
(comma "," separated)
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
ralf.denzer
Registered Member
Posts
6
Karma
0
OS
Hello Alex,

once more me,
did you ever tried sin(), exp() or log() etc. in the function definition?
If I do

Code: Select all
template <typename T>
T fun(Eigen::Matrix<T,Eigen::Dynamic,1> const &x){
   T y;
   y = sin(x(0));
   return y;
}


in your above example I get the runtime error

test_eigen_autodiff_2nd_derivative: /home/denzer/local/include/eigen3/Eigen/src/Core/CwiseBinaryOp.h:131: Eigen::CwiseBinaryOp<BinaryOp, Lhs, Rhs>::CwiseBinaryOp(const Lhs&, const Rhs&, const BinaryOp&) [with BinaryOp = Eigen::internal::scalar_sum_op<double>; Lhs = const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, -1, 1> >; Rhs = const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, -1, 1> >]: Assertion `lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()' failed.


Any hints?

Thanks

Ralf

PS: Sorry for capturing your topic
eacousineau
Registered Member
Posts
15
Karma
0
OS
For the sake of self-learning, I tinkered with generalizing nth-order autodiff'ing for a simple SISO case, basing off of Alex's example and some from drake:
https://github.com/RobotLocomotion/drak ... ff_types.h
https://github.com/RobotLocomotion/drak ... autodiff.h
I've uploaded the code here:
https://github.com/EricCousineau-TRI/re ... der.cc#L15

Snippets
Code: Select all
template <int order, int num_vars>
struct AutoDiffNdScalar {
    static_assert(order > 0 && order <= 4, "Must have order between 1 and 4");
    typedef typename AutoDiffNdScalar<order - 1, num_vars>::type prev_type;
    typedef Eigen::AutoDiffScalar<Eigen::Matrix<prev_type, num_vars, 1> > type;
};

// Base Case
template<int num_vars>
struct AutoDiffNdScalar<0, num_vars> {
    using type = double;
};
// Alternative: Define AutoDiffNdScalar<1, num_vars>

template <int order, int num_vars>
using AutoDiffNd = typename AutoDiffNdScalar<order, num_vars>::type;

...
    // AutoDiffNd<0, 1> x_bad(1); // Fails as expected
    AutoDiffNd<2, 1> x_taylor(1);


Will see if I can recreate your 2x2 Hessian case.
eacousineau
Registered Member
Posts
15
Karma
0
OS
In browsing this Wikipedia article:
https://en.wikipedia.org/w/index.php?ti ... _variables
One of the authors of the paper, [9] at present, (and I believe, editors of the article ;) ) linked to their source code for implementing the tensor operations mentioned for extending to nth order derivatives:
https://github.com/ZigaSajovic/dCpp
Will tinker with this over the next couple of months.

EDIT: Oops. Most likely did my math wrong, and the below reduction probably won't work.
EDIT2: Yup, it missed the inner product for the 2nd order case. Will leave this here for posterity's sake.

Also, as I was trying to generalize duplication for the 2+th order case, I think we can avoid the duplication if the class definition can be changed from:
Code: Select all
template<typename _DerType>
class AutoDiffScalar {
...
  protected:
    Scalar m_value;
    DerType m_derivatives;
};

to something more explicit:
Code: Select all
// Explicitly specify scalar value, rather than implicitly deriving from derivative
template<typename _Scalar, typename _DerType>
class AutoDiffScalar {
...
  protected:
    Scalar m_value;
    DerType m_derivatives;
};

// Keep the existing interface for any prior consumers
// - Most likely invalid C++, but hopefully it gets the point across
template<typename _DerType>
using AutoDiffScalar = template AutoDiffScalar<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar, _DerType>;


That way, instead of doing dual math like:
<<u, u'>, <u', u''>>
^ (with the present structure, kind of like ODE-style integration... but hyper redundant for 3+ orders)
we can instead just nest directly:
<u, <u', u''>>

I believe this should hold for an arbitrary number of derivatives as well.
I'll try this out over the next few days, and see if this can be turned into a potential enhancement.

I saw a template structure like this with AutoDiffVector, but given that (a) it is not included in the <unsupported/Eigen/AutoDiff>, and (b) that it appears to be syntactic sugar for grouping derivatives more concisely (at least when looking at the explicit indexing in the rest of the code), I'll try modding the original AutoDiffScalar definition.
(That, and I'm not entirely sure what AutoDiffJacobian is doing... Just started tinkering with AutoDiff in the past month.)


Bookmarks



Who is online

Registered users: abc72656, Bing [Bot], daret, Google [Bot], Sogou [Bot], Yahoo [Bot]