/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N S   D E S   E V E N E M E N T S  :                                                                     */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xrq/nucleon.LB$I' :                                                                                            */
/*                                                                                                                                   */
/*                    Jean-Francois Colonna (LACTAMME, 1991??????????).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        C H O I X   E N T R E   P L U S I E U R S   E V E N E M E N T S   P O S S I B L E S  :                                     */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Definitions :                                                                                                              */
/*                                                                                                                                   */
/*                    Soient N evenements E(i) de probabilites respectives                                                           */
/*                  P(i), telles que :                                                                                               */
/*                                                                                                                                   */
/*                                      [0 <] P(1) < P(2) < ... < P(i) < ... < P(N-1) < P(N) [< 1]                                   */
/*                                                                                                                                   */
/*                  l'ordre '<' etant strict pour toute valeur de l'indice 'i',                                                      */
/*                  P(N) designant l'evenement le plus probable, et P(1), le                                                         */
/*                  moins probable, et les bornes [0,1] n'etant pas obligatoires...                                                  */
/*                                                                                                                                   */
/*                  La condition habituelle :                                                                                        */
/*                                                                                                                                   */
/*                                       i=N                                                                                         */
/*                                       ____                                                                                        */
/*                                      \                                                                                            */
/*                                       \    P(i) = 1                                                                               */
/*                                       /                                                                                           */
/*                                      /____                                                                                        */
/*                                                                                                                                   */
/*                                       i=1                                                                                         */
/*                                                                                                                                   */
/*                  n'etant pas necessairement remplie...                                                                            */
/*                                                                                                                                   */
/*                    Soit R le resultat d'un tirage aleatoire,                                                                      */
/*                  tel que :                                                                                                        */
/*                                                                                                                                   */
/*                                               i=N                                                                                 */
/*                                           _   ____     _                                                                          */
/*                                          |   \          |                                                                         */
/*                                      R E | 0, \    P(i) |                                                                         */
/*                                          |    /         |                                                                         */
/*                                          |_  /____     _|                                                                         */
/*                                                                                                                                   */
/*                                              i=1                                                                                  */
/*                                                                                                                                   */
/*                    On choisit l'evenement E(k) tel que :                                                                          */
/*                                                                                                                                   */
/*                                        i=N                  i=N                                                                   */
/*                                       ______                ____                                                                  */
/*                                      \                     \                                                                      */
/*                                       \      P(i)  < R <=   \    P(i)                                                             */
/*                                       /                     /                                                                     */
/*                                      /______               /____                                                                  */
/*                                                                                                                                   */
/*                                       i=k+1                 i=k                                                                   */
/*                                                                                                                                   */
/*                                         .                                                                                         */
/*                                        /|\                                                                                        */
/*                                         |                                                                                         */
/*                                         |                                                                                         */
/*                                                                                                                                   */
/*                        (cette expression valant 0 si k=N)                                                                         */
/*                                                                                                                                   */
/*                    Ceci correspond au processus suivant :                                                                         */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*                                      ....................O.                                                                       */
/*                                                          |  .                                                                     */
/*                                                          |    .                                                                   */
/*                                      E(N)    <==         |      .                                                                 */
/*                                                          | P(N)   .                                                               */
/*                                      ....................|--------- .                                                             */
/*                                                          |            .                                                           */
/*                                                          |              .                                                         */
/*                                      E(N-1)  <==         |                .                                                       */
/*                                                          | P(N) + P(N-1)    .                                                     */
/*                                      ....................|------------------- .                                                   */
/*                                       |                  |                      .                                                 */
/*                                       |                  |                        .                                               */
/*                                      \|/                 |                          .                                             */
/*                                       .                  |                            .                                           */
/*                                      ....................|                              .                                         */
/*                                                          |                                .                                       */
/*                                                          |                                  .                                     */
/*                                      E(1)    <==         |                                    .                                   */
/*                                                          | P(N) + P(N-1) + ... + P(2) + P(1)    .                                 */
/*                                      ....................|---------------------------------------                                 */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Utilisation (en commencant par E(N), l'evenement le plus probable) :                                                       */
/*                                                                                                                                   */
/*                  DEBUT_DU_CHOIX_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES(R);                                                          */
/*                  CHOIX_D_UN_EVENEMENT_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES(P(N),Sequence(N));                                     */
/*                  CHOIX_D_UN_EVENEMENT_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES(P(N-1),Sequence(N-1));                                 */
/*                  ...                                                                                                              */
/*                  ...                                                                                                              */
/*                  ...                                                                                                              */
/*                  CHOIX_D_UN_EVENEMENT_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES(P(2),Sequence(2));                                     */
/*                  CHOIX_D_UN_EVENEMENT_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES(P(1),Sequence(1));                                     */
/*                  FIN_DU_CHOIX_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES;                                                               */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   DEBUT_DU_CHOIX_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES(variable_aleatoire)                                                       \
                                        /* ATTENTION : on n'utilise pas ici le couple ('BblockV','EblockV') car en effet sur         */ \
                                        /* certains systemes, il est vide ; or ici, dans la mesure ou l'on redefinit des variables   */ \
                                        /* locales, il est absolument necessaire que ce couple soit equivalent au couple             */ \
                                        /* ('Bblock','Eblock')...                                                                    */ \
                    Bblock                                                                                                              \
                    DEFV(Logical,INIT(l_evenement_qui_va_avoir_lieu_a_ete_trouve,FAUX));                                                \
                                        /* Indicateur indiquant si l'evenement qui va avoir lieu a ete selectionne ('VRAI'), ou pas  */ \
                                        /* encore  ('FAUX').                                                                         */ \
                    DEFV(Float,INIT(seuil_de_declenchement,variable_aleatoire));                                                        \
                                        /* Valeur de la variable 'R' ci-dessus, a la quelle sera comparee le cumul suivant...        */ \
                    DEFV(Float,INIT(cumul_des_probabilites,FZERO));                                                                     \
                                        /*                                                                                           */ \
                                        /*                                                      i=N                                  */ \
                                        /*                                                      ____                                 */ \
                                        /*                                                     \                                     */ \
                                        /*                  variable contenant en permanence :  \    P(i), pour k=N,N-1,...,2,1.     */ \
                                        /*                                                      /                                    */ \
                                        /*                                                     /____                                 */ \
                                        /*                                                                                           */ \
                                        /*                                                      i=k                                  */ \
                                        /*                                                                                           */ \
                    DEFV(Logical,INIT(c_est_la_premiere_probabilite,VRAI));                                                             \
                                        /* Indicateur indiquant si c'est la premiere probabilite, c'est-a-dire 'P(N)', qui va etre   */ \
                                        /* etre presentee ('VRAI') ou pas, c'est-a-dire 'P(N-1),...,P(1)' ('FAUX').                  */ \
                    DEFV(Float,INIT(probabilite_precedente,FLOT__UNDEF));                                                               \
                                        /* Probabilite precedente (c'est-a-dire 'P(i+1)' si l'on en est a 'P(i)'...                  */ \
                    Test(IZLT(variable_aleatoire))                                                                                      \
                         Bblock                                                                                                         \
                         PRINT_ERREUR("la variable aleatoire ne peut etre negative");                                                   \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                                        /* Debut de la sequence de selection entre plusieurs evenements possibles, et de             */ \
                                        /* probabilites decroissantes...                                                             */
#define   CHOIX_D_UN_EVENEMENT_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES(probabilite,sequence)                                               \
                    Bblock                                                                                                              \
                    Test(EST_FAUX(l_evenement_qui_va_avoir_lieu_a_ete_trouve))                                                          \
                         Bblock                                                                                                         \
                                        /* On notera que la sequence de validation de l'ordre des probabilites (qui suit) etait      */ \
                                        /* fait autrefois systematiquement. Maintenant qu'a ete introduite 'LIMIT_VIRT(...)' dans    */ \
                                        /* '$xrq/di_elec.LJ$I', cette verification ne peut plus etre systematique, car, en effet,    */ \
                                        /* on trouve des sequences du type :                                                         */ \
                                        /*                                                                                           */ \
                                        /*                  CHOIX_D_UN_EVENEMENT_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES                */ \
                                        /*                      (REGUL1(LIMIT_VIRT(probabilite_de_ELECTROWEAK_EMISSION_E___ExP       */ \
                                        /*                                        ,electronD1                                        */ \
                                        /*                                         )                                                 */ \
                                        /*                              )                                                            */ \
                                        /*                      ,BLOC(...)                                                           */ \
                                        /*                       );                                                                  */ \
                                        /*                  CHOIX_D_UN_EVENEMENT_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES                */ \
                                        /*                      (REGUL1(LIMIT_VIRT(probabilite_de_ELECTROWEAK_EMISSION_E___ExZ       */ \
                                        /*                                        ,electronD1                                        */ \
                                        /*                                         )                                                 */ \
                                        /*                              )                                                            */ \
                                        /*                      ,BLOC(...)                                                           */ \
                                        /*                       );                                                                  */ \
                                        /*                                                                                           */ \
                                        /* or ainsi, entre deux 'CHOIX_D_UN_EVENEMENT_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES(...)'     */ \
                                        /* la nature de 'electronD1' peut changer, d'ou une situation ou l'ordre des probabilites    */ \
                                        /* n'est plus correct. Le test suivant n'est effectue dorenavant que si un evenement n'a     */ \
                                        /* pas ete active...                                                                         */ \
                                                                                                                                        \
                         Test(EST_FAUX(c_est_la_premiere_probabilite))                                                                  \
                              Bblock                                                                                                    \
                              Test(IFGT(probabilite,probabilite_precedente))                                                            \
                                        /* On notera qu'il y avait autrefois :                                                       */ \
                                        /*                                                                                           */ \
                                        /*                  Test(IFGE(probabilite,probabilite_precedente))                           */ \
                                        /*                                                                                           */ \
                                        /* afin de permettre l'interdiction de plusieurs evenements de meme type en annulant leurs   */ \
                                        /* probabilites d'occurence, il faut autoriser que deux probabilites puissent etre egales    */ \
                                        /* (en particulier a zero...).                                                               */ \
                                   Bblock                                                                                               \
                                   PRINT_ATTENTION("'probabilite' mal ordonnee, il faut P(1) >= ... >= P(i) >= ... >= P(N)");           \
                                   CAL1(Prer1("Probabilite precedente=%e\n",probabilite_precedente));                                   \
                                   CAL1(Prer1("Probabilite courante=%e\n",probabilite));                                                \
                                   Eblock                                                                                               \
                              ATes                                                                                                      \
                                   Bblock                                                                                               \
                                   Eblock                                                                                               \
                              ETes                                                                                                      \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              EGAL(c_est_la_premiere_probabilite,FAUX);                                                                 \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                                                                                                                                        \
                         EGAL(probabilite_precedente,probabilite);                                                                      \
                                        /* Gestion du dispositif de verification de l'ordre strictement decroissant entre les        */ \
                                        /* probabilites 'P(i)'. On notera que cette validation est faite meme si l'evenement         */ \
                                        /* que l'on cherche a deja ete selectionne...                                                */ \
                         Test(IFEXff(probabilite,EVENEMENT_IMPOSSIBLE,EVENEMENT_CERTAIN))                                               \
                              Bblock                                                                                                    \
                              PRINT_ATTENTION("'probabilite' est hors de [0,1], ce qui peut poser des problemes d'exponentiation");     \
                              CAL1(Prer1("Probabilite courante=%d\n",probabilite));                                                     \
                                        /* En effet, on a par exemple :                                                              */ \
                                        /*                                                                                           */ \
                                        /*                  PROBABILITE_DE_STRONG_CREATION_V___GxGxGxG =                             */ \
                                        /*                  = EXP2(PROBABILITE_DE_STRONG_CREATION_V___GxGxG)                         */ \
                                        /*                                                                                           */ \
                                        /* et donc si 'PROBABILITE_DE_STRONG_CREATION_V___GxGxG' est superieur a 1, son              */ \
                                        /* 'EXP2(...)' lui sera superieure, alors qu'elle devrait etre inferieure si elle etait      */ \
                                        /* dans [0,1], comme toute bonne probabilite qui se respecte...                              */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                                                                                                                                        \
                         INCR(cumul_des_probabilites,probabilite);                                                                      \
                                        /* Prise en compte de la probabilite de l'evenement courant. On notera que l'on n'utilise    */ \
                                        /* pas 'hPROBABILITE(probabilite)', mais 'probabilite' seule, car en effet, pour une         */ \
                                        /* particule donnee (qui a donc ete deja choisie comme "victime", et a donc deja subi        */ \
                                        /* l'effet de 'hPROBABILITE(...)'), on selectionne ici un evenement conditionnel parmi 'N',  */ \
                                        /* et donc l'effet de ralentissement de l'horloge ne joue pas, car cette action est          */ \
                                        /* instantanee...                                                                            */ \
                         Test(IFLE(seuil_de_declenchement,cumul_des_probabilites))                                                      \
                              Bblock                                                                                                    \
                              BLOC(sequence);                                                                                           \
                                        /* On execute les instructions relatives a l'evenement selectionne...                        */ \
                              EGAL(l_evenement_qui_va_avoir_lieu_a_ete_trouve,VRAI);                                                    \
                                        /* Ainsi, on bloque les evenements moins probables qui suivent...                            */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                                        /* Cas ou un evenement moins probable doit etre selectionne...                               */ \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                                        /* Cas ou un evenement plus probable a deja ete selectionne...                               */ \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Fin de la sequence de selection entre plusieurs evenements possibles, et de               */ \
                                        /* probabilite decroissante...                                                               */
#define   FIN_DU_CHOIX_ENTRE_PLUSIEURS_EVENEMENTS_POSSIBLES                                                                             \
                                        /* ATTENTION : on n'utilise pas ici le couple ('BblockV','EblockV') car en effet sur         */ \
                                        /* certains systemes, il est vide ; or ici, dans la mesure ou l'on redefinit des variables   */ \
                                        /* locales, il est absoluement necessaire que ce couple soit equivalent au couple            */ \
                                        /* ('Bblock','Eblock')...                                                                    */ \
                    Test(EST_FAUX(l_evenement_qui_va_avoir_lieu_a_ete_trouve))                                                          \
                         Bblock                                                                                                         \
                         PRINT_ERREUR("l'evenement qui devrait avoir pas lieu n'a pas ete selectionne");                                \
                                        /* Cas probable ou la variable 'R' n'a pas ete tiree au sort dans le bon segment...          */ \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                    Eblock                                                                                                              \
                                        /* Fin de la sequence de selection entre plusieurs evenements possibles, et de               */ \
                                        /* probabilite decroissante...                                                               */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N   D U   G E N E R A T E U R   D ' E V E N E M E N T S  :                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   GRAINE_DU_GENERATEUR_D_EVENEMENTS                                                                                             \
                    PARE(1789)                                                                                                          \
                                        /* Graine implicite et revolutionnaire du generateur aleatoire pour la production des        */ \
                                        /* evenements.                                                                               */
DEFV(Local,DEFV(Logical,INIT(etat_du_generateur_d_evenements,INVALIDE)));
                                        /* Etat du generateur aleatoire pour la production des evenements : 'INVALIDE' (non encore   */
                                        /* initialise) ou 'VALIDE' (initialise...).                                                  */
DEFV(Local,DEFV(Int,INIT(graine_du_generateur_d_evenements,GRAINE_DU_GENERATEUR_D_EVENEMENTS)));
                                        /* Graine du generateur aleatoire pour la production des evenements. On notera qu'etant      */
                                        /* donne que l'on change de point dans l'espace de parametrage apres chaque evenement,       */
                                        /* il devient inutile de changer aussi la graine...                                          */
DEFV(Local,DEFV(pointI_3D,point_courant_de_l_espace_de_parametrage));
                                        /* Point courant d'un espace abstrait servant a parametrer le generateur d'evenements.       */
SPIRALE_DEFINITION_GENERALE(SPIRALE_DELTA_HORIZONTAL_GLOBAL,SPIRALE_DELTA_VERTICAL_GLOBAL)
                                        /* Donnees de generation d'une spirale de parcours d'un espace abstrait bidimensionnel       */
                                        /* de parametrage de la generation des evenements.                                           */
#define   GENERATION_GENERALE_D_UNE_VALEUR(valeur_aleatoire,borne_inferieure,borne_superieure,graine_courante)                          \
                    Bblock                                                                                                              \
                    EGAL(valeur_aleatoire                                                                                               \
                        ,rdnI3D(ADRESSE(point_courant_de_l_espace_de_parametrage)                                                       \
                               ,graine_courante                                                                                         \
                               ,RDN_INIT_AND_GENERE                                                                                     \
                               ,FLOT(borne_inferieure),FLOT(borne_superieure)                                                           \
                                )                                                                                                       \
                         );                                                                                                             \
                                        /* Generation d'une valeur aleatoire dans [borne_inferieure,borne_superieure] et parametree  */ \
                                        /* par le point courant de l'espace de parametrage. On notera que les 'FLOT(...)' relatifs   */ \
                                        /* a 'borne_inferieure' et 'borne_superieure' sont essentiels car, en effet, on ne connait   */ \
                                        /* pas a priori leur type (aussi bien 'Float' que 'Int'...).                                 */ \
                    Eblock                                                                                                              \
                                        /* Generation "generale" d'une valeur aleatoire dans [borne_inferieure,borne_superieure].    */
#define   FORCAGE_DE_LA_REINITIALISATION_DU_GENERATEUR_D_EVENEMENTS                                                                     \
                    Bblock                                                                                                              \
                    EGAL(etat_du_generateur_d_evenements,INVALIDE);                                                                     \
                    Eblock                                                                                                              \
                                        /* Afin de forcer la (re-)initialisation du generateur d'evenements.                         */

#ifndef   MODE_TEST_OVERFLOW_ET_UNDERFLOW
#    define    PRENDRE_LE_PREMIER_NOMBRE_ALEATOIRE_GENERE                                                                               \
                         TOUJOURS_VRAI
#Aifndef  MODE_TEST_OVERFLOW_ET_UNDERFLOW
#    define    PRENDRE_LE_PREMIER_NOMBRE_ALEATOIRE_GENERE                                                                               \
                         TOUJOURS_FAUX
#Eifndef  MODE_TEST_OVERFLOW_ET_UNDERFLOW

#define   INITIALISATION_DE_L_ESPACE_DE_PARAMETRAGE                                                                                     \
                    Bblock                                                                                                              \
                    INITIALISATION_POINT_3D(point_courant_de_l_espace_de_parametrage,Xmin,Ymin,Zmin);                                   \
                    Eblock                                                                                                              \
                                        /* Initialisation de l'espace de parametrage independante du format de l'image, puisque le   */ \
                                        /* point 'min' n'en depend pas...                                                            */

#if       (         (! defined(__VERSION__FAUSSE_GENERATION_D_UN_NUCLEON))                                                              \
          &&        (         (defined(__VERSION__GENERATION_D_UN_NUCLEON))                                                             \
                    ||        (defined(__VERSION__GENERATION_D_UN_MESON))                                                               \
                    ||        (defined(__VERSION__GENERATION_DU_VIDE))                                                                  \
                     )                                                                                                                  \
           )
#    undef     INITIALISATION_DE_L_ESPACE_DE_PARAMETRAGE
#    define    INITIALISATION_DE_L_ESPACE_DE_PARAMETRAGE                                                                                \
                         Bblock                                                                                                         \
                         INITIALISATION_POINT_3D(point_courant_de_l_espace_de_parametrage,Xcentre,Ycentre,Zcentre);                     \
                         Eblock                                                                                                         \
                                        /* Initialisation de l'espace de parametrage compatible avec les versions anterieures, mais  */ \
                                        /* qui ne donne pas des nombres aleatoires independants du format de l'image, puisque le     */ \
                                        /* point 'centre' en depend lui-meme...                                                      */
#Aif      (         (! defined(__VERSION__FAUSSE_GENERATION_D_UN_NUCLEON))                                                              \
          &&        (         (defined(__VERSION__GENERATION_D_UN_NUCLEON))                                                             \
                    ||        (defined(__VERSION__GENERATION_D_UN_MESON))                                                               \
                    ||        (defined(__VERSION__GENERATION_DU_VIDE))                                                                  \
                     )                                                                                                                  \
           )
#Eif      (         (! defined(__VERSION__FAUSSE_GENERATION_D_UN_NUCLEON))                                                              \
          &&        (         (defined(__VERSION__GENERATION_D_UN_NUCLEON))                                                             \
                    ||        (defined(__VERSION__GENERATION_D_UN_MESON))                                                               \
                    ||        (defined(__VERSION__GENERATION_DU_VIDE))                                                                  \
                     )                                                                                                                  \
           )

#define   ___GENERATION_D_UNE_VALEUR(valeur_aleatoire,borne_inferieure,borne_superieure)                                                \
                    Bblock                                                                                                              \
                    DEFV(Logical,INIT(generer_une_nouvelle_valeur_aleatoire,VRAI));                                                     \
                                        /* Indicateur de controle de l'iteration de la generation d'une valeur aleatoire.            */ \
                    DEFV(Float,INIT(valeur_aleatoire_intermediaire,FLOT__UNDEF));                                                       \
                                        /* Valeur aleatoire intermediaire destinee a eviter de generer des nombres non nuls et trop  */ \
                                        /* petits en valeur absolue...                                                               */ \
                                                                                                                                        \
                    PUSH_ECHANTILLONNAGE;                                                                                               \
                    SET_ECHANTILLONNAGE(PasX,PasY);                                                                                     \
                                        /* Mise en place d'un echantillonnage permettant toutes les operations 'SPIRALE_...'.        */ \
                                                                                                                                        \
                    Test(EST_INVALIDE(etat_du_generateur_d_evenements))                                                                 \
                         Bblock                                                                                                         \
                         SPIRALE_REINITIALISATION_BRAS_ET_DELTAS;                                                                       \
                                        /* Ces operations, inutiles la premiere fois, sont la au cas ou l'on arriverait ici a la     */ \
                                        /* suite de 'FORCAGE_DE_LA_REINITIALISATION_DU_GENERATEUR_D_EVENEMENTS' ; il faut donc se    */ \
                                        /* replacer a l'etat initial des spirales...                                                 */ \
                         SPIRALE_VALIDATION;                                                                                            \
                                        /* Validation des pas de parcours (pasX,pasY) de l'espace abstrait de parametrage du         */ \
                                        /* generateur d'evenements.                                                                  */ \
                         INITIALISATION_DE_L_ESPACE_DE_PARAMETRAGE;                                                                     \
                                        /* Initialisation du point courant de l'espace abstrait servant a parametrer le generateur   */ \
                                        /* d'evenements. Ceci est fait aussi dans '$xrq/nucleon.LW.?$I'...                           */ \
                         EGAL(etat_du_generateur_d_evenements,VALIDE);                                                                  \
                                        /* Ainsi, on sait que le generateur d'evenements est operationnel...                         */ \
                         Eblock                                                                                                         \
                    ATes                                                                                                                \
                         Bblock                                                                                                         \
                         Eblock                                                                                                         \
                    ETes                                                                                                                \
                                                                                                                                        \
                    Tant(IL_FAUT(generer_une_nouvelle_valeur_aleatoire))                                                                \
                         Bblock                                                                                                         \
                         GENERATION_GENERALE_D_UNE_VALEUR(valeur_aleatoire_intermediaire                                                \
                                                         ,borne_inferieure,borne_superieure                                             \
                                                         ,graine_du_generateur_d_evenements                                             \
                                                          );                                                                            \
                                        /* Generation d'une valeur aleatoire dans [borne_inferieure,borne_superieure] et parametree  */ \
                                        /* par le point courant de l'espace de parametrage...                                        */ \
                         SPIRALE_INITIALISATION;                                                                                        \
                                        /* Initialisation dynamique de 'spirale_nombre_de_points_a_traiter'.                         */ \
                         SPIRALE_DEPLACEMENT(ASD1(point_courant_de_l_espace_de_parametrage,x)                                           \
                                            ,ASD1(point_courant_de_l_espace_de_parametrage,y)                                           \
                                             );                                                                                         \
                                        /* Deplacement du point courant de la spirale de l'espace de parametrage, et ce en restant   */ \
                                        /* dans un plan Z=constante (Zcentre)...                                                     */ \
                         SPIRALE_PARCOURS;                                                                                              \
                                        /* Parcours de la spirale avec rotation eventuelle de PI/2 du bras courant...                */ \
                                                                                                                                        \
                         Test(I3OU(IZEQ(valeur_aleatoire_intermediaire)                                                                 \
                                  ,IFGT(ABSO(valeur_aleatoire_intermediaire)                                                            \
                                       ,MUL2(pEPSILON,SOUS(borne_superieure,borne_inferieure))                                          \
                                        )                                                                                               \
                                  ,PRENDRE_LE_PREMIER_NOMBRE_ALEATOIRE_GENERE                                                           \
                                   )                                                                                                    \
                              )                                                                                                         \
                              Bblock                                                                                                    \
                              EGAL(generer_une_nouvelle_valeur_aleatoire,FAUX);                                                         \
                                        /* Des qu'une valeur aleatoire, soit nulle, soit pas trop petite en valeur absolue, a ete    */ \
                                        /* generee, on interrompt le processus...                                                    */ \
                              Eblock                                                                                                    \
                         ATes                                                                                                           \
                              Bblock                                                                                                    \
                                        /* Tant que des valeurs aleatoires non nulles et trop petites en valeur absolue sont         */ \
                                        /* generees, on les rejette...                                                               */ \
                              Eblock                                                                                                    \
                         ETes                                                                                                           \
                         Eblock                                                                                                         \
                    ETan                                                                                                                \
                                                                                                                                        \
                    EGAL(valeur_aleatoire,valeur_aleatoire_intermediaire);                                                              \
                                        /* Renvoi d'une valeur aleatoire dans [borne_inferieure,borne_superieure] et pas trop petite */ \
                                        /* si elle est proche de zero...                                                             */ \
                                                                                                                                        \
                    PULL_ECHANTILLONNAGE;                                                                                               \
                                        /* Restauration de l'echantillonnage d'appel...                                              */ \
                    Eblock                                                                                                              \
                                        /* Generation d'une valeur aleatoire dans [borne_inferieure,borne_superieure].               */
#define   GENERATION_D_UNE_VALEUR(valeur_aleatoire,borne_inferieure,borne_superieure)                                                   \
                    Bblock                                                                                                              \
                    EGAL(valeur_aleatoire,generation_d_une_valeur(borne_inferieure,borne_superieure));                                  \
                    Eblock                                                                                                              \
                                        /* Generation d'une valeur aleatoire dans [borne_inferieure,borne_superieure].               */

BFonctionF

DEFV(Local,DEFV(FonctionF,generation_d_une_valeur(borne_inferieure,borne_superieure)))
DEFV(Argument,DEFV(Float,borne_inferieure));
DEFV(Argument,DEFV(Float,borne_superieure));
                                        /* Bornes inferieure et superieure de la generation...                                       */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
     DEFV(Float,INIT(valeur_aleatoire,FLOT__UNDEF));
                                        /* Variable locale destinee a contenir la valeur aleatoire generee pour s'eviter des         */
                                        /* problemes de renvoi de valeurs a une adresse donnee...                                    */
     /*..............................................................................................................................*/
     ___GENERATION_D_UNE_VALEUR(valeur_aleatoire,borne_inferieure,borne_superieure);
                                        /* Calcul de la valeur aleatoire...                                                          */
     RETU(valeur_aleatoire);
     Eblock

EFonctionF

DEFV(Local,DEFV(Int,INIT(increment_de_la_graine_du_generateur_d_evenements,ZERO)));
                                        /* Cet increment variable a ete introduit afin que 'rdnI3D(...)' genere des suites de        */
                                        /* nombres variables sans toucher a 'point_courant_de_l_espace_de_parametrage'...            */

#define   INITIALISATION_DE_LA_GENERATION_D_UNE_VALEUR_SANS_DEPLACEMENT(increment_initial_de_la_graine_du_generateur_d_evenements)      \
                    Bblock                                                                                                              \
                    EGAL(increment_de_la_graine_du_generateur_d_evenements                                                              \
                        ,increment_initial_de_la_graine_du_generateur_d_evenements                                                      \
                         );                                                                                                             \
                    Eblock                                                                                                              \
                                        /* Initialisation du generateur de valeurs dit "sans deplacement"...                         */
#define   GENERATION_D_UNE_VALEUR_SANS_DEPLACEMENT(valeur_aleatoire,borne_inferieure,borne_superieure)                                  \
                    Bblock                                                                                                              \
                    INCR(increment_de_la_graine_du_generateur_d_evenements,I);                                                          \
                                        /* Afin de "deplacer" la graine du generateur aleatoire...                                   */ \
                    GENERATION_GENERALE_D_UNE_VALEUR(valeur_aleatoire                                                                   \
                                                    ,borne_inferieure,borne_superieure                                                  \
                                                    ,ADD2(graine_du_generateur_d_evenements                                             \
                                                         ,increment_de_la_graine_du_generateur_d_evenements                             \
                                                          )                                                                             \
                                                     );                                                                                 \
                                        /* Generation d'une valeur aleatoire dans [borne_inferieure,borne_superieure] et parametree  */ \
                                        /* par le point courant de l'espace de parametrage, mais qui ne changera pas.                */ \
                    Eblock                                                                                                              \
                                        /* Generation d'une valeur aleatoire dans [borne_inferieure,borne_superieure]. Cette         */ \
                                        /* fonction particuliere a ete introduite pour la "randomisation" des spheres materialisant  */ \
                                        /* les particules. En effet, celles-ci sont calculees dans les coordonnees de visualisation, */ \
                                        /* et en particulier apres projection perspective. Dans ces conditions, lorsqu'un calcul en  */ \
                                        /* stereoscopie est effectuee, il y a peu de chance pour qu'une meme particule soit          */ \
                                        /* materialisee avec le meme nombre de points sur les vues 'DROITE' et 'GAUCHE'. Dans ces    */ \
                                        /* conditions, 'GENERATION_D_UNE_VALEUR(...)' n'est pas appele le meme nombre de fois pour   */ \
                                        /* les images 'DROITE' et 'GAUCHE', et donc les suites d'evenements pour les deux images     */ \
                                        /* seront donc completement differentes, ce qui est impensable...                            */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        G E N E R A T I O N   D E S   P R O B A B I L I T E S  :                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   EVENEMENT_IMPOSSIBLE                                                                                                          \
                    PROBABILITE_NULLE                                                                                                   \
                                        /* Probabilite d'un evenement impossible.                                                    */
#define   EVENEMENT_CERTAIN                                                                                                             \
                    PROBABILITE_UNITE                                                                                                   \
                                        /* Probabilite d'un evenement certain.                                                       */
#define   GENERATION_D_UNE_PROBABILITE_01(probabilite)                                                                                  \
                    Bblock                                                                                                              \
                    GENERATION_D_UNE_VALEUR(probabilite                                                                                 \
                                           ,EVENEMENT_IMPOSSIBLE                                                                        \
                                           ,EVENEMENT_CERTAIN                                                                           \
                                            );                                                                                          \
                                        /* Generation d'une probabilite dans [0,1].                                                  */ \
                    EGAL(probabilite,hPROBABILITE(probabilite));                                                                        \
                                        /* Prise en compte de la periode de l'horloge courante...                                    */ \
                    Eblock                                                                                                              \
                                        /* Generation d'une probabilite dans [0,1], avec diminution des probabilites, lorsque        */ \
                                        /* la periode de l'horloge diminue (plus l'intervalle de temps des observations est          */ \
                                        /* reduit, et plus la chance d'observer un evenement diminue...).                            */



Copyright © Jean-François Colonna, 2019-2021.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / Ecole Polytechnique, 2019-2021.