Created
May 11, 2012 16:48
-
-
Save mmalex/2660905 to your computer and use it in GitHub Desktop.
notes on symmetric 3x3 matrix maths
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// symmetric matrix stuff | |
// not heavily tested but should be about right | |
// hlsl notation | |
// thanks to @rygorous @m1k3 and mark adami for help | |
// mostly just a big geek out :) | |
// multiply e by the 3x3 symmetric 3x3 matrix fromed from d on the diagonal and u in the upper triangle | |
float3 mul_sym3x3(float3 d, float3 u, float3 e) | |
{ | |
return float3(dot(e,float3(d.x,u.z,u.y)), // u=(yz,xz,xy) in the case of covariance matrix | |
dot(e,float3(u.z,d.y,u.x)), | |
dot(e,float3(u.y,u.x,d.z))); | |
} | |
// helper showing how d and u are expanded into a 3x3 matrix | |
// useful mainly for debugging this stuff | |
float3x3 sym3x3_to_float3x3(float3 d, float3 u) | |
{ | |
return float3x3( | |
d.x,u.z,u.y, | |
u.z,d.y,u.x, | |
u.y,u.x,d.z); | |
} | |
// relatively compact expression for determinant of 3x3 sym matrix d,u | |
float sym3x3_det(float3 d, float3 u) | |
{ | |
float3 uu = u*u; | |
return u.x*u.y*u.z*2-dot(d,uu)+d.x*d.y*d.z; | |
} | |
// invert in place, assuming uu=u*u (as above) and invdet=1.f/det(d,u) | |
u = invdet * (u.zzy * u.yxx - d * u); | |
d = invdet * (d.yxx * d.zzy - uu); | |
// power iteration for eigenvectors - thanks to @rygorous for the tip-off | |
// on input, n is any initial guess as to the biggest eigenvector of symmetrix matrix d,u | |
// n converges to biggest eigenvector (biggest in that it has largest eigenvalue) | |
// if you invert the matrix, it converges to the smallest. and you could shift it by mu, but I dont need that. | |
// see wikipedia or http://twitter.com/#!/mmalex/status/200950844907200513 | |
float3 biggest_eigenvector(float3 d, float3 u, float3 n) | |
{ | |
for (int iter=0;iter<10;++iter) n=normalize(mul_sym3x3(d,u,n)); | |
return n; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment