Re: [eigen] static initialization of a const Eigen::Matrix

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


On 22.08.2012 20:27, Dale Lukas Peterson wrote:
Is it possible to statically initialize a const Eigen::Matrix whose
size and entries are known at compile time?  I.e, something like:

const Eigen::Matrix<float, 2, 2> A = {1.0f, 2.0f, 3.0f, 4.0f};

The problem is that in C++03 construction by initializer list works only for PODs, especially it does not work if there is a user-declared constructor.

See this example:

#include <Eigen/Core>

struct simple2x2{
	double data[4];
	// if you enable this, initialization won't work:
#if 0
	simple2x2(double* init){
		for(int i=0; i<4; ++i) data[i] = init[i];
	}
#endif
};


int main(void) {
	simple2x2 s2 = {{1.0, 2.0, 3.0, 4.0}};
//	Eigen::Matrix2d m2 = {{1.0, 2.0, 3.0, 4.0}}; // does not compile
}



Extending the example I came up with this very hacked solution (you can templatize simple2x2 to work with other types/dimensions):

#include <Eigen/Core>

// defined elsewhere to make sure call is not inlined:
void foo(const Eigen::Matrix2d&);

struct simple2x2{
	EIGEN_ALIGN16 double data[4];
	
	operator const Eigen::Matrix2d&() const {
		return reinterpret_cast<const Eigen::Matrix2d&>(*this);
	}
};

void inittest(void) {
	static const simple2x2 s2 = {{1.0, 2.0, 3.0, 4.0}};
	static const Eigen::Matrix2d m2 = s2;
	
	foo(m2);
}

Obviously, this requires "you know what your doing", e.g., know that Matrix2d is column-major by default, the reinterpret_cast is safe, alignment properly propagates, etc.




I wrote on the forum and there was no response, and I searched the
mailing list archives but didn't find anything.  I tried variations on
the above syntax but wasn't able to get anything to work.

On the #eigen IRC channel, one user suggested:

EIGEN_ALIGN16 static const double data[]= {1.0f, 2.0f, 3.0f, 4.0f};
static const Eigen::Matrix<float, 2, 2>::ConstAlignedMapType xx(data);

In the development branch Doxygen, it looks like the Map class offers
the functionality that I'm looking for:

   static const float A_[4] = {1.0f, 2.0f, 3.0f, 4.0f};
   Map< const Matrix<float, 2, 2> > A(A_);
   std::cout << "sizeof(A_) = " << sizeof(A_) << std::endl;
   std::cout << "sizeof(A) = " << sizeof(A) << std::endl;
   std::cout << A << std::endl;

which gives the output:

sizeof(A_) = 16
sizeof(A) = 16
1 3
2 4

Can I safely assume that Map is not a copy but instead just a
convenient wrapper to the C-array and that the matrix elements are not
being copied?

Yes, it might be more obvious if you use a bigger matrix to compare the sizes. The Map class contains a pointer to the actual data and some size and stride information. Even if the latter are known at compile time, they use some space in the Map (but are never used).

I tried debugging this program and depending on the optimization
settings (g++ -O0 or -O2), it seems like the Map of the float array
may or may not result in instructions being generated.  I'm looking

Have you checked the generated assembler? You can use this macro
EIGEN_ASM_COMMENT("in order to mark lines");

for a solution that generates little to no overhead as I am on an
embedded environment where space is tight, so ideally static
initialization of the Map or Matrix instance would be performed.  I
presume there are some other member variables besides the matrix
elements that need to be initialized before it can be used, which is

For fixed size matrices there are only the data members (otherwise sizeof(A) couldn't be 16).

fine, I just want to avoid copies  of large matrices occuring, both
for space and for cpu usage considerations.

What do you mean by "large"? Do you know all its elements at compile-time? How often does initialization happen?

Are there a set of best practices established for accomplishing what I
am trying to acheive?

Jackson's Rules of Optimization:
Rule 1. Don't do it.
Rule 2 (for experts only). Don't do it yet - that is, not until you have a perfectly clear and unoptimized solution.


HTH,
Christoph


--
----------------------------------------------
Dipl.-Inf. Christoph Hertzberg
Cartesium 0.049
Universität Bremen
Enrique-Schmidt-Straße 5
28359 Bremen

Tel: +49 (421) 218-64252
----------------------------------------------



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/