Unified object for Matrix, Block, Map
@ggael
Submitted by Gael GuennebaudAssigned to Nobody
Link to original bugzilla bug (#481)
Description
Created attachment 280
a Ref<> class mapping/evaluating any expression to a unique type
This entry is related to the "Eigen Types as Parameters for Functions" thread of the ML.
The goal is to provide a way to write nom templated functions taking any expression as argument.
Before describing the solution, let's have a look at the following self-explanatory example:
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
void foo1(Ref<VectorXf> a) { }
void foo2(Ref<const VectorXf> a) { }
int main()
{
VectorXf a(10);
const VectorXf& ac(a);
VectorBlock<VectorXf> ab(a,0,3);
MatrixXf A(10,10);
const VectorBlock<VectorXf> abc(a,0,3);
foo1(a);
//foo1(ac); // does not compile because ac is const
foo1(ab);
foo1(a.head(4));
foo1(abc);
foo1(A.col(3));
foo1(A.row(3)); // copied into a temp because innerstride!=1
foo2(A*A.col(1)); // evaluated into a temp
foo2(ac.head(5));
foo2(ac);
foo2(a);
foo2(ab);
foo2(a.head(4));
foo2(a+a); // evaluated into a temp
return 0;
}
The attached file add a Ref<> class taking the same template parameters as Map<>, but in contrary to Map<>, Ref<> is designed to map any Eigen's expression. Is the expression cannot be represented as a pointer+strides then the expression is evaluated into a temporary owned by the Ref<> object. By default, for a matrix object, Ref<> allows a pointer+outerstride and imposes innerstride==1. For a vector object, Ref<> also imposes innerstride==1. The later means that a row expression of a column major matrix will be evaluated into a temp. Unless the argument is read only once, this extra copy is preferable performance wise. Of course advanced users can finely control what they want to accept, e.g.:
void foo(Ref<VectorXf,0,InnerStride<> > vec);
will accept A.row(i) without any extra copy but at the cost of slower computations regardless of the actual innerstride.
Currently one can also control the required alignment with the second template parameter:
void foo(Ref<Vector4f,Aligned> vec);
will only accept vector expressions of 4 elements sequentially stored and whose first entry is aligned on a 16bytes boundary. This is totally useless for dynamic sized expression, but might be useful for small fixed ones.
Attachment 280, "a Ref<> class mapping/evaluating any expression to a unique type":
Ref.h