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