PIPS
inversion.c
Go to the documentation of this file.
1 /*
2 
3  $Id: inversion.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_unimodulaire_triangulaire_inversion(matrice u ,matrice inv_u,
42  * int n, * bool infer)
43  * u soit le matrice unimodulaire triangulaire.
44  * si infer = true (triangulaire inferieure),
45  * infer = false (triangulaire superieure).
46  * calcul de l'inversion de matrice u telle que I = U x INV_U .
47  * Les parametres de la fonction :
48  *
49  * matrice u : matrice unimodulaire triangulaire -- inpout
50  * int n : dimension de la matrice caree -- inpout
51  * bool infer : type de triangulaire -- input
52  * matrice inv_u : l'inversion de matrice u -- output
53  */
55 matrice u;
56 matrice inv_u;
57 int n;
58 bool infer;
59 {
60  int i, j;
61  Value x;
62 
63  /* test de l'unimodularite et de la trangularite de u */
65 
66  matrice_identite(inv_u,n,0);
67  if (infer){
68  for (i=n; i>=1;i--)
69  for (j=i-1; j>=1; j--){
70  x = ACCESS(u,n,i,j);
71  if (value_notzero_p(x))
72  matrice_soustraction_colonne(inv_u,n,n,j,i,x);
73  }
74  }
75  else{
76  for (i=1; i<=n; i++)
77  for(j=i+1; j<=n; j++){
78  x = ACCESS(u,n,i,j);
79  if (value_notzero_p(x))
80  matrice_soustraction_colonne(inv_u,n,n,j,i,x);
81  }
82  }
83 }
84 
85 /* void matrice_diagonale_inversion(matrice s,matrice inv_s,int n)
86  * calcul de l'inversion du matrice en forme reduite smith.
87  * s est un matrice de la forme reduite smith, inv_s est l'inversion
88  * de s ; telles que s * inv_s = I.
89  *
90  * les parametres de la fonction :
91  * matrice s : matrice en forme reduite smith -- input
92  * int n : dimension de la matrice caree -- input
93  * matrice inv_s : l'inversion de s -- output
94  */
96 matrice s;
97 matrice inv_s;
98 int n;
99 {
100  Value d, d1;
101  Value gcd, lcm;
102  int i;
103 
104  /* tests des preconditions */
105  assert(matrice_diagonale_p(s,n,n));
106  assert(matrice_hermite_rank(s,n,n)==n);
108 
109  matrice_nulle(inv_s,n,n);
110  /* calcul de la ppcm(s[1,1],s[2,2],...s[n,n]) */
111  lcm = ACCESS(s,n,1,1);
112  for (i=2; i<=n; i++)
113  lcm = ppcm(lcm,ACCESS(s,n,i,i));
114 
115  d = DENOMINATOR(s);
116  gcd = pgcd_slow(lcm,d);
117  d1 = value_div(d,gcd);
118  for (i=1; i<=n; i++) {
119  Value tmp = value_div(lcm,ACCESS(s,n,i,i));
120  ACCESS(inv_s,n,i,i) = value_mult(d1,tmp);
121  }
122  DENOMINATOR(inv_s) = value_div(lcm,gcd);
123 }
124 
125 /* void matrice_triangulaire_inversion(matrice h, matrice inv_h, int n,bool infer)
126  * calcul de l'inversion du matrice en forme triangulaire.
127  * soit h matrice de la reduite triangulaire; inv_h est l'inversion de
128  * h ; telle que : h * inv_h = I.
129  * selon les proprietes de la matrice triangulaire:
130  * Aii = a11* ...aii-1*aii+1...*ann;
131  * Aij = 0 i>j pour la matrice triangulaire inferieure (infer==true)
132  * i<j pour la matrice triangulaire superieure (infer==false)
133  *
134  * les parametres de la fonction :
135  * matrice h : matrice en forme triangulaire -- input
136  * matrice inv_h : l'inversion de h -- output
137  * int n : dimension de la matrice caree -- input
138  * bool infer : le type de triangulaire -- input
139  */
140 void matrice_triangulaire_inversion(h,inv_h,n,infer)
141 matrice h;
142 matrice inv_h;
143 int n;
144 bool infer;
145 {
146  Value deno,deno1; /* denominateur */
147  Value determinant,sous_determinant; /* determinant */
148  Value gcd;
149  int i,j;
150  Value aij[2];
151  register Value a;
152 
153  /* tests des preconditions */
154  assert(matrice_triangulaire_p(h,n,n,infer));
155  assert(matrice_hermite_rank(h,n,n)==n);
157 
158  matrice_nulle(inv_h,n,n);
159  deno = DENOMINATOR(h);
160  deno1 = deno;
161  DENOMINATOR(h) = VALUE_ONE;
162  /* calcul du determinant de h */
163  determinant = VALUE_ONE;
164  for (i= 1; i<=n; i++){
165  a = ACCESS(h,n,i,i);
166  value_product(determinant,a);
167  }
168  /* calcul du denominateur de inv_h */
169  gcd = pgcd_slow(deno1,determinant);
170  if (value_notone_p(gcd)){
171  value_division(deno1,gcd);
172  value_division(determinant,gcd);
173  }
174  if (value_neg_p(determinant)){
175  value_oppose(deno1);
176  value_oppose(determinant);
177  }
178  DENOMINATOR(inv_h) = determinant;
179  /* calcul des sous_determinants des Aii */
180  for (i=1; i<=n; i++){
181  sous_determinant = VALUE_ONE;
182  for (j=1; j<=n; j++)
183  if (j != i) {
184  a = ACCESS(h,n,j,j);
185  value_product(sous_determinant,a) ;
186  }
187  ACCESS(inv_h,n,i,i) = value_mult(sous_determinant,deno1);
188  }
189  /* calcul des sous_determinants des Aij (i<j) */
190  if (infer) {
191  for (i=1; i<=n; i++)
192  for(j=i+1; j<=n;j++){
193  matrice_sous_determinant(h,n,i,j,aij);
194  assert(aij[0] == VALUE_ONE);
195  ACCESS(inv_h,n,j,i) = value_mult(aij[1],deno1);
196  }
197  }
198  else {
199  for (i=1; i<=n; i++)
200  for(j=1; j<i; j++){
201  matrice_sous_determinant(h,n,i,j,aij);
202  assert(aij[0] == VALUE_ONE);
203  ACCESS(inv_h,n,j,i) = value_mult(aij[1],deno1);
204  }
205  }
206 
207  DENOMINATOR(h) = deno;
208 }
209 
210 /* void matrice_general_inversion(matrice a; matrice inv_a; int n)
211  * calcul de l'inversion du matrice general.
212  * Algorithme :
213  * calcul P, Q, H telque : PAQ = H ;
214  * -1 -1
215  * si rank(H) = n ; A = Q H P .
216  *
217  * les parametres de la fonction :
218  * matrice a : matrice general ---- input
219  * matrice inv_a : l'inversion de a ---- output
220  * int n : dimensions de la matrice caree ---- input
221  */
223 matrice a;
224 matrice inv_a;
225 int n;
226 {
227  matrice p = matrice_new(n,n);
228  matrice q = matrice_new(n,n);
229  matrice h = matrice_new(n,n);
230  matrice inv_h = matrice_new(n,n);
231  matrice temp = matrice_new(n,n);
232  Value deno;
233  Value det_p, det_q; /* ne utilise pas */
234 
235  /* test */
237 
238  deno = DENOMINATOR(a);
239  DENOMINATOR(a) = VALUE_ONE;
240  matrice_hermite(a,n,n,p,h,q,&det_p,&det_q);
241  DENOMINATOR(a) = deno;
242  if ( matrice_hermite_rank(h,n,n) == n){
243  DENOMINATOR(h) = deno;
244  matrice_triangulaire_inversion(h,inv_h,n,true);
245  matrice_multiply(q,inv_h,temp,n,n,n);
246  matrice_multiply(temp,p,inv_a,n,n,n);
247  }
248  else{
249  printf(" L'inverse de la matrice a n'existe pas!\n");
250  exit(1);
251  }
252 }
253 
254 /* void matrice_unimodulaire_inversion(matrice u, matrice inv_u, int n)
255  * calcul de l'inversion de la matrice unimodulaire.
256  * algorithme :
257  * 1. calcul la forme hermite de la matrice u :
258  * PUQ = H_U (unimodulaire triangulaire);
259  * -1 -1
260  * 2. U = Q (H_U) P.
261  *
262  * les parametres de la fonction :
263  * matrice u : matrice unimodulaire ---- input
264  * matrice inv_u : l'inversion de u ---- output
265  * int n : dimension de la matrice ---- input
266  */
268 matrice u;
269 matrice inv_u;
270 int n;
271 {
272  matrice p = matrice_new(n,n);
273  matrice q = matrice_new(n,n);
274  matrice h_u = matrice_new(n,n);
275  matrice inv_h_u = matrice_new(n,n);
276  matrice temp = matrice_new(n,n);
277  Value det_p,det_q; /* ne utilise pas */
278 
279  /* test */
281 
282  matrice_hermite(u,n,n,p,h_u,q,&det_p,&det_q);
285  matrice_multiply(q,inv_h_u,temp,n,n,n);
286  matrice_multiply(temp,p,inv_u,n,n,n);
287 }
288 
289 
290 
291 
292 
293 
#define value_pos_p(val)
#define value_oppose(ref)
#define value_notzero_p(val)
#define value_notone_p(val)
#define value_one_p(val)
int Value
#define value_division(ref, val)
#define value_product(v, w)
#define VALUE_ONE
#define value_mult(v, w)
whether the default is protected or not this define makes no sense any more...
#define value_neg_p(val)
#define value_div(v1, v2)
Value ppcm(Value, Value)
ppcm.c
Definition: ppcm.c:42
Value pgcd_slow(Value, Value)
pgcd.c
Definition: pgcd.c:44
#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
#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
void matrice_sous_determinant(matrice a, int n, int i, int j, result)
void matrice_sous_determinant(matrice a, int n,int i, int j, int result[]) calculate sub determinant ...
Definition: determinant.c:156
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
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_unimodulaire_triangulaire_inversion(matrice u, matrice inv_u, int n, bool infer)
package matrice
Definition: inversion.c:54
void matrice_triangulaire_inversion(matrice h, matrice inv_h, int n, bool infer)
void matrice_triangulaire_inversion(matrice h, matrice inv_h, int n,bool infer) calcul de l'inversion...
Definition: inversion.c:140
void matrice_general_inversion(matrice a, matrice inv_a, int n)
void matrice_general_inversion(matrice a; matrice inv_a; int n) calcul de l'inversion du matrice gene...
Definition: inversion.c:222
void matrice_diagonale_inversion(matrice s, matrice inv_s, int n)
void matrice_diagonale_inversion(matrice s,matrice inv_s,int n) calcul de l'inversion du matrice en f...
Definition: inversion.c:95
void matrice_unimodulaire_inversion(matrice u, matrice inv_u, int n)
void matrice_unimodulaire_inversion(matrice u, matrice inv_u, int n) calcul de l'inversion de la matr...
Definition: inversion.c:267
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
bool matrice_diagonale_p(matrice Z, int n, int m)
bool matrice_diagonale_p(matrice Z, int n, int m): test de nullite de la matrice Z
Definition: matrice.c:362
bool matrice_triangulaire_unimodulaire_p(matrice Z, int n, bool inferieure)
bool matrice_triangulaire_unimodulaire_p(matrice Z, int n, bool inferieure) test de la triangulaire e...
Definition: matrice.c:434
void matrice_multiply(matrice a, matrice b, matrice c, int p, int q, int r)
void matrice_multiply(matrice a, matrice b, matrice c, int p, int q, int r): multiply rational matrix...
Definition: matrice.c:82
bool matrice_triangulaire_p(matrice Z, int n, int m, bool inferieure)
bool matrice_triangulaire_p(matrice Z, int n, int m, bool inferieure): test de triangularite de la ma...
Definition: matrice.c:394
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_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 exit(code)
Definition: misc-local.h:54
#define assert(ex)
Definition: newgen_assert.h:41
int printf()
static char * x
Definition: split_file.c:159