// Test de l'inversion de matrices et valeurs propres (avec Lapack) (cmv 21/07/04) // cmvtminv -a 1234 -l 0 -s 1 -b 25,10000 -n 50 -S /////////////////////////////////////////////////// /////////////////////////////////////////////////// // PARTIE POUVANT ETRE CHANGEE PAR L'UTILISATEUR // /////////////////////////////////////////////////// /////////////////////////////////////////////////// // --- Choix de travailler avec des matrices complexes ? //#define COMPLEX ////////////////////////////////////////////////// // --- Choix de travailler en simple precision ? //#define PRECIS32 ////////////////////////////////////////////////// // --- Choix GausPiv + Lapack ? #define USE_GAUSPIV #define USE_LAPACK // --- Choix de ce que doit faire Lapack #define ALSO_LAPACK_INV #define ALSO_LAPACK_INV_SYM #define ALSO_LAPACK_INV_LSS #define ALSO_LAPACK_INV_LSS_SVD #define ALSO_LAPACK_EV #define ALSO_LAPACK_EV_SYM #define ALSO_LAPACK_SVD #define ALSO_LAPACK_SVD_DC ////////////////////////////////////////////////// ////////////////////////////////////////////////// // NE RIEN CHANGER CI-APRES // ////////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// #include "sopnamsp.h" #include "machdefs.h" #include #include #include #include #include #include #include "timing.h" #include "ntoolsinit.h" #include "pexceptions.h" #include "array.h" #include "srandgen.h" #if defined(USE_LAPACK) #include "intflapack.h" #endif ////////////////////////////////////////////////// #if defined(COMPLEX) #if defined(PRECIS32) #define TYPE complex #define TYPER r_4 #else #define TYPE complex #define TYPER r_8 #endif #define REAL_PART(_x_) (TYPE((_x_).real(),0.)) #define CONJ_VAL(_x_) (TYPE((_x_).real(),-(_x_).imag())) #define ABS_VAL(_x_) sqrt((double)((_x_).real()*(_x_).real() + (_x_).imag()*(_x_).imag())) #else #if defined(PRECIS32) #define TYPE r_4 #define TYPER r_4 #else #define TYPE r_8 #define TYPER r_8 #endif #define REAL_PART(_x_) (_x_) #define CONJ_VAL(_x_) (_x_) #define ABS_VAL(_x_) fabs((double)_x_) #endif ////////////////////////////////////////////////// void Symetrize(TMatrix< TYPE >& A); void Hermitian(TMatrix< TYPE >& A); r_8 Check_Mat_Ident(TMatrix< TYPE >& A); r_8 Check_Mat_Zero(TMatrix< TYPE >& A); r_8 Check_Mat_VecCol_0(TMatrix< TYPE >& A); void Check_Mat_VecCol_2(TMatrix< complex >& A); ////////////////////////////////////////////////// int main(int narg,char *arg[]) { //-------------------------------------------------------- //-- Initialisation //-------------------------------------------------------- // number of lines/columns uint_4 N = 5; // scale of the value (if =1 values between -1 and 1) r_8 scale = 1.; // number of values change by +/- vbig uint_4 nbig = N; r_8 vbig = 100.; // Nombre de lignes de matrice a imprimer uint_4 nprline = N; // Initialisation du pauvre de l'aleatoire uint_4 nalea = 0; // data scaling for gauss pivoting and determinant int tscal = 1; bool detok=false; // Please symetrize the input matrice bool symetok=false; // Please symetrize the input matrice bool gaussok=false; //-------------------------------------------------------- //-- Decodage arguments //-------------------------------------------------------- char c; while((c = getopt(narg,arg,"Sdgn:s:b:l:a:t:h")) != -1) { switch (c) { case 'S' : symetok = true; break; case 'd' : detok = true; break; case 'g' : gaussok = true; break; case 'n' : sscanf(optarg,"%d",&N); break; case 's' : sscanf(optarg,"%lf",&scale); break; case 'b' : sscanf(optarg,"%d,%lf",&nbig,&vbig); break; case 'l' : sscanf(optarg,"%d",&nprline); break; case 'a' : sscanf(optarg,"%d",&nalea); break; case 't' : sscanf(optarg,"%d",&tscal); break; case 'h' : cout<<"tsttminv [-h] [-n N] [-S] [-s scale] [-b nbig,vbig] [-g]"<0) for(int i=0;i Ainput(N,N); Ainput = (TYPE) 0; TMatrix< TYPE > A(N,N); A = (TYPE) 0; Ainput.Show(); //-------------------------------------------------------- //-- Fill matrices with flat random //-------------------------------------------------------- if(gaussok) Ainput = RandomSequence(RandomSequence::Gaussian,0.,1.); else Ainput = RandomSequence(RandomSequence::Flat,0.,1.); #if defined(COMPLEX) if(gaussok) A = RandomSequence(RandomSequence::Gaussian,0.,1.); else A = RandomSequence(RandomSequence::Flat,0.,1.); Ainput += TYPE(0.,1.)*A; #endif //-------------------------------------------------------- //-- Fill matrices with big values //-------------------------------------------------------- if(nbig>0) { #if defined(COMPLEX) nbig = (nbig+1)/2; #endif TMatrix< uint_2 > Vind(N,N); Vind = 0; // for real part uint_4 nbr=0; for(int k=0;k0.5)?1.:-1.; if(Vind(i,j)==0) {Ainput(i,j) += (TYPER) s*vbig; Vind(i,j)+=1; nbr++;} } cout<<"Nombre de valeurs BIG reelles = "<0.5)?1.:-1.; if(Vind(i,j)<=1) {Ainput(i,j) += TYPE(0.,(TYPER)s*vbig); Vind(i,j)+=2; nbi++;} } cout<<"Nombre de valeurs BIG imaginaires = "<0) {cout< InvA(N,N); InvA = IdentityMatrix(1.,N); int_4 info = LapackLinSolve(A,InvA); cout<<"info="< AiA(N,N); AiA = Ainput * InvA; if(nprline>0) {cout< Asym(N,N); Asym=Ainput; Symetrize(Asym); A=Asym; //-- Inversion TMatrix< TYPE > InvA(N,N); InvA = IdentityMatrix(1.,N); int_4 info = LapackLinSolveSym(A,InvA); cout<<"info="< AiA(N,N); AiA = Asym * InvA; cout<<"------------ TMatrix AiA = A * InvA:"<0) {cout< InvA(N,N); InvA = IdentityMatrix(1.,N); int_4 info = LapackLeastSquareSolve(A,InvA); cout<<"info="< AiA(N,N); AiA = Ainput * InvA; if(nprline>0) {cout< InvA(N,N); InvA = IdentityMatrix(1.,N); TVector S; int_4 rank; r_8 rcond = -1.; int_4 info = LapackLeastSquareSolveSVD_DC(A,InvA,S,rank,rcond); cout<<"info="<0) {cout< Smin/Smax = "< AiA(N,N); AiA = Ainput * InvA; if(nprline>0) {cout< Evec; TVector< complex > Eval; //-- Decompositon int_4 info = LapackEigen(A,Eval,Evec,true); cout<<"info="<0) {cout< Evalconj(N); Evalconj = 0; int_4 nconj=0; for(int i=0;i1e-150) continue; // les 2 consecutives ne sont pas conjuguees if(Eval(i).imag()<0.) continue; // first conjugate have positive imaginary part if(Eval(i+1).imag()>0.) continue; Evalconj(i) = 1; Evalconj(i+1) = 2; nconj++; } //cout< > Azmlz(N,N); Azmlz = (complex) 0; for(int l=0;l Eval_l = complex(Eval(l).real(),Eval(l).imag()); for(int i=0;i Evec_il; #if defined(COMPLEX) Evec_il = Evec(i,l); #else Evec_il = complex(Evec(i,l),0.); if(Evalconj(l)==1) Evec_il = complex(Evec(i,l),Evec(i,l+1)); else if(Evalconj(l)==2) Evec_il = complex(Evec(i,l-1),-Evec(i,l)); #endif for(int j=0;j Evec_jl; #if defined(COMPLEX) Evec_jl = Evec(j,l); #else Evec_jl = complex(Evec(j,l),0.); if(Evalconj(l)==1) Evec_jl = complex(Evec(j,l),Evec(j,l+1)); else if(Evalconj(l)==2) Evec_jl = complex(Evec(j,l-1),-Evec(j,l)); #endif Azmlz(i,l) += Ainput(i,j) * Evec_jl; } Azmlz(i,l) -= Eval_l*Evec_il; } } if(nprline>0) {cout< Aher(N,N); Aher=Ainput; Hermitian(Aher); A=Aher; TVector Eval; //-- Decompositon int_4 info = LapackEigenSym(A,Eval,true); cout<<"info="<0) {cout< Azmlz(N,N); Azmlz = (TYPE) 0; for(int l=0;l0) {cout< S; TMatrix< TYPE > U; TMatrix< TYPE > VT; //-- Decompositon int_4 info = LapackSVD(A,S,U,VT); cout<<"info="<0) {cout< Smin/Smax = "< AmUSVt(N,N); AmUSVt = U; for(int i=0;i0) {cout< S; TMatrix< TYPE > U; TMatrix< TYPE > VT; //-- Decompositon int_4 info = LapackSVD_DC(A,S,U,VT); cout<<"info="<0) {cout< Smin/Smax = "< AmUSVt(N,N); AmUSVt = U; for(int i=0;i0) {cout<::SetGausPivScal(tscal); A = Ainput; //-- Inversion TMatrix< TYPE > InvA(N,N); InvA = IdentityMatrix(1.,N); TYPE det = GausPiv(A,InvA,detok); PrtTim("--- End of GausPiv Inversion ---"); cout<<"Det = "< AiA(N,N); AiA = Ainput * InvA; cout<<"------------ TMatrix AiA = A * InvA:"<0) {cout<& A) // Symetrize A { int_4 N = A.NRows(); for(int i=0;i& A) // Put A hermitian { int_4 N = A.NRows(); for(int i=0;i& A) // Compute the biggest difference element by element of A / Identity { int_4 N = A.NRows(); r_8 vmaxd=-1.; for(int i=0;i vmaxd ) vmaxd = ABS_VAL((TYPER)1.-A(i,i)); cout<<"Ecart maximum par rapport a 1 sur diagonale = "< vmaxh ) vmaxh = ABS_VAL(A(i,j)); } cout<<"Ecart maximum par rapport a 0 hors diagonale = "<vmaxh)? vmaxd: vmaxh; } ////------------------------------------------------------- r_8 Check_Mat_Zero(TMatrix< TYPE >& A) // Compute the biggest difference element by element of A / Zero matrix { int_4 N = A.NRows(); r_8 vmax = -1.; for(int i=0;i vmax ) vmax = ABS_VAL(A(i,j)); cout<<"Ecart maximum par rapport a zero = "<& A) // Return the biggest norm of the N vectors column of matrix { int_4 N = A.NRows(); r_8 vmax=-1.; for(int l=0;l vmax ) vmax = absv; } vmax = sqrt(vmax); cout<<"Longueur max de ||A*z-l*z|| pour tous l = "< >& A) // Return the biggest norm of : // - the real part of the N vectors column of matrix // - the imaginary part of the N vectors column of matrix // - the module of the N vectors column of matrix { int_4 N = A.NRows(); r_8 vmaxr=-1., vmaxi=-1., vmaxn=-1.; for(int l=0;l vmaxr ) vmaxr = absvr; if( absvi > vmaxi ) vmaxi = absvi; if( absvn > vmaxn ) vmaxn = absvn; } vmaxr=sqrt(vmaxr); vmaxi=sqrt(vmaxi); vmaxn=sqrt(vmaxn); cout<<"Longueur max de ||A*z-l*z|| pour tous l, reel = "<