def _check_H(p, H, field, gamma_mul):
    """
    If H express the prime ideal, return (H, f),
    where f: residual degree.
    Else return some column of M_1 (not (1,0,..,0)^t).
    """
    F_p = finitefield.FinitePrimeField(p)
    if H == None:
        f = field.degree
    else:
        f = H.row - H.column # rank(A), A.column
    # CCANT Algo 6.2.9 step 10-11
    # step 10
    B = matrix.unitMatrix(f, F_p)
    M_basis = []
    for j in range(1, f + 1):
        alpha_pow = _pow_by_base_mul(B[j], p, gamma_mul, f)
        alpha_pow -= B[j]
        M_basis.append(alpha_pow)
    M_1 = matrix.FieldMatrix(f, f, M_basis).kernel()
    # step 11
    if M_1.column > 1: # dim(M_1) > 1
        return M_1[M_1.column]
    else:
        H_simple = _two_element_repr_prime_ideal(
                   p, H.map(lambda x: x.getResidue()), field, f)
        p_alg = algfield.BasicAlgNumber([[p] + [0] * (field.degree - 1), 1], 
                field.polynomial)
        sol = module.Ideal_with_generator([p_alg, H_simple])
        return (sol, f)
def _div_mod_pO(self, other, base_multiply, p):
    """
    ideal division modulo pO by using base_multiply
    """
    n = other.row
    m = other.column 
    F_p = finitefield.FinitePrimeField(p)
    #Algo 2.3.7
    if self == None:
        self_new = matrix.zeroMatrix(n, F_p)
        r = 0
    else:
        self_new = self
        r = self.column
    if r == m:
        return matrix.unitMatrix(n, F_p)
    # if r > m, raise NoInverseImage error
    X = matrix.Subspace.fromMatrix(other.inverseImage(self_new))
    B = X.supplementBasis()
    other_self = other * B # first r columns are self, others are supplement
    other_self.toFieldMatrix()

    gamma_part = other_self.subMatrix(
        range(1, n + 1), range(r + 1, m + 1))
    omega_gamma = other_self.inverseImage(_matrix_mul_by_base_mul(
        matrix.unitMatrix(n, F_p), gamma_part, base_multiply))
    vect_list = []
    for k in range(1, n + 1):
        vect = vector.Vector([F_p.zero] * ((m - r) ** 2))
        for i in range(1, m - r + 1):
            for j in range(1, m - r + 1):
                vect[(m - r) * (i - 1) + j] = _mul_place(
                    k, i, omega_gamma, m - r)[j + r]
        vect_list.append(vect)
    return matrix.FieldMatrix( (m - r) ** 2, n, vect_list).kernel()
def _matrix_mul_by_base_mul(self, other, base_mul, max_j=False):
    """
    return self * other with respect to basis (gamma_i),
    where self, other are matrix.
    (base_mul)_ij express gamma_i gamma_j
    """
    n = base_mul.row
    sol = []
    for k1 in range(1, self.column + 1):
        for k2 in range(1, other.column + 1):
            sol_ele = _vect_mul_by_base_mul(
                self[k1], other[k2], base_mul, max_j)
            sol.append(sol_ele)
    return matrix.FieldMatrix(n, len(sol), sol)
Example #4
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)
Example #5
0
def _base_multiplication(base, number_field):
    """
    return [base[i] * base[j]] (as a numberfield element)
    this is a precomputation for computing _module_mul
    """
    n = number_field.degree
    polynomial = number_field.polynomial
    base_int, base_denom = _toIntegerMatrix(base)
    base_alg = [BasicAlgNumber([base_int[j], 1], 
        polynomial) for j in range(1, n + 1)]
    base_ij_list = []
    for j in range(n):
        for i in range(j + 1):
            base_ij = base_alg[i] * base_alg[j]
            base_ij_list.append(
                vector.Vector([base_ij.coeff[k] * 
                rational.Rational(1, base_denom ** 2) for k in range(n)]))
    base_ij = base.inverse(
        matrix.FieldMatrix(n, len(base_ij_list), base_ij_list))
    return base_ij
def _splitting_squarefree(p, H, base_multiply, A, gamma_mul, alpha):
    """
    split squarefree part
    """
    F_p = finitefield.FinitePrimeField(p)
    if H == None:
        n = base_multiply.row
        f = n
        H_new = matrix.zeroMatrix(n, 1, F_p)
    else:
        n = H.row
        f = n - H.column
        H_new = H.copy()
    # step 12
    one_gamma = vector.Vector([F_p.one] + [F_p.zero] *
                              (f - 1))  # w.r.t. gamma_1
    minpoly_matrix_alpha = matrix.FieldMatrix(f, 2, [one_gamma, alpha])
    ker = minpoly_matrix_alpha.kernel()
    alpha_pow = alpha
    while ker == None:
        alpha_pow = _vect_mul_by_base_mul(alpha_pow, alpha, gamma_mul, f)
        minpoly_matrix_alpha.extendColumn(alpha_pow)
        ker = minpoly_matrix_alpha.kernel()
    minpoly_alpha = uniutil.FinitePrimeFieldPolynomial(enumerate(ker[1].compo),
                                                       F_p)
    # step 13
    m_list = minpoly_alpha.factor()
    # step 14
    L = []
    for (m_s, i) in m_list:
        M_s = H_new.copy()
        beta_s_gamma = _substitution_by_base_mul(m_s, alpha, gamma_mul,
                                                 one_gamma, f)
        # beta_s_gamma (w.r.t. gamma) -> beta_s (w.r.t. omega)
        beta_s = A * beta_s_gamma
        omega_beta_s = _matrix_mul_by_base_mul(matrix.unitMatrix(n, F_p),
                                               beta_s.toMatrix(True),
                                               base_multiply)
        M_s.extendColumn(omega_beta_s)
        L.append(M_s.image())
    return L
Example #7
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