restart;maple_mode(1);cas_setup(0,0,0,1,0,1e-10,10,[1,50,0,25],0,0,0);#radians,pas de cmplx, pas de Sqrt gcd(6,3);#Attention, a priori pour lui c'est des polynomes, on a dela chance il les normalise bien. gcd(x*(x+3),2*x); igcd(4,6,8); iquo(13,6);igcd(6,0); igcdex(4,15,'a','b');#pour un couple de bezout: 4*a+15*b; delrows(matrix([[1,1],[2,3]]),2..2); #pour une colonne: delcols A:=diag([3,6,18,36]);B:=matrix(4,4,(i,j)->rand(7)-3):;normal(det(A)*det(B)-det(ismith(A*B)[2])); // ismith(A*B); [U0,D0,V0]:=ismith(A*B):;D0-U0*A*B*V0; /* -----------------------------------------------------------------------------------------------------*/ minval:=proc(A) local m,u,v,i,j; m:=0;u:=0;v:=0; # NB: On retourne 0,0 si A est nulle for i from 1 to dim(A)[1] do for j from 1 to dim(A)[2] do if ((abs(A[i,j])>0) and ((m=0) or (abs(A[i,j])[0,0]) and size(B)>1 do // attention, ne pas oublier de declarer les variables locales // dans trans pour eviter les melanges B:=trans(B,i,j); if [i,j]=[minval(B)] then // on n'a que des zeros sur la ligne i et la colonne j sauf // en (i,j) on sauve donc B[i,j] et on raye ligne et colonne. k:=k+1; l[k]:=B[i,j]; B:=delcols(B,j..j); B:=delrows(B,i..i); //le cas B de taille 1 pose probleme car on ne peut pas rayer //une colonne puis une ligne fi; // ASTUCE: voici comment assigner 2 valeurs d'un coup. (i,j):=minval(B); end do; // On a eventuellement change le signe du determinant diag([seq(l[k],k=1..n-1),B[1,1]]); end proc; A:=matrix([[2,2,2],[6,12,6],[6,4,6]]); #Exemple: Zequiv(A); A[3,3]:=12:A; Zequiv(A); /* On v\'erifie que A et Zequiv(A) ont bien meme forme de smith:*/ ismith(A)[2], ismith(Zequiv(A))[2]; /* Attention, on n'obtient pas forcement les diviseurs elementaires, par exemple:*/ A:=matrix([[4,0,0],[0,6,0],[0,0,8]]); ismith(A)[2]; Zequiv(A); /* ca sera forc\'ement le pgcd(d_1,...,d_n) car l'algorithme reste sur la premiere ligne.*/ f:=(i,j)->if (i-j)*(i-1)=0 then 1 else 0 fi; matrix(3,3,f);A:=matrix(3,3,f)*A;Zequiv(A); /* On recopie trans et Zequiv pour qu'ils ne travaillent que sur les colonnes*/ transC:=proc(A,i,j) //attention, si on ne met pas un local n, il modifiera la valeur de n dans ZequivC local n,U,l; n:=dim(A)[1]; U:=identity(n); for l from 1 to n do U[j,l]:=-iquo(A[i,l],A[i,j]); od; //pour ne pas mettre de test dans la boucle precedente, on n'ecarte pas l=j, mais on le on corrige ici: U[j,j]:=1; A*U; end proc; ZequivC:=proc(A) k:=0; n:=dim(A)[1]; l:=[seq(0,k=1..n)]; B:=A; (i,j):=minval(B); while([i,j]<>[0,0]) and size(B)>1 do // attention, ne pas oublier de declarer les variables locales dans trans pour eviter les melanges B:=transC(B,i,j); if [i,j]=[minval(B)] then k:=k+1; l[k]:=B[i,j]; B:=delcols(B,j..j); B:=delrows(B,i..i); fi; // ASTUCE: voici comment assigner 2 valeurs d'un coup. (i,j):=minval(B); end do; // On a eventuellement change le signe du determinant diag([seq(l[k],k=1..n-1),B[1,1]]); end proc; elem:=proc(A) n:=dim(A)[1]; d:=Zequiv(A); L:=[]; for i from 1 to n-1 do T:=matrix(n+1-i,n+1-i,f); d:=ZequivC(T*d); L:=[op(L),d[1,1]]; d:=delrows(delcols(d,1..1),1..1); od; [op(L),d[1,1]]; end proc; A:=matrix([[2,2,2],[6,12,6],[6,4,12]]); elem(A);ismith(A)[2]; elem(diag(4,6,16));ismith(diag(4,6,16))[2];