PIPS
sub-matrix.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sub-matrix.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 matrix */
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 /* J'ai rajoute' une fonction peremttant d'extraire une sous matrice quelconque
34  * d'une matrice donne'e BC, Sept 94
35  */
36 
37 #ifdef HAVE_CONFIG_H
38  #include "config.h"
39 #endif
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 
44 #include "linear_assert.h"
45 
46 #include "boolean.h"
47 #include "arithmetique.h"
48 
49 #include "matrix.h"
50 
51 #define MALLOC(s,t,f) malloc(s)
52 #define FREE(s,t,f) free(s)
53 
54 /* int matrix_line_nnul(matrice MAT,int level):
55  * Recherche de la premiere ligne non nulle de la
56  * la sous-matrice MAT(level+1 ..n, level+1 ..m)
57  *
58  * resultat retourne par la fonction :
59  *
60  * int : numero de la premiere ligne non nulle de la matrice MAT;
61  * ou 0 si la sous-matrice MAT(level+1 ..n,level+1 ..m) est identiquement nulle;
62  *
63  * parametres de la fonction :
64  *
65  * int MAT[] : matrice
66  * int n : nombre de lignes de la matrice
67  * int m : nombre de colonnes de la matrice
68  * int level : niveau de la matrice i.e. numero de la premiere ligne
69  * et de la premiere colonne a partir duquel on commence
70  * a prendre en compte les elements de la matrice
71  */
73 Pmatrix MAT;
74 int level;
75 {
76  int i,j;
77  int I = 0;
78  bool trouve = false;
79  int n = MATRIX_NB_LINES(MAT);
80  int m= MATRIX_NB_COLUMNS(MAT);
81  /* recherche du premier element non nul de la sous-matrice */
82  for (i = level+1; i<=n && !trouve ; i++) {
83  for (j = level+1; j<= m && (MATRIX_ELEM(MAT,i,j) == 0); j++);
84  if(j <= m) {
85  /* on dumpe la colonne J... */
86  trouve = true;
87  I = i;
88  }
89  }
90  return (I);
91 }
92 
93 /* void matrix_perm_col(Pmatrix MAT, int k, int level):
94  * Calcul de la matrice de permutation permettant d'amener la k-ieme
95  * ligne de la matrice MAT(1..n,1..m) a la ligne (level + 1).
96  *
97  * Si l'on veut amener la k-ieme ligne de la matrice en premiere ligne
98  * 'level' doit avoir la valeur 0
99  *
100  * parametres de la fonction :
101  *
102  *!int MAT[] : matrice
103  * int n : nombre de lignes de la matrice
104  * int m : nombre de colonnes de la matrice (unused)
105  * int k : numero de la ligne a remonter a la premiere ligne
106  * int level : niveau de la matrice i.e. numero de la premiere ligne
107  * et de la premiere colonne a partir duquel on commence
108  * a prendre en compte les elements de la matrice
109  *
110  * Note: pour eviter une multiplication de matrice en O(n**3), il vaudrait
111  * mieux programmer directement la permutation en O(n**2) sans multiplications
112  * Il est inutile de faire souffrir notre chip SPARC! (FI)
113  */
114 /*ARGSUSED*/
116 Pmatrix MAT;
117 int k,level;
118 {
119  int i,j;
120  int n = MATRIX_NB_LINES(MAT);
121  matrix_nulle(MAT);
122  if (level > 0) {
123  for (i=1;i<=level; i++)
124  MATRIX_ELEM(MAT,i,i) = VALUE_ONE;
125  }
126 
127  for (i=1+level,j=k; i<=n; i++,j++)
128  {
129  if (j == n+1) j = 1 + level;
130  MATRIX_ELEM(MAT,i,j)=VALUE_ONE;
131  }
132 }
133 
134 /* void matrix_perm_line(Pmatrix MAT, int k, int level):
135  * Calcul de la matrice de permutation permettant d'amener la k-ieme
136  * colonne de la sous-matrice MAT(1..n,1..m) a la colonne 'level + 1'
137  * (premiere colonne de la sous matrice MAT(level+1 ..n,level+1 ..m)).
138  *
139  * parametres de la fonction :
140  *
141  *!int MAT[] : matrice
142  * int n : nombre de lignes de la matrice (unused)
143  * int m : nombre de colonnes de la matrice
144  * int k : numero de la colonne a placer a la premiere colonne
145  * int level : niveau de la matrice i.e. numero de la premiere ligne
146  * et de la premiere colonne a partir duquel on commence
147  * a prendre en compte les elements de la matrice
148  */
149 /*ARGSUSED*/
151 Pmatrix MAT;
152 int k,level;
153 {
154  int i,j;
155  int m= MATRIX_NB_COLUMNS(MAT);
156  matrix_nulle(MAT);
157  if(level > 0) {
158  for (i = 1; i <= level;i++)
159  MATRIX_ELEM(MAT,i,i) = VALUE_ONE;
160  }
161 
162  for(j=1,i=k-level; j <= m - level; j++,i++) {
163  if(i == m-level+1)
164  i = 1;
165  SUB_MATRIX_ELEM(MAT,i,j,level) = VALUE_ONE;
166  }
167 }
168 
169 /* void matrix_min(Pmatrix MAT, int * i_min, int * j_min,
170  * int level):
171  * Recherche des coordonnees (*i_min, *j_min) de l'element
172  * de la sous-matrice MAT(level+1 ..n, level+1 ..m) dont la valeur absolue est
173  * la plus petite et non nulle.
174  *
175  * QQ i dans [level+1 ..n]
176  * QQ j dans [level+1 ..m]
177  * | MAT[*i_min, *j_min] | <= | MAT[i, j]
178  *
179  * resultat retourne par la fonction :
180  *
181  * les parametres i_min et j_min sont modifies.
182  *
183  * parametres de la fonction :
184  *
185  * int MAT[] : matrice
186  * int n : nombre de lignes de la matrice
187  * int m : nombre de colonnes de la matrice
188  *!int i_min : numero de la ligne a laquelle se trouve le plus petit
189  * element
190  *!int j_min : numero de la colonne a laquelle se trouve le plus petit
191  * int level : niveau de la matrice i.e. numero de la premiere ligne
192  * et de la premiere colonne a partir duquel on commence
193  * a prendre en compte les elements de la matrice
194  * element
195  */
196 void matrix_min(MAT,i_min,j_min,level)
197 Pmatrix MAT;
198 int *i_min,*j_min;
199 int level;
200 {
201  int i,j;
202  int vali= 0;
203  int valj=0;
205  Value val=VALUE_ZERO;
206  bool trouve = false;
207 
208  int n = MATRIX_NB_LINES(MAT);
209  int m= MATRIX_NB_COLUMNS(MAT);
210  /* initialisation du minimum car recherche d'un minimum non nul*/
211  for (i=1+level;i<=n && !trouve;i++)
212  for(j = level+1; j <= m && !trouve; j++) {
213  min = MATRIX_ELEM(MAT,i,j);
214  min = value_abs(min);
215  if(value_notzero_p(min)) {
216  trouve = true;
217  vali = i;
218  valj = j;
219  }
220  }
221 
222  for (i=1+level;i<=n;i++)
223  for (j=1+level;j<=m && value_gt(min,VALUE_ONE); j++) {
224  val = MATRIX_ELEM(MAT,i,j);
225  val = value_abs(val);
226  if (value_notzero_p(val) && value_lt(val,min)) {
227  min = val;
228  vali= i;
229  valj =j;
230  }
231  }
232  *i_min = vali;
233  *j_min = valj;
234 }
235 
236 /* void matrix_maj_col(Pmatrix A, matrice P, int level):
237  * Calcul de la matrice permettant de remplacer chaque terme de
238  * la premiere ligne de la sous-matrice A(level+1 ..n, level+1 ..m) autre
239  * que le premier terme A11=A(level+1,level+1) par le reste de sa
240  * division entiere par A11
241  *
242  *
243  * La matrice P est modifiee.
244  *
245  * Les parametres de la fonction :
246  *
247  * int A[1..n,1..m] : matrice
248  * int n : nombre de lignes de la matrice
249  * int m : nombre de colonnes de la matrice (unused)
250  *!int P[] : matrice de dimension au moins P[1..n, 1..n]
251  * int level : niveau de la matrice i.e. numero de la premiere ligne
252  * et de la premiere colonne a partir duquel on commence
253  * a prendre en compte les elements de la matrice
254  */
255 /*ARGSUSED*/
257 Pmatrix A;
258 Pmatrix P;
259 int level;
260 {
261  Value A11;
262  int i;
263  Value x;
264  int n = MATRIX_NB_LINES(A);
265  matrix_identity(P,0);
266 
267  A11 =SUB_MATRIX_ELEM(A,1,1,level);
268  for (i=2+level; i<=n; i++) {
269  x = MATRIX_ELEM(A,i,1+level);
270  value_division(x,A11);
271  MATRIX_ELEM(P,i,1+level) = value_uminus(x);
272  }
273 }
274 
275 /* void matrix_maj_line(Pmatrix A, matrice Q, int level):
276  * Calcul de la matrice permettant de remplacer chaque terme de
277  * la premiere ligne autre que le premier terme A11=A(level+1,level+1) par le reste de sa
278  * division entiere par A11
279  *
280  *
281  * La matrice Q est modifiee.
282  *
283  * Les parametres de la fonction :
284  *
285  * int A[] : matrice
286  * int n : nombre de lignes de la matrice
287  * int m : nombre de colonnes de la matrice
288  *!int Q[] : matrice
289  * int level : niveau de la matrice i.e. numero de la premiere ligne
290  * et de la premiere colonne a partir duquel on commence
291  * a prendre en compte les elements de la matrice
292  *
293  */
295 Pmatrix A;
296 Pmatrix Q;
297 int level;
298 {
299  Value A11;
300  int j;
301  Value x;
302  int m= MATRIX_NB_COLUMNS(A);
303  matrix_identity(Q,0);
304  A11 =SUB_MATRIX_ELEM(A,1,1,level);
305  for (j=2+level; j<=m; j++) {
306  x = value_div(MATRIX_ELEM(A,1+level,j),A11);
307  MATRIX_ELEM(Q,1+level,j) = value_uminus(x);
308  }
309 }
310 
311 /* void matrix_identity(Pmatrix ID, int level)
312  * Construction d'une sous-matrice identity 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 Pmatrix ID;
324 int level;
325 {
326  int i,j;
327  int n = MATRIX_NB_LINES(ID);
328  for(i = level+1; i <= n; i++) {
329  for(j = level+1; j <= n; j++)
330  MATRIX_ELEM(ID,i,j) = VALUE_ZERO;
331  MATRIX_ELEM(ID,i,i) = VALUE_ONE;
332  }
333 
335 }
336 
337 /* bool matrix_identity_p(Pmatrix ID, int level)
338  * test d'une sous-matrice dans ID(level+1..n, level+1..n) pour savoir si
339  * c'est une matrice identity. Le test n'est correct que si la matrice
340  * ID passee en argument est normalisee (cf. matrix_normalize())
341  *
342  * Pour tester toute la matrice ID, appeler avec level==0
343  *
344  * Les parametres de la fonction :
345  *
346  * int ID[] : matrice
347  * int n : nombre de lignes (et de colonnes) de la matrice ID
348  * int level : niveau de la matrice i.e. numero de la premiere ligne
349  * et de la premiere colonne a partir duquel on commence
350  * a prendre en compte les elements de la matrice
351  */
353 Pmatrix ID;
354 int level;
355 {
356  int i,j;
357  int n = MATRIX_NB_LINES(ID);
358  for(i = level+1; i <= n; i++) {
359  for(j = level+1; j <= n; j++) {
360  if(i==j) {
361  if(value_notone_p(MATRIX_ELEM(ID,i,i)))
362  return(false);
363  }
364  else /* i!=j */
365  if(value_notzero_p(MATRIX_ELEM(ID,i,j)))
366  return(false);
367  }
368  }
369  return(true);
370 }
371 
372 /* int matrix_line_el(Pmatrix MAT, int level)
373  * renvoie le numero de colonne absolu du premier element non nul
374  * de la sous-ligne MAT(level+1,level+2..m);
375  * renvoie 0 si la sous-ligne est vide.
376  *
377  */
378 /*ARGUSED*/
380 Pmatrix MAT;
381 int level;
382 {
383  int j;
384  int j_min = 0;
385  int m = MATRIX_NB_COLUMNS(MAT);
386  /* recherche du premier element non nul de la sous-ligne
387  MAT(level+1,level+2..m) */
388  for(j = level+2; j<=m && (MATRIX_ELEM(MAT,1+level,j)==0) ; j++);
389  if(j < m+1)
390  j_min = j-1;
391  return (j_min);
392 }
393 
394 /* int matrix_col_el(Pmatrix MAT, int level)
395  * renvoie le numero de ligne absolu du premier element non nul
396  * de la sous-colonne MAT(level+2..n,level+1);
397  * renvoie 0 si la sous-colonne est vide.
398  *
399  */
400 /*ARGSUSED*/
402 Pmatrix MAT;
403 int level;
404 {
405  int i;
406  int i_min=0;
407  int n = MATRIX_NB_LINES(MAT);
408  for(i = level+2; i <= n && (MATRIX_ELEM(MAT,i,level+1)==0); i++);
409  if (i<n+1)
410  i_min = i-1;
411  return (i_min);
412 }
413 
414 /* void matrix_coeff_nnul(Pmatrix MAT, int * lg_nnul,
415  * int * cl_nnul, int level)
416  * renvoie les coordonnees du plus petit element non-nul de la premiere
417  * sous-ligne non nulle 'lg_nnul' de la sous-matrice MAT(level+1..n, level+1..m)
418  *
419  *
420  */
421 void matrix_coeff_nnul(MAT,lg_nnul,cl_nnul,level)
422 Pmatrix MAT;
423 int *lg_nnul,*cl_nnul;
424 int level;
425 {
426  bool trouve = false;
427  int j;
429  int m = MATRIX_NB_COLUMNS(MAT);
430  *lg_nnul = 0;
431  *cl_nnul = 0;
432 
433  /* recherche de la premiere ligne non nulle de la
434  sous-matrice MAT(level+1 .. n,level+1 .. m) */
435 
436  *lg_nnul= matrix_line_nnul(MAT,level);
437 
438  /* recherche du plus petit (en valeur absolue) element non nul de cette ligne */
439  if (*lg_nnul) {
440  for (j=1+level;j<=m && !trouve; j++) {
441  min = MATRIX_ELEM(MAT,*lg_nnul,j);
442  min = value_abs(min);
443  if (value_notzero_p(min)) {
444  trouve = true;
445  *cl_nnul=j;
446  }
447  }
448  for (j=1+level;j<=m && value_gt(min,VALUE_ONE); j++) {
449  val = MATRIX_ELEM(MAT,*lg_nnul,j);
450  val = value_abs(val);
451  if (value_notzero_p(val) && value_lt(val,min)) {
452  min = val;
453  *cl_nnul =j;
454  }
455  }
456  }
457 }
458 
459 
460 
461 /* void ordinary_sub_matrix(Pmatrix A, A_sub, int i1, i2, j1, j2)
462  * input : a initialized matrix A, an uninitialized matrix A_sub,
463  * which dimensions are i2-i1+1 and j2-j1+1.
464  * output : nothing.
465  * modifies : A_sub is initialized with the elements of A which coordinates range
466  * within [i1,i2] and [j1,j2].
467  * comment : A_sub must be already allocated.
468  */
469 void ordinary_sub_matrix(A, A_sub, i1, i2, j1, j2)
470 Pmatrix A, A_sub;
471 int i1, i2, j1, j2;
472 {
473  int i, j, i_sub, j_sub;
474 
475  for(i = i1, i_sub = 1; i <= i2; i++, i_sub ++)
476  for(j = j1, j_sub = 1; j <= j2; j++, j_sub ++)
477  MATRIX_ELEM(A_sub,i_sub,j_sub) = MATRIX_ELEM(A,i,j);
478 
479 }
480 
481 /* void insert_sub_matrix(A, A_sub, i1, i2, j1, j2)
482  * input: matrix A and smaller A_sub
483  * output: nothing
484  * modifies: A_sub is inserted in A at the specified position
485  * comment: A must be pre-allocated
486  */
488  Pmatrix A,
489  Pmatrix A_sub,
490  int i1, int i2,
491  int j1, int j2)
492 {
493  int i,j,i_sub,j_sub;
494 
495  assert(i1>=1 && j1>=1 &&
496  i2<=MATRIX_NB_LINES(A) && j2<=MATRIX_NB_COLUMNS(A) &&
497  i2-i1<MATRIX_NB_LINES(A_sub) && j2-j1<MATRIX_NB_COLUMNS(A_sub));
498 
499  for (i = i1, i_sub = 1; i <= i2; i++, i_sub ++)
500  for(j = j1, j_sub = 1; j <= j2; j++, j_sub ++)
501  MATRIX_ELEM(A,i,j) = MATRIX_ELEM(A_sub,i_sub,j_sub) ;
502 }
503 
504 /* that is all
505  */
#define VALUE_ZERO
#define value_gt(v1, v2)
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_notone_p(val)
int Value
#define value_division(ref, val)
#define VALUE_ONE
#define value_abs(val)
#define value_lt(v1, v2)
#define value_div(v1, v2)
#define A(i, j)
comp_matrice.c
Definition: comp_matrice.c:63
#define min(a, b)
#define SUB_MATRIX_ELEM(matrix, i, j, level)
MATRIX_RIGHT_INF_ELEM Permet d'acceder des sous-matrices dont le coin infe'rieur droit (i....
Definition: matrix-local.h:106
#define MATRIX_NB_LINES(matrix)
Definition: matrix-local.h:87
#define MATRIX_NB_COLUMNS(matrix)
Definition: matrix-local.h:88
#define MATRIX_DENOMINATOR(matrix)
int MATRIX_DENONIMATOR(matrix): acces au denominateur global d'une matrice matrix
Definition: matrix-local.h:86
#define MATRIX_ELEM(matrix, i, j)
Macros d'acces aux elements d'une matrice.
Definition: matrix-local.h:80
void matrix_nulle(Pmatrix Z)
void matrix_nulle(Pmatrix Z): Initialisation de la matrice Z a la valeur matrice nulle
Definition: matrix.c:293
#define assert(ex)
Definition: newgen_assert.h:41
#define Q
Definition: pip__type.h:39
#define level
static char * x
Definition: split_file.c:159
Definition: pip__tab.h:25
package matrice
Definition: matrix-local.h:63
void insert_sub_matrix(Pmatrix A, Pmatrix A_sub, int i1, int i2, int j1, int j2)
void insert_sub_matrix(A, A_sub, i1, i2, j1, j2) input: matrix A and smaller A_sub output: nothing mo...
Definition: sub-matrix.c:487
int matrix_line_el(Pmatrix MAT, int level)
int matrix_line_el(Pmatrix MAT, int level) renvoie le numero de colonne absolu du premier element non...
Definition: sub-matrix.c:379
void matrix_maj_col(Pmatrix A, Pmatrix P, int level)
void matrix_maj_col(Pmatrix A, matrice P, int level): Calcul de la matrice permettant de remplacer ch...
Definition: sub-matrix.c:256
void matrix_min(Pmatrix MAT, int *i_min, int *j_min, int level)
void matrix_min(Pmatrix MAT, int * i_min, int * j_min, int level): Recherche des coordonnees (*i_min,...
Definition: sub-matrix.c:196
void matrix_perm_line(Pmatrix MAT, int k, int level)
void matrix_perm_line(Pmatrix MAT, int k, int level): Calcul de la matrice de permutation permettant...
Definition: sub-matrix.c:150
int matrix_col_el(Pmatrix MAT, int level)
int matrix_col_el(Pmatrix MAT, int level) renvoie le numero de ligne absolu du premier element non nu...
Definition: sub-matrix.c:401
void matrix_identity(Pmatrix ID, int level)
void matrix_identity(Pmatrix ID, int level) Construction d'une sous-matrice identity dans ID(level+1....
Definition: sub-matrix.c:322
bool matrix_identity_p(Pmatrix ID, int level)
bool matrix_identity_p(Pmatrix ID, int level) test d'une sous-matrice dans ID(level+1....
Definition: sub-matrix.c:352
void matrix_maj_line(Pmatrix A, Pmatrix Q, int level)
void matrix_maj_line(Pmatrix A, matrice Q, int level): Calcul de la matrice permettant de remplacer c...
Definition: sub-matrix.c:294
void matrix_perm_col(Pmatrix MAT, int k, int level)
void matrix_perm_col(Pmatrix MAT, int k, int level): Calcul de la matrice de permutation permettant ...
Definition: sub-matrix.c:115
void ordinary_sub_matrix(Pmatrix A, Pmatrix A_sub, int i1, int i2, int j1, int j2)
void ordinary_sub_matrix(Pmatrix A, A_sub, int i1, i2, j1, j2) input : a initialized matrix A,...
Definition: sub-matrix.c:469
void matrix_coeff_nnul(Pmatrix MAT, int *lg_nnul, int *cl_nnul, int level)
void matrix_coeff_nnul(Pmatrix MAT, int * lg_nnul, int * cl_nnul, int level) renvoie les coordonnees ...
Definition: sub-matrix.c:421
int matrix_line_nnul(Pmatrix MAT, int level)
int matrix_line_nnul(matrice MAT,int level): Recherche de la premiere ligne non nulle de la la sous-m...
Definition: sub-matrix.c:72