Skip to content

Instantly share code, notes, and snippets.

@mmalex
Created May 11, 2012 16:48
Show Gist options
  • Save mmalex/2660905 to your computer and use it in GitHub Desktop.
Save mmalex/2660905 to your computer and use it in GitHub Desktop.
notes on symmetric 3x3 matrix maths
// 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