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

[SOLVED] Nested block in plugin unit...

Tags: None
(comma "," separated)
Hauke
Registered Member
Posts
109
Karma
3
OS
Hi again,

I stumbled over a little issue while writing a plugin. I know where it comes from but have no clue on how to overcome the issue.

First, my motivation. Since

Code: Select all
Eigen::Matrix m(3,3);
Eigen::Matrix v = m.block(0,0,1,2);


gives me a run-time error while

Code: Select all
Eigen::Matrix m(3,3);
Eigen::Matrix v = m.row(0).range(0,2);


does not, I want to go for the latter. Putting it in my plugin, it requires nested Blocks - actually as I just learned something like Block< NestByValue< Block < .... At the moment, this is not possible because ei_traits of Blocks are not yet known in the MatrixBase.

Any ideas?

Regards,
Hauke

Last edited by Hauke on Wed Apr 08, 2009 9:04 am, edited 1 time in total.
Hauke
Registered Member
Posts
109
Karma
3
OS
Ok, I was wrong with my conclusion that the traits are not known.

Actually the problem lies in the implementation of the Block traits. Recursive Blocks are basically not possible at the moment but with the following fix, they can be made possible.

Code: Select all
template
struct ei_traits >
{
  typedef typename ei_traits::Scalar Scalar;
  typedef typename ei_nested::type MatrixTypeNested;
  typedef typename ei_unref::type _MatrixTypeNested;
  enum{
    RowsAtCompileTime = ei_traits::RowsAtCompileTime == 1 ? 1 : BlockRows,
    ColsAtCompileTime = ei_traits::ColsAtCompileTime == 1 ? 1 : BlockCols,
    MaxRowsAtCompileTime = RowsAtCompileTime == 1 ? 1
      : (BlockRows==Dynamic ? ei_traits::MaxRowsAtCompileTime : BlockRows),
    MaxColsAtCompileTime = ColsAtCompileTime == 1 ? 1
      : (BlockCols==Dynamic ? ei_traits::MaxColsAtCompileTime : BlockCols),
    RowMajor = int(ei_traits::Flags)&RowMajorBit,
    InnerSize = RowMajor ? ColsAtCompileTime : RowsAtCompileTime,
    InnerMaxSize = RowMajor ? MaxColsAtCompileTime : MaxRowsAtCompileTime,
    MaskPacketAccessBit = (InnerMaxSize == Dynamic || (InnerSize >= ei_packet_traits::size))
                        ? PacketAccessBit : 0,
    FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
    Flags = (ei_traits::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
    CoeffReadCost = ei_traits::CoeffReadCost,
    PacketAccess = _PacketAccess
  };
  typedef typename ei_meta_if&,
                 Block >::ret AlignedDerivedType;
};


I basically replaced all MatrixType type accesses by the corresponding traits, i.e.

Code: Select all
typedef typename MatrixType::Scalar Scalar;
==>
typedef typename ei_traits::Scalar Scalar;


Do you think this fix is valid and could be added to the SVN?

Regards,
Hauke
Hauke
Registered Member
Posts
109
Karma
3
OS
Sorry for messing things up like this. In the end I do not really understand what is happening. Actually, the patch should not be required since

Code: Select all
MatrixType::Scalar


should properly unapply the recursion through the typedefs in EIGEN_GENERIC_PUBLIC_INTERFACE.

Just to be complete once, I add the code to reproduce the problem.

main.cpp
Code: Select all
#define EIGEN_MATRIXBASE_PLUGIN "eigen_plugin.h"

#include "Eigen/Core"

using namespace Eigen;

int main(int argc, char* argv[])
{
   // this always compiles ... even without the patch
   typedef Matrix MatrixType;
   typedef Block::ColsAtCompileTime > RowXpr;
   typedef BlockReturnType >::SubVectorType SubVectorType;
}


eigen_plugin.h
Code: Select all
// compiles only with the patch - no clue why.
inline const typename BlockReturnType >::SubVectorType
getRow(int row, int col) const
{
   return this->row(row).nestByValue().segment(col, this->cols()-col);
}


Regards,
Hauke
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
I'm also clueless. Anyway the patch you suggested is harmless so it is fine to apply it.

Also, note that your getRow can be implemented without nesting two block expressions, you can directly write it as a single Block expression:

return Block(derived(), row, 0, col, 1, cols()-col);

that is probably better for the compiler.
Hauke
Registered Member
Posts
109
Karma
3
OS
Cool, thanks again for your support and your suggestions for optimization.

I do not know how to attach files to the post - does not seem to be possible - so I add the patch right here.

Code: Select all
Index: Block.h
===================================================================
--- Block.h   (revision 950946)
+++ Block.h   (working copy)
@@ -61,27 +61,28 @@
   *
   * sa MatrixBase::block(int,int,int,int), MatrixBase::block(int,int), class VectorBlock
   */
+
 template
 struct ei_traits >
 {
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::Nested MatrixTypeNested;
+  typedef typename ei_traits::Scalar Scalar;
+  typedef typename ei_nested::type MatrixTypeNested;
   typedef typename ei_unref::type _MatrixTypeNested;
   enum{
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime == 1 ? 1 : BlockRows,
-    ColsAtCompileTime = MatrixType::ColsAtCompileTime == 1 ? 1 : BlockCols,
+    RowsAtCompileTime = ei_traits::RowsAtCompileTime == 1 ? 1 : BlockRows,
+    ColsAtCompileTime = ei_traits::ColsAtCompileTime == 1 ? 1 : BlockCols,
     MaxRowsAtCompileTime = RowsAtCompileTime == 1 ? 1
-      : (BlockRows==Dynamic ? MatrixType::MaxRowsAtCompileTime : BlockRows),
+      : (BlockRows==Dynamic ? ei_traits::MaxRowsAtCompileTime : BlockRows),
     MaxColsAtCompileTime = ColsAtCompileTime == 1 ? 1
-      : (BlockCols==Dynamic ? MatrixType::MaxColsAtCompileTime : BlockCols),
-    RowMajor = int(MatrixType::Flags)&RowMajorBit,
+      : (BlockCols==Dynamic ? ei_traits::MaxColsAtCompileTime : BlockCols),
+    RowMajor = int(ei_traits::Flags)&RowMajorBit,
     InnerSize = RowMajor ? ColsAtCompileTime : RowsAtCompileTime,
     InnerMaxSize = RowMajor ? MaxColsAtCompileTime : MaxRowsAtCompileTime,
     MaskPacketAccessBit = (InnerMaxSize == Dynamic || (InnerSize >= ei_packet_traits::size))
                         ? PacketAccessBit : 0,
     FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
-    Flags = (MatrixType::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
-    CoeffReadCost = MatrixType::CoeffReadCost,
+    Flags = (ei_traits::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
+    CoeffReadCost = ei_traits::CoeffReadCost,
     PacketAccess = _PacketAccess
   };
   typedef typename ei_meta_if<int(PacketAccess)==ForceAligned,


- Hauke
User avatar
bjacob
Registered Member
Posts
658
Karma
3
Thanks, can you send the patch by email, either to the mailing list, or to me or Gael?


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!


Bookmarks



Who is online

Registered users: Bing [Bot], Evergrowing, Google [Bot], rblackwell