/*************************************************************************************************************************************/
/* */
/* I N T E R P O L A T I O N D U N - I E M E D E G R E : */
/* */
/* */
/* Principe : */
/* */
/* On se donne un polynome de */
/* degre N en t, soit : */
/* */
/* k=N */
/* _____ */
/* \ */
/* \ k */
/* P(t) = / a .t */
/* /____ k */
/* */
/* k=0 */
/* */
/* de derivee : */
/* */
/* k=N */
/* _____ */
/* \ */
/* \ k-1 */
/* P'(t) = / k.a .t */
/* /____ k */
/* */
/* k=0 */
/* */
/* Ce polynome va etre defini sur [O,E] */
/* (pour 'Origine' et 'Extremite'), et */
/* l'on se donne les valeurs suivantes : */
/* */
/* P(O) */
/* P'(O) */
/* P(E) */
/* P'(E) */
/* */
/* Quatre indices {I,J,K,L} sont tires */
/* au sort dans [0,N] (en entier...). */
/* Les valeurs des coefficients 'a' pour */
/* des indices autres que {I,J,K,L} sont */
/* tirees au sort : */
/* */
/* a = RANDOM */
/* k */
/* */
/* avec : */
/* */
/* k # {I,J,K,L} */
/* */
/* En ce qui concerne les valeurs des quatre */
/* coefficients 'a' pour les indices {I,J,K,L}, */
/* elles sont calculees de la facon suivante ; */
/* soit : */
/* */
/* P (O) */
/* p */
/* */
/* P'(O) */
/* p */
/* */
/* P (E) */
/* p */
/* */
/* P'(E) */
/* p */
/* */
/* les valeurs respectives de P(O), P'(O) */
/* P(E) et P'(E) en omettant les monomes */
/* de rang {I,J,K,L}. On a alors le systeme */
/* lineaire suivant de 4 equations a 4 */
/* inconnues : */
/* */
/* I J K L */
/* a .O + a .O + a .O + a .O = P(O) - P (O) */
/* I J K L p */
/* */
/* I J K L */
/* a .E + a .E + a .E + a .E = P(E) - P (E) */
/* I J K L p */
/* */
/* I-1 J-1 K-1 L-1 */
/* I.a .O + J.a .O + K.a .O + L.a .O = P'(O) - P'(O) */
/* I J K L p */
/* */
/* I-1 J-1 K-1 L-1 */
/* I.a .E + J.a .E + K.a .E + L.a .E = P'(E) - P'(E) */
/* I J K L p */
/* */
/* qui, resolu avec une simple methode de */
/* Cramer, donnera la valeur des coefficients */
/* 'a' pour les indices {I,J,K,L}... */
/* */
/* */
/* Author of '$xtc/interpolN.03$c' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 1997MMJJhhmmss). */
/* */
/*************************************************************************************************************************************/
#include "INCLUDES.01.I"
/* Introduit le 20051116101250... */
extern double drand48();
#define RANDOM \
(1.0*(drand48()-0.5)) \
/* Les coefficients 'a' sont aleatoires dans [-0.5,+0.5] (sauf ceux d'indice {I,J,K,L}). */
#define FONCTION_ORIGINE \
0
#define DERIVEE_ORIGINE \
0
/* Definition de la fonction Origine. */
#define FONCTION_EXTREMITE \
1
#define DERIVEE_EXTREMITE \
0
/* Definition de la fonction Extremite. */
#define EXTENSION \
1.0 \
/* Extension du segment [FONCTION_ORIGINE,FONCTION_EXTREMITE] pour la visualisation qui */ \
/* aura donc lieu dans [FONCTION_ORIGINE-EXTENSION,FONCTION_EXTREMITE+EXTENSION]. */
#define T0 \
(0.0)
#define T1 \
(+1.0)
#define PAS \
0.01
/* Definition du parametre d'interpolation. */
#define DEGRE_N \
5 \
/* Degre du polynome. */
#define DEGRE_0 \
0
#define DEGRE_1 \
(DEGRE_0+1)
#define DEGRE_2 \
(DEGRE_1+1)
#define DEGRE_3 \
(DEGRE_2+1)
/* Premiers coefficients du polynome. */
int max2(a,b)
int a,b;
{
return(MAX2(a,b));
}
/* Cette fonction est destinee a eviter les effets de bord a prevoir si 'MAX2(...)' est */
/* appele avec comme argument 'drand48()' qui risque alors d'etre appele plusieurs fois */
/* de suite sans redonner (evidemment...) le meme resultat puisqu'il est aletaoire... */
int min2(a,b)
int a,b;
{
return(MIN2(a,b));
}
/* Cette fonction est destinee a eviter les effets de bord a prevoir si 'MIN2(...)' est */
/* appele avec comme argument 'drand48()' qui risque alors d'etre appele plusieurs fois */
/* de suite sans redonner (evidemment...) le meme resultat puisqu'il est aletaoire... */
#define CHOIX(exposant_IJKL,forcer_exposant_IJKL) \
{ \
if (tirer_au_sort_les_exposants == 1) \
{ \
while (selection_IJKL[exposant_IJKL=min2((int)(DEGRE_0+(drand48()*(DEGRE_N+1))),DEGRE_N)] != 0) \
/* On notera l'ecriture 'DEGRE_N+1' et non pas 'DEGRE_N' que la logique reclame, et ce afin */ \
/* de garantir l'accessibilite de 'DEGRE_N'... */ \
{ \
} \
} \
else \
{ \
exposant_IJKL = forcer_exposant_IJKL; \
} \
\
selection_IJKL[exposant_IJKL]++; \
}
extern void *malloc();
static int dimX=0;
#define Xmin 0
#define Xmax (Xmin + (dimX-1))
/* Definition des abscisses. */
static int dimY=0;
#define Ymin 0
#define Ymax (Ymin + (dimY-1))
/* Definition des ordonnees. */
#define IMAGE(x,y) \
(*(image + (((y-Ymin)*dimX) + (x-Xmin)))) \
/* Acces a un point de l'image. */
#define store(n,x,y) \
{ \
IMAGE(MAX2(MIN2(x,Xmax),Xmin),MAX2(MIN2(y,Ymax),Ymin)) = n; \
} \
/* Rangement d'un point valide d'une image. */
double puis(x,n)
double x;
int n;
{
int k;
double monome=((n>=0) ? 1 : 0);
for (k=1 ; k<=n ; k++)
{
monome=monome*x;
}
return(monome);
}
/* Calcul de 'x' a la puissance 'n'. */
static double coefficients[DEGRE_N+1];
/* Definition des N+1 coefficients du polynome 'P(t)'. */
double Cpolynome(x,degre)
double x;
int degre;
{
int exposant;
double polynome=0;
for (exposant=degre ; exposant>=DEGRE_0 ; exposant--)
{
polynome = (polynome*x)+coefficients[exposant];
}
return(polynome);
}
/* Calcul de la valeur du polynome en 'x' par la methode de Horner. */
double Cderivee(x,degre)
double x;
int degre;
{
int exposant;
double derivee=0;
for (exposant=degre ; exposant>DEGRE_0 ; exposant--)
{
derivee = (derivee*x)+(exposant*coefficients[exposant]);
}
return(derivee);
}
/* Calcul de la valeur de la derivee du polynome en 'x' par la methode de Horner. */
main()
{
int visualiser=1;
/* #0 : visualiser, =0 : editer les coefficients du polynome. */
int sauter;
int graine=1;
/* En fait indique un nombre d'iterations initiales sur 'drand48()' permettant de faire */
/* generer ainsi des suites de nombres aleatoires differentes. */
int tirer_au_sort_les_exposants=1;
int forcer_exposant_I=DEGRE_N;
int forcer_exposant_J=DEGRE_2;
int forcer_exposant_K=DEGRE_1;
int forcer_exposant_L=DEGRE_0;
/* #0 : tirer au sort les exposants {I,J,K,L}, =0 : les forcer avec les 4 valeurs ci-dessus. */
int tirer_au_sort_les_coefficients=1;
double valeur_commune_des_coefficients=1;
/* #0 : tirer au sort les coefficients des indices differents de {I,J,K,L}, =0 : les forcer */
/* avec la valeur commune 'valeur_commune_des_coefficients'. */
double fO=FONCTION_ORIGINE,dO=DERIVEE_ORIGINE;
double fE=FONCTION_EXTREMITE,dE=DERIVEE_EXTREMITE;
/* Definition des conditions aux limites de la fonction sur [O,E]. */
double t;
/* Variable 't' courante. */
int exposant;
/* Exposant courant. */
int selection_IJKL[DEGRE_N+1];
int exposant_I,exposant_J,exposant_K,exposant_L;
/* Exposants {I,J,K,L} aleatoires dans [0,N] et liste destinee a eviter que deux de ces */
/* exposants ne soient identiques... */
double polynome,derivee;
/* Valeur courante du polynome et de sa derivee. */
double polynome_partiel_O,derivee_partielle_O,polynome_partiel_E,derivee_partielle_E;
/* Valeur des polynomes et derivees "partiels" aux points {O,E}. */
double determinant=0;
/* Valeur du determinant du systeme cramerien. La valeur nulle indiquant qu'il n'a pas */
/* encore ete calcule. */
double membreD1,membreD2,membreD3,membreD4;
/* Valeurs des quatre membres de droite des quatre equations lineaires a resoudre... */
int x,y;
/* Definition des coordonnees de l'image. */
unsigned char *image;
/* Definition de l'image a generer... */
if (DEGRE_N < DEGRE_3)
{
printf("\n cette methode exige au moins le degre %d",DEGRE_3);
}
else
{
}
for (sauter=1 ; sauter<=graine ; sauter++)
{
double a_sauter=drand48();
}
if (visualiser == 0)
{
}
else
{
Get(dimX,"dimX");
Get(dimY,"dimY");
/* Recuperation des dimensions en 'X' et en 'Y' de l'image a generer. */
image=malloc(dimY*dimX);
/* Definition de l'image a generer... */
for (y=Ymin ; y<=Ymax ; y++)
{
for (x=Xmin ; x<=Xmax ; x++)
{
store(NOIR,x,y);
/* Initialisation de l'image a generer... */
}
}
}
while (determinant==0)
/* Tant que le determinant est nul (et donc en particulier la premiere fois), on va */
/* choisir aleatoirement quatre indices {I,J,K,L}. */
{
for (exposant=DEGRE_0 ; exposant<=DEGRE_N ; exposant++)
{
selection_IJKL[exposant] = 0;
/* Aucun des exposants aleatoires (I,J,K,L) n'a encore ete selectionne... */
}
CHOIX(exposant_I,forcer_exposant_I);
CHOIX(exposant_J,forcer_exposant_J);
CHOIX(exposant_K,forcer_exposant_K);
CHOIX(exposant_L,forcer_exposant_L);
/* Choix aleatoire des indices {I,J,K,L} des quatre coefficients qui sont calcules a partir */
/* des autres... */
for (exposant=DEGRE_0 ; exposant<=DEGRE_N ; exposant++)
{
if ( (exposant!=exposant_I)
&& (exposant!=exposant_J)
&& (exposant!=exposant_K)
&& (exposant!=exposant_L)
)
{
if (tirer_au_sort_les_coefficients == 0)
{
coefficients[exposant]=valeur_commune_des_coefficients;
}
else
{
coefficients[exposant]=RANDOM;
}
/* Initialisation arbitraire de tous les coefficients 'a' du polynome sauf les quatre */
/* d'indices {I,J,K,L} que l'on va calculer ci-apres a l'aide d'un systeme lineaire. */
}
else
{
coefficients[exposant]=0;
/* Ainsi les coefficients d'indices {I,J,K,L} ne participeront pas ci-apres au calcul de */
/* 'polynome_partiel_?' et de 'derivee_partielle_?'... */
}
}
polynome_partiel_O = Cpolynome(T0,DEGRE_N);
polynome_partiel_E = Cpolynome(T1,DEGRE_N);
/* Calcul de la valeur du polynome "partiel" en {O,E} par la methode de Horner. */
derivee_partielle_O = Cderivee(T0,DEGRE_N);
derivee_partielle_E = Cderivee(T1,DEGRE_N);
/* Et de la valeur de la derivee du polynome "partiel" en {O,E} par la methode de Horner. */
determinant = DET4(puis(T0,exposant_I)
,puis(T0,exposant_J)
,puis(T0,exposant_K)
,puis(T0,exposant_L)
,puis(T1,exposant_I)
,puis(T1,exposant_J)
,puis(T1,exposant_K)
,puis(T1,exposant_L)
,exposant_I*puis(T0,exposant_I-1)
,exposant_J*puis(T0,exposant_J-1)
,exposant_K*puis(T0,exposant_K-1)
,exposant_L*puis(T0,exposant_L-1)
,exposant_I*puis(T1,exposant_I-1)
,exposant_J*puis(T1,exposant_J-1)
,exposant_K*puis(T1,exposant_K-1)
,exposant_L*puis(T1,exposant_L-1)
);
/* Calcul du determinant du systeme lineaire a resoudre. */
}
membreD1 = fO-polynome_partiel_O;
membreD2 = fE-polynome_partiel_E;
membreD3 = dO-derivee_partielle_O;
membreD4 = dE-derivee_partielle_E;
/* Calcul des quatre membres de droite. */
coefficients[exposant_I] = DET4(membreD1
,puis(T0,exposant_J)
,puis(T0,exposant_K)
,puis(T0,exposant_L)
,membreD2
,puis(T1,exposant_J)
,puis(T1,exposant_K)
,puis(T1,exposant_L)
,membreD3
,exposant_J*puis(T0,exposant_J-1)
,exposant_K*puis(T0,exposant_K-1)
,exposant_L*puis(T0,exposant_L-1)
,membreD4
,exposant_J*puis(T1,exposant_J-1)
,exposant_K*puis(T1,exposant_K-1)
,exposant_L*puis(T1,exposant_L-1)
)/determinant;
coefficients[exposant_J] = DET4(puis(T0,exposant_I)
,membreD1
,puis(T0,exposant_K)
,puis(T0,exposant_L)
,puis(T1,exposant_I)
,membreD2
,puis(T1,exposant_K)
,puis(T1,exposant_L)
,exposant_I*puis(T0,exposant_I-1)
,membreD3
,exposant_K*puis(T0,exposant_K-1)
,exposant_L*puis(T0,exposant_L-1)
,exposant_I*puis(T1,exposant_I-1)
,membreD4
,exposant_K*puis(T1,exposant_K-1)
,exposant_L*puis(T1,exposant_L-1)
)/determinant;
coefficients[exposant_K] = DET4(puis(T0,exposant_I)
,puis(T0,exposant_J)
,membreD1
,puis(T0,exposant_L)
,puis(T1,exposant_I)
,puis(T1,exposant_J)
,membreD2
,puis(T1,exposant_L)
,exposant_I*puis(T0,exposant_I-1)
,exposant_J*puis(T0,exposant_J-1)
,membreD3
,exposant_L*puis(T0,exposant_L-1)
,exposant_I*puis(T1,exposant_I-1)
,exposant_J*puis(T1,exposant_J-1)
,membreD4
,exposant_L*puis(T1,exposant_L-1)
)/determinant;
coefficients[exposant_L] = DET4(puis(T0,exposant_I)
,puis(T0,exposant_J)
,puis(T0,exposant_K)
,membreD1
,puis(T1,exposant_I)
,puis(T1,exposant_J)
,puis(T1,exposant_K)
,membreD2
,exposant_I*puis(T0,exposant_I-1)
,exposant_J*puis(T0,exposant_J-1)
,exposant_K*puis(T0,exposant_K-1)
,membreD3
,exposant_I*puis(T1,exposant_I-1)
,exposant_J*puis(T1,exposant_J-1)
,exposant_K*puis(T1,exposant_K-1)
,membreD4
)/determinant;
/* Resolution du systeme des qu'il n'est plus indetermnine... */
if (visualiser == 0)
{
if ( (Cpolynome(T0,DEGRE_N) != fO)
|| (Cderivee(T0,DEGRE_N) != dO)
|| (Cpolynome(T1,DEGRE_N) != fE)
|| (Cderivee(T1,DEGRE_N) != dE)
)
{
printf("\n erreur d'interpolation :");
printf("\n fO : attendue=%f calculee=%f",fO,Cpolynome(T0,DEGRE_N));
printf("\n dO : attendue=%f calculee=%f",dO,Cderivee(T0,DEGRE_N));
printf("\n fE : attendue=%f calculee=%f",fE,Cpolynome(T1,DEGRE_N));
printf("\n dE : attendue=%f calculee=%f",dE,Cderivee(T1,DEGRE_N));
}
else
{
}
printf("\n I=%d",exposant_I);
printf("\n J=%d",exposant_J);
printf("\n K=%d",exposant_K);
printf("\n L=%d",exposant_L);
printf("\n\n");
for (exposant=DEGRE_N ; exposant>=DEGRE_0 ; exposant--)
{
printf("+(%g*t^%d)",coefficients[exposant],exposant);
}
/* Edition du polynome selectionne lorsque cela est demande. */
printf("\n");
}
else
{
for (t=T0 ; t<=T1 ; t=t+PAS)
{
int x,y;
polynome = Cpolynome(t,DEGRE_N);
/* Calcul du polynome par la methode de Horner. */
x = Xmin+((Xmax-Xmin)*((t-T0)/(T1-T0)));
y = Ymin+((Ymax-Ymin)*((polynome-(fO-EXTENSION))/((fE+EXTENSION)-(fO-EXTENSION))));
store(BLANC,x,y);
/* Visualisation du polynome selectionne lorsque cela est demande. */
}
write(1,image,dimX*dimY);
/* Sortie de l'image... */
}
}