[CppAD] filling Eigen sparse matrix in presence of CppAD

Braun, Michael braunm at mail.smu.edu
Fri Dec 19 12:14:37 EST 2014


On Dec 19, 2014, at 1:17 AM, Braun, Michael <braunm at mail.smu.edu<mailto:braunm at mail.smu.edu>> wrote:

Following a suggestion in the Eigen support forum, I created a file eigen_sparse_plugin.h that contains the following:

typedef Scalar value_type;

template<typename S, int R, int Opt, int MR, int MC>
inline void reserve(const Matrix<S,R,Opt,MR,MC> &reserveSizes)
{
  reserveInnerVectors(reserveSizes);
}

This now appears to work after adding

#define EIGEN_SPARSEMATRIX_PLUGIN <eigen_sparse_plugin.h>

before including the Eigen headers.

I did see another post on the Eigen mailing list (not the support forum) that suggests a traits-type approach.  But maybe the best option would be to convince the Eigen folks to add the template specialization of reserve to the SparseMatrix class.  That decision is above my level of expertise.





-------- Forwarded Message --------
Subject:        Re: [CppAD] filling Eigen sparse matrix in presence of CppAD
Date:   Thu, 18 Dec 2014 05:25:54 -0700
From:   Brad Bell <bradbell at seanet.com><mailto:bradbell at seanet.com>
To:     cppad at list.coin-or.org<mailto:cppad at list.coin-or.org>, Mic >> Braun, Michael <braunm at mail.smu.edu><mailto:braunm at mail.smu.edu>


Using  g++ 4.8.3,  if you delete
    typedef Scalar value_type;
at line 24 of
    https://projects.coin-or.org/CppAD/browser/trunk/cppad/example/eigen_plugin.hpp
the error in compiling the example below goes away.

CppAD expects
    Vector::value_type
to be the type of the elements of a vector; see
    http://www.coin-or.org/CppAD/Doc/simplevector.xml#Value%20Type

This is the same as for the C++ standard vector; as can be seen by searching for value_type on
    http://www.cplusplus.com/reference/vector/vector/

I wanted to ask about this on the eigen user's list
    http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2014/12/maillist.html
but I did not see your posting there.

Brad


On 12/17/2014 11:33 AM, Braun, Michael wrote:
I posted this same question on the Eigen forum because I do not know if it is really an Eigen issue or a CppAD issue.

As part of a larger application that uses CppAD, I am trying to fill an Eigen sparse matrix.  The following MWE does not use CppAD, and when the first line (#define EIGEN_MATRIX_PLUGIN ... ) is commented out, this code runs fine.

#define EIGEN_MATRIX_PLUGIN <cppad/example/eigen_plugin.hpp>

#include <Eigen/Eigen>
#include <Eigen/Sparse>
#include <cppad/cppad.hpp>
#include <cppad/example/cppad_eigen.hpp>

void triptest () {
  typedef Eigen::Triplet<double> TT;

  int n = 5;
  std::vector<TT> trips;
  Eigen::SparseMatrix<double> M(n,n);

  for (int i=0; i<n; i++) {
    trips.push_back (TT(i,i,i*i));
  }
  M.setFromTriplets(trips.begin(), trips.end());
  std::cout << M << "\n";

}

int main (void)
{
  triptest();
  return 0;
}


But when left in, I get the following compile error:

 $ clang++ -I/opt/cppad/include -I$R_HOME/library/RcppEigen/include trips.cpp -o trips.so
In file included from trips.cpp:4:
In file included from .../Eigen/Sparse:19:
In file included from .../Eigen/SparseCore:40:
/Library/Frameworks/R.framework/Resources/library/RcppEigen/include/Eigen/src/SparseCore/SparseMatrix.h:957:11: error:
      call to member function 'reserve' is ambiguous
    trMat.reserve(wi);
    ~~~~~~^~~~~~~
.../Eigen/src/SparseCore/SparseMatrix.h:1013:13: note:
      in instantiation of function template specialization
      'Eigen::internal::set_from_triplets<std::__1::__wrap_iter<Eigen::Triplet<double, int> *>,
      Eigen::SparseMatrix<double, 0, int> >' requested here
  internal::set_from_triplets(begin, end, *this);
            ^
trips.cpp:18:5: note: in instantiation of function template specialization 'Eigen::SparseMatrix<double, 0,
      int>::setFromTriplets<std::__1::__wrap_iter<Eigen::Triplet<double, int> *> >' requested here
  M.setFromTriplets(trips.begin(), trips.end());
    ^
.../Eigen/src/SparseCore/SparseMatrix.h:270:17: note:
      candidate function [with SizesType = Eigen::Matrix<int, -1, 1, 0, -1, 1>]
    inline void reserve(const SizesType& reserveSizes, const typename SizesType::value_type& enableif = typenam...
                ^
.../Eigen/src/SparseCore/SparseMatrix.h:276:17: note:
      candidate function [with SizesType = Eigen::Matrix<int, -1, 1, 0, -1, 1>]
    inline void reserve(const SizesType& reserveSizes, const typename SizesType::Scalar& enableif =
                ^
.../Eigen/src/SparseCore/SparseMatrix.h:256:17: note:
      candidate function not viable: no known conversion from 'Matrix<Index, Dynamic, 1>' to 'Index' (aka 'int') for 1st
      argument
    inline void reserve(Index reserveSize)
                ^


Any idea what's going on?  I have been able to narrow the problem directly to that first #define.  Also, this appears to happen only with EIGEN_MATRIX_PLUGIN, and not ARRAY or SPARSEMATRIX.

Thanks,

Michael




--------------------------
Michael Braun
Associate Professor of Marketing
Cox School of Business
Southern Methodist University
Dallas, TX 75275
braunm at smu.edu<mailto:braunm at smu.edu>






_______________________________________________
CppAD mailing list
CppAD at list.coin-or.org<mailto:CppAD at list.coin-or.org>
http://list.coin-or.org/mailman/listinfo/cppad





--------------------------------------------
Michael Braun, Ph.D.
Associate Professor of Marketing
Cox School of Business
Southern Methodist University
braunm at smu.edu<mailto:braunm at smu.edu>



--------------------------
Michael Braun
Associate Professor of Marketing
Cox School of Business
Southern Methodist University
Dallas, TX 75275
braunm at smu.edu<mailto:braunm at smu.edu>



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.coin-or.org/pipermail/cppad/attachments/20141219/c88dc28e/attachment.html>


More information about the CppAD mailing list