calcul formel ?!?

calcul formel ?!? - C - Programmation

Marsh Posté le 11-04-2005 à 15:48:56    

Bonjour,
 
Je cherche a faire des additions de matrices contenant des symbols du genre:
 
.5*A      A       A       A            I    J    K    L           (.5*A+I)    (A+J)           (A+K)       (A+L)
 2*B      B       B       B            I    J    K    L           (2*B+I)     (B+J)           (B+K)      (B+L)
    C      C   1.3*C     C     +     I    J    K    L     =     (C+I)       (1.3*C+J)      (C+K)       (C+L)
    D      D       D       D            I    J    K    L           (D+I)       (D+J)           (D+K)       (D+L)
 
C est le genre de truc qui se fait tres bien en matlab ou maple... mais j ai besoin de le faire en C!
En fait je m en fout un peu des A,B,... et autre, ce qui est vraiment important c est que les coefficients multiplicatifs devant chaque lettre ne ce melange pas. Example:
 
1.5*A + 2*A= 3.5*A  mais par contre 1.5*A + 2*B = 1.5*A + 2*B !
 
Pour l instant la solution la plus simple que j ai trouve (et en fait la seule que je vois) c'est de cree un tableau en 3D ou la troisieme dimension represente les lettres. Dans l exemple donne avec les matrices au dessus j aurais donc:
tab[8][4][4] ou le [8] permet d avoir:
tab[0][][] pour les coeff de A
tab[1][][] pour les coeff de B
...
tab[8][][] pour les coeff de L
 
Le resultat est alors obtenue en additionnant chaque dimension separement:
for (i=0;i<8;i++)
  for (j=0;j<4;j++)
    for(k=0;k<4;k++)
       res[i][j][k]=tab1[i][j][k]+tab2[i][j][k];
 
 
Le probleme de cette solution c est que dans mon prog. j ai 33 lettres possible, et que j utilise cette patie du code (tres) souvent. En gros je multiplie la complexite de cette partie la de mon programme par 33!
Si quelqu un a une idee pour une approache plus efficace ou un lien vers un site proposant des idees...J ai cherche sur internet avec des mots cles du genre "calcul formel", mais soit je trouve rien, soit c est des solutions trop complique par rapport a mon probleme.
Si mon explication n est pas claire dites le...j essayerais de faire mieux.
 
Merci d avance et bonne journee a tous

Reply

Marsh Posté le 11-04-2005 à 15:48:56   

Reply

Marsh Posté le 11-04-2005 à 16:00:19    

Petite idée sans réfléchir, peut-être utiliser une liste chaînée pour chaque case du style :
 
struct symbole
{
  char lettre;
  double coef;
  struct symbole *suiv;
};


Message édité par Tarabiscote le 11-04-2005 à 16:01:27
Reply

Marsh Posté le 11-04-2005 à 16:51:53    

Je peux effectivement faire une structure chainee, mais je ne pense pas que ca va fondamentalement changer la vitesse de mon prog. Merci quand meme

Reply

Marsh Posté le 11-04-2005 à 18:27:53    

Une liste chaînée est efficace quand il faut insérer un nouvel élément. Appremment, tous tes éléments sont là donc une liste chaînée ne te fera rien gagner.
Peut-être peux-tu découper tes calculs en deux parties, la première partie ne se faisant qu'une fois se fait en début de code et l'autre se faisant 33 fois
 
Autre truc: Tu iras plus vite en utilisant des pointeurs plutôt que des indices.
Par exemple, au lieu de faire  

for (i=0; i < 10; i++) tab[i]=...


Tu peux écrire

for (i=0, pt=tab; i < 10; i++, pt++) *pt=...


 
Sauf que toi, comme t'as 3 tableaux à 3 dimensions, tu devras manipuler 9 pointeurs => bonjour les noms
Une solution serait une structure incluant ton tableau en 3D et les pointeurs pour y accéder. Comme ça tout serait regroupé et t'aurais des noms plus réduits. Par exemple


typedef struct {
    int ***pt1;
    int **pt2;
    int *pt3;
    int tab[8][4][4];
} t_matrice;
 
t_matrice t1, t2, r;
 
for (i=0, t1.pt1=t1.tab, t2.pt1=t2.tab, r.pt1=r.tab;i<8;i++, t1.pt1++, t2.pt1++, r.pt1++)  
    for (j=0, t1.pt2=*t1.pt1, t2.pt2=*t2.pt1, r.pt2=*r.pt1;j<4;j++, t1.pt2++, t2.pt2++, r.pt2++)  
        for (k=0, t1.pt3=*t1.pt2, t2.pt3=*t2.pt2, r.pt3=*r.pt2);k<4;k++, t1.pt3++, t2.pt3++, r.pt3++)  
           *r.pt3=*t1.pt3 + *t2.pt3;

Reply

Marsh Posté le 11-04-2005 à 18:39:58    

Enfin la liste chaîné ne fait rien gagner si on utilise les 33 lettres possibles mais si on en utilise que une ou deux ...
 
Autrement avec les pointeurs, je pense qu'on peut faire mieux
 
Moi je ferais plutot :

Code :
  1. double *pt, *fin;
  2. for (pt = tab, fin = tab + 10; pt != fin; ++pt) *pt = ...


 
à la place de

Code :
  1. for (i=0, pt=tab; i < 10; i++, pt++) *pt=...


 
(moins d'incrémentation)

Reply

Marsh Posté le 11-04-2005 à 19:28:46    

Tarabiscote a écrit :

Moi je ferais plutot :

Code :
  1. double *pt, *fin;
  2. for (pt = tab, fin = tab + 10; pt != fin; ++pt) *pt = ...


 
à la place de

Code :
  1. for (i=0, pt=tab; i < 10; i++, pt++) *pt=...


 
(moins d'incrémentation)


 
Exact...

Reply

Marsh Posté le 11-04-2005 à 19:57:30    

Merci a tous pour les idees.
Je vais essayer de voire ce que ca donne au niveau gain de temps ... une fois que j ai fixe un bug que j ai decouvert entre temps dans mon raisonnement algorithmique  :cry:  

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed