New user self-registration is disabled due to spam. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Before reporting a bug, please make sure that your Eigen version is up-to-date!
Bug 110 - Generic assignement mechanism
Summary: Generic assignement mechanism
Status: RESOLVED FIXED
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - general (show other bugs)
Version: 3.0
Hardware: All All
: --- enhancement
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 3.3 984
  Show dependency treegraph
 
Reported: 2010-11-08 12:59 UTC by Gael Guennebaud
Modified: 2015-09-02 11:29 UTC (History)
2 users (show)



Attachments

Description Gael Guennebaud 2010-11-08 12:59:48 UTC
While thinking about bug 99, I've been thinking that the assignment operator could also be an expression... but this would means that operator= would not return a reference to the "this" object, that is probably not a very good thing. So as an alternative I'd suggest to have an Assignment<Dest,Source> class that could be partially templated even outside Eigen to support any fancy assignment. This mechanism should support +=, -=, and similar operators.

For instance, that would allow us to simplify a lot our EigenBase and return-by-value mechanisms while proposing something even more generic and powerful.
Comment 1 Gael Guennebaud 2015-03-30 18:03:37 UTC
Some updates on this entry. In the devel branch one can specialize internal::Assignment class for this purpose. Here is an example:

class MyFancyExpression : EigenBase<MyFancyExpression>{
 /* ... */
};

struct MyFancy2Dense {};

template<> struct AssignmentKind<DenseShape,MyFancyShape> { typedef MyFancy2Dense Kind; };

template<typename DstXprType, typename Functor, typename Scalar>
struct Assignment<DstXprType, MyFancyExpression, Functor, MyFancy2Dense, Scalar>
{
  EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
  {
    eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
    // do something
  }
};

It can be easily specialized for a given scalar type (via the Scalar template parameter) and assignment operators (via Functor for =, +=, /=, swap, etc.).

One difficulty is that since it is a templated class, we cannot specialize for MatrixBase<Derived> as the source or destination types because Assignment will be instantiated with 'Derived'. This limitation is mitigated by the "AssignmentKind" that is extracted from the shapes of the source/destinations. But again, we need to specialize for an exact combination of shapes. Perhaps, it would be better to refactor this class to a function allowing for more flexibility?

In this case, one could even build a hierarchy of assignment-kinds allowing to specialize at different levels? For instance, a generic fallback for MyFancy2EigenBase and a specialized version for MyFancy2Sparse.

At this stage it is also not possible to distinguish between "array" and "matrix" worlds, but I don't think this is necessary.
Comment 2 Gael Guennebaud 2015-09-02 11:29:58 UTC
Alright, at this stage I consider the current mechanism as good enough, and using template functions will introduce other difficulties anyways.

Note You need to log in before you can comment on or make changes to this bug.