def _separable_algebra(p, H, base_multiply): """ return A=O/H (as matrix representation) """ # CCANT Algo 6.2.9 step 8-9 F_p = finitefield.FinitePrimeField(p) n = base_multiply.row if H == None: H_new = matrix.zeroMatrix(n, 1, F_p) r = 0 else: H_new = H r = H.column # step 8 H_add_one = H_new.copy() if H_add_one.column == n: raise ValueError H_add_one.extendColumn(vector.Vector([F_p.one] + [F_p.zero] * (n - 1))) H_add_one.toSubspace(True) full_base = H_add_one.supplementBasis() full_base.toFieldMatrix() # step 9 A = full_base.subMatrix( range(1, n + 1), range(r + 1, n + 1)) gamma_mul = full_base.inverseImage( _matrix_mul_by_base_mul(A, A, base_multiply)) gamma_mul = gamma_mul.subMatrix( range(r + 1, n + 1), range(1, gamma_mul.column + 1)) return A, gamma_mul
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 intersect(self, S1, S2): cvectors = [ flatten_matrix(S) for S in S1 ] + \ [ flatten_matrix(-S) for S in S2 ] coeffs = matrix.Matrix(len(cvectors[0]), len(cvectors), cvectors, self.field) v = flatten_matrix(matrix.zeroMatrix(S1[0].row, S1[0].column)) self.addEquations(coeffs, v)
def intersect_solutions(S1, S2): if not S1 or not S2: return [] field = S1[0].coeff_ring lineq = LinearEquations(field, len(S1) + len(S2)) lineq.intersect(S1, S2) K = lineq.kernel() if K is None: return [] Kp = [ vector.Vector(v.compo[0:len(S1)]) for v in K ] intersection = [ vector_to_matrix(k, S1) for k in Kp ] return [ X for X in intersection if X != matrix.zeroMatrix(X.row) ]
def toHNF(self): """ Change matrix to HNF(hermite normal form) Note that HNF do not always give basis of self (i.e. HNF may be redundant) """ if not self.ishnf: hnf = self.hermiteNormalForm(True) if hnf == None: #zero module hnf = matrix.zeroMatrix(self.row, 1, self.coeff_ring) self.compo = hnf.compo self.column = hnf.column self.ishnf = True
def testDigitalMethod(self): zero1 = matrix.zeroMatrix(3,0) one1 = matrix.identityMatrix(3,1) d_func1 = digital_method_func( lambda a,b:a+b, lambda a,b:a*b, lambda i,a:i*a, lambda a,i:a**i, zero1, one1) coefficients11 = [] coefficients12 = [(2,1), (1,2), (0,1)] coefficients13 = [(3,1), (2,2), (1,3)] A = matrix.SquareMatrix(3, [1,2,3]+[4,5,6]+[7,8,9]) self.assertEqual(d_func1(coefficients11, A), zero1) self.assertEqual(d_func1(coefficients12, A), A**2+2*A+one1) self.assertEqual(d_func1(coefficients13, A), (A**3+2*A**2+3*A))
def _kernel_of_qpow(omega, q, p, minpoly, n): """ Return the kernel of q-th powering, which is a linear map over Fp. q is a power of p which exceeds n. (omega_j^q (mod theminpoly) = \sum a_i_j omega_i a_i_j in Fp) """ omega_poly = omega.get_polynomials() denom = omega.denominator theminpoly = minpoly.to_field_polynomial() field_p = finitefield.FinitePrimeField.getInstance(p) zero = field_p.zero qpow = matrix.zeroMatrix(n, n, field_p) # Fp matrix for j in range(n): a_j = [zero] * n omega_poly_j = uniutil.polynomial(enumerate(omega.basis[j]), Z) omega_j_qpow = pow(omega_poly_j, q, minpoly) redundancy = gcd.gcd(omega_j_qpow.content(), denom ** q) omega_j_qpow = omega_j_qpow.coefficients_map(lambda c: c // redundancy) essential = denom ** q // redundancy while omega_j_qpow: i = omega_j_qpow.degree() a_ji = int(omega_j_qpow[i] / (omega_poly[i][i] * essential)) omega_j_qpow -= a_ji * (omega_poly[i] * essential) if omega_j_qpow.degree() < i: a_j[i] = field_p.createElement(a_ji) else: _log.debug("%s / %d" % (str(omega_j_qpow), essential)) _log.debug("j = %d, a_ji = %s" % (j, a_ji)) raise ValueError("omega is not a basis") qpow.setColumn(j + 1, a_j) result = qpow.kernel() if result is None: _log.debug("(_k_q): trivial kernel") return matrix.zeroMatrix(n, 1, field_p) else: return result
def intersectionOfSubmodules(self, other): """ Return module which is intersection of self and other. """ if self.row != other.row: raise matrix.MatrixSizeError() M1 = self.copy() M1.extendColumn(other) N = M1.kernelAsModule() if N == None: # zero kernel N = matrix.zeroMatrix(self.row, 1, self.coeff_ring) N1 = N.getBlock(1, 1, self.column, N.column) # N.column is dim(ker(M1)) module = Submodule.fromMatrix(self * N1) module.toHNF() return module
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 _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