[eigen] Merged eigen-storageorders

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


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
the merge.

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
when it's really safe.

#include <Eigen/QR>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
    MatrixXd m = MatrixXd::Random(10,10);
    MatrixXd x;
    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;

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