Accueil Ti-Gen Foire Aux Questions Chat sur le chan #tigcc sur IRC
Liste des membres Rechercher Aide
Bienvenue Invité !   Se connecter             Mes sujets   
Administrer
0 membre(s) et 1 visiteur(s) actif(s) durant les 5 dernières minutes Utilisateurs actifs : Aucun membre + 1 visiteur
Avant de poster sur le forum, il y a des régles de bases à respecter pour une bonne entente et un respect de tous.
Veuillez lire la charte du forum.
  :: Index » Forum Ti68K » Programmation TI-Basic » algorithme donnant le noyau d'une matrice de dim n*m (2 réponse(s))
./POST DE DEPART (post n°0)   Marquer comme non lu.
Xantares Ecrit le: Dimanche 12 mars 2006 à 18:00 Déconnecté(e)    Voir le profil de Xantares Envoyer un email à Xantares Envoyer un message privé à Xantares  

bonjour.
j'ai besoin d'une fonction qui donne une base du noyau d'une matrice de dimension m*n.
j'ai trouvé une page qui détaille le code d'un algorithme en language xcas, un pseudo c, sur cette page:

http://www-fourier.ujf-grenoble.fr/~parisse/giac/doc/fr/casrouge/node263.html

il s'agit de la methode de gauss-jordan. je sais qu'elle est implantée d'office sur ams mais la fonction ne convient pas pour le calcul exact, elle donne des arrondis dans tous les sens... peu pratique
j'essaie de le traduire en basic, voici le code proposé (ces commentaires ne sont pas de moi) :

gaussjordan_noyau(M):={
local pivo,jc,jl,k,j,nl,nc,temp,l,a,noyau;
nl:=nrows(M);
nc:=ncols(M);
//on met des 0 sous la diagonale 
jc:=0;
jl:=0;
// on traite toutes les colonnes
while (jc<nc and jl<nl) {
  //choix du pivot que l'on veut mettre en M[jl,jc]
    k:=jl;
    while (M[k,jc]==0 and k<nl-1) {k:=k+1;}
    //on ne fait la suite que si on a pivo!=0
    if (M[k,jc]!=0) {
      pivo:=M[k,jc];
      //echange de la ligne jl et de la ligne k
      for (l:=jc;l<nc;l++){
       temp:=M[jl,l];
       M[jl,l] := M[k,l];
        M[k,l]:=temp;     
      }
     //fin du choix du pivot qui est M[jl,jc]
      //on met 1 sur la diagonale de la colonne jc
      for (l:=0;l<nc;l++) {
      M[jl,l]:=M[jl,l]/pivo;
      }
      //on met des 0 au dessus de la diagonale de la colonne jc
      for (k:=0;k<jl;k++) {
        a:=M[k,jc];  
        for (l:=0;l<nc;l++){
          M[k,l]:=M[k,l]-M[jl,l]*a; 
         } 
       }
       //on met des 0 sous la diagonale de la colonne jc
       for (k:=jl+1;k<nl;k++) {
        a:=M[k,jc];
        for (l:=jc;l<nc;l++){ 
          M[k,l]:=M[k,l]-M[jl,l]*a; 
         } 
       }
    }
    else{
    //on ajoute une ligne de 0 si ce n'est pas le dernier zero
    if (jl<nc-1){
     for (j:=nl;j>jl;j--){
      M[j]:=M[j-1];
      }
    M[jl]:=makelist(0,1,nc);
    nl:=nl+1;
    }
   }
    //ds tous les cas,le numero de colonne et de ligne augmente de 1
    jc:=jc+1;  jl:=jl+1;
    //il faut faire toutes les colonnes 
    if (jl==nl and jl<nc) { M[nl]:=makelist(0,1,nc);nl:=nl+1;}
}
noyau:=[];
//on enleve les lignes en trop pour avoir une matrice carree de dim nc
//on retranche la matrice identite
M:=M[0..nc-1]-idn(nc);
for(j:=0;j<nc;j++){
if (M[j,j]==-1) {noyau:=append(noyau,M[0..nc-1,j]);}
}
return noyau;
}

et voici ce que j'ai réussi à en tirer pour l'instant :
la fonction disponible ici :

http://membres.lycos.fr/xantares/main.matker.89f

voici le code :

matker(m)
Func
Local pivo,jc,jl,k,j,nl,nc1,temp,l,a,noyau
rowDim(m)nl
// nc est remplacée par nc1 car variable réservée
colDim(m)->nc1
0->jc
0->jl
While jc<nc1 and jl<nl
jl->k
While m[k+1,jc+1]=0 and k<nl-1
k+1->k
EndWhile
If m[k+1,jc+1]?0 Then
m[k+1,jc+1]pivo
For l,jc,nc1-1
m[jl+1,l+1]temp
m[k+1,l+1]m[jl+1,l+1]
tempm[k+1,l+1]
EndFor
For l,0,nc1-1
m[jl+1,l+1]/pivom[jl+1,l+1]
EndFor
For k,0,jl-1
m[k+1,jc+1]a
For l,0,nc1-1
m[k+1,l+1]-m[jl+1,l+1]*am[k+1,l+1]
EndFor
EndFor
For k,jl+1,nl-1
m[k+1,jc+1]->a
For l,jc,nc1-1
m[k+1,l+1]-m[jl+1,l+1]*a->m[k+1,l+1]
EndFor
EndFor
Else
If jl<nc1-1 Then
// là j'ajoute une ligne à la matrice m.
(augment(m™,newMat(nc1,1)))™->m
For j,nl,jl+1,­1
For k,0,nc1-1
m[j-1+1,k+1]->m[j+1,k+1]
EndFor
EndFor
For j,0,nc1-1
0m[jl+1,j+1]
EndFor
nl+1nl
EndIf
EndIf
jc+1->jc
jl+1->jl
If jl=nl and jl<nc1 Then
For j,0,nc1-1
0m[nl+1,j+1]
EndFor
nl+1nl
EndIf
EndWhile
// il n'y a pas commme pour les listes l'élément neutre {} donc je rajoute un vecteur de zéros
newMat(nc1,1)noyau
subMat(m,1,1,nc1,nc1)-identity(nc1)m
For j,0,nc1-1
If m[j+1,j+1]=­1 Then
// là je on colle un vecteur à noyau
augment(noyau,subMat(m,1,j,nc1,j))noyau
EndIf
EndFor
Return noyau
EndFunc


je suppose que le bout de code :

{noyau:=append(noyau,M[0..nc-1,j]);}

signifie que l'on rajoute à la matrice noyau le vecteur j de la matrice m d'où mon code:


augment(noyau,subMat(m,1,j,nc1,j))noyau


-aver les carrés représentant l'affectation ->
(fait avec tiedit pis je peux pas remplacer)

-comme pour le c il y a un décalage des indexs des listes donc j'ai mis +1 dans les appels des listes. (partout)

-la fonction makelist, apelée makelist(0,1,nc) est équivalente d'apres le site à seq(i,i,1,nc)
mais en basic les matrices ne sont pas des listes de listes (du mois ce qu'on en voit quand on programme) : dans ce language xcas m(i) designe la liste représentant la ligne i de la matrice m.

-La commande append(l,elem) permet de mettre à la fin d'une liste l, un élément (ou une liste) elem.

finalement cette fonction ne fonctionne :) que partiellement puisque je n'obtiens que 1 vecteur
des 2 vecteurs de la base si le noyau a dim 2 et aucun vecteur si la base a dim 1, en dehors du fait que je rajoute le vecteur nul manuellement à l'initialisation de la variable de sortie noyau.
il ya peut être de l'espoir car le vecteur obtenu est exact et correspond à l'exemple donné.

c'est donc ici qu'il y a une cou**** comme on dit dans le jargon informatique.
s'il y a des allergiques au maths ne fuyez pas tout de suite c juste un probleme conversion. (peut-être que vous avez déjà fui en fait devant mon pavé là).
si quelqu'un a vu la faille ou a déjà programmé une fonction similaire je suis intéressé.
merci d'avoir tout lu.

-Edité le Dimanche 12 mars 2006 à 20:11 par Xantares-
    
./Post n°1   Marquer comme non lu.
Kevin Kofler Ecrit le: Lundi 13 mars 2006 à 01:11 Déconnecté(e)    Voir le profil de Kevin Kofler Envoyer un email à Kevin Kofler Visiter le site WEB de Kevin Kofler Envoyer un message privé à Kevin Kofler  


Euh, normalement rref peut travailler en exact aussi!
Membre de l'équipe de TIGCC: http://tigcc.ticalc.org
Mainteneur du portage Linux/Unix de TIGCC: http://tigcc.ticalc.org/linux/
Membre de l'équipe de CalcForge: http://www.calcforge.org:70/

Participez à la reprise de Ti-Gen!
    
./Post n°2   Marquer comme non lu.
Xantares Ecrit le: Lundi 13 mars 2006 à 18:41 Déconnecté(e)    Voir le profil de Xantares Envoyer un email à Xantares Envoyer un message privé à Xantares  

oui, effectivement mais quand le rang devient trop grand elle foire quand même il me semble.

j'ai finalement résolu le problème en fait, il manquait un +1 : arghhhhhhhhh...

Si vous pouviez virer ce sujet en fait ca ferait de la place...
    
  :: Index » Forum Ti68K » Programmation TI-Basic » algorithme donnant le noyau d'une matrice de dim n*m (2 réponse(s))
Pages : 1/1     « [1] » »|

.Répondre à ce sujet
Les boutons de code
[B]old[I]talic[U]nderline[S]trikethrough[L]ine Flip Hori[Z]ontallyFlip [V]erticallySha[D]ow[G]low[S]poilerCode [G][C]ite
Bullet [L]istList Item [K] Link [H][E]mail[P]icture SmileysHelp
Couleurs :
Saisissez votre message
Activer les smileys
     

Forum de Ti-Gen v3.0 Copyright ©2004 by Geoffrey ANNEHEIM
Webmaster: Kevin KOFLER, Content Admins: list, Server Admins: Tyler CASSIDY and Kevin KOFLER, DNS Admin: squalyl
Page générée en 61.47ms avec 18 requetes