[eigen] Generic conservativeResize() for both matrices and vectors? |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen <eigen@xxxxxxxxxxxxxxxxxxx>
- Subject: [eigen] Generic conservativeResize() for both matrices and vectors?
- From: Jose Luis Blanco <joseluisblancoc@xxxxxxxxx>
- Date: Fri, 26 Nov 2010 19:03:11 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:date:message-id :subject:from:to:content-type; bh=snut4Zhlm6coVUh65w7XkezsLMKZHwI+tqm6OHuJe3w=; b=eL++uQLG824yQZPYcNdM182705MfbCNfRJUjQVmtmZhFh4sw2KM4nUXim+wWxNkisl 6zqJMhyT0jlh3u1Y35d6xCpT9bX5Vs5oR09eA0tSFrIIYhoaTWzbM9Ov2VM98o2+fhQS Blfva1lgKBGcrYP+Zme54Rifu9k6XGkfUYUfQ=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=v0Nc3WKYpB7Qp4sEO1G8j49XDed68irZVQ27Lm91HbLV3DQfBDx3fzhGlpNF6b9kOr BCPf0biat3LTnCm2n0oc5fPX+Vh5VkG78n32Ou9vBGQgQOWY6k9ZFZiU2v1vQfG22lyQ RQV3FMpO8KsJ8M2Q9M+Q7JMmyjbh15X6l/VbE=
Hi again,
Writing a function that takes as argument a generic
"MatrixBase<Derived>" I found that apparently there is no easy-to-use
conservativeResize() that works for both NxM matrices and column or
row matrices (vectors). The problem is that the signature changes from
2 to 1 dimensions.
I attach a test case that shows this, with a #define that, if
declared, uses the ugly workaround I wrote.
Comment that #define line to see the build errors of this first, simple idea:
template <class Derived>
void foo( Eigen::MatrixBase<Derived> &m, int nRows, int nCols )
{
m.derived().conservativeResize(nRows,nCols);
}
With the workaround, that becomes:
detail::MatOrVecResizer<Derived::RowsAtCompileTime,Derived::ColsAtCompileTime>::doit(
m.derived(),nRows,nCols);
plus the auxiliary struct "MatOrVecResizer" and two specializations....
For me it's OK to keep this solution, but just in case: Is there any
other shorter way to deal with this in Eigen??
Best,
JL
#include <iostream>
#include <Eigen/Core>
using namespace std;
using namespace Eigen;
#define USE_WORKAROUND
#ifndef USE_WORKAROUND
// ============ The first, simple idea =============
template <class Derived>
void foo( Eigen::MatrixBase<Derived> &m, int nRows, int nCols )
{
m.derived().conservativeResize(nRows,nCols);
}
#else
// ============ The solution I found (but ugly...) ==============
namespace detail
{
// Generic version for all kind of matrices:
template<int R, int C>
struct MatOrVecResizer
{
template <typename S, int Opt, int MaxR, int MaxC>
static inline void doit(Eigen::Matrix<S,R,C,Opt,MaxR,MaxC> &mat, size_t new_rows,size_t new_cols)
{
mat.derived().conservativeResize(new_rows,new_cols);
}
};
// Specialization for column matrices:
template<int R>
struct MatOrVecResizer<R,1>
{
template <typename S, int Opt, int MaxR, int MaxC>
static inline void doit(Eigen::Matrix<S,R,1,Opt,MaxR,MaxC> &mat, size_t new_rows,size_t new_cols)
{
mat.derived().conservativeResize(new_rows);
}
};
// Specialization for row matrices:
template<int C>
struct MatOrVecResizer<1,C>
{
template <typename S, int Opt, int MaxR, int MaxC>
static inline void doit(Eigen::Matrix<S,1,C,Opt,MaxR,MaxC> &mat, size_t new_rows,size_t new_cols)
{
mat.derived().conservativeResize(new_cols);
}
};
}
template <class Derived>
void foo( Eigen::MatrixBase<Derived> &m, int nRows, int nCols )
{
detail::MatOrVecResizer<Derived::RowsAtCompileTime,Derived::ColsAtCompileTime>::doit(
m.derived(),nRows,nCols);
}
#endif
int main()
{
// This one works always:
{
Matrix<double,Dynamic,Dynamic> M;
foo(M,3,4);
cout << "M:\n"<<M << endl;
}
// These two are the problem:
{
Matrix<double,1,Dynamic> M;
foo(M,1,4);
cout << "M:\n"<<M << endl;
}
{
Matrix<double,Dynamic,1> M;
foo(M,4,1);
cout << "M:\n"<<M << endl;
}
return 0;
}