def __add__(self, other): """ Return sum of two modules. """ denominator = gcd.lcm(self.denominator, other.denominator) row = self.dimension assert row == other.dimension column = self.rank + other.rank mat = matrix.createMatrix(row, column) adjust = denominator // self.denominator for i, base in enumerate(self.basis): mat.setColumn(i + 1, [c * adjust for c in base]) adjust = denominator // other.denominator for i, base in enumerate(other.basis): mat.setColumn(self.rank + i + 1, [c * adjust for c in base]) # Hermite normal form hnf = mat.hermiteNormalForm() # The hnf returned by the hermiteNormalForm method may have columns # of zeros, and they are not needed. zerovec = vector.Vector([0] * hnf.row) while hnf.row < hnf.column or hnf[1] == zerovec: hnf.deleteColumn(1) omega = [] for j in range(1, hnf.column + 1): omega.append(list(hnf[j])) return ModuleWithDenominator(omega, denominator)
def intersect(self, other): """ return intersection of self and other """ # if self.number_field != other.number_field: # raise ValueError("based on different number field") if self.base != other.base: new_self = self.change_base_module(other.base) else: new_self = self.copy() new_denominator = gcd.lcm(new_self.denominator, other.denominator) if new_self.denominator != new_denominator: multiply_denom = ring.exact_division( new_denominator, new_self.denominator) new_self_mat_repr = multiply_denom * new_self.mat_repr else: new_self_mat_repr = new_self.mat_repr if other.denominator != new_denominator: multiply_denom = ring.exact_division( new_denominator, other.denominator) new_other_mat_repr = multiply_denom * other.mat_repr else: new_other_mat_repr = other.mat_repr new_mat_repr = Submodule.fromMatrix( new_self_mat_repr).intersectionOfSubmodules(new_other_mat_repr) new_module = self.__class__( [new_mat_repr, new_denominator], self.number_field, other.base) new_module._simplify() return new_module
def intersect(self, other): """ return intersection of self and other """ # if self.number_field != other.number_field: # raise ValueError("based on different number field") if self.base != other.base: new_self = self.change_base_module(other.base) else: new_self = self.copy() new_denominator = gcd.lcm(new_self.denominator, other.denominator) if new_self.denominator != new_denominator: multiply_denom = ring.exact_division(new_denominator, new_self.denominator) new_self_mat_repr = multiply_denom * new_self.mat_repr else: new_self_mat_repr = new_self.mat_repr if other.denominator != new_denominator: multiply_denom = ring.exact_division(new_denominator, other.denominator) new_other_mat_repr = multiply_denom * other.mat_repr else: new_other_mat_repr = other.mat_repr new_mat_repr = Submodule.fromMatrix( new_self_mat_repr).intersectionOfSubmodules(new_other_mat_repr) new_module = self.__class__([new_mat_repr, new_denominator], self.number_field, other.base) new_module._simplify() return new_module
def order(self): """ This method returns order for permutation element. """ data = self.simplify().data sol = 1 for x in data: sol = gcd.lcm(sol, len(x)) return sol
def __add__(self, other): if self.size == other.size: m = self.size zr_a = Zeta(m) for i in range(m): zr_a.z[i] = self.z[i] + other.z[i] return zr_a else: m = gcd.lcm(self.size, other.size) return self.promote(m) + other.promote(m)
def ch_basic(self): denom = 1 for i in range(self.degree): if not isinstance(self.coeff[i], int): denom *= gcd.lcm(denom, (self.coeff[i]).denominator) coeff = [] for i in range(self.degree): if isinstance(self.coeff[i], int): coeff.append(self.coeff[i] * denom) else: coeff.append(int((self.coeff[i]).numerator * denom / (self.coeff[i]).denominator)) return BasicAlgNumber([coeff, denom], self.polynomial)
def _toIntegerMatrix(mat, option=0): """ transform a (including integral) rational matrix to some integral matrix as the following [option] 0: return integral-matrix, denominator (mat = 1/denominator * integral-matrix) 1: return integral-matrix, denominator, numerator (mat = numerator/denominator * reduced-int-matrix) 2: return integral-matrix, numerator (assuming mat is integral) (mat = numerator * numerator-reduced-rational-matrix) """ def getDenominator(ele): """ get the denominator of ele """ if rational.isIntegerObject(ele): return 1 else: # rational return ele.denominator def getNumerator(ele): """ get the numerator of ele """ if rational.isIntegerObject(ele): return ele else: # rational return ele.numerator if isinstance(mat, vector.Vector): mat = mat.toMatrix(True) if option <= 1: denom = mat.reduce( lambda x, y: gcd.lcm(x, getDenominator(y)), 1) new_mat = mat.map( lambda x: getNumerator(x) * ring.exact_division( denom, getDenominator(x))) if option == 0: return Submodule.fromMatrix(new_mat), denom else: new_mat = mat numer = new_mat.reduce( lambda x, y: gcd.gcd(x, getNumerator(y))) if numer != 0: new_mat2 = new_mat.map( lambda x: ring.exact_division(getNumerator(x), numer)) else: new_mat2 = new_mat if option == 1: return Submodule.fromMatrix(new_mat2), denom, numer else: return Submodule.fromMatrix(new_mat2), numer
def polyfactorizationNF(f): """ NFPolynomialFactorization(f) -> factors Return a number field factorization of given number field coefficient squarefree polynomial f. The result factors have number field coefficients, its minimum absolute representation. """ # initialize Q = rational.RationalField() # Q as RationalField K = f.getCoefficientRing() # K as NumberField # to squarefree u = f / f.gcd(f.differentiate()) # partition each degree. degree = g.degree() Gcoeffs = {} # Gcoeffs as coefficient as G (TBA) for i in range(degree + 1): U[i] = u[i] if not isinstance(U[i], algfield.BasicAlgNumber): raise NotImplementError("FIXME: support only BasicAlgNumber .") g[i] = uniutil.OneVariableDensePolynomial(U[i].coeff, "Y", Q) / U[i].denom for j in range(g[i].degree() + 1): Gcoeffs[(i, j)] = g[i][j] G = multiutil.polynomial(Gcoeffs, Q) # G as partition form of u # search for squarefree polynomial norm k = 0 # FIXME: symbolic computation, but also slower. x = multiutil.polynomial((1, 0), Q) y = multiutil.polynomial((0, 1), Q) while True: N = T(y).resultant(G(x - k * y, y), 2) if (N == N / N.gcd(N.differentiate())): break k = k + 1 # Now, here N is squarefree. # assume all the coefficients of N is rational.Rational . denom = 1 for coeff in N.coefficients(): denom = gcd.lcm(denom, coeff.denominator) Nz = N * denom # NZ be a integer, but probably not monic. for index, coeff in Nz.terms(): V[index] = coeff.numerator NZ = uniutil.polynomial(V, rational.IntegerRing()) F = integerpolynomialfactorization(NZ)
def double_embeddings(f_q1, f_q2): """ Return embedding homomorphism functions from f_q1 and f_q2 to the composite field. """ identity = lambda x: x if f_q1 is f_q2: return (identity, identity) p = f_q2.getCharacteristic() k1, k2 = f_q1.degree, f_q2.degree if not k2 % k1: return (embedding(f_q1, f_q2), identity) if not k1 % k2: return (identity, embedding(f_q2, f_q1)) composite = FiniteExtendedField(p, gcd.lcm(k1, k2)) return (embedding(f_q1, composite), embedding(f_q2, composite))
def inverse(self): f = qpoly(self.polynomial) g = qpoly(self.coeff) quot = f.extgcd(g) icoeff = [self.denom * quot[1][i] for i in range(self.degree)] #print icoeff denom_list = [] for i in range(self.degree): if icoeff[i] == 0: denom_list.append(1) else: denom_list.append(icoeff[i].denominator) new_denom = 1 for i in range(self.degree): new_denom = gcd.lcm(new_denom, denom_list[i]) icoeff = [icoeff[i].numerator * new_denom // icoeff[i].denominator for i in range(self.degree)] return BasicAlgNumber([icoeff, new_denom], self.polynomial)
def __mul__(self, other): if not isinstance(other, Zeta): zr_m = Zeta(self.size) zr_m.z = [x * other for x in self.z] return zr_m elif self.size == other.size: zr_m = Zeta(self.size) other = +other for k in range(other.size): if not other.z[k]: continue elif other.z[k] == 1: zr_m = zr_m + (self << k) else: zr_m = zr_m + (self << k) * other.z[k] return zr_m else: m = gcd.lcm(self.size, other.size) return self.promote(m) * other.promote(m)
def __mul__(self, other): if not isinstance(other, Zeta): zr_m = Zeta(self.size) zr_m.z = [x*other for x in self.z] return zr_m elif self.size == other.size: zr_m = Zeta(self.size) other = +other for k in range(other.size): if not other.z[k]: continue elif other.z[k] == 1: zr_m = zr_m + (self<<k) else: zr_m = zr_m + (self<<k)*other.z[k] return zr_m else: m = gcd.lcm(self.size,other.size) return self.promote(m)*other.promote(m)
def testLcm(self): self.assertEqual(2, gcd.lcm(1, 2)) self.assertEqual(4, gcd.lcm(2, 4)) self.assertEqual(0, gcd.lcm(0, 10)) self.assertEqual(0, gcd.lcm(10, 0)) self.assertEqual(273, gcd.lcm(13, 21))