bug in btMatrix3x3::diagonalized()? (bug tracked)

Post Reply
hyyou
Posts: 96
Joined: Wed Mar 16, 2016 10:11 am

bug in btMatrix3x3::diagonalized()? (bug tracked)

Post by hyyou »

I called btMatrix3x3::diagonalized() and find unexpected return value.

Input: (Note that it is almost diagonal.)

Code: Select all

In btMatrix3x3::diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)  :-
this =
{6.66666674e-05, 9.09494702e-13, 0.000000000, 0.000000000} 
{-9.09494702e-13, 6.66666674e-05, 0.000000000, 0.000000000} 
{0.000000000, 0.000000000, 6.66666674e-05, 0.000000000}
threshold = 0.00001   
maxStep = 20
Return result from Bullet (wrong):

Code: Select all

rot become 
{0.707106769, 0.707106769, 0.000000000, 0.000000000} 
{-0.707106769, 0.707106769, 0.000000000, 0.000000000} 
{0.000000000, 0.000000000, 1.00000000, 0.000000000} 
A correct solution is identity matrix.

Analysis
1. It run only 1 iteration :-

Code: Select all

btScalar t = threshold * (btFabs(m_el[0][0]) + btFabs(m_el[1][1]) + btFabs(m_el[2][2]));
if (max <= t)   //<-- max = 9.09494702e-13  ,  t = 1.99999994e-09
{
	if (max <= SIMD_EPSILON * t)
	{
		return;
	}
	step = 1;    //<--- run pass this statement, I think it is correct to do so.
}
2. Flow of execution might be wrong.
It should pass the second block #2 instead of #1 because the input is near diagonal.

Code: Select all

btScalar mpq = m_el[p][q];                               //<--- mpq = 9.09494702e-13
btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq);  //<--- theta = 0.000000000
btScalar theta2 = theta * theta;                         //<--- theta2 = 0.000000000
btScalar cos;
btScalar sin;
if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON))       //#1
{
	t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2))     
		: 1 / (theta - btSqrt(1 + theta2));               //<--- t = 1.00000000
	cos = 1 / btSqrt(1 + t * t);                         //<---- cos = 0.707106769   wrong
	sin = cos * t;
}else{                                             //#2
	// approximation for large theta-value, i.e., a nearly diagonal matrix
        .....    
}
I am not competent enough to debug it, .... should I use other libraries for diagonalization?

Edit: Thank, Erwin! (see the following reply)
If somebody want to debug, here is some useful link (example of c++ code, I didn't test):- http://stackoverflow.com/questions/4372 ... omposition
Last edited by hyyou on Mon Oct 31, 2016 4:46 am, edited 1 time in total.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: bug in btMatrix3x3::diagonalized()?

Post by Erwin Coumans »

You likely found a bug in the btMatrix3x3::diagonalized() method.

Thanks for reporting, we will track it down and fix the issue asap, you can track progress here:
https://github.com/bulletphysics/bullet3/issues/846
Post Reply