1
/*============================================================================
2
* Définitions des fonctions
3
* associées à la structure `tab_t' décrivant un tableau
4
*============================================================================*/
7
This file is part of Code_Saturne, a general-purpose CFD tool.
9
Copyright (C) 1998-2011 EDF S.A.
11
This program is free software; you can redistribute it and/or modify it under
12
the terms of the GNU General Public License as published by the Free Software
13
Foundation; either version 2 of the License, or (at your option) any later
16
This program is distributed in the hope that it will be useful, but WITHOUT
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21
You should have received a copy of the GNU General Public License along with
22
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
23
Street, Fifth Floor, Boston, MA 02110-1301, USA.
27
/*============================================================================
29
*============================================================================*/
31
/*----------------------------------------------------------------------------
32
* Fichiers `include' librairie standard C
33
*----------------------------------------------------------------------------*/
41
/*----------------------------------------------------------------------------
42
* Fichiers `include' visibles du paquetage courant
43
*----------------------------------------------------------------------------*/
49
/*----------------------------------------------------------------------------
50
* Fichier `include' du paquetage courant associe au fichier courant
51
*----------------------------------------------------------------------------*/
56
/*============================================================================
58
*============================================================================*/
60
/*----------------------------------------------------------------------------
61
* Fonction de descente d'un arbre binaire pour le tri lexicographique
62
* d'un vecteur d'entiers (voir ecs_int_table_ord).
63
*----------------------------------------------------------------------------*/
66
ecs_loc_tab_int__desc_arbre(const ecs_int_t *val_tab,
72
ecs_int_t i_save, p1, p2;
74
i_save = *(elem_ord+ltree);
76
while (ltree <= (ntree/2)) {
80
if (ktree < ntree - 1) {
82
p1 = *(elem_ord+ktree+1);
83
p2 = *(elem_ord+ktree);
85
if (*(val_tab+p1) > *(val_tab+p2)) ktree++;
88
if (ktree >= ntree) break;
91
p2 = *(elem_ord+ktree);
93
if (*(val_tab+p1) >= *(val_tab+p2)) break;
95
*(elem_ord+ltree) = *(elem_ord+ktree);
100
*(elem_ord+ltree) = i_save;
103
/*----------------------------------------------------------------------------
104
* Fonction de descente d'un arbre binaire pour le tri lexicographique
105
* d'un vecteur de chaînes de caractères (voir ecs_char_table_ord).
106
*----------------------------------------------------------------------------*/
109
ecs_loc_tab_char__desc_arbre(char **val_tab,
111
const ecs_int_t ntree,
115
ecs_int_t i_save, p1, p2;
117
i_save = *(elem_ord+ltree);
119
while (ltree <= (ntree/2)) {
123
if (ktree < ntree - 1) {
125
p1 = *(elem_ord+ktree+1);
126
p2 = *(elem_ord+ktree);
128
if (strcmp(*(val_tab+p1), *(val_tab+p2)) > 0) ktree++;
131
if (ktree >= ntree) break;
134
p2 = *(elem_ord+ktree);
136
if (strcmp(*(val_tab+p1), *(val_tab+p2)) >= 0) break;
138
*(elem_ord+ltree) = *(elem_ord+ktree);
143
*(elem_ord+ltree) = i_save;
146
/*============================================================================
147
* Fonctions publiques
148
*============================================================================*/
150
/*----------------------------------------------------------------------------
151
* Fonction qui crée un tableau de dimension donnée
152
*----------------------------------------------------------------------------*/
155
ecs_tab_int__cree(size_t dim_tab)
159
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
162
ECS_MALLOC(tab.val, tab.nbr, ecs_int_t);
167
/*----------------------------------------------------------------------------
168
* Fonction qui crée un tableau de dimension donnée
169
* et initialise les valeurs avec une constante
170
*----------------------------------------------------------------------------*/
173
ecs_tab_int__cree_init(size_t dim_tab,
179
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
181
tab = ecs_tab_int__cree(dim_tab);
183
for (itab = 0; itab < tab.nbr; itab++)
184
tab.val[itab] = val_init;
189
/*----------------------------------------------------------------------------
190
* Fonction qui transforme le tableau donné en son inverse
191
*----------------------------------------------------------------------------
195
* .---.---.---.---.---.---.
196
* Tableau en entrée : | 2 | 5 | 4 | 3 | 0 | 1 |
197
* `---'---'---'---'---'---'
200
* .---.---.---.---.---.---.
201
* Tableau en sortie : | 4 | 5 | 0 | 3 | 2 | 1 |
202
* `---'---'---'---'---'---'
205
*----------------------------------------------------------------------------*/
208
ecs_tab_int__inverse(ecs_tab_int_t *this_tab)
213
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
215
assert(this_tab->nbr != 0);
216
assert(this_tab->val != NULL);
218
ECS_MALLOC(val_tab, this_tab->nbr, ecs_int_t);
220
for (itab = 0; itab < this_tab->nbr; itab++)
221
val_tab[itab] = this_tab->val[itab];
223
for (itab = 0; itab < this_tab->nbr; itab++)
224
this_tab->val[val_tab[itab]] = itab;
229
/*----------------------------------------------------------------------------
230
* Fonction de tri lexicographique d'un vecteur d'entiers.
232
* La liste n'est pas modifiée directement,
233
* mais on construit un vecteur de renumérotation,
234
* afin de pouvoir appliquer cette renumérotation à d'autres tableaux
236
* Le tri utilise est de type "heapsort", de complexité O(nlog(n)).
237
* Les éléments sont rangés en ordre croissant.
238
*----------------------------------------------------------------------------*/
241
ecs_tab_int__trie(const ecs_tab_int_t this_vect,
242
ecs_tab_int_t vect_renum)
246
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
248
/* Création de l'arbre binaire vec_renum->val_tab[vect_renum->nbr] */
250
for (i = (this_vect.nbr / 2) - 1; i >= 0; i--) {
252
ecs_loc_tab_int__desc_arbre(this_vect.val,
258
/* Tri de l'arbre binaire */
260
for (i = this_vect.nbr - 1; i > 0; i--) {
262
i_save = *(vect_renum.val );
263
*(vect_renum.val ) = *(vect_renum.val + i);
264
*(vect_renum.val + i) = i_save ;
267
ecs_loc_tab_int__desc_arbre(this_vect.val,
274
/*----------------------------------------------------------------------------
275
* Fonction de tri lexicographique d'un vecteur de chaînes de caractères
277
* La liste n'est pas modifiée directement,
278
* mais on construit un vecteur de renumérotation,
279
* afin de pouvoir appliquer cette renumérotation à d'autres tableaux
281
* Le tri utilise est de type "heapsort", de complexité O(nlog(n)).
282
* Les éléments sont rangés en ordre croissant.
283
*----------------------------------------------------------------------------*/
286
ecs_tab_char__trie(const ecs_tab_char_t this_vect,
287
ecs_tab_int_t vect_renum)
291
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
293
/* Création de l'arbre binaire vec_renum->val_tab[vect_renum->nbr] */
295
for (i = (this_vect.nbr / 2) - 1; i >= 0; i--) {
297
ecs_loc_tab_char__desc_arbre(this_vect.val,
303
/* Tri de l'arbre binaire */
305
for (i = this_vect.nbr - 1; i > 0; i--) {
307
i_save = *(vect_renum.val );
308
*(vect_renum.val ) = *(vect_renum.val + i);
309
*(vect_renum.val + i) = i_save ;
311
ecs_loc_tab_char__desc_arbre(this_vect.val,
318
/*----------------------------------------------------------------------------
319
* Fonction qui trie un vecteur d'entiers donné
320
* en renvoyant le vecteur trié
322
* La fonction détermine aussi le vecteur de renumérotation des indices
323
* (pour des indices commençant à `0')
324
*----------------------------------------------------------------------------*/
327
ecs_tab_int__trie_et_renvoie(const ecs_tab_int_t this_vect,
328
ecs_tab_int_t vect_renum)
331
ecs_tab_int_t vect_trie;
333
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
335
for (ival = 0; ival < this_vect.nbr; ival++)
336
vect_renum.val[ival] = ival;
338
ecs_tab_int__trie(this_vect ,
341
ECS_MALLOC(vect_trie.val, this_vect.nbr, ecs_int_t);
342
vect_trie.nbr = this_vect.nbr;
344
for (ival = 0; ival < this_vect.nbr; ival++)
345
vect_trie.val[ival] = this_vect.val[vect_renum.val[ival]];
350
/*----------------------------------------------------------------------------
351
* Fonction qui trie un vecteur de chaînes de caractères donné
352
* en renvoyant le vecteur trié. Les chaînes ne sont pas dupliquées,
353
* seuls les pointeurs sont copiés.
355
* La fonction détermine aussi le vecteur de renumérotation des indices
356
* (pour des indices commençant à `0')
357
*----------------------------------------------------------------------------*/
360
ecs_tab_char__trie_et_renvoie(const ecs_tab_char_t this_vect,
361
ecs_tab_int_t vect_renum)
364
ecs_tab_char_t vect_trie;
366
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
368
for (ival = 0; ival < this_vect.nbr; ival++)
369
vect_renum.val[ival] = ival;
371
ecs_tab_char__trie(this_vect ,
374
ECS_MALLOC(vect_trie.val, this_vect.nbr, char *);
375
vect_trie.nbr = this_vect.nbr;
377
for (ival = 0; ival < this_vect.nbr; ival++)
378
vect_trie.val[ival] = this_vect.val[vect_renum.val[ival]];
383
/*----------------------------------------------------------------------------
384
* Fonction qui compacte un vecteur de chaînes de caractères donné
385
* en renvoyant le vecteur compacté; les chaînes ne sont pas dupliquées,
386
* seuls les pointeurs sont copiés.
388
* Le vecteur d'origine doit être trié.
389
*----------------------------------------------------------------------------*/
392
ecs_tab_char__compacte(const ecs_tab_char_t this_vect)
397
ecs_tab_char_t vect_compact ;
399
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
401
ECS_MALLOC(vect_compact.val, this_vect.nbr, char *);
402
vect_compact.nbr = this_vect.nbr;
404
if (this_vect.nbr == 0)
408
vect_compact.val[0] = this_vect.val[0];
410
for (ival = 1; ival < this_vect.nbr; ival++) {
412
if (strcmp(this_vect.val[ival], vect_compact.val[ival_last]) != 0) {
414
vect_compact.val[++ival_last] = this_vect.val[ival];
419
vect_compact.nbr = ival_last + 1;
420
ECS_REALLOC(vect_compact.val,
421
vect_compact.nbr, char *);
426
/*----------------------------------------------------------------------------
427
* Fonction de recherche d'une collection d'entiers
428
* dans une autre collection d'entiers strictement ordonnée.
429
* (Méthode de recherche dichotomique)
431
* La fonction détermine un vecteur d'indices correspondant
432
* à la position des entiers dans le vecteur ou est faite la recherche
433
* Si un entier n'est pas contenu dans le vecteur,
434
* on lui adresse un "indice" `-1'
435
*----------------------------------------------------------------------------*/
438
ecs_tab_int__recherche(ecs_tab_int_t this_vect_rec,
439
ecs_tab_int_t vect_ord,
440
ecs_tab_int_t vect_ind)
442
ecs_int_t val_rec; /* Valeur de l'entier à rechercher */
443
size_t irec; /* Indice de boucle sur les entiers à rechercher */
445
ecs_int_t mid; /* Valeur au centre dans l'intervalle de recherche */
446
ecs_int_t left; /* Valeur à gauche dans l'intervalle de recherche */
447
ecs_int_t right; /* Valeur à droite dans la recherche dichotomique */
449
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
451
for (irec = 0; irec < this_vect_rec.nbr; irec++) {
453
val_rec = *(this_vect_rec.val + irec);
455
if (val_rec <= vect_ord.val[0])
456
*(vect_ind.val + irec) = 0;
458
else if (val_rec > vect_ord.val[vect_ord.nbr - 1])
459
*(vect_ind.val + irec) = vect_ord.nbr;
464
right = vect_ord.nbr - 1;
466
while ((right - left) > 1) {
468
mid = (right + left) / 2; /* Division entière */
469
if (val_rec <= vect_ord.val[mid])
476
*(vect_ind.val + irec) = right;
480
if ( *(vect_ind.val + irec) >= (ecs_int_t)(vect_ord.nbr)
481
|| val_rec != vect_ord.val[*(vect_ind.val + irec)] ) {
483
/* Échec de la recherche : */
484
/* l'élément `val_rec' n'a pas été trouvé dans le vecteur */
485
/* => on affecte une valeur `-1' */
487
*(vect_ind.val + irec) = -1;
491
} /* Fin de la boucle sur les éléments de la liste à rechercher */
494
/*----------------------------------------------------------------------------
495
* Fonction de construction du tableau de remplacement référence -> indice
496
* Si bool_copie est à true, on alloue et on renvoie une copie de
497
* tab_att_reference, qui n'est pas modifie; sinon, tab_att_reference est
499
*----------------------------------------------------------------------------*/
502
ecs_tab_int__ref_en_indice(ecs_tab_int_t tab_att_reference,
503
const ecs_tab_int_t tab_val_idx,
508
ecs_tab_int_t tab_ind_ref_ord;
509
ecs_tab_int_t tab_renum;
510
ecs_tab_int_t tab_trie;
512
ecs_tab_int_t tab_ind_reference;
514
/*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
516
/* Allocations et initialisations */
518
tab_ind_reference.nbr = tab_att_reference.nbr;
520
if (bool_copie == true)
521
ECS_MALLOC(tab_ind_reference.val, tab_ind_reference.nbr, ecs_int_t);
524
tab_ind_reference.val = tab_att_reference.val;
526
tab_ind_ref_ord.nbr = tab_ind_reference.nbr;
527
ECS_MALLOC(tab_ind_ref_ord.val, tab_ind_ref_ord.nbr, ecs_int_t);
529
tab_renum.nbr = tab_val_idx.nbr;
530
ECS_MALLOC(tab_renum.val, tab_renum.nbr, ecs_int_t);
532
/* renumérotation de vec_idx_sous_ent->val_tab */
534
tab_trie = ecs_tab_int__trie_et_renvoie(tab_val_idx,
537
ecs_tab_int__recherche(tab_att_reference,
541
ECS_FREE(tab_trie.val);
543
for (ival = 0; ival < tab_ind_reference.nbr; ival++)
544
tab_ind_reference.val[ival] = tab_renum.val[tab_ind_ref_ord.val[ival]];
546
/* Libération de mémoire */
548
ECS_FREE(tab_renum.val);
549
ECS_FREE(tab_ind_ref_ord.val);
553
return tab_ind_reference;
556
/*----------------------------------------------------------------------------*/