* allows fixed size matrix with size==0 (via a specialization of

MatrixStorage returning a null pointer). For instance this is very
  useful to make Tridiagonalization compile for 1x1 matrices
* fix LLT and eigensolver for 1x1 matrix
This commit is contained in:
Gael Guennebaud 2009-03-23 14:44:44 +00:00
parent f4cf5e9b26
commit 70c0174bf9
5 changed files with 30 additions and 7 deletions

View File

@ -103,6 +103,8 @@ void LLT<MatrixType>::compute(const MatrixType& a)
x = ei_real(a.coeff(0,0)); x = ei_real(a.coeff(0,0));
m_isPositiveDefinite = x > eps && ei_isMuchSmallerThan(ei_imag(a.coeff(0,0)), RealScalar(1)); m_isPositiveDefinite = x > eps && ei_isMuchSmallerThan(ei_imag(a.coeff(0,0)), RealScalar(1));
m_matrix.coeffRef(0,0) = ei_sqrt(x); m_matrix.coeffRef(0,0) = ei_sqrt(x);
if(size==1)
return;
m_matrix.col(0).end(size-1) = a.row(0).end(size-1).adjoint() / ei_real(m_matrix.coeff(0,0)); m_matrix.col(0).end(size-1) = a.row(0).end(size-1).adjoint() / ei_real(m_matrix.coeff(0,0));
for (int j = 1; j < size; ++j) for (int j = 1; j < size; ++j)
{ {

View File

@ -68,8 +68,8 @@ struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectA
typedef typename MatrixType::Nested MatrixTypeNested; typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum{ enum{
RowsAtCompileTime = MatrixType::RowsAtCompileTime == 1 ? 1 : BlockRows, RowsAtCompileTime = BlockRows,
ColsAtCompileTime = MatrixType::ColsAtCompileTime == 1 ? 1 : BlockCols, ColsAtCompileTime = BlockCols,
MaxRowsAtCompileTime = RowsAtCompileTime == 1 ? 1 MaxRowsAtCompileTime = RowsAtCompileTime == 1 ? 1
: (BlockRows==Dynamic ? MatrixType::MaxRowsAtCompileTime : BlockRows), : (BlockRows==Dynamic ? MatrixType::MaxRowsAtCompileTime : BlockRows),
MaxColsAtCompileTime = ColsAtCompileTime == 1 ? 1 MaxColsAtCompileTime = ColsAtCompileTime == 1 ? 1

View File

@ -534,11 +534,9 @@ class Matrix
static EIGEN_STRONG_INLINE void _check_template_params() static EIGEN_STRONG_INLINE void _check_template_params()
{ {
EIGEN_STATIC_ASSERT((_Rows > 0 EIGEN_STATIC_ASSERT(((_MaxRows >= _Rows || _Rows==Dynamic)
&& _Cols > 0 && (_MaxCols >= _Cols || _Cols==Dynamic)
&& _MaxRows <= _Rows && (_Options & (AutoAlign|RowMajor)) == _Options),
&& _MaxCols <= _Cols
&& (_Options & (AutoAlign|RowMajor)) == _Options),
INVALID_MATRIX_TEMPLATE_PARAMETERS) INVALID_MATRIX_TEMPLATE_PARAMETERS)
} }
}; };

View File

@ -85,6 +85,21 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class ei_matr
inline T *data() { return m_data.array; } inline T *data() { return m_data.array; }
}; };
// null matrix
template<typename T, int _Rows, int _Cols, int _Options> class ei_matrix_storage<T, 0, _Rows, _Cols, _Options>
{
public:
inline explicit ei_matrix_storage() {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) {}
inline ei_matrix_storage(int,int,int) {}
inline void swap(ei_matrix_storage& other) {}
inline static int rows(void) {return _Rows;}
inline static int cols(void) {return _Cols;}
inline void resize(int,int,int) {}
inline const T *data() const { return 0; }
inline T *data() { return 0; }
};
// dynamic-size matrix with fixed-size storage // dynamic-size matrix with fixed-size storage
template<typename T, int Size, int _Options> class ei_matrix_storage<T, Size, Dynamic, Dynamic, _Options> template<typename T, int Size, int _Options> class ei_matrix_storage<T, Size, Dynamic, Dynamic, _Options>
{ {

View File

@ -189,6 +189,14 @@ void SelfAdjointEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool
assert(matrix.cols() == matrix.rows()); assert(matrix.cols() == matrix.rows());
int n = matrix.cols(); int n = matrix.cols();
m_eivalues.resize(n,1); m_eivalues.resize(n,1);
if(n==1)
{
m_eivalues.coeffRef(0,0) = ei_real(matrix.coeff(0,0));
m_eivec.setOnes();
return;
}
m_eivec = matrix; m_eivec = matrix;
// FIXME, should tridiag be a local variable of this function or an attribute of SelfAdjointEigenSolver ? // FIXME, should tridiag be a local variable of this function or an attribute of SelfAdjointEigenSolver ?