[eigen] Support for true Array |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: [eigen] Support for true Array
- From: Gael Guennebaud <gael.guennebaud@xxxxxxxxx>
- Date: Fri, 6 Nov 2009 13:58:58 +0100
- 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; bh=CxYdICuP9ckVsFm8KjfkeaGs51eveqIhaD/ODPFUZJk=; b=kFW+ytr/vsWuDT1OHndIC6X5W2OYtR4/cXGSdt2vJuE2wDUvYD62oFx1DqFRfeEnTe RAa+IACEYG6T5QJRuytZSqqp8obXbWbHptZ39hDAtMPRVp8r8eVjjmrva7/sNVjXsCLU Kq3vJVIUS6z94jr//eG6Wz1IvDz92BG1jeCI4=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=fiLr8Ixja0uiZyce2EBbKqChSvmKrM5TFuKPvxwIJGYgsFYFAMUMU0JInKTSJR+wuv HmmNCIZrkHWCEShreW1nXFIa4ImE6/axYR/lrD1tG4VnXG2KMUyeEwLdoH9kaes5m8dN iYoaHTdi4CMqj3dZQUKZ06d5x9Sk+Gj08slU4=
Hi,
I now we already have way too much modules/features which have to be polished before thinking about new features, but anyway, let me do this proposal.
Eigen has a very good support for mathematical matrices. Even though many kind of array-like operations can be performed on our matrices via the cwise() prefix, we are still lacking a true support for array of scalars. In particular, it would be very convenient to have an Array class that you could use just like a scalar value, all operations being berformed coefficient wise. I often thought about some options to Matrix/MatrixBase for that, but this is rather ugly and prone to many mistakes.
So here the idea is to mimic what is done for AutoDiffScalar, DiagonalMatrix, Quaternion, etc. Basically, the principle is wrap a MatrixBase object (a matrix or an _expression_) into a wrapper class providing a different, specialized API. In practice this is implemented by defining an ArrayBase class supporting basics operators and the math functions of the standard library (no a.sin(), but std::sin(a)). Then we define two derived classes providing the actual coefficients:
- A class Array<Scalar,Rows,Cols> providing storage and convenient ctors. It would basically store a Matrix<Scalar,RowsCols>.
- A class ArrayWrapper<_expression_> wrapping any MatrixBase _expression_ as an Array (mostly for internal use to enable _expression_ templates and, e.g., to view an existing Matrix as an Array, etc.).
To make thing even more clear, here is the implementation of operator* and std::sin:
template<typename OtherDerived>
ArrayWrapper<CwiseBinaryOp<ei_scalar_multiple_op<Scalar>, typename Derived::Coefficients, typename OtherDerived::Coefficients>
ArrayBase<Derived>::operator*(const ArrayBase<OtherDerived>& other) const
{
return matrix() * other.matrix();
}
namespace std {
template<typename Derived>
ArrayWrapper<CwiseUnaryOp<ei_scalar_sin_op<Scalar>,
typename Derived::Coefficients>
sin(const ArrayBase<Derived>& a)
{
return a.matrix().cwis().sin();
}
}
Following the AutoDiffScalar implementation, all of this can be done using a couple of macros to reduce coding and maintainability efforts.
A good thing is that can be done without any change in the core of Eigen, and so one can do it totally outside Eigen.
What do you think ?
gael.