polylib 5.22.8
NormalForms.c
Go to the documentation of this file.
1#include <polylib/polylib.h>
2#include <stdlib.h>
3
4/* nota bene: on stocke les matrices par lignes */
5/* nota bene: matrices are stored in row major order */
6
7/*------------------------------------------------------------------------
8 change les signes de la ligne i de la matrice A
9 change the sign of row i of matrix A
10------------------------------------------------------------------------*/
11
12static void moins_l(Value *a, int i, int n, int p) {
13
14 int k;
15 Value *c;
16
17 c = a + (i - 1) * p;
18
19 for (k = 1; k <= p; k++) {
20 value_oppose(*c, *c);
21 c++;
22 }
23 return;
24} /* moins_l */
25
26/*------------------------------------------------------------------------
27 change les signes de la colonne i de la matrice A
28 change the sign of column i of matrix A
29------------------------------------------------------------------------*/
30
31static void moins_c(Value *a, int i, int n, int p) {
32
33 int k;
34 Value *c;
35
36 c = a + (i - 1);
37
38 for (k = 1; k <= n; k++) {
39 value_oppose(*c, *c);
40 c = c + p;
41 }
42 return;
43} /* moins_c */
44
45/*------------------------------------------------------------------------
46 echange les lignes i et j de la matrice A
47 exchange row i and j of matrix A
48------------------------------------------------------------------------*/
49
50static void echange_l(Value *a, int i, int j, int n, int p) {
51
52 int k;
53 Value s;
54 Value *c1, *c2;
55
57 c1 = a + (i - 1) * p;
58 c2 = a + (j - 1) * p;
59
60 for (k = 1; k <= p; k++) {
61 value_assign(s, *c1);
62 value_assign(*c1, *c2);
63 value_assign(*c2, s);
64 c1++;
65 c2++;
66 }
68 return;
69} /* echange_l */
70
71/*------------------------------------------------------------------------
72 echange les colonnes i et j de la matrice A
73 exchange columns i and j of matrix A
74------------------------------------------------------------------------*/
75
76static void echange_c(Value *a, int i, int j, int n, int p) {
77
78 int k;
79 Value s;
80 Value *c1, *c2;
81
83 c1 = a + (i - 1);
84 c2 = a + (j - 1);
85
86 for (k = 1; k <= n; k++) {
87 value_assign(s, *c1);
88 value_assign(*c1, *c2);
89 value_assign(*c2, s);
90 c1 = c1 + p;
91 c2 = c2 + p;
92 }
94 return;
95} /* echange_c */
96
97/*------------------------------------------------------------------------
98 A est une matrice de taille n*p
99 on ajoute a la ligne i, x fois la ligne j
100 A is a matrix of size n*p
101 we add x times the row j to the row i
102------------------------------------------------------------------------*/
103
104static void ligne(Value *a, int i, int j, Value x, int n, int p) {
105
106 int k;
107 Value *c1, *c2;
108
109 c1 = a + (i - 1) * p;
110 c2 = a + (j - 1) * p;
111
112 for (k = 1; k <= p; k++) {
113
114 value_addmul(*c1, x, *c2);
115 c1++;
116 c2++;
117 }
118 return;
119} /* ligne */
120
121/*------------------------------------------------------------------------
122 A est une matrice de taille n*p
123 on ajoute a la colonne i, x fois la colonne j
124 A is a matrix of size n*p
125 we add x times the column j to the column i
126
127------------------------------------------------------------------------*/
128
129static void colonne(Value *a, int i, int j, Value x, int n, int p) {
130
131 int k;
132 Value *c1, *c2;
133
134 c1 = a + (i - 1);
135 c2 = a + (j - 1);
136
137 for (k = 1; k <= n; k++) {
138 value_addmul(*c1, x, *c2);
139 c1 = c1 + p;
140 c2 = c2 + p;
141 }
142 return;
143} /* colonne */
144
145/*----------------------------------------------------------------------
146 trouve le numero de colonne du plus petit element non nul de
147 la ligne q, d'indice superieur a q, de la matrice A, mais
148 renvoie zero si tous les elements sont nuls sauf le qieme.
149
150 find the column number (greater than q) of the smallest non
151 null element of row q . it returns
152 0 if all the last elements of row q are null except the qth
153
154----------------------------------------------------------------------*/
155
156static int petit_l(Value *a, int n, int p, int q) {
157
158 int numero = 0, k, tousnuls;
159 Value minus, comp;
160 Value *c;
161
162 value_init(minus);
163 value_init(comp);
164 c = a + (q - 1) * p + (p - 1);
165 tousnuls = 1;
166 for (k = p; k > q; k--) {
167 value_absolute(comp, *c);
168 if (value_notzero_p(comp)) {
169 if (tousnuls == 1) {
170 value_assign(minus, comp);
171 numero = k;
172 tousnuls = 0;
173 } else if (value_ge(minus, comp)) {
174 value_assign(minus, comp);
175 numero = k;
176 }
177 }
178 c--;
179 }
180 if (tousnuls == 1) {
181 value_clear(minus);
182 value_clear(comp);
183 return (0);
184 } else {
185 value_absolute(comp, *c);
186 if ((value_notzero_p(comp)) && (value_ge(minus, comp))) {
187 value_clear(minus);
188 value_clear(comp);
189 return (q);
190 } else {
191 value_clear(minus);
192 value_clear(comp);
193 return (numero);
194 }
195 }
196} /* petit_l */
197
198/*----------------------------------------------------------------------
199 trouve le numero de ligne du plus petit element non nul de
200 la colonne q, d'indice superieur a q, de la matrice A, mais
201 renvoie zero si tous les elements sont nuls sauf le qieme.
202
203 find the row number (greater than q) of the smallest non
204 null element of column q . it returns
205 0 if all the last elements of column q are null except the qth
206
207----------------------------------------------------------------------*/
208
209static int petit_c(Value *a, int n, int p, int q) {
210
211 int numero = 0, k, tousnuls;
212 Value minus, comp;
213 Value *c;
214
215 value_init(minus);
216 value_init(comp);
217 c = a + q - 1 + p * (n - 1);
218 tousnuls = 1;
219 for (k = n; k > q; k--) {
220 value_absolute(comp, *c);
221 if (value_notzero_p(comp)) {
222 if (tousnuls == 1) {
223 value_assign(minus, comp);
224 numero = k;
225 tousnuls = 0;
226 } else if (value_ge(minus, comp)) {
227 value_assign(minus, comp);
228 numero = k;
229 }
230 }
231 c = c - p;
232 }
233
234 if (tousnuls == 1) {
235 value_clear(minus);
236 value_clear(comp);
237 return (0);
238 } else {
239 value_absolute(comp, *c);
240 if ((value_notzero_p(comp)) && (value_ge(minus, comp))) {
241 value_clear(minus);
242 value_clear(comp);
243 return (q);
244 } else {
245 value_clear(minus);
246 value_clear(comp);
247 return (numero);
248 }
249 }
250} /* petit_c */
251
252/*-----------------------------------------------------------------------
253 A est initialisee a une matrice "identite" de taille n*p
254 A is initialized to an "identity" matrix of size n*p
255-----------------------------------------------------------------------*/
256
257static void identite(Value *a, int n, int p) {
258
259 int i, j;
260 Value *b;
261
262 b = a;
263 for (i = 1; i <= n; i++) {
264 for (j = 1; j <= p; j++) {
265 if (i == j)
266 value_set_si(*b, 1);
267 else
268 value_set_si(*b, 0);
269 b++;
270 }
271 }
272 return;
273} /* identite */
274
275/*-----------------------------------------------------------------------
276 transpose la sous-matrice de A dont les indices sont
277 superieurs ou egaux a q
278 transposition of the sub-matrix of A composed of the elements
279 whose indices are greater or equal to q
280-----------------------------------------------------------------------*/
281
282static void transpose(Value *a, int n, int q) {
283
284 int i;
285 Value val;
286 Value *b, *c;
287
288 value_init(val);
289 if (q < n) {
290 b = a + (q - 1) + (q - 1) * n;
291 c = b;
292 for (i = q + 1; i <= n; i++) {
293 b++;
294 c = c + n;
295 value_assign(val, *b);
296 value_assign(*b, *c);
297 value_assign(*c, val);
298 }
299 transpose(a, n, q + 1);
300 }
301 value_clear(val);
302 return;
303} /* transpose */
304
305/*----------------------------------------------------------------------
306 trouve le numero de colonne du premier element non divisible
307 par val dans la sous-matrice d'indices > q mais renvoie 0 sinon
308
309 find the column number of the first non-divisible by val element
310 in the sub-matrix of a composed of the elements of indices >q.
311 Return 0 is there is no such element
312----------------------------------------------------------------------*/
313
314static int encore(Value *a, int n, int p, int q, Value val) {
315
316 int k, l;
317 Value comp, tmp;
318 Value *c;
319
320 if ((q >= n) || (q >= p))
321 return (0);
322
323 value_init(comp);
324 value_init(tmp);
325 c = a + q * p + q;
326 k = q + 1;
327 l = q + 1;
328 while (k <= n) {
329 value_absolute(comp, *c);
330 if (value_zero_p(val)) {
331 if (value_notzero_p(comp)) {
332 value_clear(comp);
333 value_clear(tmp);
334 return (l);
335 }
336 } else {
337 value_modulus(tmp, comp, val);
338 if (value_notzero_p(tmp)) {
339 value_clear(comp);
340 value_clear(tmp);
341 return (l);
342 }
343 }
344 if (l == p) {
345 k = k + 1;
346 l = q + 1;
347 c = c + q + 1;
348 } else {
349 l++;
350 c++;
351 }
352 }
353 value_clear(comp);
354 value_clear(tmp);
355 return (0);
356} /* encore */
357
358/*----------------------------------------------------------------------
359 transforme la matrice A (de taille n*p), a partir de la position
360 q*q en sa forme de smith, les matrices b et c subissant les memes
361 transformations respectivement sur les lignes et colonnes
362
363 transform the matrix A (size n*p), from position (q,q) into
364 its smith normal form. the same transformations are applied to
365 matrices b and c, respectively on rows and on columns
366----------------------------------------------------------------------*/
367
368static void smith(Value *a, Value *b, Value *c, Value *b_inverse,
369 Value *c_inverse, int n, int p, int q) {
370
371 int i, k, fini;
372 Value x, pivot, tmp, x_inv;
373 Value *f;
374
375 value_init(pivot);
376 value_init(tmp);
377 value_init(x);
378 value_init(x_inv);
379
380 if ((q <= n) && (q <= p)) {
381 fini = 1;
382
383 while (fini != 0) {
384 i = petit_c(a, n, p, q);
385 while (i != 0) {
386 if (i != q) {
387 echange_l(a, i, q, n, p);
388 echange_l(b, i, q, n, n);
389 echange_c(b_inverse, i, q, n, n);
390 }
391 f = a + (q - 1) + (q - 1) * p;
392 value_assign(pivot, *f);
393 if (value_neg_p(pivot)) {
394 moins_l(a, q, n, p);
395 moins_l(b, q, n, n);
396 moins_c(b_inverse, q, n, n);
397 value_oppose(pivot, pivot);
398 }
399 for (k = q + 1; k <= n; k++) {
400 f = f + p;
401 if (value_notzero_p(*f)) {
402 value_division(x, *f, pivot);
403 value_modulus(tmp, *f, pivot);
404 if (value_neg_p(tmp))
405 value_decrement(x, x);
406 value_oppose(x_inv, x);
407 ligne(a, k, q, x_inv, n, p);
408 ligne(b, k, q, x_inv, n, n);
409 colonne(b_inverse, q, k, x, n, n);
410 }
411 }
412 i = petit_c(a, n, p, q);
413 }
414 fini = 0;
415 i = petit_l(a, n, p, q);
416 while (i != 0) {
417 if (i != q) {
418 echange_c(a, i, q, n, p);
419 echange_c(c, i, q, p, p);
420 echange_l(c_inverse, i, q, p, p);
421 fini = 1;
422 }
423 f = a + (q - 1) + (q - 1) * p;
424 value_assign(pivot, *f);
425 if (value_neg_p(pivot)) {
426 moins_c(a, q, n, p);
427 moins_c(c, q, p, p);
428 moins_l(c_inverse, q, p, p);
429 value_oppose(pivot, pivot);
430 }
431 for (k = q + 1; k <= p; k++) {
432 f++;
433 if (value_notzero_p(*f)) {
434 value_division(x, *f, pivot);
435 value_modulus(tmp, *f, pivot);
436 if (value_neg_p(tmp))
437 value_decrement(x, x);
438 value_oppose(x_inv, x);
439 colonne(a, k, q, x_inv, n, p);
440 colonne(c, k, q, x_inv, p, p);
441 ligne(c_inverse, q, k, x, p, p);
442 }
443 }
444 i = petit_l(a, n, p, q);
445 }
446 }
447 value_assign(pivot, *(a + (q - 1) + (q - 1) * p));
448 if (value_neg_p(pivot)) {
449 moins_l(a, q, n, p);
450 moins_l(b, q, n, n);
451 moins_c(b_inverse, q, n, n);
452 value_oppose(pivot, pivot);
453 }
454
455 i = encore(a, n, p, q, pivot);
456 if (i != 0) {
457 value_set_si(x, 1);
458 value_set_si(x_inv, -1);
459 colonne(a, q, i, x, n, p);
460 colonne(c, q, i, x, p, p);
461 ligne(c_inverse, i, q, x_inv, p, p);
462 smith(a, b, c, b_inverse, c_inverse, n, p, q);
463 } else
464 smith(a, b, c, b_inverse, c_inverse, n, p, q + 1);
465 }
466 value_clear(pivot);
467 value_clear(tmp);
468 value_clear(x);
469 value_clear(x_inv);
470
471 return;
472} /* smith */
473
474/*----------------------------------------------------------------------
475 decompose la matrice A en le produit d'une matrice B
476 unimodulaire et d'une matrice triangulaire superieure
477 D est l'inverse de B
478 Decompose the matrix A in the product of a matrix B unimodular
479 and a matrix upper triangular, D is the inverse of B
480----------------------------------------------------------------------*/
481
482static void hermite(Value *a, Value *b, Value *d, int n, int p, int q) {
483
484 int i, k;
485 Value x, pivot, x_inv, tmp;
486 Value *c1;
487
488 value_init(pivot);
489 value_init(tmp);
490 value_init(x);
491 value_init(x_inv);
492
493 if ((q <= p) && (q <= n)) {
494 i = petit_c(a, n, p, q);
495 while (i != 0) {
496 if (i != q) {
497 echange_l(a, i, q, n, p);
498 echange_c(b, i, q, n, n);
499 echange_l(d, i, q, n, n);
500 }
501
502 c1 = a + (q - 1) + (q - 1) * p;
503 value_assign(pivot, *c1);
504 if (value_neg_p(pivot)) {
505 moins_l(a, q, n, p);
506 moins_l(d, q, n, n);
507 moins_c(b, q, n, n);
508 value_oppose(pivot, pivot);
509 }
510 for (k = q + 1; k <= n; k++) {
511 c1 = c1 + p;
512 if (value_notzero_p(*c1)) {
513 value_division(x, *c1, pivot);
514 value_modulus(tmp, *c1, pivot);
515 if (value_neg_p(tmp))
516 value_decrement(x, x);
517 value_oppose(x_inv, x);
518 ligne(a, k, q, x_inv, n, p);
519 colonne(b, q, k, x, n, n);
520 ligne(d, k, q, x_inv, n, n);
521 }
522 }
523 i = petit_c(a, n, p, q);
524 }
525 c1 = a + (q - 1);
526 value_assign(pivot, *(c1 + (q - 1) * p));
527 if (value_neg_p(pivot)) {
528 moins_l(a, q, n, p);
529 moins_l(d, q, n, n);
530 moins_c(b, q, n, n);
531 value_oppose(pivot, pivot);
532 }
533 if (value_notzero_p(pivot)) {
534 for (k = 1; k < q; k++) {
535 if (value_notzero_p(*c1)) {
536 value_division(x, *c1, pivot);
537 value_modulus(tmp, *c1, pivot);
538 if (value_neg_p(tmp))
539 value_decrement(x, x);
540 value_oppose(x_inv, x);
541 ligne(a, k, q, x_inv, n, p);
542 colonne(b, q, k, x, n, n);
543 ligne(d, k, q, x_inv, n, n);
544 }
545 c1 = c1 + p;
546 }
547 }
548 hermite(a, b, d, n, p, q + 1);
549 }
550 value_clear(pivot);
551 value_clear(tmp);
552 value_clear(x);
553 value_clear(x_inv);
554 return;
555} /* hermite */
556
557/*----------------------------------------------------------------------
558 B est une g_base de dimension n dont les p premiers vecteurs
559 colonnes sont colineaires aux vecteurs colonnes de A
560 C est l'invers de B
561
562 B is an integral (g_base ?) of dimension n whose p first columns
563 vectors are proportionnal to the column vectors of A. C is the
564 inverse of B.
565 ----------------------------------------------------------------------*/
566
567/** Convert PolmattoDarmat :
568*** This function converts the matrix of a Polylib to a int * as necessary
569*** for the functions in Darte's implementation.
570***
571*** Input : A Polylib Matrix ( a pointer to it );
572*** Output : An int * with the matrix copied into it
573**/
574static Value *ConvertPolMattoDarMat(Matrix *A) {
575
576 int i, j;
577 Value *result;
578
579 result = (Value *)malloc(sizeof(Value) * A->NbRows * A->NbColumns);
580 for (i = 0; i < A->NbRows * A->NbColumns; i++)
581 value_init(result[i]);
582
583 for (i = 0; i < A->NbRows; i++)
584 for (j = 0; j < A->NbColumns; j++)
585 value_assign(result[i * A->NbColumns + j], A->p[i][j]);
586 return result;
587} /* ConvertPolMattoDarMat */
588
589/** Convert DarmattoPolmat
590*** This function converts the matrix from Darte representation to a matrix
591*** in PolyLib.
592***
593*** Input : The matrix (a pointer to it), number of Rows, number of columns
594*** Output : The matrix of the PolyLib
595***
596**/
597
598static Matrix *ConvertDarMattoPolMat(Value *A, int NbRows, int NbCols) {
599
600 int i, j;
601 Matrix *result;
602
603 result = Matrix_Alloc(NbRows, NbCols);
604
605 for (i = 0; i < NbRows; i++)
606 for (j = 0; j < NbCols; j++)
607 value_assign(result->p[i][j], A[i * NbCols + j]);
608 return result;
609} /* ConvertDarMattoPolMat */
610
611/**
612*** Smith : This function takes a Matrix A of dim n * l as its input
613*** and returns the three matrices U, V and Product such that
614*** A = U * Product * V, where U is an unimodular matrix of dimension
615*** n * n and V is an unimodular matrix of dimension l * l.
616*** Product is a diagonal matrix of dimension n * l.
617***
618*** We use Alan Darte's implementation of Smith for computing
619*** the Smith Normal Form
620**/
621void Smith(Matrix *A, Matrix **U, Matrix **V, Matrix **Product) {
622 int i;
623 Matrix *u, *v;
624
625 u = Identity(A->NbRows);
626 v = Identity(A->NbColumns);
627
628 *U = Identity(A->NbRows);
629 *V = Identity(A->NbColumns);
630
631 *Product = Matrix_Copy(A);
632 smith((*Product)->p_Init, u->p_Init, v->p_Init, (*U)->p_Init, (*V)->p_Init,
633 A->NbRows, A->NbColumns, 1);
634
635 Matrix_Free(u);
636 Matrix_Free(v);
637} /* Smith */
638
639/** Hermite :
640*** This function takes a Matrix as its input and finds its HNF
641*** ( Left form )
642***
643*** Input : A Matrix A (The Matrix A is not necessarily a Polylib matrix.
644*** It is just a matrix as far as Hermite is concerned. It
645*** does not even check if the matrix is a Polylib matrix or not)
646*** Output : The Hnf matrix H and the Unimodular matrix U such that
647*** A = H * U.
648***
649*** We use Alan Darte's implementation of Hermite to compute the HNF.
650*** Alan Darte's implementation computes the Upper Triangular HNF.
651*** So We work on the fact that if A = H * U then
652*** A (transpose) = U(transpose) * H (transpose)
653*** There are a set of interface functions written in Interface.c
654*** which convert a matrix from Polylib representationt to that of
655*** Alan Darte's and vice versa.
656***
657*** This Function Does the Following
658*** Step 1 : Given the matrix A it finds its Transpose.
659*** Step 2 : Finds the HNF (Right Form) using Alan Darte's Algorithm.
660*** Step 3 : The H1 and U1 obtained in Step2 are both Transposed to get
661*** the actual H and U such that A = HU.
662**/
663void Hermite(Matrix *A, Matrix **H, Matrix **U) {
664
665 int i;
666 Matrix *transpose, *tempH, *tempU;
667 Value *darte_matA, *darte_identite, *darte_id_inv;
668
669 transpose = Transpose(A);
670 darte_matA = ConvertPolMattoDarMat(transpose);
671
672 darte_identite = (Value *)malloc(sizeof(Value) * A->NbColumns * A->NbColumns);
673 darte_id_inv = (Value *)malloc(sizeof(Value) * A->NbColumns * A->NbColumns);
674 for (i = 0; i < A->NbColumns * A->NbColumns; i++)
675 value_init(darte_identite[i]);
676 for (i = 0; i < A->NbColumns * A->NbColumns; i++)
677 value_init(darte_id_inv[i]);
678
679 identite(darte_identite, transpose->NbRows, transpose->NbRows);
680 identite(darte_id_inv, transpose->NbRows, transpose->NbRows);
681 hermite(darte_matA, darte_identite, darte_id_inv, A->NbColumns, A->NbRows, 1);
683 transpose = ConvertDarMattoPolMat(darte_matA, A->NbColumns, A->NbRows);
684 tempU = ConvertDarMattoPolMat(darte_identite, A->NbColumns, A->NbColumns);
685
686 /* Finding H Transpose */
687 tempH = Transpose(transpose);
689
690 /* Finding U Transpose */
691 transpose = Transpose(tempU);
692
693 H[0] = Matrix_Copy(tempH);
694 U[0] = Matrix_Copy(transpose);
695
696 Matrix_Free(tempH);
698 Matrix_Free(tempU);
699
700 for (i = 0; i < A->NbRows * A->NbColumns; i++)
701 value_clear(darte_matA[i]);
702 for (i = 0; i < A->NbColumns * A->NbColumns; i++)
703 value_clear(darte_identite[i]);
704 for (i = 0; i < A->NbColumns * A->NbColumns; i++)
705 value_clear(darte_id_inv[i]);
706 free(darte_matA);
707 free(darte_identite);
708 free(darte_id_inv);
709 return;
710} /* Hermite */
Matrix * Identity(unsigned size)
Definition: Matop.c:39
Matrix * Transpose(Matrix *A)
Definition: Matop.c:83
Matrix * Matrix_Copy(Matrix const *Src)
Definition: Matop.c:98
static void moins_l(Value *a, int i, int n, int p)
Definition: NormalForms.c:12
static void identite(Value *a, int n, int p)
Definition: NormalForms.c:257
void Smith(Matrix *A, Matrix **U, Matrix **V, Matrix **Product)
Smith : This function takes a Matrix A of dim n * l as its input and returns the three matrices U,...
Definition: NormalForms.c:621
static int encore(Value *a, int n, int p, int q, Value val)
Definition: NormalForms.c:314
static void colonne(Value *a, int i, int j, Value x, int n, int p)
Definition: NormalForms.c:129
static void smith(Value *a, Value *b, Value *c, Value *b_inverse, Value *c_inverse, int n, int p, int q)
Definition: NormalForms.c:368
static void moins_c(Value *a, int i, int n, int p)
Definition: NormalForms.c:31
static void hermite(Value *a, Value *b, Value *d, int n, int p, int q)
Definition: NormalForms.c:482
static Value * ConvertPolMattoDarMat(Matrix *A)
Convert PolmattoDarmat : This function converts the matrix of a Polylib to a int * as necessary for t...
Definition: NormalForms.c:574
static Matrix * ConvertDarMattoPolMat(Value *A, int NbRows, int NbCols)
Convert DarmattoPolmat This function converts the matrix from Darte representation to a matrix in Pol...
Definition: NormalForms.c:598
static void transpose(Value *a, int n, int q)
Definition: NormalForms.c:282
static void ligne(Value *a, int i, int j, Value x, int n, int p)
Definition: NormalForms.c:104
void Hermite(Matrix *A, Matrix **H, Matrix **U)
Hermite : This function takes a Matrix as its input and finds its HNF ( Left form )
Definition: NormalForms.c:663
static void echange_c(Value *a, int i, int j, int n, int p)
Definition: NormalForms.c:76
static void echange_l(Value *a, int i, int j, int n, int p)
Definition: NormalForms.c:50
static int petit_l(Value *a, int n, int p, int q)
Definition: NormalForms.c:156
static int petit_c(Value *a, int n, int p, int q)
Definition: NormalForms.c:209
#define value_oppose(ref, val)
Definition: arithmetique.h:552
#define value_notzero_p(val)
Definition: arithmetique.h:576
#define value_absolute(ref, val)
Definition: arithmetique.h:553
#define value_decrement(ref, val)
Definition: arithmetique.h:546
#define value_zero_p(val)
Definition: arithmetique.h:575
#define value_assign(v1, v2)
Definition: arithmetique.h:482
#define value_set_si(val, i)
Definition: arithmetique.h:483
#define value_addmul(ref, val1, val2)
Definition: arithmetique.h:539
#define value_clear(val)
Definition: arithmetique.h:485
#define value_division(ref, val1, val2)
Definition: arithmetique.h:547
#define value_modulus(ref, val1, val2)
Definition: arithmetique.h:549
#define value_ge(v1, v2)
Definition: arithmetique.h:505
#define value_neg_p(val)
Definition: arithmetique.h:572
#define value_init(val)
Definition: arithmetique.h:481
Matrix * Matrix_Alloc(unsigned NbRows, unsigned NbColumns)
Definition: matrix.c:24
void Matrix_Free(Matrix *Mat)
Definition: matrix.c:71
static int n
Definition: polyparam.c:276
char s[128]
Definition: polytest.c:8
Definition: types.h:75
unsigned NbRows
Definition: types.h:76
Value ** p
Definition: types.h:77
unsigned NbColumns
Definition: types.h:76
Value * p_Init
Definition: types.h:78