Re: [eigen] Overloading componentwise binary operators for vectors |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Overloading componentwise binary operators for vectors
- From: Cedric Doucet <cedric.doucet@xxxxxxxx>
- Date: Mon, 5 Oct 2015 16:00:07 +0200 (CEST)
- Thread-index: sRULBhhoTgdKk8Dm+zUiFRSusGfMfw==
- Thread-topic: Overloading componentwise binary operators for vectors
Hello Marc,
thank you for your answer.
> You don't have any constructor for Vector from an Eigen type, so
> classical_sum can't produce its result type. If you really want to write
> the type Sum, you need to replace 'Vector' with 'const WrappedType'.
> That doesn't match with the example you sent. In this case you spelled
> the signature of the operator differently enough in the forward
> declaration and in the definition that the compiler considered them 2
> different functions.
Yes, that's why classical_sum is not called in the main file.
If you look further, you will see that operator + is overloaded and returns a CwiseBinaryOp.
> That doesn't match with the example you sent. In this case you spelled
> the signature of the operator differently enough in the forward
> declaration and in the definition that the compiler considered them 2
> different functions.
Yes, you're right.
I sent this error message to Gael but it does not correspond to the simple code I sent.
Please forget about it and consider only the simple code I sent to you.
> It seems hard to both isolate yourself from Eigen and benefit from the
> expression template mechanism. If operator+ returns a Vector, you lose
> expression template benefits. If operator+ returns Eigen::CwiseBinaryOp,
> you lose the isolation. You would have to reinvent your own expression
> template mechanism and internally map it to Eigen's, it isn't worth it.
>
> Would using Eigen's types directly be such an issue? Say
> typedef Eigen::Matrix<double,Eigen::Dynamic,1> Vector;
> and you only have 1 line to change to use a different library. Ok I am
> exagerating, and you may want to wrap more advanced operations than
> addition (LU factorization?) in some traits class while still using the
> real types. You may want a second typedef for Matrix_base (which in some
> library would be the same type as Vector), but that doesn't break the
> generality.
Actually, it is very simple to get the best of both worlds if I understand how to overload operator + so that it returns Eigen::CwiseBinaryOp.
I just have to add a level of indirection by replacing Eigen::CwiseBinaryOp by a typedef coming from a template:
template<typename Wrapped>
class Vector;
template<typename Wrapped>
typename Wrapped::Sum operator+(Vector const & lhs, Vector const & rhs);
So, my question is very simple : what am I doing wrong in the code I sent to you?
----- Mail original -----
> De: "Marc Glisse" <marc.glisse@xxxxxxxx>
> À: eigen@xxxxxxxxxxxxxxxxxxx
> Envoyé: Samedi 3 Octobre 2015 05:12:25
> Objet: Re: [eigen] Overloading componentwise binary operators for vectors
>
> On Sat, 3 Oct 2015, Cedric Doucet wrote:
>
> > Here is a simple but complete example of what I want, which I hope to be
> > free of syntaxic errors.
> > I does not compile because I am not sure of what I am doing with
> > CwiseBinaryOp.
>
> You don't have any constructor for Vector from an Eigen type, so
> classical_sum can't produce its result type. If you really want to write
> the type Sum, you need to replace 'Vector' with 'const WrappedType'.
>
> > /home/cdoucet/logiciels/simol/src/core/linalg/Vector.hpp:20:37: note:
> > simol::Vector<ScalarType, WrappedLibrary> simol::operator+(const
> > simol::Vector<ScalarType, WrappedLibrary>&, const
> > simol::Vector<ScalarType, WrappedLibrary>&) [with ScalarType = double;
> > WrappedLibrary = simol::eigen]
> > Vector<ScalarType,WrappedLibrary>
> > operator+(Vector<ScalarType,WrappedLibrary> const & leftVector,
> > ^
> > /home/cdoucet/logiciels/simol/src/core/linalg/Vector.hpp:63:54: note:
> > typename WrappedLibrary<ScalarType>::OperationType simol::operator+(const
> > simol::Vector<ScalarType, WrappedLibrary>&, const
> > simol::Vector<ScalarType, WrappedLibrary>&) [with ScalarType = double;
> > WrappedLibrary = simol::eigen; typename
> > WrappedLibrary<ScalarType>::OperationType =
> > Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<double>, const
> > Eigen::Matrix<double, -1, 1>, const Eigen::Matrix<double, -1, 1> >]
> > typename WrappedLibrary<ScalarType>::OperationType
> > operator+(Vector<ScalarType,WrappedLibrary> const & leftVector,
> > ^
>
> That doesn't match with the example you sent. In this case you spelled
> the signature of the operator differently enough in the forward
> declaration and in the definition that the compiler considered them 2
> different functions.
>
> >>> This should work if your Vector class has a template constructor from
> >>> an Eigen::DenseBase<Derived>. Of course, this way you will loose the
> >>> benefits of Eigen's expression templates.
> >
> > Sure. But I don't want this.
> > My goal is to design a wrapper with minimal overhead.
> [...]
> >>> Anyways, instead of writing a wrapper, maybe extending MatrixBase<> to
> >>> add compatibility methods or inherit Matrix<> could work for you? See:
> >>> http://eigen.tuxfamily.org/dox-devel/TopicCustomizingEigen.html
> >
> > I know this very useful functionality of Eigen.
> > However, in this particular case, the main code is expected to be "weakly"
> > dependent of third-party libraries: such libraries may be replaced by
> > another ones if needed.
> > Extension would create a strong dependency between the code and Eigen.
>
> It seems hard to both isolate yourself from Eigen and benefit from the
> expression template mechanism. If operator+ returns a Vector, you lose
> expression template benefits. If operator+ returns Eigen::CwiseBinaryOp,
> you lose the isolation. You would have to reinvent your own expression
> template mechanism and internally map it to Eigen's, it isn't worth it.
>
> Would using Eigen's types directly be such an issue? Say
> typedef Eigen::Matrix<double,Eigen::Dynamic,1> Vector;
> and you only have 1 line to change to use a different library. Ok I am
> exagerating, and you may want to wrap more advanced operations than
> addition (LU factorization?) in some traits class while still using the
> real types. You may want a second typedef for Matrix_base (which in some
> library would be the same type as Vector), but that doesn't break the
> generality.
>
> --
> Marc Glisse
>
>
>