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

Is eigen::Array intended to be used as plain container?

Tags: None
(comma "," separated)
ri_aje
Registered Member
Posts
8
Karma
0
Hi, I have been using eigen for sometime. First of all, very nice work, thank you.

I am currently working on a volume rendering program. The involved mathematics of rendering naturally makes me choose eigen. In the same program, I also need to hold some non-number objects, like cl_memory (an OpenCL memory object which is a pointer to a struct). I have multiple OpenCL capable cards, and each one will have some memory objects, so on the host side, the structure naturally resembles an Eigen::Array structure, so I have this declaration in my program header file,
Code: Select all
Array<cl_memory, Dynamic, 6> MemoryObjects;

I did not do any math on this->MemoryObjects as it will not make sense. However, I do use resize(), setZero(), ..., so that Array is just a nice container. It worked well until today, I tried to output those pointers to make sure they have some meaningful values like this
Code: Select all
cout << this->MemoryObjects << endl;

And then I got a long error message. I traced the source code, including eigen's source code, to see what's wrong. I found in Core/IO.h, when eigen prints a array/matrix, it needs to determine the precision of the printed objects. And the simplified logic as I understand is that if the Scalar is a integer (determined by NumTraits<Scalar>::IsInteger which is std::numeric_limits<Scalar>::is_integer), then nothing is done; if it is not, it is assumed to be a float point number type, whose precision is determined through
Code: Select all
ei_cast<RealScalar,int>(std::ceil(-ei_log(NumTraits<RealScalar>::epsilon())/ei_log(RealScalar(10))));

which failed as you cannot apply ei_log (which is std::log for float point) on a pointer type, nor can you apply the unary - operator on pointers.

My question is, does this mean that Eigen::Array is not intended to work as a general 2D container, like std::vector for 1D case, even though it does work on numeric types? Thanks.

I understand I have other solutions, like, using other containers, doing everything by myself, or printing like this
Code: Select all
this->MemoryObjects.unaryExpr([](cl_memory x){cout<<x<<" ";});

I just want to make sure the rationale here.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Indeed, Array is intended to be container for numerical types, similarly to std::valarray. However, the error you are facing still looks like a bug to me, since a non integer type does not necessary means we can apply log (e.g., rational number).

If you want to provide a patch you're welcome since I don't know when we'll have time to handle it by ourselves....
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
ah, note that you can also specialize the structure:

ei_significant_decimals_default_impl

for pointers:

Code: Select all
template<typename T>
struct ei_significant_decimals_default_impl<T*, true>
{
  static inline int run()
  {
    return 0;
  }
};
ri_aje
Registered Member
Posts
8
Karma
0
Thanks for the clarification.

For the partial specialization way, technically, I think you need to do this to make the specialization a candidate in template instantiation, right?
Code: Select all
namespace Eigen
{
 template <typename T>
 struct ei_significant_decimals_default_impl <T*, false /* note here */>
 {
  static inline int run ()
  {
   return 0;
  }
 };
}
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
yes your version is the correct one, sorry the quick copy/paste confusion...


Bookmarks



Who is online

Registered users: Bing [Bot], blue_bullet, Google [Bot], rockscient, Yahoo [Bot]