Inverser une matrice

Bonjour,

j'enseigne à distance et je voudrais montrer aux étudiantes et aux étudiants comment inverser une matrice. Est-ce que vous avez des idées sur comment faire ?

Par exemple, ça pourrait être une vidéo où je mets ma matrice à côté de la matrice identité, je dis "gnagnagna là je peux chasser un terme dans cette colonne en faisant cette transformation élémentaire et patati et patata". Mais ça prendrait beaucoup de temps ! Pour que ce soit propre, il faudrait que je tape en LaTeX toutes les étapes, il faudrait que je mette en couleur les lignes sur lesquelles je fais des opérations pour que ce soit bien visible, qu'au niveau du rendu, tout apparaisse progressivement (dans Beamer on peut mettre des \pause dans le code, certes).

Bref, avez-vous des idées ?

Réponses

  • Bonjour.

    Vous avez donné les idées principales.
    Le seul élément que je ferais à votre place, c'est mettre en gris clair les lignes sur lesquelles vous ne travaillez pas et en gris foncé les lignes sur lesquelles vous travaillez ainsi que la ligne résultat en noir, de manière séquentielle.

    Cela donne une présentation plus sobre que du rouge, du vert, voire même du jaune (déjà vu, c'est très moche).

    A bientôt.

    Cherche livres et objets du domaine mathématique :

    Intégraphes, règles log et calculateurs électromécaniques.

  • Non mais ce qui m'embête c'est de tout taper en LaTeX moi-même ! C'est horrible :-D
  • dp
    dp
    Modifié (May 2022)
    Ah... si seulement il existait, comme c'est le cas avec ConTeXt LMTX, un moyen simple de faire des matrices sans prise de tête...

    Oh, wait:
    %%% matrix_example.tex ---                    -*- mode: context; -*-
    \startTEXpage
      \thematrix{a,b,c;d,e,f;g,h,i}
    \stopTEXpage
    
    La matrice s'écrit alors de la même façon qu'on l'écrirait dans MatLab.

    Finalement, en compilant avec context
    $ context matrix_example.tex
    
    on obtient alors un PDF comme sur l'image ci-après. Bon, après, c'est sûr que si on veut toujours utiliser LaTeX (pour éviter d'avoir à tout refaire...) il va falloir importer les PDF... mais ça réduit déjà pas mal le travail. (:D

    111654

    Allez les gens, viendez utiliser ConTeXt LMTX. B-)

  • J'ai pas bien compris à quoi sert ConTeXt :-D

    En fait, le temps passe et je commence à mettre des mots sur ce que je veux. Il me faudrait un truc où je puisse faire du calcul formel et du LaTeX en même temps.

    Du style, un machin où j'entre une matrice, je programme le pivot de Gauss, et le programme me sort les étapes déjà rédigées en LaTeX avec simplification de toutes mes fractions.
  • En très gros, ConTeXt, à l'instar de LaTeX, est un système de composition de document. Les deux reposent sur TeX. La différence étant plus dans l'usage que la finalité.

    D'ailleurs, ce que tu proposes, de réaliser un programme qui s'occupe de générer ton pivot de Gauss, ça peut se faire aussi bien avec LaTeX à l'aide de LuaLaTeX (si je me souviens bien) qu'avec ConTeXt. Dans les deux cas tu programmes ce que tu veux en lua (que tu incorpores dans ton fichier tex) et tu appelles ta fonction lua qui réalise elle-même le tout. Tu peux alors jouer sur la composition du document pour que toutes les matrices (de toutes les étapes que tu désires) soient générées automatiquement à la compilation avec latex/context.


    Si ça t'intéresse, voir (par exemple) ici pour LuaLaTeX et ici pour ConTeXt. ;-)

    Si tu veux fouiller en profondeur, tu as aussi les manuels de luatex et de ConTeXt lua.
  • Concernant la syntaxe d'entrée concise de matrices, le package LaTeX spalign permet d'écrire des choses comme ça :
    \[ \spalignmat{1 12 -3; 24 -2 2; 0 0 1} \]
    
    Pour le reste (calcul formel avec sortie LaTeX), cela doit être faisable avec SageTeX voire expsagetex (ce dernier étant un peu expérimental, pas sur CTAN). On doit pouvoir programmer l'algorithme en Python et renvoyer le bon markup (« balisage »), ou au moins du code LaTeX pour chaque matrice (j'ai un peu oublié comment ça marche). Pour colorier des lignes et/ou colonnes, le package nicematrix peut être pratique.

    Note : les exemples avec nicematrix que j'ai donnés ici ne compilent plus avec nicematrix actuel compilent à nouveau après modification, donc attention aux changements incompatibles qui peuvent parfois se produire. Dans mon fichier d'exemples, il s'agissait :
    • des types de colonnes L, C, R qui n'existent plus sauf à utiliser l'option 'define-L-C-R' (c'est documenté en première page de 'texdoc nicematrix-french' et 'texdoc nicematrix' ; il vaut mieux désormais utiliser les types l, c, r, sauf si l'on vise la compatibilité avec nicematrix < 5.0) ;
    • d'un changement de technique dans nicematrix.sty pour détecter les cellules vides -> j'ai échangé à ce sujet avec François Pantigny. Il y a désormais ce qu'il faut (commande \NotEmpty) dans nicematrix 5.6. :-)
  • Hello,

    Vite fait pour faire un petit truc en latex automatique avec sage ! Je te laisse améliorer le code, si ca t'aide ! Là c'est tous pourri mais je n'ai pas le temps !
    class Matrice:
    	def __init__(self,M):
    		self.M = M
    		self.latex   = ["On part de $$ M= "+latex(self.M)+"$$"]
    		self.ligne 	 = M.nrows()
    		self.col	 = M.ncols()
    
    	def E(self,i,j):
    		return matrix(QQ,self.ligne, self.col,[[1 if ((i == k) and (j == l)) else 0  for k in range (self.ligne)]for  l in range(self.col)])
    	def P(self,k,lam):
    		P =  1+(lam-1)*self.E(k,k)
    		self.M = self.M * P 
    		self.latex.append("On multiplie à gauche par $$ " + latex(P)+ "$$ " +  "$$" + latex(self.M)+"$$")
    		return true  # ou bien return self.M si tu veu afficher la matrice ! 
    	def echange(self, i,j):
    		E = self.E
    		P = 1 -E(i,i) -E(j,j)+E(i,j)+E(j,i)
    		self.M = self.M * P 
    		self.latex.append("On multiplie à gauche par, ce qui echange blabla (me suis trompé avec la gauche et la droite ) $$" + latex(P)+  "$$" + " $$" + latex(self.M)+"$$")
    		return true
    	def add(self,k,i,lam):
    		E = self.E
    		P = 1 + lam* E(i,k)
    		self.M = self.M * P 
    		self.latex.append("On multiplie à gauche par $$" + latex(P)+ "$$" + "$$" + latex(self.M)+"$$")
    		return true
    

    Utilisation :
    sage: Ma = Matrice(M)
    sage: Ma.add(0,1,-2)
    True
    sage: Ma.echange(0,1)
    True
    sage: Ma.P(0,-1/2)
    True
    sage: Ma.add(0,1,-3)
    True
    sage: Ma.echange(0,1)
    True
    sage: Ma.latex
    [On part de $$ M= \left(\begin{array}{rr}
     1 & 2 \\
     3 & 4
     \end{array}\right) $$, On multiplie à gauche par $$ \left(\begin{array}{rr}
     1 & -2 \\
     0 & 1
     \end{array}\right) $$ $$ \left(\begin{array}{rr}
     1 & 0 \\
     3 & -2
     \end{array}\right) $$, On multiplie à gauche par, ce qui echange blabla $$ \left(\begin{array}{rr}
     0 & 1 \\
     1 & 0
     \end{array}\right) $$ $$ \left(\begin{array}{rr}
     0 & 1 \\
     -2 & 3
     \end{array}\right) $$, On multiplie à gauche par $$ \left(\begin{array}{rr}
     -\frac{1}{2} & 0 \\
     0 & 1
     \end{array}\right) $$ $$ \left(\begin{array}{rr}
     0 & 1 \\
     1 & 3
     \end{array}\right) $$, On multiplie à gauche par $$ \left(\begin{array}{rr}
     1 & -3 \\
     0 & 1
     \end{array}\right) $$ $$ \left(\begin{array}{rr}
     0 & 1 \\
     1 & 0
     \end{array}\right) $$, On multiplie à gauche par, ce qui echange blabla $$ \left(\begin{array}{rr}
     0 & 1 \\
     1 & 0
     \end{array}\right) $$ $$ \left(\begin{array}{rr}
     1 & 0 \\
     0 & 1
     \end{array}\right) $$]
    


    On part de $$ M= \left(\begin{array}{rr}
    1 & 2 \\
    3 & 4
    \end{array}\right) $$, On multiplie à gauche par $$ \left(\begin{array}{rr}
    1 & -2 \\
    0 & 1
    \end{array}\right) $$ $$ \left(\begin{array}{rr}
    1 & 0 \\
    3 & -2
    \end{array}\right) $$, On multiplie à gauche par, ce qui echange blabla $$ \left(\begin{array}{rr}
    0 & 1 \\
    1 & 0
    \end{array}\right) $$ $$ \left(\begin{array}{rr}
    0 & 1 \\
    -2 & 3
    \end{array}\right) $$, On multiplie à gauche par $$ \left(\begin{array}{rr}
    -\frac{1}{2} & 0 \\
    0 & 1
    \end{array}\right) $$ $$ \left(\begin{array}{rr}
    0 & 1 \\
    1 & 3
    \end{array}\right) $$, On multiplie à gauche par $$ \left(\begin{array}{rr}
    1 & -3 \\
    0 & 1
    \end{array}\right) $$ $$ \left(\begin{array}{rr}
    0 & 1 \\
    1 & 0
    \end{array}\right) $$, On multiplie à gauche par, ce qui echange blabla $$ \left(\begin{array}{rr}
    0 & 1 \\
    1 & 0
    \end{array}\right) $$ $$ \left(\begin{array}{rr}
    1 & 0 \\
    0 & 1
    \end{array}\right) $$
  • Vous pouvez utiliser Xcas pour Firefox, qui permet d'afficher les etapes de l'algorithme de Gauss.
    session Xcas
  • @flipflop : Chest choupère cha !
    @parisse : Merci, c'est vrai que pour l'enseignement j'aurais préféré un logiciel libre mais je vais partir sur le code "clés en mains" de flipflop parce que c'est un peu urgent.
  • Pardonnez-moi j’ai cru qu’il y avait une erreur entre « gauche » et « droite ».
    « On part de M, on multiplie à gauche par A » : ça donne AM plutôt, que MA. Non ?

    Juste une question toute pourrie qui n’aide personne... désolé.
    Mais je suis peut-être déjà cuit par cette ambiance conjoncturelle pourrie...
  • Dom, Dom, garde espoir ! Tu vas voir, on va apprendre plein de logique ensemble pendant ce confinement !
  • Georges Abitbol, xcas est un logiciel libre.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Oui, oui ! Du coup j'aurais bien aimé le faire sur Xcas mais je n'ai pas le temps !
  • @flipflop : C'est trop bien ce truc ! J'avance beaucoup. Par contre, j'ai un gros problème. Les .append, ça sert à rajouter des éléments dans des listes, mais... quand ça affiche le code $\LaTeX$ à la fin, ça met des virgules partout (et ça fait commencer par un "[" et terminer par un "]" mais c'est moins grave) ! C'est horrible parce que j'utilise dix mille fois .append et je ne sais pas comment faire disparaître les virgules...

    Je vais essayer de faire une fonction qui mange une liste de chaînes et qui crache juste la chaîne concaténée de tous ses éléments.
  • Je n'ai pas regardé le code de flipflop en détail, mais tu (GA) cherches sans doute str.join(). Par exemple, si l est une liste :
    • "".join(l) renvoie la concaténation de tous les éléments de l ;
    • r"\\".join(l) renvoie la même chose mais avec un double antislash comme séparateur entre deux éléments au lieu de la chaîne vide (le 'r' fait un “raw string literal”: dedans, l'antislash ne joue pas de rôle particulier, ce qui est très pratique pour les regexps et le code (La)TeX) ;
    • etc.
  • @brian : Merci !

    J'ai fait ça :
    def afficheMieuxListe(liste):
    	str = ""
    	for l in range (len(liste)):
    		str = str+liste[l]
    	return str
    

    et ça fait quasiment ce que je veux (j'ai encore des espaces qui viennent de je ne sais où) !
  • Ce qui suit ne fait-il pas la même chose ?
    def afficheMieuxListe(liste):
        return "".join(liste)
    
  • Jsais pô, j'ai que deux ou trois heures de vol en Sage :-D Mais merci !
  • En l'occurrence, ce dont je parle ici est le langage Python. Mais comme l'interpréteur Sage est un Python à quelques détails près, quasiment tout ce que tu trouveras dans les documentations ou tutoriels Python s'applique directement à Sage. Regarde ici et en particulier le chapitre « Types natifs » de la bibliothèque standard.

    NB : les dernières version de Sage utilisent Python 3, comme dans mes liens.
  • Coucou,
    voici mon code. Il s'utilise pareil que celui de flipflop, sauf que quand on a fini, on tape renduLaTeX(la-matrice-en-question.latex).
    Ca sort le code d'un beamer où les étapes apparaîtront sur différentes slides (je joins un .pdf d'exemple).

    Il me reste à régler des trucs importants : comme les coefficients de la matrice changent, la taille de celle-ci aussi et ça fait pas une animation très jolie... Il faudrait arranger ça en exigeant une place fixe pour les coefficients de la matrice, mais ça devient du LaTeX un peu fastidieux, non ?

    En ce qui me concerne, le bout de code qui suit est utilisable par n'importe qui (mais flipflop qui a une parenté intellectuelle a le droit de refuser !).

    Si vous avez des suggestions pour améliorer ça, n'hésitez pas !

    [Mettre une ' ' entre [ et i sinon, l'afficheur du forum le prend pour une bannière BBcode de mise en italique. AD]
    def renduLaTeX(liste):
    	str = ""
    	for l in range (len(liste)):
    		str = str+liste[l]
    	return str
    
    def estDansListe(liste,element):
    	for i in range (len(liste)):
    		if(liste[ i] == element):
    			return true
    	return false
    
    def listeEntiersEntre(i,j):
    	liste = []
    	for k in range (i,j):
    		liste.append(k)
    	return liste   
    
    def retireListe(liste,element):
    	listeMauvaisIndices = []
    	for i in range (len(liste)):
    		if(liste[ i] == element):
    			listeMauvaisIndices.append(i)
    	for i in range (len(listeMauvaisIndices)):
    		del liste[listeMauvaisIndices[ i]]
    	return liste
    
    def soustraitListe(liste1,liste2):
    	for i in range (len(liste2)):
    		retireListe(liste1,liste2[ i])
    	return liste1
    
    class Matrice:
    	def __init__(self,M):
    		self.M = M
    		self.latex   = ["\\begin{frame}\nOn considère la matrice \n\\[M := "+latex(self.M)+"\\]\n\\end{frame}\n\n"]
    		self.ligne 	 = M.nrows()
    		self.col	 = M.ncols()
            
    	def ecritCoeffCouleur(self,i,j,liste1,color1,liste2,color2):
    		if(j != 0):
    			self.latex.append("&")
    		if(estDansListe(liste1,i)):
    			self.latex.append("\\color{"+color1+"}")
    		if(estDansListe(liste2,i)):
    			self.latex.append("\\color{"+color2+"}")
    		self.latex.append(latex(self.M[ i][j])) 
    
    	def ecritLigneCouleur(self,i,liste1,color1,liste2,color2):
    		for j in range (self.col):
    			self.ecritCoeffCouleur(i,j,liste1,color1,liste2,color2)
    		self.latex.append("\\\\\n")
    
    	def ecritMatLignesCouleur(self,liste1,color1,liste2,color2):
    		self.latex.append("\\[\\left(\\begin{array}{")
    		for i in range (self.ligne):
    			self.latex.append("r")
    		self.latex.append("}\n")
    		for i in range (self.ligne):
    			self.ecritLigneCouleur(i,liste1,color1,liste2,color2)
    		self.latex.append("\\end{array}\\right)\\]\n")
    		return true
            
    	def E(self,i,j):
    		return matrix(QQ,self.ligne, self.col,[[1 if ((i == k) and (j == l)) else 0  for k in range (self.ligne)]for  l in range(self.col)])
    
    	def P(self,k,lam):
    		indicesPasTouches = retireListe(listeEntiersEntre(0,self.ligne), k)
    		self.latex.append("\\begin{frame}\n")
    		self.latex.append("\\["+latex(self.M)+"\n\\]")
    		self.latex.append("\n\\end{frame}\n\n")
    		self.latex.append("\n\n\\begin{frame}\n")
    		self.ecritMatLignesCouleur([k],"black",indicesPasTouches,"lightgray")
    		self.latex.append("On multiplie la ligne $" + latex(k+1) + "$ par $" + latex(lam) + "$.\n\\end{frame}\n\n")
    		P =  1+(lam-1)*self.E(k,k)
    		self.M = P * self.M 
    		self.latex.append("\\begin{frame}\n")
    		self.ecritMatLignesCouleur([k],"blue",indicesPasTouches,"lightgray")
    		self.latex.append("On a multiplié la ligne $" + latex(k+1) + "$ par $" + latex(lam) + "$.\n\\end{frame}\n\n")
    		return self.M  # ou bien return self.M si tu veux afficher la matrice ! 
        
    	def echange(self, i,j):
    		indicesPasTouches = soustraitListe(listeEntiersEntre(0,self.ligne), [ i,j])
    		self.latex.append("\\begin{frame}\n")
    		self.latex.append("\\["+latex(self.M)+"\n\\]")
    		self.latex.append("\n\\end{frame}\n\n")
    		self.latex.append("\\begin{frame}\n")
    		self.ecritMatLignesCouleur([ i,j],"black",indicesPasTouches,"lightgray")
    		self.latex.append("On échange les lignes $" + latex(i+1) + "$ et $" + latex(j+1) + "$.\n\\end{frame}\n\n")
    		E = self.E
    		P = 1 -E(i,i) -E(j,j)+E(i,j)+E(j,i)
    		self.M = P * self.M
    		self.latex.append("\\begin{frame}\n")
    		self.ecritMatLignesCouleur([ i,j],"blue",indicesPasTouches,"lightgray")
    		self.latex.append("On a échangé les lignes $" + latex(i+1) + "$ et $" + latex(j+1) + "$.\n\\end{frame}\n\n")
    		return self.M
    
    	def add(self,k,i,lam):
    		indicesPasTouches = soustraitListe(listeEntiersEntre(0,self.ligne), [ i,k])
    		self.latex.append("\\begin{frame}\n")
    		self.latex.append("\\["+latex(self.M)+"\n\\]")
    		self.latex.append("\n\\end{frame}\n\n")
    		self.latex.append("\\begin{frame}\n")
    		self.ecritMatLignesCouleur([ i,k],"black",indicesPasTouches,"lightgray")
    		self.latex.append("On ajoute $" + latex(lam) + "$ fois la ligne $" + latex(i+1) + "$ à la ligne $" + latex(k+1) + "$.\n\\end{frame}\n\n")
    		E = self.E
    		P = 1 + lam* E(i,k)
    		self.M = P * self.M
    		self.latex.append("\\begin{frame}\n")
    		self.ecritMatLignesCouleur([k],"blue",indicesPasTouches,"lightgray")
    		self.latex.append("On a ajouté $" + latex(lam) + "$ fois la ligne $" + latex(i+1) + "$ à la ligne $" + latex(k+1) + "$.\n\\end{frame}\n\n")
    		return self.M
    
  • Ça devrait moins bouger d'une page à l'autre si tu passes 'fleqn' en option à \documentclass, par exemple :
    \documentclass[french,fleqn]{beamer}
    
  • Nouvelle version avec tikz. C'est 'achement plus propre ! Par contre, je ne sais pas comment mettre des parenthèses à ma matrice :-D
    Bon, je m'arrête là pour aujourd'hui ! Encore merci aux personnes qui m'ont aidé !

    [Mettre une ' ' entre [ et i sinon, l'afficheur du forum le prend pour une bannière BBcode de mise en italique. AD]
    def renduLaTeX(liste):
    	str = ""
    	for l in range (len(liste)):
    		str = str+liste[l]
    	return str
    
    def estDansListe(liste,element):
    	for i in range (len(liste)):
    		if(liste[ i] == element):
    			return true
    	return false
    
    def listeEntiersEntre(i,j):
    	liste = []
    	for k in range (i,j):
    		liste.append(k)
    	return liste   
    
    def retireListe(liste,element):
    	listeMauvaisIndices = []
    	for i in range (len(liste)):
    		if(liste[ i] == element):
    			listeMauvaisIndices.append(i)
    	for i in range (len(listeMauvaisIndices)):
    		del liste[listeMauvaisIndices[ i]]
    	return liste
    
    def soustraitListe(liste1,liste2):
    	for i in range (len(liste2)):
    		retireListe(liste1,liste2[ i])
    	return liste1
    
    def renvoieTexteDilateAvant(i,lam):
    	return "On multiplie la ligne $" + latex(i+1) + "$ par $" + latex(lam) + "$.\n"
    
    def renvoieTexteDilateAprès(i,lam):
    	return "On a multiplié la ligne $" + latex(i+1) + "$ par $" + latex(lam) + "$.\n"
    
    def renvoieTexteEchangeAvant(i,j):
    	return "On échange les lignes $" + latex(i+1) + "$ et $" + latex(j+1) + "$.\n"
    
    def renvoieTexteTransvecteAvant(j,i,lam):
    	return "On ajoute $" + latex(lam) + "$ fois la ligne $" + latex(i+1) + "$ à la ligne $" + latex(j+1) + "$.\n"
    
    class Matrice:
    	def __init__(self,M):
    		self.M = M
    		self.latex   = ["\\begin{frame}\nOn considère la matrice \n\\[M := "+latex(self.M)+"\\]\n\\end{frame}\n\n"]
    		self.ligne 	 = M.nrows()
    		self.col	 = M.ncols()
            
    	def ecritEnTeteFrame(self):
    		self.latex.append("\\begin{frame}\n")
            
    	def ecritFinFrame(self):
    		self.latex.append("\\end{frame}\n\n")
            
    	def ecritEnTetePicture(self):
    		self.latex.append("\\begin{tikzpicture}\n")
            
    	def ecritFinPicture(self):
    		self.latex.append("\\end{tikzpicture}\n\n")
            
    	def ecritAncrageHautGauche(self):
    		self.latex.append("\\node at (-1,1) {};\n")
            
    	def ecritEnTeteNoeud(self,isText):
    		if(isText == true):        
    			self.latex.append("\\node[anchor=west] at")
    		else:        
    			self.latex.append("\\node at")
            
    	def ecritFinNoeud(self):
    		self.latex.append("};\n")
            
    	def ecritPositionNoeud(self,i,j):
    		self.latex.append("("+str(j)+","+str(-i)+") ")
    
    	def ecritCouleurCoefficient(self,i,j,liste1,color1,liste2,color2):
    		if(estDansListe(liste1,i)):
    			self.latex.append("\\color{"+color1+"}")
    		if(estDansListe(liste2,i)):
    			self.latex.append("\\color{"+color2+"}")
    
    	def ecritCoefficientCouleur(self,i,j,liste1,color1,liste2,color2):
    		self.ecritEnTeteNoeud(false)
    		self.ecritPositionNoeud(i,j)
    		self.latex.append("{")
    		self.ecritCouleurCoefficient(i,j,liste1,color1,liste2,color2)
    		self.latex.append("$"+latex(self.M[ i][j])+"$")
    		self.ecritFinNoeud()
            
    	def ecritNoeud(self,texte,i):
    		self.ecritEnTeteNoeud(true)
    		self.ecritPositionNoeud(i,self.ligne+1)
    		self.latex.append("{"+texte)
    		self.ecritFinNoeud()
    
    	def ecritLigneCouleur(self,i,liste1,color1,liste2,color2):
    		for j in range (self.col):
    			self.ecritCoefficientCouleur(i,j,liste1,color1,liste2,color2)
    
    	def ecritMatLignesCouleur(self,liste1,color1,liste2,color2):
    		for i in range (self.ligne):
    			self.ecritLigneCouleur(i,liste1,color1,liste2,color2)
    		return true
                              
    	def ecritPicture(self,liste1,color1,liste2,color2,texte_1,texte_2,texte_3):
    		self.ecritEnTetePicture()
    		self.ecritAncrageHautGauche()
    		self.ecritMatLignesCouleur(liste1,color1,liste2,color2)
    		self.ecritNoeud(texte_1,1)
    		self.ecritNoeud(texte_2,2)
    		self.ecritNoeud(texte_3,3)
    		self.ecritFinPicture () 
    		return true
            
    	def E(self,i,j):
    		return matrix(QQ,self.ligne, self.col,[[1 if ((i == k) and (j == l)) else 0  for k in range (self.ligne)]for  l in range(self.col)])
    
    	def P(self,k,lam):
    		indicesPasTouches = retireListe(listeEntiersEntre(0,self.ligne), k)
    # on écrit la première matrice, sans rien
    		self.ecritEnTeteFrame()
    		self.ecritPicture([],"black",[],"black","","","")
    		self.ecritFinFrame()
    # on écrit la deuxième matrice en coloriant les lignes qui vont bouger
    		self.ecritEnTeteFrame()
    		self.ecritPicture([k],"black",indicesPasTouches,"lightgray",renvoieTexteDilateAvant(k,lam),"","")
    		self.ecritFinFrame()
    # on calcule les changements
    		P =  1+(lam-1)*self.E(k,k)
    		self.M = P * self.M 
    # on écrit la troisème matrice
    		self.ecritEnTeteFrame()
    		self.ecritPicture([k],"green",indicesPasTouches,"lightgray",renvoieTexteDilateAvant(k,lam),"C'est fait !","")
    		self.ecritFinFrame()
    		return self.M  # ou bien return self.M si tu veux afficher la matrice ! 
        
    	def echange(self, i,j):
    		indicesPasTouches = soustraitListe(listeEntiersEntre(0,self.ligne), [ i,j])
    # on écrit la première matrice, sans rien
    		self.ecritEnTeteFrame()
    		self.ecritPicture([],"black",[],"black","","","")
    		self.ecritFinFrame()
    # on écrit la deuxième matrice en coloriant les lignes qui vont bouger
    		self.ecritEnTeteFrame()
    		self.ecritPicture([ i,j],"black",indicesPasTouches,"lightgray",renvoieTexteEchangeAvant(i,j),"","")
    		self.ecritFinFrame()
    # on calcule les changements
    		E = self.E
    		P = 1 -E(i,i) -E(j,j)+E(i,j)+E(j,i)
    		self.M = P * self.M
    # on écrit la troisème matrice
    		self.ecritEnTeteFrame()
    		self.ecritPicture([ i,j],"blue",indicesPasTouches,"lightgray",renvoieTexteEchangeAvant(i,j),"C'est fait !","")
    		self.ecritFinFrame()
    		return self.M
    
    	def add(self,k,i,lam):
    		indicesPasTouches = soustraitListe(listeEntiersEntre(0,self.ligne), [ i,k])
    # on écrit la première matrice, sans rien
    		self.ecritEnTeteFrame()
    		self.ecritPicture([],"black",[],"black","","","")
    		self.ecritFinFrame()
    # on écrit la deuxième matrice en coloriant les lignes qui vont bouger
    		self.ecritEnTeteFrame()
    		self.ecritPicture([k],"black",indicesPasTouches,"lightgray",renvoieTexteTransvecteAvant(k,i,lam),"","")
    		self.ecritFinFrame()
    # on calcule les changements
    		E = self.E
    		P = 1 + lam* E(i,k)
    		self.M = P * self.M
    # on écrit la troisième matrice
    		self.ecritEnTeteFrame()
    		self.ecritPicture([k],"red",indicesPasTouches,"lightgray",renvoieTexteTransvecteAvant(k,i,lam),"C'est fait !","")
    		self.ecritFinFrame()
    		return self.M
    
  • Quelques précisions.
    D'abord, aussi bien sagemaths que Xcas ou Xcas pour Firefox sont des logiciels libres.
    Ensuite la différence principale entre les codes ci-dessus et Xcas pour Firefox, c'est que l'algorithme du pivot de Gauss se fait à la main dans le premier cas et automatiquement dans le second. Chaque approche a son intérêt, c'est la raison pour laquelle Xcas propose des commandes pour faire Gauss à la main : rowSwap, rowAdd, mRow, mRowAdd, en plus de la possibilité de le faire pas à pas automatiquement.
    L'essentiel à mon avis, c'est que les étudiants soient actifs à un moment et donc manipulent eux-mêmes, que ce soit avec papier-crayon sur des exemples très simples ou en utilisant la machine pour faire les calculs arithmétiques sur les entiers ou fractions.
  • brian a écrit:
    En l'occurrence, ce dont je parle ici est le langage Python. Mais comme l'interpréteur Sage est un Python à quelques détails près,

    Je veux bien les détails.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Tu peux avantageusement remplacer les fonctions :
    def renduLaTeX(liste):
    	str = ""
    	for l in range (len(liste)):
    		str = str+liste[l]
    	return str
    
    def estDansListe(liste,element):
    	for i in range (len(liste)):
    		if(liste[ i] == element):
    			return true
    	return false
    
    def listeEntiersEntre(i,j):
    	liste = []
    	for k in range (i,j):
    		liste.append(k)
    	return liste   
    
    def retireListe(liste,element):
    	listeMauvaisIndices = []
    	for i in range (len(liste)):
    		if(liste[ i] == element):
    			listeMauvaisIndices.append(i)
    	for i in range (len(listeMauvaisIndices)):
    		del liste[listeMauvaisIndices[ i]]
    	return liste
    
    def soustraitListe(liste1,liste2):
    	for i in range (len(liste2)):
    		retireListe(liste1,liste2[ i])
    	return liste1
    

    Par :
    def renduLaTeX(liste):
    	return "".join(liste)
    
    def estDansListe(liste,element):
    	return element in liste
    
    def listeEntiersEntre(i,j):
    	return list(range(i,j)) # ou bien [k for k in range(i,j)]
    
    def retireListe(liste,element):
    	return [k for in liste if k != element] # Ne modifie pas liste par effet de bord
    
    def soustraitListe(liste1,liste2):
    	for k in liste2:
    		liste1 = retireListe(liste1,k)
    	return liste1 #Ne modifie pas liste1 par effet de bord
    

    On peut même utiliser les ensembles Python pour simplifier la dernière :
    def soustraitListe(liste1,liste2):
            #on convertit en ensembles, puis on soustrait les ensembles et on reconvertit en liste
    	return list(set(liste1) - set(liste2))
    
  • @Georges

    Pour les parenthèses (ou crochets, barres verticales, accolades...) autour d'une matrice TikZ, j'ai donné trois techniques différentes à la section 2 du document exemple ici. La plus simple est :
    \usetikzlibrary{matrix} % après le \usepackage{tikz}
    
    (...)
    
    \begin{tikzpicture}
    \matrix[matrix of nodes, left delimiter=(, right delimiter=)]
      {
        8 & 1 & 6 \\
        3 & 5 & 7 \\
        4 & 9 & 2 \\
      };
    \end{tikzpicture}
    

    @nicolas.patrois

    C'est une histoire de preprocessing. Pour l'exécution interactive, voir Paste Ignores Prompts dans The Interactive Shell :
    the Sage parser strips any leading >>> or sage: prompt before passing it to Python.
    Pour la programmation hors de l'interpréteur ligne à ligne (le REPL), voir Programming:
    When Sage loads example.sage, it converts it to Python, which is then executed by the Python interpreter. This conversion is minimal; it mainly involves wrapping integer literals in Integer(), floating point literals in RealNumber(), replacing ^’s by **’s, and replacing e.g., R.2 by R.gen(2). The converted version of example.sage is contained in the same directory as example.sage and is called example.sage.py.
  • Merci.
    Ça m’embête bien, cette histoire de chapeau pour la puissance.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • C'est un peu superflu, en effet. J'imagine que ça améliore significativement la lisibilité des expressions contenant beaucoup de puissances, donc ça doit en arranger certains. Pour l'accès au bitwise XOR, c'est ^^ ou la méthode __xor__() (de la classe Integer, je suppose) : How do I use the bitwise XOR operator in Sage?
  • @brian : Oui mais j'ai opté pour Tikz pour avoir un placement absolu des coefficients de ma matrice. Est-ce que \matrix permet de faire ça ? Moi j'ai pas utilisé \matrix mais
    \begin{tikzpicture}
    

    puis, pour tout $i,j$,
    \node at (i,-j) {$a_{i,j}$};
    

    puis
    \node at (5,-1) {Blablabla (bref du texte)};
    
    \endtikzpicture
    

    et ce que je voudrais, c'est que les coefficients de la matrice soient entre des parenthèses, mais pas le texte.

    Si \matrix me permet de placer les coefficients de manière absolue au sein d'une tikzpicture où je peux également placer le texte de manière absolue, d'accord, mais je ne sais pas comment faire.
  • @Georges

    Je n'ai pas très bien compris : les parenthèses que tu veux, ce sont bien les délimiteurs de la matrice, ou bien parles-tu de mettre certains coefficients entre parenthèses  ?

    Je suppose le premier cas. Avec TikZ, je vois deux-trois possibilités :

    1) Si tu places les coefficients les uns après les autres avec des
    \node at (5,-1) {...};
    
    dans n'importe quel ordre, tu peux tracer les parenthèses avec un \draw dans lequel tu fais tout à la main, ou bien avec quelque chose du genre :
    \usetikzlibrary{decorations.pathreplacing, calligraphy}
    
    (...)
    
    \draw[decorate, decoration={brace, mirror, amplitude=5pt}] (point A) -- (point B);
    

    2) Sinon, tu peux utiliser une matrice TikZ et avec elle, la solution que j'ai donnée plus haut ('left delimiter=('...). Ce n'est pas grave si le programme Python obtient les coefficients dans un ordre quelconque : il suffit de ne sortir le code la matrice que quand on a déjà préparé tous les coefficients dans un objet Python (liste de listes...). Les matrices TikZ sont très souples. Il s'agit d'un objet réalisant automatiquement des alignements de type quadrillage (à deux dimensions, donc) et permettant d'accéder facilement à la bordure rectangulaire et aux points intéressants (centre, nord-est, sud, etc.) du tout comme de chaque cellule. Les cellules elles-mêmes peuvent s'apparenter à des mini-'tikzpictures', à ceci près qu'il ne faut pas écrire le \begin{tikzpicture} ... \end{tikzpicture} (il est interdit d'imbriquer ces environnements ; enfin, c'est très fortement déconseillé), mais chacune a sa propre origine, par exemple. Ça, c'est la version la plus générale. Après, si l'on utilise les styles (options) 'matrix of nodes' ou 'matrix of math nodes', TikZ fait pour toi un \node par cellule, dont le contenu est ce que tu mets entre deux & ou entre un & et le \\ qui termine la ligne. La syntaxe est donc plus légère de cette manière, et c'est très souvent suffisant. Il y a un style 'nodes in empty cells' pour contrôler ce qui se passe si tu as '& &' ou '& \\' dans ta matrice : noeud vide ou pas de nœud du tout (sachant qu'un nœud peut être encadré et/ou coloré, avoir une hauteur et/ou une largeur minimale, du code TeX inséré automatiquement au début et/ou à la fin...).

    Le plus simple serait peut-être que tu postes un exemple court (complet minimal) de ce que tu veux : code LaTeX minimal avec une matrice, capture d'écran ou dessin de l'aspect souhaité.
  • Pour compléter un peu ce que je viens d'écrire sur les matrices TikZ, je conseillerais de :
    • regarder le premier exemple dans la section Matrices and Alignment (voir capture d'écran ci-dessous) ;
    • lire un peu plus loin Alignment of Cell Pictures dans le manuel de TikZ et PGF : je trouve limpide la description de l'algorithme utilisé pour aligner verticalement les cellules d'une même ligne, et horizontalement celles d'une même colonne.

    Notes :
    • il vaut mieux utiliser la syntaxe 'circle[radius=3mm]' (la syntaxe 'circle (3mm)' est obsolète et cause des bugs avec des versions de pgfplots pas si anciennes que ça).
    • cette partie de la discussion pourrait avoir lieu dans le sous-forum LaTeX.
    111902
  • brian a écrit:
    les parenthèses que tu veux, ce sont bien les délimiteurs de la matrice, ou bien parles-tu de mettre certains coefficients entre parenthèses ?

    C'est simple : il n'y a pas, formellement, de matrices. Actuellement, j'ai juste neuf nodes qui sont placés "en carré", plus un node contenant du texte qui est loin des neuf autres.
    Je voudrais des parenthèses autour des neuf, pour que cela ressemble à une matrice. Je n'ai pas utilisé d'environnement \matrix car je ne sais pas si je peux fixer la position des coefficients d'une matrice moi-même.

    Je joins une image. Je veux que les coefficients de ma matrice soient centrés en les coins du quadrillage rouge qui est fixé, et que les parenthèses autour de la matrice ne bougent pas, même si le coefficient en haut à gauche est $\frac{\frac{123456789}{5555555555555}}{\frac{5468432115}{2132321213132321}}$. Dans ce cas, la parenthèse serait en surimpression par rapport au coefficient.

    En fait, l'idéal serait de dire à Tikz : voici une boîte que tu dois imaginer mais ne pas dessiner ; autour de cette boîte invisible, tu mets des jolies parenthèses pile-poil adaptées à cette boîte ; d'autre part, voici des trucs que tu dois dessiner, et il se trouve que tu dois les dessiner à l'intérieur de la boîte invisible, mais c'est une coïncidence (clin d'oeil clin d'oeil).

    EDIT : Fraction corrigée.111920
  • Coucou,

    merci brian !
    \draw[decorate, decoration={brace, mirror, amplitude=5pt}] (point A) -- (point B);
    

    fonctionne chez moi... Mais j'ai un mal fou à trouver par quel mot remplacer "brace" pour obtenir une parenthèse :-D
  • Il est possible de faire ton alignement avec une matrice TikZ, mais si tu veux vraiment que rien ne bouge, il faudrait mettre chaque coefficient dans une boîte invisible de dimensions fixes — quitte à ce que le contenu déborde sans que TeX ne le sache. En effet, le comportement normal d'une matrice TikZ est de trouver la largeur minimale pour chaque colonne et la hauteur minimale pour chaque ligne, puis d'insérer les éventuels séparateurs choisis (cf. algorithme que j'ai référencé plus haut avec 'row sep', 'column sep', argument optionnel de & et de \\).

    On va partir du principe que tu gardes ta solution mais veux juste l'équivalent de :
    \draw[decorate, decoration={brace, mirror, amplitude=5pt}] (point A) -- (point B);
    
    avec des parenthèses. Il se trouve que « parenthèse » ne fait pas partie des décorations définies dans la bibliothèque TikZ/PGF 'decorations.pathreplacing', mais il y en a dans 'calligraphy'. Comme je l'ai dit plus haut et montré dans mon exemple, tu peux tracer des parenthèses « calligraphiques » avec :
    \usetikzlibrary{decorations.pathreplacing, calligraphy}
    
    (...)
    
    \draw[decorate, line width=0.6pt,
          decoration={calligraphic straight parenthesis, amplitude=1mm}]
      (point A) -- (point B);
    
    Tu peux remplacer 'calligraphic straight parenthesis' par 'calligraphic curved parenthesis' pour un aspect arrondi tout le long de la parenthèse (cf. capture d'écran à la fin de mon message déjà cité). Utilise 'mirror' pour avoir l'autre parenthèse.
Connectez-vous ou Inscrivez-vous pour répondre.