begin process at 2012 02 12 17:49:00
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > QUADRIQUES ET REDUCTION DE GAUSS

QUADRIQUES ET REDUCTION DE GAUSS


 Information sur la source

Note :
10 / 10 - par 2 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths & Algorithmes Classé sous :gauss, quadrique, reduction, sylvester, signature Niveau :Débutant Date de création :04/08/2007 Vu / téléchargé :7 716 / 221

Auteur : JCDjcd

Ecrire un message privé
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (6)
Ajouter un commentaire et/ou une note


 Description

Cliquez pour voir la capture en taille normale
  J'ai ete tres supris de ne pas voir sur ce site un code sur la reduction des formes quadratiques
reelles par l'algorithme de reduction de Gauss ...

  Les quadratiques sont l'equivalent des coniques en dimensions 3, et il existe une classification
des quadriques (ce sont des nappes, des surfaces) avec des noms affreux !

  Pour classifier les quadriques on a besoin de la signature de leurs formes quadratiques associees
(il y en a deux notee M et M0). La signature d'un f.q.r. (forme quadratique reelle) est un couple (p,q)
de deux entiers : si la f.q.r. est mise sous forme exclusivement de carre (par diagonalisation
de la matrice symetrique reelle par exemple, ou par reduction de Gauss (cf. matrice congruente
a une matrice diagonale)) alors le premier entier est le nombre de coefficients strictements
positifs et le second pour les negatifs. La signature d'un f.q.r. ne depend pas de la base
d'expression, i.e. elle est invariante pour deux matrices (symetriques) congruentes.
Je rappelle que la congruence entre A et B s'exprime par A=tP.B.P avec tP la transposee de P, et P
une matrice inversible, a ne surtout pas confondre avec la similitude A=P^-1.B.P, alors
les endomorphismes sont identiques.

  D'un point de vu mathematique, la reduction de Gauss permet de classifier les classes de
congruences, ceci est en rapport direct avec la loi d'inertie de Sylvester dans le cas ou le
corps de base est reel. Une autre demonstration de l'existence de la reduction (mais ne donne
pas d'algorithme pour la trouver, a part si l'on sait diagonaliser une matrice ... pas
si facile que cela) est le theoreme spectral : toute matrice symetrique reelle est diagonalisable
dans une base orthonormee (tout est dans le orthonormee ... P^-1=tP ...)

  La reduction de Gauss est une methode d'elimination, on cherche a mettre notre f.q.r. sous la
forme d'une somme d'une term carre plus une autre f.q.r. dependant d'un parametre de moins,
en fait il y a certains cas ou l'on mets sous la forme de 3 termes : deux carres et une f.q.r.
avec deux parametres en moins.

Source

  • //-------------------------------------------------
  • // GAUSS
  • //-------------------------------------------------
  • void gauss(double **M,int N)
  • {
  • int n,x,y,k;
  • n = N-1;
  • while(n > 0)
  • {
  • // si on n'a pas un terme carre ...
  • if(CmpDouble0(M[n][n]))
  • {
  • int s; // indice du "swap"
  • // ... on cherche un autre terme carre ...
  • s = -1;
  • for(k=0;k<n;k++)
  • {
  • if(!CmpDouble0(M[k][k]))
  • {
  • s = k;
  • break;
  • }
  • }
  • if(-1 == s)
  • {
  • // ... si on n'en trouver decidement pas, on regarde si on a des produits
  • // croise entre la derniere variable et l'avant derniere, puis on elimine
  • // les deux dernieres lignes et colonne :
  • if(!CmpDouble0(M[n][n-1]))
  • {
  • //
  • // ( * * * 0 0 )
  • // ( * * * 0 0 )
  • // ( * * * 0 0 )
  • // ( 0 0 0 1/2 0 )
  • // ( 0 0 0 0 -1/2 )
  • //
  • for(y=0;y<n-1;y++)
  • {
  • for(x=0;x<n-1;x++)
  • {
  • M[y][x] -= (M[n-1][x]*M[n][y]+M[n-1][y]*M[n][x])/M[n][n-1];
  • }
  • }
  • M[n-1][n-1] = + 0.5;
  • M[n-1][n ] = 0.0;
  • M[n ][n-1] = 0.0;
  • M[n ][n ] = - 0.5;
  • // on diminue de 2 le rang
  • n -= 2;
  • }
  • else
  • {
  • // sinon
  • //
  • // ( 0 * * * 0 )
  • // ( * 0 * * 0 )
  • // ( * * 0 * 0 )
  • // ( * * * 0 0 )
  • // ( 0 0 0 0 0 )
  • //
  • // on diminue de 1 le rang
  • n -= 1;
  • }
  • }
  • else
  • {
  • // ... si on en a trouve un, on l'echange et on recommence la boucle au meme rang
  • // mais cette fois-ci avec un terme carre
  • for(k=0;k<=n;k++) // ligne : L[n] <-> L[s]
  • {
  • SwapDouble(&M[n][k],&M[s][k]);
  • }
  • for(k=0;k<=n;k++) // colonne : C[n] <-> C[s]
  • {
  • SwapDouble(&M[k][n],&M[k][s]);
  • }
  • }
  • }
  • else
  • {
  • // ... on a donc un terme carre, on elimine la derniere ligne et colonne :
  • //
  • // ( * * * * 0 )
  • // ( * * * * 0 )
  • // ( * * * * 0 )
  • // ( * * * * 0 )
  • // ( 0 0 0 0 ? )
  • //
  • for(y=0;y<n;y++)
  • {
  • for(x=0;x<n;x++)
  • {
  • M[y][x] -= M[n][x] * M[y][n] / M[n][n];
  • }
  • }
  • for(k=0;k<n;k++)
  • {
  • M[k][n] = M[n][k] = 0.;
  • }
  • // on passe au rang inferieur
  • n --;
  • }
  • }
  • } // gauss()
  • //-------------------------------------------------
  • void sign(int *p,int *q,double **mat,int n)
  • {
  • double **diag;
  • int k;
  • (*p) = 0;
  • (*q) = 0;
  • diag = CopyMat(mat,n);
  • gauss(diag,n);
  • for(k=0;k<n;k++)
  • {
  • if(diag[k][k] > MATH_EPSILON)
  • {
  • (*p) ++;
  • }
  • else if(diag[k][k] < -MATH_EPSILON)
  • {
  • (*q) ++;
  • }
  • }
  • DeleteMat(diag,n);
  • } // sign()
  • //-------------------------------------------------
  • void info(int pA,int qA,int pB,int qB)
  • {
  • if(4==pB && 0==qB && 3==pA && 0==qA)
  • {
  • printf("ensemble vide (quadrique propre)\n");
  • }
  • else if(3==pB && 1==qB && 3==pA && 0==qA)
  • {
  • printf("ellipsoide (quadrique propre)\n");
  • }
  • else if(3==pB && 1==qB && 2==pA && 1==qA)
  • {
  • printf("hyperboloide à deux nappes (quadrique propre)\n");
  • }
  • else if(3==pB && 1==qB && 2==pA && 0==qA)
  • {
  • printf("paraboloide elliptique (quadrique propre)\n");
  • }
  • else if(2==pB && 2==qB && 2==pA && 1==qA)
  • {
  • printf("hyperboloide à une nappe (quadrique propre)\n");
  • }
  • else if(2==pB && 2==qB && 1==pA && 1==qA)
  • {
  • printf("paraboloide hyperbolique (quadrique propre)\n");
  • }
  • else if(3==pB && 0==qB && 3==pA && 0==qA)
  • {
  • printf("point\n");
  • }
  • else if(3==pB && 0==qB && 2==pA && 0==qA)
  • {
  • printf("ensemble vide\n");
  • }
  • else if(2==pB && 1==qB && 2==pA && 1==qA)
  • {
  • printf("cone\n");
  • }
  • else if(2==pB && 1==qB && 2==pA && 0==qA)
  • {
  • printf("cylindre elliptique\n");
  • }
  • else if(2==pB && 1==qB && 1==pA && 1==qA)
  • {
  • printf("cylindre hyperbolique\n");
  • }
  • else if(2==pB && 1==qB && 1==pA && 0==qA)
  • {
  • printf("cylindre parabolique\n");
  • }
  • else if(2==pB && 0==qB && 2==pA && 0==qA)
  • {
  • printf("droite\n");
  • }
  • else if(2==pB && 0==qB && 1==pA && 0==qA)
  • {
  • printf("ensemble vide\n");
  • }
  • else if(1==pB && 1==qB && 1==pA && 1==qA)
  • {
  • printf("deux plans sécants\n");
  • }
  • else if(1==pB && 1==qB && 1==pA && 0==qA)
  • {
  • printf("deux plans parallèles\n");
  • }
  • else if(1==pB && 0==qB && 1==pA && 0==qA)
  • {
  • printf("plan double\n");
  • }
  • else
  • {
  • printf("impossible\n");
  • }
  • } // info()
//-------------------------------------------------
// GAUSS
//-------------------------------------------------
void gauss(double **M,int N)
{
int n,x,y,k;

n = N-1;
while(n > 0)
  {

  // si on n'a pas un terme carre ...
  if(CmpDouble0(M[n][n]))
    {
    int s; // indice du "swap"

    // ... on cherche un autre terme carre ...
    s = -1;
    for(k=0;k<n;k++)
      {
      if(!CmpDouble0(M[k][k]))
        {
        s = k;
        break;
        }
      }
    
    if(-1 == s)
      {
      // ... si on n'en trouver decidement pas, on regarde si on a des produits
      // croise entre la derniere variable et l'avant derniere, puis on elimine
      // les deux dernieres lignes et colonne :
      if(!CmpDouble0(M[n][n-1]))
        {
        // 
        // ( *   *   *   0   0    )
        // ( *   *   *   0   0    )
        // ( *   *   *   0   0    )
        // ( 0   0   0  1/2  0    )
        // ( 0   0   0   0  -1/2  )
        // 
        for(y=0;y<n-1;y++)
          {
          for(x=0;x<n-1;x++)
            {
            M[y][x] -= (M[n-1][x]*M[n][y]+M[n-1][y]*M[n][x])/M[n][n-1];
            }
          }
        M[n-1][n-1] = + 0.5;
        M[n-1][n  ] =   0.0;
        M[n  ][n-1] =   0.0;
        M[n  ][n  ] = - 0.5;

        // on diminue de 2 le rang
        n -= 2;
        }
      else
        {
        // sinon
        // 
        // ( 0   *   *   *   0  )
        // ( *   0   *   *   0  )
        // ( *   *   0   *   0  )
        // ( *   *   *   0   0  )
        // ( 0   0   0   0   0  )
        // 

        // on diminue de 1 le rang
        n -= 1;
        }
      }
    else
      {
      // ... si on en a trouve un, on l'echange et on recommence la boucle au meme rang
      // mais cette fois-ci avec un terme carre
      for(k=0;k<=n;k++) // ligne : L[n]  <->  L[s]
        {
        SwapDouble(&M[n][k],&M[s][k]);
        }
      for(k=0;k<=n;k++) // colonne : C[n]  <->  C[s]
        {
        SwapDouble(&M[k][n],&M[k][s]);
        }
      }
    }
  else
    {
    // ... on a donc un terme carre, on elimine la derniere ligne et colonne :
    // 
    // ( * * * * 0 )
    // ( * * * * 0 )
    // ( * * * * 0 )
    // ( * * * * 0 )
    // ( 0 0 0 0 ? )
    // 
    for(y=0;y<n;y++)
      {
      for(x=0;x<n;x++)
        {
        M[y][x] -= M[n][x] * M[y][n] / M[n][n];
        }
      }

    for(k=0;k<n;k++)
      {
      M[k][n] = M[n][k] = 0.;
      }

    // on passe au rang inferieur
    n --;
    }
  }
} // gauss()


//-------------------------------------------------
void sign(int *p,int *q,double **mat,int n)
{
double **diag;
int      k;

(*p) = 0;
(*q) = 0;

diag = CopyMat(mat,n);
gauss(diag,n);

for(k=0;k<n;k++)
  {
  if(diag[k][k] > MATH_EPSILON)
    {
    (*p) ++;
    }
  else if(diag[k][k] < -MATH_EPSILON)
    {
    (*q) ++;
    }
  }

DeleteMat(diag,n);
} // sign()


//-------------------------------------------------
void info(int pA,int qA,int pB,int qB)
{
if(4==pB && 0==qB && 3==pA && 0==qA)
  {
  printf("ensemble vide (quadrique propre)\n");
  }
else if(3==pB && 1==qB && 3==pA && 0==qA)
  {
  printf("ellipsoide (quadrique propre)\n");
  }
else if(3==pB && 1==qB && 2==pA && 1==qA)
  {
  printf("hyperboloide à deux nappes (quadrique propre)\n");
  }
else if(3==pB && 1==qB && 2==pA && 0==qA)
  {
  printf("paraboloide elliptique (quadrique propre)\n");
  }
else if(2==pB && 2==qB && 2==pA && 1==qA)
  {
  printf("hyperboloide à une nappe (quadrique propre)\n");
  }
else if(2==pB && 2==qB && 1==pA && 1==qA)
  {
  printf("paraboloide hyperbolique (quadrique propre)\n");
  }
else if(3==pB && 0==qB && 3==pA && 0==qA)
  {
  printf("point\n");
  }
else if(3==pB && 0==qB && 2==pA && 0==qA)
  {
  printf("ensemble vide\n");
  }
else if(2==pB && 1==qB && 2==pA && 1==qA)
  {
  printf("cone\n");
  }
else if(2==pB && 1==qB && 2==pA && 0==qA)
  {
  printf("cylindre elliptique\n");
  }
else if(2==pB && 1==qB && 1==pA && 1==qA)
  {
  printf("cylindre hyperbolique\n");
  }
else if(2==pB && 1==qB && 1==pA && 0==qA)
  {
  printf("cylindre parabolique\n");
  }
else if(2==pB && 0==qB && 2==pA && 0==qA)
  {
  printf("droite\n");
  }
else if(2==pB && 0==qB && 1==pA && 0==qA)
  {
  printf("ensemble vide\n");
  }
else if(1==pB && 1==qB && 1==pA && 1==qA)
  {
  printf("deux plans sécants\n");
  }
else if(1==pB && 1==qB && 1==pA && 0==qA)
  {
  printf("deux plans parallèles\n");
  }
else if(1==pB && 0==qB && 1==pA && 0==qA)
  {
  printf("plan double\n");
  }
else
  {
  printf("impossible\n");
  }
} // info()



 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture COLORATION SYNTAXIQUE
Source avec Zip Source avec une capture ORBITES DES SATELLITES GPS
Source avec Zip Source avec une capture DESSIN D'ARBRES
Source avec Zip Source avec une capture PROGRAMMATION LINEAIRE
Source avec Zip EXTENSION DE CORPS (MATH)

 Sources de la même categorie

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture HDR EXPOSURE FUSION par mecrosoft
Source avec Zip Source avec une capture CLASSE AVEC OPENGL - OBJETS 3D ET ANIMATIONS par rasta63
PIVOT DE GAUSS par Jbs106
INVERSION, CRAMER ,GAUSS, GAUSS PIVOT PARTIEL, GAUSS PIVOT T... par ahmedkolsi
Source avec Zip BINDER D'EXE DE DÉBUTANT par TorTukiTu

Commentaires et avis

Commentaire de dletozeun le 04/08/2007 20:10:17

"J'ai ete tres supris de ne pas voir sur ce site un code sur la reduction des formes quadratiques
reelles par l'algorithme de reduction de Gauss ..."

Pourquoi? Est ce vraiment utile comme code?

Commentaire de JCDjcd le 05/08/2007 00:12:35

Ha parceque tu crois qu'il y a beaucoup de codes utiles ??
Je pense (sns aucun pretention) que ce code est beaucoup
plus utile que la moitier des sources sur ce site pour
la simple raison que deja ce n'est pas un code sur un
truc deja fait 100 fois, puis c'est dans la rubrique
maths & algorithme donc c'est plus utile (... ca c'est
mon point de vue qui n'engage que moi ...), et surtout
parceque c'est un petit algorithme d'elimination tres bien
pour les debutants qui veulent s'entrainer a programmer
des petits algorithmes marrants, c'est tres instructif pour
la manipulation des indices, tout comme les methodes de
pivots d'ailleurs.

Cordialement JCDjcd (sans avoir voulu etre trop "pretentieux")

Commentaire de dletozeun le 05/08/2007 12:33:50

Désolé je ne voulais pas te vexer... et ne me fais pas dire ce que j'ai pas dis s'il te plait.
"plus utile" ne veux pas dire utile...c'est juste que meme si ce code rentre parfaitement dans sa catégorie, j'ai vu des codes en faisant partie qui ont une réelle application dans le domaine de l'informatique et notamment de nombreux codes de ton cru. Tout ca pour te dire que je suis parfaitement d'accord avec le fait que les mathématiques sont énormément utiles en informatique, mais que ce code particulier a une application un peu trop spécifique à mon gout sans réelle utilité puisque je suis a peu pres certain que la plupart des logiciels de calcul formel savent calculer la signature d'une f.q.r....

Pour ce qui de l'"algorithme d'elimination tres bien pour les debutants qui veulent s'entrainer a programmer des petits algorithmes marrants, c'est tres instructif pour la manipulation des indices"

Je suis assez septique, encore faut t'il des maitriser le sujet des f.q.r et tout ce qui semble aller avec: diagonalisation, reductiuon de Gauss, forme exclusivement carrée...c'est plutot rebutant.
Je pense qu'une fois avoir compris tout ca on maitrise tres bien les manipulations d'indices dans une matrice, il suffirait simplement a un debutant de coder un algorithme de multiplication de matrices pour s'en faire une bonne idée...

Cordialement, en espérant ne pas paraitre brutal et incorrect. ^^

Commentaire de JCDjcd le 05/08/2007 16:39:15

C'est absolument pas brutal, et c'est tres correct :
en fait je me disais qu'il y avait beaucoup de code
sur l'inversion de matrices par pivot de Gauss, alors
qu'il existe d'autre algorithme comme celui-ci qui
permet de s'entrainer sur les indices, donc c'etait
pour montrer que l'on peut aisement diversifier...
et sinon je suis doit a fait d'accord que les f.q.r.
c'est complique pour un debutant en mathematique ...
j'y avais pas trop pense ... ;-)

Par contre je voulais aussi faire remarquer que mon
implementation n'est pas obscure, les indices sont
claires, par contre je suis d'accord que les disjonctions
de cas ne sont pas "lisibles" a premiere vue, bien que
l'indentation devrait aider ...

Ce programme peut aussi servir aux taupins qui ont
comme exercice d'application de leur cours sur les
quadriques de verifier la nature de leurs quadriques, car
quand on le fait a la main on se trompe toujours !
(je suis sur que l'on pourrait avoir plein de temoingnages)

Bien amicalement JCDjcd

Commentaire de dletozeun le 05/08/2007 16:56:40

ok merci! ^^

Oui je suis tout a fait d'accord avec toi, ton code est vraiment très clair ( je voulais le préciser masi j'ai oublié ^^).
En tant qu'ancien taupin je confirme! Rien que pour calculer un polynome caractéristique correctement, on peut trouver 10 résultats différents! Et les quadriques, j'en ai plus aucun souvenir...^^

Commentaire de Saros le 30/10/2007 20:03:54 10/10

A la main, ça se fait plutôt bien.. j'imagine que les applications doivent être assez spécifiques même si ça concerne de nombreux domaines (détermination d'extrema, équations différentielles ?)
En tout cas il t'a fallu du courage pour distinguer tous les cas :)

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

pivot de gauss [ par DeNeBj ] bonjourj'aimerais trouver un prog en c qui utilise seulement les tableaux et les boucles et qui resoud des systemes d'equations (on s'arrete à 10 ) ke algorithme de gauss et decomposition LU [ par speedamine ] bonjour a tous.je voudrai avoir des algorithmes ,ecrits en borland pascal,suivants:methode de gauss ordinaire pour la resolution d'un systeme .la deco reduction du bruit [ par tdeco ] Salutje cherche à réduire le bruit sur une image squi est sous forme de matrice (fichier txt).cette matrice (suite de 1 et 0) de dimension 16*16 repre Reduction f'un graph binaire [ par Gilleslesdf ] Bonjour,Je suis a la recherche d'un algo me permettant la reduction d'un graph binaire.Je l'explique: /-- A + B ---\Start-- Lecture de données Hexa sur 4octets avec inversion dees bits de poids faible/fort [ par VTS_35 ] bonjour,G un gros problème de lecture de données.Je bosse sur des fichiers genre images bmp et je dois en lire l'entete.voici les première variables d Insérer une signature périodique dans un fichier binaire. [ par tahamohamed ] Je veux savoir une methode d'insertion d'une signature périodique de 12 bytes sur des blocks de 1024 bytes dans un fichier binaire sans avoir a utilis REDUCTION DE SURFACE [ par cybermax62 ] Dans DirectDraw il est facile de rétrécir une image. il suffit de donner les coordonnées RECT de destination et voila. mais dans ce cas l'image est de VC++,SDI, Redessiner le contenu (disparu après reduction fenetre) de la vue apres restauration [ par ninouch ] &nbsp;&nbsp;&nbsp;J'ai un gros pb. &nbsp;&nbsp; &nbsp;J'utilise la fonction OnDraw() de la classe View pour dessiner plusieurs bitmap selon les donn&# message de reduction de fenetre [ par melkiorlenecrarque ] Quel est le message envoy&#233; lorsque l'on reduit une fenetre avec le boutton en haut &#224; droite de la fenetre?j'ai essay&#233;:case SW_MINIMIZE: Fonction de reduction de la taille d'un fichier en C ou en C++ [ par djoni ] Bjrs,Je voudrais savoir s'il existe&nbsp;en&nbsp;C&nbsp;ou&nbsp;en C++ une fonction qui permet de r&#233;duire la taille d'un fichier .&nbsp;Au cas o&


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 3,307 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales