Matrices "avancées"

Bonjour à tous,

Suite à un TD que j'ai enseigné pendant plusieurs années j'ai décidé de rédiger un petit pdf dont le titre serait quelque chose comme "Petit guide pratique de la réduction de Jordan à l'usage des étudiants". Je me heurte cependant à un gros souci : je n'arrive pas à faire de belles matrices. Y aurait-il une source en ligne qui traiterait de façon avancée les matrices sous latex ? J'aimerais pouvoir régler la taille des lignes et colonnes, tracer des traits (ou des pointillés) entre deux éléments de ma matrice et placer des rectangles/triangles/trapèzes à l'intérieur de mes matrices (pour indiquer qu'une partie de ma matrice est constituée de $0$ ou pour marquer des blocs sur la diagonale etc). Le tout si possible sans avoir à utiliser tikz...

J'ai un peu cherché sur google mais je n'ai rien trouvé de très concluant, juste les trucs basiques.

Réponses

  • En excluant totalement TikZ, ça risque d'être un peu limité (enfin, on peut faire des choses assez élaborées avec PSTricks par exemple, mais ça n'est probablement pas plus simple qu'avec TikZ). Je pense que l'on peut proposer l'extension nicematrix de F. Pantigny, documentée en français et en anglais. Elle utilise TikZ mais te permet de faire un certain nombre de choses sans l'utiliser toi-même. Pour celles qui nécessitent un peu de code TikZ, il y a plusieurs exemples intéressants dans le manuel qui montrent comment s'y prendre. De toute manière, on ne peut raisonnablement espérer avoir de la souplesse sans un langage un peu puissant derrière.

    Autrement, il y a l'extension drawmatrix d'Elmar Peise, qui s'appuie également sur TikZ et permet visiblement de tracer facilement certains blocs polygonaux. Il y a aussi blkarray de David Carlisle mais attention, l'interface est présentée comme très instable :
    The commands defined in this style are quite likely to have both their user-interface, and their internal definitions changed in later versions.

    Il y a aussi l'extension matrix de TikZ. Oui, j'ai bien lu la question, mais ça doit permettre de s'en sortir dans plein de situations non prévues par les autres packages — quitte à mettre un peu la main à la pâte. Voir Matrix Library dans le manuel de TikZ et PGF.

    (J'imagine que tu connais déjà les environnements matrix, pmatrix, bmatrix, Bmatrix, vmatrix, Vmatrix, smallmatrix d'amsmath et leurs variantes dans mathtools.)

    Edit: coquille.
  • Merci beaucoup pour toute ces idées, je ne connaissais pas l'extension matrix de tikz, ça vaut le coup d'aller regarder. Je vais aller potasser tout ça tranquillement. :-)
  • J'ai oublié de préciser : concernant TikZ, il y a deux sections du manuel à consulter (au moins, mais je pense que ça couvre l'essentiel sur les matrices) :
    1. Matrices and Alignment dans la partie III (TikZ ist kein Zeichenprogramm) ;
    2. Matrix Library dans la partie V (Libraries).
    À lire dans cet ordre. ;-)
  • Le document LaTeX ci-joint montre l'usage de quelques techniques répondant — je crois — à la question (plus joujou avec les décorations TikZ pour faire de jolies parenthèses...). J'ai laissé la matrice comportant des blocs rectangulaires représentés avec TikZ pour le message suivant.

    N.B. : l'essentiel du préambule du document n'est utilisé que pour :
    • la présentation des exemples ;
    • mon environnement 'callibraced' qui automatise le placement de parenthèses calligraphiques faites avec TikZ autour d'un environnement du package nicematrix.
    Regarde les commentaires et enlève ce que tu n'utilises pas (pour la plupart des exemples de la première partie, il suffit de charger le package 'nicematrix', éventuellement aussi 'tikz' pour être propre lorsqu'on ajoute soi-même des choses avec TikZ : blocs grisés, etc.).

    La compilation du document nécessite au moins deux passes ('nicematrix' utilise abondamment le fichier .aux, les environnements “raster” de 'tcolorbox' s'en servent aussi).

    Dernières modifications :
    • utilisation des types de colonnes l, c, r au lieu des anciens L, C, R dans les environnements NiceArray et dérivés (si votre version de nicematrix est plus ancienne que 5.0, utilisez les types de colonnes L, C, R dans ces environnements) ;
    • code de \storeLowerLeftNMNode plus simple et plus élégant ;
    • remplacement de ma commande \NMNonEmptyCell par \NotEmpty (disponible dans nicematrix à partir de la version 5.6 ; mon code fonctionne quand même si la version de nicematrix est plus ancienne).
    93832
    93834
  • Voici une manière un peu plus simple d'obtenir la matrice nilpotente du message précédent avec le bloc triangulaire grisé (on s'évite notamment le \edef\nmprefix{...}) :
    \documentclass{article}
    \usepackage{nicematrix}
    \usepackage{tikz}
    
    \begin{document}
    
    % Matrice nilpotente déjà vue, méthode un peu plus simple
    $N = \begin{pNiceMatrix}[name=nilp, margin]
    0      & 1                      & 0      & \Cdots  & 0      \\
           &                        &        & \Ddots  & \Vdots \\
    \Vdots &                        &        & \Ddots  & 0      \\
           & \Block{1-2}<\LARGE>{0} &        & \Ddots  & 1      \\\noalign{\kern 2mm}
    0      & \Cdots                 &        &         & 0
    \end{pNiceMatrix}$%
    %
    \begin{tikzpicture}[remember picture, overlay]
      \coordinate (a) at ([xshift=-5pt]nilp-1-3.north west);
      \coordinate (b) at ([yshift=-5pt]nilp-3-5.south east);
      \coordinate (c) at (nilp-1-5.north east);
      \coordinate (a0) at (nilp-1-3);
      \coordinate (b0) at (nilp-3-5);
      \coordinate (c0) at (nilp-1-5);
      \fill[gray!20, blend mode = multiply] (a) -- (b) -- (c) -- cycle;
      \node at (barycentric cs:a0=1,b0=1,c0=1) {\LARGE $0$};
    \end{tikzpicture}
    
    \end{document}
    

    Voici un exemple de matrice comportant des blocs rectangulaires (comme l'exemple précédent, il est fait avec nicematrix et TikZ) :
    \documentclass{article}
    \usepackage{xparse}
    \usepackage{nicematrix}
    \usepackage{tikz}
    \usetikzlibrary{fit}
    
    % Style commun aux blocs
    \tikzset{
      myblock/.style 2 args={
        rectangle, draw, minimum height={#1}, minimum width={#2}},
      myblock/.default={1cm}{1cm},
    }
    
    % On peut faire sans cela (et donc sans xparse) mais la commande \myblock
    % limite la redondance dans le code pour la matrice.
    \makeatletter
    \ExplSyntaxOn
    \cs_new_protected:Npn \__corto_create_block_node:nnnNn #1#2#3#4#5
      {
        \IfBooleanF {#1} { \begin{tikzpicture} }
        \node[#2, #3] { $\m@th #4#5$ };
        \IfBooleanF {#1} { \end{tikzpicture} }
      }
    
    \cs_generate_variant:Nn \__corto_create_block_node:nnnNn { nf }
    
    % #1 : permet de savoir si c'est la forme étoilée qui est utilisée
    % #2 : vide ou paire définissant les dimensions minimales : {hauteur}{largeur}
    % #3 : clés PGF supplémentaires passées au nœud créé par
    %      \__corto_create_block_node:nnnNn
    % #4 : style mathématique (par défaut : \displaystyle)
    % #5 : contenu à mettre dans le texte du nœud. Il sera composé en mode
    %      mathématique dans le style donné par #4.
    %
    % La forme étoilée ne sort pas le \begin{tikzpicture} ni le \end{tikzpicture},
    % et c'est sa seule différence avec la forme non étoilée.
    \NewDocumentCommand \myblock { s O{} O{} O{\displaystyle} m }
      {
        \__corto_create_block_node:nfnNn {#1}
          {
            \tl_if_blank:nTF {#2}
              % Si #2 est vide, on utilise la valeur par défaut du style 'myblock'
              { myblock=\pgfkeysnovalue }
              % sinon, on passe la valeur #2 au style 'myblock'.
              { myblock={#2} }
          }
          {#3} #4 {#5}
      }
    \ExplSyntaxOff
    \makeatother
    
    \begin{document}
    
    % Matrice comportant des blocs rectangulaires
    $M = \begin{pNiceMatrix}[name=foo, margin, create-extra-nodes]
    \noalign{\kern 2mm} % Pour ajouter un peu de blanc en haut
    \myblock{A_{11}}       & \myblock{A_{12}} & \hspace*{1cm}          \\
    \Block{1-1}<\LARGE>{0} & \raisebox{-0.35\height}{\myblock{A_{22}}} \\
    \noalign{\kern 2mm} % un peu de blanc en bas
    \end{pNiceMatrix}$%
    %
    % Ajout du bloc de droite
    \begin{tikzpicture}[remember picture, overlay]
      \coordinate (aa) at (foo-1-3-medium.north west);
      \coordinate (bb) at (foo-2-3-medium.south east);
      \myblock*[{0pt}{0pt}][inner sep=0, fill=gray!10, fit=(aa) (bb)]{B}
    \end{tikzpicture}
    
    \end{document}
    

    En changeant par exemple la première (vraie) ligne de la matrice précédente comme ceci :
    \myblock[{2cm}{3cm}]{A_{11}} & \myblock[{2cm}{1cm}]{A_{12}} & \hspace*{1cm} \\
    
    on obtient la troisième capture d'écran (blocs-rectangulaires-variante.png).

    Edits:
    • modification de la capture d'écran de la matrice nilpotente pour éviter qu'elle ne remplisse toute la page ;
    • suppression d'un artefact dû à la capture d'écran à niveau de zoom pas assez élevé dans la troisième image ;
    • petite amélioration (forme étoilée de \myblock pour factoriser un peu plus) et ajout de commentaires dans le code — notamment sur les arguments de \myblock ;
    • modifications d'indentation (pour une meilleure lisibilité) ;
    • suppression d'un commentaire suite à une mise à jour du message précédent.
    93618
    93620
    93622
  • J'ai amélioré mon premier message comportant des exemples. Entre les deux approches, celle utilisant 'nicematrix' me semble un peu plus pratique pour écrire des maths (disons, si les matrices se trouvent souvent au milieu de formules mathématiques). Mentionnons tout de même le code de Loop Space visant à rendre l'utilisation de matrices TikZ au sein de formules mathématiques à peu près transparente (je ne l'ai pas testé).

    Il faut bien se rendre compte que 'nicematrix' s'appuie sur l'environnement 'array' du package 'array' (plus 'amsmath', plus du code TikZ pour les pointillés et autres bricoles). En revanche, les matrices TikZ sont un truc totalement différent, à utiliser dans une 'tikzpicture'. J'espère que je ne t'ai pas mis sur une fausse route en donnant des références vers le manuel de TikZ et PGF.
  • @Brian

    Bonjour,

    Je suis François Pantigny et c'est moi qui ai écrit l'extension 'nicematrix'. J'ai vu votre document (très bien fait) et j'ai vu que, pour mettre les parenthèses calligraphiques de Tikz sur des matrices de 'nicematrix', vous avez dû utiliser une commande interne de 'nicematrix'.

    Voyant cela, j'ai ajouté dans la dernière version de 'nicematrix' (v. 3.9 2020-01-10) une nouvelle commande '\NiceMatrixLastEnv' qui donne le numéro du dernier environnement de 'nicematrix'.
  • Bonjour,

    Super ! J'avais dans un coin de ma tête « il faut écrire à F. Pantigny » au sujet de ces macros privées, mais la vie étant ce qu'elle est... je n'y étais pas encore arrivé. Je vais regarder ces nouvelles possibilités dès que les vents seront favorables. :-) Merci pour ce chouette package et pour avoir lu mon code !

    Une chose que je voulais vous dire au sujet de nicematrix : les possibilités avec les pointillés sont déjà très intéressantes, mais sur le plan esthétique, j'aurais aimé pouvoir faire en sorte qu'il y ait une petite marge réglable entre les pointillés et la cellule d'où ils partent / sur laquelle ils arrivent. Ce n'est pas très embêtant, mais si c'est facile à ajouter pour vous, il me semble que ce serait appréciable.
  • Je viens de mettre, dans la dernière version de nicematrix (version 3.10, 2020/01/22), une option 'dotted-lines-margin' qui permet de régler l'écart entre un nœud et l'extrémité de la ligne en pointillés.
    Voilà, voilà...
  • Bonjour,

    J'ai mis à jour mon message ci-dessus pour utiliser \NiceMatrixLastEnv au lieu de la variable privée \g__nm_env_int. Désolé d'avoir autant traîné, mais c'est fait. :-) Encore merci pour l'ajout de \NiceMatrixLastEnv et de l'option que vous venez de mentionner concernant les pointillés !
Connectez-vous ou Inscrivez-vous pour répondre.