mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
big huge changes, so i dont remember everything.
* renaming, e.g. LU ---> FullPivLU * split tests framework: more robust, e.g. dont generate empty tests if a number is skipped * make all remaining tests use that splitting, as needed. * Fix 4x4 inversion (see stable branch) * Transform::inverse() and geo_transform test : adapt to new inverse() API, it was also trying to instantiate inverse() for 3x4 matrices. * CMakeLists: more robust regexp to parse the version number * misc fixes in unit tests
This commit is contained in:
@@ -34,7 +34,7 @@ struct ei_compute_inverse
|
||||
{
|
||||
static inline void run(const MatrixType& matrix, ResultType& result)
|
||||
{
|
||||
result = matrix.partialLu().inverse();
|
||||
result = matrix.partialPivLu().inverse();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -232,22 +232,31 @@ struct ei_compute_inverse<MatrixType, ResultType, 4>
|
||||
typename MatrixType::PlainMatrixType matrix(_matrix);
|
||||
|
||||
// let's extract from the 2 first colums a 2x2 block whose determinant is as big as possible.
|
||||
int good_row0=0, good_row1=1;
|
||||
RealScalar good_absdet(-1);
|
||||
// this double for loop shouldn't be too costly: only 6 iterations
|
||||
for(int row0=0; row0<4; ++row0) {
|
||||
for(int row1=row0+1; row1<4; ++row1)
|
||||
{
|
||||
RealScalar absdet = ei_abs(matrix.coeff(row0,0)*matrix.coeff(row1,1)
|
||||
- matrix.coeff(row0,1)*matrix.coeff(row1,0));
|
||||
if(absdet > good_absdet)
|
||||
{
|
||||
good_absdet = absdet;
|
||||
good_row0 = row0;
|
||||
good_row1 = row1;
|
||||
}
|
||||
}
|
||||
}
|
||||
int good_row0, good_row1, good_i;
|
||||
Matrix<RealScalar,6,1> absdet;
|
||||
|
||||
// any 2x2 block with determinant above this threshold will be considered good enough
|
||||
RealScalar d = (matrix.col(0).squaredNorm()+matrix.col(1).squaredNorm()) * RealScalar(1e-2);
|
||||
#define ei_inv_size4_helper_macro(i,row0,row1) \
|
||||
absdet[i] = ei_abs(matrix.coeff(row0,0)*matrix.coeff(row1,1) \
|
||||
- matrix.coeff(row0,1)*matrix.coeff(row1,0)); \
|
||||
if(absdet[i] > d) { good_row0=row0; good_row1=row1; goto good; }
|
||||
ei_inv_size4_helper_macro(0,0,1)
|
||||
ei_inv_size4_helper_macro(1,0,2)
|
||||
ei_inv_size4_helper_macro(2,0,3)
|
||||
ei_inv_size4_helper_macro(3,1,2)
|
||||
ei_inv_size4_helper_macro(4,1,3)
|
||||
ei_inv_size4_helper_macro(5,2,3)
|
||||
|
||||
// no 2x2 block has determinant bigger than the threshold. So just take the one that
|
||||
// has the biggest determinant
|
||||
absdet.maxCoeff(&good_i);
|
||||
good_row0 = good_i <= 2 ? 0 : good_i <= 4 ? 1 : 2;
|
||||
good_row1 = good_i <= 2 ? good_i+1 : good_i <= 4 ? good_i-1 : 3;
|
||||
|
||||
// now good_row0 and good_row1 are correctly set
|
||||
good:
|
||||
|
||||
// do row permutations to move this 2x2 block to the top
|
||||
matrix.row(0).swap(matrix.row(good_row0));
|
||||
matrix.row(1).swap(matrix.row(good_row1));
|
||||
@@ -318,12 +327,12 @@ struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> >
|
||||
* \returns the matrix inverse of this matrix.
|
||||
*
|
||||
* For small fixed sizes up to 4x4, this method uses ad-hoc methods (cofactors up to 3x3, Euler's trick for 4x4).
|
||||
* In the general case, this method uses class PartialLU.
|
||||
* In the general case, this method uses class PartialPivLU.
|
||||
*
|
||||
* \note This matrix must be invertible, otherwise the result is undefined. If you need an
|
||||
* invertibility check, do the following:
|
||||
* \li for fixed sizes up to 4x4, use computeInverseAndDetWithCheck().
|
||||
* \li for the general case, use class LU.
|
||||
* \li for the general case, use class FullPivLU.
|
||||
*
|
||||
* Example: \include MatrixBase_inverse.cpp
|
||||
* Output: \verbinclude MatrixBase_inverse.out
|
||||
|
||||
Reference in New Issue
Block a user