|[eigen] Merged eigen-storageorders|
[ Thread Index |
| More lists.tuxfamily.org/eigen Archives
- To: eigen <eigen@xxxxxxxxxxxxxxxxxxx>
- Subject: [eigen] Merged eigen-storageorders
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Fri, 16 Apr 2010 14:31:03 -0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:date:received:message-id :subject:from:to:content-type; bh=+MEHoh1NDwQm+SQTublUqIunDtYA/mSlJtwQvWdfIaA=; b=gUpUdI+Y4V+ojP/qBEB46h1cyRUJEjD+2RwrwfM2SwOekcSjVYdyr35RaO+p00aF6s T7Bctg2SQTUv8k+D+zMaNAlBU3hGnCds4yFZm6woYzg6FBARN5GHSZCrV9RzY6IprAZa jG9214lhiAoKHHPka1cYRjx0o/mTCnxbVkDMw=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=E4OfOyJnBg/d+F4/Ut3q11Fz+5Mk4E4czK3//qJvUu0Ip6qkp6Kn9MBUhiqQbs2Cs7 hk/YjjONIDF49BmDRC3BVuhDysbMK6nDFfCq5IfYuO4+gFVB4pJlj/IBaIk4CX5IEsa/ mATJajiFtl3NeFM//1LHNNLWBT27LPMH+tXS4=
I just merged the eigen-storageorders.
*** Main Benefits ***
A. Unit tests are no longer failing on 1x1 matrices. Actually they're
pretty much all successful now, we only have
319 - geo_transformations_3 (Failed)
422 - NonLinearOptimization (Failed)
422 is what Thomas just reported; 319 is something different, that we
need to investigate. Anyway both were failing in eigen mainline before
B. Generally speaking we now support much better the sizes 0 and 1
that had always been problematic.
C. Compilation times are improved thanks to reducing the number of
different possibilities for vector types: vectors are now required to
have the appropriate storage order, which divides by 2 the number of
possibilities. See attached file a.cpp: for me it now compiles in
6.204s versus 7.859s before. That's 25% faster. Of course I tailored
this benchmark to make my stuff look good :)
D. Improved organization of Eigen's internals, see below.
*** Main changes ***
A. New convention: vectors are now expressions where some
Max-dimension is 1, not where some dimension is 1.
---> For example, Matrix<float,Dynamic,Dynamic,0,4,1> is considered
a column-vector expression.
B. New rule: the RowMajorBit must always be set for row-vectors, and
never for column-vectors.
---> This means that there's no "bad case" anymore: no "row-vector
with col-major storage order".
---> While Eigen selects automatically the right storage order when
you give it a chance (e.g. Matrix<float,1,3>), be careful to not
explicitly select the wrong storage order! (E.g.
Matrix<float,1,Dynamic,0,1,3> is bad because it is a row-vector with
col-major order). This is guarded by a static assertion.
---> This means that there are 2x fewer possible vector types,
giving faster compiles, as discussed above.
C. Thanks to A and B, it was then possible to fix support for 1x1
matrices. A big problem was the ambiguity: is a 1x1 matrix a
row-vector or a col-vector? Wherever needed (i.e. in VectorBlock), we
now resolve this ambiguity by looking at the RowMajorBit. I also
relaxed some overly strict assertions about 0-sized objects, so these
too should now be more convenient to use.
D. Changes in the class hierarchy. Dense expressions with the
DirectAccessBit now inherit a new class DenseDirectAccessBase, that
inherits either MatrixBase or ArrayBase depending on the kind of
expression at hand. All the direct-access API, for example
innerStride(), has moved to DenseDirectAccessBase. So if you write a
function that uses this API, make sure to let it take a
DenseDirectAccessBase<Derived>, not a MatrixBase<Derived> anymore (had
to change that in FFT).
E. Classes like DenseStorageBase and MapBase, that used to take a Base
template parameter, no longer do. Instead, they automatically inherit
the right base: the information of what is the right base is provided
by ei_traits<Derived>::StorageKind (ex- StorageType).
F. Propagation of the strides at compile time. This allows to make
sure that e.g. the optimized products code only uses direct access
using namespace Eigen;
using namespace std;
MatrixXd m = MatrixXd::Random(10,10);
x = m.householderQr().solve(m);
x = m.transpose().householderQr().solve(m);
x = m.householderQr().solve(m.transpose());
x = m.transpose().householderQr().solve(m.transpose());
x = m.colPivHouseholderQr().solve(m);
x = m.transpose().colPivHouseholderQr().solve(m);
x = m.colPivHouseholderQr().solve(m.transpose());
x = m.transpose().colPivHouseholderQr().solve(m.transpose());
std::cout << x << std::endl;