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

[help] Trying to Read Code Using Eigen

Tags: None
(comma "," separated)
chad.befus
Registered Member
Posts
1
Karma
0
OS
Hi all,

I am working with some code which uses Eigen heavily. For the most part it makes sense however there are a couple complex lines which I am having trouble with.

1) The first is working with a 2 dimensional matrix of reals:
Code: Select all
_realMat = (_realMat.cwise() + _someRealValue).cwise().log() / log(10.0);
_realMat = _realMat.cwise().pow(_someOtherRealValue);


My question is: what is the underlying algo?
is it?:
Code: Select all
    for(0 <= i++ <_realMat.rows())
        for(0 <=  j++ <_realMat.cols())
            _realMat[i][j] = log(_realMat[i][j] + _someRealValue) /log(10.0)
            _realMat[i][j] = pow(_realMat[i][j], _someOtherRealValue)

or something else?

2) The Second is working with the same matrix but uses the block funtion... this one I understand even less and have spent a fair amount of time staring at (along with http://eigen.tuxfamily.org/api/classEigen_1_1Block.html) I still dont get it.
Code: Select all
for (int j = 0; j < _realMat.rows(); j++) {
    for (int i = 0; i < _realMat.cols(); i++ ) {
      _realMat(j, i) =
          _oneDimRealMat.block(j,
                       _anotherOneDimRealMat(i,0),
                       1,
                       _anotherTwoDimRealMat[i].rows()
                       ).row(0).dot(_anotherTwoDimRealMat[i].col(0));
   }
}

Again what is the underlying psuedo-algo to this?


Any help is much appreciated.

Thanks in advance.

-Chad
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
chad.befus wrote:Hi all,

I am working with some code which uses Eigen heavily. For the most part it makes sense however there are a couple complex lines which I am having trouble with.

1) The first is working with a 2 dimensional matrix of reals:
Code: Select all
_realMat = (_realMat.cwise() + _someRealValue).cwise().log() / log(10.0);
_realMat = _realMat.cwise().pow(_someOtherRealValue);


My question is: what is the underlying algo?
is it?:
Code: Select all
    for(0 <= i++ <_realMat.rows())
        for(0 <=  j++ <_realMat.cols())
            _realMat[i][j] = log(_realMat[i][j] + _someRealValue) /log(10.0)
            _realMat[i][j] = pow(_realMat[i][j], _someOtherRealValue)

or something else?



Yes this is it. Here the ".cwise()" mean that the following operation have to be performed coefficient wise. This concerns all operations for which the behavior could be confusing. For instance the following:

M = M + 2;

will most likely be interpreted as "add 2 to each coefficients" by a computer scientist, and as "A = M + 2 * Indentity" for a mathematician. So, even though "M = M.cwise() + 2" might look cumbersome, at least it is very explicit.

Note that in practice the generated loops are different: the two expressions are evaluated one after the other, and for each such an expression we detect that the coefficients are sequentially stored in memory and so we generate only a single for loop which is also explicitly vectorized when possible, etc.

Of course, the evaluation of "1/log(10)" is moved out of the loop.

Also note that these two expressions can be written as a single one. That should be more efficient.


2) The Second is working with the same matrix but uses the block funtion... this one I understand even less and have spent a fair amount of time staring at (along with http://eigen.tuxfamily.org/api/classEigen_1_1Block.html) I still dont get it.
Code: Select all
for (int j = 0; j < _realMat.rows(); j++) {
    for (int i = 0; i < _realMat.cols(); i++ ) {
      _realMat(j, i) =
          _oneDimRealMat.block(j,
                       _anotherOneDimRealMat(i,0),
                       1,
                       _anotherTwoDimRealMat[i].rows()
                       ).row(0).dot(_anotherTwoDimRealMat[i].col(0));
   }
}

Again what is the underlying psuedo-algo to this?


Oh here it seems that _anotherTwoDimRealMat is actually a vector of matrices. So "_anotherTwoDimRealMat[i].col(0)" represents the first column of the i-th matrix stored in _anotherTwoDimRealMat. The left hand side of the dot product is indeed a bit more tricky to understand because it would have been simpler to write it like this:

Code: Select all
_oneDimRealMat.row(j).segment(_anotherOneDimRealMat(i,0), _anotherTwoDimRealMat[i].rows()).dot(...)


Here you take the j-th row of _oneDimRealMat, and then pick the _anotherTwoDimRealMat[i].rows() coefficients starting from the position given by _anotherOneDimRealMat(i,0).

In the original code, the .block() function returns exactly the same part of the _oneDimRealMat matrix, but since .block() returns a matrix, they had to add .row(0) to tell Eigen that's actually a vector expression. This is because the dot product function expect vectors, not matrices. If your still unsure, here is the equivalent algo for the compuation of _realMat(j, i):

Code: Select all
_realMat(j, i) = 0;
for (int k=0; k<_anotherTwoDimRealMat[i].rows(); ++k)
  _realMat(j, i) += _oneDimRealMat(j,_anotherOneDimRealMat(i,0)+k) * _anotherTwoDimRealMat[i](k,0)


Bookmarks



Who is online

Registered users: Bing [Bot], daret, Google [Bot], sandyvee, Sogou [Bot]