Beispiel #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);
}
int normalize_one(deque<double> & a) {

	
	double norm=norm_one(a);
	for(int i=0; i<a.size(); i++) {
		a[i]/=norm;
	}
	
	return 0;


}
Beispiel #3
0
void PolarDecomposer::PolarDecompose(const mat3& A, mat3& Q, mat3& S, double& det, double tolerance)
{
	mat3 At = A.transpose();
	mat3 Aadj;
	mat3 Ek;
	double A_one = norm_one(At);
	double A_inf = norm_inf(At);
	double Aadj_one, Aadj_inf, E_one, gamma, g1, g2;
	
	do
	{
		Aadj = mat3(At[1].Cross(At[2]), At[2].Cross(At[0]), At[0].Cross(At[1]));
		det = At[0][0] * Aadj[0][0] + At[0][1] * Aadj[0][1] + At[0][2] * Aadj[0][2];
		if(det == 0.0)
		{
			//TODO: handle this case
			printf("Warning: zero determinant encountered.\n");
			break;
		}
		Aadj_one = norm_one(Aadj);
		Aadj_inf = norm_inf(Aadj);
		
		gamma = sqrt(sqrt((Aadj_one*Aadj_inf)/(A_one*A_inf))/fabs(det));
		g1 = gamma * 0.5;
		g2 = 0.5/(gamma*det);

		for(unsigned int i = 0; i < 3; i++)
			for(unsigned int j = 0; j < 3; j++)
			{
				Ek[i][j] = At[i][j];
				At[i][j] = g1 * At[i][j] + g2 * Aadj[i][j];
				Ek[i][j] -= At[i][j];
			}

		E_one = norm_one(Ek);

		A_one = norm_one(At);
		A_inf = norm_inf(At);
	}
	while( E_one > A_one * tolerance);

	if(fabs(det) < EPSILON)//edit by Xing
		Q = mat3::Identity();
	else
		Q = At.transpose();

	//TODO: if S is to be used. uncomment this part

	for(unsigned int i = 0; i < 3; i++)
		for(unsigned int j = 0; j < 3; j++)
		{
			S[i][j] = 0;
			for(unsigned int k = 0; k < 3; k++)
				S[i][j] += At[i][k] * A[k][j];
		}
	for(unsigned int i = 0; i < 3; i++)
		for(unsigned int j = i; j < 3; j++)
		{
			S[i][j] = S[j][i] = 0.5*(S[i][j] + S[j][i]);
		}
}