|Re: [eigen] General design issue|
[ Thread Index |
| More lists.tuxfamily.org/eigen Archives
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] General design issue
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Fri, 13 Nov 2009 14:58:32 -0500
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=lPdbG6RVGl6cOmPWs+M3rerfJJ9VQoPZ6HU7VRyzmpg=; b=wO+NV7xa1ZvV3t4EHQf2d462+T/sj8wrQgVJdgDrMqG7LZVfeVK5TjCa22ZbgvJISC 4XMw1je/V7GCnoj2vQ6LTLk/SIQ8IvdBIZSdOkfVP2lb3fM0Wzy9T05qE4WURds34W8z NyreGYWo2o9t23+M060b3inv6wsIiC1J1tF+s=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=tVyASmZ4PZfujyJdYHmR/9RnzAf0lGR/3lGoV/ejOfofnkcZx86/aZAe6q/qrXrcYo Ysx5kazHF/wOkTbRYJGdGf2VjFlRurFa7NDvsKgarnQCrnv3L4XjOFWE0BTmm2oOnHim OThp01CwQYxmCSNv5yZ/cILn3YHhvKO667OG4=
Wow, your mail took me a lot of effort to understand, I think it's
mostly ok now...
First of all, I agree with your summary of current limitations. Yes, I
agree we must take care of that before beta1.
Let me rephrase some stuff in my own baby words to see if i got it
right. The 2 basic problems you want to address are:
* code sharing between dense and sparse xpr
* in xpr trees, only the leaves should be affected by what the leaves
The "naive" approach to that would probably be to let e.g. Transpose
and SparseTranspose inherit a common base AnyTranspose, making it a
curious base so AnyTranspose<Derived>... then .transpose() methods
should return objects of AnyTranspose<Derived> which is ugly and may
(out of empirical experience) give compiler warnings about strict
aliasing when casting the returned object to the derived type.
So your solution, if I understand well, consists instead in letting
Transpose itself be a template in one more integer parameter, which
you call StorageType, which could have special values Dense, Sparse,
At this point, I think I have understood how you solve the "the rest
of the tree doesn't completely change if the leaves are different"
But can you enlighten me as to how you solve the "code sharing"
problem? If Transpose<Dense> and Transpose<Sparse> can share code,
where do you put that? In a common base class TransposeBase? So that
problem and solution is actually completely orthogonal to the above?
2009/11/13 Gael Guennebaud <gael.guennebaud@xxxxxxxxx>:
> I'm more and more convinced that our current design of our expression
> template mechanism is still not very good and some improvements are required
> to make it more scalable to new matrix types. For instance, for sparse
> matrices I had to create clones of most of the expression classes we have in
> the Core module. E.g., there are SparseCwiseBinaryOp, SparseCwise,
> SparseTranspose, etc. Even though, e.g., CwiseBinaryOp and
> SparseCwiseBinaryOp have only very little in common, this till represent a
> non negligeable bit of code duplication. Especially the Cwise proxy class
> are essentially the same.
> Even though we would only correctly support dense and sparse matrices, there
> is still a major limitation: one cannot write the type of a generic
> expression dealing with either dense matrices or sparse matrices. For
> instance see what I had to do for the AutoDiff module: instead of simply
> writing CwiseBinaryOp<ei_scalar_sum_op<Scalar>,A,B>, I introduced a
> MakeCwiseBinaryOp<> little struct in Core/ExpressionMaker.h returning the
> correct type of a cwise binary op accoring to the kind of
> matrices/expressions we are dealing with. Such and helper class has to be
> written for every expression types and specialized for every kind of
> Likewise one cannot write generic expression analyser only because the name
> of the template class representing, e.g., a transpose operation, depends on
> the kind of matrices!
> Of course things are getting wors as we want to support new kind of matrix
> storages. You might argue that matrices with special storage are only useful
> for solving, but you always need matrix products involving scalar multiples,
> transpose, conjutage, etc. So it seems to me that finaly all kind of
> matrices need a pretty much complete support for expression templates.
> Well, all in all, I'd like to investigate some solutions to make this whole
> mess a little less messy, and yes I think this is something very important
> to do for 3.0 beta1. Well, unless someone show me the current design is
> already perfect....
> OK, so the general idea is to try to decouple the semantic of an expression
> from its implementation. E.g.: the type of 2*M should always be
> CwiseUnaryOp<ei_scalar_multiple<Scalar>, typeof(M)> even though it is
> evaluated differently according to the storage of M.
> To this end, I think we could introduce a "StorageType" integer to the
> matrix traits. We could also use the Flags, but adding a new attribute for
> that seems to be easier to use and more scalable.
> Then, each expression could inherit an implementation class where one of its
> template parameter would be the StorageType. This way one could add new
> storage type and only focuses on its implementation specificities. The
> implementation of all basics operators (all unary op, +, -, the entire
> .cwise() prefix, etc.) could be shared for all matrix types.
> Of course I'm still unsure about many of the details and I probably overseen
> a lot of difficulties, but it seems to be a saner design for the future.
> Discussions are open ;)