Example #1
0
/* Polar Decomposition of 3x3 matrix in 4x4,
 * M = QS.  See Nicholas Higham and Robert S. Schreiber,
 * Fast Polar Decomposition of An Arbitrary Matrix,
 * Technical Report 88-942, October 1988,
 * Department of Computer Science, Cornell University.
 */
double polar_decomp(HMatrix M, HMatrix Q, HMatrix S)
{
#define TOL 1.0e-6
    HMatrix Mk, MadjTk, Ek;
    double det, M_one, M_inf, MadjT_one, MadjT_inf, E_one, gamma, g1, g2;
    int i, j;
    mat_tpose(Mk,=,M,3);
    M_one = norm_one(Mk);  M_inf = norm_inf(Mk);
    do {
	adjoint_transpose(Mk, MadjTk);
	det = vdot(Mk[0], MadjTk[0]);
	if (det==0.0) {do_rank2(Mk, MadjTk, Mk); break;}
	MadjT_one = norm_one(MadjTk); MadjT_inf = norm_inf(MadjTk);
	gamma = sqrt(sqrt((MadjT_one*MadjT_inf)/(M_one*M_inf))/fabs(det));
	g1 = gamma*0.5;
	g2 = 0.5/(gamma*det);
	mat_copy(Ek,=,Mk,3);
	mat_binop(Mk,=,g1*Mk,+,g2*MadjTk,3);
	mat_copy(Ek,-=,Mk,3);
	E_one = norm_one(Ek);
	M_one = norm_one(Mk);  M_inf = norm_inf(Mk);
    } while (E_one>(M_one*TOL));
    mat_tpose(Q,=,Mk,3); mat_pad(Q);
    mat_mult(Mk, M, S);	 mat_pad(S);
    for (i=0; i<3; i++) for (j=i; j<3; j++)
	S[i][j] = S[j][i] = 0.5*(S[i][j]+S[j][i]);
    return (det);
}
Example #2
0
/* Polar Decomposition of 3x3 matrix in 4x4,
 * M = QS.  See Nicholas Higham and Robert S. Schreiber,
 * Fast Polar Decomposition of An Arbitrary Matrix,
 * Technical Report 88-942, October 1988,
 * Department of Computer Science, Cornell University.
 */
float polar_decomp(const mat3 & M, mat3 & Q, mat3 & S)
{
    mat3 tmp;
    mat3 Mk, MadjTk, Ek;

    nv_scalar d, M_one, M_inf, MadjT_one, MadjT_inf, E_one, gamma, g1, g2;

    transpose(Mk,M);
    M_one = Mk.norm_one();  
    M_inf = Mk.norm_inf();

    do {
        invert(MadjTk,Mk);
        transpose(MadjTk);
        MadjTk*=det(MadjTk);

        d = dot(Mk.col(0), MadjTk.col(0));

        if (d == nv_zero) 
        {
            do_rank2(Mk, MadjTk, Mk);
            break;
        }

        MadjT_one = MadjTk.norm_one(); 
        MadjT_inf = MadjTk.norm_inf();

        gamma = sqrtf(sqrtf((MadjT_one*MadjT_inf)/(M_one*M_inf))/fabs(d));

        g1 = gamma*nv_zero_5;
        g2 = nv_zero_5 / (gamma*d);

        Ek = Mk;
        tmp = Mk;
        tmp *= g1;
        MadjTk *= g2;
        add(Mk,tmp,MadjTk);
        Ek-=Mk;

        E_one = Ek.norm_one();
        M_one = Mk.norm_one();  
        M_inf = Mk.norm_inf();
    } 
    while (E_one>(M_one*nv_eps));

    transpose(Q,Mk); 
    mult(S, Mk, M);  
    
    nv_scalar x;
    for (int i = 0; i < 3; ++i) 
    {
        for (int j = i; j < 3; ++j)
        {
            x = nv_zero_5 * (S[i][j]+S[j][i]);
            S(i,j) = x;
            S(j,i) = x;
        }
    }
    return (d);
}