_______________________________________________________________________________________________________________________________________
/*************************************************************************************************************************************/
/* */
/* T R A N S F O R M E E D E F O U R I E R : */
/* */
/* */
/* Definition : */
/* */
/* Dans ce fichier se trouvent toutes */
/* les fonctions necessaires a la trans- */
/* formee de Fourier. */
/* */
/* */
/* Author of '$ximt/fourier$FON' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 19880000000000). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/* :Debut_listMN_TRANSFORMEE_DE_FOURIER_11: */
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E L A T R A N S F O R M E E D E F O U R I E R : */
/* */
/* */
/* Cas mono-dimensionnel : */
/* --------------------- */
/* */
/* Soit une fonction "discrete" 'f' */
/* connue aux points {0,1,2,...,N-1}, */
/* ce qui signifie que l'on connait les */
/* valeurs {f(0),f(1),f(2),...,f(N-1)}. */
/* Designons par T (f,u) la transformee de */
/* N */
/* Fourier "discrete" de la fonction 'f' */
/* au point 'u' et calculee pour 'N' points. */
/* Elle est definie par : */
/* */
/* n=N-1 */
/* _____ u */
/* \ -(2.i.p.---.n) */
/* T (f,u) = / f(n).e N ou 'p' designe 'pi' et */
/* N ----- 'i' la racine de -1. */
/* n=0 */
/* */
/* 'u' est appelee "frequence spatiale", */
/* et varie dans [0,N-1], tout comme la */
/* variable 'n'. */
/* */
/* L'algorithme dit de "transformee */
/* rapide" (ou 'FFT" en anglais), repose */
/* sur le raisonnement suivant : */
/* */
/* posons, en supposant 'N' pair, et */
/* meme une puissance de 2 (a cause */
/* de la dichotomie que l'on va mettre */
/* en evidence) : */
/* */
/* N */
/* M = ---, */
/* 2 */
/* */
/* on a alors : */
/* */
/* m=M-1 */
/* _____ u u u */
/* \ -(2.i.p.---.m) -(2.i.p.(---.m + ---)) */
/* T (f,u) = / [f(2.m).e M + f(2.m+1).e M N ] */
/* N ----- */
/* m=0 */
/* */
/* m=M-1 m=M-1 */
/* _____ u u _____ u */
/* \ -(2.i.p.---.m) -(2.i.p.---) \ -(2.i.p.---.m) */
/* T (f,u) = / f(2.m).e M + e N ./ f(2.m+1).e M */
/* N ----- ----- */
/* m=0 m=0 */
/* */
/* soit donc : */
/* */
/* u */
/* -(2.i.p.---) */
/* T (f,u) = T (f.paire,u) + e N .T (f.impaire,u), */
/* N N N */
/* --- --- */
/* 2 2 */
/* */
/* avec : */
/* */
/* T (f,u) = f(du_point_unique), quel que soit 'u'. */
/* 1 */
/* */
/* ou 'f.paire/impaire,u' signifie que l'on */
/* ne conserve que les coefficients pairs et */
/* impairs de la fonction 'f' respectivement. */
/* Ainsi, on divise par 2 exactement le nombre */
/* de points sur lesquels faire les calculs, */
/* tout en arrivant a une definition recursive */
/* de la transformee de Fourier... */
/* */
/* Le cout de l'algorithme de transformee */
/* de Fourier rapide mono-dimensionnelle est */
/* donc en N.Log(N). */
/* */
/* En ce qui concerne les periodes de la */
/* frequence spatiale 'u', on peut dire la */
/* chose suivante : */
/* */
/* u */
/* pour T (f,u), on trouve ---, on peut donc */
/* N N */
/* considerer que la periode de 'u' est 'N', */
/* et donc 'u' est a considerer dans [0,N-1]. */
/* Alors que pour T (f.paire,u) et T (f.impaire,u), */
/* N N */
/* --- --- */
/* 2 2 */
/* u */
/* on trouve ---, on peut donc considerer que */
/* M */
/* la periode de 'u' est alors 'M' (ou 'M' est */
/* la moitie de 'N') ; 'u' est alors a considerer */
/* dans [0,M-1]. */
/* */
/* */
/* Cas bi-dimensionnel : */
/* ------------------- */
/* */
/* Soit une fonction "discrete" 'f' */
/* connue aux points {0,1,2,...,N-1}x{0,1,2,...,N-1}, */
/* ce qui signifie que l'on connait les */
/* valeurs {f(0,0),f(0,1),f(0,2),...,f(0,N-1),...,f(N-1,0),f(N-1,1),f(N-1,2),...,f(N-1,N-1)}. */
/* Designons par T(f,u,v) la transformee de */
/* Fourier "discrete" de la fonction 'f' aux points 'u' et 'v'. */
/* Elle est definie par : */
/* */
/* y=Y-1 x=X-1 */
/* _____ _____ u v */
/* \ \ -[2.i.p.(---.x + ---.y)] */
/* T(f,u,v) = / / f(x,y).e X Y */
/* ----- ----- */
/* y=0 x=0 */
/* */
/* ou (u,v) E [0,X-1]x[0,Y-1], 'p' designe 'pi' et 'i' la racine de -1. */
/* */
/* Comme on le verra dans la programmation */
/* qui suit, la 'FFT' bi-dimensionnelle peut */
/* se ramener au calcul de 'FFT' mono- */
/* dimensionnelles "orthogonales". */
/* */
/* Le cout de l'algorithme de transformee */
/* rapide de Fourier bi-dimensionnelle est donc */
/* en 2N.N.Log(N) ; en effet, on effectue 'N' */
/* transformees horizontales, puis 'N' trans- */
/* formee verticales (d'ou le '2N'), chacune */
/* etant en N.Log(N)... On notera que : */
/* */
/* 2 2 2 */
/* 2N.N.Log(N) = N .2.Log(N) = N .Log(N ). */
/* */
/* */
/* Transformees inverses : */
/* --------------------- */
/* */
/* Pour obtenir en mono- et bi-dimensionnel */
/* la transformee inverse, il suffit de changer */
/* le signe de l'exposant dans l'exponentielle : */
/* */
/* u=N-1 */
/* _____ n */
/* 1 \ 2.i.p.---.u */
/* f(n) = --- / T (f,u).e N ou n E [0,N-1], 'p' designe 'pi' et */
/* N ----- N 'i' la racine de -1. */
/* u=0 */
/* */
/* */
/* v=Y-1 u=X-1 */
/* _____ _____ x y */
/* 1 \ \ 2.i.p.(---.u + ---.v) */
/* f(x,y) = ---- / / T(f,u,v).e X Y */
/* 2 ----- ----- */
/* N v=0 u=0 */
/* */
/* ou {x,y} E [0,X-1]x[0,Y-1], 'p' designe 'pi' et 'i' la racine de -1. */
/* */
/* */
/*************************************************************************************************************************************/
/* :Fin_listMN_TRANSFORMEE_DE_FOURIER_11: */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* A P P R O X I M A T I O N D U ' C O S I N U S ' : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fcosinus_approxime(u)))
DEFV(Argument,DEFV(Float,u));
/* Valeur de l'angle argument en radians. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fx,COSA(u)));
/* On renvoie (1-u2/2). */
/*..............................................................................................................................*/
RETU(fx);
Eblock
EFonctionF
_______________________________________________________________________________________________________________________________________
_______________________________________________________________________________________________________________________________________
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* A P P R O X I M A T I O N D U ' S I N U S ' : */
/* */
/*************************************************************************************************************************************/
BFonctionF
DEFV(Common,DEFV(FonctionF,Fsinus_approxime(u)))
DEFV(Argument,DEFV(Float,u));
/* Valeur de l'angle argument en radians. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Float,INIT(fx,SINA(u)));
/* On renvoie (u-u3/6). */
/*..............................................................................................................................*/
RETU(fx);
Eblock
EFonctionF
_______________________________________________________________________________________________________________________________________
_______________________________________________________________________________________________________________________________________
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* T R A N S F O R M E E D E F O U R I E R M O N O - D I M E N S I O N N E L L E R E E L L E : */
/* */
/*************************************************************************************************************************************/
BFonctionI
#define PREMIER_ELEMENT_DE_LA_FONCTION \
INDEX0 \
/* Premier element du vecteur definissant la fonction. */
#define PREMIER_ELEMENT_DE_LA_TRANSFORMEE \
INDEX0 \
/* Premier element du vecteur definissant sa transformee. */
#define MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION \
MOIT(nombre_de_points_de_la_fonction) \
/* La dichotomie de la transformee de Fourier se fait en diminuant de moitie */ \
/* le nombre d'elements de la definition. */
#define MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE \
MOIT(nombre_de_points_de_la_transformee) \
/* La dichotomie de la transformee de Fourier se fait en diminuant de moitie */ \
/* le nombre d'elements de la definition, ce qui double la periode a chaque etape... */
#define PAS_DES_ITERATIONS_DE_FOURIER \
TRMU(TRPU(nombre_de_points_a_la_fin_de_la_recursivite)) \
/* Pas a utiliser pour balayer les vecteurs definissant la fonction et ses transformees. */
DEFV(Local,DEFV(FonctionI,Ifourier_1D_reelle(transformee_de_la_fonction
,nombre_de_points_de_la_transformee
,fonction
,nombre_de_points_de_la_fonction
,nombre_de_points_a_la_fin_de_la_recursivite
,ARGUMENT_FONCTION(transformation)
,calcul_de_la_transformee_directe
)
)
)
DEFV(Argument,DEFV(Float,DTb0(transformee_de_la_fonction)));
/* Vecteur contenant la transformee de Fourier de la fonction argument. */
DEFV(Argument,DEFV(Positive,nombre_de_points_de_la_transformee));
/* Dimension du vecteur contenant la transformee de la fonction. */
DEFV(Argument,DEFV(Float,DTb0(fonction)));
/* Vecteur contenant la fonction discrete argument. */
DEFV(Argument,DEFV(Positive,nombre_de_points_de_la_fonction));
/* Dimension du vecteur contenant la fonction a transformer. */
DEFV(Argument,DEFV(Positive,nombre_de_points_a_la_fin_de_la_recursivite));
/* Dimension limite correspondant a la fin de la recursivite (en general */
/* vaudra 'UNITE'). */
DEFV(Argument,DEFV(Float,afPOINTEUR(transformation)));
/* Definition de la fonction de transformation (en general un 'cosinus', */
/* ou un 'sinus'). */
DEFV(Argument,DEFV(Logical,calcul_de_la_transformee_directe));
/* Cet indicateur precise si l'on calcule la transformee directe ('VRAI'), */
/* ou inverse ('FAUX'). */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
INIT_ERROR;
/* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */
/* ('BDEFV','EDEFV') suivraient... */
DEFV(Int,INIT(frequence_spatiale,UNDEF));
/* Definition de la frequence spatiale 'u' courante. */
/*..............................................................................................................................*/
Test(IFLT(nombre_de_points_de_la_fonction,nombre_de_points_a_la_fin_de_la_recursivite))
Bblock
PRINT_ERREUR("la definition de la fonction est mauvaise");
/* Ou bien, le nombre de points initial est negatif ou nul, ou bien, la */
/* fin de la recursivite n'est pas une puissance de 2... */
CODE_ERROR(ERREUR15);
Eblock
ATes
Bblock
Test(IFEQ(nombre_de_points_de_la_fonction,nombre_de_points_a_la_fin_de_la_recursivite))
Bblock
DoIn(frequence_spatiale
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,nombre_de_points_de_la_transformee)
,PAS_DES_ITERATIONS_DE_FOURIER
)
Bblock
EGAL(ITb0(transformee_de_la_fonction,INDX(frequence_spatiale,PREMIER_ELEMENT_DE_LA_TRANSFORMEE))
,ITb0(fonction,INDX(PREMIER_ELEMENT_DE_LA_FONCTION,PREMIER_ELEMENT_DE_LA_FONCTION))
);
/* Cas de la fin de la recursivite : ainsi que l'on peut le voir sur les */
/* formules, en faisant n=0, l'exponentielle complexe vaut 1, et il ne */
/* reste que la fonction... */
Eblock
EDoI
Eblock
ATes
Bblock
/* Cas, ou la recursivite doit se poursuivre... */
DEFV(Int,INIT(coordonnee_spatiale,UNDEF));
/* Index permettant de calculer les fonctions "paire" et "impaire". */
DEFV(Float,DdTb1(POINTERf
,fonction_paire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,fMalo(MUL2(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,size_Float))
)
);
/* Allocation du vecteur contenant la fonction obtenue en ne conservant que les */
/* coefficients pairs de la fonction argument. */
DEFV(Float,DdTb1(POINTERf
,transformee_de_la_fonction_paire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,fMalo(MUL2(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE,size_Float))
)
);
/* Allocation du vecteur contenant la transformee de Fourier de la fonction */
/* obtenue en ne conservant que les coefficients de rang pair de la fonction */
/* argument. */
DEFV(Float,DdTb1(POINTERf
,fonction_impaire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,fMalo(MUL2(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,size_Float))
)
);
/* Allocation du vecteur contenant la fonction obtenue en ne conservant que les */
/* coefficients de rang impair de la fonction argument. */
DEFV(Float,DdTb1(POINTERf
,transformee_de_la_fonction_impaire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,fMalo(MUL2(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE,size_Float))
)
);
/* Allocation du vecteur contenant la transformee de Fourier de la fonction */
/* obtenue en ne conservant que les coefficients impairs de la fonction */
/* argument. */
DEFV(Float,INIT(argument,FLOT__UNDEF));
/* Afin de calculer (au signe pres) l'argument de la fonction de */
/* transformation definissant la transformee a calculer (voir l'argument */
/* 'transformation' ci-dessus). */
Test(IFNE(DOUB(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION),nombre_de_points_de_la_fonction))
Bblock
PRINT_ERREUR("la dimension n'est pas une puissance de 2");
Eblock
ATes
Bblock
Eblock
ETes
DoIn(coordonnee_spatiale
,PREMIER_ELEMENT_DE_LA_FONCTION
,LSTX(PREMIER_ELEMENT_DE_LA_FONCTION,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION)
,PAS_DES_ITERATIONS_DE_FOURIER
)
Bblock
EGAL(IdTb1(fonction_paire
,INDX(coordonnee_spatiale,PREMIER_ELEMENT_DE_LA_FONCTION)
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
)
,ITb0(fonction
,INDX(NEUT(ADD2(DOUB(SOUS(coordonnee_spatiale,PREMIER_ELEMENT_DE_LA_FONCTION))
,PREMIER_ELEMENT_DE_LA_FONCTION
)
)
,PREMIER_ELEMENT_DE_LA_FONCTION
)
)
);
/* "Calcul" de la fonction ne contenant que les coefficients pairs de la */
/* fonction argument. */
EGAL(IdTb1(fonction_impaire
,INDX(coordonnee_spatiale,PREMIER_ELEMENT_DE_LA_FONCTION)
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
)
,ITb0(fonction
,INDX(ADD2(ADD2(DOUB(SOUS(coordonnee_spatiale,PREMIER_ELEMENT_DE_LA_FONCTION))
,PREMIER_ELEMENT_DE_LA_FONCTION
)
,PAS_DES_ITERATIONS_DE_FOURIER
)
,PREMIER_ELEMENT_DE_LA_FONCTION
)
)
);
/* "Calcul" de la fonction ne contenant que les coefficients impairs de la */
/* fonction argument. */
Eblock
EDoI
CALS(Ifourier_1D_reelle(transformee_de_la_fonction_paire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
,fonction_paire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,nombre_de_points_a_la_fin_de_la_recursivite
,aFONCTION(transformation)
,calcul_de_la_transformee_directe
)
);
/* Calcul de la transformee de Fourier relative aux coefficients pairs */
/* de la fonction argument. */
CALS(Ifourier_1D_reelle(transformee_de_la_fonction_impaire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
,fonction_impaire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,nombre_de_points_a_la_fin_de_la_recursivite
,aFONCTION(transformation)
,calcul_de_la_transformee_directe
)
);
/* Calcul de la transformee de Fourier relative aux coefficients impairs */
/* de la fonction argument. */
DoIn(frequence_spatiale
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,nombre_de_points_de_la_transformee)
,PAS_DES_ITERATIONS_DE_FOURIER
)
Bblock
EGAL(argument
,SCAL(CERCLE_TRIGONOMETRIQUE
,nombre_de_points_de_la_fonction
,frequence_spatiale
)
);
/* Argument de la fonction de transformation (au signe pres...). */
EGAL(ITb0(transformee_de_la_fonction
,INDX(frequence_spatiale,PREMIER_ELEMENT_DE_LA_TRANSFORMEE)
)
,ADD2(IdTb1(transformee_de_la_fonction_paire
,INDX(MODU(frequence_spatiale
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
)
)
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
)
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
)
,MUL2(FLOT(fPOINTEUR(transformation)(DPRE(COND(IL_FAUT(calcul_de_la_transformee_directe)
,NEGA(argument)
,argument
)
)
)
)
,IdTb1(transformee_de_la_fonction_impaire
,INDX(MODU(frequence_spatiale
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
)
)
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
)
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
)
)
)
);
/* Calcul de la transformee de Fourier de la fonction argument en recombinant */
/* les transformees dites "paires" et "impaires" : */
/* */
/* 1-pour la "directe" : */
/* */
/* u */
/* -(2.i.p.---) */
/* T (f,u) = T (f.paire,u) + e N .T (f.impaire,u) */
/* N N N */
/* --- --- */
/* 2 2 */
/* */
/* 2-pour l'"inverse" : */
/* */
/* u */
/* 2.i.p.--- */
/* T (f,u) = T (f.paire,u) + e N .T (f.impaire,u) */
/* N N N */
/* --- --- */
/* 2 2 */
/* */
Eblock
EDoI
/* Les 'ADRESSE_PLUS_DEFINIE's ci-dessous ont ete introduits le 20050221170159... */
FdTb1(transformee_de_la_fonction_impaire,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,Float,ADRESSE_PLUS_DEFINIE);
/* Liberation du vecteur contenant la transformee de Fourier de la fonction */
/* obtenue en ne conservant que les coefficients impairs de la fonction */
/* argument. */
FdTb1(fonction_impaire,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,Float,ADRESSE_PLUS_DEFINIE);
/* Liberation du vecteur contenant la fonction obtenue en ne conservant */
/* que les coefficients de rang impair de la fonction argument. */
FdTb1(transformee_de_la_fonction_paire,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,Float,ADRESSE_PLUS_DEFINIE);
/* Liberation du vecteur contenant la transformee de Fourier de la fonction */
/* obtenue en ne conservant que les coefficients de rang pair de la fonction */
/* argument. */
FdTb1(fonction_paire,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,Float,ADRESSE_PLUS_DEFINIE);
/* Liberation du vecteur contenant la fonction obtenue en ne conservant */
/* que les coefficients pairs de la fonction argument. */
/* Les 'ADRESSE_PLUS_DEFINIE's ci-dessus ont ete introduits le 20050221170159... */
Eblock
ETes
Eblock
ETes
RETU_ERROR;
Eblock
EFonctionI
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D O N N E E S D ' O P T I M I S A T I O N D U C A L C U L D E L A */
/* T R A N S F O R M E E D E F O U R I E R M O N O - D I M E N S I O N N E L L E C O M P L E X E : */
/* */
/*************************************************************************************************************************************/
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */
DEFV(Common,DEFV(Logical,_____CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_01));
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */
DEFV(Common,DEFV(Logical,_____CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02));
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */
#define COSF(x) \
COSX(x)
#define SINF(x) \
SINX(x)
/* Choix de la facon de calculer les lignes trigonometriques... */
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02 /* Common,DEFV(Fonction,) : objets statiques. */
DEFV(Local,DEFV(Int,INIT(Ifourier_1D_complexe_____exponentielle_complexe_etat,NEGA(CHOI(PasX,PasY)))));
/* Cet indicateur (non logique...) permet de savoir si le vecteur complexe correspondant */
/* a l'exponentielle complexe a ete initialise, et en plus avec le bon pas (le pas initial, */
/* ainsi qu'on le voit est negatif). */
# ifdef GESTION_DES_IMAGES_STATIQUES_VERSION_01
DEFV(Local,DEFV(Statique,DEFV(vecteurJ,Ifourier_1D_complexe_____exponentielle_complexe)));
/* Ce vecteur contient l'exponentielle complexe, c'est-a-dire les valeurs de : */
/* */
/* u */
/* (2.i.p.---) */
/* e N pour u E [0,N-1]. */
/* */
/* on notera qu'il s'agit la de la fonction necessaire a la transformee "inverse", */
/* pour la transformee "directe", on se souviendra de la regle : */
/* */
/* cos(-x) = +cos(x), */
/* sin(-x) = -sin(x). */
/* */
# Aifdef GESTION_DES_IMAGES_STATIQUES_VERSION_01
# Eifdef GESTION_DES_IMAGES_STATIQUES_VERSION_01
# ifdef GESTION_DES_IMAGES_STATIQUES_VERSION_02 /* Common,DEFV(Fonction,) : objets statiques. */
/* voir le commentaire associe aux declarations 'static' lors de '$PASSE_7' de */
/* 'v $xcc/cpp$Z', ainsi que l'initialisation de la liste '$liste_utiles' qui y est faite... */
/* Le 20040521092450, le '#pragma' relatif a 'xcc__cpp_Z__liste_utiles' a ete introduit */
/* pour supprimer cette dependance... */
#pragma xcc__cpp_Z__liste_utiles $ximt/fourier$EXT Ifourier_1D_complexe_____exponentielle_complexe $xbmt/fourier
DEFV(Common,DEFV(Statique,DEFV(vecteurJ,Ifourier_1D_complexe_____exponentielle_complexe)));
/* Ce vecteur contient l'exponentielle complexe, c'est-a-dire les valeurs de : */
/* */
/* u */
/* (2.i.p.---) */
/* e N pour u E [0,N-1]. */
/* */
/* on notera qu'il s'agit la de la fonction necessaire a la transformee "inverse", */
/* pour la transformee "directe", on se souviendra de la regle : */
/* */
/* cos(-x) = +cos(x), */
/* sin(-x) = -sin(x). */
/* */
# Aifdef GESTION_DES_IMAGES_STATIQUES_VERSION_02 /* Common,DEFV(Fonction,) : objets statiques. */
# Eifdef GESTION_DES_IMAGES_STATIQUES_VERSION_02 /* Common,DEFV(Fonction,) : objets statiques. */
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02 /* Common,DEFV(Fonction,) : objets statiques. */
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02 /* Common,DEFV(Fonction,) : objets statiques. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* T R A N S F O R M E E D E F O U R I E R M O N O - D I M E N S I O N N E L L E C O M P L E X E : */
/* */
/*************************************************************************************************************************************/
BFonctionI
DEFV(Local,DEFV(FonctionI,Ifourier_1D_complexe(transformee_de_la_fonction
,nombre_de_points_de_la_transformee
,fonction
,nombre_de_points_de_la_fonction
,nombre_de_points_a_la_fin_de_la_recursivite
,calcul_de_la_transformee_directe
)
)
)
DEFV(Argument,DEFV(complexe,DTb0(transformee_de_la_fonction)));
/* Vecteur contenant la transformee de Fourier de la fonction argument. */
DEFV(Argument,DEFV(Positive,nombre_de_points_de_la_transformee));
/* Dimension du vecteur contenant la transformee de la fonction. */
DEFV(Argument,DEFV(complexe,DTb0(fonction)));
/* Vecteur contenant la fonction discrete argument. */
DEFV(Argument,DEFV(Positive,nombre_de_points_de_la_fonction));
/* Dimension du vecteur contenant la fonction a transformer. */
DEFV(Argument,DEFV(Positive,nombre_de_points_a_la_fin_de_la_recursivite));
/* Dimension limite correspondant a la fin de la recursivite (en general */
/* vaudra 'UNITE'). */
DEFV(Argument,DEFV(Logical,calcul_de_la_transformee_directe));
/* Cet indicateur precise si l'on calcule la transformee directe ('VRAI'), */
/* ou inverse ('FAUX'). */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
INIT_ERROR;
/* ATTENTION : 'INIT_ERROR' est mis en tete des variables locales au cas ou des couples */
/* ('BDEFV','EDEFV') suivraient... */
DEFV(Int,INIT(frequence_spatiale,UNDEF));
/* Definition de la frequence spatiale 'u' courante. */
/*..............................................................................................................................*/
Test(IFLT(nombre_de_points_de_la_fonction,nombre_de_points_a_la_fin_de_la_recursivite))
Bblock
PRINT_ERREUR("la definition de la fonction est mauvaise");
/* Ou bien, le nombre de points initial est negatif ou nul, ou bien, la */
/* fin de la recursivite n'est pas une puissance de 2... */
CODE_ERROR(ERREUR15);
Eblock
ATes
Bblock
Test(IFEQ(nombre_de_points_de_la_fonction,nombre_de_points_a_la_fin_de_la_recursivite))
Bblock
DoIn(frequence_spatiale
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,nombre_de_points_de_la_transformee)
,PAS_DES_ITERATIONS_DE_FOURIER
)
Bblock
Cegal(ITb0(transformee_de_la_fonction,INDX(frequence_spatiale,PREMIER_ELEMENT_DE_LA_TRANSFORMEE))
,ITb0(fonction,INDX(PREMIER_ELEMENT_DE_LA_FONCTION,PREMIER_ELEMENT_DE_LA_FONCTION))
);
/* Cas de la fin de la recursivite : ainsi que l'on peut le voir sur les */
/* formules, en faisant n=0, l'exponentielle complexe vaut 1, et il ne */
/* reste que la fonction... */
Eblock
EDoI
Eblock
ATes
Bblock
/* Cas, ou la recursivite doit se poursuivre... */
DEFV(Int,INIT(coordonnee_spatiale,UNDEF));
/* Index permettant de calculer les fonctions "paire" et "impaire". */
DEFV(complexe,DdTb1(POINTERs
,fonction_paire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,tMalo(MUL2(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,size_complexe)
,complexe
)
)
);
/* Allocation du vecteur contenant la fonction obtenue en ne conservant que les */
/* coefficients pairs de la fonction argument. */
DEFV(complexe,DdTb1(POINTERs
,transformee_de_la_fonction_paire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,tMalo(MUL2(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE,size_complexe)
,complexe
)
)
);
/* Allocation du vecteur contenant la transformee de Fourier de la fonction */
/* obtenue en ne conservant que les coefficients de rang pair de la fonction */
/* argument. */
DEFV(complexe,DdTb1(POINTERs
,fonction_impaire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,tMalo(MUL2(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,size_complexe)
,complexe
)
)
);
/* Allocation du vecteur contenant la fonction obtenue en ne conservant que les */
/* coefficients de rang impair de la fonction argument. */
DEFV(complexe,DdTb1(POINTERs
,transformee_de_la_fonction_impaire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,tMalo(MUL2(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE,size_complexe)
,complexe
)
)
);
/* Allocation du vecteur contenant la transformee de Fourier de la fonction */
/* obtenue en ne conservant que les coefficients impairs de la fonction */
/* argument. */
DEFV(complexe,facteur_de_rotation);
/* Nombre complexe destine a donner : */
/* */
/* u */
/* -(2.i.p.---) */
/* e N */
/* */
/* pour la "directe", et : */
/* */
/* u */
/* 2.i.p.--- */
/* e N */
/* */
/* pour l'"inverse". */
DEFV(complexe,nombre_complexe_de_manoeuvre);
/* Nombre complexe de manoeuvre destine a memoriser le produit : */
/* */
/* u */
/* -(2.i.p.---) */
/* e N .T (f.impaire,u) */
/* N */
/* --- */
/* 2 */
/* */
/* pour la "directe", et : */
/* */
/* u */
/* 2.i.p.--- */
/* e N .T (f.impaire,u) */
/* N */
/* --- */
/* 2 */
/* */
/* pour l'"inverse". */
DEFV(Float,INIT(argument,FLOT__UNDEF));
/* Afin de calculer (au signe pres) l'argument de la fonction de */
/* transformation definissant la transformee a calculer (voir l'argument */
/* 'transformation' ci-dessus). */
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
DEFV(Int,INIT(argument_accelere,UNDEF));
/* Afin de calculer un index d'acces a l'exponentielle complexe ; il vaut : */
/* */
/* MdimXY */
/* frequence_spatiale.--------------------------------- */
/* nombre_de_points_de_la_fonction */
/* */
/* c'est-a-dire la frequence spatiale ramenee dans [0,N-1]. */
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFNE(DOUB(MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION),nombre_de_points_de_la_fonction))
Bblock
PRINT_ERREUR("la dimension n'est pas une puissance de 2");
Eblock
ATes
Bblock
Eblock
ETes
DoIn(coordonnee_spatiale
,PREMIER_ELEMENT_DE_LA_FONCTION
,LSTX(PREMIER_ELEMENT_DE_LA_FONCTION,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION)
,PAS_DES_ITERATIONS_DE_FOURIER
)
Bblock
Cegal(IdTb1(fonction_paire
,INDX(coordonnee_spatiale,PREMIER_ELEMENT_DE_LA_FONCTION)
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
)
,ITb0(fonction,INDX(NEUT(ADD2(DOUB(SOUS(coordonnee_spatiale,PREMIER_ELEMENT_DE_LA_FONCTION))
,PREMIER_ELEMENT_DE_LA_FONCTION
)
)
,PREMIER_ELEMENT_DE_LA_FONCTION
)
)
);
/* "Calcul" de la fonction ne contenant que les coefficients pairs de la */
/* fonction argument. */
Cegal(IdTb1(fonction_impaire
,INDX(coordonnee_spatiale,PREMIER_ELEMENT_DE_LA_FONCTION)
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
)
,ITb0(fonction
,INDX(ADD2(ADD2(DOUB(SOUS(coordonnee_spatiale,PREMIER_ELEMENT_DE_LA_FONCTION))
,PREMIER_ELEMENT_DE_LA_FONCTION
)
,PAS_DES_ITERATIONS_DE_FOURIER
)
,PREMIER_ELEMENT_DE_LA_FONCTION
)
)
);
/* "Calcul" de la fonction ne contenant que les coefficients impairs de la */
/* fonction argument. */
Eblock
EDoI
CALS(Ifourier_1D_complexe(transformee_de_la_fonction_paire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
,fonction_paire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,nombre_de_points_a_la_fin_de_la_recursivite
,calcul_de_la_transformee_directe
)
);
/* Calcul de la transformee de Fourier relative aux coefficients pairs */
/* de la fonction argument. */
CALS(Ifourier_1D_complexe(transformee_de_la_fonction_impaire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
,fonction_impaire
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
,nombre_de_points_a_la_fin_de_la_recursivite
,calcul_de_la_transformee_directe
)
);
/* Calcul de la transformee de Fourier relative aux coefficients impairs */
/* de la fonction argument. */
DoIn(frequence_spatiale
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,nombre_de_points_de_la_transformee)
,PAS_DES_ITERATIONS_DE_FOURIER
)
Bblock
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_01
EGAL(argument
,SCAL(CERCLE_TRIGONOMETRIQUE
,nombre_de_points_de_la_fonction
,frequence_spatiale
)
);
/* Argument de la fonction de transformation (au signe pres...). */
EGAL(argument
,COND(IL_FAUT(calcul_de_la_transformee_directe)
,NEGA(argument)
,argument
)
);
/* Argument de la fonction de transformation apres prise en compte du sens de */
/* la transformation ("directe" ou "inverse"). */
Cinitialisation(facteur_de_rotation
,COSF(argument)
,SINF(argument)
);
/* Calcul du facteur de rotation : */
/* */
/* u */
/* -(2.i.p.---) */
/* e N */
/* */
/* pour la "directe", et : */
/* */
/* u */
/* 2.i.p.--- */
/* e N */
/* */
/* pour l'"inverse". */
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_01
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_01
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFNE(Ifourier_1D_complexe_____exponentielle_complexe_etat,PAS_DES_ITERATIONS_DE_FOURIER))
Bblock
/* Lorsque l'exponentielle complexe n'est pas (ou pas encore) initialisee, on le fait : */
DEFV(Int,INIT(frequence_spatiale_d_initialisation,UNDEF));
/* Definition de la frequence spatiale d'initialisation du vecteur exponentielle complexe. */
DoIn(frequence_spatiale_d_initialisation
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,MdimXY)
,PAS_DES_ITERATIONS_DE_FOURIER
)
Bblock
EGAL(argument
,SCAL(CERCLE_TRIGONOMETRIQUE
,MdimXY
,frequence_spatiale_d_initialisation
)
);
/* Argument de la fonction de transformation "inverse". */
Cinitialisation(VECTEUR(Ifourier_1D_complexe_____exponentielle_complexe
,frequence_spatiale_d_initialisation,frequence_spatiale_d_initialisation
)
,COSF(argument)
,SINF(argument)
);
/* Calcul de l'exponentielle complexe : */
/* */
/* u */
/* 2.i.p.--- */
/* e N */
/* */
/* correspondant a la transformee "inverse"... */
Eblock
EDoI
EGAL(Ifourier_1D_complexe_____exponentielle_complexe_etat,PAS_DES_ITERATIONS_DE_FOURIER);
/* Cet indicateur (non logique...) permet de savoir si le vecteur complexe correspondant */
/* a l'exponentielle complexe a ete initialise, et en plus avec le bon pas (le pas initial, */
/* ainsi qu'on le voit est negatif). */
Eblock
ATes
Bblock
Eblock
ETes
EGAL(argument_accelere
,ADD2(INTE(SCAL(SOUS(frequence_spatiale,PREMIER_ELEMENT_DE_LA_TRANSFORMEE)
,nombre_de_points_de_la_fonction
,MdimXY
)
)
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
)
);
/* Afin de calculer un index d'acces a l'exponentielle complexe ; il vaut : */
/* */
/* MdimXY */
/* frequence_spatiale.--------------------------------- */
/* nombre_de_points_de_la_fonction */
/* */
/* c'est-a-dire la frequence spatiale ramenee dans [0,N-1]. */
Cinitialisation(facteur_de_rotation
,Reelle(VECTEUR(Ifourier_1D_complexe_____exponentielle_complexe
,argument_accelere
,argument_accelere
)
)
,COND(IL_FAUT(calcul_de_la_transformee_directe)
,NEGA(Imaginaire(VECTEUR(Ifourier_1D_complexe_____exponentielle_complexe
,argument_accelere
,argument_accelere
)
)
)
,Imaginaire(VECTEUR(Ifourier_1D_complexe_____exponentielle_complexe
,argument_accelere
,argument_accelere
)
)
)
);
/* Calcul du facteur de rotation : */
/* */
/* u */
/* -(2.i.p.---) */
/* e N */
/* */
/* pour la "directe", et : */
/* */
/* u */
/* 2.i.p.--- */
/* e N */
/* u */
/* */
/* pour l'"inverse". */
/* */
/* Ce vecteur contient l'exponentielle complexe, c'est-a-dire les valeurs de : */
/* */
/* u */
/* (2.i.p.---) */
/* e N */
/* */
/* pour u E [0,N-1]. */
/* */
/* On notera qu'il s'agit la de la fonction necessaire a la transformee "inverse", */
/* pour la transformee "directe", on se souviendra de la regle : */
/* */
/* cos(-x) = +cos(x), */
/* sin(-x) = -sin(x). */
/* */
/* le cosinus etant donne par la partie Reelle et le sinus par la partie Imaginaire. */
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Cproduit(nombre_complexe_de_manoeuvre
,facteur_de_rotation
,IdTb1(transformee_de_la_fonction_impaire
,INDX(MODU(frequence_spatiale
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
)
)
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
)
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
)
);
/* Calcul du produit : */
/* */
/* u */
/* -(2.i.p.---) */
/* e N .T (f.impaire,u) */
/* N */
/* --- */
/* 2 */
/* */
/* pour la "directe", et : */
/* */
/* u */
/* 2.i.p.--- */
/* e N .T (f.impaire,u) */
/* N */
/* --- */
/* 2 */
/* */
/* pour l'"inverse". */
Csomme(ITb0(transformee_de_la_fonction,INDX(frequence_spatiale,PREMIER_ELEMENT_DE_LA_TRANSFORMEE))
,IdTb1(transformee_de_la_fonction_paire
,INDX(MODU(frequence_spatiale
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,LSTX(PREMIER_ELEMENT_DE_LA_TRANSFORMEE
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
)
)
,PREMIER_ELEMENT_DE_LA_TRANSFORMEE
)
,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
)
,nombre_complexe_de_manoeuvre
);
/* Calcul de la transformee de Fourier de la fonction argument en recombinant */
/* les transformees dites "paires" et "impaires" : */
/* */
/* u */
/* -(2.i.p.---) */
/* T (f,u) = T (f.paire,u) + e N .T (f.impaire,u) */
/* N N N */
/* --- --- */
/* 2 2 */
/* */
/* pour la "directe", et : */
/* */
/* u */
/* 2.i.p.--- */
/* T (f,u) = T (f.paire,u) + e N .T (f.impaire,u) */
/* N N N */
/* --- --- */
/* 2 2 */
/* */
/* pour l'"inverse". */
Eblock
EDoI
/* Les 'ADRESSE_PLUS_DEFINIE's ci-dessous ont ete introduits le 20050221170159... */
FdTb1(transformee_de_la_fonction_impaire,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,complexe,ADRESSE_PLUS_DEFINIE);
/* Liberation du vecteur contenant la transformee de Fourier de la fonction */
/* obtenue en ne conservant que les coefficients impairs de la fonction */
/* argument. */
FdTb1(fonction_impaire,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,complexe,ADRESSE_PLUS_DEFINIE);
/* Liberation du vecteur contenant la fonction obtenue en ne conservant */
/* que les coefficients de rang impair de la fonction argument. */
FdTb1(transformee_de_la_fonction_paire,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,complexe,ADRESSE_PLUS_DEFINIE);
/* Liberation du vecteur contenant la transformee de Fourier de la fonction */
/* obtenue en ne conservant que les coefficients de rang pair de la fonction */
/* argument. */
FdTb1(fonction_paire,MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION,complexe,ADRESSE_PLUS_DEFINIE);
/* Liberation du vecteur contenant la fonction obtenue en ne conservant */
/* que les coefficients pairs de la fonction argument. */
/* Les 'ADRESSE_PLUS_DEFINIE's ci-dessus ont ete introduits le 20050221170159... */
Eblock
ETes
Eblock
ETes
RETU_ERROR;
Eblock
EFonctionI
#undef SINF
#undef COSF
#undef PAS_DES_ITERATIONS_DE_FOURIER
#undef MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_TRANSFORMEE
#undef MOITIE_DU_NOMBRE_DE_POINTS_DE_LA_FONCTION
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* T R A N S F O R M E E D E F O U R I E R B I - D I M E N S I O N N E L L E R E E L L E : */
/* */
/*************************************************************************************************************************************/
BFonctionP
DEFV(Common,DEFV(FonctionP,POINTERp(Ifourier_2D_reelle(transformee_de_l_image
,imageA
,ARGUMENT_FONCTION(transformation)
,calcul_de_la_transformee_directe
)
)
)
)
DEFV(Argument,DEFV(image,transformee_de_l_image));
/* Image transformee de Fourier de l'image Argument. */
DEFV(Argument,DEFV(image,imageA));
/* Image Argument. */
DEFV(Argument,DEFV(Float,afPOINTEUR(transformation)));
/* Definition de la fonction de transformation (en general un 'cosinus', */
/* ou un 'sinus'). */
DEFV(Argument,DEFV(Logical,calcul_de_la_transformee_directe));
/* Cet indicateur precise si l'on calcule la transformee directe ('VRAI'), */
/* ou inverse ('FAUX'). */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
BDEFV(imageF,transformee_flottante_de_l_image);
/* Matrice contenant la transformee flottante de l'image Argument. */
BDEFV(ligneF,ligne_courante);
/* Ligne courante, */
BDEFV(ligneF,transformee_de_la_ligne_courante);
/* Et sa transformee de Fourier mono-dimensionnelle. */
BDEFV(colonneF,colonne_courante);
/* Colonne courante, */
BDEFV(colonneF,transformee_de_la_colonne_courante);
/* Et sa transformee de Fourier mono-dimensionnelle. */
/*..............................................................................................................................*/
Test(IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,PAR0(PREMIER_ELEMENT_DE_LA_FONCTION)))
Bblock
PRINT_ERREUR("le premier element d'un vecteur doit avoir un rang pair");
Eblock
ATes
Bblock
Eblock
ETes
Test(IFOU(IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,Xmin)
,IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,Ymin)
)
)
Bblock
PRINT_ERREUR("les definitions sont incompatibles avec la methode");
Eblock
ATes
Bblock
Eblock
ETes
Test(IFOU(IZNE(REST(dimX,pasX))
,IZNE(REST(dimY,pasY))
)
)
Bblock
PRINT_ERREUR("les pas 'pasX' et 'pasY' doivent etre aussi des puissances de 2");
/* En fait, la verification que 'dimX' et 'dimY' sont aussi des puissances */
/* de 2 n'est faite que lors de la dichotomie recursive (pour des raisons */
/* de simplicite...). */
Eblock
ATes
Bblock
Eblock
ETes
begin_colonne
Bblock
/* On transforme d'abord horizontalement : */
/* */
/* Y ^ */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* -|--------------------> */
/* X */
/* */
/* (ligne apres ligne). */
begin_ligne
Bblock
EGAL(LIGNE(ligne_courante,X,Y)
,FLOT(load_point(imageA,X,Y))
);
/* Recuperation de la ligne courante dans 'imageA' (c'est-a-dire */
/* l'image Argument), */
Eblock
end_ligne
CALS(Ifourier_1D_reelle(transformee_de_la_ligne_courante
,dimX
,ligne_courante
,dimX
,TRMU(TRPU(pasX))
,aFONCTION(transformation)
,calcul_de_la_transformee_directe
)
);
/* Et transformation de Fourier mono-dimensionnelle de la ligne courante... */
begin_ligne
Bblock
storeF_point(LIGNE(transformee_de_la_ligne_courante,X,Y)
,transformee_flottante_de_l_image
,X,Y
);
/* Generation de la transformee de Fourier bi-dimensionelle, ligne */
/* apres ligne... */
Eblock
end_ligne
Eblock
end_colonne
begin_ligne
Bblock
/* Puis, on transforme verticalement : */
/* */
/* Y ^ */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* -|--------------------> */
/* X */
/* */
/* (colonne apres colonne). */
begin_colonne
Bblock
EGAL(COLONNE(colonne_courante,X,Y)
,loadF_point(transformee_flottante_de_l_image,X,Y)
);
/* Recuperation de la colonne courante dans 'transformee_flottante_de_l_image' */
/* (c'est-a-dire la transformee de Fourier "horizontale" de 'imageA'), */
Eblock
end_colonne
CALS(Ifourier_1D_reelle(transformee_de_la_colonne_courante
,dimY
,colonne_courante
,dimY
,TRMU(TRPU(pasY))
,aFONCTION(transformation)
,calcul_de_la_transformee_directe
)
);
/* Et transformation de Fourier mono-dimensionnelle de la colonne courante... */
begin_colonne
Bblock
storeF_point(COLONNE(transformee_de_la_colonne_courante,X,Y)
,transformee_flottante_de_l_image
,X,Y
);
/* Generation de la transformee de Fourier bi-dimensionelle, colonne */
/* apres colonne... */
Eblock
end_colonne
Eblock
end_ligne
CALS(Ifloat_std_avec_renormalisation(transformee_de_l_image,transformee_flottante_de_l_image));
/* On renvoie une image "standard"... */
EDEFV(colonneF,transformee_de_la_colonne_courante);
/* Transformee de Fourier mono-dimensionnelle de la colonne courante, */
EDEFV(colonneF,colonne_courante);
/* Colonne courante. */
EDEFV(ligneF,transformee_de_la_ligne_courante);
/* Transformee de Fourier mono-dimensionnelle de la ligne courante, */
EDEFV(ligneF,ligne_courante);
/* Ligne courante. */
EDEFV(imageF,transformee_flottante_de_l_image);
/* Matrice contenant la transformee flottante de l'image Argument. */
RETI(transformee_de_l_image);
Eblock
EFonctionP
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* T R A N S F O R M E E D I R E C T E D E F O U R I E R */
/* B I - D I M E N S I O N N E L L E C O M P L E X E : */
/* */
/*************************************************************************************************************************************/
BFonctionJ
#define TRANSFORMEE_DIRECTE \
VRAI \
/* Afin de positionner la variable 'calcul_de_la_transformee_directe'. */
DEFV(Common,DEFV(FonctionJ,POINTERJ(IJfourier_2D_directe_complexe(transformee_complexe_directe_de_l_imageA
,imageA
)
)
)
)
DEFV(Argument,DEFV(imageJ,transformee_complexe_directe_de_l_imageA));
/* Image complexe transformee de Fourier de l'image Argument. */
DEFV(Argument,DEFV(imageJ,imageA));
/* Image Argument complexe. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
BDEFV(ligneJ,ligne_courante);
/* Ligne courante, */
BDEFV(ligneJ,transformee_de_la_ligne_courante);
/* Et sa transformee de Fourier mono-dimensionnelle. */
BDEFV(colonneJ,colonne_courante);
/* Colonne courante, */
BDEFV(colonneJ,transformee_de_la_colonne_courante);
/* Et sa transformee de Fourier mono-dimensionnelle. */
/*..............................................................................................................................*/
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFOU(IFNE(dimX,dimY)
,IFNE(pasX,pasY)
)
)
Bblock
PRINT_ERREUR("l'image doit etre carree (dimX=dimY et pasX=pasY)");
Eblock
ATes
Bblock
Eblock
ETes
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,PAR0(PREMIER_ELEMENT_DE_LA_FONCTION)))
Bblock
PRINT_ERREUR("le premier element d'un vecteur doit avoir un rang pair");
Eblock
ATes
Bblock
Eblock
ETes
Test(IFOU(IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,Xmin)
,IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,Ymin)
)
)
Bblock
PRINT_ERREUR("les definitions sont incompatibles avec la methode");
Eblock
ATes
Bblock
Eblock
ETes
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFOU(IFNE(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,Xmin)
,IFNE(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,Ymin)
)
)
Bblock
PRINT_ERREUR("les definitions sont incompatibles avec la methode");
Eblock
ATes
Bblock
Eblock
ETes
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFOU(IZNE(REST(dimX,pasX))
,IZNE(REST(dimY,pasY))
)
)
Bblock
PRINT_ERREUR("les pas 'pasX' et 'pasY' doivent etre aussi des puissances de 2");
/* En fait, la verification que 'dimX' et 'dimY' sont aussi des puissances */
/* de 2 n'est faite que lors de la dichotomie recursive (pour des raisons */
/* de simplicite...). */
Eblock
ATes
Bblock
Eblock
ETes
begin_colonne
Bblock
/* On transforme d'abord horizontalement : */
/* */
/* Y ^ */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* -|--------------------> */
/* X */
/* */
/* (ligne apres ligne). */
begin_ligne
Bblock
Cegal(LIGNE(ligne_courante,X,Y)
,loadJ_point(imageA,X,Y)
);
/* Recuperation de la ligne courante dans 'imageA' (c'est-a-dire */
/* l'image Argument), */
Eblock
end_ligne
CALS(Ifourier_1D_complexe(transformee_de_la_ligne_courante
,dimX
,ligne_courante
,dimX
,TRMU(TRPU(pasX))
,TRANSFORMEE_DIRECTE
)
);
/* Et transformation de Fourier mono-dimensionnelle de la ligne courante... */
begin_ligne
Bblock
storeJ_point(LIGNE(transformee_de_la_ligne_courante,X,Y)
,transformee_complexe_directe_de_l_imageA
,X,Y
);
/* Generation de la transformee de Fourier bi-dimensionelle, ligne */
/* apres ligne... */
Eblock
end_ligne
Eblock
end_colonne
begin_ligne
Bblock
/* Puis, on transforme verticalement : */
/* */
/* Y ^ */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* -|--------------------> */
/* X */
/* */
/* (colonne apres colonne). */
begin_colonne
Bblock
Cegal(COLONNE(colonne_courante,X,Y)
,loadJ_point(transformee_complexe_directe_de_l_imageA,X,Y)
);
/* Recuperation de la colonne courante dans 'transformee_complexe_directe_de_l_imageA' */
/* (c'est-a-dire la transformee de Fourier "horizontale" de 'imageA'), */
Eblock
end_colonne
CALS(Ifourier_1D_complexe(transformee_de_la_colonne_courante
,dimY
,colonne_courante
,dimY
,TRMU(TRPU(pasY))
,TRANSFORMEE_DIRECTE
)
);
/* Et transformation de Fourier mono-dimensionnelle de la colonne courante... */
begin_colonne
Bblock
storeJ_point(COLONNE(transformee_de_la_colonne_courante,X,Y)
,transformee_complexe_directe_de_l_imageA
,X,Y
);
/* Generation de la transformee de Fourier bi-dimensionelle, colonne */
/* apres colonne... */
Eblock
end_colonne
Eblock
end_ligne
EDEFV(colonneJ,transformee_de_la_colonne_courante);
/* Transformee de Fourier mono-dimensionnelle de la colonne courante, */
EDEFV(colonneJ,colonne_courante);
/* Colonne courante. */
EDEFV(ligneJ,transformee_de_la_ligne_courante);
/* Transformee de Fourier mono-dimensionnelle de la ligne courante, */
EDEFV(ligneJ,ligne_courante);
/* Ligne courante. */
RETIJ(transformee_complexe_directe_de_l_imageA);
Eblock
#undef TRANSFORMEE_DIRECTE
EFonctionJ
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* T R A N S F O R M E E I N V E R S E D E F O U R I E R */
/* B I - D I M E N S I O N N E L L E C O M P L E X E : */
/* */
/*************************************************************************************************************************************/
BFonctionJ
#define TRANSFORMEE_INVERSE \
FAUX \
/* Afin de positionner la variable 'calcul_de_la_transformee_directe'. */
DEFV(Common,DEFV(FonctionJ,POINTERJ(IJfourier_2D_inverse_complexe(transformee_complexe_inverse
,transformee_complexe_directe
)
)
)
)
DEFV(Argument,DEFV(imageJ,transformee_complexe_inverse));
/* Image Resultat contenant la transformee complexe inverse de l'image Argument. */
DEFV(Argument,DEFV(imageJ,transformee_complexe_directe));
/* Transformee de Fourier que l'on cherche a inverser pour connaitre */
/* l'image Resultat. */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
BDEFV(imageF,partie_reelle);
/* Matrice contenant la partie reelle de la transformee complexe inverse */
/* de l'image Argument. */
BDEFV(imageF,partie_imaginaire);
/* Matrice contenant la partie imaginaire de la transformee complexe inverse */
/* de l'image Argument. */
BDEFV(ligneJ,ligne_courante);
/* Ligne courante, */
BDEFV(ligneJ,transformee_de_la_ligne_courante);
/* Et sa transformee de Fourier mono-dimensionnelle. */
BDEFV(colonneJ,colonne_courante);
/* Colonne courante, */
BDEFV(colonneJ,transformee_de_la_colonne_courante);
/* Et sa transformee de Fourier mono-dimensionnelle. */
/*..............................................................................................................................*/
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFOU(IFNE(dimX,dimY)
,IFNE(pasX,pasY)
)
)
Bblock
PRINT_ERREUR("l'image doit etre carree (dimX=dimY et pasX=pasY)");
Eblock
ATes
Bblock
Eblock
ETes
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,PAR0(PREMIER_ELEMENT_DE_LA_FONCTION)))
Bblock
PRINT_ERREUR("le premier element d'un vecteur doit avoir un rang pair");
Eblock
ATes
Bblock
Eblock
ETes
Test(IFOU(IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,Xmin)
,IFNE(PREMIER_ELEMENT_DE_LA_FONCTION,Ymin)
)
)
Bblock
PRINT_ERREUR("les definitions sont incompatibles avec la methode");
Eblock
ATes
Bblock
Eblock
ETes
#ifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFOU(IFNE(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,Xmin)
,IFNE(PREMIER_ELEMENT_DE_LA_TRANSFORMEE,Ymin)
)
)
Bblock
PRINT_ERREUR("les definitions sont incompatibles avec la methode");
Eblock
ATes
Bblock
Eblock
ETes
#Aifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
#Eifdef CALCUL_DE_L_EXPONENTIELLE_COMPLEXE_VERSION_02
Test(IFOU(IZNE(REST(dimX,pasX))
,IZNE(REST(dimY,pasY))
)
)
Bblock
PRINT_ERREUR("les pas 'pasX' et 'pasY' doivent etre aussi des puissances de 2");
/* En fait, la verification que 'dimX' et 'dimY' sont aussi des puissances */
/* de 2 n'est faite que lors de la dichotomie recursive (pour des raisons */
/* de simplicite...). */
Eblock
ATes
Bblock
Eblock
ETes
begin_colonne
Bblock
/* On transforme d'abord horizontalement : */
/* */
/* Y ^ */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* | ---------------- */
/* -|--------------------> */
/* X */
/* */
/* (ligne apres ligne). */
begin_ligne
Bblock
Cegal(LIGNE(ligne_courante,X,Y)
,loadJ_point(transformee_complexe_directe,X,Y)
);
/* Recuperation de la ligne courante dans la transformee de Fourier de */
/* l'image Resultat. */
Eblock
end_ligne
CALS(Ifourier_1D_complexe(transformee_de_la_ligne_courante
,dimX
,ligne_courante
,dimX
,TRMU(TRPU(pasX))
,TRANSFORMEE_INVERSE
)
);
/* Et transformation de Fourier mono-dimensionnelle inverse de */
/* la ligne courante... */
begin_ligne
Bblock
storeJ_point(LIGNE(transformee_de_la_ligne_courante,X,Y)
,transformee_complexe_inverse
,X,Y
);
/* Generation de la transformee de Fourier inverse bi-dimensionelle inverse, ligne */
/* apres ligne... */
Eblock
end_ligne
Eblock
end_colonne
begin_ligne
Bblock
/* Puis, on transforme verticalement : */
/* */
/* Y ^ */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* | | | | | | | | | */
/* -|--------------------> */
/* X */
/* */
/* (colonne apres colonne). */
begin_colonne
Bblock
Cegal(COLONNE(colonne_courante,X,Y)
,loadJ_point(transformee_complexe_inverse,X,Y)
);
/* Recuperation de la colonne courante dans 'transformee_complexe_inverse' */
/* (c'est-a-dire la transformee de Fourier "horizontale" de 'transformee_complexe_inverse'), */
Eblock
end_colonne
CALS(Ifourier_1D_complexe(transformee_de_la_colonne_courante
,dimY
,colonne_courante
,dimY
,TRMU(TRPU(pasY))
,TRANSFORMEE_INVERSE
)
);
/* Et transformation de Fourier mono-dimensionnelle inverse de */
/* la colonne courante... */
begin_colonne
Bblock
storeJ_point(COLONNE(transformee_de_la_colonne_courante,X,Y)
,transformee_complexe_inverse
,X,Y
);
/* Generation de la transformee de Fourier bi-dimensionelle inverse, colonne */
/* apres colonne... */
Eblock
end_colonne
Eblock
end_ligne
CALS(Icomplexe_reelle(partie_reelle,transformee_complexe_inverse));
CALS(IFscale(partie_reelle
,INVE(FLOT(DIVI(dimXY,MUL2(pasX,pasY))))
,partie_reelle
,FZERO
)
);
CALS(Ireelle_complexe(transformee_complexe_inverse,partie_reelle));
/* Normalisation de la partie reele de la transformee inverse avec le facteur : */
/* avec prise en compte du facteur */
/* */
/* 1 */
/* ---- (avec : N=dimX=dimY) */
/* 2 */
/* N */
/* */
CALS(Icomplexe_imaginaire(partie_imaginaire,transformee_complexe_inverse));
CALS(IFscale(partie_imaginaire
,INVE(FLOT(DIVI(dimXY,MUL2(pasX,pasY))))
,partie_imaginaire
,FZERO
)
);
CALS(Iimaginaire_complexe(transformee_complexe_inverse,partie_imaginaire));
/* Puis normalisation de la partie imaginaire de la transformee inverse avec le facteur : */
/* */
/* 1 */
/* ---- (avec : N=dimX=dimY) */
/* 2 */
/* N */
/* */
EDEFV(colonneJ,transformee_de_la_colonne_courante);
/* Transformee de Fourier mono-dimensionnelle de la colonne courante, */
EDEFV(colonneJ,colonne_courante);
/* Colonne courante. */
EDEFV(ligneJ,transformee_de_la_ligne_courante);
/* Transformee de Fourier mono-dimensionnelle de la ligne courante, */
EDEFV(ligneJ,ligne_courante);
/* Ligne courante. */
EDEFV(imageF,partie_imaginaire);
/* Matrice contenant la partie imaginaire de la transformee complexe inverse */
/* de l'image Argument. */
EDEFV(imageF,partie_reelle);
/* Matrice contenant la partie reelle de la transformee complexe inverse */
/* de l'image Argument. */
RETIJ(transformee_complexe_inverse);
Eblock
#undef TRANSFORMEE_INVERSE
EFonctionJ
#undef PREMIER_ELEMENT_DE_LA_TRANSFORMEE
#undef PREMIER_ELEMENT_DE_LA_FONCTION
_______________________________________________________________________________________________________________________________________