/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D ' U N H Y P E R C U B E D E D I M E N S I O N Q U E L C O N Q U E : */
/* */
/* */
/* Author of '$xrs/HyperCube.11$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 20230303181852). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* 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 : */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* 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 DIMENSION_DE_L_HYPER_CUBE \
TRI_DIMENSIONNEL \
/* Dimension de l'hypercube. */
#define EDITER_LE_SEPARATEUR_DES_SOMMETS \
FAUX \
/* Doit-on editer le separateur "--o-->" ('VRAI') ou pas ('FAUX') ? */
#define PROJETER_LES_SOMMETS \
FAUX
#define FAIRE_DE_L_HYPER_PROJECTION_PARALLELE \
VRAI
/* Doit-on projeter les sommets ('VRAI') ou pas ('FAUX') ? Et si 'VRAI' faut-il qu'elle */
/* soit parallele ('VRAI') ou perspective ('FAUX'), ceci ayant introduit le 20230307164837 ? */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
#define BASE \
BASE2 \
/* Base de definition... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S F I C H I E R S : */
/* */
/*************************************************************************************************************************************/
#include xrv/ARITHMET.1d.I"
#include xrv/ARITHMET.21.I"
#include xrv/champs_5.41.I"
#define PX_IMPLICITE \
FZERO
#define PY_IMPLICITE \
FZERO
#define PZ_IMPLICITE \
FZERO
gGENERATION_D_UN_FICHIER(fichier_LISTE_PX,liste_initiale_des_PX);
gGENERATION_D_UN_FICHIER(fichier_LISTE_PY,liste_initiale_des_PY);
gGENERATION_D_UN_FICHIER(fichier_LISTE_PZ,liste_initiale_des_PZ);
#define HP_IMPLICITE \
FZERO
#define HO_IMPLICITE \
FZERO
gGENERATION_D_UN_FICHIER(fichier_LISTE_HP,liste_initiale_des_HP);
gGENERATION_D_UN_FICHIER(fichier_LISTE_HO,liste_initiale_des_HO);
/* Definition en memoire des fichiers definissant la Projection. */
/* */
/* Les listes {PX,PY,PZ} definissent les Ponderations de Projection, quant aux listes */
/* 'HP' et 'HO' elles definissent respectivement l'Hyper-Plan et l'Hyper-Observateur'... */
#define INDEX_EFFECTIF(index) \
MIN2(index,LSTX(premier_element_d_un_fichier,NombreDeSommets))
#define ELEMENT_DU_FICHIER_LISTE_PX(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_PX,INDEX_EFFECTIF(index))
#define ELEMENT_DU_FICHIER_LISTE_PY(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_PY,INDEX_EFFECTIF(index))
#define ELEMENT_DU_FICHIER_LISTE_PZ(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_PZ,INDEX_EFFECTIF(index))
#define ELEMENT_DU_FICHIER_LISTE_HP(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_HP,INDEX_EFFECTIF(index))
#define ELEMENT_DU_FICHIER_LISTE_HO(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_HO,INDEX_EFFECTIF(index))
/* Acces a un element courant des fichiers definissant la Projection. */
/* */
/* On notera le 20230310142834 que le fichier 'LISTE_HP' a autant d'elements que les autres */
/* (et en particulier 'LISTE_HO') et ce a cause de 'PROKESF_ARGUMENT_FICHIER(...)' qui */
/* demande que tous les fichiers aient la meme taille. Par contre, cela n'est pas vrai */
/* dans 'v $ximd/operator.1$FON COEFFICIENT_DE_PROJECTION_PERSPECTIVE_01_4D_3D_R' ou la */
/* definition du plan de projection 'plan_de_projection_perspective_01_4D' a cinq elements */
/* alors que les autres listes en ont quatre (c'est-a-dire la dimension de l'espace...). */
/* Mais cela n'est pas grave... */
/*===================================================================================================================================*/
/* :Debut_listMN_HYPER_CUBE_DE_DIMENSION_N: */
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D ' U N H Y P E R C U B E D E D I M E N S I O N ' N ' : */
/* */
/* */
/* Definition ('v $xtc/hyper_cube.02$c') : */
/* */
/* Un cube peut etre defini par ses aretes et donc */
/* par des couples de sommets adjacents. Chacun d'entre-eux */
/* sera identifie par 'XYZ' ou 'X', 'Y' et 'Z' sont ses */
/* coordonnees que l'on suppose valoir 0 ou 1. Elles */
/* peuvent alors etre aussi considerees comme des bits */
/* et donc ces 3 bits 'XYZ' seront un numero des sommets */
/* entre 0 et 7... */
/* */
/* */
/* 011 ----------------------------- 111 */
/* /. /| */
/* / . / | */
/* / . / | */
/* / . / | */
/* / . / | */
/* / . / | */
/* / . / | */
/* / . / | */
/* / . / | */
/* 010 ----------------------------- 110 | */
/* | . | | */
/* | . | | */
/* | . | | */
/* | . | | */
/* | . | | */
/* | . | | */
/* | . | | */
/* | 001. . . . . . . . . . | . . . . | 101 */
/* | . | / */
/* | . | / */
/* | . | / */
/* Y^ | . | / */
/* | | . | / */
/* | Z | . | / */
/* | / | . | / */
/* | / | . | / */
/* |/ |. |/ */
/* O--------> 000 ----------------------------- 100 */
/* X */
/* */
/* */
/* On note alors que les deux sommets {n1,n2} */
/* definissant une arete sont codes par les memes */
/* bits sauf un. Le "ou exclusif" de leurs numeros */
/* ne contiendra donc qu'un seul bit 1, tous les autres */
/* etant nuls. Il correspondra a une puissance de 2, */
/* ce qui implique que son logarithme en base 2 */
/* sera un nombre entier. */
/* */
/* C'est donc ainsi que sera defini un hypercube */
/* de dimension N. Voici donc la procedure : */
/* */
/* 1-Generer la liste L1 des entiers 'n' dans [0,(2^N)-1]. */
/* */
/* 2-Generer la liste L2 des couples differents {n1,n2} */
/* 'n1' et n2' appartenant a L1 et l'ordre etant indifferent. */
/* */
/* 3-Calculer pour tout couple {n1,n2} : */
/* */
/* A = log (n1.EOR.n2) */
/* 2 */
/* */
/* ('.EOR.' etant l'operateur "ou exclusif"). */
/* */
/* Si 'A' est un nombre entier, alors le couple {n1,n2} */
/* defini une arete de l'hypercube de dimension N. */
/* */
/* */
/* A titre d'exemple, voici la generation de */
/* l'hypercube de dimension 3 (c'est-a-dire le */
/* cube "standard") donnee par 'v $xtc/hyper_cube.12$c' : */
/* */
/* */
/* Generation de la liste des entiers de 0 a 7 (liste 'L1') : */
/* */
/* n */
/* */
/* 000 */
/* 001 */
/* 010 */
/* 011 */
/* 100 */
/* 101 */
/* 110 */
/* 111 */
/* */
/* */
/* Generation des aretes (liste 'L2') : */
/* */
/* n1 n2 */
/* */
/* EOR(000,001)=001 log2=0 arete={000,001} */
/* */
/* EOR(000,010)=010 log2=1 arete={000,010} */
/* EOR(001,010)=011 log2=1.584963 */
/* */
/* EOR(000,011)=011 log2=1.584963 */
/* EOR(001,011)=010 log2=1 arete={001,011} */
/* EOR(010,011)=001 log2=0 arete={010,011} */
/* */
/* EOR(000,100)=100 log2=2 arete={000,100} */
/* EOR(001,100)=101 log2=2.321928 */
/* EOR(010,100)=110 log2=2.584963 */
/* EOR(011,100)=111 log2=2.807355 */
/* */
/* EOR(000,101)=101 log2=2.321928 */
/* EOR(001,101)=100 log2=2 arete={001,101} */
/* EOR(010,101)=111 log2=2.807355 */
/* EOR(011,101)=110 log2=2.584963 */
/* EOR(100,101)=001 log2=0 arete={100,101} */
/* */
/* EOR(000,110)=110 log2=2.584963 */
/* EOR(001,110)=111 log2=2.807355 */
/* EOR(010,110)=100 log2=2 arete={010,110} */
/* EOR(011,110)=101 log2=2.321928 */
/* EOR(100,110)=010 log2=1 arete={100,110} */
/* EOR(101,110)=011 log2=1.584963 */
/* */
/* EOR(000,111)=111 log2=2.807355 */
/* EOR(001,111)=110 log2=2.584963 */
/* EOR(010,111)=101 log2=2.321928 */
/* EOR(011,111)=100 log2=2 arete={011,111} */
/* EOR(100,111)=011 log2=1.584963 */
/* EOR(101,111)=010 log2=1 arete={101,111} */
/* EOR(110,111)=001 log2=0 arete={110,111} */
/* */
/* */
/*************************************************************************************************************************************/
/* :Fin_listMN_HYPER_CUBE_DE_DIMENSION_N: */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* C O N V E R S I O N B I N A I R E : */
/* */
/*************************************************************************************************************************************/
DEFV(Local,DEFV(Int,INIT(NombreDeSommets,UNDEF)));
DEFV(Local,DEFV(Logical,INIT(projeter_les_sommets,PROJETER_LES_SOMMETS)));
DEFV(Local,DEFV(Logical,INIT(faire_de_l_hyper_projection_parallele,FAIRE_DE_L_HYPER_PROJECTION_PARALLELE)));
/* Doit-on projeter les sommets ('VRAI') ou pas ('FAUX') ? Et si 'VRAI' faut-il qu'elle */
/* soit parallele ('VRAI') ou perspective ('FAUX'), ceci ayant introduit le 20230307164837 ? */
BFonctionV
DEFV(FonctionV,ConversionBase(NombreAConvertir,BaseDeNumeration,ExposantMaximaldeLaBase))
DEFV(Argument,DEFV(Int,NombreAConvertir));
DEFV(Argument,DEFV(Int,BaseDeNumeration));
DEFV(Argument,DEFV(Int,ExposantMaximaldeLaBase));
/* Definition des arguments... */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Int,INIT(diviseur,INTE(PUIX(FLOT(BaseDeNumeration),FLOT(PRED(ExposantMaximaldeLaBase))))));
DEFV(Int,INIT(NombreCourant,NombreAConvertir));
DEFV(Int,INIT(IndexDeProjection,UNDEF));
gGENERATION_D_UN_FICHIER_liste(liste_des_COORDONNEES);
#define ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(index) \
gELEMENT_DU_FICHIER(liste_des_COORDONNEES,index)
DEFV(Float,INIT(coordonnee_X,FZERO));
DEFV(Float,INIT(coordonnee_Y,FZERO));
DEFV(Float,INIT(coordonnee_Z,FZERO));
/*..............................................................................................................................*/
iGENERATION_D_UN_FICHIER(liste_des_COORDONNEES,FLOT__UNDEF);
EGAL(IndexDeProjection,premier_element_d_un_fichier);
Repe(ExposantMaximaldeLaBase)
Bblock
DEFV(Int,INIT(quotient,UNDEF));
DEFV(Int,INIT(reste___,UNDEF));
EGAL(quotient,DIVI(NombreCourant,diviseur));
EGAL(reste___,REST(NombreCourant,diviseur));
/* Division euclidienne "progressive"... */
Test(IFEXfo(quotient,ZERO,BASE))
Bblock
PRINT_ERREUR("Quotient hors limite");
CAL1(Prer3("Il vaut %d alors qu'il devrait etre dans [%d,%d[.\n"
,quotient
,ZERO
,BASE
)
);
Eblock
ATes
Bblock
Eblock
ETes
EGAL(ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection),FLOT(quotient));
/* Le "quotient" est le chiffre courant du nombre a convertir suivant la base et c'est */
/* aussi une des coordonnees du sommet courant... */
EGAL(NombreCourant,reste___);
EGAL(diviseur,DIVI(diviseur,BASE));
INCR(IndexDeProjection,I);
Eblock
ERep
Test(IL_FAUT(projeter_les_sommets))
Bblock
Test(IL_FAUT(faire_de_l_hyper_projection_parallele))
Bblock
Eblock
ATes
Bblock
DEFV(Float,INIT(numerateur___R,FZERO));
DEFV(Float,INIT(denominateur_R,FZERO));
EGAL(IndexDeProjection,premier_element_d_un_fichier);
Repe(ExposantMaximaldeLaBase)
Bblock
INCR(numerateur___R
,MUL2(ELEMENT_DU_FICHIER_LISTE_HP(IndexDeProjection)
,ELEMENT_DU_FICHIER_LISTE_HO(IndexDeProjection)
)
);
/* On notera que 'numerateur___R' possede a la fin de tous les 'Repe(...)'s la meme */
/* valeur, mais c'est plus simple de le recalculer systematiquement... */
INCR(denominateur_R
,MUL2(ELEMENT_DU_FICHIER_LISTE_HP(IndexDeProjection)
,SOUS(ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection)
,ELEMENT_DU_FICHIER_LISTE_HO(IndexDeProjection)
)
)
);
/* Voir 'v $ximd/operator.1$FON PROJECTION_PLANE_QUELCONQUE' pour plus d'informations... */
INCR(IndexDeProjection,I);
Eblock
ERep
EGAL(IndexDeProjection,premier_element_d_un_fichier);
Repe(ExposantMaximaldeLaBase)
Bblock
EGAL(ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection)
,SOUS(ELEMENT_DU_FICHIER_LISTE_HO(IndexDeProjection)
,MUL2(DIVI(numerateur___R,denominateur_R)
,SOUS(ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection)
,ELEMENT_DU_FICHIER_LISTE_HO(IndexDeProjection)
)
)
)
);
/* Voir 'v $ximd/operator.1$FON PROJECTION_PLANE_QUELCONQUE' pour plus d'informations... */
INCR(IndexDeProjection,I);
Eblock
ERep
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
EGAL(IndexDeProjection,premier_element_d_un_fichier);
Repe(ExposantMaximaldeLaBase)
Bblock
DEFV(Float,INIT(CoordonneeCourante,ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection)));
Test(IL_FAUT(projeter_les_sommets))
Bblock
INCR(coordonnee_X,MUL2(ELEMENT_DU_FICHIER_LISTE_PX(IndexDeProjection),CoordonneeCourante));
INCR(coordonnee_Y,MUL2(ELEMENT_DU_FICHIER_LISTE_PY(IndexDeProjection),CoordonneeCourante));
INCR(coordonnee_Z,MUL2(ELEMENT_DU_FICHIER_LISTE_PZ(IndexDeProjection),CoordonneeCourante));
Eblock
ATes
Bblock
CAL2(Prin1("%d ",INTE(CoordonneeCourante)));
Eblock
ETes
INCR(IndexDeProjection,I);
Eblock
ERep
Test(IL_FAUT(projeter_les_sommets))
Bblock
CAL2(Prin3("%+.^^^ %+.^^^ %+.^^^ ",coordonnee_X,coordonnee_Y,coordonnee_Z));
Eblock
ATes
Bblock
Eblock
ETes
lGENERATION_D_UN_FICHIER(liste_des_COORDONNEES,FLOT__UNDEF);
RETU_VIDE;
Eblock
EFonctionV
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D ' U N H Y P E R C U B E D E D I M E N S I O N Q U E L C O N Q U E : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
#include xrv/ARITHMET.22.I"
DEFV(Int,INIT(dimension_de_l_hyper_cube,DIMENSION_DE_L_HYPER_CUBE));
/* Dimension de l'hypercube. */
DEFV(Logical,INIT(editer_le_separateur_des_sommets,EDITER_LE_SEPARATEUR_DES_SOMMETS));
/* Doit-on editer le separateur "--o-->" ('VRAI') ou pas ('FAUX') ? */
/*..............................................................................................................................*/
GET_ARGUMENTSi(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_PX="
,fichier_LISTE_PX
,liste_initiale_des_PX
,PX_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_PY="
,fichier_LISTE_PY
,liste_initiale_des_PY
,PY_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_PZ="
,fichier_LISTE_PZ
,liste_initiale_des_PZ
,PZ_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_HP="
,fichier_LISTE_HP
,liste_initiale_des_HP
,HP_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_HO="
,fichier_LISTE_HO
,liste_initiale_des_HO
,HO_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
GET_ARGUMENT_I("dimension=""d=",dimension_de_l_hyper_cube);
GET_ARGUMENT_L("separateur_sommets=""separateur=""sep=",editer_le_separateur_des_sommets);
GET_ARGUMENT_L("projeter=""proj=",projeter_les_sommets);
GET_ARGUMENT_L("ProjectionParallele=""pparallele=""ppar=",faire_de_l_hyper_projection_parallele);
GET_ARGUMENT_N("ProjectionPerspective=""pperspective=""pper=",faire_de_l_hyper_projection_parallele);
)
);
EGAL(NombreDeSommets,INTE(PUIX(FLOT(BASE),FLOT(dimension_de_l_hyper_cube))));
Test(IFET(IFEQ(dimension_de_l_hyper_cube,DIMENSION_DE_L_HYPER_CUBE)
,IL_NE_FAUT_PAS(faire_de_l_hyper_projection_parallele)
)
)
Bblock
PRINT_ERREUR("L'hyper-projection perspective en dimension 3 est inhibee puisqu'elle cree un objet plat.");
/* Cela s'et vu le 20230308153642 avec 'v $xiirs/HYPC.21.3' en faisant une rotation */
/* autour de l'axe 'OY' d'environ '$pis2'... */
EGAL(faire_de_l_hyper_projection_parallele,VRAI);
Eblock
ATes
Bblock
Eblock
ETes
Test(IL_FAUT(projeter_les_sommets))
Bblock
Test(IFNE(nombre_d_elements,dimension_de_l_hyper_cube))
Bblock
PRINT_ERREUR("Les fichiers n'ont pas une taille compatible avec la dimension de l'hypercube");
CAL1(Prer2("La taille vaut %d alors qu'elle devrait valoir %d.\n"
,nombre_d_elements
,dimension_de_l_hyper_cube
)
);
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
begin_nouveau_block
Bblock
DEFV(Int,INIT(nombre1,UNDEF));
DEFV(Int,INIT(nombre2,UNDEF));
DoIn(nombre1,ZERO,PRED(NombreDeSommets),I)
/* Generation de la liste de toutes les configurations de "0" et de "1" entre zero et deux */
/* a la puissance 'dimension' moins 1... Il suffit pour cela d'enumerer tous les entiers... */
Bblock
DoIn(nombre2,ZERO,PRED(nombre1),I)
Bblock
DEFV(Float,INIT(logarithme,LObX(FLOT(OUEX(nombre1,nombre2)),FLOT(BASE))));
/* Une arete de l'hypercube est defini par deux entiers 'nombre1' et 'nombre2' qui ne */
/* different que d'un seul bit. Pour verifier cela il suffit de calculer le ou "exclusif" */
/* de ces deux nombres. S'il ne contient qu'un bit a 1, c'est une puissance de 2 et alors */
/* son logarithme en base 2 est un nombre entier... */
Test(EST_ENTIER(logarithme))
/* Cas ou on a trouve une artede l'hypercube : */
Bblock
ConversionBase(MIN2(nombre1,nombre2),BASE,dimension_de_l_hyper_cube);
Test(IL_FAUT(editer_le_separateur_des_sommets))
Bblock
CAL2(Prin0(" --o--> "));
Eblock
ATes
Bblock
Eblock
ETes
ConversionBase(MAX2(nombre1,nombre2),BASE,dimension_de_l_hyper_cube);
CALS(Fsauts_de_lignes(UN));
Eblock
ATes
Bblock
Eblock
ETes
Eblock
EDoI
Eblock
EDoI
Eblock
end_nouveau_block
RETU_Commande;
Eblock
ECommande