/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        F A C T O R I S A T I O N   D ' U N E   D I M E N S I O N   D ' I M A G E  :                                               */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Definition :                                                                                                               */
/*                                                                                                                                   */
/*                    Cette commande (inspiree du programme                                                                          */
/*                  'v $xtc/f_tailleI.02$c') factorise, lorsque                                                                      */
/*                  cela est possible, un nombre entier en deux                                                                      */
/*                  facteurs...                                                                                                      */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xcg/dimX_dimY$vv$K' :                                                                                          */
/*                                                                                                                                   */
/*                    Jean-Francois COLONNA (LACTAMME, 20090504090957).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        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_MINI

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        P A R A M E T R E S  :                                                                                                     */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   DIMENSION_A_FACTORISER                                                                                                        \
                    MILLION                                                                                                             \
                                        /* Dimension a factoriser en 'dimX.dimY'.                                                    */

#define   FACTEUR_DE_BALAYAGE                                                                                                           \
                    GRO3(FRA2(FU))                                                                                                      \
                                        /* Facteur dans permettant de calculer {dim?min,dim?max}.                                    */
#define   RAPPORT_dimensionX_SUR_dimensionY_OPTIMAL                                                                                     \
                    GRO3(FRA2(FU))                                                                                                      \
                                        /* Valeur optimale de 'dimX/dimY' resultat de la factorisation.                              */

#define   EDITER_TOUS_LES_COUPLES_TROUVES_ET_D_AUTRES_INFORMATIONS                                                                      \
                    FAUX                                                                                                                \
                                        /* Faut-il ('VRAI') ou pas ('FAUX') editer tous les couples {dimX,dimY} trouves plus         */ \
                                        /* d'autres choses introduites le 20090504173827...                                          */
#define   SIMPLIFIER_L_EDITION_DU_COUPLE_OPTIMAL                                                                                        \
                    VRAI                                                                                                                \
                                        /* Faut-il ('VRAI') ou pas ('FAUX') simplifier l'edition du couple {dimX,dimY} optimal ?     */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M A C R O S   U T I L E S  :                                                                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        F A C T O R I S A T I O N   D ' U N E   D I M E N S I O N   D ' I M A G E  :                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
     DEFV(Int,INIT(dimension_a_factoriser,DIMENSION_A_FACTORISER));
                                        /* Dimension a factoriser en 'dimX.dimY'. On notera que celle-ci ne peut pas etre un         */
                                        /* 'Positive' a cause d'une part du 'GET_ARGUMENT_I(...)' dont elle fait l'objet (on         */
                                        /* pourrait introduire une valeur negative...) et d'autre part du test 'Test(IZGT(...))'     */
                                        /* ci-apres qui ne detecterait alors que les valeurs nulles...                               */

     DEFV(Float,INIT(facteur_de_balayage,FACTEUR_DE_BALAYAGE));
                                        /* Facteur dans [permettant de calculer {dim?min,dim?max}.                                   */
     DEFV(Float,INIT(rapport_dimensionX_sur_dimensionY_optimal,RAPPORT_dimensionX_SUR_dimensionY_OPTIMAL));
                                        /* Valeur optimale de 'dimX/dimY' resultat de la factorisation.                              */

     DEFV(Logical,INIT(editer_tous_les_couples_trouves_et_d_autres_informations
                      ,EDITER_TOUS_LES_COUPLES_TROUVES_ET_D_AUTRES_INFORMATIONS
                       )
          );
                                        /* Faut-il ('VRAI') ou pas ('FAUX') editer tous les couples {dimX,dimY} trouves plus         */
                                        /* d'autres choses introduites le 20090504173827...                                          */
     DEFV(Logical,INIT(simplifier_l_edition_du_couple_optimal,SIMPLIFIER_L_EDITION_DU_COUPLE_OPTIMAL));
                                        /* Faut-il ('VRAI') ou pas ('FAUX') simplifier l'edition du couple {dimX,dimY} optimal ?     */
     /*..............................................................................................................................*/
     GET_ARGUMENTS_(nombre_d_arguments
                   ,BLOC(GET_ARGUMENT_I("dimension=""d=""dXdY=""XY=",dimension_a_factoriser);

                         GET_ARGUMENT_F("facteur_balayage=""facteur=""f=",facteur_de_balayage);
                         GET_ARGUMENT_F("rapport_dimensionXsY=""rapport=""r=""dXsdY=",rapport_dimensionX_sur_dimensionY_optimal);

                         GET_ARGUMENT_L("tout_editer=""editer=""e=",editer_tous_les_couples_trouves_et_d_autres_informations);
                         GET_ARGUMENT_L("simplifier=""s=",simplifier_l_edition_du_couple_optimal);
                         )
                    );

     Test(IZGT(dimension_a_factoriser))
          Bblock
          DEFV(Logical,INIT(la_factorisation_est_possible,FAUX));
                                        /* A priori, la factorisation est impossible...                                              */
          DEFV(Float,INIT(valeur_moyenne_de_dimensionX_et_de_dimensionY,FLOT__UNDEF));
          DEFV(Int,INIT(valeur_inferieure_de_dimensionX_et_de_dimensionY,UNDEF));
          DEFV(Int,INIT(valeur_superieure_de_dimensionX_et_de_dimensionY,UNDEF));
                                        /* Afin de definir les intervalles de balayage de 'dimX' et de 'dimY'.                       */
          DEFV(Int,INIT(dimensionX,UNDEF));
          DEFV(Int,INIT(dimensionY,UNDEF));
                                        /* Facteurs courants de 'dimension_a_factoriser'.                                            */
          DEFV(Int,INIT(meilleure_dimensionX,UNDEF));
          DEFV(Int,INIT(meilleure_dimensionY,UNDEF));
          DEFV(Float,INIT(minimum_de_dimensionX_sur_dimensionY_relatif,F_INFINI));
                                        /* Meilleur couple {dimX,dimY} factorisant 'dimension_a_factoriser' et "outil" permettant    */
                                        /* de le determiner...                                                                       */

          EGAL(valeur_moyenne_de_dimensionX_et_de_dimensionY
              ,RACX(dimension_a_factoriser)
               );

          Test(IFEXof(facteur_de_balayage,FZERO,valeur_moyenne_de_dimensionX_et_de_dimensionY))
                                        /* Validation introduite le 20090504173827...                                                */
               Bblock
               PRINT_ERREUR("le facteur de balayage est incorrect");
               CAL1(Prer2("(il vaut %f et n'est donc pas dans ]0,%f])\n"
                         ,facteur_de_balayage
                         ,valeur_moyenne_de_dimensionX_et_de_dimensionY
                          )
                    );
               Eblock
          ATes
               Bblock
               EGAL(valeur_inferieure_de_dimensionX_et_de_dimensionY
                   ,INTE(DIVI(FLOT(valeur_moyenne_de_dimensionX_et_de_dimensionY),facteur_de_balayage))
                    );
               EGAL(valeur_superieure_de_dimensionX_et_de_dimensionY
                   ,INTE(MUL2(FLOT(valeur_moyenne_de_dimensionX_et_de_dimensionY),facteur_de_balayage))
                    );
                                        /* Definition des intervalles de balayage de 'dimX' et de 'dimY'.                            */
                                        /*                                                                                           */
                                        /* On notera les valeurs extremales du facteur 'f' ('facteur_de_balayage') :                 */
                                        /*                                                                                           */
                                        /*                  f=0  ==>  dim? E [m,m]                  ([inf,sup]=[m,m])                */
                                        /*                  f=m  ==>  dim? E [1,d]                  ([inf,sup]=[1,d])                */
                                        /*                                                                                           */
                                        /* ou 'm' et 'd' designent respectivement 'valeur_moyenne_de_dimensionX_et_de_dimensionY'    */
                                        /* et 'dimension_a_factoriser', en rappelant que :                                           */
                                        /*                                                                                           */
                                        /*                        2                                                                  */
                                        /*                  d  = m                                                                   */
                                        /*                                                                                           */
                                        /* On peut ainsi (pour 'f=m') balayer tous le segment [1,d], mais au prix d'un temps         */
                                        /* de calcul en general redhibitoire...                                                      */
                                        /*                                                                                           */
                                        /* On notera de plus que ('inf' et 'sup' etant respectivement les 'valeur_inferieure_...'    */
                                        /* et les 'valeur_superieure_' calculees ci-dessus) :                                        */
                                        /*                                                                                           */
                                        /*                         m                                                                 */
                                        /*                  inf = ---                                                                */
                                        /*                         f                                                                 */
                                        /*                                                                                           */
                                        /* et que :                                                                                  */
                                        /*                                                                                           */
                                        /*                  sup = m.f                                                                */
                                        /*                                                                                           */
                                        /* donc :                                                                                    */
                                        /*                                                                                           */
                                        /*                             2                                                             */
                                        /*                  inf.sup = m  = d                                                         */
                                        /*                                                                                           */
                                        /* Ainsi, 'm' est la moyenne geometrique 'MOYG(...)' de 'inf' et 'sup'.                      */

               Test(IL_FAUT(editer_tous_les_couples_trouves_et_d_autres_informations))
                    Bblock
                    CAL2(Prin3("Segment de recherche pour les dimensions en 'X' et en 'Y' : [%d,%d] 'centre' en %d\n"
                              ,valeur_inferieure_de_dimensionX_et_de_dimensionY
                              ,valeur_superieure_de_dimensionX_et_de_dimensionY
                              ,INTE(valeur_moyenne_de_dimensionX_et_de_dimensionY)
                               )
                         );
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes

               DoIn(dimensionY
                   ,valeur_inferieure_de_dimensionX_et_de_dimensionY
                   ,valeur_superieure_de_dimensionX_et_de_dimensionY
                   ,I
                    )
                                        /* L'ordre de balayage ('dimY' a l'exterieur et 'dimX' a l'interieur) est le meme que celui  */
                                        /* de 'v $xiii/begin_end$DEF Gbegin_imageQ', mais cela est arbitraire et le resultat final   */
                                        /* ne depend evidemment pas de lui...                                                        */
                    Bblock
                    DoIn(dimensionX
                        ,valeur_inferieure_de_dimensionX_et_de_dimensionY
                        ,valeur_superieure_de_dimensionX_et_de_dimensionY
                        ,I
                         )
                         Bblock
                         Test(IFEQ(MUL2(FLOT(dimensionX),FLOT(dimensionY)),FLOT(dimension_a_factoriser)))
                                        /* L'introduction des 'FLOT(...)'s le 20090504113818 est destine a eviter des debordements   */
                                        /* dans le produit de 'dimensionX' par 'dimensionY' qui peuvent apparaitre des que le        */
                                        /* facteur 'facteur_de_balayage' est un peu grand. Cela s'est vu a cette date avec :         */
                                        /*                                                                                           */
                                        /*                  facteur_de_balayage         = 28                                         */
                                        /*                  dimension_a_factoriser      = 12345678                                   */
                                        /*                                                                                           */
                                        /* la valeur de 'valeur_superieure_de_dimensionX_et_de_dimensionY' etant alors 98364, dont   */
                                        /* le carre 9675476496 deborde, ce qui est donc aussi le cas de nombreux produits de         */
                                        /* 'dimensionX' par 'dimensionY' dans les deux boucles 'DoIn(...)'s ci-dessus...             */
                              Bblock
                              DEFV(Float,INIT(dimensionX_sur_dimensionY,DIVI(FLOT(dimensionX),FLOT(dimensionY))));
                              DEFV(Float,INIT(dimensionX_sur_dimensionY_relatif,FLOT__UNDEF));

                              EGAL(la_factorisation_est_possible,VRAI);
                                        /* On a trouve au moins une factorisation...                                                 */

                              Test(IL_FAUT(editer_tous_les_couples_trouves_et_d_autres_informations))
                                   Bblock
                                   CAL2(Prin6("Factorisation : %d=%dx%d (%d/%d=%f)\n"
                                             ,dimension_a_factoriser
                                             ,dimensionX
                                             ,dimensionY
                                             ,dimensionX
                                             ,dimensionY
                                             ,dimensionX_sur_dimensionY
                                              )
                                        );
                                        /* Malheureusement bien souvent la factorisation d'une "dimension" n'est pas unique.         */
                                        /* C'est ainsi le cas en format 'Pal' qui donne alors :                                      */
                                        /*                                                                                           */
                                        /*                  dimX=975  dimY=460                                                       */
                                        /*                  dimX=897  dimY=500                                                       */
                                        /*                  dimX=780  dimY=575                                                       */
                                        /*                  dimX=750  dimY=598                                                       */
                                        /*                  dimX=690  dimY=650                                                       */
                                        /*                  dimX=650  dimY=690                                                       */
                                        /*                  dimX=598  dimY=750                                                       */
                                        /*                  dimX=575  dimY=780                                                       */
                                        /*                  dimX=500  dimY=897                                                       */
                                        /*                  dimX=975  dimY=460                                                       */
                                        /*                                                                                           */
                                        /* pour 'facteur_de_balayage=1.5'.                                                           */
                                        /*                                                                                           */
                                        /* Cela rend ce processus non utilisable lors du redimensionnement automatique des images    */
                                        /* dans 'v $xiii/files$FON CHoi.taille_de_imageR.' lorsqu'aucun des formats de base des      */
                                        /* images n'a ete reconnu...                                                                 */
                                        /*                                                                                           */
                                        /* Cela est vrai aussi de formats plus "exotiques". Ainsi '999x999' donne :                  */
                                        /*                                                                                           */
                                        /*                  dimX=1369 dimY=729                                                       */
                                        /*                  dimX=999  dimY=999                                                       */
                                        /*                  dimX=729  dimY=1369                                                      */
                                        /*                                                                                           */
                                        /* alors que '1000x1000' donne :                                                             */
                                        /*                                                                                           */
                                        /*                  dimX=1250 dimY=800                                                       */
                                        /*                  dimX=1000 dimY=1000                                                      */
                                        /*                  dimX=800  dimY=1250                                                      */
                                        /*                                                                                           */
                                        /* Il y a donc en general ambiguite...                                                       */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes

                              EGAL(dimensionX_sur_dimensionY_relatif
                                  ,ABSO(SOUS(dimensionX_sur_dimensionY,rapport_dimensionX_sur_dimensionY_optimal))
                                   );

                              Test(IFLT(dimensionX_sur_dimensionY_relatif,minimum_de_dimensionX_sur_dimensionY_relatif));
                                   Bblock
                                   EGAL(meilleure_dimensionX,dimensionX);
                                   EGAL(meilleure_dimensionY,dimensionY);

                                   EGAL(minimum_de_dimensionX_sur_dimensionY_relatif,dimensionX_sur_dimensionY_relatif);
                                        /* Un couple {dimX,dimY} dont le rapport est plus proche de l'optimal vient d'etre trouve.   */
                                        /* On le memorise donc...                                                                    */
                                   Eblock
                              ATes
                                   Bblock
                                   Eblock
                              ETes
                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes
                         Eblock
                    EDoI
                    Eblock
               EDoI

               Test(EST_VRAI(la_factorisation_est_possible))
                    Bblock
                    Test(IFET(IL_FAUT(simplifier_l_edition_du_couple_optimal)
                             ,IL_NE_FAUT_PAS(editer_tous_les_couples_trouves_et_d_autres_informations)
                              )
                         )
                         Bblock
                         CAL2(Prin2("%d %d\n",meilleure_dimensionX,meilleure_dimensionY));
                         Eblock
                    ATes
                         Bblock
                         CAL2(Prin5("La meilleure factorisation est : %d=%dx%d (de rapport egal a %f, proche de %f).\n"
                                   ,dimension_a_factoriser
                                   ,meilleure_dimensionX,meilleure_dimensionY
                                   ,DIVI(FLOT(meilleure_dimensionX),FLOT(meilleure_dimensionY))
                                   ,rapport_dimensionX_sur_dimensionY_optimal
                                    )
                              );
                         Eblock
                    ETes
                    Eblock
               ATes
                    Bblock
                    CAL2(Prin1("La factorisation de %d est impossible.\n",dimension_a_factoriser));
                    Eblock
               ETes
               Eblock
          ETes
          Eblock
     ATes
          Bblock
          PRINT_ERREUR("la dimension a factoriser est negative ou nulle");
          Eblock
     ETes

     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.