Registered Member
|
I've been working on ways to try to get 1x1 (fixed size) matrix types to convert to and from the corresponding scalar type...in my case, the objective was to allow generalized function objects, but I think it could be generally useful. I basically wanted to be able to write things like
and have it work for both scalars and vector types, e.g.,
plus be able to do fun stuff like
After trying a bunch of different approaches, I think I eventually managed to find a reasonably elegant solution using EIGEN_MATRIXBASE_PLUGIN, EIGEN_MATRIX_PLUGIN, and a bit of template trickery. My EIGEN_MATRIXBASE_PLUGIN looks like
my EIGEN_MATRIX_PLUGIN looks like
and before including any Eigen headers I define
The end effect is that a MatrixBase of size 1 has a conversion operator to Scalar, and any other sized MatrixBase class has a conversion operator to DummyScalar (which is basically not a conversion operator at all, because you can't do anything with a DummyScalar). Similarly, only MatrixBase objects of size 1 can have Scalar objects assigned to them, and only Matrix objects of size 1 can be implicitly constructed from Scalar objects. Note that none of the functions involving DummyScalar objects would actually compile, since for example the line
wouldn't make sense when 'value' is a DummyScalar, but this is OK because template class members that are never used don't have to be able to compile. Thoughts? My (admittedly very few) initial tests seem to show that this works, but I'd love to hear about cases where it could fail or cause other problems. Also, are there ways to try to eliminate any overhead resulting from wrapping scalars in 1x1 matrices, i.e., ways to make sure the resulting code compiles right down to scalar operations? |
Registered Member
|
Oops - just realized operator= doesn't really work, since it can't be inherited (unlike conversion operators). I got assignment to work by some hackery in my EIGEN_MATRIXBASE_PLUGIN, redefining the EIGEN_INHERIT_ASSIGNMENT_OPERATORS so that any subclass that used the macro also got an assignment operator:
but it seems pretty ugly (I also don't know why, but trying to use EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, =) doesn't work). |
Moderator
|
we are currently talking about such a feature on the ML:
Have you looked at the array class ? isn't it enough for your needs ? |
Registered Member
|
Yeah, I ran into the ambiguous-operator problem as well...I ended up making a specialization of the Matrix template for 1x1 matrices and did NOT derive it from MatrixBase (instead just implementing all the functions separately, which is quite trivial when the matrix is a scalar!). The disadvantage is that generic functions could not be written to take a MatrixBase<Derived>.
That worked, but all this and other related template magic in my code made my compile times shoot through the roof (my fault, not Eigen's). So instead of having templated functions that could take matrices of different sizes as well as scalar types, I switched to just using dynamic-sized matrices and explcitly converting to and from scalar types when necessary. I added a .scalar() function to MatrixBase which just does an assert and then calls operator()(0, 0); I was also going to add a static Scalar() function, but then realized that would clash with the template parameter. The Array class looks very promising, although I was going to wait until the first beta before switching over to Eigen 3... |
Registered users: Bing [Bot], Google [Bot], Sogou [Bot]