polylib 5.22.8
vector.c
Go to the documentation of this file.
1/* vector.c
2 COPYRIGHT
3 Both this software and its documentation are
4
5 Copyrighted 1993 by IRISA /Universite de Rennes I - France,
6 Copyright 1995,1996 by BYU, Provo, Utah
7 all rights reserved.
8
9*/
10
11#include <polylib/polylib.h>
12#include <stdio.h>
13#include <stdlib.h>
14
15/* defined by configure script */
16/* #define THREAD_SAFE_POLYLIB */
17
18#ifdef MAC_OS
19#define abs __abs
20#endif
21
22/*
23 * Compute n!
24 */
25void Factorial(int n, Value *fact) {
26
27 int i;
28 Value tmp;
29
30 value_init(tmp);
31
32 value_set_si(*fact, 1);
33 for (i = 1; i <= n; i++) {
34 value_set_si(tmp, i);
35 value_multiply(*fact, *fact, tmp);
36 }
37 value_clear(tmp);
38} /* Factorial */
39
40/*
41 * Compute n!/(p!(n-p)!)
42 */
43void Binomial(int n, int p, Value *result) {
44
45 int i;
46 Value tmp;
47 Value f;
48
49 value_init(tmp);
50 value_init(f);
51
52 if (n - p < p)
53 p = n - p;
54 if (p != 0) {
55 value_set_si(*result, (n - p + 1));
56 for (i = n - p + 2; i <= n; i++) {
57 value_set_si(tmp, i);
58 value_multiply(*result, *result, tmp);
59 }
60 Factorial(p, &f);
61 value_division(*result, *result, f);
62 } else
63 value_set_si(*result, 1);
64 value_clear(f);
65 value_clear(tmp);
66} /* Binomial */
67
68/*
69 * Return the number of ways to choose 'b' items from 'a' items, that is,
70 * return a!/(b!(a-b)!)
71 */
72void CNP(int a, int b, Value *result) {
73
74 int i;
75 Value tmp;
76 value_init(tmp);
77
78 value_set_si(*result, 1);
79
80 /* If number of items is less than the number to be choosen, return 1 */
81 if (a <= b) {
82 value_clear(tmp);
83 return;
84 }
85 for (i = a; i > b; --i) {
86 value_set_si(tmp, i);
87 value_multiply(*result, *result, tmp);
88 }
89 for (i = 1; i <= (a - b); ++i) {
90 value_set_si(tmp, i);
91 value_division(*result, *result, tmp);
92 }
93 value_clear(tmp);
94} /* CNP */
95
96/*
97 * Compute GCD of 'a' and 'b'
98 */
99void Gcd(Value a, Value b, Value *result) {
100
101 Value acopy, bcopy;
102
103 value_init(acopy);
104 value_init(bcopy);
105 value_assign(acopy, a);
106 value_assign(bcopy, b);
107 while (value_notzero_p(acopy)) {
108 value_modulus(*result, bcopy, acopy);
109 value_assign(bcopy, acopy);
110 value_assign(acopy, *result);
111 }
112 value_absolute(*result, bcopy);
113 value_clear(acopy);
114 value_clear(bcopy);
115} /* Gcd */
116
117/*
118 * Return the smallest component index in 'p' whose value is non-zero
119 */
120int First_Non_Zero(Value *p, unsigned length) {
121
122 Value *cp;
123 int i;
124
125 cp = p;
126 for (i = 0; i < length; i++) {
127 if (value_notzero_p(*cp))
128 break;
129 cp++;
130 }
131 return ((i == length) ? -1 : i);
132} /* First_Non_Zero */
133
134/*
135 * Allocate memory space for Vector
136 */
137Vector *Vector_Alloc(unsigned length) {
138
139 int i;
140 Vector *vector;
141
142 vector = (Vector *)malloc(sizeof(Vector));
143 if (!vector) {
144 errormsg1("Vector_Alloc", "outofmem", "out of memory space");
145 return 0;
146 }
147 vector->Size = length;
148 vector->p = (Value *)malloc(length * sizeof(Value));
149 if (!vector->p) {
150 errormsg1("Vector_Alloc", "outofmem", "out of memory space");
151 free(vector);
152 return 0;
153 }
154 for (i = 0; i < length; i++)
155 value_init(vector->p[i]);
156 return vector;
157} /* Vector_Alloc */
158
159/*
160 * Free the memory space occupied by Vector
161 */
162void Vector_Free(Vector *vector) {
163
164 int i;
165
166 if (!vector)
167 return;
168 for (i = 0; i < vector->Size; i++)
169 value_clear(vector->p[i]);
170 free(vector->p);
171 free(vector);
172} /* Vector_Free */
173
174/*
175 * Print the contents of a Vector
176 */
177void Vector_Print(FILE *Dst, const char *Format, Vector *vector) {
178 int i;
179 Value *p;
180 unsigned length;
181
182 fprintf(Dst, "%d\n", length = vector->Size);
183 p = vector->p;
184 for (i = 0; i < length; i++) {
185 if (Format) {
186 value_print(Dst, Format, *p++);
187 } else {
188 value_print(Dst, P_VALUE_FMT, *p++);
189 }
190 }
191 fprintf(Dst, "\n");
192} /* Vector_Print */
193
194/*
195 * Read the contents of a Vector
196 */
198
199 Vector *vector;
200 unsigned length;
201 int i;
202 char *s;
203 Value *p;
204
205 scanf("%d", &length);
206 vector = Vector_Alloc(length);
207 if (!vector) {
208 errormsg1("Vector_Read", "outofmem", "out of memory space");
209 return 0;
210 }
211 p = vector->p;
212 for (i = 0; i < length; i++) {
213 int r = scanf("%ms", &s);
214 if (r != 1) {
215 errormsg1("Vector_Read", "hi, Mathematica", "scanf at line 231 failed");
216 return 0;
217 }
218 value_read(*(p++), s);
219 free(s);
220 }
221 return vector;
222} /* Vector_Read */
223
224/*
225 * Assign 'n' to each component of Vector 'p'
226 */
227void Vector_Set(Value *p, int n, unsigned length) {
228
229 Value *cp;
230 int i;
231
232 cp = p;
233 for (i = 0; i < length; i++) {
234 value_set_si(*cp, n);
235 cp++;
236 }
237 return;
238} /* Vector_Set */
239
240/*
241 * Exchange the components of the vectors 'p1' and 'p2' of length 'length'
242 */
243void Vector_Exchange(Value *p1, Value *p2, unsigned length) {
244
245 int i;
246
247 for (i = 0; i < length; i++) {
248 value_swap(p1[i], p2[i]);
249 }
250 return;
251}
252
253/*
254 * Copy Vector 'p1' to Vector 'p2'
255 */
256void Vector_Copy(Value *p1, Value *p2, unsigned length) {
257
258 int i;
259 Value *cp1, *cp2;
260
261 cp1 = p1;
262 cp2 = p2;
263
264 for (i = 0; i < length; i++)
265 value_assign(*cp2++, *cp1++);
266
267 return;
268}
269
270/*
271 * Add two vectors 'p1' and 'p2' and store the result in 'p3'
272 */
273void Vector_Add(Value *p1, Value *p2, Value *p3, unsigned length) {
274
275 Value *cp1, *cp2, *cp3;
276 int i;
277
278 cp1 = p1;
279 cp2 = p2;
280 cp3 = p3;
281 for (i = 0; i < length; i++) {
282
283 /* *cp3++ = *cp1++ + *cp2++ */
284 value_addto(*cp3, *cp1, *cp2);
285 cp1++;
286 cp2++;
287 cp3++;
288 }
289} /* Vector_Add */
290
291/*
292 * Subtract two vectors 'p1' and 'p2' and store the result in 'p3'
293 */
294void Vector_Sub(Value *p1, Value *p2, Value *p3, unsigned length) {
295
296 Value *cp1, *cp2, *cp3;
297 int i;
298
299 cp1 = p1;
300 cp2 = p2;
301 cp3 = p3;
302 for (i = 0; i < length; i++) {
303
304 /* *cp3++= *cp1++ - *cp2++ */
305 value_subtract(*cp3, *cp1, *cp2);
306 cp1++;
307 cp2++;
308 cp3++;
309 }
310} /* Vector_Sub */
311
312/*
313 * Compute Bitwise OR of Vectors 'p1' and 'p2' and store in 'p3'
314 */
315void Vector_Or(Value *p1, Value *p2, Value *p3, unsigned length) {
316
317 Value *cp1, *cp2, *cp3;
318 int i;
319
320 cp1 = p1;
321 cp2 = p2;
322 cp3 = p3;
323 for (i = 0; i < length; i++) {
324
325 /* *cp3++=*cp1++ | *cp2++ */
326 value_orto(*cp3, *cp1, *cp2);
327 cp1++;
328 cp2++;
329 cp3++;
330 }
331} /* Vector_Or */
332
333/*
334 * Scale Vector 'p1' lambda times and store in 'p2'
335 */
336void Vector_Scale(Value *p1, Value *p2, Value lambda, unsigned length) {
337
338 Value *cp1, *cp2;
339 int i;
340
341 cp1 = p1;
342 cp2 = p2;
343 for (i = 0; i < length; i++) {
344
345 /* *cp2++=*cp1++ * lambda */
346 value_multiply(*cp2, *cp1, lambda);
347 cp1++;
348 cp2++;
349 }
350} /* Vector_Scale */
351
352/*
353 * Antiscale Vector 'p1' by lambda and store in 'p2'
354 * Assumes all elements of 'p1' are divisble by lambda.
355 */
356void Vector_AntiScale(Value *p1, Value *p2, Value lambda, unsigned length) {
357 int i;
358
359 for (i = 0; i < length; i++)
360 value_divexact(p2[i], p1[i], lambda);
361} /* Vector_AntiScale */
362
363/*
364 * Puts negative of 'p1' in 'p2'
365 */
366void Vector_Oppose(Value *p1, Value *p2, unsigned len) {
367 unsigned i;
368
369 for (i = 0; i < len; ++i)
370 value_oppose(p2[i], p1[i]);
371}
372
373/*
374 * Return the inner product of the two Vectors 'p1' and 'p2'
375 */
376void Inner_Product(Value *p1, Value *p2, unsigned length, Value *ip) {
377 int i;
378
379 if (length != 0)
380 value_multiply(*ip, p1[0], p2[0]);
381 else
382 value_set_si(*ip, 0);
383 for (i = 1; i < length; i++)
384 value_addmul(*ip, p1[i], p2[i]);
385} /* Inner_Product */
386
387/*
388 * Return the maximum of the components of 'p'
389 */
390void Vector_Max(Value *p, unsigned length, Value *max) {
391
392 Value *cp;
393 int i;
394
395 cp = p;
396 value_assign(*max, *cp);
397 cp++;
398 for (i = 1; i < length; i++) {
399 value_maximum(*max, *max, *cp);
400 cp++;
401 }
402} /* Vector_Max */
403
404/*
405 * Return the minimum of the components of Vector 'p'
406 */
407void Vector_Min(Value *p, unsigned length, Value *min) {
408
409 Value *cp;
410 int i;
411
412 cp = p;
413 value_assign(*min, *cp);
414 cp++;
415 for (i = 1; i < length; i++) {
416 value_minimum(*min, *min, *cp);
417 cp++;
418 }
419 return;
420} /* Vector_Min */
421
422/*
423 * Given Vectors 'p1' and 'p2', return Vector 'p3' = lambda * p1 + mu * p2.
424 */
425void Vector_Combine(Value *p1, Value *p2, Value *p3, Value lambda, Value mu,
426 unsigned length) {
427 Value tmp;
428 int i;
429
430 value_init(tmp);
431 for (i = 0; i < length; i++) {
432 value_multiply(tmp, lambda, p1[i]);
433 value_addmul(tmp, mu, p2[i]);
434 value_assign(p3[i], tmp);
435 }
436 value_clear(tmp);
437 return;
438} /* Vector_Combine */
439
440/*
441 * Return 1 if 'Vec1' equals 'Vec2', otherwise return 0
442 */
443int Vector_Equal(Value *Vec1, Value *Vec2, unsigned n) {
444 int i;
445
446 for (i = 0; i < n; ++i)
447 if (value_ne(Vec1[i], Vec2[i]))
448 return 0;
449
450 return 1;
451} /* Vector_Equal */
452
453/*
454 * Return the component of 'p' with minimum non-zero absolute value. 'index'
455 * points to the component index that has the minimum value. If no such value
456 * and index is found, Value 1 is returned.
457 */
458void Vector_Min_Not_Zero(Value *p, unsigned length, int *index, Value *min) {
459 Value aux;
460 int i;
461
462 i = First_Non_Zero(p, length);
463 if (i == -1) {
464 value_set_si(*min, 1);
465 return;
466 }
467 *index = i;
468 value_absolute(*min, p[i]);
469 value_init(aux);
470 for (i = i + 1; i < length; i++) {
471 if (value_zero_p(p[i]))
472 continue;
473 value_absolute(aux, p[i]);
474 if (value_lt(aux, *min)) {
475 value_assign(*min, aux);
476 *index = i;
477 }
478 }
479 value_clear(aux);
480} /* Vector_Min_Not_Zero */
481
482/*
483 * Return the GCD of components of Vector 'p'
484 */
485void Vector_Gcd(Value *p, unsigned length, Value *min) {
486
487 Value *q, *cq, *cp;
488 int i, Not_Zero, Index_Min = 0;
489
490 q = (Value *)malloc(length * sizeof(Value));
491
492 /* Initialize all the 'Value' variables */
493 for (i = 0; i < length; i++)
494 value_init(q[i]);
495
496 /* 'cp' points to vector 'p' and cq points to vector 'q' that holds the */
497 /* absolute value of elements of vector 'p'. */
498 cp = p;
499 for (cq = q, i = 0; i < length; i++) {
500 value_absolute(*cq, *cp);
501 cq++;
502 cp++;
503 }
504 do {
505 Vector_Min_Not_Zero(q, length, &Index_Min, min);
506
507 /* if (*min != 1) */
508 if (value_notone_p(*min)) {
509
510 cq = q;
511 Not_Zero = 0;
512 for (i = 0; i < length; i++, cq++)
513 if (i != Index_Min) {
514
515 /* Not_Zero |= (*cq %= *min) */
516 value_modulus(*cq, *cq, *min);
517 Not_Zero |= value_notzero_p(*cq);
518 }
519 } else
520 break;
521 } while (Not_Zero);
522
523 /* Clear all the 'Value' variables */
524 for (i = 0; i < length; i++)
525 value_clear(q[i]);
526 free(q);
527} /* Vector_Gcd */
528
529/*
530 * Given vectors 'p1', 'p2', and a pointer to a function returning 'Value type,
531 * compute p3[i] = f(p1[i],p2[i]).
532 */
533void Vector_Map(Value *p1, Value *p2, Value *p3, unsigned length,
534 Value *(*f)(Value, Value)) {
535 Value *cp1, *cp2, *cp3;
536 int i;
537
538 cp1 = p1;
539 cp2 = p2;
540 cp3 = p3;
541 for (i = 0; i < length; i++) {
542 value_assign(*cp3, *(*f)(*cp1, *cp2));
543 cp1++;
544 cp2++;
545 cp3++;
546 }
547 return;
548} /* Vector_Map */
549
550/*
551 * Reduce a vector by dividing it by GCD. There is no restriction on
552 * components of Vector 'p'. Making the last element positive is *not* OK
553 * for equalities.
554 */
555void Vector_Normalize(Value *p, unsigned length) {
556
557 Value gcd;
558 int i;
559
560 value_init(gcd);
561
562 Vector_Gcd(p, length, &gcd);
563
564 if (value_notone_p(gcd))
565 Vector_AntiScale(p, p, gcd, length);
566
567 value_clear(gcd);
568} /* Vector_Normalize */
569
570/*
571 * Reduce a vector by dividing it by GCD and making sure its pos-th
572 * element is positive.
573 */
574void Vector_Normalize_Positive(Value *p, int length, int pos) {
575
576 Value gcd;
577 int i;
578
579 value_init(gcd);
580 Vector_Gcd(p, length, &gcd);
581 if (value_neg_p(p[pos]))
582 value_oppose(gcd, gcd);
583 if (value_notone_p(gcd))
584 Vector_AntiScale(p, p, gcd, length);
585 value_clear(gcd);
586} /* Vector_Normalize_Positive */
587
588/*
589 * Reduce 'p' by operating binary function on its components successively
590 */
591void Vector_Reduce(Value *p, unsigned length, void (*f)(Value, Value *),
592 Value *r) {
593
594 Value *cp;
595 int i;
596
597 cp = p;
598 value_assign(*r, *cp);
599 for (i = 1; i < length; i++) {
600 cp++;
601 (*f)(*cp, r);
602 }
603} /* Vector_Reduce */
604
605/*
606 * Sort the components of a Vector 'vector' using Heap Sort.
607 */
608void Vector_Sort(Value *vector, unsigned n) {
609
610 int i, j;
611 Value temp;
612 Value *current_node = (Value *)0;
613 Value *left_son, *right_son;
614
615 value_init(temp);
616
617 for (i = (n - 1) / 2; i >= 0; i--) {
618
619 /* Phase 1 : build the heap */
620 j = i;
621 value_assign(temp, *(vector + i));
622
623 /* While not a leaf */
624 while (j <= (n - 1) / 2) {
625 current_node = vector + j;
626 left_son = vector + (j << 1) + 1;
627
628 /* If only one son */
629 if ((j << 1) + 2 >= n) {
630 if (value_lt(temp, *left_son)) {
631 value_assign(*current_node, *left_son);
632 j = (j << 1) + 1;
633 } else
634 break;
635 } else {
636
637 /* If two sons */
638 right_son = left_son + 1;
639 if (value_lt(*right_son, *left_son)) {
640 if (value_lt(temp, *left_son)) {
641 value_assign(*current_node, *left_son);
642 j = (j << 1) + 1;
643 } else
644 break;
645 } else {
646 if (value_lt(temp, *right_son)) {
647 value_assign(*current_node, *right_son);
648 j = (j << 1) + 2;
649 } else
650 break;
651 }
652 }
653 }
654 value_assign(*current_node, temp);
655 }
656 for (i = n - 1; i > 0; i--) {
657
658 /* Phase 2 : sort the heap */
659 value_assign(temp, *(vector + i));
660 value_assign(*(vector + i), *vector);
661 j = 0;
662
663 /* While not a leaf */
664 while (j < i / 2) {
665 current_node = vector + j;
666 left_son = vector + (j << 1) + 1;
667
668 /* If only one son */
669 if ((j << 1) + 2 >= i) {
670 if (value_lt(temp, *left_son)) {
671 value_assign(*current_node, *left_son);
672 j = (j << 1) + 1;
673 } else
674 break;
675 } else {
676
677 /* If two sons */
678 right_son = left_son + 1;
679 if (value_lt(*right_son, *left_son)) {
680 if (value_lt(temp, *left_son)) {
681 value_assign(*current_node, *left_son);
682 j = (j << 1) + 1;
683 } else
684 break;
685 } else {
686 if (value_lt(temp, *right_son)) {
687 value_assign(*current_node, *right_son);
688 j = (j << 1) + 2;
689 } else
690 break;
691 }
692 }
693 }
694 value_assign(*current_node, temp);
695 }
696 value_clear(temp);
697 return;
698} /* Vector_Sort */
699
700/*
701 * Replaces constraint a x >= c by x >= ceil(c/a)
702 * where "a" is a common factor in the coefficients
703 * old is the constraint; v points to an initialized
704 * value that this procedure can use.
705 * Return non-zero if something changed.
706 * Result is placed in newp.
707 */
708int ConstraintSimplify(Value *old, Value *newp, int len, Value *v) {
709 /* first remove common factor of all coefficients (including "c") */
710 Vector_Gcd(old + 1, len - 1, v);
711 if (value_notone_p(*v))
712 Vector_AntiScale(old + 1, newp + 1, *v, len - 1);
713
714 Vector_Gcd(old + 1, len - 2, v);
715
716 if (value_one_p(*v))
717 return 0;
718
719 Vector_AntiScale(old + 1, newp + 1, *v, len - 2);
720 value_pdivision(newp[len - 1], old[len - 1], *v);
721 return 1;
722}
723
724int Vector_IsZero(Value *v, unsigned length) {
725 unsigned i;
726 if (value_notzero_p(v[0]))
727 return 0;
728 else {
729 value_set_si(v[0], 1);
730 for (i = length - 1; value_zero_p(v[i]); i--)
731 ;
732 value_set_si(v[0], 0);
733 return (i == 0);
734 }
735}
736
737// ***************************************************************************
738// VALUES CACHE HANDLING FUNCTIONS BELOW
739typedef struct {
740 Value *p;
741 int size;
743
744// those number of arrays of Values memory allocations are kept in the cache
745// and reused when possible.
746#define MAX_CACHE_SIZE 20
747
748/************************************************/
749/** Vincent's patch for thread safe value cache */
750/** each thread has it's own cache and size. */
751/** 02/2012 */
752/************************************************/
753
754#ifdef THREAD_SAFE_POLYLIB
755#include <assert.h>
756#include <pthread.h>
757
758static pthread_once_t once_cache = PTHREAD_ONCE_INIT;
759static pthread_key_t cache_key;
760/* cache_size is stored in the last+1 cache position */
761#define cache_size (cache[MAX_CACHE_SIZE].size)
762
763static cache_holder *allocate_local_cache(void) {
765 cache = malloc(sizeof(cache_holder) * (MAX_CACHE_SIZE + 1));
766 assert(cache != NULL);
767 cache_size = 0;
768 assert(pthread_setspecific(cache_key, cache) == 0);
769 return (cache);
770}
771static void free_local_cache(void *c) { free(c); }
772static void init_value_caches(void) {
773 pthread_key_create(&cache_key, free_local_cache);
774}
775
776#else
778static int cache_size = 0;
779#endif // THREAD_SAFE_POLYLIB
780
781Value *value_alloc(int want, int *got) {
782 int i;
783 Value *p;
784
785#ifdef THREAD_SAFE_POLYLIB
786 assert(pthread_once(&once_cache, init_value_caches) == 0);
788 if (MAX_CACHE_SIZE > 0 && (cache = pthread_getspecific(cache_key)) == NULL)
789 cache = allocate_local_cache();
790#endif // THREAD_SAFE_POLYLIB
791
792 if (MAX_CACHE_SIZE > 0 && cache_size) {
793 int best = 0;
794 for (i = 0; i < cache_size; ++i) {
795 if (cache[i].size >= want) {
796 Value *p = cache[i].p;
797 *got = cache[i].size;
798 if (--cache_size != i)
799 cache[i] = cache[cache_size];
800 Vector_Set(p, 0, want);
801 return p;
802 }
803 if (cache[i].size > cache[best].size)
804 best = i;
805 }
806
807 p = (Value *)realloc(cache[best].p, want * sizeof(Value));
808 *got = cache[best].size;
809 if (--cache_size != best)
810 cache[best] = cache[cache_size];
811 Vector_Set(p, 0, *got);
812 } else {
813 p = (Value *)malloc(want * sizeof(Value));
814 *got = 0;
815 }
816
817 if (!p)
818 return p;
819
820 for (i = *got; i < want; ++i)
821 value_init(p[i]);
822 *got = want;
823
824 return p;
825}
826
827void value_free(Value *p, int size) {
828 int i;
829
830#ifdef THREAD_SAFE_POLYLIB
831 /* suppose alloc before free :) */
832 // assert(pthread_once(&once_cache, init_value_caches) == 0);
834 // if( (cache = pthread_getspecific( cache_key )) == NULL )
835 // cache = allocate_local_cache();
836 assert(MAX_CACHE_SIZE == 0 ||
837 (cache = pthread_getspecific(cache_key)) != NULL);
838#endif // THREAD_SAFE_POLYLIB
839
841 cache[cache_size].p = p;
842 cache[cache_size].size = size;
843 ++cache_size;
844 return;
845 }
846
847 for (i = 0; i < size; i++)
848 value_clear(p[i]);
849 free(p);
850}
851
852// Free all memory allocated in the Values cache
854 int c, i;
855 if (MAX_CACHE_SIZE == 0)
856 return;
857#ifdef THREAD_SAFE_POLYLIB
858 assert(pthread_once(&once_cache, init_value_caches) == 0);
860 if ((cache = pthread_getspecific(cache_key)) == NULL)
861 return;
862 pthread_key_delete(cache_key);
863#endif // THREAD_SAFE_POLYLIB
864
865 for (c = 0; c < cache_size; c++) {
866 for (i = 0; i < cache[c].size; i++)
867 value_clear(cache[c].p[i]);
868 free(cache[c].p);
869 }
870 // just in case someone calls polylib again afterwards
871 cache_size = 0;
872
873#ifdef THREAD_SAFE_POLYLIB
874 // remove the key and free the cache holder array
875 pthread_key_delete(cache_key);
876 free(cache);
877#endif // THREAD_SAFE_POLYLIB
878}
#define value_oppose(ref, val)
Definition: arithmetique.h:552
#define value_maximum(ref, val1, val2)
Definition: arithmetique.h:555
#define value_pdivision(ref, val1, val2)
Definition: arithmetique.h:550
#define value_orto(ref, val1, val2)
Definition: arithmetique.h:558
#define value_swap(v1, v2)
Definition: arithmetique.h:488
#define value_notzero_p(val)
Definition: arithmetique.h:576
#define value_divexact(ref, val1, val2)
Definition: arithmetique.h:548
#define value_notone_p(val)
Definition: arithmetique.h:578
#define value_one_p(val)
Definition: arithmetique.h:577
#define value_absolute(ref, val)
Definition: arithmetique.h:553
#define value_ne(v1, v2)
Definition: arithmetique.h:503
#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_minimum(ref, val1, val2)
Definition: arithmetique.h:554
#define value_read(val, str)
Definition: arithmetique.h:486
#define value_clear(val)
Definition: arithmetique.h:485
#define value_division(ref, val1, val2)
Definition: arithmetique.h:547
#define value_multiply(ref, val1, val2)
Definition: arithmetique.h:543
#define value_print(Dst, fmt, val)
Definition: arithmetique.h:487
#define value_lt(v1, v2)
Definition: arithmetique.h:506
#define value_modulus(ref, val1, val2)
Definition: arithmetique.h:549
#define value_subtract(ref, val1, val2)
Definition: arithmetique.h:544
#define value_addto(ref, val1, val2)
Definition: arithmetique.h:537
#define value_neg_p(val)
Definition: arithmetique.h:572
#define value_init(val)
Definition: arithmetique.h:481
#define assert(ex)
Definition: assert.h:16
void errormsg1(const char *f, const char *msgname, const char *msg)
Definition: errormsg.c:25
static int n
Definition: polyparam.c:276
char s[128]
Definition: polytest.c:8
Definition: types.h:70
unsigned Size
Definition: types.h:71
Value * p
Definition: types.h:72
int size
Definition: vector.c:741
Value * p
Definition: vector.c:740
#define P_VALUE_FMT
Definition: types.h:39
Value * value_alloc(int want, int *got)
Definition: vector.c:781
void Vector_Free(Vector *vector)
Definition: vector.c:162
void Vector_Scale(Value *p1, Value *p2, Value lambda, unsigned length)
Definition: vector.c:336
void Vector_Print(FILE *Dst, const char *Format, Vector *vector)
Definition: vector.c:177
void Vector_Set(Value *p, int n, unsigned length)
Definition: vector.c:227
void Inner_Product(Value *p1, Value *p2, unsigned length, Value *ip)
Definition: vector.c:376
int Vector_Equal(Value *Vec1, Value *Vec2, unsigned n)
Definition: vector.c:443
void value_free(Value *p, int size)
Definition: vector.c:827
void Vector_Normalize_Positive(Value *p, int length, int pos)
Definition: vector.c:574
void Gcd(Value a, Value b, Value *result)
Definition: vector.c:99
void Vector_Combine(Value *p1, Value *p2, Value *p3, Value lambda, Value mu, unsigned length)
Definition: vector.c:425
cache_holder cache[MAX_CACHE_SIZE]
Vincent's patch for thread safe value cache.
Definition: vector.c:777
int Vector_IsZero(Value *v, unsigned length)
Definition: vector.c:724
void Vector_Max(Value *p, unsigned length, Value *max)
Definition: vector.c:390
Vector * Vector_Read()
Definition: vector.c:197
void Factorial(int n, Value *fact)
Definition: vector.c:25
#define MAX_CACHE_SIZE
Definition: vector.c:746
void Vector_Gcd(Value *p, unsigned length, Value *min)
Definition: vector.c:485
void Vector_Exchange(Value *p1, Value *p2, unsigned length)
Definition: vector.c:243
void Vector_AntiScale(Value *p1, Value *p2, Value lambda, unsigned length)
Definition: vector.c:356
void Vector_Add(Value *p1, Value *p2, Value *p3, unsigned length)
Definition: vector.c:273
void Vector_Sub(Value *p1, Value *p2, Value *p3, unsigned length)
Definition: vector.c:294
void Vector_Reduce(Value *p, unsigned length, void(*f)(Value, Value *), Value *r)
Definition: vector.c:591
void Vector_Normalize(Value *p, unsigned length)
Definition: vector.c:555
void Vector_Min_Not_Zero(Value *p, unsigned length, int *index, Value *min)
Definition: vector.c:458
void Vector_Sort(Value *vector, unsigned n)
Definition: vector.c:608
Vector * Vector_Alloc(unsigned length)
Definition: vector.c:137
void Vector_Copy(Value *p1, Value *p2, unsigned length)
Definition: vector.c:256
int First_Non_Zero(Value *p, unsigned length)
Definition: vector.c:120
void free_value_cache()
Definition: vector.c:853
void Vector_Map(Value *p1, Value *p2, Value *p3, unsigned length, Value *(*f)(Value, Value))
Definition: vector.c:533
static int cache_size
Definition: vector.c:778
void CNP(int a, int b, Value *result)
Definition: vector.c:72
void Vector_Oppose(Value *p1, Value *p2, unsigned len)
Definition: vector.c:366
int ConstraintSimplify(Value *old, Value *newp, int len, Value *v)
Definition: vector.c:708
void Binomial(int n, int p, Value *result)
Definition: vector.c:43
void Vector_Min(Value *p, unsigned length, Value *min)
Definition: vector.c:407
void Vector_Or(Value *p1, Value *p2, Value *p3, unsigned length)
Definition: vector.c:315
Value min
Definition: verif_ehrhart.c:43
Value max
Definition: verif_ehrhart.c:43