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 matrix */
26 
27 #ifdef HAVE_CONFIG_H
28  #include "config.h"
29 #endif
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include "linear_assert.h"
34 
35 #include "boolean.h"
36 #include "arithmetique.h"
37 
38 #include "matrix.h"
39 
40 /* void matrix_unimodular_triangular_inversion(Pmatrix u ,Pmatrix inv_u,
41  * * bool infer)
42  * u soit le matrice unimodulaire triangulaire.
43  * si infer = true (triangulaire inferieure),
44  * infer = false (triangulaire superieure).
45  * calcul de l'inversion de matrice u telle que I = U x INV_U .
46  * Les parametres de la fonction :
47  *
48  * Pmatrix u : matrice unimodulaire triangulaire -- inpout
49  * int n : dimension de la matrice caree -- inpout
50  * bool infer : type de triangulaire -- input
51  * matrice inv_u : l'inversion de matrice u -- output
52  */
54 Pmatrix u;
55 Pmatrix inv_u;
56 bool infer;
57 {
58  int i, j;
59  Value x;
60  int n = MATRIX_NB_LINES(u);
61  /* test de l'unimodularite et de la trangularite de u */
63 
64  matrix_identity(inv_u,0);
65  if (infer){
66  for (i=n; i>=1;i--)
67  for (j=i-1; j>=1; j--){
68  x = MATRIX_ELEM(u,i,j);
69  if (value_notzero_p(x))
70  matrix_subtraction_column(inv_u,j,i,x);
71  }
72  }
73  else{
74  for (i=1; i<=n; i++)
75  for(j=i+1; j<=n; j++){
76  x = MATRIX_ELEM(u,i,j);
77  if (value_notzero_p(x))
78  matrix_subtraction_column(inv_u,j,i,x);
79  }
80  }
81 }
82 
83 /* void matrix_diagonal_inversion(Pmatrix s,Pmatrix inv_s)
84  * calcul de l'inversion du matrice en forme reduite smith.
85  * s est un matrice de la forme reduite smith, inv_s est l'inversion
86  * de s ; telles que s * inv_s = I.
87  *
88  * les parametres de la fonction :
89  * matrice s : matrice en forme reduite smith -- input
90  * int n : dimension de la matrice caree -- input
91  * matrice inv_s : l'inversion de s -- output
92  */
94 Pmatrix s;
95 Pmatrix inv_s;
96 {
97  Value d, d1;
98  Value gcd, lcm;
99  int i;
100  int n = MATRIX_NB_LINES(s);
101  /* tests des preconditions */
105 
106  matrix_nulle(inv_s);
107  /* calcul de la ppcm(s[1,1],s[2,2],...s[n,n]) */
108  lcm = MATRIX_ELEM(s,1,1);
109  for (i=2; i<=n; i++)
110  lcm = ppcm(lcm,MATRIX_ELEM(s,i,i));
111 
112  d = MATRIX_DENOMINATOR(s);
113  gcd = pgcd(lcm,d);
114  d1 = value_div(d,gcd);
115  for (i=1; i<=n; i++) {
116  Value tmp = value_div(lcm,MATRIX_ELEM(s,i,i));
117  MATRIX_ELEM(inv_s,i,i) = value_mult(d1,tmp);
118  }
119  MATRIX_DENOMINATOR(inv_s) = value_div(lcm,gcd);
120 }
121 
122 /* void matrix_triangular_inversion(Pmatrix h, Pmatrix inv_h,bool infer)
123  * calcul de l'inversion du matrice en forme triangulaire.
124  * soit h matrice de la reduite triangulaire; inv_h est l'inversion de
125  * h ; telle que : h * inv_h = I.
126  * selon les proprietes de la matrice triangulaire:
127  * Aii = a11* ...aii-1*aii+1...*ann;
128  * Aij = 0 i>j pour la matrice triangulaire inferieure (infer==true)
129  * i<j pour la matrice triangulaire superieure (infer==false)
130  *
131  * les parametres de la fonction :
132  * matrice h : matrice en forme triangulaire -- input
133  * matrice inv_h : l'inversion de h -- output
134  * int n : dimension de la matrice caree -- input
135  * bool infer : le type de triangulaire -- input
136  */
137 void matrix_triangular_inversion(h,inv_h,infer)
138 Pmatrix h;
139 Pmatrix inv_h;
140 bool infer;
141 {
142  Value deno,deno1; /* denominateur */
143  Value determinant,sub_determinant; /* determinant */
144  Value gcd;
145  int i,j;
146  Value aij[2];
147 
148  /* tests des preconditions */
149  int n = MATRIX_NB_LINES(h);
150  assert(matrix_triangular_p(h,infer));
153 
154  matrix_nulle(inv_h);
155  deno = MATRIX_DENOMINATOR(h);
156  deno1 = deno;
158  /* calcul du determinant de h */
159  determinant = VALUE_ONE;
160  for (i= 1; i<=n; i++)
161  value_product(determinant, MATRIX_ELEM(h,i,i));
162 
163  /* calcul du denominateur de inv_h */
164  gcd = pgcd(deno1,determinant);
165  if (value_notone_p(gcd)){
166  value_division(deno1,gcd);
167  value_division(determinant,gcd);
168  }
169  if (value_neg_p(determinant)){
170  value_oppose(deno1);
171  value_oppose(determinant);
172  }
173  MATRIX_DENOMINATOR(inv_h) = determinant;
174  /* calcul des sub_determinants des Aii */
175  for (i=1; i<=n; i++){
176  sub_determinant = VALUE_ONE;
177  for (j=1; j<=n; j++)
178  if (j != i)
179  value_product(sub_determinant, MATRIX_ELEM(h,j,j));
180  MATRIX_ELEM(inv_h,i,i) = value_mult(sub_determinant,deno1);
181  }
182  /* calcul des sub_determinants des Aij (i<j) */
183  switch(infer) {
184  case true:
185  for (i=1; i<=n; i++)
186  for(j=i+1; j<=n;j++){
187  matrix_sub_determinant(h,i,j,aij);
188  assert(value_one_p(aij[0]));
189  MATRIX_ELEM(inv_h,j,i) = value_mult(aij[1],deno1);
190  }
191  break;
192  case false:
193  for (i=1; i<=n; i++)
194  for(j=1; j<i; j++){
195  matrix_sub_determinant(h,i,j,aij);
196  assert(value_one_p(aij[0]));
197  MATRIX_ELEM(inv_h,j,i) = value_mult(aij[1],deno1);
198  }
199  break;
200  }
201  MATRIX_DENOMINATOR(h) = deno;
202 }
203 
204 /* void matrix_general_inversion(Pmatrix a; Pmatrix inv_a)
205  * calcul de l'inversion du matrice general.
206  * Algorithme :
207  * calcul P, Q, H telque : PAQ = H ;
208  * -1 -1
209  * si rank(H) = n ; A = Q H P .
210  *
211  * les parametres de la fonction :
212  * matrice a : matrice general ---- input
213  * matrice inv_a : l'inversion de a ---- output
214  * int n : dimensions de la matrice caree ---- input
215  */
217 Pmatrix a;
218 Pmatrix inv_a;
219 {
220  int n = MATRIX_NB_LINES(a);
221  Pmatrix p = matrix_new(n,n);
222  Pmatrix q = matrix_new(n,n);
223  Pmatrix h = matrix_new(n,n);
224  Pmatrix inv_h = matrix_new(n,n);
225  Pmatrix temp = matrix_new(n,n);
226  Value deno;
227  Value det_p, det_q; /* ne utilise pas */
228 
229  /* test */
231 
232  deno = MATRIX_DENOMINATOR(a);
234  matrix_hermite(a,p,h,q,&det_p,&det_q);
235  MATRIX_DENOMINATOR(a) = deno;
236  if ( matrix_hermite_rank(h) == n){
237  MATRIX_DENOMINATOR(h) = deno;
238  matrix_triangular_inversion(h,inv_h,true);
239  matrix_multiply(q,inv_h,temp);
240  matrix_multiply(temp,p,inv_a);
241  }
242  else{
243  fprintf(stderr," L'inverse de la matrice a n'existe pas!\n");
244  exit(1);
245  }
246 }
247 
248 /* void matrix_unimodular_inversion(Pmatrix u, Pmatrix inv_u)
249  * calcul de l'inversion de la matrice unimodulaire.
250  * algorithme :
251  * 1. calcul la forme hermite de la matrice u :
252  * PUQ = H_U (unimodulaire triangulaire);
253  * -1 -1
254  * 2. U = Q (H_U) P.
255  *
256  * les parametres de la fonction :
257  * matrice u : matrice unimodulaire ---- input
258  * matrice inv_u : l'inversion de u ---- output
259  * int n : dimension de la matrice ---- input
260  */
262 Pmatrix u;
263 Pmatrix inv_u;
264 
265 {
266  int n = MATRIX_NB_LINES(u);
267  Pmatrix p = matrix_new(n,n);
268  Pmatrix q = matrix_new(n,n);
269  Pmatrix h_u = matrix_new(n,n);
270  Pmatrix inv_h_u = matrix_new(n,n);
271  Pmatrix temp = matrix_new(n,n);
272  Value det_p,det_q; /* ne utilise pas */
273 
274  /* test */
276 
277  matrix_hermite(u,p,h_u,q,&det_p,&det_q);
279  matrix_unimodular_triangular_inversion(h_u,inv_h_u,true);
280  matrix_multiply(q,inv_h_u,temp);
281  matrix_multiply(temp,p,inv_u);
282 }
283 
284 
285 
286 
287 
288 
289 
#define value_pos_p(val)
#define pgcd(a, b)
Pour la recherche de performance, selection d'une implementation particuliere des fonctions.
#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
#define MATRIX_NB_LINES(matrix)
Definition: matrix-local.h:87
#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
Pmatrix matrix_new(int m, int n)
package matrix
Definition: alloc.c:41
void matrix_sub_determinant(Pmatrix a, int i, int j, result)
void matrix_sub_determinant(Pmatrix a,int i, int j, int result[]) calculate sub determinant of a matr...
Definition: determinant.c:149
int matrix_hermite_rank(Pmatrix a)
int matrix_hermite_rank(Pmatrix a): rang d'une matrice en forme de hermite
Definition: hermite.c:174
void matrix_hermite(Pmatrix MAT, Pmatrix P, Pmatrix H, Pmatrix Q, Value *det_p, Value *det_q)
package matrix
Definition: hermite.c:78
void matrix_general_inversion(Pmatrix a, Pmatrix inv_a)
void matrix_general_inversion(Pmatrix a; Pmatrix inv_a) calcul de l'inversion du matrice general.
Definition: inversion.c:216
void matrix_unimodular_inversion(Pmatrix u, Pmatrix inv_u)
void matrix_unimodular_inversion(Pmatrix u, Pmatrix inv_u) calcul de l'inversion de la matrice unimod...
Definition: inversion.c:261
void matrix_unimodular_triangular_inversion(Pmatrix u, Pmatrix inv_u, bool infer)
package matrix
Definition: inversion.c:53
void matrix_triangular_inversion(Pmatrix h, Pmatrix inv_h, bool infer)
void matrix_triangular_inversion(Pmatrix h, Pmatrix inv_h,bool infer) calcul de l'inversion du matric...
Definition: inversion.c:137
void matrix_diagonal_inversion(Pmatrix s, Pmatrix inv_s)
void matrix_diagonal_inversion(Pmatrix s,Pmatrix inv_s) calcul de l'inversion du matrice en forme red...
Definition: inversion.c:93
void matrix_nulle(Pmatrix Z)
void matrix_nulle(Pmatrix Z): Initialisation de la matrice Z a la valeur matrice nulle
Definition: matrix.c:293
bool matrix_diagonal_p(Pmatrix Z)
bool matrix_diagonal_p(Pmatrix Z): test de nullite de la matrice Z
Definition: matrix.c:336
void matrix_subtraction_column(Pmatrix MAT, int c1, int c2, Value x)
void matrix_subtraction_column(Pmatrix MAT,int c1,int c2,int x): Soustrait x fois la colonne c2 de la...
Definition: matrix.c:518
void matrix_multiply(const Pmatrix a, const Pmatrix b, Pmatrix c)
void matrix_multiply(Pmatrix a, Pmatrix b, Pmatrix c): multiply rational matrix a by rational matrix ...
Definition: matrix.c:95
bool matrix_triangular_unimodular_p(Pmatrix Z, bool inferieure)
bool matrix_triangular_unimodular_p(Pmatrix Z, bool inferieure) test de la triangulaire et unimodulai...
Definition: matrix.c:403
bool matrix_triangular_p(Pmatrix Z, bool inferieure)
bool matrix_triangular_p(Pmatrix Z, bool inferieure): test de triangularite de la matrice Z
Definition: matrix.c:367
void matrix_identity(Pmatrix, int)
void matrix_identity(Pmatrix ID, int level) Construction d'une sous-matrice identity dans ID(level+1....
Definition: sub-matrix.c:322
#define exit(code)
Definition: misc-local.h:54
#define assert(ex)
Definition: newgen_assert.h:41
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
static char * x
Definition: split_file.c:159
package matrice
Definition: matrix-local.h:63