remove 1 useless layer of functions

This commit is contained in:
Benoit Jacob 2009-10-26 12:30:29 -04:00
parent ec02388a5d
commit 07d1bcffda

View File

@ -25,9 +25,56 @@
#ifndef EIGEN_INVERSE_H #ifndef EIGEN_INVERSE_H
#define EIGEN_INVERSE_H #define EIGEN_INVERSE_H
/******************************************************************** /**********************************
*** Part 1 : optimized implementations for fixed-size 2,3,4 cases *** *** General case implementation ***
********************************************************************/ **********************************/
template<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime>
struct ei_compute_inverse
{
static inline void run(const MatrixType& matrix, ResultType& result)
{
result = matrix.partialLu().inverse();
}
};
template<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime>
struct ei_compute_inverse_and_det_with_check { /* nothing! general case not supported. */ };
/****************************
*** Size 1 implementation ***
****************************/
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 1>
{
static inline void run(const MatrixType& matrix, ResultType& result)
{
typedef typename MatrixType::Scalar Scalar;
result.coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0);
}
};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 1>
{
static inline void run(
const MatrixType& matrix,
const typename MatrixType::RealScalar& absDeterminantThreshold,
ResultType& result,
typename ResultType::Scalar& determinant,
bool& invertible
)
{
determinant = matrix.coeff(0,0);
invertible = ei_abs(determinant) > absDeterminantThreshold;
if(invertible) result.coeffRef(0,0) = typename ResultType::Scalar(1) / determinant;
}
};
/****************************
*** Size 2 implementation ***
****************************/
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
inline void ei_compute_inverse_size2_helper( inline void ei_compute_inverse_size2_helper(
@ -41,29 +88,39 @@ inline void ei_compute_inverse_size2_helper(
} }
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
inline void ei_compute_inverse_size2(const MatrixType& matrix, ResultType& result) struct ei_compute_inverse<MatrixType, ResultType, 2>
{ {
static inline void run(const MatrixType& matrix, ResultType& result)
{
typedef typename ResultType::Scalar Scalar; typedef typename ResultType::Scalar Scalar;
const Scalar invdet = typename MatrixType::Scalar(1) / matrix.determinant(); const Scalar invdet = typename MatrixType::Scalar(1) / matrix.determinant();
ei_compute_inverse_size2_helper(matrix, invdet, result); ei_compute_inverse_size2_helper(matrix, invdet, result);
} }
};
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
inline void ei_compute_inverse_and_det_size2_with_check( struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 2>
{
static inline void run(
const MatrixType& matrix, const MatrixType& matrix,
const typename MatrixType::RealScalar& absDeterminantThreshold, const typename MatrixType::RealScalar& absDeterminantThreshold,
ResultType& inverse, ResultType& inverse,
typename ResultType::Scalar& determinant, typename ResultType::Scalar& determinant,
bool& invertible bool& invertible
) )
{ {
typedef typename ResultType::Scalar Scalar; typedef typename ResultType::Scalar Scalar;
determinant = matrix.determinant(); determinant = matrix.determinant();
invertible = ei_abs(determinant) > absDeterminantThreshold; invertible = ei_abs(determinant) > absDeterminantThreshold;
if(!invertible) return; if(!invertible) return;
const Scalar invdet = Scalar(1) / determinant; const Scalar invdet = Scalar(1) / determinant;
ei_compute_inverse_size2_helper(matrix, invdet, inverse); ei_compute_inverse_size2_helper(matrix, invdet, inverse);
} }
};
/****************************
*** Size 3 implementation ***
****************************/
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
void ei_compute_inverse_size3_helper( void ei_compute_inverse_size3_helper(
@ -82,10 +139,10 @@ void ei_compute_inverse_size3_helper(
} }
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
void ei_compute_inverse_size3( struct ei_compute_inverse<MatrixType, ResultType, 3>
const MatrixType& matrix,
ResultType& result)
{ {
static inline void run(const MatrixType& matrix, ResultType& result)
{
typedef typename ResultType::Scalar Scalar; typedef typename ResultType::Scalar Scalar;
Matrix<Scalar,3,1> cofactors_col0; Matrix<Scalar,3,1> cofactors_col0;
cofactors_col0.coeffRef(0) = matrix.minor(0,0).determinant(); cofactors_col0.coeffRef(0) = matrix.minor(0,0).determinant();
@ -94,17 +151,20 @@ void ei_compute_inverse_size3(
const Scalar det = (cofactors_col0.cwise()*matrix.col(0)).sum(); const Scalar det = (cofactors_col0.cwise()*matrix.col(0)).sum();
const Scalar invdet = Scalar(1) / det; const Scalar invdet = Scalar(1) / det;
ei_compute_inverse_size3_helper(matrix, invdet, cofactors_col0, result); ei_compute_inverse_size3_helper(matrix, invdet, cofactors_col0, result);
} }
};
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
void ei_compute_inverse_and_det_size3_with_check( struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 3>
{
static inline void run(
const MatrixType& matrix, const MatrixType& matrix,
const typename MatrixType::RealScalar& absDeterminantThreshold, const typename MatrixType::RealScalar& absDeterminantThreshold,
ResultType& inverse, ResultType& inverse,
typename ResultType::Scalar& determinant, typename ResultType::Scalar& determinant,
bool& invertible bool& invertible
) )
{ {
typedef typename ResultType::Scalar Scalar; typedef typename ResultType::Scalar Scalar;
Matrix<Scalar,3,1> cofactors_col0; Matrix<Scalar,3,1> cofactors_col0;
cofactors_col0.coeffRef(0) = matrix.minor(0,0).determinant(); cofactors_col0.coeffRef(0) = matrix.minor(0,0).determinant();
@ -115,7 +175,12 @@ void ei_compute_inverse_and_det_size3_with_check(
if(!invertible) return; if(!invertible) return;
const Scalar invdet = Scalar(1) / determinant; const Scalar invdet = Scalar(1) / determinant;
ei_compute_inverse_size3_helper(matrix, invdet, cofactors_col0, inverse); ei_compute_inverse_size3_helper(matrix, invdet, cofactors_col0, inverse);
} }
};
/****************************
*** Size 4 implementation ***
****************************/
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
void ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType& result) void ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType& result)
@ -136,7 +201,7 @@ void ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType& resul
typedef Block<ResultType,2,2> XprBlock22; typedef Block<ResultType,2,2> XprBlock22;
typedef typename MatrixBase<XprBlock22>::PlainMatrixType Block22; typedef typename MatrixBase<XprBlock22>::PlainMatrixType Block22;
Block22 P_inverse; Block22 P_inverse;
ei_compute_inverse_size2(matrix.template block<2,2>(0,0), P_inverse); ei_compute_inverse<XprBlock22, Block22>::run(matrix.template block<2,2>(0,0), P_inverse);
const Block22 Q = matrix.template block<2,2>(0,2); const Block22 Q = matrix.template block<2,2>(0,2);
const Block22 P_inverse_times_Q = P_inverse * Q; const Block22 P_inverse_times_Q = P_inverse * Q;
const XprBlock22 R = matrix.template block<2,2>(2,0); const XprBlock22 R = matrix.template block<2,2>(2,0);
@ -145,7 +210,7 @@ void ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType& resul
const XprBlock22 S = matrix.template block<2,2>(2,2); const XprBlock22 S = matrix.template block<2,2>(2,2);
const Block22 X = S - R_times_P_inverse_times_Q; const Block22 X = S - R_times_P_inverse_times_Q;
Block22 Y; Block22 Y;
ei_compute_inverse_size2(X, Y); ei_compute_inverse<Block22, Block22>::run(X, Y);
result.template block<2,2>(2,2) = Y; result.template block<2,2>(2,2) = Y;
result.template block<2,2>(2,0) = - Y * R_times_P_inverse; result.template block<2,2>(2,0) = - Y * R_times_P_inverse;
const Block22 Z = P_inverse_times_Q * Y; const Block22 Z = P_inverse_times_Q * Y;
@ -154,8 +219,10 @@ void ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType& resul
} }
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
void ei_compute_inverse_size4(const MatrixType& _matrix, ResultType& result) struct ei_compute_inverse<MatrixType, ResultType, 4>
{ {
static inline void run(const MatrixType& _matrix, ResultType& result)
{
typedef typename ResultType::Scalar Scalar; typedef typename ResultType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::RealScalar RealScalar;
@ -190,71 +257,29 @@ void ei_compute_inverse_size4(const MatrixType& _matrix, ResultType& result)
// in the reverse order on the inverse // in the reverse order on the inverse
result.col(1).swap(result.col(good_row1)); result.col(1).swap(result.col(good_row1));
result.col(0).swap(result.col(good_row0)); result.col(0).swap(result.col(good_row0));
} }
};
template<typename MatrixType, typename ResultType> template<typename MatrixType, typename ResultType>
void ei_compute_inverse_and_det_size4_with_check( struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 4>
{
static inline void run(
const MatrixType& matrix, const MatrixType& matrix,
const typename MatrixType::RealScalar& absDeterminantThreshold, const typename MatrixType::RealScalar& absDeterminantThreshold,
ResultType& result, ResultType& inverse,
typename ResultType::Scalar& determinant, typename ResultType::Scalar& determinant,
bool& invertible bool& invertible
) )
{ {
determinant = matrix.determinant(); determinant = matrix.determinant();
invertible = ei_abs(determinant) > absDeterminantThreshold; invertible = ei_abs(determinant) > absDeterminantThreshold;
if(invertible) ei_compute_inverse_size4(matrix, result); if(invertible) ei_compute_inverse<MatrixType, ResultType>::run(matrix, inverse);
}
/***********************************************
*** Part 2 : selectors and MatrixBase methods ***
***********************************************/
template<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime>
struct ei_compute_inverse
{
static inline void run(const MatrixType& matrix, ResultType& result)
{
result = matrix.partialLu().inverse();
} }
}; };
template<typename MatrixType, typename ResultType> /*************************
struct ei_compute_inverse<MatrixType, ResultType, 1> *** MatrixBase methods ***
{ *************************/
static inline void run(const MatrixType& matrix, ResultType& result)
{
typedef typename MatrixType::Scalar Scalar;
result.coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0);
}
};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 2>
{
static inline void run(const MatrixType& matrix, ResultType& result)
{
ei_compute_inverse_size2(matrix, result);
}
};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 3>
{
static inline void run(const MatrixType& matrix, ResultType& result)
{
ei_compute_inverse_size3(matrix, result);
}
};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 4>
{
static inline void run(const MatrixType& matrix, ResultType& result)
{
ei_compute_inverse_size4(matrix, result);
}
};
/** \lu_module /** \lu_module
* *
@ -291,79 +316,6 @@ inline const typename MatrixBase<Derived>::PlainMatrixType MatrixBase<Derived>::
return result; return result;
} }
/********************************************
* Compute inverse with invertibility check *
*******************************************/
template<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime>
struct ei_compute_inverse_and_det_with_check {};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 1>
{
static inline void run(
const MatrixType& matrix,
const typename MatrixType::RealScalar& absDeterminantThreshold,
ResultType& result,
typename ResultType::Scalar& determinant,
bool& invertible
)
{
determinant = matrix.coeff(0,0);
invertible = ei_abs(determinant) > absDeterminantThreshold;
if(invertible) result.coeffRef(0,0) = typename ResultType::Scalar(1) / determinant;
}
};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 2>
{
static inline void run(
const MatrixType& matrix,
const typename MatrixType::RealScalar& absDeterminantThreshold,
ResultType& result,
typename ResultType::Scalar& determinant,
bool& invertible
)
{
ei_compute_inverse_and_det_size2_with_check
(matrix, absDeterminantThreshold, result, determinant, invertible);
}
};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 3>
{
static inline void run(
const MatrixType& matrix,
const typename MatrixType::RealScalar& absDeterminantThreshold,
ResultType& result,
typename ResultType::Scalar& determinant,
bool& invertible
)
{
ei_compute_inverse_and_det_size3_with_check
(matrix, absDeterminantThreshold, result, determinant, invertible);
}
};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 4>
{
static inline void run(
const MatrixType& matrix,
const typename MatrixType::RealScalar& absDeterminantThreshold,
ResultType& result,
typename ResultType::Scalar& determinant,
bool& invertible
)
{
ei_compute_inverse_and_det_size4_with_check
(matrix, absDeterminantThreshold, result, determinant, invertible);
}
};
/** \lu_module /** \lu_module
* *
* Computation of matrix inverse and determinant, with invertibility check. * Computation of matrix inverse and determinant, with invertibility check.
@ -401,5 +353,4 @@ inline void MatrixBase<Derived>::computeInverseAndDetWithCheck(
(derived(), absDeterminantThreshold, inverse, determinant, invertible); (derived(), absDeterminantThreshold, inverse, determinant, invertible);
} }
#endif // EIGEN_INVERSE_H #endif // EIGEN_INVERSE_H