This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Passing matrix-row-segment by non-const reference

Tags: None
(comma "," separated)
NomDePlume
Registered Member
Posts
1
Karma
0
G'day all. New user of Eigen here, still learning the ropes.

I am trying to pass a segment of a row of a matrix to a function which will change the underlying data values in the actual matrix. i.e. the segment I pass around will not use a copy of the data.

A simple function for testing:
Code: Select all
template<typename Derived>  void sillyfun(MatrixBase<Derived>& arg, double fac = 2.0)
{
  arg *= fac;
}


Now in the main() routine I create some matrices. One a "normal" Matrix, the other formed by Mapping an existing buffer:
Code: Select all
  MatrixXf  M1(4,4);
  M1 << 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ;

  float buff[] = {-1,2,-3,4,10,11,12,13,-3.1,-3.2,-3.3,-3.4,11,11,11,11};
  Eigen::Map<MatrixXf> map2 = MatrixXf::Map(buff,4,4);


I can create objects which give me writable access to the underlying rows/columns as follows:
Code: Select all
  MatrixBase<MatrixXf>::ColXpr colA = M1.col(2);
  MatrixBase<Eigen::Map<MatrixXf> >::ColXpr colB = map2.col(0);


And objects giving me write access to underlying segments of rows/cols:
Code: Select all
  Eigen::Block<Eigen::Block<Eigen::MatrixXf,10000,1,1,32>,10000,1,1,32 > seg1c = M1.col(2).segment(1,2);
Eigen::Block< MatrixBase<Eigen::Map<MatrixXf> >::RowXpr, 1,10000,1,32> seg2r = map2.row(2).segment(1,2);


I can pass any of the above declared variables to my test function quite happily, and the underlying matrix values (in M1 or map2) are changed accordingly.
Code: Select all
// all these work as expexted:
sillyfun(seg1c,2.0);
sillyfun(seg2r,0.5);
sillyfun(colA,10);
sillyfun(colB,-1);


It is however extremely unwieldy to create individual variables only to provide temporary access to underlying data in a matrix. This is particularly so for the case of the row segments - look at the type declarations!

It would be nice to be able to pass row-segments into functions anonymously, e.g.
Code: Select all
sillyfun(M1.row(0), 2.0);
sillyfun(map2.col(2).segment(1,2), 5.0);

but of course C++ insists that such temporary reference arguments be const, and I want to use non-const operations on the object within my function.

So - is there a nice, easy way of selecting (not copying) regions of a matrix and passing them into a function which will change the underlying values in the original matrix?

Thanks in advance for all help.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
This is a common flaw of C++ and unfortunately there is no easy solution to that problem. In Eigen itself we have the same issue for the swap function:

mat.col(i).swap(mat.col(k));

for which we declared the argument using a const reference and then we const-cast it inside the function.

Note that C++1x solves this issue via rvalue references : http://en.wikipedia.org/wiki/C%2B%2B0x# ... _semantics.


Bookmarks



Who is online

Registered users: abc72656, Bing [Bot], Google [Bot], lockheed, Sogou [Bot], Yahoo [Bot]