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])<m))) then m:=abs(A[i,j]);u:=i;v:=j; end if; od; od; u,v;end proc; A:=matrix([[6, 0, 7, 9], [6, 8, 6, 9], [3, 2, 4, 6], [3, 2, 3, 3]]); minval(A); (i,j):=minval(A); U:=identity(4); /* normalement il faudrait faire bouger l dans {1..4} sauf j, c'est plus simple de£ne pas mettre de test, et de corriger U[j,j] ensuite*/ for l from 1 to 4 do U[j,l]:=-iquo(A[i,l],A[i,j]) od:U[j,j]:=1:U; A*U; trans:=proc(A,i,j) local n,U,V,l; n:=dim(A)[1]; U:=identity(n); V:=identity(n); for l from 1 to n do V[l,i]:=-iquo(A[l,j],A[i,j]); od; //on corrige V[i,i]:=1; for l from 1 to n do U[j,l]:=-iquo(A[i,l],A[i,j]); od; //on corrige U[j,j]:=1; V*A*U; end proc; A:=matrix([[6, 1, 7, 9], [6, 8, 6, 9], [3, 1, 4, 6], [3, 2, 1, 3]]); trans(A,3,1); Zequiv:=proc(A) k:=0; n:=dim(A)[1]; l:=[seq(0,k=1..n)]; B:=A; (i,j):=minval(B); //minval retourne les coordonnees du minimum non nul, //ou un couple impossible (Ex ici (0,0) en mode maple) si B est nulle. 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:=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];