PIPS
hermite.c
Go to the documentation of this file.
1 /*
2 
3  $Id: hermite.c 1669 2019-06-26 17:24:57Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25  /* package matrice */
26 
27 #ifdef HAVE_CONFIG_H
28  #include "config.h"
29 #endif
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 
34 #include "linear_assert.h"
35 
36 #include "boolean.h"
37 #include "arithmetique.h"
38 
39 #include "matrice.h"
40 
41 /* void matrice_hermite(matrice MAT, int n, int m, matrice P, matrice H,
42  * matrice Q, int *det_p, int *det_q):
43  * calcul de la forme reduite de Hermite H de la matrice MAT avec
44  * les deux matrices de changement de base unimodulaire P et Q,
45  * telles que H = P x MAT x Q
46  * et en le meme temp, produit les determinants des P et Q.
47  * det_p = |P|, det_q = |Q|.
48  *
49  * (c.f. Programmation Lineaire. Theorie et algorithmes. tome 2. M.MINOUX. Dunod (1983))
50  * FI: Quels est l'invariant de l'algorithme? MAT = P x H x Q?
51  * FI: Quelle est la norme decroissante? La condition d'arret?
52  *
53  * Les parametres de la fonction :
54  *
55  * int MAT[n,m]: matrice
56  * int n : nombre de lignes de la matrice
57  * int m : nombre de colonnes de la matrice
58  * int P[n,n] : matrice
59  * int H[n,m] : matrice reduite de Hermite
60  * int Q[m,m] : matrice
61  * int *det_p : determinant de P (nombre de permutation de ligne)
62  * int *det_q : determinant de Q (nombre de permutation de colonne)
63  *
64  * Les 3 matrices P(nxn), Q(mxm) et H(nxm) doivent etre allouees avant le
65  * calcul.
66  *
67  * Note: les denominateurs de MAT, P, A et H ne sont pas utilises.
68  *
69  * Auteurs: Corinne Ancourt, Yi-qing Yang
70  *
71  * Modifications:
72  * - modification du profil de la fonction pour permettre le calcul du
73  * determinant de MAT
74  * - permutation de colonnes directe, remplacant une permutation
75  * par produit de matrices
76  * - suppression des copies entre H, P, Q et NH, PN, QN
77  */
78 void matrice_hermite(MAT,n,m,P,H,Q,det_p,det_q)
79 Value *MAT;
80 int n,m;
81 Value *P;
82 Value *H;
83 Value *Q;
84 Value *det_p;
85 Value *det_q;
86 
87 {
88  Value *PN=NULL;
89  Value *QN=NULL;
90  Value *HN = NULL;
91 
92  /* indice de la ligne et indice de la colonne correspondant
93  au plus petit element de la sous-matrice traitee */
94  int ind_n,ind_m;
95 
96  /* niveau de la sous-matrice traitee */
97  int level = 0;
98 
99  register Value ALL; /* le plus petit element sur la diagonale */
100  register Value x; /* la rest de la division par ALL */
101  bool stop = false;
102  int i;
103 
104  *det_p = VALUE_ONE;
105  *det_q = VALUE_ONE;
106 
107  /* if ((n>0) && (m>0) && MAT) */
108  assert((n > 0) && (m > 0));
110 
111  HN = matrice_new(n, m);
112  PN = matrice_new(n, n);
113  QN = matrice_new(m, m);
114 
115  /* Initialisation des matrices */
116 
117  matrice_assign(MAT,H,n,m);
118  matrice_identite(PN,n,0);
119  matrice_identite(QN,m,0);
120  matrice_identite(P,n,0);
121  matrice_identite(Q,m,0);
122  matrice_nulle(HN,n,m);
123 
124  while (!stop) {
125  /* tant qu'il reste des termes non nuls dans la partie
126  triangulaire superieure de la matrice H,
127  on cherche le plus petit element de la sous-matrice */
128  mat_coeff_nnul(H,n,m,&ind_n,&ind_m,level);
129 
130  if (ind_n == 0 && ind_m == 0)
131  /* la sous-matrice restante est nulle, on a terminee */
132  stop = true;
133  else {
134  /* s'il existe un plus petit element non nul dans la partie
135  triangulaire superieure de la sous-matrice,
136  on amene cet element en haut sur la diagonale.
137  si cet element est deja sur la diagonale, et que tous les
138  termes de la ligne correspondante sont nuls,
139  on effectue les calculs sur la sous-matrice de rang superieur*/
140 
141  if (ind_n > level + 1) {
142  matrice_swap_rows(H,n,m,level+1,ind_n);
143  matrice_swap_rows(PN,n,n,level+1,ind_n);
144  value_oppose(*det_p);
145  }
146 
147  if (ind_m > level+1) {
148  matrice_swap_columns(H,n,m,level+1,ind_m);
149  matrice_swap_columns(QN,m,m,level+1,ind_m);
150  value_oppose(*det_q);
151  }
152 
153  if(mat_lig_el(H,n,m,level) != 0) {
154  ALL = ACC_ELEM(H,n,1,1,level);
155  for (i=level+2; i<=m; i++) {
156  x = ACCESS(H,n,level+1,i);
160  }
161 
162  }
163  else level++;
164  }
165  }
166 
167  matrice_assign(PN,P,n,n);
168  matrice_assign(QN,Q,m,m);
169 
170  matrice_free(HN);
171  matrice_free(PN);
172  matrice_free(QN);
173 }
174 
175 /* int matrice_hermite_rank(matrice a, int n, int m): rang d'une matrice
176  * en forme de hermite
177  */
178 int matrice_hermite_rank(matrice a, int n, int m __attribute__ ((unused)))
179 {
180  int i;
181  int r = 0;
182 
183  for(i=1; i<=n; i++, r++)
184  if(value_zero_p(ACCESS(a, n, i, i))) break;
185 
186  return r;
187 }
188 
189 
190 /* Calcul de la dimension de la matrice de Hermite H.
191  * La matrice de Hermite est une matrice tres particuliere,
192  * pour laquelle il est tres facile de calculer sa dimension.
193  * Elle est egale au nombre de colonnes non nulles de la matrice.
194  */
195 
196 
197 int dim_H (H,n,m)
198 matrice H;
199 int n,m;
200 {
201 
202 
203  int i,j;
204  bool trouve_j = false;
205  int res=0;
206 
207  for (j = 1; j<=m && !trouve_j;j++) {
208  for (i=1; i<= n && value_zero_p(ACCESS(H,n,i,j)); i++);
209  if (i>n) {
210  trouve_j = true;
211  res= j-1;
212  }
213  }
214 
215 
216  if (!trouve_j && m>=1) res = m;
217  return (res);
218 
219 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
#define value_oppose(ref)
#define value_one_p(val)
#define value_zero_p(val)
int Value
#define value_division(ref, val)
#define VALUE_ONE
#define DENOMINATOR(matrix)
int DENOMINATEUR(matrix): acces au denominateur global d'une matrice matrix La combinaison *(&()) est...
Definition: matrice-local.h:93
#define matrice_free(m)
Definition: matrice-local.h:78
#define ACCESS(matrix, column, i, j)
Macros d'acces aux elements d'une matrice.
Definition: matrice-local.h:86
#define matrice_new(n, m)
Allocation et desallocation d'une matrice.
Definition: matrice-local.h:77
Value * matrice
package matrice
Definition: matrice-local.h:71
#define ACC_ELEM(matrix, column, i, j, level)
FI: Corinne, peux-tu expliquer la raison d'etre de cette macro?
int matrice_hermite_rank(matrice a, int n, int m __attribute__((unused)))
int matrice_hermite_rank(matrice a, int n, int m): rang d'une matrice en forme de hermite
Definition: hermite.c:178
int dim_H(matrice H, int n, int m)
Calcul de la dimension de la matrice de Hermite H.
Definition: hermite.c:197
void matrice_hermite(Value *MAT, int n, int m, Value *P, Value *H, Value *Q, Value *det_p, Value *det_q)
package matrice
Definition: hermite.c:78
void matrice_soustraction_colonne(matrice MAT, int n, int m __attribute__((unused)), int c1, int c2, Value x)
void matrice_soustraction_colonne(matrice MAT,int n,int m,int c1,int c2,int x): Soustrait x fois la c...
Definition: matrice.c:523
void matrice_assign(matrice A, matrice B, int n, int m)
void matrice_assign(matrice A, matrice B, int n, int m) Copie de la matrice A dans la matrice B
Definition: matrice.c:264
void matrice_swap_rows(matrice a, int n, int m, int r1, int r2)
void matrice_swap_rows(matrice a, int n, int m, int r1, int r2): exchange rows r1 and r2 of an (nxm) ...
Definition: matrice.c:230
void matrice_nulle(matrice Z, int n, int m)
void matrice_nulle(matrice Z, int n, int m): Initialisation de la matrice Z a la valeur matrice nulle
Definition: matrice.c:311
void matrice_swap_columns(matrice matrix, int n, int m, int c1, int c2)
void matrice_swap_columns(matrice matrix, int n, int m, int c1, int c2): exchange columns c1,...
Definition: matrice.c:200
int mat_lig_el(matrice, int, int, int)
int mat_lig_el(matrice MAT, int n, int m, int level) renvoie le numero de colonne absolu du premier e...
Definition: sous-matrice.c:381
void mat_coeff_nnul(matrice, int, int, int *, int *, int)
void mat_coeff_nnul(matrice MAT, int n, int m, int * lg_nnul, int * cl_nnul, int level) renvoie les c...
Definition: sous-matrice.c:426
void matrice_identite(matrice, int, int)
void matrice_identite(matrice ID, int n, int level) Construction d'une sous-matrice identite dans ID(...
Definition: sous-matrice.c:322
#define assert(ex)
Definition: newgen_assert.h:41
#define Q
Definition: pip__type.h:39
#define ALL
Definition: readmakefile.c:178
#define level
static char * x
Definition: split_file.c:159