void svd_pseudoinverse(out float[,] o, Vector3 sigma, float[,] v)
{
float d0 = svd_invdet(sigma.X, epsilon);
float d1 = svd_invdet(sigma.Y, epsilon);
float d2 = svd_invdet(sigma.Z, epsilon);
o = new float[,]
{
{
v[0,0] * d0 * v[0,0] + v[0,1] * d1 * v[0,1] + v[0,2] * d2 * v[0,2],
v[0,0] * d0 * v[1,0] + v[0,1] * d1 * v[1,1] + v[0,2] * d2 * v[1,2],
v[0,0] * d0 * v[2,0] + v[0,1] * d1 * v[2,1] + v[0,2] * d2 * v[2,2]
},
{
v[1,0] * d0 * v[0,0] + v[1,1] * d1 * v[0,1] + v[1,2] * d2 * v[0,2],
v[1,0] * d0 * v[1,0] + v[1,1] * d1 * v[1,1] + v[1,2] * d2 * v[1,2],
v[1,0] * d0 * v[2,0] + v[1,1] * d1 * v[2,1] + v[1,2] * d2 * v[2,2]
},
{
v[2,0] * d0 * v[0,0] + v[2,1] * d1 * v[0,1] + v[2,2] * d2 * v[0,2],
v[2,0] * d0 * v[1,0] + v[2,1] * d1 * v[1,1] + v[2,2] * d2 * v[1,2],
v[2,0] * d0 * v[2,0] + v[2,1] * d1 * v[2,1] + v[2,2] * d2 * v[2,2]
}
};
}