Registered Member
|
Is there some method to compute the inverse of a matrix and obtain information if the matrix is invertible, like ei_compute_inverse_in_size2_case_with_check ?
As most of the time computing if the matrix is invertible is as costly as inverting the matrix, doing the check and then inverting the matrix seems not optimal. If the method is not available: How complex it is to have this feature ? I propose the function: bool compute_inverse_with_check( const MatrixType& matrix, MatrixType* result ) and the associated method of matrix_base: bool computeInverseWithCheck( MatrixType* result ) const I have modified the file Inverse.hpp and MatrixBase.hpp (just added the declaration of one method there) to include those features, it compiles and seems to execute fine on some random examples. You can find the files there: http://rapidshare.com/files/246412035/m ... s.tgz.html What do you think of that feature ? Of the way I modified your code ? I am not very happy with the fact that there is a lot of copy/paste from the original code of compute_inverse. But the only way I see, for the moment, to factorize the code is to use macros (do you see a better choice ?) for instance: template bool ei_compute_inverse_in_size3_case_with_check(const XprType& matrix, MatrixType* result) { typedef typename MatrixType::Scalar Scalar; const Scalar det_minor00 = matrix.minor(0,0).determinant(); const Scalar det_minor10 = matrix.minor(1,0).determinant(); const Scalar det_minor20 = matrix.minor(2,0).determinant(); const Scalar det = ( det_minor00 * matrix.coeff(0,0) - det_minor10 * matrix.coeff(1,0) + det_minor20 * matrix.coeff(2,0) ); if(ei_isMuchSmallerThan(det, matrix.cwise().abs().maxCoeff())) return false; const Scalar invdet = Scalar(1) / det; result->coeffRef(0, 0) = det_minor00 * invdet; result->coeffRef(0, 1) = -det_minor10 * invdet; result->coeffRef(0, 2) = det_minor20 * invdet; result->coeffRef(1, 0) = -matrix.minor(0,1).determinant() * invdet; result->coeffRef(1, 1) = matrix.minor(1,1).determinant() * invdet; result->coeffRef(1, 2) = -matrix.minor(2,1).determinant() * invdet; result->coeffRef(2, 0) = matrix.minor(0,2).determinant() * invdet; result->coeffRef(2, 1) = -matrix.minor(1,2).determinant() * invdet; result->coeffRef(2, 2) = matrix.minor(2,2).determinant() * invdet; return true; } can be replaced by: #define MINOR_AND_DETERMINANT_COMPUTATION_3D typedef typename MatrixType::Scalar Scalar; const Scalar det_minor00 = matrix.minor(0,0).determinant(); const Scalar det_minor10 = matrix.minor(1,0).determinant(); const Scalar det_minor20 = matrix.minor(2,0).determinant(); const Scalar det = ( det_minor00 * matrix.coeff(0,0) - det_minor10 * matrix.coeff(1,0) + det_minor20 * matrix.coeff(2,0) ); #define INVERSE_FROM_COMATRIX_3D ... template bool ei_compute_inverse_in_size3_case_with_check(const XprType& matrix, MatrixType* result) { MINOR_AND_DETERMINANT_COMPUTATION_3D if(ei_isMuchSmallerThan(det, matrix.cwise().abs().maxCoeff())) return false; INVERSE_FROM_COMATRIX_3D return true; } #undef MINOR_AND_DETERMINANT_3D #undef INVERSE_FROM_COMATRIX_3D and use this macro where it is usefull in ei_compute_inverse_in_size3_case for instance. However, I don't think that way of coding is very nice especially for two instances of the code only. |
Registered Member
|
I just had a look to main page and have seen that the current versioning tool is mercurial.
I did a checkout with svn, so perhaps the files I modified were not up-to-date. Is the svn repository updated too ? I will get the mercurial repository and see it tomorrow. Sorry for the post. |
Registered Member
|
Of course Eigen allows you to check invertibility and to combine this computation with the computation of the inverse so that there is no redundancy. The Eigen way to do that is:
This method is fast for large enough matrices. But it's true that it's inherently slow for very small matrices: up to size 4x4. Are you specifically interested in <= 4x4 matrices and do you specifically need inverse-with-check for them? It's true that we overlooked this case, but that's because we didn't believe that there would be much of a use case for that. What's your use case? It sure would be possible to add a inverseWithCheck() method, that uses the LU method in the generic case, and specialize to special code in small size. Don't worry, we won't have to use macros, templates and inline functions allow to do a lot of things
The SVN repo isn't updated anymore, it will be removed soon.
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered Member
|
OK I looked at your files but it would be 10x better for me to have a diff:
if you used svn, you can do: cd eigen2/ svn diff > my_diff it creates a file my_diff that you can send us or paste here as code.
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered Member
|
Ok, I need the 3x3 case.
Here is the diff:
Last edited by bjacob on Mon Jun 22, 2009 12:36 am, edited 1 time in total.
|
Registered Member
|
OK, thanks for pinging me on IRC, I was forgetting about this.
I looked at your patch but it's looking like some <...> were eaten away ? like after "template"
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered users: Bing [Bot], Google [Bot], Sogou [Bot]