Logo Search packages:      
Sourcecode: ecs version File versions  Download package

ecs_vec_int.c

/*============================================================================
 *  Définitions des fonctions de base
 *   associées à la structure `ecs_vec_int_t' décrivant un vecteur indexé entier
 *============================================================================*/

/*
  This file is part of the Code_Saturne Preprocessor, element of the
  Code_Saturne CFD tool.

  Copyright (C) 1999-2007 EDF S.A., France

  contact: saturne-support@edf.fr

  The Code_Saturne Preprocessor is free software; you can redistribute it
  and/or modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2 of
  the License, or (at your option) any later version.

  The Code_Saturne Preprocessor is distributed in the hope that it will be
  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with the Code_Saturne Preprocessor; if not, write to the
  Free Software Foundation, Inc.,
  51 Franklin St, Fifth Floor,
  Boston, MA  02110-1301  USA
*/


/*============================================================================
 *                                 Visibilité
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Fichiers `include' librairie standard C ou BFT
 *----------------------------------------------------------------------------*/

#include <assert.h>
#include <stdlib.h>

#include <bft_mem.h>


/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles du  paquetage global "Utilitaire"
 *----------------------------------------------------------------------------*/

#include "ecs_chrono.h"

#include "ecs_def.h"

#include "ecs_elt_typ_liste.h"


/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles des paquetages visibles
 *----------------------------------------------------------------------------*/



/*----------------------------------------------------------------------------
 *  Fichiers `include' visibles du  paquetage courant
 *----------------------------------------------------------------------------*/

#include "ecs_vec_int_tri.h"


/*----------------------------------------------------------------------------
 *  Fichier  `include' du  paquetage courant associé au fichier courant
 *----------------------------------------------------------------------------*/

#include "ecs_vec_int.h"


/*----------------------------------------------------------------------------
 *  Fichiers `include' privés   du  paquetage courant
 *----------------------------------------------------------------------------*/

#include "ecs_vec_int_priv.h"


/*============================================================================
 *                       Prototypes de fonctions privées
 *============================================================================*/


/*----------------------------------------------------------------------------
 *  Fonction qui détermine pour chaque sous-élément,
 *   le nombre d'éléments dont le sous-élément participe à la définition
 *   dans une connectivité "élément -> sous-élément"
 *----------------------------------------------------------------------------*/

static void ecs_loc_vec_int__compte_elt
(
 const ecs_vec_int_t  *const vec_def_elt       ,
       int            *const sselt_cpt_def_elt ,
       size_t                nbr_sselt
) ;


/*----------------------------------------------------------------------------
 *  Fonction qui détermine le nombre de valeurs associées
 *   à chaque sous-élément participant à la définition d'éléments
 *   dans une connectivité "élément -> sous-élément"
 *----------------------------------------------------------------------------*/

static ecs_int_t ecs_loc_vec_int__compte_val
(
 const ecs_vec_int_t *const vec_elt_def_sselt   ,
 const ecs_vec_int_t *const vec_val_elt         ,
       int           *const liste_nbr_val_sselt ,
       size_t               nbr_sselt
) ;


/*----------------------------------------------------------------------------
 *    Fonction de descente d'un arbre binaire pour le tri sur place
 *  d'un tableau d'entiers.
 *----------------------------------------------------------------------------*/

static void ecs_loc_vec_int__desc_arbre_val
(
       ecs_int_t  ltree     ,     /* --> Niveau arbre binaire à descendre     */
 const ecs_int_t  ntree     ,     /* --> Taille arbre binaire à descendre     */
       ecs_int_t  elem_ord[]      /* <-> Liste à trier éléments considérés    */
) ;


/*----------------------------------------------------------------------------
 *  Fonction qui réalise un tri sur les valeurs d'un vecteur indexé
 *   entre 2 positions
 *----------------------------------------------------------------------------*/

static ecs_vec_int_t * ecs_loc_vec_int__trie_val_pos
(
 const ecs_vec_int_t *const this_vec_int   /* --> Structure avec déf. à trier */
) ;


/*============================================================================
 *                             Fonctions publiques
 *============================================================================*/

/*----------------------------------------------------------------------------
 *  Fonction allouant et initialisant une structure `ecs_vec_int_t'
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__cree
(                      /* <-- Pointeur sur une structure `ecs_vec_int_t'      */
 void
)
{

  ecs_vec_int_t *this_vec_int ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  BFT_MALLOC(this_vec_int, 1, ecs_vec_int_t) ;


  /* Initialisation de la structure de type `ecs_vec_int_t' */

  this_vec_int->pos_nbr = 0 ;

  this_vec_int->pos_tab = NULL ;

  this_vec_int->val_tab = NULL ;


  return this_vec_int ;


}


/*----------------------------------------------------------------------------
 *  Fonction libérant une structure `ecs_vec_int_t' donnée en argument.
 *  Elle renvoie un pointeur NULL
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__detruit
(
 ecs_vec_int_t * this_vec_int
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_vec_int != NULL) ;


  /* Libération du contenu de la structure `ecs_vec_int_t' */
  /*===================================================*/


  assert(this_vec_int->pos_nbr != 0) ;


  /* Libération du tableau des valeurs */
  /*-----------------------------------*/

  if (this_vec_int->val_tab != NULL)

    BFT_FREE(this_vec_int->val_tab) ;


  /* Libération du tableau des positions */
  /*-------------------------------------*/

  if (this_vec_int->pos_tab != NULL) {

    BFT_FREE(this_vec_int->pos_tab) ;

  }


  /* Libération de la structure `ecs_vec_int_t' */
  /*======================================*/

  BFT_FREE(this_vec_int) ;


  return this_vec_int ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui alloue une structure `ecs_vec_int_t' ainsi que ses membres
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__alloue
(                    /* <-- Renvoie la référence à la structure créée         */
 size_t      pos_nbr , /* --> Nombre de positions pour  tableau des positions */
 size_t      val_nbr   /* --> Nombre de valeurs   pour  tableau des valeurs   */
)
{

  ecs_vec_int_t *this_vec_int ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Allocation de la structure elle-même */

  this_vec_int = ecs_vec_int__cree() ;


  /* Allocation de ses membres */


  if (pos_nbr != 0) {

    this_vec_int->pos_nbr = pos_nbr ;

    BFT_MALLOC(this_vec_int->pos_tab, pos_nbr, ecs_size_t);

  }
  else {

    /* this_vec_int->pos_tab == NULL grâce à ecs_vec_int__cree() */

    this_vec_int->pos_nbr = val_nbr + 1 ;

  }


  BFT_MALLOC(this_vec_int->val_tab, val_nbr, ecs_int_t);


  return this_vec_int ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui redimensionne les membres d'une structure `ecs_vec_int_t'
 *----------------------------------------------------------------------------*/

void ecs_vec_int__redimensionne
(
 ecs_vec_int_t  *const this_vec_int ,
 size_t                pos_nbr , /* --> Nouvelle dim. du tableau des pos.     */
 size_t                val_nbr   /* --> Nouvelle dim. du tableau des val. x   */
)
{
  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Réallocation des membres */

  if (pos_nbr != 0)
    this_vec_int->pos_nbr = pos_nbr ;
  else
    this_vec_int->pos_nbr = val_nbr + 1 ;

  BFT_REALLOC(this_vec_int->pos_tab, pos_nbr, ecs_size_t);
  BFT_REALLOC(this_vec_int->val_tab, val_nbr, ecs_int_t);

}


/*----------------------------------------------------------------------------
 *  Fonction libérant une structure `ecs_vec_int_t'
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__libere
(                               /* <-- Renvoie un pointeur NULL               */
 ecs_vec_int_t  *this_vec_int   /* <-> Structure `ecs_vec_int_t' à liberer    */
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_vec_int != NULL) ;


  /* Libération de la structure `ecs_vec_int_t' */
  /*======================================*/

  BFT_FREE(this_vec_int) ;


  return this_vec_int ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui crée un vecteur `ecs_vec_int_t'
 *   et qui l'initialise avec les références données
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__initialise
(
 size_t      pos_nbr ,
 ecs_size_t *pos_tab ,
 ecs_int_t  *val_tab
)
{

  ecs_vec_int_t *this_vec_int ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(pos_nbr != 0) ;


  /* Création de la structure de type `ecs_vec_int_t' */

  this_vec_int = ecs_vec_int__cree() ;


  /* Initialisation de la structure de type `ecs_vec_int_t' */

  this_vec_int->pos_nbr = pos_nbr ;

  this_vec_int->pos_tab = pos_tab ;

  this_vec_int->val_tab = val_tab ;


  return this_vec_int ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui créé une structure `ecs_vec_int_t'
 *   à partir d'un tableau bi-dimensionnel `tab_elt' contenant
 *   pour chaque élément un ensemble de valeurs
 *  Si un élément `ielt' n'a pas de valeur associée, `tab_elt[ielt].nbr = 0'
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__transforme_bi_tab
(
 const ecs_tab_int_t  *const tab_elt ,
       size_t                nbr_elt ,
       size_t                nbr_val
)
{

  size_t        cpt_val ;
  size_t        ielt ;
  size_t        ival ;

  ecs_vec_int_t * this_vec_int ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(tab_elt != NULL) ;


  /* Construction des tableaux de positions et de valeurs */
  /*------------------------------------------------------*/


  this_vec_int = ecs_vec_int__alloue(nbr_elt + 1,
                                     nbr_val) ;

  this_vec_int->pos_tab[0] = 1 ;
  cpt_val = 0 ;

  for (ielt = 0 ; ielt < nbr_elt ; ielt++) {

    if (tab_elt[ielt].nbr != 0) {

      this_vec_int->pos_tab[ielt + 1]
        = this_vec_int->pos_tab[ielt] + tab_elt[ielt].nbr ;

      for (ival = 0 ; ival < tab_elt[ielt].nbr ; ival++)
        this_vec_int->val_tab[cpt_val++] = tab_elt[ielt].val[ival] ;

    }
    else {

      this_vec_int->pos_tab[ielt + 1]  = this_vec_int->pos_tab[ielt] ;

    }

  }


  return this_vec_int ;


}


/*----------------------------------------------------------------------------
 *  Fonction retournant le nombre de positions
 *----------------------------------------------------------------------------*/

size_t ecs_vec_int__ret_pos_nbr
(
 const ecs_vec_int_t *const this_vec_int
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_vec_int != NULL) ;


  return this_vec_int->pos_nbr ;


}


/*----------------------------------------------------------------------------
 *  Fonction retournant le nombre de valeurs associées au tableau des positions
 *----------------------------------------------------------------------------*/

size_t ecs_vec_int__ret_val_nbr
(
 const ecs_vec_int_t *const this_vec_int
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_vec_int != NULL) ;


  if (this_vec_int->pos_tab != NULL) {

    return this_vec_int->pos_tab[this_vec_int->pos_nbr - 1] - 1 ;

  }
  else {

    return this_vec_int->pos_nbr - 1 ;

  }


}

/*----------------------------------------------------------------------------
 *  Fonction retournant la référence du tableau des positions
 *----------------------------------------------------------------------------*/

ecs_size_t * ecs_vec_int__ret_pos_tab
(
 ecs_vec_int_t *this_vec_int
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_vec_int != NULL) ;


  return this_vec_int->pos_tab ;


}


/*----------------------------------------------------------------------------
 *  Fonction retournant la référence du tableau des valeurs
 *----------------------------------------------------------------------------*/

ecs_int_t * ecs_vec_int__ret_val_tab
(
 ecs_vec_int_t *this_vec_int
)
{

  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(this_vec_int != NULL) ;


  return this_vec_int->val_tab ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui retourne le tableau des valeurs du vecteur indexé donné,
 *   dimensionné au nombre de valeurs distinctes du vecteur indexé,
 *   (valeurs qui correspondent à des références)
 *----------------------------------------------------------------------------*/

ecs_tab_int_t ecs_vec_int__ret_reference
(
 ecs_vec_int_t     *const this_vec_int
)
{

  size_t        cpt_ref ;
  size_t        nbr_ref ;
  ecs_int_t     ind_ref ;
  size_t        iref ;
  size_t        ipos ;
  size_t        ival ;
  size_t        nbr_val_pos ;
  size_t        pos_val_inf ;
  ecs_int_t   * liste_ref ;
  ecs_tab_int_t   tab_ref ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /* Dimensionnement a priori de le liste des références */

  nbr_ref = 10 ;
  BFT_MALLOC(liste_ref, nbr_ref, ecs_int_t) ;
  for (iref = 0 ; iref < nbr_ref ; iref++)
    liste_ref[iref] = ECS_FALSE ;


  for (ipos = 0 ; ipos < this_vec_int->pos_nbr - 1 ; ipos++) {

    pos_val_inf = this_vec_int->pos_tab[ipos    ] - 1 ;
    nbr_val_pos = this_vec_int->pos_tab[ipos + 1] - 1 - pos_val_inf ;


    for (ival = 0 ; ival < nbr_val_pos ; ival++) {

      ind_ref = this_vec_int->val_tab[pos_val_inf + ival] - 1 ;

      /* Re-dimensionnement si nécessaire de la liste des références */

      if (ind_ref >= (ecs_int_t)nbr_ref) {
        BFT_REALLOC(liste_ref, ind_ref * 2, ecs_int_t) ;
        for (iref = nbr_ref ; iref < (size_t)ind_ref*2 ; iref++)
          liste_ref[iref] = ECS_FALSE ;
        nbr_ref = ind_ref * 2 ;
      }

      if (ind_ref > -1)
        liste_ref[ind_ref] = ECS_TRUE ;

    }

  }

  BFT_MALLOC(tab_ref.val, nbr_ref, ecs_int_t) ;

  cpt_ref = 0 ;

  for (iref = 0 ; iref < nbr_ref ; iref++) {

    if (liste_ref[iref] == ECS_TRUE) {

      tab_ref.val[cpt_ref++] = iref + 1 ;

    }

  }

  BFT_FREE(liste_ref) ;

  if (cpt_ref != 0)
    BFT_REALLOC(tab_ref.val, cpt_ref, ecs_int_t) ;
  else
    BFT_FREE(tab_ref.val) ;
  tab_ref.nbr = cpt_ref ;


  return tab_ref ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui incrémente les valeurs d'un vecteur indexé donné
 *   d'une constante donnée
 *----------------------------------------------------------------------------*/

void ecs_vec_int__incremente_val
(
       ecs_vec_int_t  *const this_vec_int ,
 const ecs_int_t             increment
)
{

  size_t  nbr_val ;
  size_t  ival ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_val = ecs_vec_int__ret_val_nbr(this_vec_int) ;


  for (ival = 0 ; ival < nbr_val ; ival++)

    this_vec_int->val_tab[ival] += increment ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui incrémente les valeurs d'un vecteur indexé donné
 *   d'une constante donnée
 *----------------------------------------------------------------------------*/

void ecs_vec_int__incremente_val_sgn
(
       ecs_vec_int_t  *const this_vec_int ,
 const ecs_int_t             increment
)
{

  size_t     nbr_val ;
  size_t     ival ;
  ecs_int_t  signe_val ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_val = ecs_vec_int__ret_val_nbr(this_vec_int) ;


  for (ival = 0 ; ival < nbr_val ; ival++) {

    signe_val
      = this_vec_int->val_tab[ival]
      / ECS_ABS(this_vec_int->val_tab[ival]) ;

    this_vec_int->val_tab[ival]
      = (ECS_ABS(this_vec_int->val_tab[ival]) + increment) * signe_val ;

  }

}


/*----------------------------------------------------------------------------
 *  Fonction réalisant la transformation d'un vecteur indexé
 *   en appliquant directement le vecteur de transformation donné
 *   sur ses valeurs
 *
 *  Le nombre de valeurs transformées peut être inférieur
 *  au nombre de valeurs avant transformation
 *----------------------------------------------------------------------------*/

void ecs_vec_int__transforme_val
(
       ecs_vec_int_t  *const this_vec_int ,
       size_t                nbr_elt_new  ,
 const ecs_tab_int_t         vect_transf
)
{

  ecs_vec_int_t *vec_int_ref ;
  size_t       nbr_val_ref ;
  size_t       ival_ref ;
  size_t       ielt_new ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_val_ref = ecs_vec_int__ret_val_nbr(this_vec_int) ;

  vec_int_ref = ecs_vec_int__alloue(0,
                                    nbr_val_ref) ;

  for (ival_ref = 0 ; ival_ref < nbr_val_ref ; ival_ref++)
    vec_int_ref->val_tab[ival_ref] = this_vec_int->val_tab[ival_ref] ;


  BFT_REALLOC(this_vec_int->pos_tab, nbr_elt_new + 1, ecs_size_t) ;

  BFT_REALLOC(this_vec_int->val_tab, nbr_elt_new, ecs_int_t) ;


  this_vec_int->pos_nbr = nbr_elt_new + 1 ;


  this_vec_int->pos_tab[0] = 1 ;

  for (ielt_new = 0 ; ielt_new < nbr_elt_new ; ielt_new++) {

    this_vec_int->pos_tab[ielt_new + 1]
      = this_vec_int->pos_tab[ielt_new] + 1 ;

  }


  for (ival_ref = 0 ; ival_ref < nbr_val_ref ; ival_ref++) {

    this_vec_int->val_tab[vect_transf.val[ival_ref]]
      = vec_int_ref->val_tab[ival_ref] ;

  }


  ecs_vec_int__detruit(vec_int_ref) ;


}


/*----------------------------------------------------------------------------
 *  Fonction réalisant la transformation d'un vecteur indexé
 *   en appliquant directement le vecteur de transformation donné
 *   sur ses positions
 *
 *  Le nombre de valeurs transformées doit être égal
 *  au nombre de valeurs avant transformation
 *----------------------------------------------------------------------------*/

void ecs_vec_int__transforme_pos
(
       ecs_vec_int_t  *const this_vec_int ,
       size_t                nbr_elt_ref  ,
 const ecs_tab_int_t         vect_transf
)
{

  ecs_vec_int_t *vec_int_ref ;
  size_t       nbr_val_ref ;
  ecs_int_t    ival ;
  size_t       ielt_ref ;
  size_t       ielt_transf ;
  size_t       ival_ref ;
  ecs_int_t    elt_nbr_val ;
  ecs_int_t    pre_pos ;
  ecs_int_t    cpt_val ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vect_transf.nbr == nbr_elt_ref) ;
  assert(this_vec_int->pos_nbr - 1 == nbr_elt_ref) ;


  nbr_val_ref = ecs_vec_int__ret_val_nbr(this_vec_int) ;

  vec_int_ref = ecs_vec_int__alloue(nbr_elt_ref + 1,
                                    nbr_val_ref     ) ;

  for (ielt_ref = 0 ; ielt_ref < nbr_elt_ref + 1 ; ielt_ref++)
    vec_int_ref->pos_tab[ielt_ref] = this_vec_int->pos_tab[ielt_ref] ;

  for (ival_ref = 0 ; ival_ref < nbr_val_ref ; ival_ref++)
    vec_int_ref->val_tab[ival_ref] = this_vec_int->val_tab[ival_ref] ;


  this_vec_int->pos_tab[0] = 1 ;

  cpt_val = 0 ;


  for (ielt_transf = 0 ; ielt_transf < nbr_elt_ref ; ielt_transf++) {

    pre_pos = vec_int_ref->pos_tab[vect_transf.val[ielt_transf]] ;

    elt_nbr_val
      = vec_int_ref->pos_tab[vect_transf.val[ielt_transf] + 1] - pre_pos ;

    this_vec_int->pos_tab[ielt_transf + 1]
      = this_vec_int->pos_tab[ielt_transf] + elt_nbr_val ;

    for (ival = 0 ; ival < elt_nbr_val ; ival++) {

      this_vec_int->val_tab[cpt_val++]
        = vec_int_ref->val_tab[pre_pos - 1 + ival] ;

    }

  }


  ecs_vec_int__detruit(vec_int_ref) ;


}


/*----------------------------------------------------------------------------
 *  Fonction réalisant la transformation d'un vecteur indexé
 *   en appliquant directement le vecteur de transformation donné
 *   sur les valeurs associées à ses éléments
 *----------------------------------------------------------------------------*/

void ecs_vec_int__renumerote
(
       ecs_vec_int_t  *const this_vec_int ,
 const ecs_tab_int_t         vect_transf
)
{

  ecs_vec_int_t *vec_int_ref ;
  size_t       nbr_val_ref ;
  size_t       ival_ref ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_val_ref = ecs_vec_int__ret_val_nbr(this_vec_int) ;

  vec_int_ref = ecs_vec_int__alloue(0,
                                    nbr_val_ref) ;

  for (ival_ref = 0 ; ival_ref < nbr_val_ref ; ival_ref++)
    vec_int_ref->val_tab[ival_ref] = this_vec_int->val_tab[ival_ref] ;


  for (ival_ref = 0 ; ival_ref < nbr_val_ref ; ival_ref++) {

    this_vec_int->val_tab[ival_ref]
      = vect_transf.val[ECS_ABS(vec_int_ref->val_tab[ival_ref]) - 1] + 1 ;

  }


  ecs_vec_int__detruit(vec_int_ref) ;


}


/*----------------------------------------------------------------------------
 *  Fonction réalisant la transformation d'un vecteur indexé
 *   en appliquant directement le vecteur de transformation donné
 *   sur les valeurs associées à ses éléments
 *----------------------------------------------------------------------------*/

void ecs_vec_int__renumerote_et_sgn
(
       ecs_vec_int_t  *const this_vec_int ,
 const ecs_tab_int_t         vect_transf  ,
 const ecs_tab_int_t         signe_elt
)
{

  ecs_vec_int_t *vec_int_ref ;
  size_t       nbr_val_ref ;
  ecs_int_t    val_ref ;
  ecs_int_t    sgn_ref ;
  size_t       ival_ref ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_val_ref = ecs_vec_int__ret_val_nbr(this_vec_int) ;

  vec_int_ref = ecs_vec_int__alloue(0,
                                    nbr_val_ref) ;

  for (ival_ref = 0 ; ival_ref < nbr_val_ref ; ival_ref++)
    vec_int_ref->val_tab[ival_ref] = this_vec_int->val_tab[ival_ref] ;


  for (ival_ref = 0 ; ival_ref < nbr_val_ref ; ival_ref++) {

    val_ref = ECS_ABS(vec_int_ref->val_tab[ival_ref]) ;
    sgn_ref = vec_int_ref->val_tab[ival_ref] / val_ref ;

    this_vec_int->val_tab[ival_ref]  = vect_transf.val[val_ref - 1] + 1 ;

    this_vec_int->val_tab[ival_ref] *= signe_elt.val[val_ref - 1] * sgn_ref ;

  }


  ecs_vec_int__detruit(vec_int_ref) ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui remplace les références à des éléments
 *  en des références à d'autres éléments liés aux premiers
 *  par un vecteur indexé
 *----------------------------------------------------------------------------*/

void ecs_vec_int__remplace_ref
(
       ecs_vec_int_t  *const vec_rep ,
 const ecs_vec_int_t  *const vec_def
)
{

  ecs_vec_int_t * vec_rep_new ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  vec_rep_new = ecs_vec_int__ret_remplace_ref(vec_rep,
                                              vec_def) ;


  BFT_FREE(vec_rep->pos_tab) ;
  BFT_FREE(vec_rep->val_tab) ;


  vec_rep->pos_tab = vec_rep_new->pos_tab ;
  vec_rep->val_tab = vec_rep_new->val_tab ;


  ecs_vec_int__libere(vec_rep_new) ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui remplace les références à des éléments
 *  en des références à d'autres éléments liés aux premiers
 *  par un vecteur indexé ; les références à 0 sont ignorées
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__ret_remplace_ref
(
       ecs_vec_int_t  *const vec_rep ,
 const ecs_vec_int_t  *const vec_def
)
{

  ecs_vec_int_t * vec_rep_new ;

  ecs_int_t     cpt_val_rep ;
  ecs_int_t     ielt_rep ;
  ecs_int_t     ipos_def ;
  ecs_int_t     ipos_rep ;
  ecs_int_t     nbr_elt_rep ;
  ecs_int_t     nbr_pos_def ;
  ecs_int_t     nbr_val_rep_new ;
  ecs_int_t     num_val_def ;
  ecs_int_t     pos_deb_def ;
  ecs_int_t     pos_deb_rep ;
  ecs_int_t     pos_fin_def ;
  ecs_int_t     pos_fin_rep ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_elt_rep = vec_rep->pos_nbr - 1 ;


  /* Passage pour dimensionnement */


  cpt_val_rep = 0 ;
  nbr_val_rep_new = 0 ;


  for (ielt_rep = 0 ; ielt_rep < nbr_elt_rep ; ielt_rep++) {


    pos_deb_rep = vec_rep->pos_tab[ielt_rep]     - 1 ;
    pos_fin_rep = vec_rep->pos_tab[ielt_rep + 1] - 1 ;


    for (ipos_rep = pos_deb_rep ; ipos_rep < pos_fin_rep ; ipos_rep++) {

      num_val_def = ECS_ABS(vec_rep->val_tab[ipos_rep]) ;

      if (num_val_def != 0) {

        pos_deb_def = vec_def->pos_tab[num_val_def - 1] - 1 ;
        pos_fin_def = vec_def->pos_tab[num_val_def    ] - 1 ;

        nbr_pos_def = pos_fin_def - pos_deb_def ;

        nbr_val_rep_new = ECS_MAX(nbr_val_rep_new, cpt_val_rep + nbr_pos_def) ;

        cpt_val_rep += nbr_pos_def ;

      }

    }


  }


  /* Traitement effectif */

  vec_rep_new = ecs_vec_int__alloue(nbr_elt_rep + 1,
                                    nbr_val_rep_new) ;

  vec_rep_new->pos_tab[0] = 1 ;


  cpt_val_rep = 0 ;


  for (ielt_rep = 0 ; ielt_rep < nbr_elt_rep ; ielt_rep++) {


    pos_deb_rep = vec_rep->pos_tab[ielt_rep]     - 1 ;
    pos_fin_rep = vec_rep->pos_tab[ielt_rep + 1] - 1 ;


    for (ipos_rep = pos_deb_rep ; ipos_rep < pos_fin_rep ; ipos_rep++) {

      num_val_def = vec_rep->val_tab[ipos_rep] ;

      if (num_val_def > 0) {

        pos_deb_def = vec_def->pos_tab[num_val_def - 1] - 1 ;
        pos_fin_def = vec_def->pos_tab[num_val_def    ] - 1 ;

        nbr_pos_def = pos_fin_def - pos_deb_def ;

        for (ipos_def = 0 ; ipos_def < nbr_pos_def ; ipos_def++) {

          vec_rep_new->val_tab[cpt_val_rep + ipos_def]
            = vec_def->val_tab[pos_deb_def + ipos_def] ;

        }

      }
      else if (num_val_def < 0) {

        num_val_def = ECS_ABS(num_val_def) ;

        pos_deb_def = vec_def->pos_tab[num_val_def - 1] - 1 ;
        pos_fin_def = vec_def->pos_tab[num_val_def    ] - 1 ;

        nbr_pos_def = pos_fin_def - pos_deb_def ;

        for (ipos_def = 0 ; ipos_def < nbr_pos_def ; ipos_def++) {

          vec_rep_new->val_tab[cpt_val_rep + ipos_def]
            = vec_def->val_tab[pos_fin_def - 1 - ipos_def] * (-1) ;

        }

      }
      else {

        nbr_pos_def = 0 ;

      }


      cpt_val_rep += nbr_pos_def ;

    }

    vec_rep_new->pos_tab[ielt_rep + 1] = cpt_val_rep + 1 ;

  }


  return vec_rep_new ;


}


/*----------------------------------------------------------------------------
 *  Fonction réalisant le transfert des valeurs d'un champ associées
 *   aux éléments, sur les sous-éléments
 *   participant à la définition des éléments
 *   dans une connectivité "élément -> sous-élément"
 *
 *  Un même sous-élément peut appartenir à plusieurs éléments
 *  Un élément est supposé n'avoir qu'une seule valeur
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__herite
(                                                /* <-- Valeurs transférées   */
 const ecs_vec_int_t  *const vec_val_elt       , /* --> Valeurs à transférer  */
 const ecs_vec_int_t  *const vec_elt_def_sselt , /* --> Définition éléments   */
       size_t                nbr_sselt
)
{

  int           ival_sselt ;
  size_t        ival_elt ;
  size_t        ielt ;
  size_t        isselt ;
  size_t        isselt_elt ;

  size_t        nbr_val_elt ;
  size_t        nbr_sselt_elt ;
  size_t        nbr_val_sselt ;
  ecs_int_t     num_sselt ;

  size_t        pos_val_elt ;
  size_t        pos_val_sselt ;
  size_t        pos_sselt_elt ;
  size_t        pos_sselt ;

  ecs_int_t     val_elt ;

  int   * liste_cpt_val_sselt ;
  int   * liste_nbr_val_sselt ;

  ecs_vec_int_t * this_vec_val_sselt = NULL ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vec_elt_def_sselt != NULL) ;


  BFT_MALLOC(liste_nbr_val_sselt, nbr_sselt, int) ;
  BFT_MALLOC(liste_cpt_val_sselt, nbr_sselt, int) ;


  nbr_val_sselt = ecs_loc_vec_int__compte_val(vec_elt_def_sselt,
                                              vec_val_elt,
                                              liste_nbr_val_sselt,
                                              nbr_sselt) ;


  if (nbr_val_sselt != 0) {


    this_vec_val_sselt = ecs_vec_int__alloue(nbr_sselt + 1,
                                             nbr_val_sselt) ;

    this_vec_val_sselt->pos_tab[0] = 1 ;


    for (isselt = 0 ; isselt < nbr_sselt ; isselt++) {

      this_vec_val_sselt->pos_tab[isselt + 1]
        =  this_vec_val_sselt->pos_tab[isselt] + liste_nbr_val_sselt[isselt] ;

      liste_cpt_val_sselt[isselt] = 0 ;

    }


    for (ielt = 0 ; ielt < vec_elt_def_sselt->pos_nbr - 1 ; ielt++) {


      pos_sselt_elt = vec_elt_def_sselt->pos_tab[ielt] - 1 ;
      nbr_sselt_elt
        = vec_elt_def_sselt->pos_tab[ielt + 1] - 1
        - pos_sselt_elt ;


      pos_val_elt = vec_val_elt->pos_tab[ielt] - 1 ;
      nbr_val_elt
        = vec_val_elt->pos_tab[ielt + 1] - 1
        - pos_val_elt ;


      for (isselt_elt = 0 ; isselt_elt < nbr_sselt_elt ; isselt_elt++) {


        num_sselt
          = ECS_ABS(vec_elt_def_sselt->val_tab[pos_sselt_elt + isselt_elt]) - 1;

        pos_sselt = this_vec_val_sselt->pos_tab[num_sselt] - 1 ;

        for (ival_elt = 0 ; ival_elt < nbr_val_elt ; ival_elt++) {

          val_elt = vec_val_elt->val_tab[pos_val_elt + ival_elt] ;

          ival_sselt = 0 ;
          while (ival_sselt < liste_cpt_val_sselt[num_sselt] &&
                 this_vec_val_sselt->val_tab[pos_sselt + ival_sselt] != val_elt)
            ival_sselt++ ;

          if (ival_sselt == liste_cpt_val_sselt[num_sselt]) {

            /* La valeur de l'attribut pour le sous-élément */
            /*  est une nouvelle valeur à stocker           */

            pos_val_sselt = pos_sselt + liste_cpt_val_sselt[num_sselt];

            liste_cpt_val_sselt[num_sselt]++ ;

            this_vec_val_sselt->val_tab[pos_val_sselt] = val_elt ;

          }
          /* else : rien à faire (la valeur de l'attribut est déjà présente) */

        } /* Fin : boucle sur les valeurs du champ de l'élément */


      } /* Fin : boucle sur les sous-éléments de l'élément */


    } /* Fin : boucle sur les éléments */


  } /* Fin : s'il y a des valeurs pour les sous-éléments */


  BFT_FREE(liste_cpt_val_sselt) ;
  BFT_FREE(liste_nbr_val_sselt) ;


  return this_vec_val_sselt ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui détermine un nouveau vecteur à partir d'un vecteur donné
 *   en extrayant de ce dernier les éléments sélectionnés
 *   par le tableau de booléens
 *
 *  Cette fonction renvoie le vecteur qui définit les anciens éléments
 * du vecteur de référence en fonction des nouveaux éléments du vecteur renvoyé
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__extrait
(
       ecs_vec_int_t   *const vec_new         ,
 const ecs_vec_int_t   *const vec_ref         ,
 const ecs_tab_bool_t         bool_elt_select
)
{

  size_t        cpt_elt_new ;
  size_t        cpt_val_new ;
  size_t        cpt_val_old_new ;
  size_t        nbr_elt_ref ;
  size_t        nbr_val_ref ;
  size_t        pos_ref_inf ;
  size_t        pos_ref_sup ;

  size_t        ielt_ref ;
  size_t        ipos_ref ;

  ecs_vec_int_t * vec_old_new ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_elt_ref = ecs_vec_int__ret_pos_nbr(vec_ref) - 1 ;
  nbr_val_ref = ecs_vec_int__ret_val_nbr(vec_ref) ;


  vec_old_new = ecs_vec_int__alloue(nbr_elt_ref + 1,
                                    nbr_val_ref) ;


  vec_new->pos_tab[0]     = 1 ;
  vec_old_new->pos_tab[0] = 1 ;
  cpt_elt_new             = 0 ;
  cpt_val_new             = 0 ;
  cpt_val_old_new         = 0 ;


  for (ielt_ref = 0 ; ielt_ref < nbr_elt_ref ; ielt_ref++) {


    if (bool_elt_select.val[ielt_ref] == ECS_TRUE) {

      /* L'élément est à extraire */

      pos_ref_inf = vec_ref->pos_tab[ielt_ref    ] - 1 ;
      pos_ref_sup = vec_ref->pos_tab[ielt_ref + 1] - 1 ;


      for (ipos_ref = pos_ref_inf ; ipos_ref < pos_ref_sup ; ipos_ref++) {

        vec_new->val_tab[cpt_val_new++] = vec_ref->val_tab[ipos_ref] ;

      }


      vec_new->pos_tab[cpt_elt_new + 1] = cpt_val_new + 1 ;

      vec_old_new->pos_tab[ielt_ref + 1] = vec_old_new->pos_tab[ielt_ref] + 1 ;
      vec_old_new->val_tab[cpt_val_old_new++] = cpt_elt_new + 1 ;

      cpt_elt_new++ ;

    }
    else {

      /* L'élément n'est pas à extraire */

      vec_old_new->pos_tab[ielt_ref + 1] = vec_old_new->pos_tab[ielt_ref] ;

    }


  }


  BFT_REALLOC(vec_new->pos_tab, cpt_elt_new + 1, ecs_size_t) ;
  BFT_REALLOC(vec_new->val_tab, cpt_val_new    , ecs_int_t) ;

  vec_new->pos_nbr = cpt_elt_new + 1 ;


  BFT_REALLOC(vec_old_new->val_tab, cpt_val_old_new, ecs_int_t) ;


  return vec_old_new ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui construit la  table de connectivité inverse
 *  "sous-éléments -> éléments"
 *
 *  Si dans la connectivité "éléments -> sous-éléments",
 *  le sous-élément est référencé négativement dans la définition de l'élément,
 *  alors dans la connectivité inverse,
 *  l'élément est référencé négativement dans la définition du sous-élément
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__inverse
(
 const ecs_vec_int_t *const vec_def_elt ,
       size_t               nbr_sselt
)
{

  int         * sselt_cpt_elt ;
  int         * cpt_sselt ;
  ecs_vec_int_t * vec_connect_sselt_elt ;

  size_t        nbr_val_cel;
  size_t        isselt ;
  size_t        ielt ;
  size_t        isselt_inf ;
  size_t        isselt_sup ;
  ecs_int_t     num_sselt ;
  size_t        pos_sselt ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vec_def_elt != NULL) ;


  nbr_val_cel = ecs_vec_int__ret_val_nbr(vec_def_elt) ;


  BFT_MALLOC(sselt_cpt_elt, nbr_sselt, int) ;
  BFT_MALLOC(cpt_sselt    , nbr_sselt, int) ;


  ecs_loc_vec_int__compte_elt(vec_def_elt,
                              sselt_cpt_elt,
                              nbr_sselt) ;


  vec_connect_sselt_elt = ecs_vec_int__alloue(nbr_sselt + 1,
                                              nbr_val_cel) ;


  vec_connect_sselt_elt->pos_tab[0] = 1 ;

  for (isselt = 0 ; isselt < nbr_sselt ; isselt++) {

    vec_connect_sselt_elt->pos_tab[isselt + 1]
      =  vec_connect_sselt_elt->pos_tab[isselt] + sselt_cpt_elt[isselt] ;

    cpt_sselt[isselt] = 0 ;

  }


  for (ielt = 0 ; ielt < vec_def_elt->pos_nbr - 1 ; ielt++) {

    isselt_inf = vec_def_elt->pos_tab[ielt]     - 1 ;
    isselt_sup = vec_def_elt->pos_tab[ielt + 1] - 1 ;


    for (isselt = isselt_inf ; isselt < isselt_sup ; isselt++) {


      num_sselt = ECS_ABS(vec_def_elt->val_tab[isselt]) - 1 ;

      pos_sselt
        = vec_connect_sselt_elt->pos_tab[num_sselt] - 1 + cpt_sselt[num_sselt] ;

      cpt_sselt[num_sselt]++ ;


      if      (vec_def_elt->val_tab[isselt] < 0)
        vec_connect_sselt_elt->val_tab[pos_sselt] = - (ielt + 1) ;
      else if (vec_def_elt->val_tab[isselt] > 0)
        vec_connect_sselt_elt->val_tab[pos_sselt] =   (ielt + 1) ;
      else
        assert(vec_def_elt->val_tab[isselt] != 0) ;


    } /* Fin : boucle sur les sous-éléments de l'élément */

  } /* Fin : boucle sur les éléments */


  BFT_FREE(cpt_sselt) ;
  BFT_FREE(sselt_cpt_elt) ;


  return vec_connect_sselt_elt ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui réalise l'ordination des valeurs d'un vecteur indexé
 *     en triant les valeurs pour chaque ensemble de valeurs entre 2 positions
 *  et en triant chaque ensemble de valeurs dans l'ordre lexicographique
 *----------------------------------------------------------------------------*/

ecs_tab_int_t ecs_vec_int__trie_val
(
 ecs_vec_int_t  * *const this_vec_int
)
{

  ecs_vec_int_t  * vec_def_ord ;     /* Vecteur des définitions ordonnées    */
  ecs_vec_int_t  * vec_elt_ord ;     /* Vecteur ordonné  des éléments        */

  ecs_tab_int_t    vect_transf ;     /* Vecteur de transformation            */

  size_t         nbr_elt ;         /* Nombre d'éléments                      */
  size_t         nbr_val ;
  size_t         ielt ;            /* Indice de boucle sur les éléments      */


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_elt = ecs_vec_int__ret_pos_nbr(*this_vec_int) - 1 ;


  /*--------------------------------------------------------------------------*/
  /* 1ère étape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Tri sur les définitions des éléments                                     */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  vec_def_ord = ecs_loc_vec_int__trie_val_pos(*this_vec_int) ;


  ecs_vec_int__detruit(*this_vec_int) ;



  /*--------------------------------------------------------------------------*/
  /* 2ème étape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Tri des éléments en fonction de leurs définitions ordonnées              */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  nbr_val = ecs_vec_int__ret_val_nbr(vec_def_ord) ;


  vect_transf.nbr = nbr_elt ;
  BFT_MALLOC(vect_transf.val, nbr_elt, ecs_int_t) ;
  for (ielt = 0 ; ielt < nbr_elt ; ielt++)
    vect_transf.val[ielt] = ielt ;

  vec_elt_ord = ecs_vec_int__alloue(nbr_elt + 1,
                                    nbr_val) ;

  ecs_vec_int__trie_et_renvoie(vec_def_ord,
                               vec_elt_ord,
                               &vect_transf) ;

  ecs_vec_int__detruit(vec_def_ord) ;



  /*--------------------------------------------------------------------------*/
  /* 3ème étape                                                               */
  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Affectation de la nouvelle liste compactée                               */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  *this_vec_int = vec_elt_ord ;



  /*--------------------------------------------------------------------------*/
  /*                                                                          */
  /* Renvoi du vecteur de transformation                                      */
  /*                                                                          */
  /*--------------------------------------------------------------------------*/


  return vect_transf ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui compare les ensembles de valeurs comprises entre 2 positions
 *   et renvoie un tableau donnant pour chaque ensemble
 *      le numéro du 1er ensemble de chaque groupe d'ensembles identiques
 *
 *  Si entre 2 positions il n'y a pas de valeurs, le numéro est `-1'
 *
 *  Cette fonction prend tout son intérêt lorsque
 *   - les valeurs ont été triées dans chaque ensemble de valeurs
 *   - les ensembles de valeurs ont été tries dans l'ordre lexicographique
 *----------------------------------------------------------------------------*/

ecs_tab_int_t ecs_vec_int__compare_val_pos
(
 const ecs_vec_int_t *const this_vec_int
)
{

  ecs_bool_t      bool_diff ;

  size_t        ipos ;
  size_t        ival ;
  size_t        max_val_pos ;
  size_t        nbr_val_pos ;
  size_t        nbr_val_pos_ref ;
  size_t        pos_ref ;
  size_t        pos_val ;

  ecs_int_t   * val_pos_ref ;

  ecs_tab_int_t   tab_idem ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /*=================*/
  /* Initialisations */
  /*=================*/

  tab_idem.nbr = this_vec_int->pos_nbr - 1 ;
  BFT_MALLOC(tab_idem.val, tab_idem.nbr, ecs_int_t) ;


  max_val_pos = this_vec_int->pos_tab[1] - this_vec_int->pos_tab[0] ;
  for (ipos = 1 ; ipos < tab_idem.nbr ; ipos++)
    max_val_pos = ECS_MAX(max_val_pos,
                          this_vec_int->pos_tab[ipos + 1] -
                          this_vec_int->pos_tab[ipos    ]   ) ;

  BFT_MALLOC(val_pos_ref, max_val_pos, ecs_int_t) ;


  /*=================================================================*/
  /* Repérage des ensembles de valeurs (comprises entre 2 positions) */
  /*  identiques par comparaison de deux ensembles successifs        */
  /*=================================================================*/

  /*----------------------------------------------*/
  /* Initialisation pour le tout premier ensemble */
  /*----------------------------------------------*/

  /* Ensemble servant de référence au 1er tour */

  pos_val         = this_vec_int->pos_tab[0] - 1 ;
  nbr_val_pos_ref = this_vec_int->pos_tab[1] - 1 - pos_val ;

  for (ival = 0 ; ival < nbr_val_pos_ref ; ival++)
    val_pos_ref[ival] = this_vec_int->val_tab[pos_val + ival] ;

  pos_ref = 0 ;

  if (nbr_val_pos_ref == 0)
    tab_idem.val[0] = -1 ;
  else
    tab_idem.val[0] =  0 ;


  /*---------------------------------*/
  /* Boucle sur les autres ensembles */
  /*---------------------------------*/

  for (ipos = 1 ; ipos < tab_idem.nbr ; ipos++) {

    pos_val     = this_vec_int->pos_tab[ipos    ] - 1 ;
    nbr_val_pos = this_vec_int->pos_tab[ipos + 1] - 1 - pos_val ;

    if (nbr_val_pos == nbr_val_pos_ref) {

      ival = 0 ;
      while (ival < nbr_val_pos                                &&
             ECS_ABS(this_vec_int->val_tab[pos_val + ival]) ==
             ECS_ABS(val_pos_ref[ival])                           )
        ival++ ;

      if (ival == nbr_val_pos) {

        /* Les 2 ensembles de valeurs consécutifs sont identiques */

        tab_idem.val[ipos] = tab_idem.val[pos_ref] ;

        bool_diff = ECS_FALSE ;

      }
      else {

        /* Les 2 ensembles de valeurs consécutifs sont différents */

        bool_diff = ECS_TRUE ;

      }

    }
    else{

      /* Les 2 ensembles de valeurs consécutifs sont différents */

      bool_diff = ECS_TRUE ;

    }


    if (bool_diff == ECS_TRUE) { /* Si les deux ensembles sont différents */

      /* L'ensemble qui vient d'être comparé       */
      /*  devient l'ensemble de référence          */
      /*  pour la comparaison du prochain ensemble */

      nbr_val_pos_ref = nbr_val_pos ;

      for (ival = 0 ; ival < nbr_val_pos ; ival++)
        val_pos_ref[ival] = this_vec_int->val_tab[pos_val + ival] ;

      pos_ref = ipos ;

      if (nbr_val_pos == 0)
        tab_idem.val[ipos] = -1 ;
      else
        tab_idem.val[ipos] = ipos ;

    } /* Fin : si les 2 ensembles sont différents */


  } /* Fin : boucle sur les autres ensembles */


  BFT_FREE(val_pos_ref) ;


  return tab_idem ;


}


/*----------------------------------------------------------------------------
 *  Fonction qui prolonge le tableau des valeurs d'une structure
 *  ecs_vec_int_t de manière à ce qu'à chaque position corresponde au
 *  moins une valeur.
 *
 *  Si la structure ecs_vec_int_t n'existe pas, on en crée une.
 *
 *  Cette fonction est utile notamment lors de la construction des familles,
 *  afin que chaque élément appartienne bien explicitement à une famille
 *  donnée, et non pas seulement implicitement à la famille 0 s'il ne porte
 *  aucune couleur ou groupe.
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__prolonge_val_pos
(
 ecs_vec_int_t *const this_vec_int ,
 ecs_int_t            val_defaut   ,
 size_t               nbr_defaut
)
{

  size_t        nbr_val ;
  size_t        nbr_val_add ;
  size_t        nbr_val_loc ;
  size_t        ind ;
  size_t        ind_loc ;

  ecs_size_t   *pos_tab_prol ;
  ecs_int_t    *val_tab_prol ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  if (this_vec_int != NULL) {

    /* Comptage du nombre de valeurs à rajouter */

    nbr_val_add = 0 ;

    for (ind = 0 ; ind < this_vec_int->pos_nbr - 1; ind++) {

      if (this_vec_int->pos_tab[ind + 1] == this_vec_int->pos_tab[ind])
        nbr_val_add += 1 ;

    }

    /* Retour si rien à faire */

    if (nbr_val_add == 0)
      return this_vec_int ;

    /* Prolongement si nécessaire */

    nbr_val =   this_vec_int->pos_tab[this_vec_int->pos_nbr - 1] - 1
              + nbr_val_add ;

    BFT_MALLOC(pos_tab_prol, this_vec_int->pos_nbr, ecs_size_t) ;
    BFT_MALLOC(val_tab_prol, nbr_val,               ecs_int_t) ;

    pos_tab_prol[0] = 1 ;

    for (ind = 0 ; ind < this_vec_int->pos_nbr - 1; ind++) {

      nbr_val_loc = this_vec_int->pos_tab[ind + 1] - this_vec_int->pos_tab[ind] ;

      if (nbr_val_loc == 0) {

        pos_tab_prol[ind + 1] = pos_tab_prol[ind] + 1 ;
        val_tab_prol[pos_tab_prol[ind] - 1] = val_defaut ;

      }
      else {

        pos_tab_prol[ind + 1] = pos_tab_prol[ind] + nbr_val_loc ;

        for (ind_loc = 0 ; ind_loc < nbr_val_loc ; ind_loc++) {

          val_tab_prol[pos_tab_prol[ind] - 1 + ind_loc]
            = this_vec_int->val_tab[this_vec_int->pos_tab[ind] - 1 + ind_loc] ;

        }

      }

    }

    BFT_FREE(this_vec_int->pos_tab) ;
    BFT_FREE(this_vec_int->val_tab) ;

    this_vec_int->pos_tab = pos_tab_prol ;
    this_vec_int->val_tab = val_tab_prol ;

    return this_vec_int ;

  }
  else {

    ecs_vec_int_t  *vec_int_ret ;

    /* Le vecteur n'existe pas, on doit le créer */

    if (nbr_defaut == 0)
      return NULL ;

    vec_int_ret = ecs_vec_int__alloue(nbr_defaut + 1, nbr_defaut) ;

    for (ind = 0 ; ind < nbr_defaut ; ind++) {

      vec_int_ret->pos_tab[ind] = ind + 1 ;
      vec_int_ret->val_tab[ind] = val_defaut ;

    }

    vec_int_ret->pos_tab[nbr_defaut] = nbr_defaut + 1 ;

    return vec_int_ret ;

  }

}


/*----------------------------------------------------------------------------
 *  Fonction qui renvoie un vecteur indexé donnant pour chaque élément
 *   le numéro de famille à laquelle il appartient
 *   à partir -    du vecteur indexé donnant pour chaque élément
 *               les numéros d'attribut le caractérisant
 *            - et du tableau donnant pour chaque élément :
 *                 - le 1er élément ayant la même liste d'attributs
 *                 - ou `-1' s'il n'a pas d'attribut
 *
 *  La fonction détermine aussi :
 *   - les définitions des familles en fonction des numéros de descripteur
 *   - les nombres de descripteurs composant chaque famille
 *   - le  nombre  de familles
 *----------------------------------------------------------------------------*/

ecs_vec_int_t * ecs_vec_int__attribue_fam
(
 const ecs_vec_int_t      *const vec_int_att_unifie ,
 const ecs_tab_int_t             tab_idem           ,
       ecs_int_t      * * *      def_fam_descr      ,
       ecs_int_t        * *      nbr_descr_fam      ,
 const ecs_int_t                 num_fam_deb        ,
       ecs_int_t          *const nbr_fam
)
{

  ecs_int_t     cpt_fam ;
  size_t        cpt_val ;
  ecs_int_t     idescr ;
  size_t        ielt ;
  ecs_int_t     ifam ;
  ecs_int_t     nbr_att_elt ;
  size_t        nbr_elt ;
  size_t        pos_elt ;

  ecs_vec_int_t * vec_int_elt_fam ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  nbr_elt = vec_int_att_unifie->pos_nbr - 1 ;

  vec_int_elt_fam = ecs_vec_int__alloue(nbr_elt + 1,
                                        nbr_elt) ;

  vec_int_elt_fam->pos_tab[0] = 1 ;


  /* Détermination du nombre de familles */
  /*-------------------------------------*/

  *nbr_fam = 0 ;

  for (ielt = 0 ; ielt < nbr_elt ; ielt++) {

    if (tab_idem.val[ielt] == (ecs_int_t)ielt) {

      (*nbr_fam)++ ;

    }

  }


  /* Détermination du nombre de descripteurs par famille */
  /*-----------------------------------------------------*/

  BFT_MALLOC(*nbr_descr_fam, *nbr_fam, ecs_int_t) ;

  cpt_fam = 0 ;

  for (ielt = 0 ; ielt < nbr_elt ; ielt++) {

    if (tab_idem.val[ielt] == (ecs_int_t)ielt) {

      pos_elt     = vec_int_att_unifie->pos_tab[ielt    ] - 1 ;
      (*nbr_descr_fam)[cpt_fam]
        = vec_int_att_unifie->pos_tab[ielt + 1] - 1 - pos_elt ;

      cpt_fam++ ;

    }

  }


  /* Détermination des définitions des familles en fonction des descripteurs */
  /*-------------------------------------------------------------------------*/

  BFT_MALLOC(*def_fam_descr, *nbr_fam, ecs_int_t *) ;

  for (ifam = 0 ; ifam < *nbr_fam ; ifam++)
    BFT_MALLOC((*def_fam_descr)[ifam], (*nbr_descr_fam)[ifam], ecs_int_t) ;

  cpt_val = 0 ;
  cpt_fam = 0 ;

  for (ielt = 0 ; ielt < nbr_elt ; ielt++) {

    if (tab_idem.val[ielt] == (ecs_int_t)ielt) {

      /* Définition de la famille en fonction des numéros d'attribut */

      pos_elt     = vec_int_att_unifie->pos_tab[ielt    ] - 1 ;
      nbr_att_elt = vec_int_att_unifie->pos_tab[ielt + 1] - 1 - pos_elt ;

      for (idescr = 0 ; idescr < nbr_att_elt ; idescr++)
        (*def_fam_descr)[cpt_fam][idescr]
          = vec_int_att_unifie->val_tab[pos_elt + idescr] ;

      cpt_fam++ ;

    }


    if (tab_idem.val[ielt] != -1) {

      vec_int_elt_fam->pos_tab[ielt + 1]
        = vec_int_elt_fam->pos_tab[ielt] + 1 ;

      vec_int_elt_fam->val_tab[cpt_val++] = cpt_fam + num_fam_deb - 1 ;

    }
    else {

      /* L'élément n'a pas de famille */

      vec_int_elt_fam->pos_tab[ielt + 1]
        = vec_int_elt_fam->pos_tab[ielt] ;

    }


  }


  BFT_REALLOC(vec_int_elt_fam->val_tab, cpt_val, ecs_int_t) ;


  return vec_int_elt_fam ;


}


/*============================================================================
 *                              Fonctions privées
 *============================================================================*/


/*----------------------------------------------------------------------------
 *  Fonction qui détermine pour chaque sous-élément,
 *   le nombre d'éléments dont le sous-élément participe à la définition
 *   dans une connectivité "élément -> sous-élément"
 *----------------------------------------------------------------------------*/

static void ecs_loc_vec_int__compte_elt
(
 const ecs_vec_int_t  *const vec_def_elt       ,
       int            *const sselt_cpt_def_elt ,
       size_t                nbr_sselt
)
{


  size_t      isselt ;
  size_t      ielt ;

  ecs_int_t   num_sselt ;

  size_t      isselt_inf ;
  size_t      isselt_sup ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vec_def_elt != NULL) ;


  /* On compte le nombre de fois qu'un numéro du sous-élément */
  /*  participe à la définition d'un élément                  */
  /*----------------------------------------------------------*/


  for (isselt = 0 ; isselt < nbr_sselt ; isselt++)
    sselt_cpt_def_elt[isselt] = 0 ;


  for (ielt = 0 ; ielt < vec_def_elt->pos_nbr - 1 ; ielt++) {

    isselt_inf = vec_def_elt->pos_tab[ielt]     - 1 ;
    isselt_sup = vec_def_elt->pos_tab[ielt + 1] - 1 ;


    for (isselt = isselt_inf ; isselt < isselt_sup ; isselt++) {

      num_sselt = ECS_ABS(vec_def_elt->val_tab[isselt]) - 1 ;


      sselt_cpt_def_elt[num_sselt]++ ;


    } /* Fin : boucle sur les sous-éléments de l'élément */

  } /* Fin : boucle sur les éléments */


}


/*----------------------------------------------------------------------------
 *  Fonction qui détermine le nombre de valeurs associées
 *   à chaque sous-élément participant à la définition d'éléments
 *   dans une connectivité "élément -> sous-élément"
 *
 *  Un même sous-élément peut appartenir à plusieurs éléments
 *  Un élément est supposé n'avoir qu'une seule valeur
 *----------------------------------------------------------------------------*/

static ecs_int_t ecs_loc_vec_int__compte_val
(
 const ecs_vec_int_t *const vec_elt_def_sselt   ,
 const ecs_vec_int_t *const vec_val_elt         ,
       int           *const liste_nbr_val_sselt ,
       size_t               nbr_sselt
)
{

  size_t        isselt ;
  size_t        ielt ;
  size_t        ival_elt ;
  int           ival_sselt ;

  size_t        max_nbr_elt_sselt ;
  size_t        nbr_val_elt ;
  size_t        nbr_val_sselt ;
  size_t        nbr_elt_sselt ;
  ecs_int_t     num_elt ;

  size_t        pos_elt ;
  size_t        pos_val_elt ;

  ecs_int_t     val_elt ;

  ecs_int_t * * val_sselt ;
  ecs_int_t   * val_sselt_uni ;

  ecs_vec_int_t * vec_sselt_elt ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  assert(vec_elt_def_sselt != NULL) ;
  assert(vec_val_elt       != NULL) ;


  /* Chaque fois qu'un sous-élément participe à la définition d'un élément */
  /*  on incrémente le compteur pour ce sous-élément du nombre de valeurs  */
  /*  associées à l'élément                                                */
  /*-----------------------------------------------------------------------*/


  nbr_val_sselt = 0 ;


  vec_sselt_elt = ecs_vec_int__inverse(vec_elt_def_sselt,
                                       nbr_sselt) ;


  /* Comptage */

  max_nbr_elt_sselt = 0 ;

  for (isselt = 0 ; isselt < nbr_sselt ; isselt++) {

    nbr_elt_sselt = 0 ;

    pos_elt = vec_sselt_elt->pos_tab[isselt] - 1 ;

    for (ielt = 0 ;
         ielt < vec_sselt_elt->pos_tab[isselt + 1] - 1 - pos_elt ;
         ielt++) {

      num_elt = ECS_ABS(vec_sselt_elt->val_tab[pos_elt + ielt]) - 1 ;

      nbr_elt_sselt +=   vec_val_elt->pos_tab[num_elt + 1]
                       - vec_val_elt->pos_tab[num_elt] ;

    }

    max_nbr_elt_sselt = ECS_MAX(max_nbr_elt_sselt, nbr_elt_sselt) ;

  }


  /* Allocation */

  BFT_MALLOC(val_sselt_uni, nbr_sselt * max_nbr_elt_sselt, ecs_int_t) ;
  BFT_MALLOC(val_sselt, nbr_sselt, ecs_int_t *) ;


  /* Remplissage */

  for (isselt = 0 ; isselt < nbr_sselt ; isselt++)
    val_sselt[isselt] = val_sselt_uni + isselt * max_nbr_elt_sselt ;

  for (isselt = 0 ; isselt < nbr_sselt ; isselt++) {

    liste_nbr_val_sselt[isselt] = 0 ;

    pos_elt = vec_sselt_elt->pos_tab[isselt] - 1 ;
    nbr_elt_sselt = vec_sselt_elt->pos_tab[isselt + 1] - 1 - pos_elt ;

    if (nbr_elt_sselt != 0) {


      for (ielt = 0 ; ielt < nbr_elt_sselt ; ielt++) {

        num_elt = ECS_ABS(vec_sselt_elt->val_tab[pos_elt + ielt]) - 1 ;

        pos_val_elt = vec_val_elt->pos_tab[num_elt] - 1 ;
        nbr_val_elt
          = vec_val_elt->pos_tab[num_elt + 1] - 1
          - pos_val_elt ;

        for (ival_elt = 0 ; ival_elt < nbr_val_elt ; ival_elt++) {

          val_elt = vec_val_elt->val_tab[pos_val_elt + ival_elt] ;

          ival_sselt = 0 ;
          while (ival_sselt < liste_nbr_val_sselt[isselt] &&
                 val_sselt[isselt][ival_sselt] != val_elt)
            ival_sselt++ ;

          if (ival_sselt == liste_nbr_val_sselt[isselt]) {

            /* La valeur de l'attribut pour le sous-élément */
            /*  est une nouvelle valeur à stocker           */

            val_sselt[isselt][ival_sselt] = val_elt ;

            liste_nbr_val_sselt[isselt]++ ;

          }
          /* else : rien à faire (la valeur de l'attribut est déjà présente) */

        } /* Fin : boucle sur les valeurs du champ de l'élément */

      } /* Fin : boucle sur les éléments du sous-elément */


      nbr_val_sselt += liste_nbr_val_sselt[isselt] ;

    } /* Fin : s'il y a des éléments pour ce sous-élément */

  } /* Fin : boucle sur les sous-éléments */


  ecs_vec_int__detruit(vec_sselt_elt) ;

  BFT_FREE(val_sselt_uni) ;
  BFT_FREE(val_sselt) ;


  return nbr_val_sselt ;


}


/*----------------------------------------------------------------------------
 *    Fonction de descente d'un arbre binaire pour le tri sur place
 *  d'un tableau d'entiers.
 *----------------------------------------------------------------------------*/

static void ecs_loc_vec_int__desc_arbre_val
(
       ecs_int_t  ltree     ,     /* --> Niveau arbre binaire à descendre     */
 const ecs_int_t  ntree     ,     /* --> Taille arbre binaire à descendre     */
       ecs_int_t  elem_ord[]      /* <-> Liste à trier éléments considérés    */
)
{
  ecs_int_t ktree;
  ecs_int_t i_save;

  i_save = elem_ord[ltree];

  while (ltree <= (ntree / 2)) {

    ktree = (2 * ltree) + 1;

    if (ktree < ntree - 1)
      if (elem_ord[ktree + 1] > elem_ord[ktree]) ktree++;

    if (ktree >= ntree) break;

    if (i_save >= elem_ord[ktree]) break;

    elem_ord[ltree] = elem_ord[ktree];
    ltree = ktree;

  }

  elem_ord[ltree] = i_save;


}


/*----------------------------------------------------------------------------
 *  Fonction qui réalise un tri sur les valeurs d'un vecteur indexé
 *   entre 2 positions
 *----------------------------------------------------------------------------*/

static ecs_vec_int_t  * ecs_loc_vec_int__trie_val_pos
(
 const ecs_vec_int_t *const this_vec_int   /* --> Structure avec déf. à trier */
)
{

  ecs_vec_int_t *vec_int_ord ; /* Structure `ecs_vec_int_t' defs. ordonnées   */

  ecs_int_t    nbr_elt ;     /* Nombre d'elts dont définitions sont à trier   */
  ecs_int_t    nbr_def ;     /* Nombre de définitions pour tous les éléments  */

  ecs_int_t    ielt ;        /* Indice sur les éléments                       */
  ecs_int_t    ipos ;
  ecs_int_t    ipos_deb ;
  ecs_int_t    ipos_fin ;
  ecs_int_t    nbr_def_loc ;
  ecs_int_t    i ;
  ecs_int_t    i_save ;

  ecs_int_t   *tab_val_loc ;


  /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/


  /*=================*/
  /* Initialisations */
  /*=================*/

  nbr_elt = this_vec_int->pos_nbr - 1 ;
  nbr_def = this_vec_int->pos_tab[nbr_elt] - 1 ;


  vec_int_ord = ecs_vec_int__alloue(nbr_elt + 1,
                                    nbr_def) ;

  vec_int_ord->pos_tab[0] = 1 ;


  /*=========================*/
  /* Boucle sur les éléments */
  /*=========================*/


  for (ielt = 0 ; ielt < nbr_elt ; ielt++) {


    /* Les positions restent inchangées */

    vec_int_ord->pos_tab[ielt + 1] = this_vec_int->pos_tab[ielt + 1] ;

    ipos_deb = this_vec_int->pos_tab[ielt    ] - 1 ;
    ipos_fin = this_vec_int->pos_tab[ielt + 1] - 1 ;


    /* On commence par recopier les valeurs */

    for (ipos = ipos_deb ; ipos < ipos_fin ; ipos++)
      vec_int_ord->val_tab[ipos] = this_vec_int->val_tab[ipos] ;


    /* Tri des valeurs de la copie */
    /*-----------------------------*/

    nbr_def_loc = ipos_fin -ipos_deb ;

    tab_val_loc = vec_int_ord->val_tab + ipos_deb ;


    /* Création de l'arbre binaire vec_renum->val_tab[vect_renum->nbr] */

    for (i = (nbr_def_loc / 2) - 1 ; i >= 0 ; i--)
      ecs_loc_vec_int__desc_arbre_val(i, nbr_def_loc, tab_val_loc) ;


    /* Tri de l'arbre binaire */

    for (i = nbr_def_loc - 1 ; i > 0 ; i--) {

      i_save         = tab_val_loc[0] ;
      tab_val_loc[0] = tab_val_loc[i] ;
      tab_val_loc[i] = i_save ;

      ecs_loc_vec_int__desc_arbre_val(0, i, tab_val_loc) ;

    }


  } /* Fin : boucle sur les éléments */


  /*--------------------------------------------------*/
  /* Renvoi de la structure des définitions ordonnées */
  /*--------------------------------------------------*/


  return vec_int_ord ;


}

Generated by  Doxygen 1.6.0   Back to index