예제 #1
0
 def to_HNFRepresentation(self):
     """
     Transform self to the corresponding ideal as HNF representation
     """
     int_ring = self.number_field.integer_ring()
     n = self.number_field.degree
     polynomial = self.number_field.polynomial
     k = len(self.generator)
     # separate coeff and denom for generators and base
     gen_denom = reduce( gcd.lcm,
                         (self.generator[j].denom for j in range(k)) )
     gen_list = [gen_denom * self.generator[j] for j in range(k)]
     base_int, base_denom = _toIntegerMatrix(int_ring)
     
     base_alg = [BasicAlgNumber([base_int[j], 1], 
     polynomial) for j in range(1, n + 1)]
     repr_mat_list = []
     for gen in gen_list:
         for base in base_alg:
             new_gen = gen * base
             repr_mat_list.append(
                 vector.Vector([new_gen.coeff[j] for j in range(n)]))
     mat_repr = matrix.RingMatrix(n, n * k, repr_mat_list)
     new_mat_repr, numer = _toIntegerMatrix(mat_repr, 2)
     denom = gen_denom * base_denom
     denom_gcd = gcd.gcd(numer, denom)
     if denom_gcd != 1:
         denom = ring.exact_division(denom, denom_gcd)
         numer = ring.exact_division(numer, denom_gcd)
         if numer != 1:
             new_mat_repr = numer * new_mat_repr
     else:
         new_mat_repr = mat_repr
     return Ideal([new_mat_repr, denom], self.number_field)
예제 #2
0
 def change_base_module(self, other_base):
     """
     change base_module to other_base_module
     (i.e. represent with respect to base_module)
     """
     if self.base == other_base:
         return self
     n = self.number_field.degree
     if isinstance(other_base, list):
         other_base = matrix.FieldSquareMatrix(n,
             [vector.Vector(other_base[i]) for i in range(n)])
     else: # matrix repr
         other_base = other_base.copy()
     tr_base_mat, tr_base_denom = _toIntegerMatrix(
         other_base.inverse(self.base))
     denom = tr_base_denom * self.denominator
     mat_repr, numer = _toIntegerMatrix(
         tr_base_mat * self.mat_repr, 2)
     d = gcd.gcd(denom, numer)
     if d != 1:
         denom = ring.exact_division(denom, d)
         numer = ring.exact_division(numer, d)
     if numer != 1:
         mat_repr = numer * mat_repr
     return self.__class__([mat_repr, denom], self.number_field, other_base)
예제 #3
0
 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
예제 #4
0
파일: module.py 프로젝트: nickspoon/part-ii
 def change_base_module(self, other_base):
     """
     change base_module to other_base_module
     (i.e. represent with respect to base_module)
     """
     if self.base == other_base:
         return self
     n = self.number_field.degree
     if isinstance(other_base, list):
         other_base = matrix.FieldSquareMatrix(n,
             [vector.Vector(other_base[i]) for i in range(n)])
     else: # matrix repr
         other_base = other_base.copy()
     tr_base_mat, tr_base_denom = _toIntegerMatrix(
         other_base.inverse(self.base))
     denom = tr_base_denom * self.denominator
     mat_repr, numer = _toIntegerMatrix(
         tr_base_mat * self.mat_repr, 2)
     d = gcd.gcd(denom, numer)
     if d != 1:
         denom = ring.exact_division(denom, d)
         numer = ring.exact_division(numer, d)
     if numer != 1:
         mat_repr = numer * mat_repr
     return self.__class__([mat_repr, denom], self.number_field, other_base)
예제 #5
0
파일: module.py 프로젝트: nickspoon/part-ii
 def to_HNFRepresentation(self):
     """
     Transform self to the corresponding ideal as HNF representation
     """
     int_ring = self.number_field.integer_ring()
     n = self.number_field.degree
     polynomial = self.number_field.polynomial
     k = len(self.generator)
     # separate coeff and denom for generators and base
     gen_denom = reduce( gcd.lcm,
                         (self.generator[j].denom for j in range(k)) )
     gen_list = [gen_denom * self.generator[j] for j in range(k)]
     base_int, base_denom = _toIntegerMatrix(int_ring)
     
     base_alg = [BasicAlgNumber([base_int[j], 1], 
     polynomial) for j in range(1, n + 1)]
     repr_mat_list = []
     for gen in gen_list:
         for base in base_alg:
             new_gen = gen * base
             repr_mat_list.append(
                 vector.Vector([new_gen.coeff[j] for j in range(n)]))
     mat_repr = matrix.RingMatrix(n, n * k, repr_mat_list)
     new_mat_repr, numer = _toIntegerMatrix(mat_repr, 2)
     denom = gen_denom * base_denom
     denom_gcd = gcd.gcd(numer, denom)
     if denom_gcd != 1:
         denom = ring.exact_division(denom, denom_gcd)
         numer = ring.exact_division(numer, denom_gcd)
         if numer != 1:
             new_mat_repr = numer * new_mat_repr
     else:
         new_mat_repr = mat_repr
     return Ideal([new_mat_repr, denom], self.number_field)
예제 #6
0
파일: module.py 프로젝트: nickspoon/part-ii
 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
예제 #7
0
 def _simplify(self):
     """
     simplify self.denominator
     """
     mat_repr, numer = _toIntegerMatrix(self.mat_repr, 2)
     denom_gcd = gcd.gcd(numer, self.denominator)
     if denom_gcd != 1:
         self.denominator = ring.exact_division(self.denominator, denom_gcd)
         self.mat_repr = Submodule.fromMatrix(
             ring.exact_division(numer, denom_gcd) * mat_repr)
예제 #8
0
파일: module.py 프로젝트: nickspoon/part-ii
 def _simplify(self):
     """
     simplify self.denominator
     """
     mat_repr, numer = _toIntegerMatrix(self.mat_repr, 2)
     denom_gcd = gcd.gcd(numer, self.denominator)
     if denom_gcd != 1:
         self.denominator = ring.exact_division(self.denominator, denom_gcd)
         self.mat_repr = Submodule.fromMatrix(
             ring.exact_division(numer, denom_gcd) * mat_repr)
예제 #9
0
파일: module.py 프로젝트: nickspoon/part-ii
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
예제 #10
0
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
예제 #11
0
 def __contains__(self, other):
     """
     Check whether other is an element of self or not
     """
     #if not(other in self.number_field):
     #    return False
     if isinstance(other, (tuple, vector.Vector)):  #vector repr
         other_int, other_denom = _toIntegerMatrix(vector.Vector(other))
     elif isinstance(other, list):
         if isinstance(other[0], (tuple, vector.Vector)):
             other_int = vector.Vector(other[0])
             other_denom = other[1]
         else:
             raise ValueError("input [vector, denominator]!")
     else:  # field element
         if not isinstance(other, BasicAlgNumber):
             other_copy = other.ch_basic()
         else:
             other_copy = other
         other_base_repr = self.base.inverse(vector.Vector(
             other_copy.coeff))
         other_int, other_int_denom = _toIntegerMatrix(other_base_repr)
         other_denom = other_int_denom * other_copy.denom
     if isinstance(other_int, matrix.Matrix):
         other_int = other_int[1]
     try:
         numer = ring.exact_division(self.denominator, other_denom)
     except ValueError:  # division is not exact
         return False
     if numer != 1:
         other_vect = numer * other_int
     else:
         other_vect = other_int
     return not isinstance(self.mat_repr.represent_element(other_vect),
                           bool)
예제 #12
0
파일: module.py 프로젝트: nickspoon/part-ii
 def __contains__(self, other):
     """
     Check whether other is an element of self or not
     """
     #if not(other in self.number_field):
     #    return False
     if isinstance(other, (tuple, vector.Vector)): #vector repr
         other_int, other_denom = _toIntegerMatrix(vector.Vector(other))
     elif isinstance(other, list):
         if isinstance(other[0], (tuple, vector.Vector)):
             other_int = vector.Vector(other[0])
             other_denom = other[1]
         else:
             raise ValueError("input [vector, denominator]!")
     else: # field element
         if not isinstance(other, BasicAlgNumber):
             other_copy = other.ch_basic()
         else:
             other_copy = other
         other_base_repr = self.base.inverse(
             vector.Vector(other_copy.coeff))
         other_int, other_int_denom = _toIntegerMatrix(other_base_repr)
         other_denom = other_int_denom * other_copy.denom
     if isinstance(other_int, matrix.Matrix):
         other_int = other_int[1]
     try:
         numer = ring.exact_division(self.denominator, other_denom)
     except ValueError: # division is not exact
         return False
     if numer != 1:
         other_vect = numer * other_int
     else:
         other_vect = other_int
     return not isinstance(
         self.mat_repr.represent_element(other_vect), bool)
예제 #13
0
파일: module.py 프로젝트: nickspoon/part-ii
 def twoElementRepresentation(self):
     # refer to [Poh-Zas] 
     # Algorithm 4.7.10 and Exercise 29 in CCANT
     """
     Reduce the number of generator to only two elements
     Warning: If self is not a prime ideal, this method is not efficient
     """
     k = len(self.generator)
     gen_denom = reduce( gcd.lcm, 
         (self.generator[j].denom for j in range(k)) )
     gen_list = [gen_denom * self.generator[j] for j in range(k)]
     int_I = Ideal_with_generator(gen_list)
     R = 1
     norm_I = int_I.norm()
     l_I = int_I.smallest_rational()
     if l_I.denominator > 1:
         raise ValueError, "input an integral ideal"
     else:
         l_I = l_I.numerator
     while True:
         lmda = [R for i in range(k)]
         while lmda[0] > 0:
             alpha = lmda[0] * gen_list[0]
             for i in range(1, k):
                 alpha += lmda[i] * gen_list[i]
             if gcd.gcd(
               norm_I, ring.exact_division(
               alpha.norm(), norm_I)
               ) == 1 or gcd.gcd(
               norm_I, ring.exact_division(
               (alpha + l_I).norm(), norm_I)) == 1:
                 l_I_ori = BasicAlgNumber(
                     [[l_I] + [0] * (self.number_field.degree - 1),
                     gen_denom], self.number_field.polynomial)
                 alpha_ori = BasicAlgNumber([alpha.coeff, 
                     gen_denom], self.number_field.polynomial)
                 return Ideal_with_generator([l_I_ori, alpha_ori])
             for j in range(k)[::-1]:
                 if lmda[j] != -R:
                     lmda[j] -= 1
                     break
                 else:
                     lmda[j] = R
         R += 1
예제 #14
0
 def twoElementRepresentation(self):
     # refer to [Poh-Zas]
     # Algorithm 4.7.10 and Exercise 29 in CCANT
     """
     Reduce the number of generator to only two elements
     Warning: If self is not a prime ideal, this method is not efficient
     """
     k = len(self.generator)
     gen_denom = reduce(gcd.lcm,
                        (self.generator[j].denom for j in range(k)))
     gen_list = [gen_denom * self.generator[j] for j in range(k)]
     int_I = Ideal_with_generator(gen_list)
     R = 1
     norm_I = int_I.norm()
     l_I = int_I.smallest_rational()
     if l_I.denominator > 1:
         raise ValueError, "input an integral ideal"
     else:
         l_I = l_I.numerator
     while True:
         lmda = [R for i in range(k)]
         while lmda[0] > 0:
             alpha = lmda[0] * gen_list[0]
             for i in range(1, k):
                 alpha += lmda[i] * gen_list[i]
             if gcd.gcd(norm_I, ring.exact_division(
                     alpha.norm(), norm_I)) == 1 or gcd.gcd(
                         norm_I,
                         ring.exact_division(
                             (alpha + l_I).norm(), norm_I)) == 1:
                 l_I_ori = BasicAlgNumber(
                     [[l_I] + [0] *
                      (self.number_field.degree - 1), gen_denom],
                     self.number_field.polynomial)
                 alpha_ori = BasicAlgNumber([alpha.coeff, gen_denom],
                                            self.number_field.polynomial)
                 return Ideal_with_generator([l_I_ori, alpha_ori])
             for j in range(k)[::-1]:
                 if lmda[j] != -R:
                     lmda[j] -= 1
                     break
                 else:
                     lmda[j] = R
         R += 1
예제 #15
0
 def _scalar_mul(self, other):
     """
     return other * self, assuming other is a scalar
     (i.e. an element of self.number_field)
     """
     # use other is an element of higher or lower degree number field ?
     #if other.getRing() != self.number_field:
     #    raise NotImplementedError(
     #        "other is not a element of number field")
     if not isinstance(other, BasicAlgNumber):
         try:
             other = other.ch_basic()
         except:
             raise NotImplementedError(
                 "other is not an element of a number field")
     # represent other with respect to self.base
     other_repr, pseudo_other_denom = _toIntegerMatrix(
         self.base.inverse(vector.Vector(other.coeff)))
     other_repr = other_repr[1]
     # compute mul using self.base's multiplication
     base_mul = self._base_multiplication()
     n = self.number_field.degree
     mat_repr = []
     for k in range(1, self.mat_repr.column + 1):
         mat_repr_ele = vector.Vector([0] * n)
         for i1 in range(1, n + 1):
             for i2 in range(1, n + 1):
                 mat_repr_ele += self.mat_repr[
                     i1, k] * other_repr[i2] * _symmetric_element(
                         i1, i2, base_mul)
         mat_repr.append(mat_repr_ele)
     mat_repr, denom, numer = _toIntegerMatrix(
         matrix.FieldMatrix(n, len(mat_repr), mat_repr), 1)
     denom = self.denominator * pseudo_other_denom * other.denom * denom
     gcds = gcd.gcd(denom, numer)
     if gcds != 1:
         denom = ring.exact_division(denom, gcds)
         numer = ring.exact_division(numer, gcds)
     if numer != 1:
         mat_repr = numer * mat_repr
     else:
         mat_repr = mat_repr
     return self.__class__([mat_repr, denom], self.number_field, self.base)
예제 #16
0
파일: module.py 프로젝트: nickspoon/part-ii
 def _scalar_mul(self, other):
     """
     return other * self, assuming other is a scalar
     (i.e. an element of self.number_field)
     """
     # use other is an element of higher or lower degree number field ?
     #if other.getRing() != self.number_field:
     #    raise NotImplementedError(
     #        "other is not a element of number field")
     if not isinstance(other, BasicAlgNumber):
         try:
             other = other.ch_basic()
         except:
             raise NotImplementedError(
                 "other is not an element of a number field")
     # represent other with respect to self.base
     other_repr, pseudo_other_denom = _toIntegerMatrix(
         self.base.inverse(vector.Vector(other.coeff)))
     other_repr = other_repr[1]
     # compute mul using self.base's multiplication
     base_mul = self._base_multiplication()
     n = self.number_field.degree
     mat_repr = []
     for k in range(1, self.mat_repr.column +1):
         mat_repr_ele = vector.Vector([0] * n)
         for i1 in range(1, n + 1):
             for i2 in range(1, n + 1):
                 mat_repr_ele += self.mat_repr[i1, k] * other_repr[
                     i2] * _symmetric_element(i1, i2, base_mul)
         mat_repr.append(mat_repr_ele)
     mat_repr, denom, numer = _toIntegerMatrix(
         matrix.FieldMatrix(n, len(mat_repr), mat_repr), 1)
     denom = self.denominator * pseudo_other_denom * other.denom * denom
     gcds = gcd.gcd(denom, numer)
     if gcds != 1:
         denom = ring.exact_division(denom, gcds)
         numer = ring.exact_division(numer, gcds)
     if numer != 1:
         mat_repr = numer * mat_repr
     else:
         mat_repr = mat_repr
     return self.__class__([mat_repr, denom], self.number_field, self.base)
예제 #17
0
 def inverse(self):
     """
     Return the inverse ideal of self
     """
     # Algorithm 4.8.21 in CCANT
     field = self.number_field
     # step 1 (Note that det(T)T^-1=(adjugate matrix of T))
     T = Ideal._precompute_for_different(field)
     d = int(T.determinant())
     inv_different = Ideal([T.adjugateMatrix(), 1], field,
                           field.integer_ring())
     # step 2
     inv_I = self * inv_different  # already base is taken for integer_ring
     inv_I.toHNF()
     # step 3
     inv_mat, denom = _toIntegerMatrix(
         (inv_I.mat_repr.transpose() * T).inverse(), 0)
     numer = d * inv_I.denominator
     gcd_denom = gcd.gcd(denom, numer)
     if gcd_denom != 1:
         denom = ring.exact_division(denom, gcd_denom)
         numer = ring.exact_division(numer, gcd_denom)
     return Ideal([numer * inv_mat, denom], field, field.integer_ring())
예제 #18
0
파일: module.py 프로젝트: nickspoon/part-ii
 def inverse(self):
     """
     Return the inverse ideal of self
     """
     # Algorithm 4.8.21 in CCANT
     field = self.number_field
     # step 1 (Note that det(T)T^-1=(adjugate matrix of T))
     T = Ideal._precompute_for_different(field)
     d = int(T.determinant())
     inv_different = Ideal([T.adjugateMatrix(), 1], field,
                           field.integer_ring())
     # step 2
     inv_I = self * inv_different # already base is taken for integer_ring
     inv_I.toHNF()
     # step 3
     inv_mat, denom = _toIntegerMatrix(
         (inv_I.mat_repr.transpose() * T).inverse(), 0)
     numer = d * inv_I.denominator
     gcd_denom = gcd.gcd(denom, numer)
     if gcd_denom != 1:
         denom = ring.exact_division(denom, gcd_denom)
         numer = ring.exact_division(numer, gcd_denom)
     return Ideal([numer * inv_mat, denom], field, field.integer_ring())
예제 #19
0
 def _module_mul(self, other):
     """
     return self * other as the multiplication of modules
     """
     #if self.number_field != other.number_field:
     #    raise NotImplementedError
     if self.base != other.base:
         new_self = self.change_base_module(other.base)
     else:
         new_self = self.copy()
     base_mul = other._base_multiplication()
     n = self.number_field.degree
     new_mat_repr = []
     for k1 in range(1, new_self.mat_repr.column + 1):
         for k2 in range(1, other.mat_repr.column + 1):
             new_mat_repr_ele = vector.Vector([0] * n)
             for i1 in range(1, n + 1):
                 for i2 in range(1, n + 1):
                     new_mat_repr_ele += new_self.mat_repr[
                         i1, k1] * other.mat_repr[i2,
                                                  k2] * _symmetric_element(
                                                      i1, i2, base_mul)
             new_mat_repr.append(new_mat_repr_ele)
     new_mat_repr, denom, numer = _toIntegerMatrix(
         matrix.FieldMatrix(n, len(new_mat_repr), new_mat_repr), 1)
     denom = new_self.denominator * other.denominator * denom
     gcds = gcd.gcd(denom, numer)
     if gcds != 1:
         denom = ring.exact_division(denom, gcds)
         numer = ring.exact_division(numer, gcds)
     if numer != 1:
         mat_repr = numer * new_mat_repr
     else:
         mat_repr = new_mat_repr
     sol = self.__class__([mat_repr, denom], self.number_field, other.base)
     sol.toHNF()
     return sol
예제 #20
0
파일: module.py 프로젝트: nickspoon/part-ii
 def _module_mul(self, other):
     """
     return self * other as the multiplication of modules
     """
     #if self.number_field != other.number_field:
     #    raise NotImplementedError
     if self.base != other.base:
         new_self = self.change_base_module(other.base)
     else:
         new_self = self.copy()
     base_mul = other._base_multiplication()
     n = self.number_field.degree
     new_mat_repr = []
     for k1 in range(1, new_self.mat_repr.column + 1):
         for k2 in range(1, other.mat_repr.column + 1):
             new_mat_repr_ele = vector.Vector([0] * n)
             for i1 in range(1, n + 1):
                 for i2 in range(1, n + 1):
                     new_mat_repr_ele += new_self.mat_repr[
                         i1, k1] * other.mat_repr[i2, k2
                         ] * _symmetric_element(i1, i2, base_mul)
             new_mat_repr.append(new_mat_repr_ele)
     new_mat_repr, denom, numer = _toIntegerMatrix(
         matrix.FieldMatrix(n, len(new_mat_repr), new_mat_repr), 1)
     denom = new_self.denominator * other.denominator * denom
     gcds = gcd.gcd(denom, numer)
     if gcds != 1:
         denom = ring.exact_division(denom, gcds)
         numer = ring.exact_division(numer, gcds)
     if numer != 1:
         mat_repr = numer * new_mat_repr
     else:
         mat_repr = new_mat_repr
     sol = self.__class__(
         [mat_repr, denom], self.number_field, other.base)
     sol.toHNF()
     return sol
예제 #21
0
 def _HNF_solve(self, other):
     """
     return X over coeff_ring s.t. self * X = other,
     where self is HNF, other is vector
     """
     if self.row != len(other):
         raise vector.VectorSizeError()
     n = self.column
     zero = self.coeff_ring.zero
     X = vector.Vector([zero] * n)
     # search non-zero entry
     for i in range(1, self.row + 1)[::-1]:
         if self[i, n] != zero:
             break
         if other[i] != zero:
             return False
     else:
         return X
     # solve HNF system (only integral solution)
     for j in range(1, n + 1)[::-1]:
         sum_i = other[i]
         for k in range(j + 1, n + 1):
             sum_i -= X[k] * self[i, k]
         try:
             X[j] = ring.exact_division(sum_i, self[i, j])
         except ValueError:  # division is not exact
             return False
         ii = i
         i -= 1
         for i in range(1, ii)[::-1]:
             if j != 1 and self[i, j - 1] != zero:
                 break
             sum_i = X[j] * self[i, j]
             for k in range(j + 1, n + 1):
                 sum_i += X[k] * self[i, k]
             if sum_i != other[i]:
                 return False
         if i == 0:
             break
     return X
예제 #22
0
파일: module.py 프로젝트: nickspoon/part-ii
 def _HNF_solve(self, other):
     """
     return X over coeff_ring s.t. self * X = other,
     where self is HNF, other is vector
     """
     if self.row != len(other):
         raise vector.VectorSizeError()
     n = self.column
     zero = self.coeff_ring.zero
     X = vector.Vector([zero] * n)
     # search non-zero entry
     for i in range(1, self.row + 1)[::-1]:
         if self[i, n] != zero:
             break
         if other[i] != zero:
             return False
     else:
         return X
     # solve HNF system (only integral solution)
     for j in range(1, n + 1)[::-1]:
         sum_i = other[i]
         for k in range(j + 1, n + 1):
             sum_i -= X[k] * self[i, k]
         try:
             X[j] = ring.exact_division(sum_i, self[i, j])
         except ValueError: # division is not exact
             return False
         ii = i
         i -= 1
         for i in range(1, ii)[::-1]:
             if j != 1 and self[i, j - 1] != zero:
                 break
             sum_i = X[j] * self[i, j]
             for k in range(j + 1, n + 1):
                 sum_i += X[k] * self[i, k]
             if sum_i != other[i]:
                 return False
         if i == 0:
             break
     return X
예제 #23
0
파일: module.py 프로젝트: nickspoon/part-ii
 def _rational_mul(self, other):
     """
     return other * self, assuming other is a rational element
     """
     if rational.isIntegerObject(other):
         other_numerator = rational.Integer(other)
         other_denominator = rational.Integer(1)
     else:
         other_numerator = other.numerator
         other_denominator = other.denominator
     denom_gcd = gcd.gcd(self.denominator, other_numerator)
     if denom_gcd != 1:
         new_denominator = ring.exact_division(
             self.denominator, denom_gcd) * other_denominator
         multiply_num = other_numerator.exact_division(denom_gcd)
     else:
         new_denominator = self.denominator * other_denominator
         multiply_num = other_numerator
     new_module = self.__class__(
                      [self.mat_repr * multiply_num, new_denominator],
                      self.number_field, self.base, self.mat_repr.ishnf)
     new_module._simplify()
     return new_module
예제 #24
0
 def _rational_mul(self, other):
     """
     return other * self, assuming other is a rational element
     """
     if rational.isIntegerObject(other):
         other_numerator = rational.Integer(other)
         other_denominator = rational.Integer(1)
     else:
         other_numerator = other.numerator
         other_denominator = other.denominator
     denom_gcd = gcd.gcd(self.denominator, other_numerator)
     if denom_gcd != 1:
         new_denominator = ring.exact_division(
             self.denominator, denom_gcd) * other_denominator
         multiply_num = other_numerator.exact_division(denom_gcd)
     else:
         new_denominator = self.denominator * other_denominator
         multiply_num = other_numerator
     new_module = self.__class__(
         [self.mat_repr * multiply_num, new_denominator], self.number_field,
         self.base, self.mat_repr.ishnf)
     new_module._simplify()
     return new_module
예제 #25
0
    def represent_element(self, other):
        """
        represent other as a linear combination with generators of self
        if other not in self, return False
        Note that we do not assume self.mat_repr is HNF
        """
        #if other not in self.number_field:
        #    return False
        theta_repr = (self.base * self.mat_repr)
        theta_repr.toFieldMatrix()
        pseudo_vect_repr = theta_repr.inverseImage(
            vector.Vector(other.coeff))
        pseudo_vect_repr = pseudo_vect_repr[1]
        gcd_self_other = gcd.gcd(self.denominator, other.denom)
        multiply_numerator = self.denominator // gcd_self_other
        multiply_denominator = other.denom // gcd_self_other

        def getNumerator_and_Denominator(ele):
            """
            get the pair of numerator and denominator of ele
            """
            if rational.isIntegerObject(ele):
                return (ele, 1)
            else: # rational
                return (ele.numerator, ele.denominator)

        list_repr = []
        for j in range(1, len(pseudo_vect_repr) + 1):
            try:
                numer, denom = getNumerator_and_Denominator(
                    pseudo_vect_repr[j])
                list_repr_ele = ring.exact_division(
                    numer * multiply_numerator, denom * multiply_denominator)
                list_repr.append(list_repr_ele)
            except ValueError: # division is not exact
                return False
        return list_repr
예제 #26
0
파일: module.py 프로젝트: nickspoon/part-ii
    def represent_element(self, other):
        """
        represent other as a linear combination with generators of self
        if other not in self, return False
        Note that we do not assume self.mat_repr is HNF
        """
        #if other not in self.number_field:
        #    return False
        theta_repr = (self.base * self.mat_repr)
        theta_repr.toFieldMatrix()
        pseudo_vect_repr = theta_repr.inverseImage(
            vector.Vector(other.coeff))
        pseudo_vect_repr = pseudo_vect_repr[1]
        gcd_self_other = gcd.gcd(self.denominator, other.denom)
        multiply_numerator = self.denominator // gcd_self_other
        multiply_denominator = other.denom // gcd_self_other

        def getNumerator_and_Denominator(ele):
            """
            get the pair of numerator and denominator of ele
            """
            if rational.isIntegerObject(ele):
                return (ele, 1)
            else: # rational
                return (ele.numerator, ele.denominator)

        list_repr = []
        for j in range(1, len(pseudo_vect_repr) + 1):
            try:
                numer, denom = getNumerator_and_Denominator(
                    pseudo_vect_repr[j])
                list_repr_ele = ring.exact_division(
                    numer * multiply_numerator, denom * multiply_denominator)
                list_repr.append(list_repr_ele)
            except ValueError: # division is not exact
                return False
        return list_repr