_______________________________________________________________________________________________________________________________________ /*************************************************************************************************************************************/ /* */ /* 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 _______________________________________________________________________________________________________________________________________