PIPS
sous-matrice.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sous-matrice.c 1641 2016-03-02 08:20:19Z 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  /* ce fichier comporte les routines traitant des sous-matrices inferieures
28  droites; ces routines traitent la matrice toute entiere si le parametre
29  level vaut 0; les routines sur les matrices completes se trouvent dans
30  le fichier matrice.c
31  */
32 
33 #ifdef HAVE_CONFIG_H
34  #include "config.h"
35 #endif
36 
37 #include <stdio.h>
38 
39 #include "boolean.h"
40 #include "arithmetique.h"
41 
42 #include "matrice.h"
43 
44 #define MALLOC(s,t,f) malloc(s)
45 #define FREE(s,t,f) free(s)
46 
47 /* int mat_lig_nnul(matrice MAT, int n, int m, int level):
48  * Recherche de la premiere ligne non nulle de la
49  * la sous-matrice MAT(level+1 ..n, level+1 ..m)
50  *
51  * resultat retourne par la fonction :
52  *
53  * int : numero de la premiere ligne non nulle de la matrice MAT;
54  * ou 0 si la sous-matrice MAT(level+1 ..n,level+1 ..m) est identiquement nulle;
55  *
56  * parametres de la fonction :
57  *
58  * int MAT[] : matrice
59  * int n : nombre de lignes de la matrice
60  * int m : nombre de colonnes de la matrice
61  * int level : niveau de la matrice i.e. numero de la premiere ligne
62  * et de la premiere colonne a partir duquel on commence
63  * a prendre en compte les elements de la matrice
64  */
65 int mat_lig_nnul(MAT,n,m,level)
66 matrice MAT;
67 int n,m;
68 int level;
69 {
70  int i,j;
71  int I = 0;
72  bool trouve = false;
73 
74  /* recherche du premier element non nul de la sous-matrice */
75  for (i = level+1; i<=n && !trouve ; i++) {
76  for (j = level+1; j<= m && value_zero_p(ACCESS(MAT,n,i,j)); j++);
77  if(j <= m) {
78  /* on dumpe la colonne J... */
79  trouve = true;
80  I = i;
81  }
82  }
83  return (I);
84 }
85 
86 /* void mat_perm_col(matrice MAT, int n, int m, int k, int level):
87  * Calcul de la matrice de permutation permettant d'amener la k-ieme
88  * ligne de la matrice MAT(1..n,1..m) a la ligne (level + 1).
89  *
90  * Si l'on veut amener la k-ieme ligne de la matrice en premiere ligne
91  * 'level' doit avoir la valeur 0
92  *
93  * parametres de la fonction :
94  *
95  *!int MAT[] : matrice
96  * int n : nombre de lignes de la matrice
97  * int m : nombre de colonnes de la matrice (unused)
98  * int k : numero de la ligne a remonter a la premiere ligne
99  * int level : niveau de la matrice i.e. numero de la premiere ligne
100  * et de la premiere colonne a partir duquel on commence
101  * a prendre en compte les elements de la matrice
102  *
103  * Note: pour eviter une multiplication de matrice en O(n**3), il vaudrait
104  * mieux programmer directement la permutation en O(n**2) sans multiplications
105  * Il est inutile de faire souffrir notre chip SPARC! (FI)
106  */
107 /*ARGSUSED*/
109  int n __attribute__ ((unused)),
110  int m __attribute__ ((unused)),
111  int k,
112  int level)
113 {
114  int i,j;
115 
116  matrice_nulle(MAT,n,n);
117  if (level > 0) {
118  for (i=1;i<=level; i++)
119  ACCESS(MAT,n,i,i) = VALUE_ONE;
120  }
121 
122  for (i=1+level,j=k; i<=n; i++,j++)
123  {
124  if (j == n+1) j = 1 + level;
125  ACCESS(MAT,n,i,j)=VALUE_ONE;
126  }
127 }
128 
129 /* void mat_perm_lig(matrice MAT, int n, int m, int k, int level):
130  * Calcul de la matrice de permutation permettant d'amener la k-ieme
131  * colonne de la sous-matrice MAT(1..n,1..m) a la colonne 'level + 1'
132  * (premiere colonne de la sous matrice MAT(level+1 ..n,level+1 ..m)).
133  *
134  * parametres de la fonction :
135  *
136  *!int MAT[] : matrice
137  * int n : nombre de lignes de la matrice (unused)
138  * int m : nombre de colonnes de la matrice
139  * int k : numero de la colonne a placer a la premiere colonne
140  * int level : niveau de la matrice i.e. numero de la premiere ligne
141  * et de la premiere colonne a partir duquel on commence
142  * a prendre en compte les elements de la matrice
143  */
144 /*ARGSUSED*/
146  int n __attribute__ ((unused)),
147  int m __attribute__ ((unused)),
148  int k,
149  int level)
150 {
151  int i,j;
152 
153  matrice_nulle(MAT,m,m);
154  if(level > 0) {
155  for (i = 1; i <= level;i++)
156  ACCESS(MAT,m,i,i) = VALUE_ONE;
157  }
158 
159  for(j=1,i=k-level; j <= m - level; j++,i++) {
160  if(i == m-level+1)
161  i = 1;
162  ACC_ELEM(MAT,m,i,j,level) = VALUE_ONE;
163  }
164 }
165 
166 /* void mat_min(matrice MAT, int n, int m, int * i_min, int * j_min,
167  * int level):
168  * Recherche des coordonnees (*i_min, *j_min) de l'element
169  * de la sous-matrice MAT(level+1 ..n, level+1 ..m) dont la valeur absolue est
170  * la plus petite et non nulle.
171  *
172  * QQ i dans [level+1 ..n]
173  * QQ j dans [level+1 ..m]
174  * | MAT[*i_min, *j_min] | <= | MAT[i, j]
175  *
176  * resultat retourne par la fonction :
177  *
178  * les parametres i_min et j_min sont modifies.
179  *
180  * parametres de la fonction :
181  *
182  * int MAT[] : matrice
183  * int n : nombre de lignes de la matrice
184  * int m : nombre de colonnes de la matrice
185  *!int i_min : numero de la ligne a laquelle se trouve le plus petit
186  * element
187  *!int j_min : numero de la colonne a laquelle se trouve le plus petit
188  * int level : niveau de la matrice i.e. numero de la premiere ligne
189  * et de la premiere colonne a partir duquel on commence
190  * a prendre en compte les elements de la matrice
191  * element
192  */
193 void mat_min(MAT,n,m,i_min,j_min,level)
194 matrice MAT;
195 int n,m;
196 int *i_min,*j_min;
197 int level;
198 {
199  int i,j;
200  int vali= 0;
201  int valj=0;
202  register Value min=VALUE_ZERO, val;
203  bool trouve = false;
204 
205 
206  /* initialisation du minimum car recherche d'un minimum non nul*/
207  for (i=1+level;i<=n && !trouve;i++)
208  for(j = level+1; j <= m && !trouve; j++) {
209  min = ACCESS(MAT,n,i,j);
211  if(min != 0) {
212  trouve = true;
213  vali = i;
214  valj = j;
215  }
216  }
217 
218  for (i=1+level;i<=n;i++)
219  for (j=1+level;j<=m && value_gt(min,VALUE_ONE); j++) {
220  val = ACCESS(MAT,n,i,j);
221  value_absolute(val);
222  if (value_notzero_p(val) && value_lt(val,min)) {
223  min = val;
224  vali= i;
225  valj =j;
226  }
227  }
228  *i_min = vali;
229  *j_min = valj;
230 }
231 
232 /* void mat_maj_col(matrice A, int n, int m, matrice P, int level):
233  * Calcul de la matrice permettant de remplacer chaque terme de
234  * la premiere ligne de la sous-matrice A(level+1 ..n, level+1 ..m) autre
235  * que le premier terme A11=A(level+1,level+1) par le reste de sa
236  * division entiere par A11
237  *
238  *
239  * La matrice P est modifiee.
240  *
241  * Les parametres de la fonction :
242  *
243  * int A[1..n,1..m] : matrice
244  * int n : nombre de lignes de la matrice
245  * int m : nombre de colonnes de la matrice (unused)
246  *!int P[] : matrice de dimension au moins P[1..n, 1..n]
247  * int level : niveau de la matrice i.e. numero de la premiere ligne
248  * et de la premiere colonne a partir duquel on commence
249  * a prendre en compte les elements de la matrice
250  */
251 /*ARGSUSED*/
253  int n __attribute__ ((unused)),
254  int m __attribute__ ((unused)),
255  matrice P,
256  int level)
257 {
258  register Value A11;
259  register Value x;
260  int i;
261 
262  matrice_identite(P,n,0);
263 
264  A11 = ACC_ELEM(A,n,1,1,level);
265  for (i=2+level; i<=n; i++) {
266  x = ACCESS(A,n,i,1+level);
267  value_division(x,A11);
268  ACCESS(P,n,i,1+level) = value_uminus(x);
269  }
270 }
271 
272 /* void mat_maj_lig(matrice A, int n, int m, matrice Q, int level):
273  * Calcul de la matrice permettant de remplacer chaque terme de
274  * la premiere ligne autre que le premier terme A11=A(level+1,level+1)
275  * par le reste de sa
276  * division entiere par A11
277  *
278  *
279  * La matrice Q est modifiee.
280  *
281  * Les parametres de la fonction :
282  *
283  * int A[] : matrice
284  * int n : nombre de lignes de la matrice
285  * int m : nombre de colonnes de la matrice
286  *!int Q[] : matrice
287  * int level : niveau de la matrice i.e. numero de la premiere ligne
288  * et de la premiere colonne a partir duquel on commence
289  * a prendre en compte les elements de la matrice
290  *
291  */
292 void mat_maj_lig(A,n,m,Q,level)
293 matrice A;
294 int n,m;
295 matrice Q;
296 int level;
297 {
298  register Value A11;
299  int j;
300  register Value x;
301 
302  matrice_identite(Q,m,0);
303  A11 = ACC_ELEM(A,n,1,1,level);
304  for (j=2+level; j<=m; j++) {
305  x = ACCESS(A,n,1+level,j);
306  value_division(x,A11);
307  ACCESS(Q,m,1+level,j) = value_uminus(x);
308  }
309 }
310 
311 /* void matrice_identite(matrice ID, int n, int level)
312  * Construction d'une sous-matrice identite dans ID(level+1..n, level+1..n)
313  *
314  * Les parametres de la fonction :
315  *
316  *!int ID[] : matrice
317  * int n : nombre de lignes de la matrice
318  * int level : niveau de la matrice i.e. numero de la premiere ligne
319  * et de la premiere colonne a partir duquel on commence
320  * a prendre en compte les elements de la matrice
321  */
323 matrice ID;
324 int n;
325 int level;
326 {
327  int i,j;
328 
329  for(i = level+1; i <= n; i++) {
330  for(j = level+1; j <= n; j++)
331  ACCESS(ID,n,i,j) = VALUE_ZERO;
332  ACCESS(ID,n,i,i) = VALUE_ONE;
333  }
334 
335  DENOMINATOR(ID) = VALUE_ONE;
336 }
337 
338 /* bool matrice_identite_p(matrice ID, int n, int level)
339  * test d'une sous-matrice dans ID(level+1..n, level+1..n) pour savoir si
340  * c'est une matrice identite. Le test n'est correct que si la matrice
341  * ID passee en argument est normalisee (cf. matrice_normalize())
342  *
343  * Pour tester toute la matrice ID, appeler avec level==0
344  *
345  * Les parametres de la fonction :
346  *
347  * int ID[] : matrice
348  * int n : nombre de lignes (et de colonnes) de la matrice ID
349  * int level : niveau de la matrice i.e. numero de la premiere ligne
350  * et de la premiere colonne a partir duquel on commence
351  * a prendre en compte les elements de la matrice
352  */
354 matrice ID;
355 int n;
356 int level;
357 {
358  int i,j;
359 
360  for(i = level+1; i <= n; i++) {
361  for(j = level+1; j <= n; j++) {
362  if(i==j) {
363  if(value_notone_p(ACCESS(ID,n,i,i)))
364  return(false);
365  }
366  else /* i!=j */
367  if(value_notzero_p(ACCESS(ID,n,i,j)))
368  return(false);
369  }
370  }
371  return(true);
372 }
373 
374 /* int mat_lig_el(matrice MAT, int n, int m, int level)
375  * renvoie le numero de colonne absolu du premier element non nul
376  * de la sous-ligne MAT(level+1,level+2..m);
377  * renvoie 0 si la sous-ligne est vide.
378  *
379  */
380 /*ARGUSED*/
381 int mat_lig_el(MAT,n,m,level)
382 matrice MAT;
383 int n,m;
384 int level;
385 {
386  int j;
387  int j_min = 0;
388 
389  /* recherche du premier element non nul de la sous-ligne
390  MAT(level+1,level+2..m) */
391  for(j = level+2; j<=m && value_zero_p(ACCESS(MAT,n,1+level,j)) ; j++);
392  if(j < m+1)
393  j_min = j-1;
394  return (j_min);
395 }
396 
397 /* int mat_col_el(matrice MAT, int n, int m, int level)
398  * renvoie le numero de ligne absolu du premier element non nul
399  * de la sous-colonne MAT(level+2..n,level+1);
400  * renvoie 0 si la sous-colonne est vide.
401  *
402  */
403 /*ARGSUSED*/
405  int n,
406  int m __attribute__ ((unused)),
407  int level)
408 {
409  int i;
410  int i_min=0;
411 
412  for(i = level+2; i <= n && value_zero_p(ACCESS(MAT,n,i,level+1)); i++);
413  if (i<n+1)
414  i_min = i-1;
415  return (i_min);
416 }
417 
418 /* void mat_coeff_nnul(matrice MAT, int n, int m, int * lg_nnul,
419  * int * cl_nnul, int level)
420  * renvoie les coordonnees du plus petit element non-nul de la premiere
421  * sous-ligne non nulle 'lg_nnul' de la sous-matrice
422  MAT(level+1..n, level+1..m)
423  *
424  *
425  */
426 void mat_coeff_nnul(MAT,n,m,lg_nnul,cl_nnul,level)
427 matrice MAT;
428 int n,m;
429 int *lg_nnul,*cl_nnul;
430 int level;
431 {
432  bool trouve = false;
433  int j;
434  register Value min=VALUE_ZERO,val;
435 
436  *lg_nnul = 0;
437  *cl_nnul = 0;
438 
439  /* recherche de la premiere ligne non nulle de la
440  sous-matrice MAT(level+1 .. n,level+1 .. m) */
441 
442  *lg_nnul= mat_lig_nnul(MAT,n,m,level);
443 
444  /* recherche du plus petit (en valeur absolue)
445  * element non nul de cette ligne */
446  if (*lg_nnul) {
447  for (j=1+level;j<=m && !trouve; j++) {
448  min = ACCESS(MAT,n,*lg_nnul,j);
450  if (value_notzero_p(min)) {
451  trouve = true;
452  *cl_nnul=j;
453  }
454  }
455  for (j=1+level;j<=m && value_gt(min,VALUE_ONE); j++) {
456  val = ACCESS(MAT,n,*lg_nnul,j);
457  value_absolute(val);
458  if (value_notzero_p(val) && value_lt(val,min)) {
459  min = val;
460  *cl_nnul =j;
461  }
462  }
463  }
464 }
465 
466 
467 
468 
469 
470 
471 
472 
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_ZERO
#define value_absolute(ref)
#define value_gt(v1, v2)
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_notone_p(val)
#define value_zero_p(val)
int Value
#define value_division(ref, val)
#define VALUE_ONE
#define value_lt(v1, v2)
#define A(i, j)
comp_matrice.c
Definition: comp_matrice.c:63
#define min(a, b)
#define DENOMINATOR(matrix)
int DENOMINATEUR(matrix): acces au denominateur global d'une matrice matrix La combinaison *(&()) est...
Definition: matrice-local.h:93
#define ACCESS(matrix, column, i, j)
Macros d'acces aux elements d'une matrice.
Definition: matrice-local.h:86
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?
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
#define Q
Definition: pip__type.h:39
#define level
void mat_min(matrice MAT, int n, int m, int *i_min, int *j_min, int level)
void mat_min(matrice MAT, int n, int m, int * i_min, int * j_min, int level): Recherche des coordonne...
Definition: sous-matrice.c:193
void mat_maj_col(matrice A, int n __attribute__((unused)), int m __attribute__((unused)), matrice P, int level)
void mat_maj_col(matrice A, int n, int m, matrice P, int level): Calcul de la matrice permettant de r...
Definition: sous-matrice.c:252
int mat_lig_nnul(matrice MAT, int n, int m, int level)
int mat_lig_nnul(matrice MAT, int n, int m, int level): Recherche de la premiere ligne non nulle de l...
Definition: sous-matrice.c:65
void mat_maj_lig(matrice A, int n, int m, matrice Q, int level)
void mat_maj_lig(matrice A, int n, int m, matrice Q, int level): Calcul de la matrice permettant de r...
Definition: sous-matrice.c:292
void matrice_identite(matrice ID, int n, int level)
void matrice_identite(matrice ID, int n, int level) Construction d'une sous-matrice identite dans ID(...
Definition: sous-matrice.c:322
bool matrice_identite_p(matrice ID, int n, int level)
bool matrice_identite_p(matrice ID, int n, int level) test d'une sous-matrice dans ID(level+1....
Definition: sous-matrice.c:353
void mat_perm_col(matrice MAT, int n __attribute__((unused)), int m __attribute__((unused)), int k, int level)
void mat_perm_col(matrice MAT, int n, int m, int k, int level): Calcul de la matrice de permutation p...
Definition: sous-matrice.c:108
int mat_col_el(matrice MAT, int n, int m __attribute__((unused)), int level)
int mat_col_el(matrice MAT, int n, int m, int level) renvoie le numero de ligne absolu du premier ele...
Definition: sous-matrice.c:404
void mat_perm_lig(matrice MAT, int n __attribute__((unused)), int m __attribute__((unused)), int k, int level)
void mat_perm_lig(matrice MAT, int n, int m, int k, int level): Calcul de la matrice de permutation p...
Definition: sous-matrice.c:145
void mat_coeff_nnul(matrice MAT, int n, int m, int *lg_nnul, int *cl_nnul, int level)
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
int mat_lig_el(matrice MAT, int n, int m, int level)
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
static char * x
Definition: split_file.c:159
Definition: pip__tab.h:25