Interpolation de lagrange (suite et surtout fin)

cs_highvoltage Messages postés 3 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 9 janvier 2008 - 8 janv. 2008 à 22:14
cs_highvoltage Messages postés 3 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 9 janvier 2008 - 9 janv. 2008 à 14:54
Bonjour à tous et à toutes (si il y en a ),
j'ai créer un nouveau post suite à un précédent car le problème est carrément différent: au départ on était complêtement perdus (tout restait à faire), maintenant le programme est casi fini. Si les admins jugaient cela inutile, je les pris de bien vouloir remettre ce post et ses réponses à la suite du précédent. Si vous voulez connaitre toute l'histoire, voici le premier post:
http://www.cppfrance.com/infomsg_INTERPOLATION-LAGRANGE_1048540.aspx#1
Sinon, je vous résume le but du programme rapidement: On lui donne des points (leur coordonnées) et il nous renvoie un polynome qui passe par ces points. Dans tout les cas vous pouvez nous aidez sans connaitre le concept.

Notre problème: on compile le programme, il se lance, mais le résultat n'est pas bon. On a a peu près identifier le problème: il semblerait que lorsqu'on attribue la coordonnées en y de chaque point à la première colonne de notre matrice, il n'enregistre que la valeur du dernier y dans chaque case. C'est à dire que si on rentre les points A(1,2) et B(2,3), le tableau de y contiendra bien 2 3, mais lorsqu'on recopie le tableau de y dans la première colonne de la matrice, il met des 3 dans toute la première colonne. En ce qui concerne les fonctions, la plupart vienne de ce site (donc sont considérables comme sans erreur) sauf div_pol qu'on n'a codé nous même. On a peu être d'autre problème qu'on n'a pas encore remarquer, si vous en voyez n'hesitez pas, je suis ouvert à toute critique; et désolé si c'est un peu moche comme code, on est encore débutants.Voici la source, suivi d'un exemple de se que ça donne une fois compiler/executer. J'ai mis en évidence par un commentaire en maj la ligne qui semble poser problème:

#include<stdlib.h>
#include<stdio.h>
#include
#include<math.h>
#include<malloc.h>

struct polynome
{
 int degre;
 float *coef;
};

//nul?
int est_nul(polynome p)   
    {
    int i,ret=1;
    for(i=0;i<=p.degre;i++)
        {
        if(p.coef[i] != 0)
            {
            ret = 0;
            break;
            }
    }
 return ret;
 }
//maximum
int max(int a, int b)
{if(a>=b)
return a;
else
return b;
}

//Necessaire a la soustraction
void oppose(float *coefs,int deg) //Attention coefs~coeff
    {
     for(int i=0;i<=deg;i++)
        {
         coefs[i] = -coefs[i];
        }
    }
//
void new_pol(polynome *p,int deg)
    {
     int i;
     if(deg>0)
        {
         p->degre = deg;
         p->coef = (float*)calloc(deg+1,sizeof(float));
        }
     else
        {
         p->degre = 0;
         p->coef = (float*)calloc(1,sizeof(float));
        }
    }

/* Libere la memoire allou�e pour un polynome */
void free_pol(polynome *p)
    {
     p->degre=0;
     free(p->coef);
    }
   
 /* Pour afficher correctement un polynome ... */
void afficher(polynome p)
    {
    int i;
    char si;
    for(i=p.degre;i>=0;i--)
        {
        if(p.coef[i]<0.0) si = '-';
        else si = '+';

        if(i == 0) break;
        if(fabs(p.coef[i]) == 1.0) printf(" %c x^%d",si,i);
        else if(p.coef[i] != 0.0) printf(" %c %fx^%d",si,fabs(p.coef[i]),i);

        }
    if(p.coef[0] != 0)
        printf(" %c %f",si,fabs(p.coef[0]));
    printf("\n");
    }

/*Addition de p1 et p2*/
 polynome add(polynome p1,polynome p2)
    {
    int i,deg;
    polynome p;

    deg = max(p1.degre,p2.degre);
    if(p1.degre == p2.degre)
        {
        while(p1.coef[deg] == -p2.coef[deg])
            {
            deg--;
            }
        }
 new_pol(&p,deg);

    for(i=p.degre;i>=0;i--)
        {
        if(i>p1.degre) p.coef[i] = p2.coef[i];
        else if(i>p2.degre) p.coef[i] = p1.coef[i];
        else p.coef[i] = p1.coef[i]+p2.coef[i];
        }
    return p;
 }

 /*Calcul de p1 - p2*/
 polynome diff(polynome p1,polynome p2)
    {
    oppose(p2.coef,p2.degre);
    return(add(p1,p2));
    }

//Multiplication de  p1 et p2
polynome mult(polynome p1,polynome p2)
    {
     polynome p;
     if(est_nul(p1) || est_nul(p2))
        {
         new_pol(&p,0);
        }
     else
        {
         int i,j;
         new_pol(&p,p1.degre + p2.degre);
         for(i=0;i<=p1.degre;i++)
            {
             for(j=0;j<=p2.degre;j++)
                {
                 p.coef[i+j] += p1.coef[i] * p2.coef[j];
                }
            }
        }
     return p;
    }

//Division par un r�el
polynome div_pol(polynome p1,float d)
    {
    polynome p;
    if(d==0)
        exit(0);//A verifier
    if(est_nul(p1))
        {
        new_pol(&p,0);
        }
    else
        {
        new_pol(&p,p1.degre);
        for(int i=0;i<p1.degre+1;i++)
            {
            if(p1.coef[i]==0)
                p.coef[i]==0;
            else
                p.coef[i]=p1.coef[i]/d;
            }
        }
    return p;
    }

   
int main()   
{
int n,i,j;

float *x,*y;

printf("A partir de combien de points voulez-vous interpoler le polynome?\n");
scanf("%d",&n);
x=(float*)malloc(n*sizeof(float));
y=(float*)malloc(n*sizeof(float));

debut:
printf("\n Attention! Ne pas rentrer deux points de meme abscisse\n");
for (i=0;i<n;i++)
    {
     printf("\n Entrer le point %d sous la forme: x y\n",i+1);
     scanf("%f%f",&x[i],&y[i]);
     printf("%f %f\n",x[i],y[i]);
    };
for (i=0;i<n;i++)
    {
    for(j=i+1;j<n;j++)
        {if(x[i]==x[j])
            {
            printf("\n BOULET! on a dit pas 2 fois la meme abscisse, vous allez etre redirige vers l'insertion des points \n");
            goto debut;
             }
        };
    };
printf("\n Creation polynome nul...");
polynome nul;
new_pol(&nul,0);
nul.coef[0]=0;
printf("OK\n");
printf("\n Creation matrice polynome...");
polynome **t;
t=(polynome **)malloc(n*sizeof(polynome*));
for (j=0;j<n;j++)
t[j]= (polynome *)malloc(n*sizeof(polynome));
for (j=0;j<n;j++)
{
    for(i=0;i<n;i++)
    {
        t[j][i]=nul;
    }
};
printf("OK\n");

for (i=0;i<n;i++)
    {
    t[0][i].coef[0]=y[i];  //C'EST CETTE LIGNE QUI POSE PROBLEME
    };
   
afficher(t[0][0]);           //dans le résultat afficher de ses 2 lignes on devrait avoir 2 et 3 suivant l'exemple si dessous, or on obtient
afficher(t[0][1]);        // seulement 3 et 3

printf("\n Remplissage matrice...\n");
for (j=0;j<n;j++)
    {
     for(i=0;i<n-j-1;i++)
        {
        polynome Q,L,M,N,O,P;
        new_pol(&Q,1);
        Q.coef[0]=x[i];
        Q.coef[1]=-1;
        new_pol(&L,1);
        L.coef[0]=x[i+j+1];
        L.coef[1]=-1;
        afficher(Q);
        afficher(L);
        M=mult(Q,t[j][i+1]);
        afficher(M);
        N=mult(L,t[j][i]);
        afficher(N);
        O=diff(M,N);
        afficher(O);
        P=div_pol(O,(x[i]-x[i+j+1]));
        t[j+1][i]=P;
        afficher(P);
        //t[j+1][i]=div_pol((diff(mult(Q,t[j][i+1]),mult(L,t[j][i]))),(x[i]-x[i+j+1]));

        free_pol(&Q);
        free_pol(&L);
        };
    };
printf("OK\n");
afficher(t[n-1][0]);
for (int k=0;k<n;k++)
    {
    free(t[k]);
    };
free(t);

printf("\nFin du programe\n");
scanf("%d",i);
}

Exemple une fois compiler/executer:

A partir de combien de points voulez-vous interpoler le polynome?
2
Attention! Ne pas rentrer deux points de meme abscisse

Entrer le point 1 sous la forme: x y
1 2
1.00000 2.00000

Entrer le point 2 sous la forme: x y
2 3
2.00000 3.00000

Creation polynome nul....OK

Création matrice polynome...OK
+3,00000  // au lieu de 2
+3,00000  // là c'est bon

Remplissage matrice...
-x^1 + 1.00000
-x^1 + 2.00000
-3,00000x^1 + 3.00000
-3.00000x^1 + 6.00000
-3.00000
+3.00000
OK
+3.00000

Fin du programe

Merci d'avance pour votre réponse, toute aide est la bienvenue !

2 réponses

luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
8 janv. 2008 à 23:45
for (i= 0;i<n;i++)
    {
    t[0][i].coef[0]=y[i];  //C'EST CETTE LIGNE QUI POSE PROBLEME
    };

Non ce n'est pas celle la. C'est celle la:
for (j=0;j<n;j++)

{

    for(i=0;i<n;i++)

    {

        t[j][i]=nul; <== !!!


    }

};

Tous tes polynomes partages le meme buffer... celui de "polynome nul;". Donc forcément, si tu modifies un des polynomes, ils sont tous modifiés. Donc la version correcte:
for (j =0;j<n;j++)


{


    for(i=0;i<n;i++)


    {
        new_pol(&t[j][i], nul.degre);
        memcpy((void*)t[j][i].coef, (const void*)nul.coef, (nul.degre+1) * sizeof(float));



    }


};

Une remarque hors sujet:
Le coup du polynome qui alloue de la mémoire meme s'il est de degré 0, je trouve ca assez étonnant:
     if(deg>0)
        {
         p->degre = deg;
         p->coef = (float*)calloc(deg+1,sizeof(float));
        }
     else
        {
         p->degre = 0;
         p->coef = (float*)calloc(1,sizeof(float)); // J'aurais mis NULL.
        }
0
cs_highvoltage Messages postés 3 Date d'inscription jeudi 13 décembre 2007 Statut Membre Dernière intervention 9 janvier 2008
9 janv. 2008 à 14:54
Merci beaucoup pour ta reponse, tu nous sauve la mise...

Je suis etonne aue tout soit modifier dans la matrice quand on modifie
une case avec ce qu'on avait fait. En meme temps, nous on en etait
rester (dans nos cours) au bete tableau de flotants qu'on intialisait a
zero, alors on avait garder la meme methode... ces profs sont fous de
nous demander ce genre de chose avec ce qu'on a appris. Enfin,
heureusement qu'il existe des gens comme toi pret a aider de facon
completement desinteresse... Encore mille merci.


ps: dsl pour les accents, qwerty oblige
0
Rejoignez-nous