lundi 26 février 2018

reduction of eigen based templates

I am trying to do a reduction based on eigen matrix.

#include <iostream>
#include <Eigen/Dense>
#include <type_traits>

template<typename T1, typename T2, int n1, int n2>
auto reduction(Eigen::Matrix<T1, n1, n2> &a1,
               Eigen::Matrix<T2, n1, n2> &a2)
     -> decltype(T1{}*T2{})
{
  using BaseT3 = 
    typename std::remove_cv<typename std::remove_reference<decltype(T1{}*T2{})>::type>::type;

  BaseT3 res = a1(0, 0)*a2(0, 0);

  for (int i=0; i<n1; ++i)
    for (int j=0; j<n2; ++j)
      if (i+j)
        res = res + a1(i, j)*a2(i, j);

  return res;
}

int main()
{
  Eigen::Matrix<double, 3, 3> m;
  Eigen::Matrix<Eigen::Vector3d, 3, 3> n;

  std::cout << reduction(m, n) << std::endl;
}

Basically, Im a trying to get sum_{i, j} a1[i, j] * a2[i, j] where a1 and a2 are some eigen mathix but I get compilation errors. The error I get is

error: no match for ‘operator=’ (operand types are ‘BaseT3 {aka 
Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, 
const Eigen::Matrix<double, 3, 1> >}’ 
and 
‘const Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<double>, 
const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, 
const Eigen::Matrix<double, 3, 1> >, 
const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, 
const Eigen::Matrix<double, 3, 1> > >’)
         res = res + a1(i, j)*a2(i, j);
             ^

If I am not mistaken, for the given main, type BaseT3 should have been Eigen::Vector3d. I also tried to static cast so the operator= should not fail but I then get other errors.

This is c++11, I use Eigen3 and the compiler is g++ 5.4.1.

Aucun commentaire:

Enregistrer un commentaire