Résolution d'un système à 3 équations - 3 inconnues

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Résolution d'un système à 3 équations - 3 inconnues

Message par Guimauve »

Le sujet est dans le titre.

Je ne sais pas si ça peut-être utile à certains. Je viens de passer environ 1 heure pour le débogguer.

A+
Guimauve

Code : Tout sélectionner

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : Exemple de résolution d'un système à 3 équations - 3 inconnues
; Fichier : Trucs et astuces
; Version 1.0.0
; Programmation = OK - PAS SÉCURITAIRE
; Alias : Guimauve
; Date : 18 juin 2005
; Mise à jour : 18 juin 2005
; Codé avec PureBasic V3.93
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Cet exemple montre comment trouver trouver les coefficients d'une équation du
; type : f(x) = ax^2 + bx + c passant par trois point.
;
; P0(x ; y)
; 
; P1(1 ; 9)
; P2(3 ; 53)
; P3(6 ; 194)
; 
; 9 = a1² + b1 + c
; 53 = a3² + b3 + c
; 194 = a6² + b6 + c
;
; 1a + 1b + 1c = 9
; 9a + 3b + 1c = 53
; 36a + 6b + 1c = 194
;
; La matrice à résoudre est la suivante :
;   
;  1  1  1 : 9
;  9  3  1 : 53
;  36 6  1 : 194
; 
; La matrice résolue est la suivante :
;
; 1 0 0 : 5 ---> 1a + 0b + 0c = 5
; 0 1 0 : 2 ---> 0a + 1b + 0c = 2
; 0 0 1 : 2 ---> 0a + 0b + 1c = 2
; 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; REMARQUE :
;
; LES POINTS CONNUS DOIVENT ÊTRE DIFFÉRENT DE (0 ; 0) UN TEST DEVERAIT ÊTRE 
; AJOUTER POUR VÉRIFIER SI UNE LIGNE DE LA MATRICE DEVIENT NULLE. SI TEL EST LE 
; CAS, ALORS IL N'Y A AUCUNE SOLUTION. IL SERAIT PRÉFÉRABLE DE CREER LA MATRICE
; COMME CECI :
;
;  C1  B1  A1 : CTE1
;  C2  B2  A2 : CTE2
;  C3  B3  A3 : CTE3
;
; C'EST POUR ÉVITER LES PROBLÈMES DU L'UN DES POINTS SERAIT (0 ; 5)
; ON ÉVITE UNE DIVISION PAR 0
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; N.B. LES POINTS ON ÉTÉ TROUVÉS AVEC L'ÉQUATION SUIVANTE :
;
; f(x) = 5x^2 + 2x + 2
; 
; Ceci à été fait pour trouver des coefficients entiers. (Plus facile à voir) 
;
; En passant par les points :
;
; P1(1 ; 2)
; P2(4 ; 4)
; P3(3 ; 9)
;
; L'équation devient : 
; f(x) = -2.833333x^2 + 14.833333x + -9.999999
; 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; L'équation trouvé est :
;
; f(x) = 5.000000x^2 + 2.000001x + 1.999999
;
; L'erreur est généré par l'utilisation de nombre flottant codé sur 32 bits
; lorsque la précision est de 6 décimales.
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Enumeration
  
  #Colonne1
  #Colonne2
  #Colonne3
  #Colonne4
  
EndEnumeration 

Enumeration
  
  #Ligne1
  #Ligne2
  #Ligne3
  
EndEnumeration 

Dim Matrice.f(#Colonne4,#Ligne3)

; Coefficient a
Matrice(#Colonne1,#Ligne1) = 1
Matrice(#Colonne1,#Ligne2) = 9
Matrice(#Colonne1,#Ligne3) = 36

; Coefficient b
Matrice(#Colonne2,#Ligne1) = 1
Matrice(#Colonne2,#Ligne2) = 3
Matrice(#Colonne2,#Ligne3) = 6

; Coefficient c
Matrice(#Colonne3,#Ligne1) = 1
Matrice(#Colonne3,#Ligne2) = 1
Matrice(#Colonne3,#Ligne3) = 1

; Le résultat
Matrice(#Colonne4,#Ligne1) = 9
Matrice(#Colonne4,#Ligne2) = 53
Matrice(#Colonne4,#Ligne3) = 194

Debug "Matrice originale"
Debug ""

For i = #Colonne1 To #Colonne4
  
  Debug "Colonne : " +Str(i+1)
  
  For j = #Ligne1 To #Ligne3
    
    Debug Matrice(i,j)
    
  Next
  Debug ""
Next

StartTime = ElapsedMilliseconds()

For i_j = #Ligne1 To #Ligne3
  
  ; On prend la valeur qui se trouve à la position 1
  ; dans la diagonale principale
  Valeur_i_j.f = Matrice(i_j, i_j) 
  
  ; on divise toute la ligne par valeur_i_j afin d'avoir 1
  ; dans la diagonale principale
  For colonne = #Colonne1 To #Colonne4 
    
    Matrice(colonne,i_j) = Matrice(colonne, i_j) / Valeur_i_j
    
  Next 
  
  ; on effectue les opérations élémentaires de ligne
  ; sur les autres lignes de la matrice
  For Ligne_a_modifier = #Ligne1 To #Ligne3 
    
    If Ligne_a_modifier <> i_j
      
      Valeur_2.f = Matrice(i_j,Ligne_a_modifier)
      
      For colonne = #Colonne1 To #Colonne4 
        
        Matrice(colonne,Ligne_a_modifier) = Matrice(colonne,Ligne_a_modifier) - (Matrice(colonne, i_j) * Valeur_2)
        
      Next
      
    EndIf 
    
  Next
  
Next

ElapsedTime = ElapsedMilliseconds() - StartTime

Debug ""
Debug "Matrice échelonnée - réduite"
Debug ""

For i = #Colonne1 To #Colonne4
  
  Debug "Colonne : " +Str(i+1)
  
  For j = #Ligne1 To #Ligne3
    
    Debug Matrice(i,j)
    
  Next
  Debug ""
Next

Debug ""
Debug "Temps requis pour trouver la matrice (ms) : " +Str(ElapsedTime)
Debug ""

coeff_a.f = Matrice(#Colonne4,#Ligne1)
coeff_b.f = Matrice(#Colonne4,#Ligne2)
coeff_c.f = Matrice(#Colonne4,#Ligne3)

Debug "L'équation trouvée :" 
Debug ""

For precision = 0 To 6
  Debug "Précision des flottant 32 bits : " + Str(precision)
  Debug "f(x) = " + StrF(coeff_a,precision) + "x^2 + " + StrF(coeff_b,precision) + "x + " + StrF(coeff_c,precision)
  Debug""
Next 

Debug "L'équation attendu :" 
Debug "f(x) = 5x^2 + 2x + 2"
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

A ce sujet, quelqu'un à déjà vu un algo d'inversion de matrice de n'importe quel taille ?
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

Et bien pour inverser une matrice elle doit être carré.

Il faidrait faire des tests mais je pense que l'algorithme que j'ai donnée dans l'exemple peut être utlisé pour inverser une matrice. Je pense qu'il suffit de passer une matrice comme celle-ci.

1 1 1 : 1 0 0
9 3 1 : 0 1 0
36 6 1 : 0 0 1

Le résultat deverait donner :

1 0 0 : 0.1 -0.16 0.06
0 1 0 : -0.9 1.16 -0.26
0 0 1 : 1.8 -1.0 0.2

Si c'est le cas, la matrice inverse trouve dans la moitié de droite. Il n'y a plus qu'à l'extraire.

Je commence à programmer les commandse pour faire du calcul matricielle. J'en ai besoin pour calculer les coefficients d'équations de spline cubique paramétrique passant par 3 point 3D. En fonction de u on calcul la position sur la trajectoire.

x = au³ + bu² + cu + d
y = au³ + bu² + cu + d
z = au³ + bu² + cu + d

La dérivée des équations va donner le vecteur tangent ce qui va me permettre d'orienter un entity dans la bonne direction.

J'ai figuré que je vais devoir inverser une matrice qui fait 12X12. Mais je ne suis pas encore aussi avancé. J'ai toute les choses de base à programmer avant.

Je vous donne des nouvelles aussitôt que possible.

A+
Guimauve
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

CONFIRMÉ !!

Le code précédent peut inverser une matrice. J'ai testé avec ma calculatrice (Voyage 200 - Texas Instruments) et le résultat est le même mais avec plus de décimales.

Il faudrait peut-être remplacer les constantes par des variables pour inverser les matrices de taille plus grande que 3X3.

Bon maintenant DODO, faut se lever à 5h50 am demain.

A+
Guimauve

Code : Tout sélectionner

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : Exemple d'inversion de matrice
; Fichier : Trucs et astuces
; Version 1.0.0
; Programmation = OK - PAS SÉCURITAIRE
; Alias : Guimauve
; Date : 19 juin 2005
; Mise à jour : 19 juin 2005
; Codé avec PureBasic V3.93
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Cet exemple montre comment Inverser une matrice

;
; La matrice à résoudre est la suivante :
;   
;  1  1  1 : 1 0 0
;  9  3  1 : 0 1 0
;  36 6  1 : 0 0 1
; 
; La matrice Inverse se retrouve dans la matrice de droite :
;
; 1 0 0 : 0.1 -0.16 0.06
; 0 1 0 : -0.9 1.16 -0.26
; 0 0 1 : 1.8 -1.0 0.2
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Enumeration
  
  #Colonne1
  #Colonne2
  #Colonne3
  #Colonne4
  #Colonne5
  #Colonne6
  
  
EndEnumeration 

Enumeration
  
  #Ligne1
  #Ligne2
  #Ligne3
  
EndEnumeration 

Dim Matrice.f(#Colonne6,#Ligne3)

; Colonne 1
Matrice(#Colonne1,#Ligne1) = 1
Matrice(#Colonne1,#Ligne2) = 9
Matrice(#Colonne1,#Ligne3) = 36

; Colonne 2
Matrice(#Colonne2,#Ligne1) = 1
Matrice(#Colonne2,#Ligne2) = 3
Matrice(#Colonne2,#Ligne3) = 6

; Colonne 3
Matrice(#Colonne3,#Ligne1) = 1
Matrice(#Colonne3,#Ligne2) = 1
Matrice(#Colonne3,#Ligne3) = 1

; Matrice Identité Colonne 1
Matrice(#Colonne4,#Ligne1) = 1
Matrice(#Colonne4,#Ligne2) = 0
Matrice(#Colonne4,#Ligne3) = 0

; Matrice Identité Colonne 2
Matrice(#Colonne5,#Ligne1) = 0
Matrice(#Colonne5,#Ligne2) = 1
Matrice(#Colonne5,#Ligne3) = 0

; Matrice Identité Colonne 3
Matrice(#Colonne6,#Ligne1) = 0
Matrice(#Colonne6,#Ligne2) = 0
Matrice(#Colonne6,#Ligne3) = 1

Debug "Matrice originale"
Debug ""

For i = #Colonne1 To #Colonne3
  
  Debug "Colonne : " +Str(i+1)
  
  For j = #Ligne1 To #Ligne3
    
    Debug Matrice(i,j)
    
  Next
  Debug ""
Next

StartTime = ElapsedMilliseconds()

For i_j = #Ligne1 To #Ligne3
  
  ; On prend la valeur qui se trouve à la position 1
  ; dans la diagonale principale
  Valeur_i_j.f = Matrice(i_j, i_j) 
  
  ; on divise toute la ligne par valeur_i_j afin d'avoir 1
  ; dans la diagonale principale
  For Colonne = #Colonne1 To #Colonne6 
    
    Matrice(Colonne,i_j) = Matrice(Colonne, i_j) / Valeur_i_j
    
  Next 
  
  ; on effectue les opérations élémentaires de ligne
  ; sur les autres lignes de la matrice
  For Ligne_a_modifier = #Ligne1 To #Ligne3 
    
    If Ligne_a_modifier <> i_j
      
      Valeur_2.f = Matrice(i_j,Ligne_a_modifier)
      
      For Colonne = #Colonne1 To #Colonne6 
        
        Matrice(Colonne,Ligne_a_modifier) = Matrice(Colonne,Ligne_a_modifier) - (Matrice(Colonne, i_j) * Valeur_2)
        
      Next
      
    EndIf 
    
  Next
  
Next

ElapsedTime = ElapsedMilliseconds() - StartTime

Debug ""
Debug "Matrice Inverse"
Debug ""

For i = #Colonne4 To #Colonne6
  
  Debug "Colonne : " +Str(i+1)
  
  For j = #Ligne1 To #Ligne3
    
    Debug Matrice(i,j)
    
  Next
  Debug ""
Next

Debug "Temps requis pour trouver la matrice (ms) : " +Str(ElapsedTime)
Debug ""
Patrick88
Messages : 1564
Inscription : mer. 21/janv./2004 18:24

Message par Patrick88 »

pffff

on voit que c'est la période des exam's, ça sent le neurone grillé



:wink: :lol: :lol: :lol: :lol:

pat
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Message par Frenchy Pilou »

Au sujet des neurones grillés :)
http://membres.lycos.fr/acell/lr08993.html
Est beau ce qui plaît sans concept :)
Speedy Galerie
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

une méthode d'inversion de matrice

http://www.chez.com/algor/pan.htm

plus qu'a traduire ;) mais comme c'est du turbo pascal, ça ira vite car c'est très proche du Pure
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

La méthode que j'utilise est celle de GAUSS-JORDAN. Il va falloir que je passe plus de temps sur mon algo. Je vais tenter d'utiliser la division en dernier recours.

A+
Guimauve
Répondre