// Apply Householder reflection represented by u to column vectors of M void reflect_cols(mat3 &M, vec3 &u) { for (int i=0; i < 3; ++i) { nv_scalar s = dot(u , M.col(i)); for (int j=0; j < 3; ++j) M(j,i) -= u[j]*s; } }
// Find orthogonal factor Q of rank 1 (or less) M void do_rank1(mat3 & M, mat3& Q) { vec3 v1, v2; nv_scalar s; int col; Q = mat3_id; /* If rank(M) is 1, we should find a non-zero column in M */ col = find_max_col(M); if ( col < 0 ) return; /* Rank is 0 */ v1 = M.col(col); make_reflector(v1, v1); reflect_cols(M, v1); v2[0] = M[2][0]; v2[1] = M[2][1]; v2[2] = M[2][2]; make_reflector(v2, v2); reflect_rows(M, v2); s = M[2][2]; if (s < nv_zero) Q(2,2) = -nv_one; reflect_cols(Q, v1); reflect_rows(Q, v2); }