-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlaurent_polys.py
119 lines (97 loc) · 3.47 KB
/
laurent_polys.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/bin/sh
''''exec python -- "$0" ${1+"$@"} # '''
from sage.all import *
def unique(seq):
# not order preserving
set = {}
map(set.__setitem__, seq, [])
return set.keys()
class ParamPoly(object):
def __init__(self, R, p, n):
self.old_R = R
self.old_polynomial = p
self.P = PolynomialRing(QQ, R.gens()[:n])
self.V = PolynomialRing(self.P, R.gens()[n:])
self.parameters = self.P.gens()
self.variables = self.V.gens()
self.polynomial = self.poly2parampoly(R,self.P,self.V,p)
def poly2parampoly(self, R,P,V, polynomial):
variables = R.gens()
new_variables = P.gens() + V.gens()
coeffs = polynomial.coefficients()
monoms = polynomial.monomials()
poly = 0
for i in range(len(coeffs)):
term = coeffs[i]
for j in range(len(variables)):
term *= new_variables[j]**(monoms[i].degree(monoms[i].parent()(variables[j])))
poly += term
return poly
def __mul__(self, other):
return ParamPoly(self.old_R, self.old_polynomial * other.old_polynomial, len(self.parameters))
def coeffs_monoms(self):
old_coeffs = self.old_polynomial.coefficients()
old_monoms = self.old_polynomial.monomials()
output = []
for i in range(len(old_monoms)):
new_coeff = old_coeffs[i]
new_monom = 1
for p in self.old_R.gens()[:(len(self.parameters))]:
new_coeff *= p**(old_monoms[i].degree(old_monoms[i].parent()(p)))
for v in self.old_R.gens()[(len(self.parameters)):]:
new_monom *= v**(old_monoms[i].degree(old_monoms[i].parent()(v)))
output.append((new_coeff, new_monom))
output_monoms = [m for (c,m) in output]
new_output = []
for m in sorted(unique(output_monoms)):
new_coeff = 0
for (C,M) in output:
if (m == M): new_coeff += C
new_output.append((new_coeff, m))
return new_output
def factorize(self):
factors = self.old_polynomial.factor()
new_factors = []
for i in range(len(factors)):
new_factors += [factors[i][0] for j in range(factors[i][1])]
return [ParamPoly(self.old_R, f, len(self.parameters)) for f in new_factors]
def __str__(self):
return str(self.polynomial)
def reduce_gcd(first, second):
factors_first = first.factorize()
factors_second = second.factorize()
output1 = factors_first[0]
for f in factors_first[1:]:
if f not in factors_second: output1 *= f
output2 = factors_second[0]
for f in factors_second[1:]:
if f not in factors_first: output2 *= f
return output1, output2
def product(list_polys):
p = list_polys[0]
for p2 in list_polys[1:]:
p *= p2
return p
def constraintsForLaurent(R, n, num, den):
Num = ParamPoly(R, num, n)
Den = ParamPoly(R, den, n)
num_factors = Num.factorize()
den_factors = Den.factorize()
disjunct_cases = [[]]
for gi in den_factors:
new_disjunct_cases = []
for dcase in disjunct_cases:
if gi.old_polynomial in [p.old_polynomial for p in num_factors]:
list = []
for p in num_factors:
if p.old_polynomial != gi.old_polynomial:
list.append(p.old_polynomial)
new_disjunct_cases.append(dcase + [product(list)])
continue
else:
new_disjunct_cases.append(dcase + [Num.old_polynomial % gi.old_polynomial] )
if len(gi.coeffs_monoms()) > 1:
for coeff in gi.coeffs_monoms():
new_disjunct_cases.append(dcase + [gi.old_polynomial - (coeff[0]*coeff[1])] )
disjunct_cases = new_disjunct_cases
return disjunct_cases