PIPS
matrice.c
Go to the documentation of this file.
1 /*
2 
3  $Id: matrice.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 /* void matrice_transpose(matrice a, matrice a_t, int n, int m):
43  * transpose an (nxm) rational matrix a into a (mxn) rational matrix a_t
44  *
45  * t
46  * a_t := a ;
47  */
48 void matrice_transpose(a,a_t,n,m)
49 matrice a;
50 matrice a_t;
51 int n;
52 int m;
53 {
54  int loop1,loop2;
55 
56  /* verification step */
57  assert(n >= 0 && m >= 0);
58 
59  /* copy from a to a_t */
60  DENOMINATOR(a_t) = DENOMINATOR(a);
61  for(loop1=1; loop1<=n; loop1++)
62  for(loop2=1; loop2<=m; loop2++)
63  ACCESS(a_t,m,loop2,loop1) = ACCESS(a,n,loop1,loop2);
64 }
65 
66 /* void matrice_multiply(matrice a, matrice b, matrice c, int p, int q, int r):
67  * multiply rational matrix a by rational matrix b and store result in matrix c
68  *
69  * a is a (pxq) matrix, b a (qxr) and c a (pxr)
70  *
71  * c := a x b ;
72  *
73  * Algorithm used is directly from definition, and space has to be
74  * provided for output matrix c by caller. Matrix c is not necessarily
75  * normalized: its denominator may divide all its elements
76  * (see matrice_normalize()).
77  *
78  * Precondition: p > 0; q > 0; r > 0;
79  * c != a; c != b; -- aliasing between c and a or b
80  * -- is not supported
81  */
82 void matrice_multiply(a,b,c,p,q,r)
83 matrice a; /* input */
84 matrice b; /* input */
85 matrice c; /* output */
86 int p; /* input */
87 int q; /* input */
88 int r; /* input */
89 {
90  int loop1,loop2,loop3;
91  register Value i,va,vb;
92 
93  /* validate dimensions */
94  assert(p > 0 && q > 0 && r > 0);
95  /* simplified aliasing test */
96  assert(c != a && c != b);
97 
98  /* set denominator */
100 
101  /* use ordinary school book algorithm */
102  for(loop1=1; loop1<=p; loop1++)
103  for(loop2=1; loop2<=r; loop2++) {
104  i = VALUE_ZERO;
105  for(loop3=1; loop3<=q; loop3++)
106  {
107  va = ACCESS(a,p,loop1,loop3);
108  vb = ACCESS(b,q,loop3,loop2);
109  value_addto(i,value_mult(va,vb));
110  }
111  ACCESS(c,p,loop1,loop2) = i;
112  }
113 }
114 
115 /* void matrice_normalize(matrice a, int n, int m)
116  *
117  * A rational matrix is stored as an integer one with one extra
118  * integer, the denominator for all the elements. To normalise the
119  * matrix in this sense means to reduce this denominator to the
120  * smallest positive number possible. All elements are also reduced
121  * to their smallest possible value.
122  *
123  * Precondition: DENOMINATOR(a)!=0
124  */
125 void matrice_normalize(a,n,m)
126 matrice a; /* input */
127 int n; /* input */
128 int m; /* output */
129 {
130  int loop1,loop2;
131  Value factor;
132 
134 
135  /* we must find the GCD of all elements of matrix */
136  factor = DENOMINATOR(a);
137 
138  for(loop1=1; loop1<=n; loop1++)
139  for(loop2=1; loop2<=m; loop2++)
140  factor = pgcd(factor,ACCESS(a,n,loop1,loop2));
141 
142  /* factor out */
143  if (value_notone_p(factor)) {
144  for(loop1=1; loop1<=n; loop1++)
145  for(loop2=1; loop2<=m; loop2++)
146  value_division(ACCESS(a,n,loop1,loop2),factor);
147  value_division(DENOMINATOR(a),factor);
148  }
149 
150  /* ensure denominator is positive */
151  /* FI: this code is useless because pgcd()always return a positive integer,
152  even if a is the null matrix; its denominator CANNOT be 0 */
154  /*
155  if(DENOMINATOR(a) < 0) {
156  DENOMINATOR(a) = DENOMINATOR(a)*-1;
157  for(loop1=1; loop1<=n; loop1++)
158  for(loop2=1; loop2<=m; loop2++)
159  value_oppose(ACCESS(a,n,loop1,loop2));
160  }*/
161 }
162 
163 /* void matrice_normalizec(matrice MAT, int n, int m):
164  * Normalisation des coefficients de la matrice MAT, i.e. division des
165  * coefficients de la matrice MAT et de son denominateur par leur pgcd
166  *
167  * La matrice est modifiee.
168  *
169  * Les parametres de la fonction :
170  *
171  *!int MAT[] : matrice de dimension (n,m)
172  * int n : nombre de lignes de la matrice
173  * int m : nombre de colonnes de la matrice
174  */
175 void matrice_normalizec(MAT,n,m)
176 matrice MAT;
177 int n,m;
178 {
179  int i;
180  Value a;
181 
182  /* FI What an awful test! It should be an assert() */
183  if (n && m) {
184  a = MAT[0];
185  for (i = 1;(i<=n*m) && value_gt(a,VALUE_ONE);i++)
186  a = pgcd(a,MAT[i]);
187 
188  if (value_gt(a,VALUE_ONE)) {
189  for (i = 0;i<=n*m;i++)
190  value_division(MAT[i],a);
191  }
192  }
193 }
194 
195 /* void matrice_swap_columns(matrice matrix, int n, int m, int c1, int c2):
196  * exchange columns c1,c2 of an (nxm) rational matrix
197  *
198  * Precondition: n > 0; m > 0; 0 < c1 <= m; 0 < c2 <= m;
199  */
201 matrice matrix; /* input and output matrix */
202 int n; /* number of rows */
203 int m; /* number of columns */
204 int c1,c2; /* column numbers */
205 {
206  int loop1;
207  register Value temp;
208 
209  /* validation step */
210  /*
211  * if ((n < 1) || (m < 1)) return(-208);
212  * if ((c1 > m) || (c2 > m)) return(-209);
213  */
214  assert(n > 0 && m > 0);
215  assert(0 < c1 && c1 <= m);
216  assert(0 < c2 && c2 <= m);
217 
218  for(loop1=1; loop1<=n; loop1++) {
219  temp = ACCESS(matrix,n,loop1,c1);
220  ACCESS(matrix,n,loop1,c1) = ACCESS(matrix,n,loop1,c2);
221  ACCESS(matrix,n,loop1,c2) = temp;
222  }
223 }
224 
225 /* void matrice_swap_rows(matrice a, int n, int m, int r1, int r2):
226  * exchange rows r1 and r2 of an (nxm) rational matrix a
227  *
228  * Precondition: n > 0; m > 0; 1 <= r1 <= n; 1 <= r2 <= n
229  */
230 void matrice_swap_rows(a,n,m,r1,r2)
231 matrice a; /* input and output matrix */
232 int n; /* number of columns */
233 int m; /* number of rows */
234 int r1,r2; /* row numbers */
235 {
236  int loop1;
237  register Value temp;
238 
239  /* validation */
240  assert(n > 0);
241  assert(m > 0);
242  assert(0 < r1 && r1 <= n);
243  assert(0 < r2 && r2 <= n);
244 
245  for(loop1=1; loop1<=m; loop1++) {
246  temp = ACCESS(a,n,r1,loop1);
247  ACCESS(a,n,r1,loop1) = ACCESS(a,n,r2,loop1);
248  ACCESS(a,n,r2,loop1) = temp;
249  }
250 }
251 
252 /* void matrice_assign(matrice A, matrice B, int n, int m)
253  * Copie de la matrice A dans la matrice B
254  *
255  * Les parametres de la fonction :
256  *
257  * int A[] : matrice
258  *!int B[] : matrice
259  * int n : nombre de lignes de la matrice
260  * int m : nombre de colonnes de la matrice
261  *
262  * Ancien nom: mat_dup
263  */
264 void matrice_assign(A,B,n,m)
265 matrice A,B;
266 int n,m;
267 {
268  int i, size=n*m;
269  for (i = 0 ;i<=size;i++)
270  B[i] = A[i];
271 }
272 
273 /* bool matrice_egalite(matrice A, matrice B, int n, int m)
274  * test de l'egalite de deux matrices A et B; elles doivent avoir
275  * ete normalisees au prealable pour que le test soit mathematiquement
276  * exact
277  *
278  * Les parametres de la fonction :
279  *
280  * int A[] : matrice
281  * int B[] : matrice
282  * int n : nombre de lignes de la matrice
283  * int m : nombre de colonnes de la matrice
284  */
285 bool matrice_egalite(A,B,n,m)
286 matrice A, B;
287 int n,m;
288 {
289  int i;
290  for (i = 0 ;i<= n*m;i++)
291  if(value_ne(B[i],A[i]))
292  return(false);
293  return(true);
294 }
295 
296 /* void matrice_nulle(matrice Z, int n, int m):
297  * Initialisation de la matrice Z a la valeur matrice nulle
298  *
299  * Post-condition:
300  *
301  * QQ i dans [1..n]
302  * QQ j dans [1..n]
303  * Z(i,j) == 0
304  *
305  * Les parametres de la fonction :
306  *
307  *!int Z[] : matrice
308  * int n : nombre de lignes de la matrice
309  * int m : nombre de colonnes de la matrice
310  */
311 void matrice_nulle(Z,n,m)
312 matrice Z;
313 int n,m;
314 {
315  int i,j;
316 
317  for (i=1;i<=n;i++)
318  for (j=1;j<=m;j++)
319  ACCESS(Z,n,i,j)=VALUE_ZERO;
320  DENOMINATOR(Z) = VALUE_ONE;
321 }
322 
323 /* bool matrice_nulle_p(matrice Z, int n, int m):
324  * test de nullite de la matrice Z
325  *
326  * QQ i dans [1..n]
327  * QQ j dans [1..n]
328  * Z(i,j) == 0
329  *
330  * Les parametres de la fonction :
331  *
332  * int Z[] : matrice
333  * int n : nombre de lignes de la matrice
334  * int m : nombre de colonnes de la matrice
335  */
336 bool matrice_nulle_p(Z,n,m)
337 matrice Z;
338 int n,m;
339 {
340  int i,j;
341 
342  for (i=1;i<=n;i++)
343  for (j=1;j<=m;j++)
344  if(value_notzero_p(ACCESS(Z,n,i,j)))
345  return(false);
346  return(true);
347 }
348 
349 /* bool matrice_diagonale_p(matrice Z, int n, int m):
350  * test de nullite de la matrice Z
351  *
352  * QQ i dans [1..n]
353  * QQ j dans [1..n]
354  * Z(i,j) == 0 && i != j || i == j
355  *
356  * Les parametres de la fonction :
357  *
358  * int Z[] : matrice
359  * int n : nombre de lignes de la matrice
360  * int m : nombre de colonnes de la matrice
361  */
363 matrice Z;
364 int n,m;
365 {
366  int i,j;
367 
368  for (i=1;i<=n;i++)
369  for (j=1;j<=m;j++)
370  if(i!=j && value_notzero_p(ACCESS(Z,n,i,j)))
371  return(false);
372  return(true);
373 }
374 
375 /* bool matrice_triangulaire_p(matrice Z, int n, int m, bool inferieure):
376  * test de triangularite de la matrice Z
377  *
378  * si inferieure == true
379  * QQ i dans [1..n]
380  * QQ j dans [i+1..m]
381  * Z(i,j) == 0
382  *
383  * si inferieure == false (triangulaire superieure)
384  * QQ i dans [1..n]
385  * QQ j dans [1..i-1]
386  * Z(i,j) == 0
387  *
388  * Les parametres de la fonction :
389  *
390  * int Z[] : matrice
391  * int n : nombre de lignes de la matrice
392  * int m : nombre de colonnes de la matrice
393  */
394 bool matrice_triangulaire_p(Z,n,m,inferieure)
395 matrice Z;
396 int n,m;
397 bool inferieure;
398 {
399  int i,j;
400 
401  for (i=1; i <= n; i++)
402  if(inferieure) {
403  for (j=i+1; j <= m; j++)
404  if(value_notzero_p(ACCESS(Z,n,i,j)))
405  return(false);
406  }
407  else
408  for (j=1; j <= i-1; j++)
409  if(value_notzero_p(ACCESS(Z,n,i,j)))
410  return(false);
411  return(true);
412 }
413 
414 /* bool matrice_triangulaire_unimodulaire_p(matrice Z, int n, bool inferieure)
415  * test de la triangulaire et unimodulaire de la matrice Z.
416  * si inferieure == true
417  * QQ i dans [1..n]
418  * QQ j dans [i+1..n]
419  * Z(i,j) == 0
420  * i dans [1..n]
421  * Z(i,i) == 1
422  *
423  * si inferieure == false (triangulaire superieure)
424  * QQ i dans [1..n]
425  * QQ j dans [1..i-1]
426  * Z(i,j) == 0
427  * i dans [1..n]
428  * Z(i,i) == 1
429  *
430  * les parametres de la fonction :
431  * matrice Z : la matrice entre
432  * int n : la dimension de la martice caree
433  */
435 matrice Z;
436 int n;
437 bool inferieure;
438 {
439  bool triangulaire;
440  int i;
441  triangulaire = matrice_triangulaire_p(Z,n,n,inferieure);
442  if (triangulaire == false)
443  return(false);
444  else{
445  for(i=1; i<=n; i++)
446  if (value_notone_p(ACCESS(Z,n,i,i)))
447  return(false);
448  return(true);
449  }
450 }
451 
452 /* void matrice_substract(matrice a, matrice b, matrice c, int n, int m):
453  * substract rational matrix c from rational matrix b and store result
454  * in matrix a
455  *
456  * a is a (nxm) matrix, b a (nxm) and c a (nxm)
457  *
458  * a = b - c ;
459  *
460  * Algorithm used is directly from definition, and space has to be
461  * provided for output matrix a by caller. Matrix a is not necessarily
462  * normalized: its denominator may divide all its elements
463  * (see matrice_normalize()).
464  *
465  * Precondition: n > 0; m > 0;
466  * Note: aliasing between a and b or c is supported
467  */
468 void matrice_substract(a,b,c,n,m)
469 matrice a; /* output */
470 matrice b, c; /* input */
471 int n,m; /* input */
472 {
473  register Value d1,d2; /* denominators of b, c */
474  register Value lcm; /* ppcm of b,c */
475  int i,j;
476 
477  /* precondition */
478  assert(n>0 && m>0);
481 
482  d1 = DENOMINATOR(b);
483  d2 = DENOMINATOR(c);
484  if (d1 == d2){
485  for (i=1; i<=n; i++)
486  for (j=1; j<=m; j++)
487  ACCESS(a,n,i,j) = value_minus(ACCESS(b,n,i,j),
488  ACCESS(c,n,i,j));
489  DENOMINATOR(a) = d1;
490  }
491  else{
492  register Value v1,v2;
493  lcm = ppcm(d1,d2);
494  DENOMINATOR(a) = lcm;
495  d1 = value_div(lcm,d1);
496  d2 = value_div(lcm,d2);
497  for (i=1; i<=n; i++)
498  for (j=1; j<=m; j++)
499  {
500  v1 = ACCESS(b,n,i,j);
501  value_product(v1, d1);
502  v2 = ACCESS(c,n,i,j);
503  value_product(v2, d2);
504  ACCESS(a,n,i,j) = value_minus(v1,v2);
505  }
506  }
507 }
508 
509 /* void matrice_soustraction_colonne(matrice MAT,int n,int m,int c1,int c2,int x):
510  * Soustrait x fois la colonne c2 de la colonne c1
511  * Precondition: n > 0; m > 0; 0 < c1, c2 < m;
512  * Effet: c1[0..n-1] = c1[0..n-1] - x*c2[0..n-1].
513  *
514  * Les parametres de la fonction :
515  *
516  * int MAT[] : matrice
517  * int n : nombre de lignes de la matrice
518  * int m : nombre de colonnes de la matrice
519  * int c1 : numero du colonne
520  * int c2 : numero du colonne
521  * int x :
522  */
524  int n,
525  int m __attribute__((unused)),
526  int c1,
527  int c2,
528  Value x)
529 {
530  int i;
531  register Value p;
532  for (i=1; i<=n; i++)
533  {
534  p = ACCESS(MAT,n,i,c2);
535  value_product(p,x);
536  value_substract(ACCESS(MAT,n,i,c1),p);
537  }
538 }
539 
540 /* void matrice_soustraction_ligne(matrice MAT,int n,int m,int r1,int r2,int x):
541  * Soustrait x fois la ligne r2 de la ligne r1
542  * Precondition: n > 0; m > 0; 0 < r1, r2 < n;
543  * Effet: r1[0..m-1] = r1[0..m-1] - x*r2[0..m-1]
544  *
545  * Les parametres de la fonction :
546  *
547  * int MAT[] : matrice
548  * int n : nombre de lignes de la matrice
549  * int m : nombre de colonnes de la matrice
550  * int r1 : numero du ligne
551  * int r2 : numero du ligne
552  * int x :
553  */
554 void matrice_soustraction_ligne(MAT,n,m,r1,r2,x)
555 matrice MAT;
556 int n,m;
557 int r1,r2;
558 Value x;
559 {
560  int i;
561  register Value p;
562  for (i=1; i<=m; i++)
563  {
564  p = ACCESS(MAT,n,r2,i);
565  value_product(p,x);
566  value_substract(ACCESS(MAT,n,r1,i),p);
567  }
568 }
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_pos_p(val)
#define VALUE_ZERO
#define value_minus(v1, v2)
#define value_gt(v1, v2)
#define pgcd(a, b)
Pour la recherche de performance, selection d'une implementation particuliere des fonctions.
#define value_notzero_p(val)
#define value_notone_p(val)
#define value_ne(v1, v2)
int Value
#define value_addto(ref, val)
#define value_division(ref, val)
#define value_product(v, w)
#define VALUE_ONE
#define value_substract(ref, val)
#define value_mult(v, w)
whether the default is protected or not this define makes no sense any more...
#define value_div(v1, v2)
Value ppcm(Value, Value)
ppcm.c
Definition: ppcm.c:42
#define A(i, j)
comp_matrice.c
Definition: comp_matrice.c:63
#define B(A)
Definition: iabrev.h:61
loop loop1
tiling_sequence.c
#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
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_transpose(matrice a, matrice a_t, int n, int m)
package matrice
Definition: matrice.c:48
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_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_normalizec(matrice MAT, int n, int m)
void matrice_normalizec(matrice MAT, int n, int m): Normalisation des coefficients de la matrice MAT,...
Definition: matrice.c:175
void matrice_substract(matrice a, matrice b, matrice c, int n, int m)
void matrice_substract(matrice a, matrice b, matrice c, int n, int m): substract rational matrix c fr...
Definition: matrice.c:468
void matrice_normalize(matrice a, int n, int m)
void matrice_normalize(matrice a, int n, int m)
Definition: matrice.c:125
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_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_nulle_p(matrice Z, int n, int m)
bool matrice_nulle_p(matrice Z, int n, int m): test de nullite de la matrice Z
Definition: matrice.c:336
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
bool matrice_egalite(matrice A, matrice B, int n, int m)
bool matrice_egalite(matrice A, matrice B, int n, int m) test de l'egalite de deux matrices A et B; e...
Definition: matrice.c:285
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_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
#define assert(ex)
Definition: newgen_assert.h:41
static char * x
Definition: split_file.c:159
Definition: pip__tab.h:25
struct matrix matrix