- make MatrixBase and all expressions aware of their preferred traversal order.

Honor this preference in operator=.
- add several methods to the API
- rework API for diagonal matrices
- add benchmarking code
This commit is contained in:
Benoit Jacob
2008-01-05 10:57:14 +00:00
parent 23ffede3d0
commit d1d55e67e9
33 changed files with 354 additions and 84 deletions

View File

@@ -27,28 +27,25 @@
#ifndef EIGEN_OPERATOREQUALS_H
#define EIGEN_OPERATOREQUALS_H
template<typename Derived1, typename Derived2, int UnrollCount, int Rows>
template<typename Derived1, typename Derived2, int UnrollCount, TraversalOrder Order>
struct MatrixOperatorEqualsUnroller
{
static const int col = (UnrollCount-1) / Rows;
static const int row = (UnrollCount-1) % Rows;
static const int col = (Order == ColumnMajor)
? (UnrollCount-1) / Derived1::RowsAtCompileTime
: (UnrollCount-1) % Derived1::ColsAtCompileTime;
static const int row = (Order == ColumnMajor)
? (UnrollCount-1) % Derived1::RowsAtCompileTime
: (UnrollCount-1) / Derived1::ColsAtCompileTime;
static void run(Derived1 &dst, const Derived2 &src)
{
MatrixOperatorEqualsUnroller<Derived1, Derived2, UnrollCount-1, Rows>::run(dst, src);
MatrixOperatorEqualsUnroller<Derived1, Derived2, UnrollCount-1, Order>::run(dst, src);
dst.coeffRef(row, col) = src.coeff(row, col);
}
};
// prevent buggy user code from causing an infinite recursion
template<typename Derived1, typename Derived2, int UnrollCount>
struct MatrixOperatorEqualsUnroller<Derived1, Derived2, UnrollCount, 0>
{
static void run(Derived1 &, const Derived2 &) {}
};
template<typename Derived1, typename Derived2, int Rows>
struct MatrixOperatorEqualsUnroller<Derived1, Derived2, 1, Rows>
template<typename Derived1, typename Derived2, TraversalOrder Order>
struct MatrixOperatorEqualsUnroller<Derived1, Derived2, 1, Order>
{
static void run(Derived1 &dst, const Derived2 &src)
{
@@ -56,8 +53,15 @@ struct MatrixOperatorEqualsUnroller<Derived1, Derived2, 1, Rows>
}
};
template<typename Derived1, typename Derived2, int Rows>
struct MatrixOperatorEqualsUnroller<Derived1, Derived2, Dynamic, Rows>
// prevent buggy user code from causing an infinite recursion
template<typename Derived1, typename Derived2, TraversalOrder Order>
struct MatrixOperatorEqualsUnroller<Derived1, Derived2, 0, Order>
{
static void run(Derived1 &, const Derived2 &) {}
};
template<typename Derived1, typename Derived2, TraversalOrder Order>
struct MatrixOperatorEqualsUnroller<Derived1, Derived2, Dynamic, Order>
{
static void run(Derived1 &, const Derived2 &) {}
};
@@ -101,7 +105,8 @@ template<typename OtherDerived>
Derived& MatrixBase<Scalar, Derived>
::operator=(const MatrixBase<Scalar, OtherDerived>& other)
{
if(IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime) // copying a vector expression into a vector
if(IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime)
// copying a vector expression into a vector
{
assert(size() == other.size());
if(EIGEN_UNROLLED_LOOPS && SizeAtCompileTime != Dynamic && SizeAtCompileTime <= 25)
@@ -113,17 +118,24 @@ Derived& MatrixBase<Scalar, Derived>
coeffRef(i) = other.coeff(i);
return *static_cast<Derived*>(this);
}
else // all other cases (typically, but not necessarily, copying a matrix)
else // copying a matrix expression into a matrix
{
assert(rows() == other.rows() && cols() == other.cols());
if(EIGEN_UNROLLED_LOOPS && SizeAtCompileTime != Dynamic && SizeAtCompileTime <= 25)
MatrixOperatorEqualsUnroller
<Derived, OtherDerived, SizeAtCompileTime, RowsAtCompileTime>::run
<Derived, OtherDerived, SizeAtCompileTime, Order>::run
(*static_cast<Derived*>(this), *static_cast<const OtherDerived*>(&other));
else
for(int j = 0; j < cols(); j++) //traverse in column-dominant order
{
if(Order == ColumnMajor)
for(int j = 0; j < cols(); j++)
for(int i = 0; i < rows(); i++)
coeffRef(i, j) = other.coeff(i, j);
else // RowMajor
for(int i = 0; i < rows(); i++)
coeffRef(i, j) = other.coeff(i, j);
for(int j = 0; j < cols(); j++)
coeffRef(i, j) = other.coeff(i, j);
}
return *static_cast<Derived*>(this);
}
}