PIPS
pgcd.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include "arithmetique.h"
#include "linear_assert.h"
+ Include dependency graph for pgcd.c:

Go to the source code of this file.

Macros

#define GCD_MAX_A   15
 
#define GCD_MAX_B   15
 

Functions

Value pgcd_slow (Value a, Value b)
 package arithmetique More...
 
Value pgcd_fast (Value a, Value b)
 int pgcd_fast(int a, int b): calcul iteratif du pgcd de deux entiers; le pgcd retourne est toujours positif; il n'est pas defini si a et b sont nuls (abort); More...
 
Value pgcd_interne (Value a, Value b)
 int pgcd_interne(int a, int b): calcul iteratif du pgcd de deux entiers strictement positifs tels que a > b; le pgcd retourne est toujours positif; More...
 
Value gcd_subtract (Value a, Value b)
 int gcd_subtract(int a, int b): find the gcd (pgcd) of two integers More...
 
Value vecteur_bezout (Value u[], Value v[], int l)
 int vecteur_bezout(int u[], int v[], int l): calcul du vecteur v qui verifie le theoreme de bezout pour le vecteur u; les vecteurs u et v sont de dimension l More...
 
Value bezout (Value a, Value b, Value *x, Value *y)
 int bezout(int a, int b, int *x, int *y): calcule x et y, les deux nombres qui verifient le theoreme de Bezout pour a et b; le pgcd de a et b est retourne par valeur More...
 
Value bezout_grl (Value a, Value b, Value *x, Value *y)
 int bezout_grl(int a, int b, int *x, int *y): calcule x et y, les deux entiers quelconcs qui verifient le theoreme de Bezout pour a et b; le pgcd de a et b est retourne par valeur More...
 

Macro Definition Documentation

◆ GCD_MAX_A

#define GCD_MAX_A   15

◆ GCD_MAX_B

#define GCD_MAX_B   15

Function Documentation

◆ bezout()

Value bezout ( Value  a,
Value  b,
Value x,
Value y 
)

int bezout(int a, int b, int *x, int *y): calcule x et y, les deux nombres qui verifient le theoreme de Bezout pour a et b; le pgcd de a et b est retourne par valeur

a * x + b * y = gcd(a,b) return gcd(a,b)

Definition at line 265 of file pgcd.c.

266 {
268  Value a0,a1,u,v,r,q,c;
269 
270  if (value_ge(a,b))
271  {
272  a0 = a;
273  a1 = b;
274  c = VALUE_ZERO;
275  }
276  else
277  {
278  a0 = b;
279  a1 = a;
280  c = VALUE_ONE;
281  }
282 
283  r = value_mod(a0,a1);
284  while (value_notzero_p(r))
285  {
286  q = value_div(a0,a1);
287  u = value_mult(u1,q);
288  u = value_minus(u0,u);
289 
290  v = value_mult(v1,q);
291  v = value_minus(v0,v);
292  a0 = a1; a1 = r;
293  u0 = u1; u1 = u;
294  v0 = v1; v1 = v;
295 
296  r = value_mod(a0,a1);
297  }
298 
299  if (value_zero_p(c)) {
300  *x = u1;
301  *y = v1;
302  }
303  else {
304  *x = v1;
305  *y = u1;
306  }
307 
308  return(a1);
309 }
#define VALUE_ZERO
#define value_minus(v1, v2)
#define value_notzero_p(val)
#define value_zero_p(val)
int Value
#define VALUE_ONE
#define value_mult(v, w)
whether the default is protected or not this define makes no sense any more...
#define value_mod(v1, v2)
#define value_ge(v1, v2)
#define value_div(v1, v2)
static char * x
Definition: split_file.c:159

References value_div, value_ge, value_minus, value_mod, value_mult, value_notzero_p, VALUE_ONE, VALUE_ZERO, value_zero_p, and x.

Referenced by vecteur_bezout().

+ Here is the caller graph for this function:

◆ bezout_grl()

Value bezout_grl ( Value  a,
Value  b,
Value x,
Value y 
)

int bezout_grl(int a, int b, int *x, int *y): calcule x et y, les deux entiers quelconcs qui verifient le theoreme de Bezout pour a et b; le pgcd de a et b est retourne par valeur

a * x + b * y = gcd(a,b) return gcd(a,b) gcd () >=0 le pre et le post conditions de pgcd sont comme la fonction gcd_subtract(). les situations speciaux sont donnes ci_dessous: si (a==0 et b==0) x=y=0; gcd()=0, si (a==0)(ou b==0) x=1(ou -1) y=0 (ou x=0 y=1(ou -1)) et gcd()=a(ou -a) (ou gcd()=b(ou -b))

les signes de a et b

Definition at line 324 of file pgcd.c.

325 {
327  Value a0,a1,u,v,r,q,c;
328  Value sa,sb; /* les signes de a et b */
329 
330  sa = sb = VALUE_ONE;
331  if (value_neg_p(a)){
332  sa = VALUE_MONE;
333  a = value_uminus(a);
334  }
335  if (value_neg_p(b)){
336  sb = VALUE_MONE;
337  b = value_uminus(b);
338  }
339  if (value_zero_p(a) && value_zero_p(b)){
340  *x = VALUE_ONE;
341  *y = VALUE_ONE;
342  return VALUE_ZERO;
343  }
344  else if(value_zero_p(a) || value_zero_p(b)){
345  if (value_zero_p(a)){
346  *x = VALUE_ZERO;
347  *y = sb;
348  return(b);
349  }
350  else{
351  *x = sa;
352  *y = VALUE_ZERO;
353  return(a);
354  }
355  }
356  else{
357 
358  if (value_ge(a,b))
359  {
360  a0 = a;
361  a1 = b;
362  c = VALUE_ZERO;
363  }
364  else
365  {
366  a0 = b;
367  a1 = a;
368  c = VALUE_ONE;
369  }
370 
371  r = value_mod(a0,a1);
372  while (value_notzero_p(r))
373  {
374  q = value_div(a0,a1);
375  u = value_mult(u1,q);
376  u = value_minus(u0,u);
377 
378  v = value_mult(v1,q);
379  v = value_minus(v0,v);
380  a0 = a1; a1 = r;
381  u0 = u1; u1 = u;
382  v0 = v1; v1 = v;
383 
384  r = value_mod(a0,a1);
385  }
386 
387  if (value_zero_p(c)) {
388  *x = value_mult(sa,u1);
389  *y = value_mult(sb,v1);
390  }
391  else {
392  *x = value_mult(sa,v1);
393  *y = value_mult(sb,u1);
394  }
395 
396  return a1;
397  }
398 }
#define value_uminus(val)
unary operators on values
#define VALUE_MONE
#define value_neg_p(val)
Definition: statement.c:4047

References value_div, value_ge, value_minus, value_mod, VALUE_MONE, value_mult, value_neg_p, value_notzero_p, VALUE_ONE, value_uminus, VALUE_ZERO, value_zero_p, and x.

Referenced by base_G_h1_unnull().

+ Here is the caller graph for this function:

◆ gcd_subtract()

Value gcd_subtract ( Value  a,
Value  b 
)

int gcd_subtract(int a, int b): find the gcd (pgcd) of two integers

 There is no precondition on the input. Negative input is handled
 in the same way as positive ones. If one input is zero the output
 is equal to the other input - thus an input of two zeros is the
 only way an output of zero is created.

 Postcondition:     gcd(a,b) > 0 ; gcd(a,b)==0 iff a==0 and b==0
                 whereas it should be undefined (F. Irigoin)

 Exception: gcd(0,0) aborts

 Implementation: by subtractions

Note: the signs of a and b do not matter because they can be exactly divided by the gcd

b == 0

Definition at line 189 of file pgcd.c.

190 {
191  a = value_abs(a);
192  b = value_abs(b);
193 
194  while (value_notzero_p(a) && value_notzero_p(b)) {
195  if (value_ge(a,b))
196  a = value_minus(a,b);
197  else
198  b = value_minus(b,a);
199  }
200 
201  if (value_zero_p(a)) {
203  return b;
204  }
205  else {
206  /* b == 0 */
208  return a;
209  }
210 }
#define value_abs(val)
#define assert(ex)
Definition: newgen_assert.h:41

References assert, value_abs, value_ge, value_minus, value_notzero_p, and value_zero_p.

◆ pgcd_fast()

Value pgcd_fast ( Value  a,
Value  b 
)

int pgcd_fast(int a, int b): calcul iteratif du pgcd de deux entiers; le pgcd retourne est toujours positif; il n'est pas defini si a et b sont nuls (abort);

si cette routine n'est JAMAIS appelee avec des arguments nuls, il faudrait supprimer les deux tests d'egalite a 0; ca devrait etre le cas avec les vecteurs creux

Definition at line 82 of file pgcd.c.

83 {
84  Value gcd;
85 
87 
88  a = value_abs(a);
89  b = value_abs(b);
90 
91  /* si cette routine n'est JAMAIS appelee avec des arguments nuls,
92  il faudrait supprimer les deux tests d'egalite a 0; ca devrait
93  etre le cas avec les vecteurs creux */
94  if(value_gt(a,b))
95  gcd = value_zero_p(b)? a : pgcd_interne(a,b);
96  else
97  gcd = value_zero_p(a)? b : pgcd_interne(b,a);
98 
99  return gcd;
100 }
#define value_gt(v1, v2)
Value pgcd_interne(Value a, Value b)
int pgcd_interne(int a, int b): calcul iteratif du pgcd de deux entiers strictement positifs tels que...
Definition: pgcd.c:106

References assert, pgcd_interne(), value_abs, value_gt, value_notzero_p, and value_zero_p.

+ Here is the call graph for this function:

◆ pgcd_interne()

Value pgcd_interne ( Value  a,
Value  b 
)

int pgcd_interne(int a, int b): calcul iteratif du pgcd de deux entiers strictement positifs tels que a > b; le pgcd retourne est toujours positif;

Definition d'une look-up table pour les valeurs de a appartenant a 0..GCD_MAX_A et pour les valeurs de b appartenant a 1..GCD_MAX_B

Serait-il utile d'ajouter une test b==1 pour supprimer une colonne?

la commutativite du pgcd n'est pas utilisee pour reduire la taille de la table

b == 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

a == 0

a == 1

a == 2

a == 3

a == 4

a == 5

a == 6

a == 7

a == 8

a == 9

a == 10

a == 11

a == 12

a == 13

a == 14

a == 15

on pourrait aussi utiliser une table des nombres premiers pour diminuer le nombre de boucles

on utilise la valeur particuliere -1 pour iterer

compute modulo(a,b) en utilisant la routine C puisque a et b sont strictement positifs (vaudrait-il mieux utiliser la soustraction?)

Definition at line 106 of file pgcd.c.

107 {
108  /* Definition d'une look-up table pour les valeurs de a appartenant
109  a [0..GCD_MAX_A] (en fait [-GCD_MAX_A..GCD_MAX_A])
110  et pour les valeurs de b appartenant a [1..GCD_MAX_B]
111  (en fait [-GCD_MAX_B..GCD_MAX_B] a cause du changement de signe)
112 
113  Serait-il utile d'ajouter une test b==1 pour supprimer une colonne?
114  */
115 #define GCD_MAX_A 15
116 #define GCD_MAX_B 15
117  /* la commutativite du pgcd n'est pas utilisee pour reduire la
118  taille de la table */
119  static Value
120  gcd_look_up[GCD_MAX_A+1][GCD_MAX_B+1]= {
121  /* b == 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
122  {/* a == 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},
123  {/* a == 1 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
124  {/* a == 2 */ 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1},
125  {/* a == 3 */ 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3},
126  {/* a == 4 */ 4, 1, 2, 1, 4, 1, 2, 1, 4, 1, 2, 1, 4, 1, 2, 1},
127  {/* a == 5 */ 5, 1, 1, 1, 1, 5, 1, 1, 1, 1, 5, 1, 1, 1, 1, 5},
128  {/* a == 6 */ 6, 1, 2, 3, 2, 1, 6, 1, 2, 3, 2, 1, 6, 1, 2, 3},
129  {/* a == 7 */ 7, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 7, 1},
130  {/* a == 8 */ 8, 1, 2, 1, 4, 1, 2, 1, 8, 1, 2, 1, 4, 1, 2, 1},
131  {/* a == 9 */ 9, 1, 1, 3, 1, 1, 3, 1, 1, 9, 1, 1, 3, 1, 1, 3},
132  {/* a == 10 */10, 1, 2, 1, 2, 5, 2, 1, 2, 1,10, 1, 2, 1, 2, 5},
133  {/* a == 11 */11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,11, 1, 1, 1, 1},
134  {/* a == 12 */12, 1, 2, 3, 4, 1, 6, 1, 4, 3, 2, 1,12, 1, 2, 3},
135  {/* a == 13 */13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,13, 1, 1},
136  {/* a == 14 */14, 1, 2, 1, 2, 1, 2, 7, 2, 1, 2, 1, 2, 1,14, 1},
137  {/* a == 15 */15, 1, 1, 3, 1, 5, 3, 1, 1, 3, 5, 1, 3, 1, 1, 15}
138  };
139  /* on pourrait aussi utiliser une table des nombres premiers
140  pour diminuer le nombre de boucles */
141 
142  /* on utilise la valeur particuliere -1 pour iterer */
143  Value gcd = VALUE_MONE;
144  Value mod;
145 
146  assert(value_gt(a,b) && value_pos_p(b));
147 
148  do{
149  if(value_le(b,int_to_value(GCD_MAX_B)) &&
151  gcd = gcd_look_up[VALUE_TO_INT(a)][VALUE_TO_INT(b)];
152  break;
153  }
154  else {
155  /* compute modulo(a,b) en utilisant la routine C puisque a et b
156  sont strictement positifs (vaudrait-il mieux utiliser la
157  soustraction?) */
158  mod = value_mod(a,b);
159  if(value_zero_p(mod)) {
160  gcd = b;
161  }
162  else {
163  a = b;
164  b = mod;
165  }
166  }
167  } while(value_neg_p(gcd));
168 
169  return gcd;
170 }
#define value_pos_p(val)
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
#define VALUE_TO_INT(val)
#define value_le(v1, v2)
#define GCD_MAX_A
#define GCD_MAX_B

References assert, GCD_MAX_A, GCD_MAX_B, int_to_value, value_gt, value_le, value_mod, VALUE_MONE, value_neg_p, value_pos_p, VALUE_TO_INT, and value_zero_p.

Referenced by pgcd_fast().

+ Here is the caller graph for this function:

◆ pgcd_slow()

Value pgcd_slow ( Value  a,
Value  b 
)

package arithmetique

pgcd.c

INTLIBRARY Value pgcd_slow(Value a, Value b) computation of the gcd of a and b. the result is always positive. standard algorithm in log(max(a,b)). pgcd_slow(0,0)==1 (maybe should we abort?). I changed from a recursive for a simple iterative version, FC 07/96.

a==0, b==0

a==0, b!=0

a!=0, b==0

a==b

swap

on entry in this loop, a > b > 0 is insured

Definition at line 44 of file pgcd.c.

45 {
46  Value m;
47 
48  if (value_zero_p(a))
49  {
50  if (value_zero_p(b))
51  return VALUE_ONE; /* a==0, b==0 */
52  else
53  return value_abs(b); /* a==0, b!=0 */
54  }
55  else
56  if (value_zero_p(b))
57  return value_abs(a); /* a!=0, b==0 */
58 
59  value_absolute(a);
60  value_absolute(b);
61 
62  if (value_eq(a,b)) /* a==b */
63  return a;
64 
65  if (value_gt(b,a))
66  m = a, a = b, b = m; /* swap */
67 
68  /* on entry in this loop, a > b > 0 is insured */
69  do {
70  m = value_mod(a,b);
71  a = b;
72  b = m;
73  } while(value_notzero_p(b));
74 
75  return a;
76 }
#define value_absolute(ref)
#define value_eq(v1, v2)
bool operators on values

References value_abs, value_absolute, value_eq, value_gt, value_mod, value_notzero_p, VALUE_ONE, and value_zero_p.

Referenced by matrice_determinant(), matrice_diagonale_inversion(), matrice_triangulaire_inversion(), matrix_determinant(), and substitute_var_with_vec().

+ Here is the caller graph for this function:

◆ vecteur_bezout()

Value vecteur_bezout ( Value  u[],
Value  v[],
int  l 
)

int vecteur_bezout(int u[], int v[], int l): calcul du vecteur v qui verifie le theoreme de bezout pour le vecteur u; les vecteurs u et v sont de dimension l

-> -> -> < u . v > = gcd(u ) i

printf("gcd = %d \n",gcd);

sum u * v = gcd(u ) k<l k k k<l k

a1 = gcd (u ) k<l-1 k

printf("gcd = %d\n",gcd);

Definition at line 220 of file pgcd.c.

221 {
222  Value gcd, a1, x;
223  Value *p1, *p2;
224  int i, j;
225 
226  assert(l>0);
227 
228  if (l==1) {
229  v[0] = VALUE_ONE;
230  gcd = u[0];
231  }
232  else {
233  p1 = &v[0]; p2 = &v[1];
234  a1 = u[0]; gcd = u[1];
235  gcd = bezout(a1,gcd,p1,p2);
236 
237  /* printf("gcd = %d \n",gcd); */
238 
239  for (i=2;i<l;i++){
240  /* sum u * v = gcd(u )
241  * k<l k k k<l k
242  *
243  * a1 = gcd (u )
244  * k<l-1 k
245  */
246  a1 = u[i];
247  p1 = &v[i];
248  gcd = bezout(a1,gcd,p1,&x);
249  /* printf("gcd = %d\n",gcd); */
250  for (j=0;j<i;j++)
251  value_product(v[j],x);
252  }
253  }
254 
255  return gcd;
256 }
#define value_product(v, w)
Value bezout(Value a, Value b, Value *x, Value *y)
int bezout(int a, int b, int *x, int *y): calcule x et y, les deux nombres qui verifient le theoreme ...
Definition: pgcd.c:265

References assert, bezout(), VALUE_ONE, value_product, and x.

+ Here is the call graph for this function: