PIPS
smith.c
Go to the documentation of this file.
1 /*
2 
3  $Id: smith.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 <stdio.h>
32 #include <stdlib.h>
33 #include <stdlib.h>
34 
35 #include "linear_assert.h"
36 
37 #include "boolean.h"
38 #include "arithmetique.h"
39 
40 #include "matrice.h"
41 
42 #define MALLOC(s,t,f) malloc((unsigned)(s))
43 #define FREE(s,t,f) free((char *)(s))
44 
45 /* void matrice_smith(matrice MAT, int n, int m, matrice P, matrice D,
46  * matrice Q):
47  * Calcul de la forme reduite de Smith D d'une matrice entiere MAT et des deux
48  * matrices de changement de base unimodulaires associees, P et Q.
49  *
50  * D est la forme reduite de Smith, P et Q sont des matrices unimodulaires;
51  * telles que D == P x MAT x Q
52  *
53  * (c.f. Programmation Lineaire. M.MINOUX. (83))
54  *
55  * int MAT[n,m] : matrice
56  * int n : nombre de lignes de la matrice MAT
57  * int m : nombre de colonnes de la matrice MAT
58  * int P[n,n] : matrice
59  * int D[n,m] : matrice (quasi-diagonale) reduite de Smith
60  * int Q[m,m] : matrice
61  *
62  * Les 3 matrices P(nxn), Q(mxm) et D(nxm) doivent etre allouees avant le
63  * calcul.
64  *
65  * Note: les determinants des matrices MAT, P, Q et D ne sont pas utilises.
66  *
67  */
68 void matrice_smith(MAT,n,m,P,D,Q)
69 matrice MAT;
70 int n,m;
71 matrice P;
72 matrice D;
73 matrice Q;
74 {
75  int n_min,m_min;
76  int level = 0;
77  register Value ALL; /* le plus petit element sur la diagonale */
78  register Value x; /* le rest de la division par ALL */
79  int i;
80 
81  bool stop = false;
82  bool next = true;
83 
84  /* precondition sur les parametres */
85  assert(m > 0 && n >0);
86  matrice_assign(MAT,D,n,m);
88 
89  matrice_identite(P,n,0);
90  matrice_identite(Q,m,0);
91 
92  while (!stop) {
93  mat_min(D,n,m,&n_min,&m_min,level);
94 
95  if ((n_min == 0) && (m_min == 0))
96  stop = true;
97  else {
98  /* le transformation n'est pas fini. */
99  if (n_min > level +1) {
100  matrice_swap_rows(D,n,m,level+1,n_min);
101  matrice_swap_rows(P,n,n,level+1,n_min);
102  }
103 #ifdef TRACE
104  (void) printf (" apres alignement du plus petit element a la premiere ligne \n");
105  matrice_print(D,n,m);
106 #endif
107  if (m_min >1+level) {
108  matrice_swap_columns(D,n,m,level+1,m_min);
109  matrice_swap_columns(Q,m,m,level+1,m_min);
110  }
111 #ifdef TRACE
112  (void) printf (" apres alignement du plus petit element"
113  " a la premiere colonne\n");
114  matrice_print(D,n,m);
115 #endif
116 
117  ALL = ACC_ELEM(D,n,1,1,level);
118  if (mat_lig_el(D,n,m,level) != 0)
119  for (i=level+2; i<=m; i++) {
120  x = ACCESS(D,n,level+1,i);
124  next = false;
125  }
126  if (mat_col_el(D,n,m,level) != 0)
127  for(i=level+2;i<=n;i++) {
128  x = ACCESS(D,n,i,level+1);
132  next = false;
133  }
134 #ifdef TRACE
135  (void) printf("apres division par A(%d,%d) des termes de la %d-ieme ligne et de la %d-em colonne \n",level+1,level+1,level+1,level+1);
136  matrice_print(D,n,m);
137 #endif
138  if (next) level++;
139  next = true;
140  }
141  }
142 
143 #ifdef TRACE
144  (void) printf (" la matrice D apres transformation est la suivante :");
145  matrice_print(D,n,m);
146 
147  (void) printf (" la matrice P est \n");
148  matrice_print(P,n,n);
149 
150  (void) printf (" la matrice Q est \n");
151  matrice_print(Q,m,m);
152 #endif
153 }
154 
155 
#define value_one_p(val)
int Value
#define value_division(ref, val)
#define D(A)
Definition: iabrev.h:56
#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_smith(matrice MAT, int n, int m, matrice P, matrice D, matrice Q)
void matrice_smith(matrice MAT, int n, int m, matrice P, matrice D, matrice Q): Calcul de la forme re...
Definition: smith.c:68
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_soustraction_ligne(matrice MAT, int n, int m, int r1, int r2, Value x)
void matrice_soustraction_ligne(matrice MAT,int n,int m,int r1,int r2,int x): Soustrait x fois la lig...
Definition: matrice.c:554
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_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_min(matrice, int, int, int *, int *, int)
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 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
void matrice_print(matrice, int, int)
void matrice_print(matrice a, int n, int m): print an (nxm) rational matrix
Definition: matrice_io.c:90
int mat_col_el(matrice, int, int, int)
#define assert(ex)
Definition: newgen_assert.h:41
#define Q
Definition: pip__type.h:39
#define ALL
Definition: readmakefile.c:178
#define level
int printf()
static char * x
Definition: split_file.c:159