/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        C A L C U L   D E   T O U T E S   L E S   D I S T A N C E S   2   A   2   D A N S                                          */
/*        U N   E N S E M B L E   D E   P O I N T S   { X , Y , Z }  :                                                               */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xrv/distance.02$K' :                                                                                           */
/*                                                                                                                                   */
/*                    Jean-Francois COLONNA (LACTAMME, 20000522115636).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        I N T E R F A C E   ' listG '  :                                                                                           */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        :Debut_listG:                                                                                                              */
/*        :Fin_listG:                                                                                                                */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D I R E C T I V E S   S P E C I F I Q U E S   D E   C O M P I L A T I O N  :                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
                                        /* Le 20080311163442, fut supprime :                                                         */
                                        /*                                                                                           */
                                        /*                  @define   PRAGMA_CL_____MODULE_NON_OPTIMISABLE                           */
                                        /*                                                                                           */
                                        /* qui semblait inutile...                                                                   */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        F I C H I E R S   D ' I N C L U D E S  :                                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#include  INCLUDES_BASE

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        V A L E U R S   I M P L I C I T E S   D E S   P A R A M E T R E S  :                                                       */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   EDITER_LES_N_PREMIERS_VOISINS                                                                                                 \
                    FAUX
#define   NOMBRE_DE_PREMIERS_VOISINS                                                                                                    \
                    TROIS
#define   TRIER_LES_INDEX_DES_PREMIERS_VOISINS                                                                                          \
                    VRAI
#define   EDITER_LES_COORDONNEES_DES_POINTS_LORSQU_IL_Y_A_TRI_DES_PREMIERS_VOISINS                                                      \
                    FAUX
#define   METTRE_LES_POINTS_DANS_LE_BON_ORDRE_LORSQU_IL_Y_A_TRI_DES_PREMIERS_VOISINS                                                    \
                    FAUX
                                        /* Doit-on n'editer que les 'N' premiers voisins ('VRAI') ou bien editer quasiment tous      */
                                        /* couples {I,J} ('FAUX') suivant 'IL_FAUT(editer_tous_les_couples_IJ)' ? D'autre part,      */
                                        /* doit-on editer les couples {I,J} des premiers voisins quel que soit leur ordre ('FAUX')   */
                                        /* ou bien en respectant le critere de tri I<J ('VRAI') ? On notera au passage que cette     */
                                        /* option ('TRIER_LES_INDEX_DES_PREMIERS_VOISINS') a ete introduite le 20011014091311        */
                                        /* afin d'optimiser 'v $xiirs/.PSPH.21.1.$U 20011014091311' et eliminer la redondance        */
                                        /* des couples...                                                                            */
                                        /*                                                                                           */
                                        /* Le 20051201133356 a ete introduit la possibilite d'editer (en plus des index) les         */
                                        /* coordonnees des points lorsque 'IL_FAUT(editer_les_N_premiers_voisins)'...                */
                                        /*                                                                                           */
                                        /* Le 20051203100941,la possibilite de lister les points {I,J} dans le bon ordre, lorsque    */
                                        /* 'IL_FAUT(editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins)', a    */
                                        /* a ete introduite...                                                                       */

#define   EDITER_TOUS_LES_COUPLES_IJ                                                                                                    \
                    VRAI                                                                                                                \
                                        /* Doit-on editer tous les couples {I,J} ('VRAI') ou bien n'editer ceux pour lesquels        */ \
                                        /* I<J strictement ('FAUX') ?                                                                */

#define   FILTRER_LES_DISTANCES                                                                                                         \
                    FAUX
#define   BORNE_INFERIEURE_DES_DISTANCES                                                                                                \
                    FZERO
#define   BORNE_SUPERIEURE_DES_DISTANCES                                                                                                \
                    F_INFINI
                                        /* Doit-on filtrer dans [inf,sup] les distances ('VRAI') ou pas ('FAUX') ? Les valeurs par   */
                                        /* defaut garantissent la compatibilite anterieure. Cela fut introduit le 20161109083817     */

#define   AMPLITUDE_DE_LA_TRANSLATION_DES_INDEX_DES_POINTS                                                                              \
                    PREMIER_ELEMENT_D_UN_FICHIER                                                                                        \
                                        /* Translation des index des points lors de leur edition. Ceci a ete introduit le            */ \
                                        /* 20011011112017 car, en effet, '$xrv/distance.02$K' utilise :                              */ \
                                        /*                                                                                           */ \
                                        /* 1-'gELEMENT_DU_FICHIER(...)', pour lequel le premier element vaut :                       */ \
                                        /*                                                                                           */ \
                                        /*        PREMIER_ELEMENT_D_UN_FICHIER = INDEX0 = ZERO                                       */ \
                                        /*                                                                                           */ \
                                        /* qui ne peut utiliser 'Komp(...)' et demande donc une gestion de type 'DoIn(...)' en       */ \
                                        /* precisant le premier element en tant qu'argument du 'DoIn(...)' (et valant donc 'ZERO').  */ \
                                        /* Alors que de nombreux programmes gerant des points ('v $xrv/particule.10$K ACCES_LISTE'   */ \
                                        /* par exemple) utilisent :                                                                  */ \
                                        /*                                                                                           */ \
                                        /* 2-'ACCES_LISTE(...)', pour lequel le premier element vaut :                               */ \
                                        /*                                                                                           */ \
                                        /*        PREMIER_POINT_DES_LISTES = PREMIER_POINT = PREMIERE_ITERATION_D_UN_Komp = UN       */ \
                                        /*                                                                                           */ \
                                        /* qui est donc adapte a une gestion de type 'Komp(...)' ou le premier element est defini    */ \
                                        /* implicitement (et vaut donc 'UN')...                                                      */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D E F I N I T I O N   D E S   F I C H I E R S  :                                                                           */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   NOMBRE_MAXIMAL_D_ELEMENTS_DANS_LE_FICHIER                                                                                     \
                    GRO1(MILLE)                                                                                                         \
                                        /* En prevision d'une matrice memorisant les distances 2 a 2...                              */

#include  xrv/ARITHMET.1d.I"
                                        /* Passage a l'allocation dynamique le 20060214190521...                                     */
#include  xrv/ARITHMET.21.I"
#include  xrk/attractor.12.I"
#include  xrv/champs_5.11.I"

#define   X_IMPLICITE                                                                                                                   \
                    FZERO
#define   Y_IMPLICITE                                                                                                                   \
                    FZERO
#define   Z_IMPLICITE                                                                                                                   \
                    FZERO

gGENERATION_D_UN_FICHIER(fichier_LISTE_X,liste_initiale_des_X);
gGENERATION_D_UN_FICHIER(fichier_LISTE_Y,liste_initiale_des_Y);
gGENERATION_D_UN_FICHIER(fichier_LISTE_Z,liste_initiale_des_Z);
                                        /* Definition en memoire des fichiers de coordonnees cartesiennes.                           */

#define   ELEMENT_DU_FICHIER_LISTE_X(index)                                                                                             \
                    gELEMENT_DU_FICHIER(liste_initiale_des_X,index)
#define   ELEMENT_DU_FICHIER_LISTE_Y(index)                                                                                             \
                    gELEMENT_DU_FICHIER(liste_initiale_des_Y,index)
#define   ELEMENT_DU_FICHIER_LISTE_Z(index)                                                                                             \
                    gELEMENT_DU_FICHIER(liste_initiale_des_Z,index)
                                        /* Acces a un element courant des fichiers de coordonnees cartesiennes.                      */

#define   VOISIN_IMPLICITE                                                                                                              \
                    FLOT(AUTORISE)

gGENERATION_D_UN_FICHIER(fichier_LISTE_VOISIN,liste_initiale_des_VOISIN);
                                        /* Definition en memoire des fichiers des "autorisations" de voisinnage (ceci fut            */
                                        /* introduit le 20051206093616). Pour chaque point 'I', on va disposer (si cela est          */
                                        /* demande via 'IL_FAUT(editer_les_N_premiers_voisins)') de la liste triee par distances     */
                                        /* croissantes des voisins {J} du point 'I'. La liste 'liste_initiale_des_VOISIN'            */
                                        /* permet de selectionner les voisins a editer dans cette liste. On notera que le            */
                                        /* point 'J' d'index 0 est le point 'I' lui-meme et donc la premiere entree du fichier       */
                                        /* 'liste_initiale_des_VOISIN' n'est pas utilisee ; on verra a ce propos le test :           */
                                        /*                                                                                           */
                                        /*                  Test(IFNE(indexI,index_J_trie))                                          */
                                        /*                                                                                           */
                                        /* ci-apres qui fait que les couples de type {I,I} sont ignores lors de l'edition des        */
                                        /* premiers voisins...                                                                       */

#define   ELEMENT_DU_FICHIER_LISTE_VOISIN(index)                                                                                        \
                    LOGI(gELEMENT_DU_FICHIER(liste_initiale_des_VOISIN,index))
                                        /* Acces a un element courant des fichiers des "autorisations" de voisinnage.                */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M A C R O S   U T I L E S  :                                                                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   TRANSLATION_DES_INDEX_DES_POINTS(index)                                                                                       \
                    CONX(index,PREMIER_ELEMENT_D_UN_FICHIER,amplitude_de_la_translation_des_index_des_points)                           \
                                        /* Translation des index des points lors de leur edition.                                    */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        C A L C U L   D E   T O U T E S   L E S   D I S T A N C E S   2   A   2   D A N S                                          */
/*        U N   E N S E M B L E   D E   P O I N T S   { X , Y , Z }  :                                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
#include  xrv/ARITHMET.22.I"

     DEFV(Logical,INIT(editer_les_N_premiers_voisins,EDITER_LES_N_PREMIERS_VOISINS));
     DEFV(Positive,INIT(nombre_de_premiers_voisins,NOMBRE_DE_PREMIERS_VOISINS));
     DEFV(Logical,INIT(trier_les_index_des_premiers_voisins,TRIER_LES_INDEX_DES_PREMIERS_VOISINS));
     DEFV(Logical,INIT(editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins
                      ,EDITER_LES_COORDONNEES_DES_POINTS_LORSQU_IL_Y_A_TRI_DES_PREMIERS_VOISINS
                       )
          );
     DEFV(Logical,INIT(mettre_les_points_dans_le_bon_ordre_lorsqu_il_y_a_tri_des_premiers_voisins
                      ,METTRE_LES_POINTS_DANS_LE_BON_ORDRE_LORSQU_IL_Y_A_TRI_DES_PREMIERS_VOISINS
                       )
          );
                                        /* Doit-on n'editer que les 'N' premiers voisins ('VRAI') ou bien editer quasiment tous      */
                                        /* couples {I,J} ('FAUX') suivant 'IL_FAUT(editer_tous_les_couples_IJ)' ? D'autre part,      */
                                        /* doit-on editer les couples {I,J} des premiers voisins quel que soit leur ordre ('FAUX')   */
                                        /* ou bien en respectant le critere de tri I<J ('VRAI') ? On notera au passage que cette     */
                                        /* option ('TRIER_LES_INDEX_DES_PREMIERS_VOISINS') a ete introduite le 20011014091311        */
                                        /* afin d'optimiser 'v $xiirs/.PSPH.21.1.$U 20011014091311' et eliminer la redondance        */
                                        /* des couples...                                                                            */
                                        /*                                                                                           */
                                        /* Le 20051201133356 a ete introduit la possibilite d'editer (en plus des index) les         */
                                        /* coordonnees des points lorsque 'IL_FAUT(editer_les_N_premiers_voisins)'...                */
                                        /*                                                                                           */
                                        /* Le 20051203100941,la possibilite de lister les points {I,J} dans le bon ordre, lorsque    */
                                        /* 'IL_FAUT(editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins)', a    */
                                        /* a ete introduite...                                                                       */
     DEFV(Logical,INIT(editer_tous_les_couples_IJ,EDITER_TOUS_LES_COUPLES_IJ));
                                        /* Doit-on editer tous les couples {I,J} ('VRAI') ou bien n'editer ceux pour lesquels        */
                                        /* I<J strictement ('FAUX') ?                                                                */

     DEFV(Logical,INIT(filtrer_les_distances,FILTRER_LES_DISTANCES));
     DEFV(Float,INIT(borne_inferieure_des_distances,BORNE_INFERIEURE_DES_DISTANCES));
     DEFV(Float,INIT(borne_superieure_des_distances,BORNE_SUPERIEURE_DES_DISTANCES));
                                        /* Doit-on filtrer dans [inf,sup] les distances ('VRAI') ou pas ('FAUX') ? Les valeurs par   */
                                        /* defaut garantissent la compatibilite anterieure. Cela fut introduit le 20161109083817     */

     DEFV(Int,INIT(amplitude_de_la_translation_des_index_des_points,AMPLITUDE_DE_LA_TRANSLATION_DES_INDEX_DES_POINTS));
                                        /* Translation des index des points lors de leur edition. Ceci a ete introduit le            */
                                        /* 20011011112017 car, en effet, '$xrv/distance.02$K' utilise :                              */
                                        /*                                                                                           */
                                        /* 1-'gELEMENT_DU_FICHIER(...)', pour lequel le premier element vaut :                       */
                                        /*                                                                                           */
                                        /*                  PREMIER_ELEMENT_D_UN_FICHIER=INDEX0=ZERO                                 */
                                        /*                                                                                           */
                                        /* qui ne peut utiliser 'Komp(...)' et demande donc une gestion de type 'DoIn(...)' en       */
                                        /* precisant le premier element en tant qu'argument du 'DoIn(...)' (et valant donc 'ZERO').  */
                                        /* Alors que de nombreux programmes gerant des points ('v $xrv/particule.10$K ACCES_LISTE'   */
                                        /* par exemple) utilisent :                                                                  */
                                        /*                                                                                           */
                                        /* 2-'ACCES_LISTE(...)', pour lequel le premier element vaut :                               */
                                        /*                                                                                           */
                                        /*                  PREMIER_POINT_DES_LISTES=PREMIER_POINT=PREMIERE_ITERATION_D_UN_Komp=UN   */
                                        /*                                                                                           */
                                        /* qui est donc adapte a une gestion de type 'Komp(...)' ou le premier element est defini    */
                                        /* implicitement (et vaut donc 'UN')...                                                      */

     DEFV(Int,INIT(indexI,UNDEF));
     DEFV(Int,INIT(indexJ,UNDEF));
                                        /* Index des elements courants dans les fichiers pour calculer les distances {I,J}.          */
     DEFV(Int,INIT(compteur_des_distances,ZERO));
                                        /* Compteur des distances destine a editer eventuellement un message d'avertissement         */
                                        /* (introduit le 20161109120606)...                                                          */
     /*..............................................................................................................................*/
     GET_ARGUMENTS_(nombre_d_arguments
                   ,BLOC(PROCESS_ARGUMENT_I("nombre_elements=""ne=",nombre_d_elements
                                           ,BLOC(VIDE;)
                                           ,BLOC(Bblock
                                                 PRINT_AVERTISSEMENT("'ne=' doit etre defini avant toute entree de fichiers");
                                                 Eblock
                                                 )
                                            );

                         PROCESS_ARGUMENTS_DE_DEFINITION_DES_FICHIERS_01;

                         PROKESF_ARGUMENT_FICHIER("LISTE_X="
                                                 ,fichier_LISTE_X
                                                 ,liste_initiale_des_X
                                                 ,X_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );
                         PROKESF_ARGUMENT_FICHIER("LISTE_Y="
                                                 ,fichier_LISTE_Y
                                                 ,liste_initiale_des_Y
                                                 ,Y_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );
                         PROKESF_ARGUMENT_FICHIER("LISTE_Z="
                                                 ,fichier_LISTE_Z
                                                 ,liste_initiale_des_Z
                                                 ,Z_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );

                         PROKESF_ARGUMENT_FICHIER("LISTE_VOISIN="
                                                 ,fichier_LISTE_VOISIN
                                                 ,liste_initiale_des_VOISIN
                                                 ,VOISIN_IMPLICITE
                                                 ,lTRANSFORMAT_0d
                                                 ,iGENERATION_D_UN_FICHIER
                                                  );

                         GET_ARGUMENT_L("pv=""premiers_voisins=",editer_les_N_premiers_voisins);
                         GET_ARGUMENT_I("N=",nombre_de_premiers_voisins);
                         GET_ARGUMENT_L("tri=",trier_les_index_des_premiers_voisins);
                         GET_ARGUMENT_L("editer_coordonnees_si_tri=""ecst=""coordonnees="
                                       ,editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins
                                        );
                         GET_ARGUMENT_L("bost=""bon_ordre_des_points_si_tri=""bon_ordre="
                                       ,mettre_les_points_dans_le_bon_ordre_lorsqu_il_y_a_tri_des_premiers_voisins
                                        );

                         GET_ARGUMENT_L("tri_N2=""N_carre=""N_au_carre=""N_AU_CARRE=""N2="
                                       ,utiliser_le_tri_d_une_liste_quelconque_VERSION_N_AU_CARRE
                                        );
                         GET_ARGUMENT_N("tri_NlogN=""NlN=""N_log_N=""N1=",utiliser_le_tri_d_une_liste_quelconque_VERSION_N_AU_CARRE);
                                        /* Les parametres "N_log_N=", "N_log_N",... ont ete introduits le 20111028201026...          */
                         GET_ARGUMENT_L("IFGT_N_carre=""IFGT_N_au_carre=""IFGT_N_AU_CARRE=""IFGT_N2="
                                       ,TRI_D_UNE_LISTE_QUELCONQUE_VERSION_N_AU_CARRE_____faire_un_IFGT
                                        );
                         GET_ARGUMENT_L("message_N_carre=""message_N_au_carre=""message_N_AU_CARRE=""mN2="
                                       ,TRI_D_UNE_LISTE_QUELCONQUE_VERSION_N_AU_CARRE_____editer_le_message_de_duree_excessive
                                        );
                                        /* Arguments introduits le 20120509095215...                                                 */

                         GET_ARGUMENT_L("tousIJ=""tous=""IJ=",editer_tous_les_couples_IJ);

                         GET_ARGUMENT_L("filtrer_distances=""fd=",filtrer_les_distances);
                         GET_ARGUMENT_F("borne_inferieure_distances=""bid=",borne_inferieure_des_distances);
                         GET_ARGUMENT_F("borne_superieure_distances=""bsd=",borne_superieure_des_distances);
                                        /* Arguments introduits le 20161109083817...                                                 */

                         GET_ARGUMENT_I("translation=""t=",amplitude_de_la_translation_des_index_des_points);
                         )
                    );

     Test(IFGE(nombre_de_premiers_voisins,nombre_d_elements))
          Bblock
          EGAL(nombre_de_premiers_voisins,PRED(nombre_d_elements));
                                        /* Introduit le 20051206101606 car, en effet, cela manquait par erreur...                    */

          PRINT_ATTENTION("le nombre de premiers voisins est trop grand par rapport au nombre de points");
          CAL1(Prer1("(la valeur maximale (%d) va donc etre utilisee)\n",nombre_de_premiers_voisins));
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     Test(IL_FAUT(editer_les_N_premiers_voisins))
          Bblock
          DEFV(Logical,INIT(au_moins_un_voisin_est_autorise,FAUX));
                                        /* Ce test de validation de 'liste_initiale_des_VOISIN' a ete introduit le 20051206101606.   */

          DoIn(indexI
              ,SUCC(PREMIER_ELEMENT_D_UN_FICHIER)
              ,DERNIER_ELEMENT_D_UN_FICHIER
              ,I
               )
                                        /* Le 'SUCC(...)' est destine a prendre en compte le fait que le premier point (d'index 0)   */
                                        /* de la liste 'liste_initiale_des_VOISIN' correspond aux couples de type {I,I} lors du      */
                                        /* calcul des distances 2 a 2 ...                                                            */
               Bblock
               Test(EST_AUTORISE(ELEMENT_DU_FICHIER_LISTE_VOISIN(indexI)))
                    Bblock
                    EGAL(au_moins_un_voisin_est_autorise,VRAI);
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes
               Eblock
          EDoI

          Test(EST_FAUX(au_moins_un_voisin_est_autorise))
               Bblock
               PRINT_ATTENTION("aucun voisin n'est autorise (le premier element etant ignore), on les autorise donc tous");

               iGENERATION_D_UN_FICHIER(liste_initiale_des_VOISIN,VOISIN_IMPLICITE);
               Eblock
          ATes
               Bblock
               Eblock
          ETes
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     DoIn(indexI
         ,PREMIER_ELEMENT_D_UN_FICHIER
         ,DERNIER_ELEMENT_D_UN_FICHIER
         ,I
          )
          Bblock
          DEFV(Float,INIT(coordonnee_XI,ELEMENT_DU_FICHIER_LISTE_X(indexI)));
          DEFV(Float,INIT(coordonnee_YI,ELEMENT_DU_FICHIER_LISTE_Y(indexI)));
          DEFV(Float,INIT(coordonnee_ZI,ELEMENT_DU_FICHIER_LISTE_Z(indexI)));
                                        /* Recuperation des coordonnees {X,Y,Z} courantes du point 'I' dans les fichiers.            */

          gGENERATION_D_UN_FICHIER_liste(liste_des_points);
          gGENERATION_D_UN_FICHIER_liste(liste_des_distances_du_point_I_aux_points_J);
                                        /* Liste des distances du point 'I' (fixe) aux points 'J' variables.                         */
          iGENERATION_D_UN_FICHIER(liste_des_points,FLOT__UNDEF);
          iGENERATION_D_UN_FICHIER(liste_des_distances_du_point_I_aux_points_J,FLOT__UNDEF);
                                        /* Ceci est rendu obligatoire par l'allocation dynamique de la memoire (le 20060214190521).  */

                                        /* Dans la boucle 'DoIn(...)' qui suit on va rechercher les 'nombre_de_premiers_voisins'     */
                                        /* d'index 'indexJ' du point courant d'index 'indexI'. On notera que cela ne donne pas       */
                                        /* toujours le resultat "global" que l'on attend comme cela s'est vu aux environs du         */
                                        /* 20180828152255. Ainsi, lors de la generation de l'image 'v $xiirs/PSPH.B5.1.20' en        */
                                        /* choisissant '_____NPoints=3', le point d'index 4 (en tant que 'indexI' ou 'indexJ')       */
                                        /* se retrouve plus de 3 fois :                                                              */
                                        /*                                                                                           */
                                        /*                                                                                           */
                                        /*        indexJ=4                                                                           */
                                        /*                  couple={0,4}        distance=+0.792554635397115126                       */
                                        /*                                                                                           */
                                        /*        indexJ=4                                                                           */
                                        /*                  couple={1,4}        distance=+0.794813519138595659                       */
                                        /*                                                                                           */
                                        /*        indexJ=4                                                                           */
                                        /*                  couple={2,4}        distance=+0.798600008488370872                       */
                                        /*                                                                                           */
                                        /*   indexI=4                                                                                */
                                        /*                  couple={4,0}        distance=+0.792554635397115126                       */
                                        /*                  couple={4,1}        distance=+0.794813519138595659                       */
                                        /*                  couple={4,13}       distance=+0.796233061158463595                       */
                                        /*                                                                                           */
                                        /*        indexJ=4                                                                           */
                                        /*                  couple={11,4}       distance=+0.816106796257996314                       */
                                        /*                                                                                           */
                                        /*        indexJ=4                                                                           */
                                        /*                  couple={13,4}       distance=+0.796233061158463595                       */
                                        /*                                                                                           */
                                        /*                                                                                           */
                                        /* et ainsi, le point d'index 4 semble avoir 5 plus proches voisins, soit :                  */
                                        /*                                                                                           */
                                        /*                  couple ={0,4}  = {4,0}                   0        vrai 3-proche voisin   */
                                        /*                  couple ={1,4}  = {4,1}                   1        vrai 3-proche voisin   */
                                        /*                  couple ={2,4}                            2                               */
                                        /*                  couple ={11,4}                           11                              */
                                        /*                  couple ={4,13} = {13,4}                  13       vrai 3-proche voisin   */
                                        /*                                                                                           */
                                        /* et non pas 3 (=$_____NPoints) ! Et c'est cela qui fait que l'on voit certains points      */
                                        /* connectes a plus de 3 autres (dont le point 4 qui est donc connecte a 5 autres...).       */
                                        /*                                                                                           */
                                        /* Que faire ? Je crois qu'il n'y a pas de solution pour le moment car, en effet, pour       */
                                        /* reprendre le cas precedent, on ne peut pas eliminer le couple {2,4} car, en effet, le     */
                                        /* point 4 est bien un 3-proche voisin du point 2, alors que le point 2 n'est pas un         */
                                        /* un 3-proche voisin du point 4...                                                          */
                                        /*                                                                                           */
                                        /* Moralite : la notion de "N-proche voisin" ne "commute" pas...                             */

          DoIn(indexJ
              ,PREMIER_ELEMENT_D_UN_FICHIER
              ,DERNIER_ELEMENT_D_UN_FICHIER
              ,I
               )
               Bblock
                                        /* Les donnees qui suivent pourraient etre evidemment apres le 'Test(...)' relatif a         */
                                        /* 'editer_tous_les_couples_IJ', mais en fait cette localisation peu optimisee a priori      */
                                        /* est en prevision d'une matrice memorisant les distances 2 a 2...                          */

               DEFV(Float,INIT(coordonnee_XJ,ELEMENT_DU_FICHIER_LISTE_X(indexJ)));
               DEFV(Float,INIT(coordonnee_YJ,ELEMENT_DU_FICHIER_LISTE_Y(indexJ)));
               DEFV(Float,INIT(coordonnee_ZJ,ELEMENT_DU_FICHIER_LISTE_Z(indexJ)));
                                        /* Recuperation des coordonnees {X,Y,Z} courantes du point 'J' dans les fichiers.            */

               DEFV(Float,INIT(distance_IJ
                              ,RdisF3D(coordonnee_XI,coordonnee_YI,coordonnee_ZI
                                      ,coordonnee_XJ,coordonnee_YJ,coordonnee_ZJ
                                       )
                               )
                    );
                                        /* Calcul de la distance des points {I,J}.                                                   */

               Test(IL_FAUT(editer_les_N_premiers_voisins))
                    Bblock
                    EGAL(gELEMENT_DU_FICHIER(liste_des_points,indexJ),FLOT(indexJ));
                    EGAL(gELEMENT_DU_FICHIER(liste_des_distances_du_point_I_aux_points_J,indexJ),distance_IJ);
                    Eblock
               ATes
                    Bblock
                    Test(IFOU(IL_FAUT(editer_tous_les_couples_IJ)
                             ,IFET(IL_NE_FAUT_PAS(editer_tous_les_couples_IJ)
                                  ,IFLT(indexI,indexJ)
                                   )
                              )
                         )
                         Bblock
                         Test(IFOU(IL_NE_FAUT_PAS(filtrer_les_distances)
                                  ,IFET(IL_FAUT(filtrer_les_distances)
                                       ,IFINff(distance_IJ,borne_inferieure_des_distances,borne_superieure_des_distances)
                                        )
                                   )
                              )
                                        /* Possibilite introduite le 20161109083817...                                               */
                              Bblock
                              CAL2(Prin2(" couple={%d,%d}"
                                        ,TRANSLATION_DES_INDEX_DES_POINTS(indexI)
                                        ,TRANSLATION_DES_INDEX_DES_POINTS(indexJ)
                                         )
                                   );
                                        /* On notera (le 20040128142430) que lorsque 'IL_FAUT(trier_les_index_des_premiers_voisins)' */
                                        /* l'index du premier element d'un couple est inferieur a celui du second element. D'autre   */
                                        /* part, il est tout a fait logique dans ces memes circonstances de trouver en double        */
                                        /* certaines lignes ; elles correspondent alors que fait que :                               */
                                        /*                                                                                           */
                                        /*                  DISTANCE(i,j) = DISTANCE(j,i)                                            */
                                        /*                                                                                           */
                                        /* et que faisant un tri des {i,j} et en supposant que i<j, on sort donc deux fois la        */
                                        /* ligne 'couple={i,j}' (mais pas la ligne 'couple={j,i}'). Cela ne se produira evidemment   */
                                        /* pas si 'IL_FAUT(editer_les_N_premiers_voisins)' et que l'une ou les deux de ce lignes     */
                                        /* sont alors eliminees...                                                                   */
                              CAL2(Prin3(" pointI={%+.^^^,%+.^^^,%+.^^^}",coordonnee_XI,coordonnee_YI,coordonnee_ZI));
                              CAL2(Prin3(" pointJ={%+.^^^,%+.^^^,%+.^^^}",coordonnee_XJ,coordonnee_YJ,coordonnee_ZJ));
                              CAL2(Prin1(" distance=%+.^^^",distance_IJ));
                              CAL2(Prin0("\n"));
                                        /* Edition de la distance des points {I,J}.                                                  */
                                        /*                                                                                           */
                                        /* Le 20060105152121, le format "16g" est passe a "^^g" pour plus de souplesse...            */
                                        /*                                                                                           */
                                        /* Le 20091123123539, le format "^^g" est passe a "^^^" pour plus de souplesse...            */

                              INCR(compteur_des_distances,I);
                                        /* Introduit le 20161109120606...                                                            */
                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes
                    Eblock
               ETes
               Eblock
          EDoI

          Test(IL_FAUT(editer_les_N_premiers_voisins))
               Bblock
               TRI_D_UNE_LISTE_QUELCONQUE(liste_des_distances_du_point_I_aux_points_J
                                         ,liste_des_points
                                         ,PREMIER_ELEMENT_D_UN_FICHIER
                                         ,NEUT(DERNIER_ELEMENT_D_UN_FICHIER)
                                         ,EST_CE_LE_TRI_AUTOMATIQUE_D_UNE_LISTE_QUELCONQUE
                                         ,utiliser_le_tri_d_une_liste_quelconque_VERSION_N_AU_CARRE
                                         ,gELEMENT_DU_FICHIER
                                          );
                                        /* Tri des distances du point 'I' (fixe) aux points 'J' variables.                           */
                                        /*                                                                                           */
                                        /* Le 20020828170851 j'ai fait en sorte que l'argument '????_dernier_element' des            */
                                        /* procedures de tri pointe bien sur le dernier element de la liste et non pas sur son       */
                                        /* successeur, d'ou le remplacement des operateurs 'SUCC(...)' par des 'NEUT(...)' (voir     */
                                        /* a ce propos 'v $ximd/operator.1$FON 20020828170851').                                     */
                                        /*                                                                                           */
                                        /* L'argument 'EST_CE_LE_TRI_AUTOMATIQUE_D_UNE_LISTE_QUELCONQUE' a ete introduit le          */
                                        /* 20170608103553...                                                                         */

               DoIn(indexJ
                   ,PREMIER_ELEMENT_D_UN_FICHIER
                   ,LSTX(PREMIER_ELEMENT_D_UN_FICHIER,MIN2(SUCC(nombre_de_premiers_voisins),nombre_d_elements))
                   ,I
                    )
                                        /* Le 'SUCC(...)' est destine a prendre en compte le couple {I,I} pour lequel la distance    */
                                        /* est minimale (nulle...).                                                                  */
                    Bblock
                    DEFV(Int,INIT(index_J_trie,INTE(gELEMENT_DU_FICHIER(liste_des_points,indexJ))));

                    Test(EST_AUTORISE(ELEMENT_DU_FICHIER_LISTE_VOISIN(indexJ)))
                         Bblock
                                        /* Test introduit le 20051206093616 afin de pouvoir selectionner de facon individuelle       */
                                        /* les voisins a editer. ATTENTION : c'est 'indexJ' et non point 'index_J_trie' qu'il        */
                                        /* faut utiliser ici car, en effet, on cherche a tester les couples {I,J} par distances      */
                                        /* croissantes...                                                                            */
                         Test(IFNE(indexI,index_J_trie))
                              Bblock
                              DEFV(Int,INIT(premier_index
                                           ,COND(IL_FAUT(trier_les_index_des_premiers_voisins)
                                                ,MIN2(indexI,index_J_trie)
                                                ,indexI
                                                 )
                                            )
                                   );
                              DEFV(Int,INIT(second_index
                                           ,COND(IL_FAUT(trier_les_index_des_premiers_voisins)
                                                ,MAX2(indexI,index_J_trie)
                                                ,index_J_trie
                                                 )
                                            )
                                   );

                              CAL2(Prin2(" couple={%d,%d}"
                                        ,TRANSLATION_DES_INDEX_DES_POINTS(premier_index)
                                        ,TRANSLATION_DES_INDEX_DES_POINTS(second_index)
                                         )
                                   );
                                        /* On rappelle le 20080224180559 que si 'IL_FAUT(trier_les_index_des_premiers_voisins)',     */
                                        /* il y a alors frequemment des couples qui sortent en double (par exemple {I,J} et {I,J}    */
                                        /* avec I<J, provenant donc de {I,J} et {J,I}). Cela justifie donc les '$SOR -u's faits      */
                                        /* ulterieurement apres ces sorties ('v $xiirs/.PSPH.21.1.$U ListeCouples' par exemple...).  */

                              Test(IL_FAUT(editer_les_coordonnees_des_points_lorsqu_il_y_a_tri_des_premiers_voisins))
                                   Bblock
                                   DEFV(Float,INIT(coordonnee_XJ,ELEMENT_DU_FICHIER_LISTE_X(index_J_trie)));
                                   DEFV(Float,INIT(coordonnee_YJ,ELEMENT_DU_FICHIER_LISTE_Y(index_J_trie)));
                                   DEFV(Float,INIT(coordonnee_ZJ,ELEMENT_DU_FICHIER_LISTE_Z(index_J_trie)));
                                        /* Recuperation des coordonnees {X,Y,Z} courantes du point 'J' dans les fichiers.            */
                                   DEFV(Float,INIT(coordonnee_X1,FLOT__UNDEF));
                                   DEFV(Float,INIT(coordonnee_Y1,FLOT__UNDEF));
                                   DEFV(Float,INIT(coordonnee_Z1,FLOT__UNDEF));

                                   DEFV(Float,INIT(coordonnee_X2,FLOT__UNDEF));
                                   DEFV(Float,INIT(coordonnee_Y2,FLOT__UNDEF));
                                   DEFV(Float,INIT(coordonnee_Z2,FLOT__UNDEF));
                                        /* Afin de pouvoir changer l'ordre des 2 points {I,J} (introduit le 20051203100941)...       */

                                   EGAL(coordonnee_X1,coordonnee_XI);
                                   EGAL(coordonnee_Y1,coordonnee_YI);
                                   EGAL(coordonnee_Z1,coordonnee_ZI);

                                   EGAL(coordonnee_X2,coordonnee_XJ);
                                   EGAL(coordonnee_Y2,coordonnee_YJ);
                                   EGAL(coordonnee_Z2,coordonnee_ZJ);
                                        /* Choix de l'ordre {I,J} pour les deux points.                                              */

                                   Test(IFET(IL_FAUT(mettre_les_points_dans_le_bon_ordre_lorsqu_il_y_a_tri_des_premiers_voisins)
                                            ,IFET(IFEQ(premier_index,index_J_trie)
                                                 ,IFEQ(second_index,indexI)
                                                  )
                                             )
                                        )
                                        /* Ce test a ete introduit le 20051203100941...                                              */
                                        Bblock
                                        fSWAP(coordonnee_X1,coordonnee_X2);
                                        fSWAP(coordonnee_Y1,coordonnee_Y2);
                                        fSWAP(coordonnee_Z1,coordonnee_Z2);
                                        /* Choix de l'ordre {J,I} pour les deux points (l'utilisation de la procedure 'fSWAP(...)'   */
                                        /* fut introduite le 20051206093039...).                                                     */
                                        Eblock
                                   ATes
                                        Bblock
                                        Eblock
                                   ETes

                                   CAL2(Prin3(" pointI={%+.^^^,%+.^^^,%+.^^^}",coordonnee_X1,coordonnee_Y1,coordonnee_Z1));
                                   CAL2(Prin3(" pointJ={%+.^^^,%+.^^^,%+.^^^}",coordonnee_X2,coordonnee_Y2,coordonnee_Z2));
                                        /* Le 20060105152121, le format "16g" est passe a "^^g" pour plus de souplesse...            */
                                        /*                                                                                           */
                                        /* Le 20091123123539, le format "^^g" est passe a "^^^" pour plus de souplesse...            */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              CAL2(Prin1(" distance=%+.^^^"
                                        ,gELEMENT_DU_FICHIER(liste_des_distances_du_point_I_aux_points_J,index_J_trie)
                                         )
                                   );
                              CAL2(Prin0("\n"));
                                        /* Edition de la distance du point 'I' (fixe) a ses N premiers voisins 'J'.                  */
                                        /*                                                                                           */
                                        /* Le 20060105152121, le format "16g" est passe a "^^g" pour plus de souplesse...            */
                                        /*                                                                                           */
                                        /* Le 20091123123539, le format "^^g" est passe a "^^^" pour plus de souplesse...            */

                              INCR(compteur_des_distances,I);
                                        /* Introduit le 20161109120606...                                                            */
                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes
                    Eblock
               EDoI
               Eblock
          ATes
               Bblock
               Eblock
          ETes

          lGENERATION_D_UN_FICHIER(liste_des_distances_du_point_I_aux_points_J,FLOT__UNDEF);
          lGENERATION_D_UN_FICHIER(liste_des_points,FLOT__UNDEF);
          Eblock
     EDoI

     Test(IZEQ(compteur_des_distances))
                                        /* Test introduit le 20161109120606...                                                       */
          Bblock
          PRINT_ATTENTION("aucune distance n'a ete editee");

          Test(IL_FAUT(filtrer_les_distances))
               Bblock
               PRINT_ATTENTION("il y a filtrage et les bornes sont certainement 'insuffisantes'");
               CAL1(Prer2("(les bornes inferieure et superieure valent respectivement %f et %f)\n"
                         ,borne_inferieure_des_distances
                         ,borne_superieure_des_distances
                          )
                    );
               Eblock
          ATes
               Bblock
               Eblock
          ETes
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     lGENERATION_D_UN_FICHIER(liste_initiale_des_VOISIN,VOISIN_IMPLICITE);
     lGENERATION_D_UN_FICHIER(liste_initiale_des_VOISIN,VOISIN_IMPLICITE);
     lGENERATION_D_UN_FICHIER(liste_initiale_des_Z,Z_IMPLICITE);
     lGENERATION_D_UN_FICHIER(liste_initiale_des_Y,Y_IMPLICITE);
     lGENERATION_D_UN_FICHIER(liste_initiale_des_X,X_IMPLICITE);

     RETU_Commande;
     Eblock
ECommande



Copyright © Jean-François COLONNA, 2019-2024.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2019-2024.