[eigen] Special Matrices: first get diagonal matrices done |

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]

*To*: eigen <eigen@xxxxxxxxxxxxxxxxxxx>*Subject*: [eigen] Special Matrices: first get diagonal matrices done*From*: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>*Date*: Mon, 11 May 2009 15:39:05 +0200*Dkim-signature*: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:date:message-id:subject :from:to:content-type:content-transfer-encoding; bh=7Js5D8SQkh3Y9aDURLGbVkZQcvvBMGHkwnPxCnUPovk=; b=gA6b6tVPPoagjB4d1jBayohgpUUjFmJ6j0RMxb47YnDdUL+hyaJxYdm19WiHkPtqAw m1gQZVR20dM5Qz+tPqF2uHyU/gxItUU9Qc5nKRunNm5ScfqBKPtw0ZoI+j0sA9zrXB1L FGOo23tEtUJCzZu3yTm1WZh6vsriCDkfe+f9g=*Domainkey-signature*: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type :content-transfer-encoding; b=dzPaDpM7kxxVcmuW/6rw3YePa2J+/Z6knvE4p/9GOyHlgmlyvhc10iap1UGj3msgST 0QFcXFBApJgRYsO98SgjtkgJXKE3RH+0agvAWjI1OElGKq7ZIHFfr0ui50updCEZh69j LpR8JQSxydM07/1vszgzbYN6Bsy3ZwEaQLRF8=

Hi, Before getting started with BandedMatrix and other kinds of special matrices, I think the perfect starting point is to first nail the situation with diagonal matrices. Currently we have: * class Diagonal nests a matrix xpr and is a vector xpr * class DiagonalMatrixWrapper nests a vector xpr and is a matrix xpr * class DiagonalMatrix stores a vector and is a matrix xpr I think that we agree that we want instead DiagonalMatrix to NOT be a matrix xpr (ie NOT inherit MatrixBase) and have a coeff() method that just asserts row==col. DiagonalMatrixWrapper is still as much needed as before for situations like mat * vec.asDiagonal(); where asDiagonal() is actually just being used as a thin wrapper around the vector allowing to select the matrix product strategy. What is open for discussion is whether DiagonalMatrixWrapper should still inherit MatrixBase? And if not, should there be an AsDense kind of class constructing a MatrixBase expression out of a DiagonalMatrixWrapper without evaluating? Let me explain why I think that the answer to both questions is _no_. The solution i'm going to advocate will be to keep the same class names, only make DiagonalMatrixBase no longer inherit MatrixBase. First of all we could have a DiagonalMatrixBase::toMatrix() that returns a plain matrix (see at the end for naming discussion), so that the user who wants something that behaves like a matrix, can get a plain matrix if he wants to: cout << vec.asDiagonal().toMatrix() << endl; The argument for having instead a asDense() returning a MatrixBase, is to avoid the cost of evaluating the matrix, but then remember that this expression would have a very expensive coeff() method as it would have to do a if(row==col). So as soon as you're accessing a large part of the matrix, it's not good anyway (performance wise) to have an asDense expression here. I also think that there isn't much of a use case for doing directly "vec.asDiagonal()(i,j)" -- it's OK, i think, to force the user to replace that by "i==j?vec(i):0" making him realize where there is room for optimization. Then let's look at the main use case for asDiagonal(): mat * vec.asDiagonal() Currently, since DiagonalMatrixWrapper is a MatrixBase, we have to catch that in Product.h, adding complexity in there. If instead DiagonalMatrixWrapper were NOT a MatrixBase, we could catch that in a completely separate operator*. Less code overall and especially in Product.h, shorter compilations times, "you don't pay for what you don't use", same result. Is there anything I didn't think of? Yes that means that one could no longer do: mat * mat2.marked<DiagonalBits>() and hope for that product to be optimized, but frankly !! if you know that a matrix happens to be diagonal, then you can probably avoid storing it as a full matrix in the first place! So I don't think there's a real use case for that; and even if there were one could still do: mat * mat2.diagonal().asDiagonal(). To summarize my plan: *no more changes to Diagonal (the ex-DiagonalCoeffs) *make DiagonalMatrixBase no longer inherit MatrixBase. It doesn't even need a coeff() method. *DiagonalMatrix still inherits DiagonalMatrixBase *DiagonalMatrixWrapper still inherits DiagonalMatrixBase *DiagonalMatrixBase is the class against which we implement the operator* catching diagonal products, and by the way we can also have operator= etc. *DiagonalMatrixBase::toMatrix() returns a plain Matrix. (the last method toMatrix(), i couldn't find a nicer name: eval() suggests it returns a DiagonalMatrix, toDense() doesn't make it clear it evaluates, ...) Notice that if you are really in favor of a diagonal matrix expression, we can still add this to this scheme using multiple inheritance on MatrixBase and DiagonalMatrixBase... Cheers, Benoit

**Follow-Ups**:**Re: [eigen] Special Matrices: first get diagonal matrices done***From:*Gael Guennebaud

**Messages sorted by:**[ date | thread ]- Prev by Date:
**Re: [eigen] Statistics module** - Next by Date:
**Re: [eigen] Re: LU precision tuning** - Previous by thread:
**Re: [eigen] MappedSparseMatrix.coeff() uses RowMajor but shouldn't it be IsRowMajor** - Next by thread:
**Re: [eigen] Special Matrices: first get diagonal matrices done**

Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |