2 This file is part of PolyLib.
4 PolyLib is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 PolyLib is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with PolyLib. If not, see <http://www.gnu.org/licenses/>.
20 Both this software and its documentation are
22 Copyrighted 1993 by IRISA /Universite de Rennes I - France,
23 Copyright 1995,1996 by BYU, Provo, Utah
30 #include <polylib/polylib.h>
33 /* defined by configure script */
34 /* #define THREAD_SAFE_POLYLIB */
43 void Factorial(int n
, Value
*fact
) {
50 value_set_si(*fact
,1);
53 value_multiply(*fact
,*fact
,tmp
);
59 * Compute n!/(p!(n-p)!)
61 void Binomial(int n
, int p
, Value
*result
) {
67 value_init(tmp
);value_init(f
);
72 value_set_si(*result
,(n
-p
+1));
73 for (i
=n
-p
+2;i
<=n
;i
++) {
75 value_multiply(*result
,*result
,tmp
);
78 value_division(*result
,*result
,f
);
81 value_set_si(*result
,1);
82 value_clear(f
);value_clear(tmp
);
86 * Return the number of ways to choose 'b' items from 'a' items, that is,
87 * return a!/(b!(a-b)!)
89 void CNP(int a
,int b
, Value
*result
) {
95 value_set_si(*result
,1);
97 /* If number of items is less than the number to be choosen, return 1 */
104 value_multiply(*result
,*result
,tmp
);
106 for(i
=1;i
<=(a
-b
);++i
) {
108 value_division(*result
,*result
,tmp
);
114 * Compute GCD of 'a' and 'b'
116 void Gcd(Value a
,Value b
,Value
*result
) {
122 value_assign(acopy
,a
);
123 value_assign(bcopy
,b
);
124 while(value_notzero_p(acopy
)) {
125 value_modulus(*result
,bcopy
,acopy
);
126 value_assign(bcopy
,acopy
);
127 value_assign(acopy
,*result
);
129 value_absolute(*result
,bcopy
);
135 * Return the smallest component index in 'p' whose value is non-zero
137 int First_Non_Zero(Value
*p
,unsigned length
) {
143 for (i
=0;i
<length
;i
++) {
144 if (value_notzero_p(*cp
))
148 return((i
==length
) ? -1 : i
);
149 } /* First_Non_Zero */
152 * Allocate memory space for Vector
154 Vector
*Vector_Alloc(unsigned length
) {
159 vector
= (Vector
*)malloc(sizeof(Vector
));
161 errormsg1("Vector_Alloc", "outofmem", "out of memory space");
165 vector
->p
=(Value
*)malloc(length
* sizeof(Value
));
167 errormsg1("Vector_Alloc", "outofmem", "out of memory space");
171 for(i
=0;i
<length
;i
++)
172 value_init(vector
->p
[i
]);
177 * Free the memory space occupied by Vector
179 void Vector_Free(Vector
*vector
) {
184 for(i
=0;i
<vector
->Size
;i
++)
185 value_clear(vector
->p
[i
]);
191 * Print the contents of a Vector
193 void Vector_Print(FILE *Dst
, const char *Format
, Vector
*vector
)
199 fprintf(Dst
, "%d\n", length
=vector
->Size
);
201 for (i
=0;i
<length
;i
++) {
203 value_print(Dst
,Format
,*p
++);
206 value_print(Dst
,P_VALUE_FMT
,*p
++);
213 * Read the contents of a Vector
215 Vector
*Vector_Read() {
223 scanf("%d", &length
);
224 vector
= Vector_Alloc(length
);
226 errormsg1("Vector_Read", "outofmem", "out of memory space");
230 for (i
=0;i
<length
;i
++)
232 int r
=scanf("%ms",&s
);
235 errormsg1("Vector_Read", "hi, Mathematica", "scanf at line 231 failed");
238 value_read(*(p
++),s
);
245 * Assign 'n' to each component of Vector 'p'
247 void Vector_Set(Value
*p
,int n
,unsigned length
) {
253 for (i
=0;i
<length
;i
++) {
261 * Exchange the components of the vectors 'p1' and 'p2' of length 'length'
263 void Vector_Exchange(Value
*p1
, Value
*p2
, unsigned length
) {
267 for(i
=0;i
<length
;i
++) {
268 value_swap(p1
[i
],p2
[i
]);
274 * Copy Vector 'p1' to Vector 'p2'
276 void Vector_Copy(Value
*p1
,Value
*p2
,unsigned length
) {
284 for(i
=0;i
<length
;i
++)
285 value_assign(*cp2
++,*cp1
++);
291 * Add two vectors 'p1' and 'p2' and store the result in 'p3'
293 void Vector_Add(Value
*p1
,Value
*p2
,Value
*p3
,unsigned length
) {
295 Value
*cp1
, *cp2
, *cp3
;
301 for (i
=0;i
<length
;i
++) {
303 /* *cp3++ = *cp1++ + *cp2++ */
304 value_addto(*cp3
,*cp1
,*cp2
);
310 * Subtract two vectors 'p1' and 'p2' and store the result in 'p3'
312 void Vector_Sub(Value
*p1
,Value
*p2
,Value
*p3
,unsigned length
) {
314 Value
*cp1
, *cp2
, *cp3
;
320 for (i
=0;i
<length
;i
++) {
322 /* *cp3++= *cp1++ - *cp2++ */
323 value_subtract(*cp3
,*cp1
,*cp2
);
329 * Compute Bitwise OR of Vectors 'p1' and 'p2' and store in 'p3'
331 void Vector_Or(Value
*p1
,Value
*p2
,Value
*p3
,unsigned length
) {
333 Value
*cp1
, *cp2
, *cp3
;
339 for (i
=0;i
<length
;i
++) {
341 /* *cp3++=*cp1++ | *cp2++ */
342 value_orto(*cp3
,*cp1
,*cp2
);
348 * Scale Vector 'p1' lambda times and store in 'p2'
350 void Vector_Scale(Value
*p1
,Value
*p2
,Value lambda
,unsigned length
) {
357 for (i
=0;i
<length
;i
++) {
359 /* *cp2++=*cp1++ * lambda */
360 value_multiply(*cp2
,*cp1
,lambda
);
366 * Antiscale Vector 'p1' by lambda and store in 'p2'
367 * Assumes all elements of 'p1' are divisble by lambda.
369 void Vector_AntiScale(Value
*p1
, Value
*p2
, Value lambda
, unsigned length
)
373 for (i
= 0; i
< length
; i
++)
374 value_divexact(p2
[i
], p1
[i
], lambda
);
375 } /* Vector_AntiScale */
378 * Puts negative of 'p1' in 'p2'
380 void Vector_Oppose(Value
*p1
, Value
*p2
, unsigned len
)
384 for (i
= 0; i
< len
; ++i
)
385 value_oppose(p2
[i
], p1
[i
]);
389 * Return the inner product of the two Vectors 'p1' and 'p2'
391 void Inner_Product(Value
*p1
, Value
*p2
, unsigned length
, Value
*ip
)
396 value_multiply(*ip
, p1
[0], p2
[0]);
398 value_set_si(*ip
, 0);
399 for(i
= 1; i
< length
; i
++)
400 value_addmul(*ip
, p1
[i
], p2
[i
]);
401 } /* Inner_Product */
404 * Return the maximum of the components of 'p'
406 void Vector_Max(Value
*p
,unsigned length
, Value
*max
) {
412 value_assign(*max
,*cp
);
414 for (i
=1;i
<length
;i
++) {
415 value_maximum(*max
,*max
,*cp
);
421 * Return the minimum of the components of Vector 'p'
423 void Vector_Min(Value
*p
,unsigned length
,Value
*min
) {
429 value_assign(*min
,*cp
);
431 for (i
=1;i
<length
;i
++) {
432 value_minimum(*min
,*min
,*cp
);
439 * Given Vectors 'p1' and 'p2', return Vector 'p3' = lambda * p1 + mu * p2.
441 void Vector_Combine(Value
*p1
, Value
*p2
, Value
*p3
, Value lambda
, Value mu
,
448 for (i
= 0; i
< length
; i
++) {
449 value_multiply(tmp
, lambda
, p1
[i
]);
450 value_addmul(tmp
, mu
, p2
[i
]);
451 value_assign(p3
[i
], tmp
);
455 } /* Vector_Combine */
458 * Return 1 if 'Vec1' equals 'Vec2', otherwise return 0
460 int Vector_Equal(Value
*Vec1
, Value
*Vec2
, unsigned n
)
464 for (i
= 0; i
< n
; ++i
)
465 if (value_ne(Vec1
[i
], Vec2
[i
]))
472 * Return the component of 'p' with minimum non-zero absolute value. 'index'
473 * points to the component index that has the minimum value. If no such value
474 * and index is found, Value 1 is returned.
476 void Vector_Min_Not_Zero(Value
*p
,unsigned length
,int *index
,Value
*min
)
482 i
= First_Non_Zero(p
, length
);
484 value_set_si(*min
,1);
488 value_absolute(*min
, p
[i
]);
490 for (i
= i
+1; i
< length
; i
++) {
491 if (value_zero_p(p
[i
]))
493 value_absolute(aux
, p
[i
]);
494 if (value_lt(aux
,*min
)) {
495 value_assign(*min
,aux
);
500 } /* Vector_Min_Not_Zero */
503 * Return the GCD of components of Vector 'p'
505 void Vector_Gcd(Value
*p
,unsigned length
,Value
*min
) {
508 int i
, Not_Zero
, Index_Min
=0;
510 q
= (Value
*)malloc(length
*sizeof(Value
));
512 /* Initialize all the 'Value' variables */
513 for(i
=0;i
<length
;i
++)
516 /* 'cp' points to vector 'p' and cq points to vector 'q' that holds the */
517 /* absolute value of elements of vector 'p'. */
519 for (cq
= q
,i
=0;i
<length
;i
++) {
520 value_absolute(*cq
,*cp
);
525 Vector_Min_Not_Zero(q
,length
,&Index_Min
,min
);
528 if (value_notone_p(*min
)) {
532 for (i
=0;i
<length
;i
++,cq
++)
535 /* Not_Zero |= (*cq %= *min) */
536 value_modulus(*cq
,*cq
,*min
);
537 Not_Zero
|= value_notzero_p(*cq
);
544 /* Clear all the 'Value' variables */
545 for(i
=0;i
<length
;i
++)
551 * Given vectors 'p1', 'p2', and a pointer to a function returning 'Value type,
552 * compute p3[i] = f(p1[i],p2[i]).
554 void Vector_Map(Value
*p1
,Value
*p2
,Value
*p3
,unsigned length
,
555 Value
*(*f
)(Value
,Value
))
557 Value
*cp1
, *cp2
, *cp3
;
563 for(i
=0;i
<length
;i
++) {
564 value_assign(*cp3
,*(*f
)(*cp1
, *cp2
));
571 * Reduce a vector by dividing it by GCD. There is no restriction on
572 * components of Vector 'p'. Making the last element positive is *not* OK
575 void Vector_Normalize(Value
*p
,unsigned length
) {
582 Vector_Gcd(p
,length
,&gcd
);
584 if (value_notone_p(gcd
))
585 Vector_AntiScale(p
, p
, gcd
, length
);
588 } /* Vector_Normalize */
591 * Reduce a vector by dividing it by GCD and making sure its pos-th
592 * element is positive.
594 void Vector_Normalize_Positive(Value
*p
,int length
,int pos
) {
600 Vector_Gcd(p
,length
,&gcd
);
601 if (value_neg_p(p
[pos
]))
602 value_oppose(gcd
,gcd
);
603 if(value_notone_p(gcd
))
604 Vector_AntiScale(p
, p
, gcd
, length
);
606 } /* Vector_Normalize_Positive */
609 * Reduce 'p' by operating binary function on its components successively
611 void Vector_Reduce(Value
*p
,unsigned length
,void(*f
)(Value
,Value
*),Value
*r
) {
617 value_assign(*r
,*cp
);
618 for(i
=1;i
<length
;i
++) {
622 } /* Vector_Reduce */
625 * Sort the components of a Vector 'vector' using Heap Sort.
627 void Vector_Sort(Value
*vector
,unsigned n
) {
631 Value
*current_node
=(Value
*)0;
632 Value
*left_son
,*right_son
;
636 for (i
=(n
-1)/2;i
>=0;i
--) {
638 /* Phase 1 : build the heap */
640 value_assign(temp
,*(vector
+i
));
642 /* While not a leaf */
644 current_node
= vector
+j
;
645 left_son
= vector
+(j
<<1)+1;
647 /* If only one son */
649 if (value_lt(temp
,*left_son
)) {
650 value_assign(*current_node
,*left_son
);
659 right_son
=left_son
+1;
660 if (value_lt(*right_son
,*left_son
)) {
661 if (value_lt(temp
,*left_son
)) {
662 value_assign(*current_node
,*left_son
);
669 if (value_lt(temp
,*right_son
)) {
670 value_assign(*current_node
,*right_son
);
678 value_assign(*current_node
,temp
);
682 /* Phase 2 : sort the heap */
683 value_assign(temp
, *(vector
+i
));
684 value_assign(*(vector
+i
),*vector
);
687 /* While not a leaf */
689 current_node
=vector
+j
;
690 left_son
=vector
+(j
<<1)+1;
692 /* If only one son */
694 if (value_lt(temp
,*left_son
)) {
695 value_assign(*current_node
,*left_son
);
704 right_son
=left_son
+1;
705 if (value_lt(*right_son
,*left_son
)) {
706 if (value_lt(temp
,*left_son
)) {
707 value_assign(*current_node
,*left_son
);
714 if (value_lt(temp
,*right_son
)) {
715 value_assign(*current_node
,*right_son
);
723 value_assign(*current_node
,temp
);
730 * Replaces constraint a x >= c by x >= ceil(c/a)
731 * where "a" is a common factor in the coefficients
732 * old is the constraint; v points to an initialized
733 * value that this procedure can use.
734 * Return non-zero if something changed.
735 * Result is placed in newp.
737 int ConstraintSimplify(Value
*old
, Value
*newp
, int len
, Value
* v
)
739 /* first remove common factor of all coefficients (including "c") */
740 Vector_Gcd(old
+1, len
- 1, v
);
741 if (value_notone_p(*v
))
742 Vector_AntiScale(old
+1, newp
+1, *v
, len
-1);
744 Vector_Gcd(old
+1, len
- 2, v
);
749 Vector_AntiScale(old
+1, newp
+1, *v
, len
-2);
750 value_pdivision(newp
[len
-1], old
[len
-1], *v
);
754 int Vector_IsZero(Value
* v
, unsigned length
) {
756 if (value_notzero_p(v
[0])) return 0;
758 value_set_si(v
[0], 1);
759 for (i
=length
-1; value_zero_p(v
[i
]); i
--);
760 value_set_si(v
[0], 0);
769 #define MAX_CACHE_SIZE 20
772 /************************************************/
773 /** Vincent's patch for thread safe value cache */
774 /** each thread has it's own cache and size. */
776 /************************************************/
778 #ifdef THREAD_SAFE_POLYLIB
783 static pthread_once_t once_cache
= PTHREAD_ONCE_INIT
;
784 static pthread_key_t cache_key
;
785 /* cache_size is stored in the last+1 cache position */
786 #define cache_size (cache[MAX_CACHE_SIZE].size)
788 static cache_holder
*allocate_local_cache(void)
791 cache
= malloc( sizeof(cache_holder
)*(MAX_CACHE_SIZE
+1) );
792 assert( cache
!=NULL
);
794 assert( pthread_setspecific( cache_key
, cache
) == 0 );
797 static void free_local_cache(void *c
)
800 assert( pthread_setspecific(cache_key
, NULL
) == 0 );
802 static void init_value_caches(void)
804 pthread_key_create(&cache_key
, free_local_cache
);
808 cache_holder cache
[MAX_CACHE_SIZE
];
809 static int cache_size
= 0;
810 #endif // THREAD_SAFE_POLYLIB
813 Value
* value_alloc(int want
, int *got
)
818 #ifdef THREAD_SAFE_POLYLIB
819 assert(pthread_once(&once_cache
, init_value_caches
) == 0);
821 if( (cache
= pthread_getspecific( cache_key
)) == NULL
)
822 cache
= allocate_local_cache();
823 #endif // THREAD_SAFE_POLYLIB
827 for (i
= 0; i
< cache_size
; ++i
) {
828 if (cache
[i
].size
>= want
) {
829 Value
*p
= cache
[i
].p
;
830 *got
= cache
[i
].size
;
831 if (--cache_size
!= i
)
832 cache
[i
] = cache
[cache_size
];
833 Vector_Set(p
, 0, want
);
836 if (cache
[i
].size
> cache
[best
].size
)
840 p
= (Value
*)realloc(cache
[best
].p
, want
* sizeof(Value
));
841 *got
= cache
[best
].size
;
842 if (--cache_size
!= best
)
843 cache
[best
] = cache
[cache_size
];
844 Vector_Set(p
, 0, *got
);
847 p
= (Value
*)malloc(want
* sizeof(Value
));
854 for (i
= *got
; i
< want
; ++i
)
861 void value_free(Value
*p
, int size
)
865 #ifdef THREAD_SAFE_POLYLIB
866 /* suppose alloc before free :) */
867 // assert(pthread_once(&once_cache, init_value_caches) == 0);
869 // if( (cache = pthread_getspecific( cache_key )) == NULL )
870 // cache = allocate_local_cache();
871 assert( (cache
= pthread_getspecific( cache_key
)) != NULL
);
872 #endif // THREAD_SAFE_POLYLIB
874 if (cache_size
< MAX_CACHE_SIZE
) {
875 cache
[cache_size
].p
= p
;
876 cache
[cache_size
].size
= size
;
881 for (i
=0; i
< size
; i
++)