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 __init__(self, field, stconsts, name): self.stconsts = stconsts self.field = field self.dim = stconsts[0].row self.unit = matrix.unitMatrix(self.dim, self.field) self.name = name self.Rad = None
def algebra_example(dim, n): # Algebras are defined over GF(2) field = GF2 # All the algebras are unital stconsts = [matrix.unitMatrix(dim, field)] if dim == 1: if n == 1: # 1D, semisimple, 1 * 1 = 1 return AlgebraDescription(field, stconsts, True) if dim == 2: if n == 1: # 2D, not semisimple, identity 1, aa = 1 stconsts.append(matrix.Matrix(2, 2, [(0,1),(1,0)], field)) return AlgebraDescription(field, stconsts, False) if n == 2: # 2D, not semisimple, identity 1, aa = 0 stconsts.append(matrix.Matrix(2, 2, [(0,1),(0,0)], field)) return AlgebraDescription(field, stconsts, False) if dim == 3: if n == 1: # 3D, semisimple, identity 1, aa = a, bb = b, ab = ba = 0 stconsts.append(matrix.Matrix(3, 3, [(0,1,0),(0,1,0),(0,0,0)], field)) stconsts.append(matrix.Matrix(3, 3, [(0,0,1),(0,0,0),(0,0,1)], field)) return AlgebraDescription(field, stconsts, True) raise ValueError("No such example")
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 testMainCase(self): # cubic_first [1, 9, 0, 3] field = algfield.NumberField(self.cubic_first) # p=3 cubic_first_3_index = [(1, 1), (2, 1)] # split & ramify cubic_first_3_prime = 3 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(3, self.cubic_first)) self.assertEqual(result_e_f, cubic_first_3_index) self.assertEqual(result_mul, cubic_first_3_prime) # cubic_second [1, 8, 0, 3] field = algfield.NumberField(self.cubic_second) # p=5 cubic_second_5_index = [(1, 1), (1, 2)] # split & inert cubic_second_5_prime = 5 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(5, self.cubic_second)) self.assertEqual(result_e_f, cubic_second_5_index) self.assertEqual(result_mul, cubic_second_5_prime) # sextic_first [7, 6, 5, 4, 3, 2, 1] field = algfield.NumberField(self.sextic_first) # p=2 sextic_first_2_index = [(2, 1), (4, 1)] # split & ramify sextic_first_2_prime = 2 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(2, self.sextic_first)) self.assertEqual(result_e_f, sextic_first_2_index) self.assertEqual(result_mul, sextic_first_2_prime) # sextic_second [6480, 1296, -252, 36, -7, 1] field = algfield.NumberField(self.sextic_second) # p=2 sextic_second_2_index = [(1, 1), (1, 4)] # split & ramify sextic_second_2_prime = 2 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(2, self.sextic_second)) self.assertEqual(result_e_f, sextic_second_2_index) self.assertEqual(result_mul, sextic_second_2_prime) # p=3 sextic_second_3_index = [(1, 1), (1, 1), (1, 1), (1, 2)] # split & inert sextic_second_3_prime = 3 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(3, self.sextic_second)) self.assertEqual(result_e_f, sextic_second_3_index) self.assertEqual(result_mul, sextic_second_3_prime)
def __pow__(self, other): if other < 0: return Module.__pow__(self.inverse(), -other) elif other == 0: field = self.number_field n = field.degree int_basis = field.integer_ring() return Ideal([matrix.unitMatrix(n), 1], field, int_basis) else: return Module.__pow__(self, other)
def _two_element_repr_prime_ideal(p, hnf, field, f): """ return alpha such that (p, alpha) is same ideal to the ideal represented by hnf (matrix) w.r.t. the integer ring of field. we assume the ideal is a prime ideal whose norm is p^f, where p is prime. """ # assume that first basis of the integral basis equals 1 int_basis = field.integer_ring() # step 1 n = field.degree Z = rational.theIntegerRing beta = (p * matrix.unitMatrix(n, Z).subMatrix( range(1, n + 1), range(2, n + 1))).copy() beta.extendColumn(hnf) m = beta.column # step 2 R = 0 P_norm = p ** f while True: R += 1 lmd = [R] * m while True: # step 3 alpha = lmd[0] * beta[1] for j in range(1, m): alpha += lmd[j] * beta[j + 1] alpha = _vector_to_algnumber(int_basis * alpha, field) n = alpha.norm() / P_norm r = divmod(int(n), p)[1] if r: return alpha # step 4 for j in range(m - 1, 0, -1): if lmd[j] != -R: break lmd[j] -= 1 for i in range(j + 1, m): lmd[i] = R # step 5 for j in range(m): if lmd[j] != 0: break else: break
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
def testEasyCase(self): # Q_rt_minus_1 [1, 0, 1] field = algfield.NumberField(self.Q_rt_minus_1) # p=2 Q_rt_minus_1_2_index = [(2, 1)] # ramify Q_rt_minus_1_2_prime = 2 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(2, self.Q_rt_minus_1)) self.assertEqual(result_e_f, Q_rt_minus_1_2_index) self.assertEqual(result_mul, Q_rt_minus_1_2_prime) # p=3 Q_rt_minus_1_3_index = [(1, 2)] # inert Q_rt_minus_1_3_prime = 3 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(3, self.Q_rt_minus_1)) self.assertEqual(result_e_f, Q_rt_minus_1_3_index) self.assertEqual(result_mul, Q_rt_minus_1_3_prime) # p=5 Q_rt_minus_1_5_index = [(1, 1), (1, 1)] # split Q_rt_minus_1_5_prime = 5 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(5, self.Q_rt_minus_1)) self.assertEqual(result_e_f, Q_rt_minus_1_5_index) self.assertEqual(result_mul, Q_rt_minus_1_5_prime) # Q_cb_2 [-2, 0, 0, 1] field = algfield.NumberField(self.Q_cb_2) # p=3 Q_cb_2_3_index = [(3, 1)] # ramify Q_cb_2_3_prime = 3 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(3, self.Q_cb_2)) self.assertEqual(result_e_f, Q_cb_2_3_index) self.assertEqual(result_mul, Q_cb_2_3_prime) # p=5 Q_cb_2_5_index = [(1, 1), (1, 2)] # split & inert Q_cb_2_5_prime = 5 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(5, self.Q_cb_2)) self.assertEqual(result_e_f, Q_cb_2_5_index) self.assertEqual(result_mul, Q_cb_2_5_prime) # p=31 Q_cb_2_31_index = [(1, 1), (1, 1), (1, 1)] # split Q_cb_2_31_prime = 31 * module.Ideal( matrix.unitMatrix(field.degree), field, field.integer_ring()) result_e_f, result_mul = self.result_transform(prime_decomp(31, self.Q_cb_2)) self.assertEqual(result_e_f, Q_cb_2_31_index) self.assertEqual(result_mul, Q_cb_2_31_prime)
def __init__(self, pair_mat_repr, number_field, base=None, ishnf=False): """ pair_mat_repr: generators represented with respect to base_module 1: [[deg(number_field))-integral tuple/vector], denominator] 2: [integral matrix whose the number of row is deg(number_field), denominator] 3: rational matrix whose the number of row is deg(number_field) number_field: an instance of NumberField base: a base module represented with respect to Z[theta] 1: [deg(number_field)-rational tuple/vector], which represents basis 2: deg(number_field)-square non-singular rational matrix ishnf: if hnf_repr is already HNF-form, set True """ self.number_field = number_field size = self.number_field.degree if isinstance(base, bool): ishnf = base base = None if base == None: # power basis self.base = matrix.unitMatrix(size, rational.theIntegerRing) self.base.toFieldMatrix() elif isinstance(base, list): # list repr self.base = matrix.FieldSquareMatrix(size, base) else: # matrix repr if base.row != size: raise TypeError("The number of row of base is incorrect.") self.base = base.copy() self.base.toFieldMatrix() if not isinstance(pair_mat_repr, list): #rational matrix repr self.mat_repr, self.denominator = _toIntegerMatrix( pair_mat_repr) else: self.denominator = pair_mat_repr[1] if isinstance(pair_mat_repr[0], list): # list repr column = len(pair_mat_repr[0]) self.mat_repr = Submodule( size, column, pair_mat_repr[0], ishnf) else: # integral matrix repr self.mat_repr = Submodule.fromMatrix( pair_mat_repr[0].copy(), ishnf)
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
def radical(self): p = self.field.getCharacteristic() l = int(math.log(self.dim, p)) # B = A union {1_n} # If we assume that the algebra is unital we don't need this B = self.stconsts + [self.unit] # I_-1 = A, represented by a matrix of basis vectors over A I = matrix.unitMatrix(len(B), self.field) I.deleteColumn(len(B)) with pool.InPool() as Pool: for i in range1(0, l): print >>sys.stderr, "Radical computation #%d" % i M = matrix.Matrix(len(B), I.column, self.field) for k in range1(I.column): X = self.toMatrix(I[k], B) Xp = pack_matrix(X) work = [(p, i, Xp, pack_matrix(B[j-1])) for j in range1(len(B))] vec = map(self.field.createElement, Pool.map(compute_g_worker, work)) M.setColumn(k, vector.Vector(vec)) #for j in range1(len(B)): # M[j,k] = compute_g(p, i, X*B[j-1]) basis = M.kernel() if basis is None: self.semisimple = True return None # The solution is a set of column vectors sum_j(x_j * i_(i-1),j) # where i_k,1, ..., i_k,n = basis(I_k). Here we transform these # back to vectors in the basis of B by multiplying by basis(I_k). zero = vector.Vector([ self.field.zero for i in range(I.row) ]) I = matrix.Matrix(len(B), basis.column, [ sum((basis[i,j] * I[i] for i in range1(I.column)), zero) for j in range1(basis.column)]) assert(all(x == self.field.zero for x in I.getRow(I.row))) self.Rad = I.getBlock(1, 1, self.dim, I.column) self.save() return self.Rad
def T(A, j): p = A.coeff_ring.getCharacteristic() phi = lambda A: (x * A + matrix.unitMatrix(A.row, A.coeff_ring)).determinant() return phi(A)[p**j]
def POLRED(self): """ Given a polynomial f i.e. a field self, output some polynomials defining subfield of self, where self is a field defined by f. Algorithm 4.4.11 in Cohen's book. """ n = self.degree appr = self.getConj() #Step 1. Basis = self.integer_ring() BaseList = [] for i in range(n): AlgInt = MatAlgNumber(Basis[i].compo, self.polynomial) BaseList.append(AlgInt) #Step 2. traces = [] if self.signature()[1] == 0: for i in range(n): for j in range(n): s = BaseList[i] * BaseList[j] traces.append(s.trace()) else: sigma = self.getConj() f = [] for i in range(n): f.append(zpoly(Basis[i])) for i in range(n): for j in range(n): m = 0 + 0j for k in range(n): m += f[i](sigma[k]) * f[j](sigma[k].conjugate()) traces.append(m.real) #Step 3. M = matrix.createMatrix(n, n, traces) S = matrix.unitMatrix(n) L = lattice.LLL(S, M)[0] #Step 4. Ch_Basis = [] for i in range(n): base_cor = changetype(0, self.polynomial).ch_matrix() for v in range(n): base_cor += BaseList[v] * L.compo[v][i] Ch_Basis.append(base_cor) C = [] a = Ch_Basis[0] for i in range(n): coeff = Ch_Basis[i].ch_basic().getCharPoly() C.append(zpoly(coeff)) #Step 5. P = [] for i in range(n): diff_C = C[i].differentiate() gcd_C = C[i].subresultant_gcd(diff_C) P.append(C[i].exact_division(gcd_C)) return P
def POLRED(self): """ Given a polynomial f i.e. a field self, output some polynomials defining subfield of self, where self is a field defined by f. Algorithm 4.4.11 in Cohen's book. """ n = self.degree appr = self.getConj() #Step 1. Basis = self.integer_ring() BaseList = [] for i in range(n): AlgInt = MatAlgNumber(Basis[i].compo, self.polynomial) BaseList.append(AlgInt) #Step 2. traces = [] if self.signature()[1] == 0: for i in range(n): for j in range(n): s = BaseList[i]*BaseList[j] traces.append(s.trace()) else: sigma = self.getConj() f = [] for i in range(n): f.append(zpoly(Basis[i])) for i in range(n): for j in range(n): m = 0 + 0j for k in range(n): m += f[i](sigma[k])*f[j](sigma[k].conjugate()) traces.append(m.real) #Step 3. M = matrix.createMatrix(n, n, traces) S = matrix.unitMatrix(n) L = lattice.LLL(S, M)[0] #Step 4. Ch_Basis = [] for i in range(n): base_cor = changetype(0, self.polynomial).ch_matrix() for v in range(n): base_cor += BaseList[v]*L.compo[v][i] Ch_Basis.append(base_cor) C = [] a = Ch_Basis[0] for i in range(n): coeff = Ch_Basis[i].ch_basic().getCharPoly() C.append(zpoly(coeff)) #Step 5. P = [] for i in range(n): diff_C = C[i].differentiate() gcd_C = C[i].subresultant_gcd(diff_C) P.append(C[i].exact_division(gcd_C)) return P