mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-05-12 15:58:05 +08:00
remove 1 useless layer of functions
This commit is contained in:
parent
ec02388a5d
commit
07d1bcffda
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user