def test_DomainMatrix_init(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) assert A.rep == DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) assert A.shape == (2, 2) assert A.domain == ZZ raises(DDMBadInputError, lambda: DomainMatrix([[ZZ(1), ZZ(2)]], (2, 2), ZZ))
def test_DomainMatrix_from_Matrix(): sdm = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) A = DomainMatrix.from_Matrix(Matrix([[1, 2], [3, 4]])) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == ZZ K = QQ.algebraic_field(sqrt(2)) sdm = SDM( { 0: { 0: K.convert(1 + sqrt(2)), 1: K.convert(2 + sqrt(2)) }, 1: { 0: K.convert(3 + sqrt(2)), 1: K.convert(4 + sqrt(2)) } }, (2, 2), K) A = DomainMatrix.from_Matrix(Matrix([[1 + sqrt(2), 2 + sqrt(2)], [3 + sqrt(2), 4 + sqrt(2)]]), extension=True) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == K A = DomainMatrix.from_Matrix(Matrix([[QQ(1, 2), QQ(3, 4)], [QQ(0, 1), QQ(0, 1)]]), fmt='dense') ddm = DDM([[QQ(1, 2), QQ(3, 4)], [QQ(0, 1), QQ(0, 1)]], (2, 2), QQ) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == QQ
def test_dom_eigenvects_algebraic(): # Algebraic eigenvalues A = DomainMatrix([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], (2, 2), QQ) Avects = dom_eigenvects(A) # Extract the dummy to build the expected result: lamda = Avects[1][0][1].gens[0] irreducible = Poly(lamda**2 - 5 * lamda - 2, lamda, domain=QQ) K = FiniteExtension(irreducible) KK = K.from_sympy algebraic_eigenvects = [ (K, irreducible, 1, DomainMatrix([[KK((lamda - 4) / 3), KK(1)]], (1, 2), K)), ] assert Avects == ([], algebraic_eigenvects) # Test converting to Expr: sympy_eigenvects = [ (S(5) / 2 - sqrt(33) / 2, 1, [Matrix([[-sqrt(33) / 6 - S(1) / 2], [1]])]), (S(5) / 2 + sqrt(33) / 2, 1, [Matrix([[-S(1) / 2 + sqrt(33) / 6], [1]])]), ] assert dom_eigenvects_to_sympy([], algebraic_eigenvects, Matrix) == sympy_eigenvects
def test_dom_eigenvects_rootof(): # Algebraic eigenvalues A = DomainMatrix([[0, 0, 0, 0, -1], [1, 0, 0, 0, 1], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0]], (5, 5), QQ) Avects = dom_eigenvects(A) # Extract the dummy to build the expected result: lamda = Avects[1][0][1].gens[0] irreducible = Poly(lamda**5 - lamda + 1, lamda, domain=QQ) K = FiniteExtension(irreducible) KK = K.from_sympy algebraic_eigenvects = [ (K, irreducible, 1, DomainMatrix( [[KK(lamda**4 - 1), KK(lamda**3), KK(lamda**2), KK(lamda), KK(1)]], (1, 5), K)), ] assert Avects == ([], algebraic_eigenvects) # Test converting to Expr (slow): l0, l1, l2, l3, l4 = [CRootOf(lamda**5 - lamda + 1, i) for i in range(5)] sympy_eigenvects = [ (l0, 1, [Matrix([-1 + l0**4, l0**3, l0**2, l0, 1])]), (l1, 1, [Matrix([-1 + l1**4, l1**3, l1**2, l1, 1])]), (l2, 1, [Matrix([-1 + l2**4, l2**3, l2**2, l2, 1])]), (l3, 1, [Matrix([-1 + l3**4, l3**3, l3**2, l3, 1])]), (l4, 1, [Matrix([-1 + l4**4, l4**3, l4**2, l4, 1])]), ] assert dom_eigenvects_to_sympy([], algebraic_eigenvects, Matrix) == sympy_eigenvects
def test_DomainMatrix_eq(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) assert A == A B = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(1)]], (2, 2), ZZ) assert A != B C = [[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]] assert A != C
def test_DomainMatrix_get_domain(): K, items = DomainMatrix.get_domain([1, 2, 3, 4]) assert items == [ZZ(1), ZZ(2), ZZ(3), ZZ(4)] assert K == ZZ K, items = DomainMatrix.get_domain([1, 2, 3, Rational(1, 2)]) assert items == [QQ(1), QQ(2), QQ(3), QQ(1, 2)] assert K == QQ
def test_DomainMatrix_to_dok(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) assert A.to_dok() == { (0, 0): ZZ(1), (0, 1): ZZ(2), (1, 0): ZZ(3), (1, 1): ZZ(4) }
def test_DomainMatrix_setitem(): dM = DomainMatrix({2: {2: ZZ(1)}, 4: {4: ZZ(1)}}, (5, 5), ZZ) dM[2, 2] = ZZ(2) assert dM == DomainMatrix({2: {2: ZZ(2)}, 4: {4: ZZ(1)}}, (5, 5), ZZ) def setitem(i, j, val): dM[i, j] = val raises(TypeError, lambda: setitem(2, 2, QQ(1, 2))) raises(NotImplementedError, lambda: setitem(slice(1, 2), 2, ZZ(1)))
def test_DomainMatrix_scalarmul(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) lamda = DomainScalar(QQ(3)/QQ(2), QQ) assert A * lamda == DomainMatrix([[QQ(3, 2), QQ(3)], [QQ(9, 2), QQ(6)]], (2, 2), QQ) assert A * 2 == DomainMatrix([[ZZ(2), ZZ(4)], [ZZ(6), ZZ(8)]], (2, 2), ZZ) assert A * DomainScalar(ZZ(0), ZZ) == DomainMatrix([[ZZ(0)]*2]*2, (2, 2), ZZ) assert A * DomainScalar(ZZ(1), ZZ) == A raises(TypeError, lambda: A * 1.5)
def test_DomainMatrix_scc(): Ad = DomainMatrix( [[ZZ(1), ZZ(2), ZZ(3)], [ZZ(0), ZZ(1), ZZ(0)], [ZZ(2), ZZ(0), ZZ(4)]], (3, 3), ZZ) As = Ad.to_sparse() Addm = Ad.rep Asdm = As.rep for A in [Ad, As, Addm, Asdm]: assert Ad.scc() == [[1], [0, 2]]
def test_DomainMatrix_init(): lol = [[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]] dod = {0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}} ddm = DDM(lol, (2, 2), ZZ) sdm = SDM(dod, (2, 2), ZZ) A = DomainMatrix(lol, (2, 2), ZZ) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ A = DomainMatrix(dod, (2, 2), ZZ) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == ZZ raises(TypeError, lambda: DomainMatrix(ddm, (2, 2), ZZ)) raises(TypeError, lambda: DomainMatrix(sdm, (2, 2), ZZ)) raises(TypeError, lambda: DomainMatrix(Matrix([[1]]), (1, 1), ZZ)) for fmt, rep in [('sparse', sdm), ('dense', ddm)]: A = DomainMatrix(lol, (2, 2), ZZ, fmt=fmt) assert A.rep == rep A = DomainMatrix(dod, (2, 2), ZZ, fmt=fmt) assert A.rep == rep raises(ValueError, lambda: DomainMatrix(lol, (2, 2), ZZ, fmt='invalid')) raises(DMBadInputError, lambda: DomainMatrix([[ZZ(1), ZZ(2)]], (2, 2), ZZ))
def test_DomainMatrix_truediv(): A = DomainMatrix.from_Matrix(Matrix([[1, 2], [3, 4]])) lamda = DomainScalar(QQ(3) / QQ(2), QQ) assert A / lamda == DomainMatrix( { 0: { 0: QQ(2, 3), 1: QQ(4, 3) }, 1: { 0: QQ(2), 1: QQ(8, 3) } }, (2, 2), QQ) b = DomainScalar(ZZ(1), ZZ) assert A / b == DomainMatrix( { 0: { 0: QQ(1), 1: QQ(2) }, 1: { 0: QQ(3), 1: QQ(4) } }, (2, 2), QQ) assert A / 1 == DomainMatrix( { 0: { 0: QQ(1), 1: QQ(2) }, 1: { 0: QQ(3), 1: QQ(4) } }, (2, 2), QQ) assert A / 2 == DomainMatrix( { 0: { 0: QQ(1, 2), 1: QQ(1) }, 1: { 0: QQ(3, 2), 1: QQ(2) } }, (2, 2), QQ) raises(ZeroDivisionError, lambda: A / 0) raises(TypeError, lambda: A / 1.5) raises(ZeroDivisionError, lambda: A / DomainScalar(ZZ(0), ZZ))
def test_DomainMatrix_solve(): # XXX: Maybe the _solve method should be changed... A = DomainMatrix([[QQ(1), QQ(2)], [QQ(2), QQ(4)]], (2, 2), QQ) b = DomainMatrix([[QQ(1)], [QQ(2)]], (2, 1), QQ) particular = DomainMatrix([[1, 0]], (1, 2), QQ) nullspace = DomainMatrix([[-2, 1]], (1, 2), QQ) assert A._solve(b) == (particular, nullspace) b3 = DomainMatrix([[QQ(1)], [QQ(1)], [QQ(1)]], (3, 1), QQ) raises(DMShapeError, lambda: A._solve(b3)) bz = DomainMatrix([[ZZ(1)], [ZZ(1)]], (2, 1), ZZ) raises(DMNotAField, lambda: A._solve(bz))
def test_DomainMatrix_from_rep(): ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A = DomainMatrix.from_rep(ddm) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ sdm = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) A = DomainMatrix.from_rep(sdm) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == ZZ A = DomainMatrix([[ZZ(1)]], (1, 1), ZZ) raises(TypeError, lambda: DomainMatrix.from_rep(A))
def test_DomainMatrix_from_rep(): # ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) ddm = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) A = DomainMatrix.from_rep(ddm) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ
def test_dom_eigenvects_rational(): # Rational eigenvalues A = DomainMatrix([[QQ(1), QQ(2)], [QQ(1), QQ(2)]], (2, 2), QQ) rational_eigenvects = [ (QQ, QQ(3), 1, DomainMatrix([[QQ(1), QQ(1)]], (1, 2), QQ)), (QQ, QQ(0), 1, DomainMatrix([[QQ(-2), QQ(1)]], (1, 2), QQ)), ] assert dom_eigenvects(A) == (rational_eigenvects, []) # Test converting to Expr: sympy_eigenvects = [ (S(3), 1, [Matrix([1, 1])]), (S(0), 1, [Matrix([-2, 1])]), ] assert dom_eigenvects_to_sympy(rational_eigenvects, [], Matrix) == sympy_eigenvects
def test_DomainMatrix_from_Matrix(): ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A = DomainMatrix.from_Matrix(Matrix([[1, 2], [3, 4]])) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ K = QQ.algebraic_field(sqrt(2)) ddm = DDM([[ K.convert(1 + sqrt(2)), K.convert(2 + sqrt(2)) ], [K.convert(3 + sqrt(2)), K.convert(4 + sqrt(2))]], (2, 2), K) A = DomainMatrix.from_Matrix(Matrix([[1 + sqrt(2), 2 + sqrt(2)], [3 + sqrt(2), 4 + sqrt(2)]]), extension=True) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == K
def test_DomainMatrix_rowspace(): A = DomainMatrix( [[QQ(1), QQ(-1), QQ(1)], [QQ(2), QQ(-2), QQ(3)]], (2, 3), QQ) assert A.rowspace() == A Az = DomainMatrix( [[ZZ(1), ZZ(-1), ZZ(1)], [ZZ(2), ZZ(-2), ZZ(3)]], (2, 3), ZZ) raises(DMNotAField, lambda: Az.rowspace()) A = DomainMatrix( [[QQ(1), QQ(-1), QQ(1)], [QQ(2), QQ(-2), QQ(3)]], (2, 3), QQ, fmt='sparse') assert A.rowspace() == A
def test_DomainMatrix_nullspace(): A = DomainMatrix([[QQ(1), QQ(1)], [QQ(1), QQ(1)]], (2, 2), QQ) Anull = DomainMatrix([[QQ(-1), QQ(1)]], (1, 2), QQ) assert A.nullspace() == Anull Az = DomainMatrix([[ZZ(1), ZZ(1)], [ZZ(1), ZZ(1)]], (2, 2), ZZ) raises(DMNotAField, lambda: Az.nullspace())
def test_DomainScalar_mul(): A = DomainScalar(ZZ(1), ZZ) B = DomainScalar(QQ(2), QQ) dm = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) assert A * B == DomainScalar(QQ(2), QQ) assert A * dm == dm assert B * 2 == DomainScalar(QQ(4), QQ) raises(TypeError, lambda: A * 1.5)
def test_DomainMatrix_unify_eq(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) B1 = DomainMatrix([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], (2, 2), QQ) B2 = DomainMatrix([[QQ(1), QQ(3)], [QQ(3), QQ(4)]], (2, 2), QQ) B3 = DomainMatrix([[ZZ(1)]], (1, 1), ZZ) assert A.unify_eq(B1) is True assert A.unify_eq(B2) is False assert A.unify_eq(B3) is False
def test_DomainMatrix_from_list(): ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A = DomainMatrix.from_list([[1, 2], [3, 4]], ZZ) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ dom = FF(7) ddm = DDM([[dom(1), dom(2)], [dom(3), dom(4)]], (2, 2), dom) A = DomainMatrix.from_list([[1, 2], [3, 4]], dom) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == dom ddm = DDM([[QQ(1, 2), QQ(3, 1)], [QQ(1, 4), QQ(5, 1)]], (2, 2), QQ) A = DomainMatrix.from_list([[(1, 2), (3, 1)], [(1, 4), (5, 1)]], QQ) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == QQ
def test_DomainMatrix_pow(): eye = DomainMatrix.eye(2, ZZ) A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) A2 = DomainMatrix([[ZZ(7), ZZ(10)], [ZZ(15), ZZ(22)]], (2, 2), ZZ) A3 = DomainMatrix([[ZZ(37), ZZ(54)], [ZZ(81), ZZ(118)]], (2, 2), ZZ) assert A**0 == A.pow(0) == eye assert A**1 == A.pow(1) == A assert A**2 == A.pow(2) == A2 assert A**3 == A.pow(3) == A3 raises(TypeError, lambda: A**Rational(1, 2)) raises(NotImplementedError, lambda: A**-1) raises(NotImplementedError, lambda: A.pow(-1)) A = DomainMatrix.zeros((2, 1), ZZ) raises(DMNonSquareMatrixError, lambda: A**1)
def test_DomainMatrix_from_list_sympy(): # ddm = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) ddm = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) A = DomainMatrix.from_list_sympy(2, 2, [[1, 2], [3, 4]]) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == ZZ K = QQ.algebraic_field(sqrt(2)) ddm = DDM([[ K.convert(1 + sqrt(2)), K.convert(2 + sqrt(2)) ], [K.convert(3 + sqrt(2)), K.convert(4 + sqrt(2))]], (2, 2), K) ddm = SDM.from_ddm(ddm) A = DomainMatrix.from_list_sympy( 2, 2, [[1 + sqrt(2), 2 + sqrt(2)], [3 + sqrt(2), 4 + sqrt(2)]], extension=True) assert A.rep == ddm assert A.shape == (2, 2) assert A.domain == K
def test_DomainMatrix_from_dict_sympy(): sdm = SDM({0: {0: QQ(1, 2)}, 1: {1: QQ(2, 3)}}, (2, 2), QQ) sympy_dict = {0: {0: Rational(1, 2)}, 1: {1: Rational(2, 3)}} A = DomainMatrix.from_dict_sympy(2, 2, sympy_dict) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == QQ fds = DomainMatrix.from_dict_sympy raises(DMBadInputError, lambda: fds(2, 2, {3: {0: Rational(1, 2)}})) raises(DMBadInputError, lambda: fds(2, 2, {0: {3: Rational(1, 2)}}))
def test_DomainMatrix_vstack(): A = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) B = DomainMatrix([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ) C = DomainMatrix([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ) AB = DomainMatrix( [[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)], [ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (4, 2), ZZ) ABC = DomainMatrix( [[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)], [ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)], [ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (6, 2), ZZ) assert A.vstack(B) == AB assert A.vstack(B, C) == ABC
def test_DomainMatrix_unify(): Az = DomainMatrix([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) Aq = DomainMatrix([[QQ(1), QQ(2)], [QQ(3), QQ(4)]], (2, 2), QQ) assert Az.unify(Az) == (Az, Az) assert Az.unify(Aq) == (Aq, Aq) assert Aq.unify(Az) == (Aq, Aq) assert Aq.unify(Aq) == (Aq, Aq)
def test_DomainMatrix_from_dict_sympy(): sdm = SDM({0: {0: QQ(1, 2)}, 1: {1: QQ(2, 3)}}, (2, 2), QQ) A = DomainMatrix.from_dict_sympy(2, 2, { 0: { 0: QQ(1, 2) }, 1: { 1: QQ(2, 3) } }) assert A.rep == sdm assert A.shape == (2, 2) assert A.domain == QQ
def _compute_test_factor(p, gens, ZK): r""" Compute the test factor for a :py:class:`~.PrimeIdeal` $\mathfrak{p}$. Parameters ========== p : int The rational prime $\mathfrak{p}$ divides gens : list of :py:class:`PowerBasisElement` A complete set of generators for $\mathfrak{p}$ over *ZK*, EXCEPT that an element equivalent to rational *p* can and should be omitted (since it has no effect except to waste time). ZK : :py:class:`~.Submodule` The maximal order where the prime ideal $\mathfrak{p}$ lives. Returns ======= :py:class:`~.PowerBasisElement` References ========== .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.* (See Proposition 4.8.15.) """ _check_formal_conditions_for_maximal_order(ZK) E = ZK.endomorphism_ring() matrices = [E.inner_endomorphism(g).matrix(modulus=p) for g in gens] B = DomainMatrix.zeros((0, ZK.n), FF(p)).vstack(*matrices) # A nonzero element of the nullspace of B will represent a # lin comb over the omegas which (i) is not a multiple of p # (since it is nonzero over FF(p)), while (ii) is such that # its product with each g in gens _is_ a multiple of p (since # B represents multiplication by these generators). Theory # predicts that such an element must exist, so nullspace should # be non-trivial. x = B.nullspace()[0, :].transpose() beta = ZK.parent(ZK.matrix * x, denom=ZK.denom) return beta
def _det_DOM(M): DOM = DomainMatrix.from_Matrix(M, field=True, extension=True) K = DOM.domain return K.to_sympy(DOM.det())