Partage
  • Partager sur Facebook
  • Partager sur Twitter

Inversibilité de matrice par quoi ?

Un algo que je saisis mal

    27 janvier 2011 à 14:01:53

    Salut

    j'ai appris qu'une matrice était inversible si son déterminant != 0.

    Mais fail de mémoire: inversible par rapport à quoi ? Le pivot de Gauss ?

    Merci d'éventuels éclaircissements...
    • Partager sur Facebook
    • Partager sur Twitter
      27 janvier 2011 à 14:11:48

      Salut,

      l'inversibilité n'a rien avoir avec la manière dont tu l'inverses: pouvoir inverser une matrice, c'est dire que l'endomorphisme qu'elle représente est bijectif (a priori rien de plus).
      Une matrice est inversible si les colonnes de ta matrice forment une famille indépendante de vecteurs (grosso modo une base d'un espace de dimension finie). Si cette famille est liée, et c'est une équivalence en fait, le déterminant de la matrice est nul. Je te renvoie également à la manière dont on construit une matrice, sa signification, etc...
      Tu peux éventuellement mieux le voir en regardant la formule de résolution d'un système linéaire de n équations à n inconnues (formule de Cramer il me semble).

      Bonne journée

      Marc
      • Partager sur Facebook
      • Partager sur Twitter

      Avez-vous entendu parler de Julia ? Laissez-vous tenter ...

        27 janvier 2011 à 14:32:30

        Bonjour,

        La définition d'inversibilité d'une matrice est comme dans tout Anneau :

        <math>\(Soit \; A\in \mathcal{M}_n(\mathbb{K})\)</math>

        <math>\(\; A \; est \; inversible \; \Leftrightarrow \; \exists \; B\in \mathcal{M}_n(\mathbb{K}) \; \; A\cdot B = I_n \; et \; \; B\cdot A = I_n\)</math>

        ( D'ailleurs, L'inversibilité à gauche équivaut à l'inversibilité à droite )

        voilà j'espère que ce retour aux sources t'éclaire.
        bonne journée

        • Partager sur Facebook
        • Partager sur Twitter
          27 janvier 2011 à 14:50:35

          Ce n'est pas un retour, je n'ai jamais étudié les matrices :D

          Néanmoins récemment pour un certain problème, j'ai eu besoin de savoir si une matrice carrée était inversible -avec une condition spéciale: on ne pouvait inverser qu'une petite zone de cette matrice à la fois.
          Ex:

          10001
          00011
          00001
          11000

          pour une croix
          ..X
          XXX
          ..X

          le centre de la croix devant obligatoirement être dans la matrice, chacune de ses applications inverse les cases sur lesquelles elle se trouve.

          Ex d'application pour la précédente:
          1000X......................10000
          000XX......donne......00000
          0000X......................00000
          11000......................11000

          nous cherchons donc à arriver au résultat

          01110
          11100
          11110
          00111

          J'ai découvert le pivot de Gauss en cherchant à résoudre ce problème -qui a été résolu grâce à ce dernier par ailleurs.

          Diverses informations m'ayant été apportées par des professeurs comme pouvant m'aider, je me rend cependant compte que des points obscurs persistent. Et pour cause: je n'ai jamais étudié les matrices.

          Connaissant maintenant mon problème: quels éléments pensez-vous être en mesure de m'apporter de l'aide ?
          Ou bien: par quoi commencer pour appréhender les matrices ?
          • Partager sur Facebook
          • Partager sur Twitter
            27 janvier 2011 à 16:15:58

            Comment commencer avec les matrices?
            Difficiles à dire, quelle est ton niveau actuel?
            As tu fait de l'algèbre de manière générale?
            slt!
            • Partager sur Facebook
            • Partager sur Twitter
              27 janvier 2011 à 16:26:51

              Citation : *Nat


              le centre de la croix devant obligatoirement être dans la matrice, chacune de ses applications inverse les cases sur lesquelles elle se trouve.

              Ex d'application pour la précédente:
              1000X......................10000
              000XX.......donne........00000
              0000X......................00000
              11000......................11000



              Ouh là!
              Ah ok, pour toi, inverser un nombre, c'est transformer un 1 en 0, et un 0 en 1? (j'ai failli dire "et inversement?", mais ça aurait embrouillé plus qu'autre chose :p )
              Ça n'a absolument rien à voir avec inverser une matrice!

              Citation : *Nat


              J'ai découvert le pivot de Gauss en cherchant à résoudre ce problème -qui a été résolu grâce à ce dernier par ailleurs.


              Tu as une source? J'aimerai bien voir comment ils ont fait.

              Citation : *Nat


              nous cherchons donc à arriver au résultat
              01110
              11100
              11110
              00111



              En gros, étant donné une matrice, tu veux changer tous ses 0 en 1, et ses 1 en 0? Ça n'a pas grand chose à voir avec les "vraies" matrices (sauf si effectivement, ils ont trouvés une méthode vachement rusé pour faire ça en se basant sur le pivot de Gauss).
              • Partager sur Facebook
              • Partager sur Twitter
                27 janvier 2011 à 20:42:08

                Tu peux réprésenter la matrice des centres où tu inverses (ajoute 1 sur Z/2Z en fait) par un vecteur colonne (de taille n*m), et tu y associes une matrice tel que quand on multiplie la matrice par le vecteur, ça te donne la matrice associée aux inversions en question.
                Il ne te reste plus qu'à résoudre Ax=B+C où A est la matrice décrite précédemment, x le vecteur décrit précédemment, B la matrice de départ et C la matrice d'arrivée.
                Ça fait du bon O((nm)³) que tu peux améliorer en O(nm³) puis O(nm) si ton cœur est accroché.

                PS : Ça sent le prologin à plein nez.
                • Partager sur Facebook
                • Partager sur Twitter
                  28 janvier 2011 à 1:53:26

                  Tu arrives à résoudre un système d'équation en temps quadratique ? Si tu as un lien je prends !
                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 janvier 2011 à 14:48:36

                    Un quelconque, non.
                    Un creux, oui : http://perso.univ-rennes1.fr/antoine.c [...] wiedemann.pdf
                    Un polynôme d'une matrice creuse (p(A)), presque (même base que l'algo précédent).
                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 février 2011 à 20:12:55

                      En effet il y a du Prologin ;) (algo 4 du qcm) c'est aussi pour cela que j'excuse mon retard aux réponses... (demi-finale ce we)
                      Pour ceux qui sont curieux de notre procédé -et qui ont des notions en C et le coeur accroché:
                      #include <stdio.h>
                      #include <stdlib.h>
                      
                      /*
                          Algorithme 4 : Prologin 2011
                      
                          Nous allons utiliser le pivot de Gauss pour trigonaliser une matrice composée comme expliqué dans les commentaires de la fonction etablitMatrice().
                          Ensuite, on cherche une ligne dans la matrice d'équations de forme 0 = 1, ce qui est le seul cas où une grille est insoluble.
                      
                          Cette matrice d'équations est de taille (N*M) * (N*(M+1)), ce qui fait une matrice de taille maximale de 2251500 cases, soit 9006000 octets de mémoire en utilisant des integer (soit une grande utilisation de la mémoire).
                          Pour cela, nous allons travailler en binaire : nous n'avons besoin de stocker que des 0 et 1. Ainsi, chaque unsigned int permet de stocker 32 valeurs, soit 32 cases du tableau. On aboutit donc à une utilisation de 9006000 / 32 = 281438 octets (diminution massive de la mémoire utilisée).
                      
                          Les fonctions getValue() et setValue() servent respectivement à obtenir la valeur d'une case du tableau, et à modifier celle-ci.
                          Pour l'allocation dynamique, nous avons besoin d'un nombre multiple de sizeof(unsigned int). Pour cela, la fonction toMultipleOf() arrondit un nombre à une valeur d'un multiple supérieur. La fonction topround(), elle, arrondit un nombre décimal au nombre entier supérieur (le serveur Prologin compilant sans math.h, nous sommes obligés de ré-implémenter la fonction).
                      */
                      
                      int topround(double input) // arrondit à l'unité supérieure (marche sur les nombres posint topround(double input) // arrondit à l'unité supérieure (marche sur les nombres positifs)
                      {
                          int ret=0;
                      
                          if(input == (int)input) // si on a affaire à un nommbre déjà arrondi
                              ret=input;
                          else
                              ret=(int)input+1; // on le cast en int (valeur entière en dessous), puis l'incrémente
                          return ret;
                      }
                      
                      int toMultipleOf(int input, int multiple) // arrondit "input" au multiple de "multiple" supérieur
                      {
                          double division=(double)input / (double)multiple; // division de input par multiple
                      
                          if(input/multiple == division) // si input est déjà multiple de multiple
                              return input;
                      
                          return topround(division) * multiple; // on multiplie l'arrondi supérieur de division par multiple
                      }
                      
                      void setValue(unsigned int *binary, char value, int pos)
                      {
                          int caseTableau=pos/32; // une case est un unsigned int, soit 4octets = 32bits. Un sizeof prend du temps à l'exec
                          int posInCase=pos%32; // position du bit à modifier dans la case (0 = bit le plus à droite)
                          int toAdd=1; // nombre ayant un seul 1 dans son binaire, à l'emplacement de pos
                      
                          toAdd = toAdd << posInCase; // on décale le 1
                      
                          if((binary[caseTableau] & toAdd) != 0) // si le bit à modif vaut 1
                          {
                              if(value==1)
                                  return; // le bit est déjà à la valeur souhaitée
                              else
                                  binary[caseTableau]-=toAdd; // si le bit doit valoir 0, on retire toAdd
                          }
                          else
                          {
                              if(value==1)
                                  binary[caseTableau]+=toAdd;
                              else
                                  return;
                          }
                      }
                      
                      int getValue(unsigned int *binary, int pos)
                      {
                          // variables : idem setValue()
                          int caseTableau=pos/32;
                          int posInCase=pos%32;
                          int toAdd=1;
                          
                          toAdd = toAdd << posInCase;
                      
                          if((binary[caseTableau] & toAdd) != 0) // si le bit vaut 1
                              return 1;
                      
                          return 0;
                      }
                      
                      void etablitMatrice(int N, int M, int** matrix, unsigned int** systemeEquations)
                      {
                          int y, x, tailleCote = N * M;
                      
                          /*
                              systemeEquations est une grille représentant les cases affectées par un clic:
                              une ligne correspond à une case de matrix: la première case celle de départ,
                              les autres cases noircies les cases touchées en même temps que la case de départ.
                      
                              On ajoute une dernière colonne représentant l'état de la case dans matrix.
                              
                              Ce tableau est un système d'équations.
                          */
                      
                      
                          for(y = 0; y < tailleCote; y++)
                          {
                              for(x = 0; x < tailleCote; x++)
                              {
                                  if(abs(x%M - y%M) + abs(x/M - y/M) <= 1)
                                  {
                                      setValue(systemeEquations[y], 1, x); // noir
                                  }
                                  else
                                  {
                                      setValue(systemeEquations[y], 0, x); // blanc
                                  }
                              }
                          }
                      
                          // ===== Remplissage de la dernière colonne =====
                          //            ========================
                      
                          for(y = 0; y < tailleCote; y++)
                          {
                              setValue(systemeEquations[y], matrix[y/M][y%M], tailleCote);
                          }
                      }
                      
                      // efftecue un xor entre les lignes "ligne" et "pivot"
                      void xorisateur(unsigned int** systemeEquations, int ligne, int pivot, int longueur)
                      {
                          for(int x = 0; x < longueur; x++)
                          {
                              setValue(systemeEquations[ligne], getValue(systemeEquations[ligne],x) ^ getValue(systemeEquations[pivot],x), x);
                          }
                      }
                      
                      void estDessinableCorrupted(int N, int M, int** matrix)
                      {
                          // ===== ETAPE 1 ========================
                          // initialiser la matrice ("Que la mémoire soit")
                          unsigned int **systemeEquations, longueur = N*M; //création de la matrice d'équations
                          systemeEquations=calloc(longueur, sizeof(unsigned int*));
                          if(systemeEquations == NULL)
                          {
                              printf("ERROR : allocation bug");
                              exit(EXIT_FAILURE);
                          }
                      
                          for(int y=0; y < longueur; y++)
                          {
                              // alloue une ligne de minimum longueur+1 bits, où bits est multiple de sizeof(unsigned int)
                              systemeEquations[y]=malloc(toMultipleOf(topround((longueur+1)/8), sizeof(unsigned int)));
                              if(systemeEquations[y] == NULL)
                              {
                                  printf("ERROR : allocation bug at line %d", y);
                                  exit(EXIT_FAILURE);
                              }
                          }
                          
                          etablitMatrice(N, M, matrix, systemeEquations); //voir commentaires dans etablitMatrice()
                      
                          // ===== ETAPE 2 ========================
                          // Trigonalisation de la matrice avec le pivot de Gauss.
                      
                          for(int fait = 0; fait < longueur; fait++)
                          {
                              int premierX = -42, premierY = -42; // inutile, donc indispensable.
                      
                              //On va parcourir systemeEquations colonne par colonne pour trouver le premier 1
                              for(int x=fait; x < longueur && premierX < 0; x++)
                              {
                                  for(int y=fait; y < longueur && premierY < 0; y++)
                                  {
                                      if(getValue(systemeEquations[y], x))
                                      {
                                          premierX = x;
                                          premierY = y;
                                      }
                                  }
                              }
                      
                              if(premierX == -42) // si aucun 1 n'a été trouvé
                              {
                                  for(int y=fait; y < longueur; y++)
                                  {
                                      //et qu'une case de la solution vaut 1 (equation 0=1 impossible)
                                      if(getValue(systemeEquations[y], longueur))
                                      {
                                          printf("0\n"); //aucune solution n'existe (CAPTAIN OBVIOUS)
                                          return;
                                      }
                                  }
                              }
                      
                              if(premierY > fait) //dans le cas où le premier 1 trouvé n'est pas dans la première ligne non faite
                                  //on applique le xor de manière à pouvoir utiliser la première ligne comme pivot
                                  xorisateur(systemeEquations, fait, premierY, longueur+1);
                              for(int y=fait+1; y<longueur; y++)
                              {
                                  if(getValue(systemeEquations[y], premierX))
                                      xorisateur(systemeEquations, y, fait, longueur+1); // puis on élimine tous les 1 de la colonne en dessous des lignes faites.
                              }
                          }
                      
                          printf("1\n"); // si on est arrivés jusqu'ici, la solution existe
                      
                          // ==== PROLOGUE ===================
                          // "Et la mémoire fut libérée".
                      
                          for(int i=0; i < N*M; i++)
                          {
                              free(systemeEquations[i]);
                          }
                          free(systemeEquations);
                      }
                      
                      int main(void)
                      {
                          int N;
                          int M;
                          int** matrix;
                      
                          scanf("%d\n", &N);
                          scanf("%d\n", &M);
                          matrix = calloc(N, sizeof(int*));
                          for(int _l = 0; _l < N; ++_l)
                              matrix[_l] = calloc(M, sizeof(int));
                          for(int _l = 0; _l < N; ++_l)
                              for(int _c = 0; _c < M; ++_c)
                                  scanf("%d", &matrix[_l][_c]);
                      
                          estDessinableCorrupted(N, M, matrix);
                      
                          return 0;
                      }
                      


                      Mais pour en revenir donc au topic:
                      Mon niveau actuel, je suis en seconde donc :-°

                      Citation : Pole

                      Tu peux réprésenter la matrice des centres où tu inverses (ajoute 1 sur Z/2Z en fait) par un vecteur colonne (de taille n*m), et tu y associes une matrice tel que quand on multiplie la matrice par le vecteur, ça te donne la matrice associée aux inversions en question.
                      Il ne te reste plus qu'à résoudre Ax=B+C où A est la matrice décrite précédemment, x le vecteur décrit précédemment, B la matrice de départ et C la matrice d'arrivée.
                      Ça fait du bon O((nm)³) que tu peux améliorer en O(nm³) puis O(nm) si ton cœur est accroché.


                      Il me semble que c'est ce que nous avons fait mais que sont Z/2Z ?

                      (merci pour le lien :)
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        1 février 2011 à 20:34:22

                        Ton but était d'inverser une matrice ?
                        C'est pas mal d'avoir pensé au travail en binaire.
                        Ca me semble bien long pour une méthode de Gauss...

                        Z/2Z est un anneau. http://fr.wikipedia.org/wiki/Anneau_Z/nZ
                        • Partager sur Facebook
                        • Partager sur Twitter
                          1 février 2011 à 22:04:01

                          OMG !
                          ((a+b-1)/b)*b ça peut être pratique (arrondit au multiple supérieur).
                          |=1<<k et &=~(1<<k) aussi.
                          Dans ton "xorisateur", tu devrais simplement faire un ^ qui permet de xorer les 32 (ou plus) bits en même temps.

                          Et puis je me demande comment tu trigonalises une matrice non trigonalisable.
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            1 février 2011 à 22:33:15

                            Pole > Un exemple de matrice non trigonalisable dans <math>\(\mathhbb{C}\)</math> ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              1 février 2011 à 22:43:59

                              doulilos > Où parle-t-on de C ? Nulle part, on parle de Z/2Z.
                              Tu es prié de me scinder x²+x+1 dans Z/2Z. Enjoy.
                              Autre question ?

                              PS : L'arithmétique exacte dans C, c'est pas pratique. De même que pour mettre 32 nombres quelconques de C dans un int.
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Inversibilité de matrice par quoi ?

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown