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

[SOLVED] HStack(..)

Tags: None
(comma "," separated)
bomboze
Registered Member
Posts
12
Karma
0

[SOLVED] HStack(..)

Sun Jun 21, 2009 7:28 am
Hi,

I'm porting libmv to Windows and having problems with using Eigen, would appreciate help:

This is HStack() definition from libmv (horizonally stack matrices)

Code: Select all
template
Eigen::Matrix
HStack(const Eigen::Matrix  &left,
       const Eigen::Matrix &right) {


ROWS/COLS are macros for "Dynamic":

Code: Select all
#define COLS
  ((ColsLeft == Eigen::Dynamic || ColsRight == Eigen::Dynamic)
   ? Eigen::Dynamic : (ColsLeft + ColsRight))

#define ROWS
  ((RowsLeft == Eigen::Dynamic && RowsRight == Eigen::Dynamic)
   ? Eigen::Dynamic
   : ((RowsLeft == Eigen::Dynamic)
      ? RowsRight
      : RowsLeft
     )
  )


It works well if both arguments are Eigen::Matrix. Then they have

Code: Select all
HStack(R, t)


t is Vector3d.

MS VC complains:

Code: Select all
1>L:tmplibmv-devellibmv-1srclibmv/multiview/test_data_sets.h(63) : error C2784: 'Eigen::Matrix libmv::HStack(const Eigen::Matrix &,const Eigen::Matrix &)' : [b]could not deduce template argument[/b] for 'const Eigen::Matrix &' from 'libmv::Vec3'


"libmv::Vec3" is defined as "typedef Eigen::Vector3d Vec3;"

Any help would be greatly appreciated.
bomboze
Registered Member
Posts
12
Karma
0

RE: [SOLVED] HStack(..)

Sun Jun 21, 2009 8:34 am
Seems like I solved it myself.

Code: Select all
template
MatrixBase HStack(MatrixBase& lhs, MatrixBase& rhs)
{
   Derived1 res;
   res << l, r;
   return res;
};

Last edited by bomboze on Sun Jun 21, 2009 8:46 am, edited 1 time in total.
User avatar
bjacob
Registered Member
Posts
658
Karma
3

RE: [SOLVED] HStack(..)

Sun Jun 21, 2009 12:59 pm
Yep, good solution :) You may want to make the return type Derived1 automatically determined from Derived2 and Derived3, though.

Last edited by bjacob on Sun Jun 21, 2009 1:02 pm, edited 1 time in total.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
bomboze
Registered Member
Posts
12
Karma
0

RE: [SOLVED] HStack(..)

Sun Jun 21, 2009 5:01 pm
>You may want to make the return type Derived1 automatically determined from Derived2 and Derived3, though.

That's interesting. How do I do that?
User avatar
bjacob
Registered Member
Posts
658
Karma
3

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 12:33 am
bomboze wrote:>You may want to make the return type Derived1 automatically determined from Derived2 and Derived3, though.

That's interesting. How do I do that?


Something along these lines:

Code: Select all
template
struct hstack_return
{
  typedef typename Derived1::Scalar Scalar;
  enum { RowsAtCompileTime = Derived1::RowsAtCompileTime,
         ColsAtCompileTime = Derived1::ColsAtCompileTime + Derived2::ColsAtCompileTime,
         Options = Derived1::Options,
         MaxRowsAtCompileTime = Derived1::MaxRowsAtCompileTime,
         MaxColsAtCompileTime = Derived1::MaxColsAtCompileTime + Derived2::MaxColsAtCompileTime
  };
  typedef Matrix type;
};

template
typename hstack_return::type
HStack(MatrixBase& lhs, MatrixBase& rhs)
{
  typename hstack_return::type res;
  res << l, r;
  return res;
}

Last edited by bjacob on Mon Jun 22, 2009 12:35 am, edited 1 time in total.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
bomboze
Registered Member
Posts
12
Karma
0

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 8:38 am
bjacob wrote:Something along these lines:


Awesome! That works. Except for my typo in original code that should be: "res << lhs, rhs;" (instead of l,r)

Thanks!
bomboze
Registered Member
Posts
12
Karma
0

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 9:25 am
Thanks once again for the solution, Benoît, I'm growing to really love Eigen.

However I've wanted to push the things a little further and stumbled into something I don't understand about Eigen's lazy evaluation.

I've implemented HStack as operator| (VStack as operator&), so that I can do "(A|B)", but when I do "(A*B)|C" I get:

Code: Select all
'Options' : is not a member of 'Eigen::Product'


in here:

Code: Select all
  enum { RowsAtCompileTime = Derived1::RowsAtCompileTime,
         ColsAtCompileTime = Derived1::ColsAtCompileTime + Derived2::ColsAtCompileTime,
>>>         Options = Derived1::Options,
         MaxRowsAtCompileTime = Derived1::MaxRowsAtCompileTime,
         MaxColsAtCompileTime = Derived1::MaxColsAtCompileTime + Derived2::MaxColsAtCompileTime


Not a big deal, I can do the multiplication in two steps (Matrix3f E=A*B; return E|C ), but maybe there's a better way?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 10:34 am
this is because Options is specific to the class Matrix, so you can replace the line:
Code: Select all
Options = Derived1::Options,

by
Code: Select all
Options = Derived1::Flags&RowMajorBit ? RowMajor : 0,
User avatar
bjacob
Registered Member
Posts
658
Karma
3

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 2:20 pm
OOOPS !

There's something very bad in what i told you. Basically it only works for fixed-size matrices but not dynamic-size, because a line like
Code: Select all
ColsAtCompileTime = Derived1::ColsAtCompileTime + Derived2::ColsAtCompileTime

would give Dynamic+Dynamic instead of Dynamic !!!

So the solution is rather:
Code: Select all
#define SUM_OR_DYNAMIC(x,y) (x==Dynamic||y==Dynamic)?Dynamic:(x+y)
enum {
 ........
ColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::ColsAtCompileTime, Derived2::ColsAtCompileTime),
         
.........
MaxColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxColsAtCompileTime, Derived2::MaxColsAtCompileTime)
};


Also in the dynamic case I think that you must set the matrix size before you use the comma initializer:
Code: Select all
{
  typename hstack_return::type res(lhs.rows(), lhs.cols()+rhs.cols());
  ...
}

Last edited by bjacob on Mon Jun 22, 2009 2:22 pm, edited 1 time in total.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
bomboze
Registered Member
Posts
12
Karma
0

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 4:33 pm
Thanks for such extensive help!

But:

Code: Select all
Options = Derived1::Flags&RowMajorBit ? RowMajor : 0,


Code: Select all
1>z:c++_sharedhelpers_eigen.hpp(28) : error C2440: '=' : cannot convert from 'int' to ''
1>        Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)
User avatar
bjacob
Registered Member
Posts
658
Karma
3

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 4:43 pm
That's just that you need to add int(...) somewhere to convert to int (which it will then be able to auto convert to the right enum type). Try around RowMajor for instance.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
bomboze
Registered Member
Posts
12
Karma
0

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 4:52 pm
bjacob wrote:That's just that you need to add int(...) somewhere to convert to int (which it will then be able to auto convert to the right enum type). Try around RowMajor for instance.


Options = Derived1::Flags&RowMajorBit ? (int)RowMajor : 0,
error C2440: '=' : cannot convert from 'int' to ''

Options = Derived1::Flags&RowMajorBit ? int(RowMajor) : 0,
error C2440: '=' : cannot convert from 'int' to ''

Options = Derived1::Flags&RowMajorBit ? static_cast(RowMajor) : 0,
error C2440: '=' : cannot convert from 'int' to ''

Options = Derived1::Flags&RowMajorBit ? RowMajor : RowMajor, // wrong, but...
[!] error C2440: '=' : cannot convert from '' to '' // [!!!]
(So, I guess the problem is second argument, but the error message blows my brain up from '' to '' ??)

Same error:
Options = int(int(Derived1::Flags&RowMajorBit) ? RowMajor : RowMajor),
Options = int(Derived1::Flags&RowMajorBit) ? RowMajor : RowMajor,
Options = int(Derived1::Flags&RowMajorBit ? RowMajor : 0),
error C2440: '=' : cannot convert from 'int' to ''
bomboze
Registered Member
Posts
12
Karma
0

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 4:55 pm
Oh, dam, I put Options to "typedef" instead of "enum" part. The original line works! Sorry :)
User avatar
bjacob
Registered Member
Posts
658
Karma
3

RE: [SOLVED] HStack(..)

Mon Jun 22, 2009 4:56 pm
try this:

Code: Select all
Options = int(Derived1::Flags)&int(RowMajorBit) ? int(RowMajor) : 0,


EDIT: Oh OK glad that it works

Last edited by bjacob on Mon Jun 22, 2009 4:57 pm, edited 1 time in total.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
bomboze
Registered Member
Posts
12
Karma
0

Re: [SOLVED] HStack(..)

Thu Jul 02, 2009 4:06 am
Just in case somebody else tries to replicate this function, turns out you need to also res.resize(...) before comma initialization. See here: http://codereview.appspot.com/90077/dif ... :1004/1006 lines 320 (HStack), 328 (VStack)


Bookmarks



Who is online

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