int main(void){ linear(); newton2(); newton3(); lagrange(); return 0; }
/** * \brief Find eigenvalues and vectors of a 3x3 matrix. * \param symmat 0 if matrix is not symetric, 1 otherwise. * \param mat pointer toward the matrix. * \param lambda eigenvalues. * \param v eigenvectors. * \return order of eigenvalues (1,2,3) or 0 if failed. */ int _MMG5_eigenv(int symmat,double *mat,double lambda[3],double v[3][3]) { double a11,a12,a13,a21,a22,a23,a31,a32,a33; double aa,bb,cc,dd,ee,ii,vx1[3],vx2[3],vx3[3],dd1,dd2,dd3; double maxd,maxm,valm,p[4],w1[3],w2[3],w3[3]; int k,n; /* default */ memcpy(v,Id,9*sizeof(double)); if ( symmat ) { lambda[0] = (double)mat[0]; lambda[1] = (double)mat[3]; lambda[2] = (double)mat[5]; maxm = fabs(mat[0]); for (k=1; k<6; k++) { valm = fabs(mat[k]); if ( valm > maxm ) maxm = valm; } /* single float accuracy */ if ( maxm < _MG_EPS6 ) return(1); /* normalize matrix */ dd = 1.0 / maxm; a11 = mat[0] * dd; a12 = mat[1] * dd; a13 = mat[2] * dd; a22 = mat[3] * dd; a23 = mat[4] * dd; a33 = mat[5] * dd; /* diagonal matrix */ maxd = fabs(a12); valm = fabs(a13); if ( valm > maxd ) maxd = valm; valm = fabs(a23); if ( valm > maxd ) maxd = valm; if ( maxd < _MG_EPSD ) return(1); a21 = a12; a31 = a13; a32 = a23; /* build characteristic polynomial P(X) = X^3 - trace X^2 + (somme des mineurs)X - det = 0 */ aa = a11*a22; bb = a23*a32; cc = a12*a21; dd = a13*a31; p[0] = a11*bb + a33*(cc-aa) + a22*dd -2.0*a12*a13*a23; p[1] = a11*(a22 + a33) + a22*a33 - bb - cc - dd; p[2] = -a11 - a22 - a33; p[3] = 1.0; } else { lambda[0] = (double)mat[0]; lambda[1] = (double)mat[4]; lambda[2] = (double)mat[8]; maxm = fabs(mat[0]); for (k=1; k<9; k++) { valm = fabs(mat[k]); if ( valm > maxm ) maxm = valm; } if ( maxm < _MG_EPS6 ) return(1); /* normalize matrix */ dd = 1.0 / maxm; a11 = mat[0] * dd; a12 = mat[1] * dd; a13 = mat[2] * dd; a21 = mat[3] * dd; a22 = mat[4] * dd; a23 = mat[5] * dd; a31 = mat[6] * dd; a32 = mat[7] * dd; a33 = mat[8] * dd; /* diagonal matrix */ maxd = fabs(a12); valm = fabs(a13); if ( valm > maxd ) maxd = valm; valm = fabs(a23); if ( valm > maxd ) maxd = valm; valm = fabs(a21); if ( valm > maxd ) maxd = valm; valm = fabs(a31); if ( valm > maxd ) maxd = valm; valm = fabs(a32); if ( valm > maxd ) maxd = valm; if ( maxd < _MG_EPSD ) return(1); /* build characteristic polynomial P(X) = X^3 - trace X^2 + (somme des mineurs)X - det = 0 */ aa = a22*a33 - a23*a32; bb = a23*a31 - a21*a33; cc = a21*a32 - a31*a22; ee = a11*a33 - a13*a31; ii = a11*a22 - a12*a21; p[0] = -a11*aa - a12*bb - a13*cc; p[1] = aa + ee + ii; p[2] = -a11 - a22 - a33; p[3] = 1.0; } /* solve polynomial (find roots using newton) */ n = newton3(p,lambda); if ( n <= 0 ) return(0); /* compute eigenvectors: an eigenvalue belong to orthogonal of Im(A-lambda*Id) */ v[0][0] = 1.0; v[0][1] = v[0][2] = 0.0; v[1][1] = 1.0; v[1][0] = v[1][2] = 0.0; v[2][2] = 1.0; v[2][0] = v[2][1] = 0.0; w1[1] = a12; w1[2] = a13; w2[0] = a21; w2[2] = a23; w3[0] = a31; w3[1] = a32; if ( n == 1 ) { /* vk = crsprd(wi,wj) */ for (k=0; k<3; k++) { w1[0] = a11 - lambda[k]; w2[1] = a22 - lambda[k]; w3[2] = a33 - lambda[k]; /* cross product vectors in (Im(A-lambda(i) Id) ortho */ vx1[0] = w1[1]*w3[2] - w1[2]*w3[1]; vx1[1] = w1[2]*w3[0] - w1[0]*w3[2]; vx1[2] = w1[0]*w3[1] - w1[1]*w3[0]; dd1 = vx1[0]*vx1[0] + vx1[1]*vx1[1] + vx1[2]*vx1[2]; vx2[0] = w1[1]*w2[2] - w1[2]*w2[1]; vx2[1] = w1[2]*w2[0] - w1[0]*w2[2]; vx2[2] = w1[0]*w2[1] - w1[1]*w2[0]; dd2 = vx2[0]*vx2[0] + vx2[1]*vx2[1] + vx2[2]*vx2[2]; vx3[0] = w2[1]*w3[2] - w2[2]*w3[1]; vx3[1] = w2[2]*w3[0] - w2[0]*w3[2]; vx3[2] = w2[0]*w3[1] - w2[1]*w3[0]; dd3 = vx3[0]*vx3[0] + vx3[1]*vx3[1] + vx3[2]*vx3[2]; /* find vector of max norm */ if ( dd1 > dd2 ) { if ( dd1 > dd3 ) { dd1 = 1.0 / sqrt(dd1); v[k][0] = vx1[0] * dd1; v[k][1] = vx1[1] * dd1; v[k][2] = vx1[2] * dd1; } else { dd3 = 1.0 / sqrt(dd3); v[k][0] = vx3[0] * dd3; v[k][1] = vx3[1] * dd3; v[k][2] = vx3[2] * dd3; } } else { if ( dd2 > dd3 ) { dd2 = 1.0 / sqrt(dd2); v[k][0] = vx2[0] * dd2; v[k][1] = vx2[1] * dd2; v[k][2] = vx2[2] * dd2; } else { dd3 = 1.0 / sqrt(dd3); v[k][0] = vx3[0] * dd3; v[k][1] = vx3[1] * dd3; v[k][2] = vx3[2] * dd3; } } } } /* (vp1,vp2) double, vp3 simple root */ else if ( n == 2 ) { w1[0] = a11 - lambda[2]; w2[1] = a22 - lambda[2]; w3[2] = a33 - lambda[2]; /* cross product */ vx1[0] = w1[1]*w3[2] - w1[2]*w3[1]; vx1[1] = w1[2]*w3[0] - w1[0]*w3[2]; vx1[2] = w1[0]*w3[1] - w1[1]*w3[0]; dd1 = vx1[0]*vx1[0] + vx1[1]*vx1[1] + vx1[2]*vx1[2]; vx2[0] = w1[1]*w2[2] - w1[2]*w2[1]; vx2[1] = w1[2]*w2[0] - w1[0]*w2[2]; vx2[2] = w1[0]*w2[1] - w1[1]*w2[0]; dd2 = vx2[0]*vx2[0] + vx2[1]*vx2[1] + vx2[2]*vx2[2]; vx3[0] = w2[1]*w3[2] - w2[2]*w3[1]; vx3[1] = w2[2]*w3[0] - w2[0]*w3[2]; vx3[2] = w2[0]*w3[1] - w2[1]*w3[0]; dd3 = vx3[0]*vx3[0] + vx3[1]*vx3[1] + vx3[2]*vx3[2]; /* find vector of max norm */ if ( dd1 > dd2 ) { if ( dd1 > dd3 ) { dd1 = 1.0 / sqrt(dd1); v[2][0] = vx1[0] * dd1; v[2][1] = vx1[1] * dd1; v[2][2] = vx1[2] * dd1; } else { dd3 = 1.0 / sqrt(dd3); v[2][0] = vx3[0] * dd3; v[2][1] = vx3[1] * dd3; v[2][2] = vx3[2] * dd3; } } else { if ( dd2 > dd3 ) { dd2 = 1.0 / sqrt(dd2); v[2][0] = vx2[0] * dd2; v[2][1] = vx2[1] * dd2; v[2][2] = vx2[2] * dd2; } else { dd3 = 1.0 / sqrt(dd3); v[2][0] = vx3[0] * dd3; v[2][1] = vx3[1] * dd3; v[2][2] = vx3[2] * dd3; } } /* compute v1 and v2 in Im(A-vp3*Id) */ dd1 = w1[0]*w1[0] + w1[1]*w1[1] + w1[2]*w1[2]; dd2 = w2[0]*w2[0] + w2[1]*w2[1] + w2[2]*w2[2]; if ( dd1 > dd2 ) { dd1 = 1.0 / sqrt(dd1); v[0][0] = w1[0]*dd1; v[0][1] = w1[1]*dd1; v[0][2] = w1[2]*dd1; } else { dd2 = 1.0 / sqrt(dd2); v[0][0] = w2[0]*dd2; v[0][1] = w2[1]*dd2; v[0][2] = w2[2]*dd2; } /* 3rd vector orthogonal */ v[1][0] = v[2][1]*v[0][2] - v[2][2]*v[0][1]; v[1][1] = v[2][2]*v[0][0] - v[2][0]*v[0][2]; v[1][2] = v[2][0]*v[0][1] - v[2][1]*v[0][0]; dd1 = v[1][0]*v[1][0] + v[1][1]*v[1][1] + v[1][2]*v[1][2]; dd1 = 1.0 / sqrt(dd1); v[1][0] *= dd1; v[1][1] *= dd1; v[1][2] *= dd1; } lambda[0] *= maxm; lambda[1] *= maxm; lambda[2] *= maxm; /* check accuracy */ /*------------------------------------------------------------------- if ( ddebug && symmat ) { double err,tmpx,tmpy,tmpz; float m[6]; int i,j; k = 0; for (i=0; i<3; i++) for (j=i; j<3; j++) m[k++] = lambda[0]*v[i][0]*v[j][0] + lambda[1]*v[i][1]*v[j][1] + lambda[2]*v[i][2]*v[j][2]; err = fabs(mat[0]-m[0]); for (i=1; i<6; i++) if ( fabs(m[i]-mat[i]) > err ) err = fabs(m[i]-mat[i]); if ( err > 1.e03*maxm ) { printf("\nProbleme eigenv3: err= %f\n",err*maxm); printf("mat depart :\n"); printf("%13.6f %13.6f %13.6f\n",mat[0],mat[1],mat[2]); printf("%13.6f %13.6f %13.6f\n",mat[1],mat[3],mat[4]); printf("%13.6f %13.6f %13.6f\n",mat[2],mat[4],mat[5]); printf("mat finale :\n"); printf("%13.6f %13.6f %13.6f\n",m[0],m[1],m[2]); printf("%13.6f %13.6f %13.6f\n",m[1],m[3],m[4]); printf("%13.6f %13.6f %13.6f\n",m[2],m[4],m[5]); printf("lambda : %f %f %f\n",lambda[0],lambda[1],lambda[2]); printf(" ordre %d\n",n); printf("\nOrtho:\n"); printf("v1.v2 = %.14f\n", v[0][0]*v[1][0]+v[0][1]*v[1][1]+ v[0][2]*v[1][2]); printf("v1.v3 = %.14f\n", v[0][0]*v[2][0]+v[0][1]*v[2][1]+ v[0][2]*v[2][2]); printf("v2.v3 = %.14f\n", v[1][0]*v[2][0]+v[1][1]*v[2][1]+ v[1][2]*v[2][2]); printf("Consistency\n"); for (i=0; i<3; i++) { tmpx = v[0][i]*m[0] + v[1][i]*m[1] + v[2][i]*m[2] - lambda[i]*v[0][i]; tmpy = v[0][i]*m[1] + v[1][i]*m[3] + v[2][i]*m[4] - lambda[i]*v[1][i]; tmpz = v[0][i]*m[2] + v[1][i]*m[4] + v[2][i]*m[5] - lambda[i]*v[2][i]; printf(" Av %d - lambda %d *v %d = %f %f %f\n", i,i,i,tmpx,tmpy,tmpz); printf("w1 %f %f %f\n",w1[0],w1[1],w1[2]); printf("w2 %f %f %f\n",w2[0],w2[1],w2[2]); printf("w3 %f %f %f\n",w3[0],w3[1],w3[2]); } exit(1); } } -------------------------------------------------------------------*/ return(n); }