From 97894ffd47a2a76eeca98c5253cacba9136b14c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 22:10:49 -0700 Subject: [PATCH 01/99] src/sage/matrix/special.py: Do not fail if numpy cannot be imported --- src/sage/matrix/special.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index b85a4d29777..ba6eda71d66 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -852,8 +852,14 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): entries = arg0 # sanity check for entries - from numpy import ndarray - if not isinstance(entries, (list, tuple, ndarray)): + types = (list, tuple) + try: + from numpy import ndarray + except ImportError: + pass + else: + types += (ndarray,) + if not isinstance(entries, types): entries = list(entries) # Reconcile matrix size and number of entries From 9da00c5dbcd748f2dae4c3447adb55cfd1a095d2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 22 Feb 2022 19:28:05 -0800 Subject: [PATCH 02/99] src/sage/modules/free_module_integer.py: Do not fail if OrderElement_absolute cannot be imported --- src/sage/modules/free_module_integer.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index 2e9db90bbe6..ef326ac0a7c 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -38,7 +38,11 @@ from sage.misc.cachefunc import cached_method from sage.modules.free_module import FreeModule_submodule_with_basis_pid, FreeModule_ambient_pid from sage.modules.free_module_element import vector -from sage.rings.number_field.number_field_element import OrderElement_absolute + +try: + from sage.rings.number_field.number_field_element import OrderElement_absolute +except ImportError: + OrderElement_absolute = () def IntegerLattice(basis, lll_reduce=True): From 514994a0f8816d4ea97eac35a3bc0ed0be397410 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 16 Feb 2023 20:41:12 -0800 Subject: [PATCH 03/99] src/sage/matrix/special.py: Mark doctests # optional - sage.symbolic --- src/sage/matrix/special.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index ba6eda71d66..840f4719b1c 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -7,7 +7,7 @@ For example, here is a circulant matrix of order five:: - sage: matrix.circulant(SR.var('a b c d e')) + sage: matrix.circulant(SR.var('a b c d e')) # optional - sage.symbolic [a b c d e] [e a b c d] [d e a b c] @@ -3484,7 +3484,7 @@ def vandermonde(v, ring=None): A Vandermonde matrix of order three over the symbolic ring:: - sage: matrix.vandermonde(SR.var(['x0', 'x1', 'x2'])) + sage: matrix.vandermonde(SR.var(['x0', 'x1', 'x2'])) # optional - sage.symbolic [ 1 x0 x0^2] [ 1 x1 x1^2] [ 1 x2 x2^2] @@ -3571,7 +3571,7 @@ def hankel(c, r=None, ring=None): A Hankel matrix with symbolic entries:: - sage: matrix.hankel(SR.var('a, b, c, d, e')) + sage: matrix.hankel(SR.var('a, b, c, d, e')) # optional - sage.symbolic [a b c d e] [b c d e 0] [c d e 0 0] @@ -3580,7 +3580,7 @@ def hankel(c, r=None, ring=None): We can also pass the elements of the last row, starting at the second column:: - sage: matrix.hankel(SR.var('a, b, c, d, e'), SR.var('f, g, h, i')) + sage: matrix.hankel(SR.var('a, b, c, d, e'), SR.var('f, g, h, i')) # optional - sage.symbolic [a b c d e] [b c d e f] [c d e f g] From 047b269f6fff730c21416c1a385720bbce53725c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 25 Feb 2023 17:45:51 -0800 Subject: [PATCH 04/99] sage.matrix: More # optional --- src/sage/matrix/constructor.pyx | 15 +- src/sage/matrix/matrix2.pyx | 914 +++++++++++++++++--------------- 2 files changed, 481 insertions(+), 448 deletions(-) diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index ae4652c45f8..692d58aff5b 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -185,10 +185,10 @@ def matrix(*args, **kwds): sage: m = matrix(v); m; m.parent() [ 1 10 100] Full MatrixSpace of 1 by 3 dense matrices over Integer Ring - sage: m = matrix(GF(7), v); m; m.parent() + sage: m = matrix(GF(7), v); m; m.parent() # optional - sage.libs.pari [1 3 2] Full MatrixSpace of 1 by 3 dense matrices over Finite Field of size 7 - sage: m = matrix(GF(7), 3, 1, v); m; m.parent() + sage: m = matrix(GF(7), 3, 1, v); m; m.parent() # optional - sage.libs.pari [1] [3] [2] @@ -196,15 +196,15 @@ def matrix(*args, **kwds): :: - sage: matrix(pari.mathilbert(3)) + sage: matrix(pari.mathilbert(3)) # optional - sage.libs.pari [ 1 1/2 1/3] [1/2 1/3 1/4] [1/3 1/4 1/5] :: - sage: g = graphs.PetersenGraph() - sage: m = matrix(g); m; m.parent() + sage: g = graphs.PetersenGraph() # optional - sage.graphs + sage: m = matrix(g); m; m.parent() # optional - sage.graphs [0 1 0 0 1 1 0 0 0 0] [1 0 1 0 0 0 1 0 0 0] [0 1 0 1 0 0 0 1 0 0] @@ -542,10 +542,11 @@ def matrix(*args, **kwds): sage: v = vector(ZZ, [1, 10, 100]) sage: m = matrix(ZZ['x'], v); m; m.parent() [ 1 10 100] - Full MatrixSpace of 1 by 3 dense matrices over Univariate Polynomial Ring in x over Integer Ring + Full MatrixSpace of 1 by 3 dense matrices + over Univariate Polynomial Ring in x over Integer Ring sage: matrix(ZZ, 10, 10, range(100)).parent() Full MatrixSpace of 10 by 10 dense matrices over Integer Ring - sage: m = matrix(GF(7), [[1/3,2/3,1/2], [3/4,4/5,7]]); m; m.parent() + sage: m = matrix(GF(7), [[1/3,2/3,1/2], [3/4,4/5,7]]); m; m.parent() # optional - sage.libs.pari [5 3 4] [6 5 0] Full MatrixSpace of 2 by 3 dense matrices over Finite Field of size 7 diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 2053bca80c3..dcbf73faa2a 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -391,9 +391,9 @@ cdef class Matrix(Matrix1): The vector of constants needs to be compatible with the base ring of the coefficient matrix:: - sage: F. = FiniteField(27) - sage: b = vector(F, [a,a,a,a,a]) - sage: A.solve_left(b) + sage: F. = FiniteField(27) # optional - sage.libs.pari + sage: b = vector(F, [a,a,a,a,a]) # optional - sage.libs.pari + sage: A.solve_left(b) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: ... @@ -777,9 +777,9 @@ cdef class Matrix(Matrix1): The vector of constants needs to be compatible with the base ring of the coefficient matrix. :: - sage: F. = FiniteField(27) - sage: b = vector(F, [a,a,a,a,a]) - sage: A.solve_right(b) + sage: F. = FiniteField(27) # optional - sage.libs.pari + sage: b = vector(F, [a,a,a,a,a]) # optional - sage.libs.pari + sage: A.solve_right(b) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: ... @@ -1131,14 +1131,15 @@ cdef class Matrix(Matrix1): :: - sage: G = matrix(GF(3),2,[0,1,2,2]) - sage: H = matrix(ZZ,2,[1,2,3,4]) - sage: J = G.elementwise_product(H) - sage: J + sage: G = matrix(GF(3), 2, [0, 1, 2, 2]) # optional - sage.libs.pari + sage: H = matrix(ZZ, 2, [1, 2, 3, 4]) + sage: J = G.elementwise_product(H) # optional - sage.libs.pari + sage: J # optional - sage.libs.pari [0 2] [0 2] - sage: J.parent() - Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 + sage: J.parent() # optional - sage.libs.pari + Full MatrixSpace of 2 by 2 dense matrices + over Finite Field of size 3 Non-commutative rings behave as expected. These are the usual quaternions. :: @@ -1179,11 +1180,13 @@ cdef class Matrix(Matrix1): multiplication makes sense. This will raise an error. :: sage: A = matrix(QQ, 3, 2, range(6)) - sage: B = matrix(GF(3), 3, [2]*6) - sage: A.elementwise_product(B) + sage: B = matrix(GF(3), 3, [2]*6) # optional - sage.libs.pari + sage: A.elementwise_product(B) # optional - sage.libs.pari Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' and 'Full MatrixSpace of 3 by 2 dense matrices over Finite Field of size 3' + TypeError: no common canonical parent for objects with parents: + 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' and + 'Full MatrixSpace of 3 by 2 dense matrices over Finite Field of size 3' We illustrate various combinations of sparse and dense matrices. The usual coercion rules apply:: @@ -1758,20 +1761,20 @@ cdef class Matrix(Matrix1): An example with an exotic matrix (for which only Butera-Pernici and Ryser algorithms are available):: - sage: R. = PolynomialRing(GF(5)) - sage: A = matrix(R,[[1,x,y],[x*y,x**2+y,0]]) - sage: A.rook_vector(algorithm="ButeraPernici") + sage: R. = PolynomialRing(GF(5)) # optional - sage.libs.pari + sage: A = matrix(R, [[1, x, y], [x*y, x**2+y, 0]]) # optional - sage.libs.pari + sage: A.rook_vector(algorithm="ButeraPernici") # optional - sage.libs.pari [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: A.rook_vector(algorithm="Ryser") + sage: A.rook_vector(algorithm="Ryser") # optional - sage.libs.pari [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: A.rook_vector(algorithm="Godsil") + sage: A.rook_vector(algorithm="Godsil") # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: coefficients must be zero or one, but we have 'x' in position (0,1). - sage: B = A.transpose() - sage: B.rook_vector(algorithm="ButeraPernici") + sage: B = A.transpose() # optional - sage.libs.pari + sage: B.rook_vector(algorithm="ButeraPernici") # optional - sage.libs.pari [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: B.rook_vector(algorithm="Ryser") + sage: B.rook_vector(algorithm="Ryser") # optional - sage.libs.pari [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] TESTS:: @@ -1914,11 +1917,13 @@ cdef class Matrix(Matrix1): :: - sage: k = GF(37) - sage: P. = PolynomialRing(k) - sage: A = Matrix(P,2,3,[x0*x1, x0, x1, x2, x2 + 16, x2 + 5*x1 ]) - sage: A.minors(2) - [x0*x1*x2 + 16*x0*x1 - x0*x2, 5*x0*x1^2 + x0*x1*x2 - x1*x2, 5*x0*x1 + x0*x2 - x1*x2 - 16*x1] + sage: k = GF(37) # optional - sage.libs.pari + sage: P. = PolynomialRing(k) # optional - sage.libs.pari + sage: A = Matrix(P, 2, 3, [x0*x1, x0, x1, x2, x2 + 16, x2 + 5*x1]) # optional - sage.libs.pari + sage: A.minors(2) # optional - sage.libs.pari + [x0*x1*x2 + 16*x0*x1 - x0*x2, + 5*x0*x1^2 + x0*x1*x2 - x1*x2, + 5*x0*x1 + x0*x2 - x1*x2 - 16*x1] This test addresses an issue raised at :trac:`20512`:: @@ -2021,8 +2026,8 @@ cdef class Matrix(Matrix1): We verify that :trac:`5569` is resolved (otherwise the following would hang for hours):: - sage: d = random_matrix(GF(next_prime(10^20)),50).det() - sage: d = random_matrix(Integers(10^50),50).det() + sage: d = random_matrix(GF(next_prime(10^20)), 50).det() # optional - sage.libs.pari + sage: d = random_matrix(Integers(10^50), 50).det() # optional - sage.libs.pari We verify that :trac:`7704` is resolved:: @@ -2033,15 +2038,20 @@ cdef class Matrix(Matrix1): We verify that :trac:`10063` is resolved:: - sage: A = GF(2)['x,y,z'] - sage: A.inject_variables() + sage: A = GF(2)['x,y,z'] # optional - sage.libs.pari + sage: A.inject_variables() # optional - sage.libs.pari Defining x, y, z - sage: R = A.quotient(x^2 + 1).quotient(y^2 + 1).quotient(z^2 + 1) - sage: R.inject_variables() + sage: R = A.quotient(x^2 + 1).quotient(y^2 + 1).quotient(z^2 + 1) # optional - sage.libs.pari + sage: R.inject_variables() # optional - sage.libs.pari Defining xbarbarbar, ybarbarbar, zbarbarbar - sage: M = matrix([[1,1,1,1],[xbarbarbar,ybarbarbar,1,1],[0,1,zbarbarbar,1],[xbarbarbar,zbarbarbar,1,1]]) - sage: M.determinant() - xbarbarbar*ybarbarbar*zbarbarbar + xbarbarbar*ybarbarbar + xbarbarbar*zbarbarbar + ybarbarbar*zbarbarbar + xbarbarbar + ybarbarbar + zbarbarbar + 1 + sage: M = matrix([[1, 1, 1, 1], # optional - sage.libs.pari + ....: [xbarbarbar, ybarbarbar, 1, 1], + ....: [0, 1, zbarbarbar, 1], + ....: [xbarbarbar, zbarbarbar, 1, 1]]) + sage: M.determinant() # optional - sage.libs.pari + xbarbarbar*ybarbarbar*zbarbarbar + xbarbarbar*ybarbarbar + + xbarbarbar*zbarbarbar + ybarbarbar*zbarbarbar + xbarbarbar + + ybarbarbar + zbarbarbar + 1 Check that the determinant is computed from a cached charpoly properly:: @@ -2222,17 +2232,17 @@ cdef class Matrix(Matrix1): sage: A.quantum_determinant(q^-2) 7*q^-6 + q^-4 + q^-2 + 5 - sage: S. = PolynomialRing(GF(7)) - sage: R. = LaurentPolynomialRing(S) - sage: MS = MatrixSpace(S, 3, sparse=True) - sage: A = MS([[x, y, 3], [4, 2+y, x^2], [0, 1-x, x+y]]) - sage: A.det() + sage: S. = PolynomialRing(GF(7)) # optional - sage.libs.pari + sage: R. = LaurentPolynomialRing(S) # optional - sage.libs.pari + sage: MS = MatrixSpace(S, 3, sparse=True) # optional - sage.libs.pari + sage: A = MS([[x, y, 3], [4, 2+y, x^2], [0, 1-x, x+y]]) # optional - sage.libs.pari + sage: A.det() # optional - sage.libs.pari x^4 - x^3 + x^2*y + x*y^2 + 2*x^2 - 2*x*y + 3*y^2 + 2*x - 2 - sage: A.quantum_determinant() + sage: A.quantum_determinant() # optional - sage.libs.pari (2*x - 2)*q^2 + (x^4 - x^3 + 3*x*y + 3*y^2)*q + x^2*y + x*y^2 + 2*x^2 + 2*x*y - sage: A.quantum_determinant(int(2)) + sage: A.quantum_determinant(int(2)) # optional - sage.libs.pari 2*x^4 - 2*x^3 + x^2*y + x*y^2 + 2*x^2 + x*y - y^2 + x - 1 - sage: A.quantum_determinant(q*x + q^-1*y) + sage: A.quantum_determinant(q*x + q^-1*y) # optional - sage.libs.pari (2*x*y^2 - 2*y^2)*q^-2 + (x^4*y - x^3*y + 3*x*y^2 + 3*y^3)*q^-1 + (-2*x^2*y + x*y^2 + 2*x^2 - 2*x*y) + (x^5 - x^4 + 3*x^2*y + 3*x*y^2)*q + (2*x^3 - 2*x^2)*q^2 @@ -2400,13 +2410,13 @@ cdef class Matrix(Matrix1): In order to use the Bär-Faddeev-LeVerrier algorithm, the base ring must have characteristic zero:: - sage: A = matrix(GF(5), [(0, 3, 4, 1, 3, 4), + sage: A = matrix(GF(5), [(0, 3, 4, 1, 3, 4), # optional - sage.libs.pari ....: (2, 0, 2, 0, 1, 0), ....: (1, 3, 0, 4, 1, 0), ....: (4, 0, 1, 0, 2, 0), ....: (2, 4, 4, 3, 0, 0), ....: (1, 0, 0, 0, 0, 0)]) - sage: A.pfaffian(algorithm='bfl') + sage: A.pfaffian(algorithm='bfl') # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: Bär-Faddeev-LeVerrier algorithm not applicable, @@ -2414,7 +2424,7 @@ cdef class Matrix(Matrix1): In that case, the definition by perfect matchings is used instead:: - sage: A.pfaffian() + sage: A.pfaffian() # optional - sage.libs.pari 2 """ @@ -2602,13 +2612,14 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: m = matrix(ZZ, 3, 3, range(9)) - sage: phi = ZZ.hom(GF(5)) - sage: m.apply_morphism(phi) + sage: phi = ZZ.hom(GF(5)) # optional - sage.libs.pari + sage: m.apply_morphism(phi) # optional - sage.libs.pari [0 1 2] [3 4 0] [1 2 3] - sage: parent(m.apply_morphism(phi)) - Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 5 + sage: parent(m.apply_morphism(phi)) # optional - sage.libs.pari + Full MatrixSpace of 3 by 3 dense matrices + over Finite Field of size 5 We apply a morphism to a matrix over a polynomial ring:: @@ -2650,27 +2661,29 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: m = matrix(ZZ, 3, 3, range(9)) - sage: k. = GF(9) - sage: f = lambda x: k(x) - sage: n = m.apply_map(f); n + sage: k. = GF(9) # optional - sage.libs.pari + sage: f = lambda x: k(x) # optional - sage.libs.pari + sage: n = m.apply_map(f); n # optional - sage.libs.pari [0 1 2] [0 1 2] [0 1 2] - sage: n.parent() - Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 + sage: n.parent() # optional - sage.libs.pari + Full MatrixSpace of 3 by 3 dense matrices + over Finite Field in a of size 3^2 In this example, we explicitly specify the codomain. :: - sage: s = GF(3) - sage: f = lambda x: s(x) - sage: n = m.apply_map(f, k); n + sage: s = GF(3) # optional - sage.libs.pari + sage: f = lambda x: s(x) # optional - sage.libs.pari + sage: n = m.apply_map(f, k); n # optional - sage.libs.pari [0 1 2] [0 1 2] [0 1 2] - sage: n.parent() - Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 + sage: n.parent() # optional - sage.libs.pari + Full MatrixSpace of 3 by 3 dense matrices + over Finite Field in a of size 3^2 If self is subdivided, the result will be as well:: @@ -2792,12 +2805,12 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(GF(9,'c'), 4, [1, 1, 0,0, 0,1,0,0, 0,0,5,0, 0,0,0,5]) - sage: factor(A.minpoly()) + sage: A = matrix(GF(9, 'c'), 4, [1,1,0,0, 0,1,0,0, 0,0,5,0, 0,0,0,5]) # optional - sage.libs.pari + sage: factor(A.minpoly()) # optional - sage.libs.pari (x + 1) * (x + 2)^2 - sage: A.minpoly()(A) == 0 + sage: A.minpoly()(A) == 0 # optional - sage.libs.pari True - sage: factor(A.charpoly()) + sage: factor(A.charpoly()) # optional - sage.libs.pari (x + 1)^2 * (x + 2)^2 The default variable name is `x`, but you can specify @@ -3274,14 +3287,14 @@ cdef class Matrix(Matrix1): Here's an example involving a cyclotomic field:: - sage: K. = CyclotomicField(3) - sage: M = MatrixSpace(K,3,sparse=True) - sage: A = M([(1+z)/3,(2+z)/3,z/3,1,1+z,-2,1,5,-1+z]) - sage: print(A) + sage: K. = CyclotomicField(3) # optional - sage.rings.number_field + sage: M = MatrixSpace(K, 3, sparse=True) # optional - sage.rings.number_field + sage: A = M([(1+z)/3, (2+z)/3, z/3, 1, 1+z, -2, 1, 5, -1+z]) # optional - sage.rings.number_field + sage: print(A) # optional - sage.rings.number_field [1/3*z + 1/3 1/3*z + 2/3 1/3*z] [ 1 z + 1 -2] [ 1 5 z - 1] - sage: print(A.denominator()) + sage: print(A.denominator()) # optional - sage.rings.number_field 3 """ if self.nrows() == 0 or self.ncols() == 0: @@ -3557,7 +3570,7 @@ cdef class Matrix(Matrix1): Z^3 - 12*Z^2 - 18*Z sage: matrix(ZZ,3,3,range(9))._charpoly_hessenberg('Z') Z^3 - 12*Z^2 - 18*Z - sage: matrix(GF(7),3,3,range(9))._charpoly_hessenberg('Z') + sage: matrix(GF(7), 3, 3,range(9))._charpoly_hessenberg('Z') # optional - sage.libs.pari Z^3 + 2*Z^2 + 3*Z sage: matrix(QQ['x'],3,3,range(9))._charpoly_hessenberg('Z') Z^3 - 12*Z^2 - 18*Z @@ -3684,7 +3697,7 @@ cdef class Matrix(Matrix1): OUTPUT: - Returns a pair. First item is the string 'pivot-pari-numberfield' + Returns a pair. First item is the string ``'pivot-pari-numberfield'`` that identifies the nature of the basis vectors. Second item is a matrix whose rows are a basis for the right kernel, @@ -3692,32 +3705,34 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[ 2, 5-a, 15-a], + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[ 2, 5-a, 15-a], # optional - sage.rings.number_field ....: [2+a, a, -7 + 5*a]]) - sage: result = A._right_kernel_matrix_over_number_field() - sage: result[0] + sage: result = A._right_kernel_matrix_over_number_field() # optional - sage.rings.number_field, sage.libs.pari + sage: result[0] # optional - sage.rings.number_field, sage.libs.pari 'pivot-pari-numberfield' - sage: P = result[1]; P + sage: P = result[1]; P # optional - sage.rings.number_field, sage.libs.pari [-a -3 1] - sage: A*P.transpose() == zero_matrix(Q, 2, 1) + sage: A*P.transpose() == zero_matrix(Q, 2, 1) # optional - sage.rings.number_field, sage.libs.pari True TESTS: We test some trivial cases. :: - sage: Q = QuadraticField(-7) - sage: A = matrix(Q, 0, 2) - sage: A._right_kernel_matrix_over_number_field()[1] + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: A = matrix(Q, 0, 2) # optional - sage.rings.number_field + sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field, sage.libs.pari [1 0] [0 1] - sage: A = matrix(Q, 2, 0) - sage: A._right_kernel_matrix_over_number_field()[1].parent() - Full MatrixSpace of 0 by 0 dense matrices over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I - sage: A = zero_matrix(Q, 4, 3) - sage: A._right_kernel_matrix_over_number_field()[1] + sage: A = matrix(Q, 2, 0) # optional - sage.rings.number_field, sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1].parent() # optional - sage.rings.number_field, sage.libs.pari + Full MatrixSpace of 0 by 0 dense matrices + over Number Field in a with defining polynomial x^2 + 7 + with a = 2.645751311064591?*I + sage: A = zero_matrix(Q, 4, 3) # optional - sage.rings.number_field, sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field, sage.libs.pari [1 0 0] [0 1 0] [0 0 1] @@ -3746,34 +3761,35 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: C = CyclotomicField(14) - sage: a = C.gen(0) - sage: A = matrix(C, 3, 4, [[ 1, a, 1+a, a^3+a^5], + sage: C = CyclotomicField(14) # optional - sage.rings.number_field + sage: a = C.gen(0) # optional - sage.rings.number_field + sage: A = matrix(C, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.rings.number_field ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: result = A._right_kernel_matrix_over_field() - sage: result[0] + sage: result = A._right_kernel_matrix_over_field() # optional - sage.rings.number_field + sage: result[0] # optional - sage.rings.number_field 'pivot-generic' - sage: P = result[1]; P + sage: P = result[1]; P # optional - sage.rings.number_field [ -1 -1 1 0] [-zeta14^3 -zeta14^4 0 1] - sage: A*P.transpose() == zero_matrix(C, 3, 2) + sage: A*P.transpose() == zero_matrix(C, 3, 2) # optional - sage.rings.number_field True TESTS: We test some trivial cases. :: - sage: C = CyclotomicField(14) - sage: A = matrix(C, 0, 2) - sage: A._right_kernel_matrix_over_field()[1] + sage: C = CyclotomicField(14) # optional - sage.rings.number_field + sage: A = matrix(C, 0, 2) # optional - sage.rings.number_field + sage: A._right_kernel_matrix_over_field()[1] # optional - sage.rings.number_field [1 0] [0 1] - sage: A = matrix(C, 2, 0) - sage: A._right_kernel_matrix_over_field()[1].parent() - Full MatrixSpace of 0 by 0 dense matrices over Cyclotomic Field of order 14 and degree 6 - sage: A = zero_matrix(C, 4, 3) - sage: A._right_kernel_matrix_over_field()[1] + sage: A = matrix(C, 2, 0) # optional - sage.rings.number_field + sage: A._right_kernel_matrix_over_field()[1].parent() # optional - sage.rings.number_field + Full MatrixSpace of 0 by 0 dense matrices + over Cyclotomic Field of order 14 and degree 6 + sage: A = zero_matrix(C, 4, 3) # optional - sage.rings.number_field + sage: A._right_kernel_matrix_over_field()[1] # optional - sage.rings.number_field [1 0 0] [0 1 0] [0 0 1] @@ -4053,47 +4069,47 @@ cdef class Matrix(Matrix1): basis, so the `basis` keywords 'computed' and 'pivot' will return the same results. :: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], # optional - sage.rings.number_field ....: [2+a, a, -7 + 5*a, -3+3*a]]) - sage: C = A.right_kernel_matrix(algorithm='default', basis='computed'); C + sage: C = A.right_kernel_matrix(algorithm='default', basis='computed'); C # optional - sage.rings.number_field [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*C.transpose() == zero_matrix(Q, 2, 2) + sage: A*C.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True - sage: P = A.right_kernel_matrix(algorithm='pari', basis='pivot'); P + sage: P = A.right_kernel_matrix(algorithm='pari', basis='pivot'); P # optional - sage.rings.number_field, sage.libs.pari [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*P.transpose() == zero_matrix(Q, 2, 2) + sage: A*P.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field, sage.libs.pari True - sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E + sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E # optional - sage.rings.number_field [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: A*E.transpose() == zero_matrix(Q, 2, 2) + sage: A*E.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True We can bypass using PARI for number fields and use Sage's general code for matrices over any field. The basis vectors as computed are in pivot format. :: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a],[2+a, a, -7 + 5*a, -3+3*a]]) - sage: G = A.right_kernel_matrix(algorithm='generic', basis='computed'); G + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a],[2+a, a, -7 + 5*a, -3+3*a]]) # optional - sage.rings.number_field + sage: G = A.right_kernel_matrix(algorithm='generic', basis='computed'); G # optional - sage.rings.number_field [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*G.transpose() == zero_matrix(Q, 2, 2) + sage: A*G.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True We check that number fields are handled by the right routine as part of typical right kernel computation. :: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a],[2+a, a, -7 + 5*a, -3+3*a]]) + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a],[2+a, a, -7 + 5*a, -3+3*a]]) # optional - sage.rings.number_field sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') + sage: A.right_kernel(algorithm='default') # optional - sage.rings.number_field verbose ... verbose 1 () computing right kernel matrix over a number field for 2x4 matrix verbose 1 () done computing right kernel matrix over a number field for 2x4 matrix @@ -4111,15 +4127,15 @@ cdef class Matrix(Matrix1): :meth:`~sage.matrix.matrix_mod2_dense.Matrix_mod2_dense._right_kernel_matrix` method. There are no options for the algorithm used. :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], + sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], # optional - sage.libs.pari ....: [1, 0, 0, 0, 1, 1,], ....: [1, 0, 0, 0, 1, 1]]) - sage: E = A.right_kernel_matrix(algorithm='default', format='echelon'); E + sage: E = A.right_kernel_matrix(algorithm='default', format='echelon'); E # optional - sage.libs.pari [1 0 0 0 0 1] [0 1 1 0 0 0] [0 0 0 1 0 0] [0 0 0 0 1 1] - sage: A*E.transpose() == zero_matrix(GF(2), 3, 4) + sage: A*E.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.libs.pari True Since GF(2) is a field we can route this computation to the generic @@ -4127,24 +4143,24 @@ cdef class Matrix(Matrix1): keywords, 'pluq', 'default' and unspecified, all have the same effect as there is no optional behavior. :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], + sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], # optional - sage.libs.pari ....: [1, 0, 0, 0, 1, 1,], ....: [1, 0, 0, 0, 1, 1]]) - sage: P = A.right_kernel_matrix(algorithm='generic', basis='pivot'); P + sage: P = A.right_kernel_matrix(algorithm='generic', basis='pivot'); P # optional - sage.libs.pari [0 1 1 0 0 0] [0 0 0 1 0 0] [1 0 0 0 1 0] [1 0 0 0 0 1] - sage: A*P.transpose() == zero_matrix(GF(2), 3, 4) + sage: A*P.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.libs.pari True - sage: DP = A.right_kernel_matrix(algorithm='default', basis='pivot'); DP + sage: DP = A.right_kernel_matrix(algorithm='default', basis='pivot'); DP # optional - sage.libs.pari [0 1 1 0 0 0] [0 0 0 1 0 0] [1 0 0 0 1 0] [1 0 0 0 0 1] - sage: A*DP.transpose() == zero_matrix(GF(2), 3, 4) + sage: A*DP.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.libs.pari True - sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') + sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') # optional - sage.libs.pari [1 0 0 0 0 1] [0 1 1 0 0 0] [0 0 0 1 0 0] @@ -4152,11 +4168,11 @@ cdef class Matrix(Matrix1): We test that the mod 2 code is called for matrices over GF(2). :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], + sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], # optional - sage.libs.pari ....: [1, 0, 0, 0, 1, 1,], ....: [1, 0, 0, 0, 1, 1]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') + sage: A.right_kernel(algorithm='default') # optional - sage.libs.pari verbose ... verbose 1 () computing right kernel matrix over integers mod 2 for 3x6 matrix verbose 1 () done computing right kernel matrix over integers mod 2 for 3x6 matrix @@ -4175,19 +4191,19 @@ cdef class Matrix(Matrix1): will compute a set of basis vectors in the pivot format. These could be returned as a basis in echelon form. :: - sage: F. = FiniteField(5^2) - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], + sage: F. = FiniteField(5^2) # optional - sage.libs.pari + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.libs.pari ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: P = A.right_kernel_matrix(algorithm='default', basis='pivot'); P + sage: P = A.right_kernel_matrix(algorithm='default', basis='pivot'); P # optional - sage.libs.pari [ 4 4 1 0] [ a + 2 3*a + 3 0 1] - sage: A*P.transpose() == zero_matrix(F, 3, 2) + sage: A*P.transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari True - sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E + sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E # optional - sage.libs.pari [ 1 0 3*a + 4 2*a + 2] [ 0 1 2*a 3*a + 3] - sage: A*E.transpose() == zero_matrix(F, 3, 2) + sage: A*E.transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari True This general code can be requested for matrices over any field @@ -4214,12 +4230,12 @@ cdef class Matrix(Matrix1): We test that the generic code is called for matrices over fields, lacking any more specific routine. :: - sage: F. = FiniteField(5^2) - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], + sage: F. = FiniteField(5^2) # optional - sage.libs.pari + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.libs.pari ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') + sage: A.right_kernel(algorithm='default') # optional - sage.libs.pari verbose ... verbose 1 () computing right kernel matrix over an arbitrary field for 3x4 matrix ... @@ -4383,8 +4399,8 @@ cdef class Matrix(Matrix1): sage: A.right_kernel_matrix() [1 0] [0 1] - sage: A = matrix(FiniteField(7), 2, 0) - sage: A.right_kernel_matrix().parent() + sage: A = matrix(FiniteField(7), 2, 0) # optional - sage.libs.pari + sage: A.right_kernel_matrix().parent() # optional - sage.libs.pari Full MatrixSpace of 0 by 0 dense matrices over Finite Field of size 7 TESTS: @@ -4406,7 +4422,7 @@ cdef class Matrix(Matrix1): Traceback (most recent call last): ... ValueError: matrix kernel algorithm 'junk' not recognized - sage: matrix(GF(2), 2, 2).right_kernel_matrix(algorithm='padic') + sage: matrix(GF(2), 2, 2).right_kernel_matrix(algorithm='padic') # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: 'padic' matrix kernel algorithm only available over the rationals and the integers, not over Finite Field of size 2 @@ -4698,16 +4714,17 @@ cdef class Matrix(Matrix1): Over an arbitrary field, with two basis formats. Same vector space, different bases. :: - sage: F. = FiniteField(5^2) - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], + sage: F. = FiniteField(5^2) # optional - sage.libs.pari + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.libs.pari ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: K = A.right_kernel(); K - Vector space of degree 4 and dimension 2 over Finite Field in a of size 5^2 + sage: K = A.right_kernel(); K # optional - sage.libs.pari + Vector space of degree 4 and dimension 2 + over Finite Field in a of size 5^2 Basis matrix: [ 1 0 3*a + 4 2*a + 2] [ 0 1 2*a 3*a + 3] - sage: A*K.basis_matrix().transpose() == zero_matrix(F, 3, 2) + sage: A*K.basis_matrix().transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari True In the following test, we have to force usage of @@ -4717,9 +4734,10 @@ cdef class Matrix(Matrix1): installed. :: sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense - sage: B = Matrix_generic_dense(A.parent(), A.list(), False, False) - sage: P = B.right_kernel(basis = 'pivot'); P - Vector space of degree 4 and dimension 2 over Finite Field in a of size 5^2 + sage: B = Matrix_generic_dense(A.parent(), A.list(), False, False) # optional - sage.libs.pari + sage: P = B.right_kernel(basis='pivot'); P # optional - sage.libs.pari + Vector space of degree 4 and dimension 2 + over Finite Field in a of size 5^2 User basis matrix: [ 4 4 1 0] [ a + 2 3*a + 3 0 1] @@ -4727,7 +4745,7 @@ cdef class Matrix(Matrix1): If the optional meataxe package is installed, we again have to make sure to work with a copy of B that has the same type as ``P.basis_matrix()``:: - sage: B.parent()(B.list())*P.basis_matrix().transpose() == zero_matrix(F, 3, 2) + sage: B.parent()(B.list())*P.basis_matrix().transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari True sage: K == P True @@ -4735,20 +4753,22 @@ cdef class Matrix(Matrix1): Over number fields, PARI is used by default, but general-purpose code can be requested. Same vector space, same bases, different code.:: - sage: Q = QuadraticField(-7) - sage: a = Q.gen(0) - sage: A = matrix(Q, [[ 2, 5-a, 15-a, 16+4*a], + sage: Q = QuadraticField(-7) # optional - sage.rings.number_field + sage: a = Q.gen(0) # optional - sage.rings.number_field + sage: A = matrix(Q, [[ 2, 5-a, 15-a, 16+4*a], # optional - sage.rings.number_field ....: [2+a, a, -7 + 5*a, -3+3*a]]) - sage: K = A.right_kernel(algorithm='default'); K - Vector space of degree 4 and dimension 2 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + sage: K = A.right_kernel(algorithm='default'); K # optional - sage.rings.number_field + Vector space of degree 4 and dimension 2 + over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I Basis matrix: [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: A*K.basis_matrix().transpose() == zero_matrix(Q, 2, 2) + sage: A*K.basis_matrix().transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True - sage: B = copy(A) - sage: G = A.right_kernel(algorithm='generic'); G - Vector space of degree 4 and dimension 2 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + sage: B = copy(A) # optional - sage.rings.number_field + sage: G = A.right_kernel(algorithm='generic'); G # optional - sage.rings.number_field + Vector space of degree 4 and dimension 2 + over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I Basis matrix: [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] @@ -5018,11 +5038,11 @@ cdef class Matrix(Matrix1): Over a finite field, with a basis matrix in "pivot" format. :: - sage: A = matrix(FiniteField(7), [[5, 0, 5, 2, 4], + sage: A = matrix(FiniteField(7), [[5, 0, 5, 2, 4], # optional - sage.libs.pari ....: [1, 3, 2, 3, 6], ....: [1, 1, 6, 5, 3], ....: [2, 5, 6, 0, 0]]) - sage: A.kernel(basis='pivot') + sage: A.kernel(basis='pivot') # optional - sage.libs.pari Vector space of degree 4 and dimension 2 over Finite Field of size 7 User basis matrix: [5 2 1 0] @@ -6019,8 +6039,8 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, 2, range(4)) sage: A._eigenspace_format(None) == 'all' True - sage: B = matrix(GF(13), 2, range(4)) - sage: B._eigenspace_format(None) + sage: B = matrix(GF(13), 2, range(4)) # optional - sage.libs.pari + sage: B._eigenspace_format(None) # optional - sage.libs.pari 'all' Subrings are promoted to fraction fields and then checked for the @@ -6216,26 +6236,25 @@ cdef class Matrix(Matrix1): Next we compute the left eigenspaces over the finite field of order 11. :: - sage: A = ModularSymbols(43, base_ring=GF(11), sign=1).T(2).matrix(); A + sage: A = ModularSymbols(43, base_ring=GF(11), sign=1).T(2).matrix(); A # optional - sage.libs.pari [ 3 0 9 0] [ 0 9 0 10] [ 0 0 10 1] [ 0 0 1 1] - sage: A.base_ring() + sage: A.base_ring() # optional - sage.libs.pari Finite Field of size 11 - sage: A.charpoly() + sage: A.charpoly() # optional - sage.libs.pari x^4 + 10*x^3 + 3*x^2 + 2*x + 1 - sage: A.eigenspaces_left(format='galois', var = 'beta') + sage: A.eigenspaces_left(format='galois', var='beta') # optional - sage.libs.pari [ - (9, Vector space of degree 4 and dimension 1 over Finite Field of size 11 - User basis matrix: - [0 1 5 6]), - (3, Vector space of degree 4 and dimension 1 over Finite Field of size 11 - User basis matrix: - [1 0 1 6]), - (beta2, Vector space of degree 4 and dimension 1 over Univariate Quotient Polynomial Ring in beta2 over Finite Field of size 11 with modulus x^2 + 9 - User basis matrix: - [ 0 0 1 beta2 + 1]) + (9, Vector space of degree 4 and dimension 1 over Finite Field of size 11 + User basis matrix: [0 1 5 6]), + (3, Vector space of degree 4 and dimension 1 over Finite Field of size 11 + User basis matrix: [1 0 1 6]), + (beta2, Vector space of degree 4 and dimension 1 + over Univariate Quotient Polynomial Ring in beta2 + over Finite Field of size 11 with modulus x^2 + 9 + User basis matrix: [ 0 0 1 beta2 + 1]) ] This method is only applicable to exact matrices. @@ -6277,15 +6296,15 @@ cdef class Matrix(Matrix1): possible, will raise an error. Using the ``'galois'`` format option is more likely to be successful. :: - sage: F. = FiniteField(11^2) - sage: A = matrix(F, [[b + 1, b + 1], [10*b + 4, 5*b + 4]]) - sage: A.eigenspaces_left(format='all') + sage: F. = FiniteField(11^2) # optional - sage.libs.pari + sage: A = matrix(F, [[b + 1, b + 1], [10*b + 4, 5*b + 4]]) # optional - sage.libs.pari + sage: A.eigenspaces_left(format='all') # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError: unable to construct eigenspaces for eigenvalues outside the base field, try the keyword option: format='galois' - sage: A.eigenspaces_left(format='galois') + sage: A.eigenspaces_left(format='galois') # optional - sage.libs.pari [ (a0, Vector space of degree 2 and dimension 1 over Univariate Quotient Polynomial Ring in a0 over Finite Field in b of size 11^2 with modulus x^2 + (5*b + 6)*x + 8*b + 10 User basis matrix: @@ -6591,11 +6610,11 @@ cdef class Matrix(Matrix1): right_eigenspaces = eigenspaces_right - def eigenvalues(self,extend=True): + def eigenvalues(self, extend=True): r""" Return a sequence of the eigenvalues of a matrix, with - multiplicity. If the eigenvalues are roots of polynomials in QQ, - then QQbar elements are returned that represent each separate + multiplicity. If the eigenvalues are roots of polynomials in ``QQ``, + then ``QQbar`` elements are returned that represent each separate root. If the option extend is set to False, only eigenvalues in the base @@ -6608,33 +6627,40 @@ cdef class Matrix(Matrix1): [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15] - sage: sorted(a.eigenvalues(), reverse=True) + sage: sorted(a.eigenvalues(), reverse=True) # optional - sage.rings.number_field [32.46424919657298?, 0, 0, -2.464249196572981?] :: - sage: a=matrix([(1, 9, -1, -1), (-2, 0, -10, 2), (-1, 0, 15, -2), (0, 1, 0, -1)]) - sage: a.eigenvalues() - [-0.9386318578049146?, 15.50655435353258?, 0.2160387521361705? - 4.713151979747493?*I, 0.2160387521361705? + 4.713151979747493?*I] + sage: a = matrix([(1, 9, -1, -1), + ....: (-2, 0, -10, 2), + ....: (-1, 0, 15, -2), + ....: (0, 1, 0, -1)]) + sage: a.eigenvalues() # optional - sage.rings.number_field + [-0.9386318578049146?, + 15.50655435353258?, + 0.2160387521361705? - 4.713151979747493?*I, + 0.2160387521361705? + 4.713151979747493?*I] - A symmetric matrix a+a.transpose() should have real eigenvalues + A symmetric matrix ``a + a.transpose()`` should have real eigenvalues :: - sage: b=a+a.transpose() - sage: ev = b.eigenvalues(); ev - [-8.35066086057957?, -1.107247901349379?, 5.718651326708515?, 33.73925743522043?] + sage: b = a + a.transpose() + sage: ev = b.eigenvalues(); ev # optional - sage.rings.number_field + [-8.35066086057957?, -1.107247901349379?, + 5.718651326708515?, 33.73925743522043?] - The eigenvalues are elements of QQbar, so they really represent + The eigenvalues are elements of ``QQbar``, so they really represent exact roots of polynomials, not just approximations. :: - sage: e = ev[0]; e + sage: e = ev[0]; e # optional - sage.rings.number_field -8.35066086057957? - sage: p = e.minpoly(); p + sage: p = e.minpoly(); p # optional - sage.rings.number_field x^4 - 30*x^3 - 171*x^2 + 1460*x + 1784 - sage: p(e) == 0 + sage: p(e) == 0 # optional - sage.rings.number_field True To perform computations on the eigenvalue as an element of a number @@ -6642,38 +6668,39 @@ cdef class Matrix(Matrix1): :: - sage: e.as_number_field_element() - (Number Field in a with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264, + sage: e.as_number_field_element() # optional - sage.rings.number_field + (Number Field in a + with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264, a + 7, Ring morphism: From: Number Field in a with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264 To: Algebraic Real Field Defn: a |--> -15.35066086057957?) - Notice the effect of the extend option. + Notice the effect of the ``extend`` option. :: - sage: M=matrix(QQ,[[0,-1,0],[1,0,0],[0,0,2]]) - sage: M.eigenvalues() + sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) + sage: M.eigenvalues() # optional - sage.rings.number_field [2, -1*I, 1*I] sage: M.eigenvalues(extend=False) [2] The method also works for matrices over finite fields:: - sage: M = matrix(GF(3), [[0,1,1],[1,2,0],[2,0,1]]) - sage: ev = sorted(M.eigenvalues()); ev + sage: M = matrix(GF(3), [[0,1,1], [1,2,0], [2,0,1]]) # optional - sage.libs.pari + sage: ev = sorted(M.eigenvalues()); ev # optional - sage.libs.pari [2*z3, 2*z3 + 1, 2*z3 + 2] - Similarly as in the case of QQbar, the eigenvalues belong to some + Similarly as in the case of ``QQbar``, the eigenvalues belong to some algebraic closure but they can be converted to elements of a finite field:: - sage: e = ev[0] - sage: e.parent() + sage: e = ev[0] # optional - sage.libs.pari + sage: e.parent() # optional - sage.libs.pari Algebraic closure of Finite Field of size 3 - sage: e.as_finite_field_element() + sage: e.as_finite_field_element() # optional - sage.libs.pari (Finite Field in z3 of size 3^3, 2*z3, Ring morphism: From: Finite Field in z3 of size 3^3 To: Algebraic closure of Finite Field of size 3 @@ -6794,9 +6821,9 @@ cdef class Matrix(Matrix1): Check :trac:`30518`:: - sage: K. = QuadraticField(-1) - sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4, 4*i-4,1-i,-2]) - sage: assert all(m*v == e*v for e, vs, _ in m.eigenvectors_right() for v in vs) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4, 4*i-4,1-i,-2]) # optional - sage.rings.number_field + sage: assert all(m*v == e*v for e, vs, _ in m.eigenvectors_right() for v in vs) # optional - sage.rings.number_field """ if other is not None: if isinstance(other, bool): @@ -7772,13 +7799,13 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: MS = MatrixSpace(GF(19),2,3) - sage: C = MS.matrix([1,2,3,4,5,6]) - sage: C.rank() + sage: MS = MatrixSpace(GF(19), 2, 3) # optional - sage.libs.pari + sage: C = MS.matrix([1,2,3,4,5,6]) # optional - sage.libs.pari + sage: C.rank() # optional - sage.libs.pari 2 - sage: C.nullity() + sage: C.nullity() # optional - sage.libs.pari 0 - sage: C.echelon_form() + sage: C.echelon_form() # optional - sage.libs.pari [ 1 0 18] [ 0 1 2] @@ -7786,7 +7813,7 @@ cdef class Matrix(Matrix1): the transformation matrix, so the ``transformation`` option is ignored:: - sage: C.echelon_form(transformation=True) + sage: C.echelon_form(transformation=True) # optional - sage.libs.pari [ 1 0 18] [ 0 1 2] @@ -8212,20 +8239,20 @@ cdef class Matrix(Matrix1): Subdivided, or not, the result is immutable, so make a copy if you want to make changes. :: - sage: A = matrix(FiniteField(7), [[2,0,3], [5,5,3], [5,6,5]]) - sage: E = A.extended_echelon_form() - sage: E.is_mutable() + sage: A = matrix(FiniteField(7), [[2,0,3], [5,5,3], [5,6,5]]) # optional - sage.libs.pari + sage: E = A.extended_echelon_form() # optional - sage.libs.pari + sage: E.is_mutable() # optional - sage.libs.pari False - sage: F = A.extended_echelon_form(subdivide=True) - sage: F + sage: F = A.extended_echelon_form(subdivide=True) # optional - sage.libs.pari + sage: F # optional - sage.libs.pari [1 0 0|0 4 6] [0 1 0|4 2 2] [0 0 1|5 2 3] [-----+-----] - sage: F.is_mutable() + sage: F.is_mutable() # optional - sage.libs.pari False - sage: G = copy(F) - sage: G.subdivide([],[]); G + sage: G = copy(F) # optional - sage.libs.pari + sage: G.subdivide([], []); G # optional - sage.libs.pari [1 0 0 0 4 6] [0 1 0 4 2 2] [0 0 1 5 2 3] @@ -9203,15 +9230,17 @@ cdef class Matrix(Matrix1): Different base rings are handled sensibly. :: sage: A = matrix(ZZ, 2, 3, range(6)) - sage: B = matrix(FiniteField(23), 3, 4, range(12)) - sage: C = matrix(FiniteField(29), 4, 5, range(20)) - sage: D = A.tensor_product(B) - sage: D.parent() + sage: B = matrix(FiniteField(23), 3, 4, range(12)) # optional - sage.libs.pari + sage: C = matrix(FiniteField(29), 4, 5, range(20)) # optional - sage.libs.pari + sage: D = A.tensor_product(B) # optional - sage.libs.pari + sage: D.parent() # optional - sage.libs.pari Full MatrixSpace of 6 by 12 dense matrices over Finite Field of size 23 - sage: E = C.tensor_product(B) + sage: E = C.tensor_product(B) # optional - sage.libs.pari Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Finite Field of size 29' and 'Full MatrixSpace of 3 by 4 dense matrices over Finite Field of size 23' + TypeError: unsupported operand parent(s) for *: + 'Finite Field of size 29' and + 'Full MatrixSpace of 3 by 4 dense matrices over Finite Field of size 23' The input is checked to be sure it is a matrix. :: @@ -9238,9 +9267,9 @@ cdef class Matrix(Matrix1): sage: m2.tensor_product(m3).dimensions() (0, 6) - sage: m1 = MatrixSpace(GF(5), 3, 2).an_element() - sage: m2 = MatrixSpace(GF(5), 0, 4).an_element() - sage: m1.tensor_product(m2).parent() + sage: m1 = MatrixSpace(GF(5), 3, 2).an_element() # optional - sage.libs.pari + sage: m2 = MatrixSpace(GF(5), 0, 4).an_element() # optional - sage.libs.pari + sage: m1.tensor_product(m2).parent() # optional - sage.libs.pari Full MatrixSpace of 0 by 8 dense matrices over Finite Field of size 5 """ if not isinstance(A, Matrix): @@ -9523,26 +9552,26 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQbar, [[(1/sqrt(5))*(1+i), (1/sqrt(55))*(3+2*I), (1/sqrt(22))*(2+2*I)], + sage: A = matrix(QQbar, [[(1/sqrt(5))*(1+i), (1/sqrt(55))*(3+2*I), (1/sqrt(22))*(2+2*I)], # optional - sage.symbolic, sage.rings.number_field ....: [(1/sqrt(5))*(1-i), (1/sqrt(55))*(2+2*I), (1/sqrt(22))*(-3+I)], ....: [ (1/sqrt(5))*I, (1/sqrt(55))*(3-5*I), (1/sqrt(22))*(-2)]]) - sage: A.is_unitary() + sage: A.is_unitary() # optional - sage.symbolic, sage.rings.number_field True A permutation matrix is always orthogonal. :: - sage: sigma = Permutation([1,3,4,5,2]) - sage: P = sigma.to_matrix(); P + sage: sigma = Permutation([1,3,4,5,2]) # optional - sage.combinat + sage: P = sigma.to_matrix(); P # optional - sage.combinat [1 0 0 0 0] [0 0 0 0 1] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] - sage: P.is_unitary() + sage: P.is_unitary() # optional - sage.combinat True - sage: P.change_ring(GF(3)).is_unitary() + sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat, sage.libs.pari True - sage: P.change_ring(GF(3)).is_unitary() + sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat, sage.libs.pari True A square matrix far from unitary. :: @@ -9553,7 +9582,7 @@ cdef class Matrix(Matrix1): Rectangular matrices are never unitary. :: - sage: A = matrix(QQbar, 3, 4) + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field sage: A.is_unitary() False """ @@ -9677,30 +9706,30 @@ cdef class Matrix(Matrix1): Sage has several fields besides the entire complex numbers where conjugation is non-trivial. :: - sage: F. = QuadraticField(-7) - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], + sage: F. = QuadraticField(-7) # optional - sage.rings.number_field + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C = C*C.conjugate_transpose() - sage: C.is_normal() + sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field + sage: C.is_normal() # optional - sage.rings.number_field True A matrix that is nearly normal, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A.is_normal() + sage: A.is_normal() # optional - sage.rings.number_field False - sage: A[1,1] = 132 - sage: A.is_normal() + sage: A[1,1] = 132 # optional - sage.rings.number_field + sage: A.is_normal() # optional - sage.rings.number_field True Rectangular matrices are never normal. :: - sage: A = matrix(QQbar, 3, 4) - sage: A.is_normal() + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field + sage: A.is_normal() # optional - sage.rings.number_field False A square, empty matrix is trivially normal. :: @@ -9832,7 +9861,7 @@ cdef class Matrix(Matrix1): Test :trac:`17341`:: - sage: random_matrix(GF(2), 8, 586, sparse=True).visualize_structure() + sage: random_matrix(GF(2), 8, 586, sparse=True).visualize_structure() # optional - sage.libs.pari 512x6px 24-bit RGB image """ cdef Py_ssize_t x, y, _x, _y, v, bi, bisq @@ -9884,8 +9913,8 @@ cdef class Matrix(Matrix1): :: - sage: A = random_matrix(GF(127),200,200,density=0.3) - sage: A.density() <= 0.3 + sage: A = random_matrix(GF(127), 200, 200, density=0.3) # optional - sage.libs.pari + sage: A.density() <= 0.3 # optional - sage.libs.pari True :: @@ -9956,9 +9985,9 @@ cdef class Matrix(Matrix1): Test :trac:`27473`:: - sage: F. = LaurentSeriesRing(GF(2)) - sage: M = Matrix([[t,1],[0,t]]) - sage: ~M + sage: F. = LaurentSeriesRing(GF(2)) # optional - sage.libs.pari + sage: M = Matrix([[t,1], [0,t]]) # optional - sage.libs.pari + sage: ~M # optional - sage.libs.pari [t^-1 t^-2] [ 0 t^-1] @@ -10484,32 +10513,32 @@ cdef class Matrix(Matrix1): so we need to check with the conjugate-transpose. This example verifies that the bug on :trac:`10791` is fixed. :: - sage: F. = QuadraticField(-5) - sage: A = matrix(F, [[ 1, a - 3, a - 2, a + 1], + sage: F. = QuadraticField(-5) # optional - sage.rings.number_field + sage: A = matrix(F, [[ 1, a - 3, a - 2, a + 1], # optional - sage.rings.number_field ....: [ a, 2*a + 1, 3*a + 1, 1], ....: [a + 1, a - 6, 2*a - 5, 1], ....: [ 2*a, a, 3*a, -3], ....: [ 1, a - 1, a, a - 1]]) - sage: A.rank() + sage: A.rank() # optional - sage.rings.number_field 3 - sage: Q, R = A._gram_schmidt_noscale() - sage: Q + sage: Q, R = A._gram_schmidt_noscale() # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ 1 25/33*a - 38/11 641/1163*a + 453/1163] [ a 17/11*a + 73/33 322/1163*a + 1566/1163] [ a + 1 10/33*a - 173/33 -784/1163*a + 1614/1163] [ 2*a 1/11*a + 80/33 196/1163*a - 1234/1163] [ 1 25/33*a - 16/11 855/1163*a - 1717/1163] - sage: R + sage: R # optional - sage.rings.number_field [ 1 8/33*a + 5/11 8/33*a + 16/11 2/11*a + 1/33] [ 0 1 1 -107/1163*a - 78/1163] [ 0 0 0 1] - sage: Q*R == A + sage: Q*R == A # optional - sage.rings.number_field True - sage: Q.transpose().conjugate()*Q + sage: Q.transpose().conjugate()*Q # optional - sage.rings.number_field [ 33 0 0] [ 0 2326/33 0] [ 0 0 16532/1163] - sage: Q.column_space() == A.column_space() + sage: Q.column_space() == A.column_space() # optional - sage.rings.number_field True Some trivial cases. :: @@ -10994,7 +11023,7 @@ cdef class Matrix(Matrix1): in the smallest ring containing the matrix entries (:trac:`14508`):: sage: c = matrix([[0,1,0],[0,0,1],[1,0,0]]) - sage: c.jordan_form(CyclotomicField(3)) + sage: c.jordan_form(CyclotomicField(3)) # optional - sage.rings.number_field [ 1| 0| 0] [----------+----------+----------] [ 0| zeta3| 0] @@ -11062,9 +11091,11 @@ cdef class Matrix(Matrix1): We verify that the bug from :trac:`6942` is fixed:: - sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1],[1,0,0,1,1,1,0],[1,1,0,1,1,1,1],[1,1,1,0,1,1,1],[1,1,1,0,0,1,0],[1,1,1,0,1,0,0],[1,1,1,1,1,1,0]]) - sage: J, T = M.jordan_form(transformation=True) - sage: J + sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1], [1,0,0,1,1,1,0], [1,1,0,1,1,1,1], # optional - sage.libs.pari + ....: [1,1,1,0,1,1,1], [1,1,1,0,0,1,0], [1,1,1,0,1,0,0], + ....: [1,1,1,1,1,1,0]]) + sage: J, T = M.jordan_form(transformation=True) # optional - sage.libs.pari + sage: J # optional - sage.libs.pari [1 1|0 0|0 0|0] [0 1|0 0|0 0|0] [---+---+---+-] @@ -11075,11 +11106,11 @@ cdef class Matrix(Matrix1): [0 0|0 0|0 1|0] [---+---+---+-] [0 0|0 0|0 0|1] - sage: M * T == T * J + sage: M * T == T * J # optional - sage.libs.pari True - sage: T.rank() + sage: T.rank() # optional - sage.libs.pari 7 - sage: M.rank() + sage: M.rank() # optional - sage.libs.pari 7 We verify that the bug from :trac:`6932` is fixed:: @@ -11609,7 +11640,7 @@ cdef class Matrix(Matrix1): ....: [2, -1, 1, 0, -2], ....: [0, -1, -1, -5, -8]]) - sage: [e in QQ for e in A.eigenvalues()] + sage: [e in QQ for e in A.eigenvalues()] # optional - sage.rings.number_field [False, False, False, False, False] sage: A.is_diagonalizable() False @@ -11618,37 +11649,37 @@ cdef class Matrix(Matrix1): ... ValueError: not diagonalizable over Rational Field - sage: [e in QQbar for e in A.eigenvalues()] + sage: [e in QQbar for e in A.eigenvalues()] # optional - sage.rings.number_field [True, True, True, True, True] - sage: A.is_diagonalizable(base_field=QQbar) + sage: A.is_diagonalizable(base_field=QQbar) # optional - sage.rings.number_field True Other exact fields may be employed, though it will not always be possible to extend their base fields to contain all the eigenvalues. :: - sage: F. = FiniteField(5^2) - sage: A = matrix(F, [[ 4, 3*b + 2, 3*b + 1, 3*b + 4], + sage: F. = FiniteField(5^2) # optional - sage.libs.pari + sage: A = matrix(F, [[ 4, 3*b + 2, 3*b + 1, 3*b + 4], # optional - sage.libs.pari ....: [2*b + 1, 4*b, 0, 2], ....: [ 4*b, b + 2, 2*b + 3, 3], ....: [ 2*b, 3*b, 4*b + 4, 3*b + 3]]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari False - sage: A.jordan_form() + sage: A.jordan_form() # optional - sage.libs.pari [ 4 1| 0 0] [ 0 4| 0 0] [---------------+---------------] [ 0 0|2*b + 1 1] [ 0 0| 0 2*b + 1] - sage: F. = QuadraticField(-7) - sage: A = matrix(F, [[ c + 3, 2*c - 2, -2*c + 2, c - 1], + sage: F. = QuadraticField(-7) # optional - sage.rings.number_field + sage: A = matrix(F, [[ c + 3, 2*c - 2, -2*c + 2, c - 1], # optional - sage.rings.number_field ....: [2*c + 10, 13*c + 15, -13*c - 17, 11*c + 31], ....: [2*c + 10, 14*c + 10, -14*c - 12, 12*c + 30], ....: [ 0, 2*c - 2, -2*c + 2, 2*c + 2]]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.rings.number_field True - sage: A.diagonalization() + sage: A.diagonalization() # optional - sage.rings.number_field ( [ 4 0 0 0] [ 1 0 1 0] [ 0 -2 0 0] [ 4 1 0 1] @@ -11826,23 +11857,23 @@ cdef class Matrix(Matrix1): Other exact fields are supported. :: - sage: F. = FiniteField(7^2) - sage: A = matrix(F,[[2*a + 5, 6*a + 6, a + 3], + sage: F. = FiniteField(7^2) # optional - sage.libs.pari + sage: A = matrix(F,[[2*a + 5, 6*a + 6, a + 3], # optional - sage.libs.pari ....: [ a + 3, 2*a + 2, 4*a + 2], ....: [2*a + 6, 5*a + 5, 3*a]]) - sage: B = matrix(F,[[5*a + 5, 6*a + 4, a + 1], + sage: B = matrix(F,[[5*a + 5, 6*a + 4, a + 1], # optional - sage.libs.pari ....: [ a + 5, 4*a + 3, 3*a + 3], ....: [3*a + 5, a + 4, 5*a + 6]]) - sage: A.is_similar(B) + sage: A.is_similar(B) # optional - sage.libs.pari True - sage: B.is_similar(A) + sage: B.is_similar(A) # optional - sage.libs.pari True - sage: _, T = A.is_similar(B, transformation=True) - sage: T + sage: _, T = A.is_similar(B, transformation=True) # optional - sage.libs.pari + sage: T # optional - sage.libs.pari [ 1 0 0] [6*a + 1 4*a + 3 4*a + 2] [6*a + 3 3*a + 5 3*a + 6] - sage: A == T.inverse()*B*T + sage: A == T.inverse()*B*T # optional - sage.libs.pari True Two matrices with different sets of eigenvalues, so they @@ -11901,19 +11932,19 @@ cdef class Matrix(Matrix1): design, but we are not able to resurrect a similarity transformation. :: - sage: F. = FiniteField(7^2) - sage: C = matrix(F,[[ a + 2, 5*a + 4], - ....: [6*a + 6, 6*a + 4]]) - sage: S = matrix(F, [[0, 1], + sage: F. = FiniteField(7^2) # optional - sage.libs.pari + sage: C = matrix(F, [[ a + 2, 5*a + 4], # optional - sage.libs.pari + ....: [6*a + 6, 6*a + 4]]) + sage: S = matrix(F, [[0, 1], # optional - sage.libs.pari ....: [1, 0]]) - sage: D = S.inverse()*C*S - sage: C.is_similar(D) + sage: D = S.inverse()*C*S # optional - sage.libs.pari + sage: C.is_similar(D) # optional - sage.libs.pari True - sage: C.is_similar(D, transformation=True) + sage: C.is_similar(D, transformation=True) # optional - sage.libs.pari Traceback (most recent call last): ... RuntimeError: unable to compute transformation for similar matrices - sage: C.jordan_form() + sage: C.jordan_form() # optional - sage.libs.pari Traceback (most recent call last): ... RuntimeError: Some eigenvalue does not exist in @@ -11923,9 +11954,9 @@ cdef class Matrix(Matrix1): algebraic closure of this field to find the change-of-basis matrix:: - sage: cox = posets.TamariLattice(3).coxeter_transformation() - sage: M = cox.change_ring(GF(3)) - sage: M.is_similar(M**3, True) # long time + sage: cox = posets.TamariLattice(3).coxeter_transformation() # optional - sage.graphs, sage.combinat, sage.libs.pari + sage: M = cox.change_ring(GF(3)) # optional - sage.graphs, sage.combinat, sage.libs.pari + sage: M.is_similar(M**3, True) # long time # optional - sage.graphs, sage.combinat, sage.libs.pari ( [1 0 0 0 0] [0 1 1 0 2] @@ -11958,9 +11989,9 @@ cdef class Matrix(Matrix1): If the fraction fields of the entries are unequal and do not coerce in a common field, it is an error. :: - sage: A = matrix(GF(3), 2, 2, range(4)) - sage: B = matrix(GF(2), 2, 2, range(4)) - sage: A.is_similar(B, transformation=True) + sage: A = matrix(GF(3), 2, 2, range(4)) # optional - sage.libs.pari + sage: B = matrix(GF(2), 2, 2, range(4)) # optional - sage.libs.pari + sage: A.is_similar(B, transformation=True) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -11974,8 +12005,8 @@ cdef class Matrix(Matrix1): of ``QQ`` in ``QQbar``). :: sage: A = matrix(ZZ, 2, 2, range(4)) - sage: B = matrix(QQbar, 2, 2, range(4)) - sage: A.is_similar(B) + sage: B = matrix(QQbar, 2, 2, range(4)) # optional - sage.rings.number_field + sage: A.is_similar(B) # optional - sage.rings.number_field True TESTS: @@ -12395,7 +12426,7 @@ cdef class Matrix(Matrix1): ... TypeError: polynomial generator must be over the same ring as the matrix entries - sage: A.cyclic_subspace(v, basis='garbage') + sage: A.cyclic_subspace(v, basis='garbage') # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: basis format must be 'echelon' or 'iterates', not garbage @@ -12424,10 +12455,10 @@ cdef class Matrix(Matrix1): ... TypeError: matrix entries must be from an exact field, not Ring of integers modulo 6 - sage: F. = GF(2^4) - sage: G = matrix(QQ, 4, range(16)) - sage: w = vector(F, 4, [1, a, a^2, a^3]) - sage: G.cyclic_subspace(w) + sage: F. = GF(2^4) # optional - sage.libs.pari + sage: G = matrix(QQ, 4, range(16)) # optional - sage.libs.pari + sage: w = vector(F, 4, [1, a, a^2, a^3]) # optional - sage.libs.pari + sage: G.cyclic_subspace(w) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: unable to make vector entries compatible with matrix entries @@ -12586,40 +12617,40 @@ cdef class Matrix(Matrix1): field of complex numbers with rational real and imaginary parts, allow for this computation:: - sage: C. = QuadraticField(-1) - sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], + sage: C. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], # optional - sage.rings.number_field ....: [ -17*I + 3, 38, -69*I + 89, 7*I + 15], ....: [-24*I + 25, 69*I + 89, 976, 24*I + 6], ....: [ -21*I, -7*I + 15, -24*I + 6, 28]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field True - sage: L = A.cholesky() + sage: L = A.cholesky() # optional - sage.rings.number_field sage: L [ 4.79...? 0 0 0] [ 0.62...? - 3.54...?*I 5.00...? 0 0] [ 5.21...? - 5.00...?*I 13.58...? + 10.72...?*I 24.98...? 0] [ -4.37...?*I -0.10...? - 0.85...?*I -0.21...? + 0.37...?*I 2.81...?] - sage: L.parent() + sage: L.parent() # optional - sage.rings.number_field Full MatrixSpace of 4 by 4 dense matrices over Algebraic Field - sage: (L*L.conjugate_transpose() - A.change_ring(QQbar)).norm() < 10^-10 + sage: (L*L.conjugate_transpose() - A.change_ring(QQbar)).norm() < 10^-10 # optional - sage.rings.number_field True The field of algebraic numbers is an ideal setting for this computation:: - sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], + sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], # optional - sage.rings.number_field ....: [ -2*I + 4, 11, 10 - 12*I], ....: [ 4*I + 6, 10 + 12*I, 37]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field True - sage: L = A.cholesky() - sage: L + sage: L = A.cholesky() # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field [ 1.414213562373095? 0 0] [2.828427124746190? - 1.414213562373095?*I 1 0] [4.242640687119285? + 2.828427124746190?*I -2*I + 2 1.732050807568878?] - sage: L.parent() + sage: L.parent() # optional - sage.rings.number_field Full MatrixSpace of 3 by 3 dense matrices over Algebraic Field - sage: L*L.conjugate_transpose() == A + sage: L*L.conjugate_transpose() == A # optional - sage.rings.number_field True Results are cached, hence immutable. Use the ``copy`` function @@ -12675,22 +12706,22 @@ cdef class Matrix(Matrix1): The matrix may not be Hermitian:: - sage: F. = FiniteField(5^4) - sage: A = matrix(F, [[2+a^3, 3], [3, 3]]) - sage: A.cholesky() + sage: F. = FiniteField(5^4) # optional - sage.libs.pari + sage: A = matrix(F, [[2+a^3, 3], [3, 3]]) # optional - sage.libs.pari + sage: A.cholesky() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matrix is not Hermitian The matrix may not be positive-definite:: - sage: C. = QuadraticField(-1) - sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], + sage: C. = QuadraticField(-1) # optional - sage.rings.number_field + sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: B.is_positive_definite() + sage: B.is_positive_definite() # optional - sage.rings.number_field False - sage: B.cholesky() + sage: B.cholesky() # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: matrix is not positive definite @@ -13225,30 +13256,30 @@ cdef class Matrix(Matrix1): sage: B == P*L*U True - sage: F. = FiniteField(5^2) - sage: C = matrix(F, [[a + 3, 4*a + 4, 2, 4*a + 2], + sage: F. = FiniteField(5^2) # optional - sage.libs.pari + sage: C = matrix(F, [[a + 3, 4*a + 4, 2, 4*a + 2], # optional - sage.libs.pari ....: [3, 2*a + 4, 2*a + 4, 2*a + 1], ....: [3*a + 1, a + 3, 2*a + 4, 4*a + 3], ....: [a, 3, 3*a + 1, a]]) - sage: P, L, U = C.LU(pivot='nonzero') - sage: P + sage: P, L, U = C.LU(pivot='nonzero') # optional - sage.libs.pari + sage: P # optional - sage.libs.pari [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] - sage: L + sage: L # optional - sage.libs.pari [ 1 0 0 0] [3*a + 3 1 0 0] [ 2*a 4*a + 2 1 0] [2*a + 3 2 2*a + 4 1] - sage: U + sage: U # optional - sage.libs.pari [ a + 3 4*a + 4 2 4*a + 2] [ 0 a + 1 a + 3 2*a + 4] [ 0 0 1 4*a + 2] [ 0 0 0 0] - sage: L.base_ring() + sage: L.base_ring() # optional - sage.libs.pari Finite Field in a of size 5^2 - sage: C == P*L*U + sage: C == P*L*U # optional - sage.libs.pari True With no pivoting strategy given (i.e. ``pivot=None``) @@ -13325,18 +13356,18 @@ cdef class Matrix(Matrix1): absolute value must be handled carefully. This tests that situation in the case of cyclotomic fields. :: - sage: C = SymmetricGroup(5).character_table() - sage: C.base_ring() + sage: C = SymmetricGroup(5).character_table() # optional - sage.groups, sage.rings.number_field + sage: C.base_ring() # optional - sage.groups, sage.rings.number_field Cyclotomic Field of order 1 and degree 1 - sage: P, L, U = C.LU(pivot='partial') - sage: C == P*L*U + sage: P, L, U = C.LU(pivot='partial') # optional - sage.groups, sage.rings.number_field + sage: C == P*L*U # optional - sage.groups, sage.rings.number_field True Check that :trac:`32736` is solved:: - sage: M = Matrix(FiniteField(11), [[2,3],[4,5]]) - sage: P, L, U = M.LU() - sage: P.base_ring() + sage: M = Matrix(FiniteField(11), [[2,3],[4,5]]) # optional - sage.libs.pari + sage: P, L, U = M.LU() # optional - sage.libs.pari + sage: P.base_ring() # optional - sage.libs.pari Finite Field of size 11 """ if pivot not in [None, 'partial', 'nonzero']: @@ -13788,23 +13819,23 @@ cdef class Matrix(Matrix1): with rational real and imaginary parts. As theory predicts, the diagonal entries will be real numbers. :: - sage: C. = QuadraticField(-1) - sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], + sage: C. = QuadraticField(-1) # optional - sage.rings.number_field + sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: B.is_hermitian() + sage: B.is_hermitian() # optional - sage.rings.number_field True - sage: L, d = B.indefinite_factorization(algorithm='hermitian') - sage: D = diagonal_matrix(d) - sage: L + sage: L, d = B.indefinite_factorization(algorithm='hermitian') # optional - sage.rings.number_field + sage: D = diagonal_matrix(d) # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field [ 1 0 0] [ I + 2 1 0] [ -I + 1 2*I + 1 1] - sage: D + sage: D # optional - sage.rings.number_field [ 2 0 0] [ 0 -2 0] [ 0 0 3] - sage: B == L*D*L.conjugate_transpose() + sage: B == L*D*L.conjugate_transpose() # optional - sage.rings.number_field True If a leading principal submatrix has zero determinant, this @@ -13830,27 +13861,27 @@ cdef class Matrix(Matrix1): may be factored. This provides a reasonable alternative to the Cholesky decomposition. :: - sage: F. = FiniteField(5^3) - sage: A = matrix(F, + sage: F. = FiniteField(5^3) # optional - sage.libs.pari + sage: A = matrix(F, # optional - sage.libs.pari ....: [[ a^2 + 2*a, 4*a^2 + 3*a + 4, 3*a^2 + a, 2*a^2 + 2*a + 1], ....: [4*a^2 + 3*a + 4, 4*a^2 + 2, 3*a, 2*a^2 + 4*a + 2], ....: [ 3*a^2 + a, 3*a, 3*a^2 + 2, 3*a^2 + 2*a + 3], ....: [2*a^2 + 2*a + 1, 2*a^2 + 4*a + 2, 3*a^2 + 2*a + 3, 3*a^2 + 2*a + 4]]) - sage: A.is_symmetric() + sage: A.is_symmetric() # optional - sage.libs.pari True - sage: L, d = A.indefinite_factorization() - sage: D = diagonal_matrix(d) + sage: L, d = A.indefinite_factorization() # optional - sage.libs.pari + sage: D = diagonal_matrix(d) # optional - sage.libs.pari sage: L [ 1 0 0 0] [4*a^2 + 4*a + 3 1 0 0] [ 3 4*a^2 + a + 2 1 0] [ 4*a^2 + 4 2*a^2 + 3*a + 3 2*a^2 + 3*a + 1 1] - sage: D + sage: D # optional - sage.libs.pari [ a^2 + 2*a 0 0 0] [ 0 2*a^2 + 2*a + 4 0 0] [ 0 0 3*a^2 + 4*a + 3 0] [ 0 0 0 a^2 + 3*a] - sage: A == L*D*L.transpose() + sage: A == L*D*L.transpose() # optional - sage.libs.pari True This works correctly for the 0x0 matrix:: @@ -14350,11 +14381,11 @@ cdef class Matrix(Matrix1): An indefinite Hermitian matrix that happens to have a classical factorization:: - sage: F. = QuadraticField(-1) - sage: A = matrix(F, [[ 2, 4 - 2*I, 2 + 2*I], + sage: F. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A = matrix(F, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: A.block_ldlt(classical=True)[1:] + sage: A.block_ldlt(classical=True)[1:] # optional - sage.rings.number_field ( [ 2| 0| 0] [--+--+--] @@ -14386,11 +14417,11 @@ cdef class Matrix(Matrix1): correctly:: sage: n = ZZ.random_element(6) - sage: F = QuadraticField(-1, 'I') - sage: A = matrix.random(F, n) - sage: A = A + A.conjugate_transpose() - sage: P,L,D = A.block_ldlt() - sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() + sage: F = QuadraticField(-1, 'I') # optional - sage.rings.number_field + sage: A = matrix.random(F, n) # optional - sage.rings.number_field + sage: A = A + A.conjugate_transpose() # optional - sage.rings.number_field + sage: P,L,D = A.block_ldlt() # optional - sage.rings.number_field + sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() # optional - sage.rings.number_field True Ensure that a "random" complex positive-semidefinite matrix is @@ -14398,13 +14429,13 @@ cdef class Matrix(Matrix1): is in fact diagonal:: sage: n = ZZ.random_element(6) - sage: F = QuadraticField(-1, 'I') - sage: A = matrix.random(F, n) - sage: A = A*A.conjugate_transpose() - sage: P,L,D = A.block_ldlt() - sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() + sage: F = QuadraticField(-1, 'I') # optional - sage.rings.number_field + sage: A = matrix.random(F, n) # optional - sage.rings.number_field + sage: A = A*A.conjugate_transpose() # optional - sage.rings.number_field + sage: P,L,D = A.block_ldlt() # optional - sage.rings.number_field + sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() # optional - sage.rings.number_field True - sage: diagonal_matrix(D.diagonal()) == D + sage: diagonal_matrix(D.diagonal()) == D # optional - sage.rings.number_field True The factorization should be a no-op on diagonal matrices:: @@ -14607,9 +14638,10 @@ cdef class Matrix(Matrix1): a Hermitian matrix (for a non-Hermitian matrix, both "obviously" return ``False``):: - sage: F = QuadraticField(-1, 'I') + sage: rings = [ZZ, QQ, RDF, CDF] + sage: rings.append(QuadraticField(-1, 'I')) # optional - sage.rings.number_field sage: from sage.misc.prandom import choice - sage: ring = choice([ZZ, QQ, F, RDF, CDF]) + sage: ring = choice(rings) sage: A = matrix.random(ring, 10); A = A + A.conjugate_transpose() sage: def is_positive_semidefinite_naive(A): ....: if A.nrows() == 0: @@ -14625,9 +14657,9 @@ cdef class Matrix(Matrix1): either real numbers, complex numbers, or symbolics; otherwise we risk returning nonsensical results:: - sage: F = FiniteField(5^2) - sage: A = matrix.identity(F, 1) - sage: A.is_positive_semidefinite() + sage: F = FiniteField(5^2) # optional - sage.libs.pari + sage: A = matrix.identity(F, 1) # optional - sage.libs.pari + sage: A.is_positive_semidefinite() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: Could not see Finite Field in z2 of size 5^2 @@ -14777,17 +14809,17 @@ cdef class Matrix(Matrix1): numbers, complex numbers, or symbolic ring, then this routine will fail since comparison to zero is meaningless:: - sage: F. = FiniteField(5^3) - sage: a.conjugate() + sage: F. = FiniteField(5^3) # optional - sage.libs.pari + sage: a.conjugate() # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: cardinality of the field must be a square number - sage: A = matrix(F, + sage: A = matrix(F, # optional - sage.libs.pari ....: [[ a^2 + 2*a, 4*a^2 + 3*a + 4, 3*a^2 + a, 2*a^2 + 2*a + 1], ....: [4*a^2 + 3*a + 4, 4*a^2 + 2, 3*a, 2*a^2 + 4*a + 2], ....: [ 3*a^2 + a, 3*a, 3*a^2 + 2, 3*a^2 + 2*a + 3], ....: [2*a^2 + 2*a + 1, 2*a^2 + 4*a + 2, 3*a^2 + 2*a + 3, 3*a^2 + 2*a + 4]]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: Could not see Finite Field in a of size 5^3 as a subring @@ -15095,31 +15127,31 @@ cdef class Matrix(Matrix1): (Matrices over quadratic number fields are another class of examples.) :: - sage: C = CyclotomicField(5) - sage: a = C.gen(); a + sage: C = CyclotomicField(5) # optional - sage.rings.number_field + sage: a = C.gen(); a # optional - sage.rings.number_field zeta5 - sage: CC(a) + sage: CC(a) # optional - sage.rings.number_field 0.309016994374947 + 0.951056516295154*I - sage: M = matrix(C, 1, 2, [a^2, a+a^3]) - sage: M.conjugate_transpose() + sage: M = matrix(C, 1, 2, [a^2, a+a^3]) # optional - sage.rings.number_field + sage: M.conjugate_transpose() # optional - sage.rings.number_field [ zeta5^3] [-zeta5^3 - zeta5 - 1] Furthermore, this method can be applied to matrices over quadratic extensions of finite fields:: - sage: F. = GF(9,'a') - sage: N = matrix(F, 2, [0,a,-a,1]); N + sage: F. = GF(9,'a') # optional - sage.libs.pari + sage: N = matrix(F, 2, [0,a,-a,1]); N # optional - sage.libs.pari [ 0 a] [2*a 1] - sage: N.conjugate_transpose() + sage: N.conjugate_transpose() # optional - sage.libs.pari [ 0 a + 2] [2*a + 1 1] Conjugation does not make sense over rings not containing complex numbers or finite fields which are not a quadratic extension:: - sage: N = matrix(GF(5), 2, [0,1,2,3]) + sage: N = matrix(GF(5), 2, [0,1,2,3]) # optional - sage.libs.pari sage: N.conjugate_transpose() Traceback (most recent call last): ... @@ -15138,8 +15170,7 @@ cdef class Matrix(Matrix1): INPUT: - - ``self`` - a matrix whose entries are coercible into - CDF + - ``self`` - a matrix whose entries are coercible into ``CDF`` - ``p`` - one of the following options: @@ -15345,7 +15376,7 @@ cdef class Matrix(Matrix1): sage: A.plot() Graphics object consisting of 1 graphics primitive - Here we make a random matrix over RR and use cmap='hsv' to color + Here we make a random matrix over ``RR`` and use ``cmap='hsv'`` to color the matrix elements different RGB colors (see documentation for ``matrix_plot`` for more information on cmaps):: @@ -15355,8 +15386,8 @@ cdef class Matrix(Matrix1): Another random plot, but over GF(389):: - sage: A = random_matrix(GF(389), 10) - sage: A.plot(cmap='Oranges') + sage: A = random_matrix(GF(389), 10) # optional - sage.libs.pari + sage: A.plot(cmap='Oranges') # optional - sage.libs.pari Graphics object consisting of 1 graphics primitive """ from sage.plot.matrix_plot import matrix_plot @@ -15580,12 +15611,13 @@ cdef class Matrix(Matrix1): An example over a field:: - sage: m = matrix( GF(17), 3, 3, [11,5,1,3,6,8,1,16,0]); d,u,v = m.smith_form() - sage: d + sage: m = matrix(GF(17), 3, 3, [11,5,1,3,6,8,1,16,0]) # optional - sage.libs.pari + sage: d,u,v = m.smith_form() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari [1 0 0] [0 1 0] [0 0 0] - sage: u*m*v == d + sage: u*m*v == d # optional - sage.libs.pari True When the base ring has a ``ring_of_integers`` method and supports denominators, @@ -15857,31 +15889,31 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = FunctionField(GF(7),'x').maximal_order() - sage: K. = FunctionField(GF(7)); M = K.maximal_order() - sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) - sage: A.hermite_form() + sage: M = FunctionField(GF(7), 'x').maximal_order() # optional - sage.libs.pari + sage: K. = FunctionField(GF(7)); M = K.maximal_order() # optional - sage.libs.pari + sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) # optional - sage.libs.pari + sage: A.hermite_form() # optional - sage.libs.pari [ x 1 2*x] [ 0 x 5*x + 2] - sage: A.hermite_form(transformation=True) + sage: A.hermite_form(transformation=True) # optional - sage.libs.pari ( [ x 1 2*x] [1 0] [ 0 x 5*x + 2], [6 1] ) - sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) - sage: A.hermite_form(transformation=True, include_zero_rows=False) + sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) # optional - sage.libs.pari + sage: A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.libs.pari ([ x 1 2*x], [1 0]) - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True); H, U + sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True); H, U # optional - sage.libs.pari ( [ x 1 2*x] [1 0] [ 0 0 0], [5 1] ) - sage: U*A == H + sage: U*A == H # optional - sage.libs.pari True - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False) - sage: U*A + sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.libs.pari + sage: U*A # optional - sage.libs.pari [ x 1 2*x] - sage: U*A == H + sage: U*A == H # optional - sage.libs.pari True """ left, H, pivots = self._echelon_form_PID() @@ -15955,11 +15987,11 @@ cdef class Matrix(Matrix1): We verify that :trac:`9053` is resolved:: - sage: R. = GF(7)[] - sage: A = R^3 - sage: L = A.span([x*A.0 + (x^3 + 1)*A.1, x*A.2]) - sage: M = A.span([x*L.0]) - sage: M.0 in L + sage: R. = GF(7)[] # optional - sage.libs.pari + sage: A = R^3 # optional - sage.libs.pari + sage: L = A.span([x*A.0 + (x^3 + 1)*A.1, x*A.2]) # optional - sage.libs.pari + sage: M = A.span([x*L.0]) # optional - sage.libs.pari + sage: M.0 in L # optional - sage.libs.pari True """ @@ -16450,31 +16482,31 @@ cdef class Matrix(Matrix1): while the eigenvalues may lie outside the field, this does not impede the computation of the form. :: - sage: F. = GF(5^4) - sage: A = matrix(F, [[ a, 0, 0, a + 3], + sage: F. = GF(5^4) # optional - sage.libs.pari + sage: A = matrix(F, [[ a, 0, 0, a + 3], # optional - sage.libs.pari ....: [ 0,a^2 + 1, 0, 0], ....: [ 0, 0,a^3, 0], ....: [a^2 +4 , 0, 0,a + 2]]) - sage: A.zigzag_form() + sage: A.zigzag_form() # optional - sage.libs.pari [ 0 a^3 + 2*a^2 + 2*a + 2| 0| 0] [ 1 2*a + 2| 0| 0] [-------------------------------------------+---------------------+---------------------] [ 0 0| a^3| 0] [-------------------------------------------+---------------------+---------------------] [ 0 0| 0| a^2 + 1] - sage: A.eigenvalues() + sage: A.eigenvalues() # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError: algebraic closures of finite fields are only implemented for prime fields Subdivisions are optional. :: - sage: F. = GF(5^4) - sage: A = matrix(F, [[ a, 0, 0, a + 3], + sage: F. = GF(5^4) # optional - sage.libs.pari + sage: A = matrix(F, [[ a, 0, 0, a + 3], # optional - sage.libs.pari ....: [ 0,a^2 + 1, 0, 0], ....: [ 0, 0,a^3, 0], ....: [a^2 +4 , 0, 0,a + 2]]) - sage: A.zigzag_form(subdivide=False) + sage: A.zigzag_form(subdivide=False) # optional - sage.libs.pari [ 0 a^3 + 2*a^2 + 2*a + 2 0 0] [ 1 2*a + 2 0 0] [ 0 0 a^3 0] @@ -16785,8 +16817,8 @@ cdef class Matrix(Matrix1): Rational form may be computed over any field. The matrix below is an example where the eigenvalues lie outside the field. :: - sage: F. = FiniteField(7^2) - sage: A = matrix(F, + sage: F. = FiniteField(7^2) # optional - sage.libs.pari + sage: A = matrix(F, # optional - sage.libs.pari ....: [[5*a + 3, 4*a + 1, 6*a + 2, 2*a + 5, 6, 4*a + 5, 4*a + 5, 5, a + 6, 5, 4*a + 4], ....: [6*a + 3, 2*a + 4, 0, 6, 5*a + 5, 2*a, 5*a + 1, 1, 5*a + 2, 4*a, 5*a + 6], ....: [3*a + 1, 6*a + 6, a + 6, 2, 0, 3*a + 6, 5*a + 4, 5*a + 6, 5*a + 2, 3, 4*a + 2], @@ -16798,7 +16830,7 @@ cdef class Matrix(Matrix1): ....: [3*a + 5, 6*a + 2, 4*a, a + 5, 0, 5*a, 6*a + 5, 2*a + 1, 3*a + 1, 3*a + 5, 4*a + 2], ....: [3*a + 2, a + 3, 3*a + 6, a, 3*a + 5, 5*a + 1, 3*a + 2, a + 3, a + 2, 6*a + 1, 3*a + 3], ....: [6*a + 6, 5*a + 1, 4*a, 2, 5*a + 5, 3*a + 5, 3*a + 1, 2*a, 2*a, 2*a + 4, 4*a + 2]]) - sage: A.rational_form() + sage: A.rational_form() # optional - sage.libs.pari [ a + 2| 0 0 0| 0 0 0 0 0 0 0] [-------+-----------------------+-------------------------------------------------------] [ 0| 0 0 a + 6| 0 0 0 0 0 0 0] @@ -16812,18 +16844,18 @@ cdef class Matrix(Matrix1): [ 0| 0 0 0| 0 0 0 1 0 0 a + 6] [ 0| 0 0 0| 0 0 0 0 1 0 2*a + 1] [ 0| 0 0 0| 0 0 0 0 0 1 2*a + 1] - sage: invariants = A.rational_form(format='invariants') - sage: invariants + sage: invariants = A.rational_form(format='invariants') # optional - sage.libs.pari + sage: invariants # optional - sage.libs.pari [[6*a + 5, 1], [6*a + 1, a + 3, a + 3, 1], [5*a, a + 4, a + 6, 6*a + 5, 6*a + 1, 5*a + 6, 5*a + 6, 1]] - sage: R. = F[] - sage: polys = [R(p) for p in invariants] - sage: [p.factor() for p in polys] + sage: R. = F[] # optional - sage.libs.pari + sage: polys = [R(p) for p in invariants] # optional - sage.libs.pari + sage: [p.factor() for p in polys] # optional - sage.libs.pari [x + 6*a + 5, (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a), (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a)^3] - sage: polys[-1] == A.minimal_polynomial() + sage: polys[-1] == A.minimal_polynomial() # optional - sage.libs.pari True - sage: prod(polys) == A.characteristic_polynomial() + sage: prod(polys) == A.characteristic_polynomial() # optional - sage.libs.pari True - sage: A.eigenvalues() + sage: A.eigenvalues() # optional - sage.libs.pari Traceback (most recent call last): ... NotImplementedError: algebraic closures of finite fields are only implemented for prime fields @@ -17732,10 +17764,10 @@ def _smith_diag(d, transformation=True): ) sage: D == U*A*V True - sage: m = matrix(GF(7),2, [3,0,0,6]); d,u,v = _smith_diag(m); d + sage: m = matrix(GF(7), 2, [3,0,0,6]); d,u,v = _smith_diag(m); d # optional - sage.libs.pari [1 0] [0 1] - sage: u*m*v == d + sage: u*m*v == d # optional - sage.libs.pari True """ From 7c3fdba6fa1600f340917d29b48d2d0c1b77ce82 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 25 Feb 2023 18:20:47 -0800 Subject: [PATCH 05/99] sage.modules: More # optional --- src/sage/modules/free_module.py | 245 ++++++++++++----------- src/sage/modules/free_module_element.pyx | 186 ++++++++--------- 2 files changed, 222 insertions(+), 209 deletions(-) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 946c354e764..cd64ea4ce51 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -618,7 +618,7 @@ def span(gens, base_ring=None, check=True, already_echelonized=False): Basis matrix: [ 1 0 -3] - sage: span([[1,2,3], [2,2,2], [1,2,5]], GF(2)) + sage: span([[1,2,3], [2,2,2], [1,2,5]], GF(2)) # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 2 Basis matrix: [1 0 1] @@ -1108,15 +1108,15 @@ def relations_matrix(self): EXAMPLES:: - sage: V = GF(2)^2 - sage: V.relations_matrix() + sage: V = GF(2)^2 # optional - sage.libs.pari + sage: V.relations_matrix() # optional - sage.libs.pari [] - sage: W = V.subspace([[1, 0]]) - sage: W.relations_matrix() + sage: W = V.subspace([[1, 0]]) # optional - sage.libs.pari + sage: W.relations_matrix() # optional - sage.libs.pari [] - sage: Q = V / W - sage: Q.relations_matrix() + sage: Q = V / W # optional - sage.libs.pari + sage: Q.relations_matrix() # optional - sage.libs.pari [1 0] sage: S. = PolynomialRing(QQ) @@ -1196,13 +1196,13 @@ def __richcmp__(self, other, op): False sage: V1 <= V2 False - sage: R2 = GF(5)[x] - sage: F3 = R2^3 - sage: V3 = F3.span([[x^5-1,1+x+x^2+x^3+x^4,0]]) - sage: W3 = F3.span([[1,1,0],[0,4,0]]) - sage: V3 <= W3 + sage: R2 = GF(5)[x] # optional - sage.libs.pari + sage: F3 = R2^3 # optional - sage.libs.pari + sage: V3 = F3.span([[x^5-1, 1+x+x^2+x^3+x^4, 0]]) # optional - sage.libs.pari + sage: W3 = F3.span([[1,1,0], [0,4,0]]) # optional - sage.libs.pari + sage: V3 <= W3 # optional - sage.libs.pari True - sage: W3 <= V3 + sage: W3 <= V3 # optional - sage.libs.pari False We compare a one dimensional space to a two dimensional space:: @@ -1567,12 +1567,12 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari + sage: W = V.subspace([[2, 3, 4]]); W # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span([[1,1,1]]) + sage: W.span([[1, 1, 1]]) # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 1] @@ -1636,20 +1636,20 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): TESTS:: - sage: V = FreeModule(RDF,3) + sage: V = FreeModule(RDF, 3) sage: W = V.submodule([V.gen(0)]) - sage: W.span([V.gen(1)], base_ring=GF(7)) + sage: W.span([V.gen(1)], base_ring=GF(7)) # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 1 0] sage: v = V((1, pi, log(2))); v (1.0, 3.141592653589793, 0.6931471805599453) - sage: W.span([v], base_ring=GF(7)) + sage: W.span([v], base_ring=GF(7)) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: argument gens (= [(1.0, 3.141592653589793, 0.6931471805599453)]) is not compatible with base_ring (= Finite Field of size 7) sage: W = V.submodule([v]) - sage: W.span([V.gen(2)], base_ring=GF(7)) + sage: W.span([V.gen(2)], base_ring=GF(7)) # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 0 1] @@ -1895,14 +1895,15 @@ class FreeModule_generic(Module_free_ambient): sage: PolynomialRing(QQ,3,'x')^3 Ambient free module of rank 3 over the integral domain Multivariate Polynomial Ring in x0, x1, x2 over Rational Field - sage: FreeModule(GF(7),3).category() + sage: FreeModule(GF(7), 3).category() # optional - sage.libs.pari Category of enumerated finite dimensional vector spaces with basis over (finite enumerated fields and subquotients of monoids and quotients of semigroups) sage: V = QQ^4; V.category() Category of finite dimensional vector spaces with basis over (number fields and quotient fields and metric spaces) - sage: V = GF(5)**20; V.category() - Category of enumerated finite dimensional vector spaces with basis over (finite enumerated fields and subquotients of monoids and quotients of semigroups) + sage: V = GF(5)**20; V.category() # optional - sage.libs.pari + Category of enumerated finite dimensional vector spaces with basis over + (finite enumerated fields and subquotients of monoids and quotients of semigroups) sage: FreeModule(ZZ,3).category() Category of finite dimensional modules with basis over (euclidean domains and infinite enumerated sets @@ -2355,14 +2356,16 @@ def __iter__(self): EXAMPLES:: - sage: V = VectorSpace(GF(4,'a'),2) - sage: [x for x in V] - [(0, 0), (a, 0), (a + 1, 0), (1, 0), (0, a), (a, a), (a + 1, a), (1, a), (0, a + 1), (a, a + 1), (a + 1, a + 1), (1, a + 1), (0, 1), (a, 1), (a + 1, 1), (1, 1)] + sage: V = VectorSpace(GF(4, 'a'), 2) # optional - sage.libs.pari + sage: [x for x in V] # optional - sage.libs.pari + [(0, 0), (a, 0), (a + 1, 0), (1, 0), (0, a), (a, a), (a + 1, a), (1, a), + (0, a + 1), (a, a + 1), (a + 1, a + 1), (1, a + 1), (0, 1), (a, 1), + (a + 1, 1), (1, 1)] :: - sage: W = V.subspace([V([1,1])]) - sage: [x for x in W] + sage: W = V.subspace([V([1, 1])]) # optional - sage.libs.pari + sage: [x for x in W] # optional - sage.libs.pari [(0, 0), (a, a), (a + 1, a + 1), (1, 1)] Free modules over enumerated infinite rings (i.e., those in the @@ -2379,8 +2382,8 @@ def __iter__(self): TESTS:: - sage: V = VectorSpace(GF(2,'a'),2) - sage: V.list() + sage: V = VectorSpace(GF(2, 'a'), 2) # optional - sage.libs.pari + sage: V.list() # optional - sage.libs.pari [(0, 0), (1, 0), (0, 1), (1, 1)] Test ``iter(ZZ^n)`` and the like:: @@ -2533,19 +2536,19 @@ def basis_matrix(self, ring=None): :: - sage: M = FreeModule(GF(7),3).span([[2,3,4],[1,1,1]]); M + sage: M = FreeModule(GF(7), 3).span([[2,3,4], [1,1,1]]); M # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 6] [0 1 2] - sage: M.basis_matrix() + sage: M.basis_matrix() # optional - sage.libs.pari [1 0 6] [0 1 2] :: - sage: M = FreeModule(GF(7),3).span_of_basis([[2,3,4],[1,1,1]]) - sage: M.basis_matrix() + sage: M = FreeModule(GF(7), 3).span_of_basis([[2,3,4], [1,1,1]]) # optional - sage.libs.pari + sage: M.basis_matrix() # optional - sage.libs.pari [2 3 4] [1 1 1] @@ -2863,12 +2866,13 @@ def base_field(self): EXAMPLES:: - sage: FreeModule(GF(3), 2).base_field() + sage: FreeModule(GF(3), 2).base_field() # optional - sage.libs.pari Finite Field of size 3 - sage: FreeModule(ZZ, 2).base_field() + sage: FreeModule(ZZ, 2).base_field() # optional - sage.libs.pari Rational Field - sage: FreeModule(PolynomialRing(GF(7),'x'), 2).base_field() - Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 7 + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2).base_field() # optional - sage.libs.pari + Fraction Field of Univariate Polynomial Ring in x + over Finite Field of size 7 """ return self.base_ring().fraction_field() @@ -3527,11 +3531,12 @@ def _mul_(self, other, switch_sides=False): Check that :trac:`17705` is fixed:: - sage: V = GF(2)^2 - sage: W = V.subspace([[1, 0]]) - sage: x = matrix(GF(2), [[1, 1], [0, 1]]) - sage: W*x - Vector space of degree 2 and dimension 1 over Finite Field of size 2 + sage: V = GF(2)^2 # optional - sage.libs.pari + sage: W = V.subspace([[1, 0]]) # optional - sage.libs.pari + sage: x = matrix(GF(2), [[1, 1], [0, 1]]) # optional - sage.libs.pari + sage: W*x # optional - sage.libs.pari + Vector space of degree 2 and dimension 1 + over Finite Field of size 2 Basis matrix: [1 1] @@ -3546,15 +3551,15 @@ def relations(self): EXAMPLES:: - sage: V = GF(2)^2 - sage: V.relations() == V.zero_submodule() + sage: V = GF(2)^2 # optional - sage.libs.pari + sage: V.relations() == V.zero_submodule() # optional - sage.libs.pari True - sage: W = V.subspace([[1, 0]]) - sage: W.relations() == V.zero_submodule() + sage: W = V.subspace([[1, 0]]) # optional - sage.libs.pari + sage: W.relations() == V.zero_submodule() # optional - sage.libs.pari True - sage: Q = V / W - sage: Q.relations() == W + sage: Q = V / W # optional - sage.libs.pari + sage: Q.relations() == W # optional - sage.libs.pari True """ return self.zero_submodule() @@ -3571,9 +3576,12 @@ def __init__(self, base_ring, rank, degree, sparse=False, coordinate_ring=None, EXAMPLES:: sage: FreeModule(ZZ, 2) - Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: FreeModule(PolynomialRing(GF(7),'x'), 2) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 7 + Ambient free module of rank 2 + over the principal ideal domain Integer Ring + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2) # optional - sage.libs.pari + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x + over Finite Field of size 7 """ FreeModule_generic.__init__(self, base_ring, rank, degree, sparse, coordinate_ring, category=category) @@ -3665,9 +3673,12 @@ def __init__(self, base_ring, rank, degree, sparse=False, coordinate_ring=None, EXAMPLES:: sage: FreeModule(ZZ, 2) - Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: FreeModule(PolynomialRing(GF(7),'x'), 2) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 7 + Ambient free module of rank 2 + over the principal ideal domain Integer Ring + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2) # optional - sage.libs.pari + Ambient free module of rank 2 + over the principal ideal domain Univariate Polynomial Ring in x + over Finite Field of size 7 """ super().__init__(base_ring, rank, degree, sparse, coordinate_ring, category=category) @@ -4582,12 +4593,12 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari + sage: W = V.subspace([[2,3,4]]); W # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span_of_basis([[2,2,2], [3,3,0]]) + sage: W.span_of_basis([[2,2,2], [3,3,0]]) # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -4596,7 +4607,7 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F The basis vectors must be linearly independent or a ``ValueError`` exception is raised:: - sage: W.span_of_basis([[2,2,2], [3,3,3]]) + sage: W.span_of_basis([[2,2,2], [3,3,3]]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -4637,8 +4648,8 @@ def subspace(self, gens, check=True, already_echelonized=False): ambient `3`-dimensional space over the finite field of order `7`:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari + sage: W = V.subspace([[2,3,4]]); W # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] @@ -4647,7 +4658,7 @@ def subspace(self, gens, check=True, already_echelonized=False): ``check=False``. This is just equivalent to computing the span of the element:: - sage: W.subspace([[1,1,0]], check=False) + sage: W.subspace([[1,1,0]], check=False) # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 0] @@ -4655,7 +4666,7 @@ def subspace(self, gens, check=True, already_echelonized=False): With ``check=True`` (the default) the mistake is correctly detected and reported with an ``ArithmeticError`` exception:: - sage: W.subspace([[1,1,0]], check=True) + sage: W.subspace([[1,1,0]], check=True) # optional - sage.libs.pari Traceback (most recent call last): ... ArithmeticError: argument gens (= [[1, 1, 0]]) does not generate a submodule of self @@ -4672,25 +4683,25 @@ def subspaces(self, dim): EXAMPLES:: - sage: V = VectorSpace(GF(3), 5) - sage: len(list(V.subspaces(0))) + sage: V = VectorSpace(GF(3), 5) # optional - sage.libs.pari + sage: len(list(V.subspaces(0))) # optional - sage.libs.pari 1 - sage: len(list(V.subspaces(1))) + sage: len(list(V.subspaces(1))) # optional - sage.libs.pari 121 - sage: len(list(V.subspaces(2))) + sage: len(list(V.subspaces(2))) # optional - sage.libs.pari 1210 - sage: len(list(V.subspaces(3))) + sage: len(list(V.subspaces(3))) # optional - sage.libs.pari 1210 - sage: len(list(V.subspaces(4))) + sage: len(list(V.subspaces(4))) # optional - sage.libs.pari 121 - sage: len(list(V.subspaces(5))) + sage: len(list(V.subspaces(5))) # optional - sage.libs.pari 1 :: - sage: V = VectorSpace(GF(3), 5) - sage: V = V.subspace([V([1,1,0,0,0]),V([0,0,1,1,0])]) - sage: list(V.subspaces(1)) + sage: V = VectorSpace(GF(3), 5) # optional - sage.libs.pari + sage: V = V.subspace([V([1,1,0,0,0]), V([0,0,1,1,0])]) # optional - sage.libs.pari + sage: list(V.subspaces(1)) # optional - sage.libs.pari [Vector space of degree 5 and dimension 1 over Finite Field of size 3 Basis matrix: [1 1 0 0 0], @@ -4721,8 +4732,8 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace_with_basis([[2,2,2], [1,2,3]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari + sage: W = V.subspace_with_basis([[2,2,2], [1,2,3]]); W # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -4732,7 +4743,7 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: W1 = W.subspace_with_basis([[3,4,5]]); W1 + sage: W1 = W.subspace_with_basis([[3,4,5]]); W1 # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 User basis matrix: [3 4 5] @@ -4742,14 +4753,14 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: W2 = W.subspace([[3,4,5]]); W2 + sage: W2 = W.subspace([[3,4,5]]); W2 # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 6 4] Nonetheless the two subspaces are equal (as mathematical objects):: - sage: W1 == W2 + sage: W1 == W2 # optional - sage.libs.pari True """ return self.submodule_with_basis(gens, check=check, already_echelonized=already_echelonized) @@ -4797,14 +4808,14 @@ def complement(self): we can get complements which are only isomorphic to a vector space decomposition complement. :: - sage: F2 = GF(2,x) - sage: V = F2^6 - sage: W = V.span([[1,1,0,0,0,0]]) - sage: W + sage: F2 = GF(2, x) # optional - sage.libs.pari + sage: V = F2^6 # optional - sage.libs.pari + sage: W = V.span([[1,1,0,0,0,0]]) # optional - sage.libs.pari + sage: W # optional - sage.libs.pari Vector space of degree 6 and dimension 1 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] - sage: W.complement() + sage: W.complement() # optional - sage.libs.pari Vector space of degree 6 and dimension 5 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] @@ -4812,7 +4823,7 @@ def complement(self): [0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] - sage: W.intersection(W.complement()) + sage: W.intersection(W.complement()) # optional - sage.libs.pari Vector space of degree 6 and dimension 1 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] @@ -5135,7 +5146,7 @@ def __quotient_matrices(self, sub): An example in characteristic 5:: - sage: A = GF(5)^2; B = A.span([[1,3]]); A / B + sage: A = GF(5)^2; B = A.span([[1,3]]); A / B # optional - sage.libs.pari Vector space quotient V/W of dimension 1 over Finite Field of size 5 where V: Vector space of dimension 2 over Finite Field of size 5 W: Vector space of degree 2 and dimension 1 over Finite Field of size 5 @@ -5225,14 +5236,14 @@ def quotient_abstract(self, sub, check=True, **kwds): EXAMPLES:: - sage: V = GF(19)^3 - sage: W = V.span_of_basis([ [1,2,3], [1,0,1] ]) - sage: U,pi,lift = V.quotient_abstract(W) - sage: pi(V.2) + sage: V = GF(19)^3 # optional - sage.libs.pari + sage: W = V.span_of_basis([[1,2,3], [1,0,1]]) # optional - sage.libs.pari + sage: U, pi, lift = V.quotient_abstract(W) # optional - sage.libs.pari + sage: pi(V.2) # optional - sage.libs.pari (18) - sage: pi(V.0) + sage: pi(V.0) # optional - sage.libs.pari (1) - sage: pi(V.0 + V.2) + sage: pi(V.0 + V.2) # optional - sage.libs.pari (0) Another example involving a quotient of one subspace by another:: @@ -5297,14 +5308,14 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category We check that the creation of a submodule does not trigger the construction of a basis of the ambient space. See :trac:`15953`:: - sage: F. = GF(4) - sage: V = VectorSpace(F, 1) - sage: v = V.random_element() - sage: _ = V.subspace([v]) - sage: hasattr(V, '_FreeModule_ambient__basis') + sage: F. = GF(4) # optional - sage.libs.pari + sage: V = VectorSpace(F, 1) # optional - sage.libs.pari + sage: v = V.random_element() # optional - sage.libs.pari + sage: _ = V.subspace([v]) # optional - sage.libs.pari + sage: hasattr(V, '_FreeModule_ambient__basis') # optional - sage.libs.pari False - sage: _ = V.basis() - sage: hasattr(V, '_FreeModule_ambient__basis') + sage: _ = V.basis() # optional - sage.libs.pari + sage: hasattr(V, '_FreeModule_ambient__basis') # optional - sage.libs.pari True """ FreeModule_generic.__init__(self, base_ring, rank=rank, @@ -5587,14 +5598,14 @@ def _latex_(self): :: - sage: A = GF(5)^20 - sage: latex(A) # indirect doctest + sage: A = GF(5)^20 # optional - sage.libs.pari + sage: latex(A) # indirect doctest # optional - sage.libs.pari \Bold{F}_{5}^{20} :: - sage: A = PolynomialRing(QQ,3,'x') ^ 20 - sage: latex(A) #indirect doctest + sage: A = PolynomialRing(QQ, 3, 'x')^20 + sage: latex(A) # indirect doctest (\Bold{Q}[x_{0}, x_{1}, x_{2}])^{20} """ t = "%s" % latex.latex(self.base_ring()) @@ -5689,12 +5700,12 @@ def change_ring(self, R): sage: A = ZZ^3; A.change_ring(QQ) Vector space of dimension 3 over Rational Field - sage: A = ZZ^3; A.change_ring(GF(5)) + sage: A = ZZ^3; A.change_ring(GF(5)) # optional - sage.libs.pari Vector space of dimension 3 over Finite Field of size 5 For ambient modules any change of rings is defined:: - sage: A = GF(5)**3; A.change_ring(QQ) + sage: A = GF(5)**3; A.change_ring(QQ) # optional - sage.libs.pari Vector space of dimension 3 over Rational Field TESTS: @@ -5982,7 +5993,7 @@ class FreeModule_ambient_domain(FreeModule_generic_domain, FreeModule_ambient): EXAMPLES:: - sage: FreeModule(PolynomialRing(GF(5),'x'), 3) + sage: FreeModule(PolynomialRing(GF(5), 'x'), 3) # optional - sage.libs.pari Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 5 """ @@ -5993,7 +6004,7 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category TESTS:: - sage: A = FreeModule(PolynomialRing(GF(5),'x'), 3) + sage: A = FreeModule(PolynomialRing(GF(5),'x'), 3) # optional - sage.libs.pari sage: TestSuite(A).run() """ FreeModule_ambient.__init__(self, base_ring, rank, sparse, coordinate_ring, category=category) @@ -6341,9 +6352,9 @@ def _element_constructor_(self, e, *args, **kwds): EXAMPLES:: - sage: k. = GF(3^4) - sage: VS = k.vector_space(map=False) - sage: VS(a) + sage: k. = GF(3^4) # optional - sage.libs.pari + sage: VS = k.vector_space(map=False) # optional - sage.libs.pari + sage: VS(a) # optional - sage.libs.pari (0, 1, 0, 0) """ try: @@ -6925,15 +6936,15 @@ def relations(self): EXAMPLES:: - sage: V = GF(2)^2 - sage: W = V.subspace([[1, 0]]) - sage: W.relations() == V.zero_submodule() + sage: V = GF(2)^2 # optional - sage.libs.pari + sage: W = V.subspace([[1, 0]]) # optional - sage.libs.pari + sage: W.relations() == V.zero_submodule() # optional - sage.libs.pari True - sage: Q = V / W - sage: Q.relations() == W + sage: Q = V / W # optional - sage.libs.pari + sage: Q.relations() == W # optional - sage.libs.pari True - sage: Q.zero_submodule().relations() == W + sage: Q.zero_submodule().relations() == W # optional - sage.libs.pari True """ return self.__ambient_module.relations() @@ -7334,7 +7345,7 @@ def change_ring(self, R): sage: V = QQ^3 sage: W = V.subspace([[2, 1/2, 1]]) - sage: W.change_ring(GF(7)) + sage: W.change_ring(GF(7)) # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 2 4] @@ -8144,7 +8155,7 @@ def element_class(R, is_sparse): sage: sage.modules.free_module.element_class(FF, is_sparse=False) - sage: sage.modules.free_module.element_class(GF(7), is_sparse=False) + sage: sage.modules.free_module.element_class(GF(7), is_sparse=False) # optional - sage.libs.pari sage: sage.modules.free_module.element_class(P, is_sparse=True) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index f813b37cf70..8d3c829f28a 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -43,7 +43,7 @@ field. :: sage: K = ZZ^5 - sage: M = GF(7)^5 + sage: M = GF(7)^5 # optional - sage.libs.pari Arithmetic between the `\QQ` and `\ZZ` modules is defined, and the result is always @@ -60,10 +60,12 @@ to `\QQ`. Since there is no canonical coercion map to the finite field from `\QQ` the following arithmetic is not defined:: - sage: V.0 + M.0 + sage: V.0 + M.0 # optional - sage.libs.pari Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Vector space of dimension 5 over Rational Field' and 'Vector space of dimension 5 over Finite Field of size 7' + TypeError: unsupported operand parent(s) for +: + 'Vector space of dimension 5 over Rational Field' and + 'Vector space of dimension 5 over Finite Field of size 7' However, there is a map from `\ZZ` to the finite field, so the following is defined, and the result is in the finite @@ -71,11 +73,11 @@ field. :: - sage: w = K.0 + M.0; w + sage: w = K.0 + M.0; w # optional - sage.libs.pari (2, 0, 0, 0, 0) - sage: parent(w) + sage: parent(w) # optional - sage.libs.pari Vector space of dimension 5 over Finite Field of size 7 - sage: parent(M.0 + K.0) + sage: parent(M.0 + K.0) # optional - sage.libs.pari Vector space of dimension 5 over Finite Field of size 7 Matrix vector multiply:: @@ -213,20 +215,20 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): All entries must *canonically* coerce to some common ring:: - sage: v = vector([17, GF(11)(5), 19/3]); v + sage: v = vector([17, GF(11)(5), 19/3]); v # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: unable to find a common ring for all elements :: - sage: v = vector([17, GF(11)(5), 19]); v + sage: v = vector([17, GF(11)(5), 19]); v # optional - sage.libs.pari (6, 5, 8) - sage: v.parent() + sage: v.parent() # optional - sage.libs.pari Vector space of dimension 3 over Finite Field of size 11 - sage: v = vector([17, GF(11)(5), 19], QQ); v + sage: v = vector([17, GF(11)(5), 19], QQ); v # optional - sage.libs.pari (17, 5, 19) - sage: v.parent() + sage: v.parent() # optional - sage.libs.pari Vector space of dimension 3 over Rational Field sage: v = vector((1,2,3), QQ); v (1, 2, 3) @@ -249,7 +251,7 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): We make a vector mod 3 out of a vector over `\ZZ`. :: - sage: vector(vector([1,2,3]), GF(3)) + sage: vector(vector([1,2,3]), GF(3)) # optional - sage.libs.pari (1, 2, 0) The degree of a vector may be specified:: @@ -269,9 +271,9 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): you must specify the degree since it is not implied. Here we use a finite field as the base ring. :: - sage: w = vector(FiniteField(7), 4); w + sage: w = vector(FiniteField(7), 4); w # optional - sage.libs.pari (0, 0, 0, 0) - sage: w.parent() + sage: w.parent() # optional - sage.libs.pari Vector space of dimension 4 over Finite Field of size 7 The fastest method to construct a zero vector is to call the @@ -464,9 +466,9 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): We check that :trac:`31470` is fixed:: - sage: k. = GF(5^3) - sage: S. = k['x', k.frobenius_endomorphism()] - sage: vector(S, 3) + sage: k. = GF(5^3) # optional - sage.libs.pari + sage: S. = k['x', k.frobenius_endomorphism()] # optional - sage.libs.pari + sage: vector(S, 3) # optional - sage.libs.pari ... (0, 0, 0) """ @@ -843,11 +845,11 @@ def random_vector(ring, degree=None, *args, **kwds): Any ring with a ``random_element()`` method may be used. :: - sage: F = FiniteField(23) - sage: hasattr(F, 'random_element') + sage: F = FiniteField(23) # optional - sage.libs.pari + sage: hasattr(F, 'random_element') # optional - sage.libs.pari True - sage: v = random_vector(F, 10) - sage: v.parent() + sage: v = random_vector(F, 10) # optional - sage.libs.pari + sage: v.parent() # optional - sage.libs.pari Vector space of dimension 10 over Finite Field of size 23 The default implementation is a dense representation, equivalent to @@ -869,13 +871,13 @@ def random_vector(ring, degree=None, *args, **kwds): sage: v1 = random_vector(ZZ, 20, distribution="1/n") sage: v2 = random_vector(ZZ, 15, x=-1000, y=1000) sage: v3 = random_vector(QQ, 10) - sage: v4 = random_vector(FiniteField(17), 10) + sage: v4 = random_vector(FiniteField(17), 10) # optional - sage.libs.pari sage: v5 = random_vector(RR, 10) sage: set_random_seed(seed) sage: w1 = vector(ZZ.random_element(distribution="1/n") for _ in range(20)) sage: w2 = vector(ZZ.random_element(x=-1000, y=1000) for _ in range(15)) sage: w3 = vector(QQ.random_element() for _ in range(10)) - sage: w4 = vector(FiniteField(17).random_element() for _ in range(10)) + sage: w4 = vector(FiniteField(17).random_element() for _ in range(10)) # optional - sage.libs.pari sage: w5 = vector(RR.random_element() for _ in range(10)) sage: [v1, v2, v3, v4, v5] == [w1, w2, w3, w4, w5] True @@ -998,11 +1000,11 @@ cdef class FreeModuleElement(Vector): # abstract base class Create the multiplication table of `GF(4)` using GP:: - sage: k. = GF(4, impl="pari_ffelt") - sage: v = gp(vector(list(k))) - sage: v + sage: k. = GF(4, impl="pari_ffelt") # optional - sage.libs.pari + sage: v = gp(vector(list(k))) # optional - sage.libs.pari + sage: v # optional - sage.libs.pari [0, 1, a, a + 1] - sage: v.mattranspose() * v + sage: v.mattranspose() * v # optional - sage.libs.pari [0, 0, 0, 0; 0, 1, a, a + 1; 0, a, a + 1, 1; 0, a + 1, 1, a] """ # Elements in vectors are always Sage Elements, so they should @@ -1148,7 +1150,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v = vector(ZZ, [2, 12, 22]) sage: vector(v) (2, 12, 22) - sage: vector(GF(7), v) + sage: vector(GF(7), v) # optional - sage.libs.pari (2, 5, 1) sage: vector(v, ZZ['x', 'y']) (2, 12, 22) @@ -1171,7 +1173,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: sage_input(vector(RR, [pi, e, 0.5]), verify=True) # Verified vector(RR, [3.1415926535897931, 2.7182818284590451, 0.5]) - sage: sage_input(vector(GF(5), [1, 2, 3, 4, 5]), verify=True) + sage: sage_input(vector(GF(5), [1, 2, 3, 4, 5]), verify=True) # optional - sage.libs.pari # Verified vector(GF(5), [1, 2, 3, 4, 0]) sage: sage_input(vector([0, 0, 0, 1, 0, 0, 0], sparse=True), verify=True) @@ -1322,14 +1324,14 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: v = vector(GF(2), [1,2,3]) - sage: v.n() + sage: v = vector(GF(2), [1,2,3]) # optional - sage.libs.pari + sage: v.n() # optional - sage.libs.pari (1.00000000000000, 0.000000000000000, 1.00000000000000) - sage: _.parent() + sage: _.parent() # optional - sage.libs.pari Vector space of dimension 3 over Real Field with 53 bits of precision - sage: v.n(prec=75) + sage: v.n(prec=75) # optional - sage.libs.pari (1.000000000000000000000, 0.0000000000000000000000, 1.000000000000000000000) - sage: _.parent() + sage: _.parent() # optional - sage.libs.pari Vector space of dimension 3 over Real Field with 75 bits of precision TESTS: @@ -1366,8 +1368,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: w.parent() Full MatrixSpace of 1 by 3 dense matrices over Integer Ring - sage: x = vector(FiniteField(13), [2,4,8,16]) - sage: x.row() + sage: x = vector(FiniteField(13), [2,4,8,16]) # optional - sage.libs.pari + sage: x.row() # optional - sage.libs.pari [2 4 8 3] There is more than one way to get one-row matrix from a vector, @@ -1435,8 +1437,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: w.parent() Full MatrixSpace of 3 by 1 dense matrices over Integer Ring - sage: x = vector(FiniteField(13), [2,4,8,16]) - sage: x.column() + sage: x = vector(FiniteField(13), [2,4,8,16]) # optional - sage.libs.pari + sage: x.column() # optional - sage.libs.pari [2] [4] [8] @@ -1533,7 +1535,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.change_ring(GF(3)) + sage: v = vector(QQ['x,y'], [1..5]); v.change_ring(GF(3)) # optional - sage.libs.pari (1, 2, 0, 1, 2) TESTS: @@ -1541,7 +1543,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Check for :trac:`29630`:: sage: v = vector(QQ, 4, {0:1}, sparse=True) - sage: v.change_ring(AA).is_sparse() + sage: v.change_ring(AA).is_sparse() # optional - sage.rings.number_field True """ if self.base_ring() is R: @@ -2190,9 +2192,9 @@ cdef class FreeModuleElement(Vector): # abstract base class The following was fixed in :trac:`8800`:: - sage: M = GF(5)^3 - sage: v = M((4,0,2)) - sage: v.denominator() + sage: M = GF(5)^3 # optional - sage.libs.pari + sage: v = M((4,0,2)) # optional - sage.libs.pari + sage: v.denominator() # optional - sage.libs.pari 1 """ # It may be that the coordinates do not have a denominator @@ -2544,15 +2546,15 @@ cdef class FreeModuleElement(Vector): # abstract base class arguments is reversed.:: sage: v = vector(ZZ, [1,2,3]) - sage: w = vector(FiniteField(3), [0,1,2]) - sage: ip = w.dot_product(v); ip + sage: w = vector(FiniteField(3), [0,1,2]) # optional - sage.libs.pari + sage: ip = w.dot_product(v); ip # optional - sage.libs.pari 2 - sage: ip.parent() + sage: ip.parent() # optional - sage.libs.pari Finite Field of size 3 - sage: ip = v.dot_product(w); ip + sage: ip = v.dot_product(w); ip # optional - sage.libs.pari 2 - sage: ip.parent() + sage: ip.parent() # optional - sage.libs.pari Finite Field of size 3 The dot product of a vector with itself is the 2-norm, squared. :: @@ -2754,26 +2756,26 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: F = GF(previous_prime(2^32)) - sage: v = random_vector(F, 3) - sage: w = random_vector(F, 3) - sage: vh = v.cross_product_matrix() - sage: vh*w == v.cross_product(w) + sage: F = GF(previous_prime(2^32)) # optional - sage.libs.pari + sage: v = random_vector(F, 3) # optional - sage.libs.pari + sage: w = random_vector(F, 3) # optional - sage.libs.pari + sage: vh = v.cross_product_matrix() # optional - sage.libs.pari + sage: vh*w == v.cross_product(w) # optional - sage.libs.pari True - sage: w*vh == w.cross_product(v) + sage: w*vh == w.cross_product(v) # optional - sage.libs.pari True - sage: vh.is_alternating() + sage: vh.is_alternating() # optional - sage.libs.pari True - sage: v = random_vector(F, 7) - sage: w = random_vector(F, 7) - sage: vh = v.cross_product_matrix() - sage: vh*w == v.cross_product(w) + sage: v = random_vector(F, 7) # optional - sage.libs.pari + sage: w = random_vector(F, 7) # optional - sage.libs.pari + sage: vh = v.cross_product_matrix() # optional - sage.libs.pari + sage: vh*w == v.cross_product(w) # optional - sage.libs.pari True - sage: w*vh == w.cross_product(v) + sage: w*vh == w.cross_product(v) # optional - sage.libs.pari True - sage: vh.is_alternating() + sage: vh.is_alternating() # optional - sage.libs.pari True - sage: random_vector(F, 5).cross_product_matrix() + sage: random_vector(F, 5).cross_product_matrix() # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: Cross product only defined for vectors of length three or seven, not 5 @@ -2828,11 +2830,11 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: W = VectorSpace(GF(3),3) - sage: w = W([0,1,2]) - sage: w.pairwise_product(v) + sage: W = VectorSpace(GF(3), 3) # optional - sage.libs.pari + sage: w = W([0,1,2]) # optional - sage.libs.pari + sage: w.pairwise_product(v) # optional - sage.libs.pari (0, 2, 0) - sage: w.pairwise_product(v).parent() + sage: w.pairwise_product(v).parent() # optional - sage.libs.pari Vector space of dimension 3 over Finite Field of size 3 Implicit coercion is well defined (regardless of order), so we @@ -3401,9 +3403,9 @@ cdef class FreeModuleElement(Vector): # abstract base class But some inputs are not compatible, even if vectors. :: - sage: w = vector(GF(5), [1,2]) - sage: v = vector(GF(7), [1,2,3,4]) - sage: z = w.outer_product(v) + sage: w = vector(GF(5), [1,2]) # optional - sage.libs.pari + sage: v = vector(GF(7), [1,2,3,4]) # optional - sage.libs.pari + sage: z = w.outer_product(v) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 1 dense matrices over Finite Field of size 5' and 'Full MatrixSpace of 1 by 4 dense matrices over Finite Field of size 7' @@ -3825,19 +3827,19 @@ cdef class FreeModuleElement(Vector): # abstract base class :: sage: m = vector(ZZ, 9, range(9)) - sage: k. = GF(9) - sage: m.apply_map(k) + sage: k. = GF(9) # optional - sage.libs.pari + sage: m.apply_map(k) # optional - sage.libs.pari (0, 1, 2, 0, 1, 2, 0, 1, 2) In this example, we explicitly specify the codomain. :: - sage: s = GF(3) - sage: f = lambda x: s(x) - sage: n = m.apply_map(f, k); n + sage: s = GF(3) # optional - sage.libs.pari + sage: f = lambda x: s(x) # optional - sage.libs.pari + sage: n = m.apply_map(f, k); n # optional - sage.libs.pari (0, 1, 2, 0, 1, 2, 0, 1, 2) - sage: n.parent() + sage: n.parent() # optional - sage.libs.pari Vector space of dimension 9 over Finite Field in a of size 3^2 If your map sends 0 to a non-zero value, then your resulting @@ -3893,10 +3895,10 @@ cdef class FreeModuleElement(Vector): # abstract base class Check that the bug in :trac:`14558` has been fixed:: - sage: F. = GF(9) - sage: v = vector([a, 0,0,0], sparse=True) - sage: f = F.hom([a**3]) - sage: v.apply_map(f) + sage: F. = GF(9) # optional - sage.libs.pari + sage: v = vector([a, 0, 0, 0], sparse=True) # optional - sage.libs.pari + sage: f = F.hom([a**3]) # optional - sage.libs.pari + sage: v.apply_map(f) # optional - sage.libs.pari (2*a + 1, 0, 0, 0) """ if sparse is None: @@ -4704,8 +4706,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): We correctly initialize values which become 0 only after coercion:: - sage: v = FreeModuleElement_generic_sparse(S(GF(3),6), [1,2,3,4,5,6]) - sage: v.nonzero_positions() + sage: v = FreeModuleElement_generic_sparse(S(GF(3), 6), [1,2,3,4,5,6]) # optional - sage.libs.pari + sage: v.nonzero_positions() # optional - sage.libs.pari [0, 1, 3, 4] """ #WARNING: In creation, we do not check that the indices i satisfy @@ -4913,10 +4915,10 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): Check that the bug in :trac:`13929` has been fixed:: - sage: V = FreeModule( GF(3), 2, sparse=True) - sage: a = V([0,1]) - sage: b = V([1,0]) - sage: a < b + sage: V = FreeModule(GF(3), 2, sparse=True) # optional - sage.libs.pari + sage: a = V([0,1]) # optional - sage.libs.pari + sage: b = V([1,0]) # optional - sage.libs.pari + sage: a < b # optional - sage.libs.pari True """ a = sorted((left)._entries.iteritems()) @@ -5049,16 +5051,16 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: V = VectorSpace(GF(17), 10000000, sparse=True) - sage: w = V(0) - sage: w[39893] = 20 - sage: w[39893] + sage: V = VectorSpace(GF(17), 10000000, sparse=True) # optional - sage.libs.pari + sage: w = V(0) # optional - sage.libs.pari + sage: w[39893] = 20 # optional - sage.libs.pari + sage: w[39893] # optional - sage.libs.pari 3 - sage: w[39000:39003] = [4, 5, 6]; w[39000:39003] + sage: w[39000:39003] = [4, 5, 6]; w[39000:39003] # optional - sage.libs.pari (4, 5, 6) - sage: parent(w[39893]) + sage: parent(w[39893]) # optional - sage.libs.pari Finite Field of size 17 - sage: w[39893] = sqrt(2) + sage: w[39893] = sqrt(2) # optional - sage.libs.pari, sage.symbolic Traceback (most recent call last): ... TypeError: self must be a numeric expression From 7dcc84f6e74e6c453fbd01819c35eab74836999b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 25 Feb 2023 23:28:49 -0800 Subject: [PATCH 06/99] sage.modules, sage.matrix: More # optional --- src/sage/matrix/args.pyx | 26 +- src/sage/matrix/echelon_matrix.pyx | 20 +- src/sage/matrix/matrix0.pyx | 176 +-- src/sage/matrix/matrix1.pyx | 66 +- src/sage/matrix/matrix_polynomial_dense.pyx | 1094 ++++++++++--------- src/sage/matrix/matrix_space.py | 223 ++-- src/sage/matrix/matrix_sparse.pyx | 34 +- src/sage/matrix/symplectic_basis.py | 19 +- src/sage/matrix/tests.py | 4 +- src/sage/modules/matrix_morphism.py | 17 +- 10 files changed, 857 insertions(+), 822 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index f52780e8b95..eeeb9f47f09 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -758,10 +758,10 @@ cdef class MatrixArgs: :: - sage: ma = MatrixArgs(GF(2), 2, 3, L) - sage: ma.dict(convert=False) + sage: ma = MatrixArgs(GF(2), 2, 3, L) # optional - sage.libs.pari + sage: ma.dict(convert=False) # optional - sage.libs.pari {(0, 1): 1, (0, 2): 2, (1, 0): 3, (1, 1): 4, (1, 2): 5} - sage: ma.dict() + sage: ma.dict() # optional - sage.libs.pari {(0, 1): 1, (1, 0): 1, (1, 2): 1} """ self.finalize() @@ -1222,21 +1222,21 @@ cdef class MatrixArgs: Check that :trac:`26655` is fixed:: - sage: F. = GF(9) - sage: M = MatrixSpace(F, 2, 2) - sage: A = M([[1, a], [0, 1]]) - sage: M(pari(A)) + sage: F. = GF(9) # optional - sage.libs.pari + sage: M = MatrixSpace(F, 2, 2) # optional - sage.libs.pari + sage: A = M([[1, a], [0, 1]]) # optional - sage.libs.pari + sage: M(pari(A)) # optional - sage.libs.pari [1 a] [0 1] Constructing a matrix from a PARI ``t_VEC`` or ``t_COL`` with ``t_VEC`` or ``t_COL`` elements is currently not supported:: - sage: M(pari([1, a, 0, 1])) + sage: M(pari([1, a, 0, 1])) # optional - sage.libs.pari Traceback (most recent call last): ... NameError: name 'a' is not defined - sage: M(pari([[1, a], [0, 1]])) + sage: M(pari([[1, a], [0, 1]])) # optional - sage.libs.pari Traceback (most recent call last): ... NameError: name 'a' is not defined @@ -1350,12 +1350,12 @@ cpdef MatrixArgs MatrixArgs_init(space, entries): EXAMPLES:: sage: from sage.matrix.args import MatrixArgs_init - sage: S = MatrixSpace(GF(2), 2, 4) - sage: ma = MatrixArgs_init(S, {(1,3):7}) - sage: M = ma.matrix(); M + sage: S = MatrixSpace(GF(2), 2, 4) # optional - sage.libs.pari + sage: ma = MatrixArgs_init(S, {(1, 3): 7}) # optional - sage.libs.pari + sage: M = ma.matrix(); M # optional - sage.libs.pari [0 0 0 0] [0 0 0 1] - sage: parent(M) is S + sage: parent(M) is S # optional - sage.libs.pari True """ cdef MatrixArgs ret diff --git a/src/sage/matrix/echelon_matrix.pyx b/src/sage/matrix/echelon_matrix.pyx index 3fc43b485ca..59127dfdaef 100644 --- a/src/sage/matrix/echelon_matrix.pyx +++ b/src/sage/matrix/echelon_matrix.pyx @@ -48,8 +48,8 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, EXAMPLES:: sage: from sage.matrix.echelon_matrix import reduced_echelon_matrix_iterator - sage: it = reduced_echelon_matrix_iterator(GF(2),2,3) - sage: for m in it: + sage: it = reduced_echelon_matrix_iterator(GF(2), 2, 3) # optional - sage.libs.pari + sage: for m in it: # optional - sage.libs.pari ....: print(m) ....: print(m.pivots()) ....: print("*******") @@ -87,21 +87,21 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, Testing cardinalities:: sage: q = 71 - sage: F = GF(q) - sage: len(list(reduced_echelon_matrix_iterator(F, 1, 3, copy=False))) == q**2+q+1 + sage: F = GF(q) # optional - sage.libs.pari + sage: len(list(reduced_echelon_matrix_iterator(F, 1, 3, copy=False))) == q**2+q+1 # optional - sage.libs.pari True - sage: len(list(reduced_echelon_matrix_iterator(F, 2, 3, copy=False))) == q**2+q+1 + sage: len(list(reduced_echelon_matrix_iterator(F, 2, 3, copy=False))) == q**2+q+1 # optional - sage.libs.pari True Testing options:: - sage: it = reduced_echelon_matrix_iterator(GF(4,'z'), 2, 4, copy=False) - sage: next(it) is next(it) + sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, copy=False) # optional - sage.libs.pari + sage: next(it) is next(it) # optional - sage.libs.pari True - sage: for a in it: pass + sage: for a in it: pass # optional - sage.libs.pari - sage: it = reduced_echelon_matrix_iterator(GF(4,'z'), 2, 4, set_immutable=True) - sage: all(a.is_immutable() and a.echelon_form() == a for a in it) + sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, set_immutable=True) # optional - sage.libs.pari + sage: all(a.is_immutable() and a.echelon_form() == a for a in it) # optional - sage.libs.pari True """ cdef Matrix m0,m,mm diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 572936b9c42..8a4b0922d40 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -907,16 +907,18 @@ cdef class Matrix(sage.structure.element.Matrix): Check that submatrices with a specified implementation have the same implementation:: - sage: M = MatrixSpace(GF(2), 3, 3, implementation='generic') - sage: m = M(range(9)) - sage: type(m) + sage: M = MatrixSpace(GF(2), 3, 3, implementation='generic') # optional - sage.libs.pari + sage: m = M(range(9)) # optional - sage.libs.pari + sage: type(m) # optional - sage.libs.pari - sage: parent(m) - Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 2 (using Matrix_generic_dense) - sage: type(m[:2,:2]) + sage: parent(m) # optional - sage.libs.pari + Full MatrixSpace of 3 by 3 dense matrices + over Finite Field of size 2 (using Matrix_generic_dense) + sage: type(m[:2,:2]) # optional - sage.libs.pari sage: parent(m[:2,:2]) - Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 2 (using Matrix_generic_dense) + Full MatrixSpace of 2 by 2 dense matrices # optional - sage.libs.pari + over Finite Field of size 2 (using Matrix_generic_dense) """ cdef list row_list cdef list col_list @@ -1637,12 +1639,13 @@ cdef class Matrix(sage.structure.element.Matrix): sage: A = Matrix(QQ, 2, 2, [1/2, 1/3, 1/3, 1/4]) sage: A.parent() Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: A.change_ring(GF(25,'a')) + sage: A.change_ring(GF(25,'a')) # optional - sage.libs.pari [3 2] [2 4] - sage: A.change_ring(GF(25,'a')).parent() - Full MatrixSpace of 2 by 2 dense matrices over Finite Field in a of size 5^2 - sage: A.change_ring(ZZ) + sage: A.change_ring(GF(25,'a')).parent() # optional - sage.libs.pari + Full MatrixSpace of 2 by 2 dense matrices + over Finite Field in a of size 5^2 + sage: A.change_ring(ZZ) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: matrix has denominators so can...t change to ZZ @@ -1653,7 +1656,7 @@ cdef class Matrix(sage.structure.element.Matrix): [1/2 1/3] [-------] [1/3 1/4] - sage: A.change_ring(GF(25,'a')) + sage: A.change_ring(GF(25,'a')) # optional - sage.libs.pari [3 2] [---] [2 4] @@ -3987,44 +3990,44 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], + sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], # optional - sage.rings.number_field ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) - sage: A._is_hermitian(skew=False, tolerance=0) + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False - sage: B = A*A.conjugate_transpose() - sage: B._is_hermitian(skew=False, tolerance=0) + sage: B = A*A.conjugate_transpose() # optional - sage.rings.number_field + sage: B._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field True Sage has several fields besides the entire complex numbers where conjugation is non-trivial:: - sage: F. = QuadraticField(-7) - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], + sage: F. = QuadraticField(-7) # optional - sage.rings.number_field + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C._is_hermitian(skew=False, tolerance=0) + sage: C._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False - sage: C = C*C.conjugate_transpose() - sage: C._is_hermitian(skew=False, tolerance=0) + sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field + sage: C._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field True A matrix that is nearly Hermitian, but for a non-real diagonal entry:: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A._is_hermitian(skew=False, tolerance=0) + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False - sage: A[1,1] = 132 - sage: A._is_hermitian(skew=False, tolerance=0) + sage: A[1, 1] = 132 # optional - sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field True Rectangular matrices are never Hermitian:: - sage: A = matrix(QQbar, 3, 4) - sage: A._is_hermitian(skew=False, tolerance=0) + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False A square, empty matrix is trivially Hermitian:: @@ -4034,10 +4037,11 @@ cdef class Matrix(sage.structure.element.Matrix): True A matrix that is skew-Hermitian:: - sage: A = matrix(QQbar, [[-I, 2+I], [-2+I, 0]]) - sage: A._is_hermitian(skew=False, tolerance=0) + + sage: A = matrix(QQbar, [[-I, 2+I], [-2+I, 0]]) # optional - sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field False - sage: A._is_hermitian(skew=True, tolerance=0) + sage: A._is_hermitian(skew=True, tolerance=0) # optional - sage.rings.number_field True """ key = ("_is_hermitian", skew, tolerance) @@ -4129,43 +4133,43 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], + sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], # optional - sage.rings.number_field ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field False - sage: B = A*A.conjugate_transpose() - sage: B.is_hermitian() + sage: B = A*A.conjugate_transpose() # optional - sage.rings.number_field + sage: B.is_hermitian() # optional - sage.rings.number_field True Sage has several fields besides the entire complex numbers where conjugation is non-trivial. :: - sage: F. = QuadraticField(-7) - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], + sage: F. = QuadraticField(-7) # optional - sage.rings.number_field + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C.is_hermitian() + sage: C.is_hermitian() # optional - sage.rings.number_field False - sage: C = C*C.conjugate_transpose() - sage: C.is_hermitian() + sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field + sage: C.is_hermitian() # optional - sage.rings.number_field True A matrix that is nearly Hermitian, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field False - sage: A[1,1] = 132 - sage: A.is_hermitian() + sage: A[1, 1] = 132 # optional - sage.rings.number_field + sage: A.is_hermitian() # optional - sage.rings.number_field True Rectangular matrices are never Hermitian. :: - sage: A = matrix(QQbar, 3, 4) + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field sage: A.is_hermitian() False @@ -4204,27 +4208,27 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[0, -1], + sage: A = matrix(QQbar, [[0, -1], # optional - sage.rings.number_field ....: [1, 0]]) - sage: A.is_skew_hermitian() + sage: A.is_skew_hermitian() # optional - sage.rings.number_field True A matrix that is nearly skew-Hermitian, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ -I, -1, 1-I], + sage: A = matrix(QQbar, [[ -I, -1, 1-I], # optional - sage.rings.number_field ....: [ 1, 1, -1], ....: [-1-I, 1, -I]]) - sage: A.is_skew_hermitian() + sage: A.is_skew_hermitian() # optional - sage.rings.number_field False - sage: A[1,1] = -I - sage: A.is_skew_hermitian() + sage: A[1, 1] = -I # optional - sage.rings.number_field + sage: A.is_skew_hermitian() # optional - sage.rings.number_field True Rectangular matrices are never skew-Hermitian. :: - sage: A = matrix(QQbar, 3, 4) - sage: A.is_skew_hermitian() + sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field + sage: A.is_skew_hermitian() # optional - sage.rings.number_field False A square, empty matrix is trivially Hermitian. :: @@ -4627,8 +4631,8 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: m = matrix(GF(7),5,range(25)) - sage: m.rank() + sage: m = matrix(GF(7), 5, range(25)) # optional - sage.libs.pari + sage: m.rank() # optional - sage.libs.pari 2 Rank is not implemented over the integers modulo a composite yet.:: @@ -4644,10 +4648,10 @@ cdef class Matrix(sage.structure.element.Matrix): We should be able to compute the rank of a matrix whose entries are polynomials over a finite field (:trac:`5014`):: - sage: P. = PolynomialRing(GF(17)) - sage: m = matrix(P, [ [ 6*x^2 + 8*x + 12, 10*x^2 + 4*x + 11], - ....: [8*x^2 + 12*x + 15, 8*x^2 + 9*x + 16] ]) - sage: m.rank() + sage: P. = PolynomialRing(GF(17)) # optional - sage.libs.pari + sage: m = matrix(P, [[ 6*x^2 + 8*x + 12, 10*x^2 + 4*x + 11], # optional - sage.libs.pari + ....: [8*x^2 + 12*x + 15, 8*x^2 + 9*x + 16]]) + sage: m.rank() # optional - sage.libs.pari 2 """ x = self.fetch('rank') @@ -4879,21 +4883,21 @@ cdef class Matrix(sage.structure.element.Matrix): Over finite fields:: - sage: A = matrix(GF(59),3,[10,56,39,53,56,33,58,24,55]) - sage: A.multiplicative_order() + sage: A = matrix(GF(59), 3, [10,56,39,53,56,33,58,24,55]) # optional - sage.libs.pari + sage: A.multiplicative_order() # optional - sage.libs.pari 580 - sage: (A^580).is_one() + sage: (A^580).is_one() # optional - sage.libs.pari True - sage: B = matrix(GF(10007^3,'b'),0) - sage: B.multiplicative_order() + sage: B = matrix(GF(10007^3, 'b'), 0) # optional - sage.libs.pari + sage: B.multiplicative_order() # optional - sage.libs.pari 1 - sage: M = MatrixSpace(GF(11^2,'e'),5) - sage: E = M.random_element() - sage: while E.det() == 0: + sage: M = MatrixSpace(GF(11^2, 'e'), 5) # optional - sage.libs.pari + sage: E = M.random_element() # optional - sage.libs.pari + sage: while E.det() == 0: # optional - sage.libs.pari ....: E = M.random_element() - sage: (E^E.multiplicative_order()).is_one() + sage: (E^E.multiplicative_order()).is_one() # optional - sage.libs.pari True Over `\ZZ`:: @@ -4934,8 +4938,8 @@ cdef class Matrix(sage.structure.element.Matrix): TESTS:: - sage: C = matrix(GF(2^10,'c'),2,3,[1]*6) - sage: C.multiplicative_order() + sage: C = matrix(GF(2^10, 'c'), 2, 3, [1]*6) # optional - sage.libs.pari + sage: C.multiplicative_order() # optional - sage.libs.pari Traceback (most recent call last): ... ArithmeticError: self must be invertible ... @@ -5387,43 +5391,45 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLE of matrix times matrix over different base rings:: - sage: a = matrix(ZZ,2,2,range(4)) - sage: b = matrix(GF(7),2,2,range(4)) - sage: c = matrix(QQ,2,2,range(4)) - sage: d = a*b; d + sage: a = matrix(ZZ, 2, 2, range(4)) + sage: b = matrix(GF(7), 2, 2, range(4)) # optional - sage.libs.pari + sage: c = matrix(QQ, 2, 2, range(4)) + sage: d = a * b; d # optional - sage.libs.pari [2 3] [6 4] - sage: parent(d) + sage: parent(d) # optional - sage.libs.pari Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 - sage: parent(b*a) + sage: parent(b * a) # optional - sage.libs.pari Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 - sage: d = a*c; d + sage: d = a * c; d [ 2 3] [ 6 11] sage: parent(d) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: d = b+c + sage: d = b + c # optional - sage.libs.pari Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7' and 'Full MatrixSpace of 2 by 2 dense matrices over Rational Field' - sage: d = b+c.change_ring(GF(7)); d + TypeError: unsupported operand parent(s) for +: + 'Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7' and + 'Full MatrixSpace of 2 by 2 dense matrices over Rational Field' + sage: d = b + c.change_ring(GF(7)); d # optional - sage.libs.pari [0 2] [4 6] EXAMPLE of matrix times matrix where one matrix is sparse and the other is dense (in such mixed cases, the result is always dense):: - sage: a = matrix(ZZ,2,2,range(4),sparse=True) - sage: b = matrix(GF(7),2,2,range(4),sparse=False) - sage: c = a*b; c + sage: a = matrix(ZZ, 2, 2, range(4), sparse=True) + sage: b = matrix(GF(7), 2, 2, range(4), sparse=False) # optional - sage.libs.pari + sage: c = a * b; c # optional - sage.libs.pari [2 3] [6 4] - sage: parent(c) + sage: parent(c) # optional - sage.libs.pari Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 - sage: c = b*a; c + sage: c = b * a; c # optional - sage.libs.pari [2 3] [6 4] - sage: parent(c) + sage: parent(c) # optional - sage.libs.pari Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 EXAMPLE of matrix multiplication over a noncommutative base ring:: diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 8983192931b..d11687cadb7 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -5,8 +5,8 @@ For design documentation see :mod:`sage.matrix.docs`. TESTS:: - sage: A = Matrix(GF(5),3,3,srange(9)) - sage: TestSuite(A).run() + sage: A = Matrix(GF(5), 3, 3, srange(9)) # optional - sage.libs.pari + sage: TestSuite(A).run() # optional - sage.libs.pari """ #***************************************************************************** @@ -110,13 +110,13 @@ cdef class Matrix(Matrix0): Particularly difficult is the case of matrices over cyclotomic fields and general number fields. See :trac:`5618` and :trac:`8909`:: - sage: K. = CyclotomicField(8) - sage: A = MatrixSpace(K,2,2)([0,1+zeta,2*zeta,3]) - sage: g = gap(A); g + sage: K. = CyclotomicField(8) # optional - sage.rings.number_field + sage: A = MatrixSpace(K, 2, 2)([0, 1+zeta, 2*zeta, 3]) # optional - sage.rings.number_field + sage: g = gap(A); g # optional - sage.rings.number_field [ [ 0, 1+E(8) ], [ 2*E(8), 3 ] ] - sage: matrix(K, g) == A + sage: matrix(K, g) == A # optional - sage.rings.number_field True - sage: g.IsMatrix() + sage: g.IsMatrix() # optional - sage.rings.number_field true sage: x = polygen(ZZ, 'x') @@ -124,7 +124,7 @@ cdef class Matrix(Matrix0): sage: A = MatrixSpace(L, 2, 2)([0, 1+tau, 2*tau, 3]) # optional - sage.rings.number_field sage: g = gap(A); g # optional - sage.rings.number_field [ [ !0, tau+1 ], [ 2*tau, !3 ] ] - sage: matrix(L, g) == A + sage: matrix(L, g) == A # optional - sage.rings.number_field True """ cdef Py_ssize_t i, j @@ -153,9 +153,9 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: libgap(identity_matrix(ZZ,2)) + sage: libgap(identity_matrix(ZZ, 2)) [ [ 1, 0 ], [ 0, 1 ] ] - sage: libgap(matrix(GF(3),2,2,[4,5,6,7])) + sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # optional - sage.libs.pari [ [ Z(3)^0, Z(3) ], [ 0*Z(3), Z(3)^0 ] ] """ from sage.libs.gap.libgap import libgap @@ -336,9 +336,9 @@ cdef class Matrix(Matrix0): We coerce a matrix over a cyclotomic field, where the generator must be named during the coercion. :: - sage: K = CyclotomicField(9) ; z = K.0 - sage: M = matrix(K,3,3,[0,1,3,z,z**4,z-1,z**17,1,0]) - sage: M + sage: K = CyclotomicField(9); z = K.0 # optional - sage.rings.number_field + sage: M = matrix(K, 3, 3, [0,1,3,z,z**4,z-1,z**17,1,0]) # optional - sage.rings.number_field + sage: M # optional - sage.rings.number_field [ 0 1 3] [ zeta9 zeta9^4 zeta9 - 1] [-zeta9^5 - zeta9^2 1 0] @@ -405,12 +405,12 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: M = matrix(ZZ,2,range(4)) - sage: polymake(M) # optional - jupymake + sage: polymake(M) # optional - jupymake 0 1 2 3 - sage: K. = QuadraticField(5) - sage: M = matrix(K, [[1, 2], [sqrt5, 3]]) - sage: polymake(M) # optional - jupymake + sage: K. = QuadraticField(5) # optional - sage.rings.number_field + sage: M = matrix(K, [[1, 2], [sqrt5, 3]]) # optional - sage.rings.number_field + sage: polymake(M) # optional - jupymake # optional - sage.rings.number_field 1 2 0+1r5 3 """ @@ -626,9 +626,9 @@ cdef class Matrix(Matrix0): sage: sage_input(matrix(QQ, 3, 3, [5..13])/7, verify=True) # Verified matrix(QQ, [[5/7, 6/7, 1], [8/7, 9/7, 10/7], [11/7, 12/7, 13/7]]) - sage: M = MatrixSpace(GF(5), 50, 50, sparse=True).random_element(density=0.002) - sage: input = sage_input(M, verify=True) - sage: sage_eval(input) == M + sage: M = MatrixSpace(GF(5), 50, 50, sparse=True).random_element(density=0.002) # optional - sage.libs.pari + sage: input = sage_input(M, verify=True) # optional - sage.libs.pari + sage: sage_eval(input) == M # optional - sage.libs.pari True sage: from sage.misc.sage_input import SageInputBuilder sage: matrix(RDF, [[3, 1], [4, 1]])._sage_input_(SageInputBuilder(), False) @@ -2450,7 +2450,7 @@ cdef class Matrix(Matrix0): Specify a different base ring for the output:: - sage: M.zero_pattern_matrix(GF(2)).base_ring() + sage: M.zero_pattern_matrix(GF(2)).base_ring() # optional - sage.libs.pari Finite Field of size 2 Examples for different base rings for ``self``:: @@ -2466,36 +2466,36 @@ cdef class Matrix(Matrix0): :: - sage: W. = CyclotomicField(100) - sage: M = Matrix(2, 3, [a, a/2, 0, a^2, a^100-1, a^2 - a]); M + sage: W. = CyclotomicField(100) # optional - sage.rings.number_field + sage: M = Matrix(2, 3, [a, a/2, 0, a^2, a^100-1, a^2 - a]); M # optional - sage.rings.number_field [ a 1/2*a 0] [ a^2 0 a^2 - a] - sage: M.zero_pattern_matrix() + sage: M.zero_pattern_matrix() # optional - sage.rings.number_field [0 0 1] [0 1 0] :: - sage: K. = GF(2^4) - sage: l = [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1, + sage: K. = GF(2^4) # optional - sage.libs.pari + sage: l = [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1, # optional - sage.libs.pari ....: a + 1, a^2, a^3 + a + 1, a^3 + a, a^3 + a] - sage: M = Matrix(K, 3, 4, l); M + sage: M = Matrix(K, 3, 4, l); M # optional - sage.libs.pari [ a^2 + 1 a^3 + 1 0 0] [ a a^3 + a + 1 a + 1 a + 1] [ a^2 a^3 + a + 1 a^3 + a a^3 + a] - sage: M.zero_pattern_matrix() + sage: M.zero_pattern_matrix() # optional - sage.libs.pari [0 0 1 1] [0 0 0 0] [0 0 0 0] :: - sage: K. = GF(25) - sage: M = Matrix(K, 2, 3, [0, 2, 3, 5, a, a^2]) - sage: M + sage: K. = GF(25) # optional - sage.libs.pari + sage: M = Matrix(K, 2, 3, [0, 2, 3, 5, a, a^2]) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari [ 0 2 3] [ 0 a a + 3] - sage: M.zero_pattern_matrix() + sage: M.zero_pattern_matrix() # optional - sage.libs.pari [1 0 0] [1 0 0] @@ -2582,7 +2582,7 @@ cdef class Matrix(Matrix0): dict items are ETuples (see :trac:`17658`):: sage: from sage.rings.polynomial.polydict import ETuple - sage: matrix(GF(5^2,"z"),{ETuple((1, 1)): 2}).dense_matrix() + sage: matrix(GF(5^2, "z"), {ETuple((1, 1)): 2}).dense_matrix() # optional - sage.libs.pari [0 0] [0 2] """ diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 532350bdc66..4f409850406 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -113,11 +113,11 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix( pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) - sage: M._check_shift_dimension(shifts=[1,3,2]) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari + sage: M._check_shift_dimension(shifts=[1,3,2]) # optional - sage.libs.pari - sage: M._check_shift_dimension(shifts=[1,3,2], row_wise=False) + sage: M._check_shift_dimension(shifts=[1,3,2], row_wise=False) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: shifts length should be the row dimension @@ -139,21 +139,21 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix( pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) - sage: M.degree() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari + sage: M.degree() # optional - sage.libs.pari 3 The zero matrix has degree ``-1``:: - sage: M = Matrix( pR, 2, 3 ) - sage: M.degree() + sage: M = Matrix(pR, 2, 3) # optional - sage.libs.pari + sage: M.degree() # optional - sage.libs.pari -1 For an empty matrix, the degree is not defined:: - sage: M = Matrix( pR, 3, 0 ) - sage: M.degree() + sage: M = Matrix(pR, 3, 0) # optional - sage.libs.pari + sage: M.degree() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: empty matrix does not have a degree @@ -193,20 +193,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix( pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) - sage: M.degree_matrix() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari + sage: M.degree_matrix() # optional - sage.libs.pari [ 1 -1 0] [ 3 -1 -1] - sage: M.degree_matrix(shifts=[0,1,2]) + sage: M.degree_matrix(shifts=[0,1,2]) # optional - sage.libs.pari [ 1 -1 2] [ 3 -1 -1] The zero entries in the polynomial matrix can be identified in the (shifted) degree matrix as the entries equal to ``min(shifts)-1``:: - sage: M.degree_matrix(shifts=[-2,1,2]) + sage: M.degree_matrix(shifts=[-2,1,2]) # optional - sage.libs.pari [-1 -3 2] [ 1 -3 -3] @@ -214,7 +214,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): rows of the matrix (which, in terms of modules, means that we are working column-wise, see the class documentation):: - sage: M.degree_matrix(shifts=[-1,2], row_wise=False) + sage: M.degree_matrix(shifts=[-1,2], row_wise=False) # optional - sage.libs.pari [ 0 -2 -1] [ 5 -2 -2] """ @@ -241,14 +241,14 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.libs.pari ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.constant_matrix() + sage: M.constant_matrix() # optional - sage.libs.pari [1 5 4 0] [1 1 2 0] [4 1 5 6] @@ -266,18 +266,18 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.libs.pari ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.is_constant() + sage: M.is_constant() # optional - sage.libs.pari False - sage: M = Matrix(pR,[[1,5,2],[3,1,5]]); M.is_constant() + sage: M = Matrix(pR, [[1,5,2], [3,1,5]]); M.is_constant() # optional - sage.libs.pari True - sage: M = Matrix.zero(pR,3,5); M.is_constant() + sage: M = Matrix.zero(pR, 3, 5); M.is_constant() # optional - sage.libs.pari True .. SEEALSO:: @@ -313,48 +313,48 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.libs.pari ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.coefficient_matrix(2) + sage: M.coefficient_matrix(2) # optional - sage.libs.pari [5 0 0 0] [6 0 0 0] [4 0 2 1] - sage: M.coefficient_matrix(0) == M.constant_matrix() + sage: M.coefficient_matrix(0) == M.constant_matrix() # optional - sage.libs.pari True Row-wise and column-wise coefficient extraction are available:: - sage: M.coefficient_matrix([3,2,1]) + sage: M.coefficient_matrix([3,2,1]) # optional - sage.libs.pari [1 0 0 0] [6 0 0 0] [6 5 5 5] - sage: M.coefficient_matrix([2,0,1,3], row_wise=False) + sage: M.coefficient_matrix([2,0,1,3], row_wise=False) # optional - sage.libs.pari [5 5 6 0] [6 1 0 0] [4 1 5 0] Negative degrees give zero coefficients:: - sage: M.coefficient_matrix([-1,0,1,3], row_wise=False) + sage: M.coefficient_matrix([-1,0,1,3], row_wise=False) # optional - sage.libs.pari [0 5 6 0] [0 1 0 0] [0 1 5 0] Length of list of degrees is checked:: - sage: M.coefficient_matrix([2,1,1,2]) + sage: M.coefficient_matrix([2,1,1,2]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: length of input degree list should be the row dimension of the input matrix - sage: M.coefficient_matrix([3,2,1], row_wise=False) + sage: M.coefficient_matrix([3,2,1], row_wise=False) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: length of input degree list should be the column @@ -409,41 +409,41 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.libs.pari ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.truncate(2) + sage: M.truncate(2) # optional - sage.libs.pari [5*x + 1 5 6*x + 4 0] [3*x + 1 1 2 0] [6*x + 4 5*x + 1 5*x + 5 5*x + 6] - sage: M.truncate(1) == M.constant_matrix() + sage: M.truncate(1) == M.constant_matrix() # optional - sage.libs.pari True Row-wise and column-wise truncation are available:: - sage: M.truncate([3,2,1]) + sage: M.truncate([3,2,1]) # optional - sage.libs.pari [5*x^2 + 5*x + 1 5 6*x + 4 0] [ 3*x + 1 1 2 0] [ 4 1 5 6] - sage: M.truncate([2,1,1,2], row_wise=False) + sage: M.truncate([2,1,1,2], row_wise=False) # optional - sage.libs.pari [5*x + 1 5 4 0] [3*x + 1 1 2 0] [6*x + 4 1 5 5*x + 6] Length of list of truncation orders is checked:: - sage: M.truncate([2,1,1,2]) + sage: M.truncate([2,1,1,2]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: length of input precision list should be the row dimension of the input matrix - sage: M.truncate([3,2,1], row_wise=False) + sage: M.truncate([3,2,1], row_wise=False) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: length of input precision list should be the column @@ -500,42 +500,42 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.libs.pari ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.shift(-2) + sage: M.shift(-2) # optional - sage.libs.pari [ x + 5 0 0 0] [ 6 0 0 0] [2*x + 4 0 2 1] Row-wise and column-wise shifting are available:: - sage: M.shift([-1,2,-2]) + sage: M.shift([-1,2,-2]) # optional - sage.libs.pari [ x^2 + 5*x + 5 0 6 0] [6*x^4 + 3*x^3 + x^2 x^2 2*x^2 0] [ 2*x + 4 0 2 1] - sage: M.shift([-1,1,0,0], row_wise=False) + sage: M.shift([-1,1,0,0], row_wise=False) # optional - sage.libs.pari [ x^2 + 5*x + 5 5*x 6*x + 4 0] [ 6*x + 3 x 2 0] [2*x^2 + 4*x + 6 5*x^2 + x 2*x^2 + 5*x + 5 x^2 + 5*x + 6] - sage: M.shift([-d for d in M.row_degrees()]) == M.leading_matrix() + sage: M.shift([-d for d in M.row_degrees()]) == M.leading_matrix() # optional - sage.libs.pari True Length of input shift degree list is checked:: - sage: M.shift([1,3,1,4]) + sage: M.shift([1,3,1,4]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: length of input shift list should be the row dimension of the input matrix - sage: M.shift([5,2,-1], row_wise=False) + sage: M.shift([5,2,-1], row_wise=False) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: length of input shift list should be the column @@ -608,14 +608,14 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.libs.pari ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.reverse() + sage: M.reverse() # optional - sage.libs.pari [ x^3 + 5*x^2 + 5*x + 1 5*x^3 4*x^3 + 6*x^2 0] [ x^3 + 3*x^2 + 6*x x^3 @@ -623,17 +623,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [4*x^3 + 6*x^2 + 4*x + 2 x^3 + 5*x^2 5*x^3 + 5*x^2 + 2*x 6*x^3 + 5*x^2 + x] - sage: M.reverse(1) + sage: M.reverse(1) # optional - sage.libs.pari [ x + 5 5*x 4*x + 6 0] [ x + 3 x 2*x 0] [4*x + 6 x + 5 5*x + 5 6*x + 5] - sage: M.reverse(0) == M.constant_matrix() + sage: M.reverse(0) == M.constant_matrix() # optional - sage.libs.pari True Entry-wise reversing with respect to each entry's degree:: - sage: M.reverse(entry_wise=True) + sage: M.reverse(entry_wise=True) # optional - sage.libs.pari [ x^3 + 5*x^2 + 5*x + 1 5 4*x + 6 0] [ x^2 + 3*x + 6 1 @@ -643,7 +643,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Row-wise and column-wise degree reversing are available:: - sage: M.reverse([2,3,1]) + sage: M.reverse([2,3,1]) # optional - sage.libs.pari [ x^2 + 5*x + 5 5*x^2 4*x^2 + 6*x 0] [x^3 + 3*x^2 + 6*x x^3 2*x^3 @@ -651,7 +651,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 6 x + 5 5*x + 5 6*x + 5] - sage: M.reverse(M.column_degrees(),row_wise=False) + sage: M.reverse(M.column_degrees(), row_wise=False) # optional - sage.libs.pari [ x^3 + 5*x^2 + 5*x + 1 5*x 4*x^2 + 6*x 0] [ x^3 + 3*x^2 + 6*x x @@ -661,19 +661,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Wrong length or negativity of input degree raise errors: - sage: M.reverse([1,3,1,4]) + sage: M.reverse([1,3,1,4]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: length of input degree list should be the row dimension of the input matrix - sage: M.reverse([5,2,1], row_wise=False) + sage: M.reverse([5,2,1], row_wise=False) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: length of input degree list should be the column dimension of the input matrix - sage: M.reverse([2,3,-1]) + sage: M.reverse([2,3,-1]) # optional - sage.libs.pari Traceback (most recent call last): ... OverflowError: can't convert negative value to unsigned long @@ -742,30 +742,30 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 3, 3, \ - [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], \ - [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], \ - [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: B = A.inverse_series_trunc(4); B + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: A = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], + ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], + ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) + sage: B = A.inverse_series_trunc(4); B # optional - sage.libs.pari [ x^3 + 5*x^2 + x + 4 x^3 + 5*x^2 + 6*x + 4 6*x^2 + 5*x + 3] [ 4*x^2 + 5*x + 6 6*x^3 + x^2 + x + 6 3*x^3 + 2*x^2 + 2] [5*x^3 + 5*x^2 + 6*x + 6 4*x^3 + 2*x^2 + 6*x + 4 6*x^3 + x^2 + 6*x + 1] - sage: (B*A).truncate(4) == 1 + sage: (B*A).truncate(4) == 1 # optional - sage.libs.pari True - sage: A.inverse_series_trunc(0) + sage: A.inverse_series_trunc(0) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: the precision must be positive - sage: A[:2,:].inverse_series_trunc(4) + sage: A[:2,:].inverse_series_trunc(4) # optional - sage.libs.pari Traceback (most recent call last): ... ArithmeticError: the input matrix must be square - sage: A[0,:] = A[0,:] - A[0,:](0) + A[1,:](0) + A[2,:](0) - sage: A.inverse_series_trunc(4) + sage: A[0,:] = A[0,:] - A[0,:](0) + A[1,:](0) + A[2,:](0) # optional - sage.libs.pari + sage: A.inverse_series_trunc(4) # optional - sage.libs.pari Traceback (most recent call last): ... ZeroDivisionError: the constant matrix term self(0) must be invertible @@ -839,61 +839,61 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 3, 3, \ - [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], \ - [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], \ - [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: A.is_square() and A.constant_matrix().is_invertible() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: A = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], + ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], + ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) + sage: A.is_square() and A.constant_matrix().is_invertible() # optional - sage.libs.pari True - sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) - sage: X = A.solve_left_series_trunc(B,4); X + sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) # optional - sage.libs.pari + sage: X = A.solve_left_series_trunc(B, 4); X # optional - sage.libs.pari (3*x^3 + 3*x^2 + 2*x + 4, 4*x^3 + x^2 + 2*x + 6, 6*x^3 + x + 3) - sage: B == X*A % x**4 + sage: B == X*A % x**4 # optional - sage.libs.pari True - sage: B = Matrix(pR, 2, 3, \ - [[3*x, x^2 + x + 2, x^2 + 2*x + 3], \ - [ 0, 6*x^2 + 1, 1]]) - sage: A.solve_left_series_trunc(B,3) + sage: B = Matrix(pR, 2, 3, # optional - sage.libs.pari + ....: [[3*x, x^2 + x + 2, x^2 + 2*x + 3], + ....: [ 0, 6*x^2 + 1, 1]]) + sage: A.solve_left_series_trunc(B, 3) # optional - sage.libs.pari [6*x^2 + 2*x + 2 4*x + 3 2*x^2 + 3*x] [3*x^2 + 4*x + 5 4*x^2 + 3 x^2 + 6*x + 3] - sage: X = A.solve_left_series_trunc(B,37); B == X*A % x**37 + sage: X = A.solve_left_series_trunc(B, 37); B == X*A % x**37 # optional - sage.libs.pari True Dimensions of input are checked:: - sage: A.solve_left_series_trunc(B[:,:2],3) + sage: A.solve_left_series_trunc(B[:,:2], 3) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: number of columns of self must equal number of columns of right-hand side Raises an exception when no solution:: - sage: A[2:,:].solve_left_series_trunc(B,4) + sage: A[2:,:].solve_left_series_trunc(B, 4) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matrix equation has no solutions - sage: Ax = x*A; C = vector(pR, [1,1,1]) - sage: Ax.solve_left_series_trunc(C,5) + sage: Ax = x*A; C = vector(pR, [1,1,1]) # optional - sage.libs.pari + sage: Ax.solve_left_series_trunc(C, 5) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matrix equation has no solutions Supports rectangular and rank-deficient cases:: - sage: A[:,:2].solve_left_series_trunc(B[:,:2],4) + sage: A[:,:2].solve_left_series_trunc(B[:,:2], 4) # optional - sage.libs.pari [5*x^2 + 2*x + 5 5*x + 5 2*x + 4] [5*x^3 + 2*x + 1 2*x^2 + 2*x + 5 4*x^2] - sage: V = Matrix([[3*x^2 + 4*x + 1, 4*x]]) - sage: A[:2,:].solve_left_series_trunc(V*A[:2,:], 4) == V + sage: V = Matrix([[3*x^2 + 4*x + 1, 4*x]]) # optional - sage.libs.pari + sage: A[:2,:].solve_left_series_trunc(V*A[:2,:], 4) == V # optional - sage.libs.pari True - sage: A[1,:] = (x+1) * A[0,:]; A[2,:] = (x+5) * A[0,:] - sage: B = (3*x^3+x^2+2)*A[0,:] - sage: A.solve_left_series_trunc(B, 6) + sage: A[1,:] = (x+1) * A[0,:]; A[2,:] = (x+5) * A[0,:] # optional - sage.libs.pari + sage: B = (3*x^3+x^2+2)*A[0,:] # optional - sage.libs.pari + sage: A.solve_left_series_trunc(B, 6) # optional - sage.libs.pari [4*x^2 + 6*x + 2 3*x^2 + x 0] .. SEEALSO:: @@ -986,64 +986,64 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 3, 3, \ - [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], \ - [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], \ - [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: A.is_square() and A.constant_matrix().is_invertible() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: A = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], + ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], + ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) + sage: A.is_square() and A.constant_matrix().is_invertible() # optional - sage.libs.pari True - sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) - sage: X = A.solve_right_series_trunc(B,4); X + sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) # optional - sage.libs.pari + sage: X = A.solve_right_series_trunc(B, 4); X # optional - sage.libs.pari (2*x^3 + x^2, 5*x^3 + x^2 + 5*x + 6, 4*x^3 + 6*x^2 + 4*x) - sage: B == A*X % x**4 + sage: B == A*X % x**4 # optional - sage.libs.pari True - sage: B = Matrix(pR, 3, 2, \ - [[5*x^2 + 6*x + 3, 4*x^2 + 6*x + 4], \ - [ x^2 + 4*x + 2, 5*x + 2], \ - [ 5*x + 3, 0]]) - sage: A.solve_right_series_trunc(B,3) + sage: B = Matrix(pR, 3, 2, # optional - sage.libs.pari + ....: [[5*x^2 + 6*x + 3, 4*x^2 + 6*x + 4], + ....: [ x^2 + 4*x + 2, 5*x + 2], + ....: [ 5*x + 3, 0]]) + sage: A.solve_right_series_trunc(B, 3) # optional - sage.libs.pari [ 3*x^2 + x + 1 5*x^2 + 4*x + 3] [6*x^2 + 3*x + 1 4*x + 1] [ 6*x^2 + 1 2*x^2 + x + 4] - sage: X = A.solve_right_series_trunc(B,37); B == A*X % x**37 + sage: X = A.solve_right_series_trunc(B, 37); B == A*X % x**37 # optional - sage.libs.pari True Dimensions of input are checked:: - sage: A.solve_right_series_trunc(B[:2,:],3) + sage: A.solve_right_series_trunc(B[:2,:], 3) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: number of rows of self must equal number of rows of right-hand side Raises an exception when no solution:: - sage: A[:,2:].solve_right_series_trunc(B,4) + sage: A[:,2:].solve_right_series_trunc(B, 4) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matrix equation has no solutions - sage: Ax = x*A; C = vector(pR, [1,1,1]) - sage: Ax.solve_right_series_trunc(C,5) + sage: Ax = x*A; C = vector(pR, [1,1,1]) # optional - sage.libs.pari + sage: Ax.solve_right_series_trunc(C, 5) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matrix equation has no solutions Supports rectangular and rank-deficient cases:: - sage: A[:2,:].solve_right_series_trunc(B[:2,:],4) + sage: A[:2,:].solve_right_series_trunc(B[:2,:],4) # optional - sage.libs.pari [ 5*x^2 + 4*x x + 4] [ x^2 + 3*x + 5 3*x^2 + 4*x + 4] [ 5*x + 3 3*x + 2] - sage: V = Matrix([[2*x^2 + 5*x + 1], [3*x^2+4]]) - sage: A[:,:2].solve_right_series_trunc(A[:,:2]*V, 4) == V + sage: V = Matrix([[2*x^2 + 5*x + 1], [3*x^2+4]]) # optional - sage.libs.pari + sage: A[:,:2].solve_right_series_trunc(A[:,:2]*V, 4) == V # optional - sage.libs.pari True - sage: A[:,1] = (x+1) * A[:,0]; A[:,2] = (x+5) * A[:,0] - sage: B = (3*x^3+x^2+2)*A[:,0] - sage: A.solve_right_series_trunc(B, 6) + sage: A[:,1] = (x+1) * A[:,0]; A[:,2] = (x+5) * A[:,0] # optional - sage.libs.pari + sage: B = (3*x^3+x^2+2)*A[:,0] # optional - sage.libs.pari + sage: A.solve_right_series_trunc(B, 6) # optional - sage.libs.pari [4*x^2 + 6*x + 2] [ 3*x^2 + x] [ 0] @@ -1095,35 +1095,35 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.row_degrees() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari + sage: M.row_degrees() # optional - sage.libs.pari [1, 3] - sage: M.row_degrees(shifts=[0,1,2]) + sage: M.row_degrees(shifts=[0,1,2]) # optional - sage.libs.pari [2, 3] A zero row in a polynomial matrix can be identified in the (shifted) row degrees as the entries equal to ``min(shifts)-1``:: - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 0, 0]]) - sage: M.row_degrees() + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 0, 0]]) # optional - sage.libs.pari + sage: M.row_degrees() # optional - sage.libs.pari [1, 3, -1] - sage: M.row_degrees(shifts=[-2,1,2]) + sage: M.row_degrees(shifts=[-2,1,2]) # optional - sage.libs.pari [2, 1, -3] The row degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix( pR, 0, 3 ) - sage: M.row_degrees() + sage: M = Matrix(pR, 0, 3) # optional - sage.libs.pari + sage: M.row_degrees() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: empty matrix does not have row degrees - sage: M = Matrix( pR, 3, 0 ) - sage: M.row_degrees() + sage: M = Matrix(pR, 3, 0) # optional - sage.libs.pari + sage: M.row_degrees() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: empty matrix does not have row degrees @@ -1162,31 +1162,31 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.column_degrees() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari + sage: M.column_degrees() # optional - sage.libs.pari [3, -1, 0] - sage: M.column_degrees(shifts=[0,2]) + sage: M.column_degrees(shifts=[0,2]) # optional - sage.libs.pari [5, -1, 0] A zero column in a polynomial matrix can be identified in the (shifted) column degrees as the entries equal to ``min(shifts)-1``:: - sage: M.column_degrees(shifts=[-2,1]) + sage: M.column_degrees(shifts=[-2,1]) # optional - sage.libs.pari [4, -3, -2] The column degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix( pR, 0, 3 ) - sage: M.column_degrees() + sage: M = Matrix(pR, 0, 3) # optional - sage.libs.pari + sage: M.column_degrees() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: empty matrix does not have column degrees - sage: M = Matrix( pR, 3, 0 ) - sage: M.column_degrees() + sage: M = Matrix(pR, 3, 0) # optional - sage.libs.pari + sage: M.column_degrees() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: empty matrix does not have column degrees @@ -1243,28 +1243,28 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.leading_matrix() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari + sage: M.leading_matrix() # optional - sage.libs.pari [3 0 0] [1 0 0] - sage: M.leading_matrix().base_ring() + sage: M.leading_matrix().base_ring() # optional - sage.libs.pari Finite Field of size 7 - sage: M.leading_matrix(shifts=[0,1,2]) + sage: M.leading_matrix(shifts=[0,1,2]) # optional - sage.libs.pari [0 0 1] [1 0 0] - sage: M.leading_matrix(row_wise=False) + sage: M.leading_matrix(row_wise=False) # optional - sage.libs.pari [0 0 1] [1 0 0] - sage: M.leading_matrix(shifts=[-2,1], row_wise=False) + sage: M.leading_matrix(shifts=[-2,1], row_wise=False) # optional - sage.libs.pari [0 0 1] [1 0 0] - sage: M.leading_matrix(shifts=[2,0], row_wise=False) + sage: M.leading_matrix(shifts=[2,0], row_wise=False) # optional - sage.libs.pari [3 0 1] [1 0 0] """ @@ -1318,19 +1318,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, 0, 0) - sage: M._is_empty_popov() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, 0, 0) # optional - sage.libs.pari + sage: M._is_empty_popov() # optional - sage.libs.pari True - sage: M._is_empty_popov(include_zero_vectors=False) + sage: M._is_empty_popov(include_zero_vectors=False) # optional - sage.libs.pari True - sage: M = Matrix(pR, 0, 3) - sage: M._is_empty_popov(include_zero_vectors=False) + sage: M = Matrix(pR, 0, 3) # optional - sage.libs.pari + sage: M._is_empty_popov(include_zero_vectors=False) # optional - sage.libs.pari True - sage: M._is_empty_popov(row_wise=False) + sage: M._is_empty_popov(row_wise=False) # optional - sage.libs.pari True - sage: M._is_empty_popov(row_wise=False,include_zero_vectors=False) + sage: M._is_empty_popov(row_wise=False,include_zero_vectors=False) # optional - sage.libs.pari False .. SEEALSO:: @@ -1389,23 +1389,23 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.is_reduced() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari + sage: M.is_reduced() # optional - sage.libs.pari False - sage: M.is_reduced(shifts=[0,1,2]) + sage: M.is_reduced(shifts=[0,1,2]) # optional - sage.libs.pari True - sage: M.is_reduced(shifts=[2,0], row_wise=False) + sage: M.is_reduced(shifts=[2,0], row_wise=False) # optional - sage.libs.pari True - sage: M.is_reduced(shifts=[2,0], row_wise=False, - ....: include_zero_vectors=False) + sage: M.is_reduced(shifts=[2,0], row_wise=False, # optional - sage.libs.pari + ....: include_zero_vectors=False) False - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0], [0, 1, 0] ]) - sage: M.is_reduced(shifts=[2,0,0], row_wise=False) + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 1, 0]]) # optional - sage.libs.pari + sage: M.is_reduced(shifts=[2,0,0], row_wise=False) # optional - sage.libs.pari True .. SEEALSO:: @@ -1469,50 +1469,51 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [3*x+1, 0, 1], [x^3+3, 0, 0] ]) - sage: M.leading_positions() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari + sage: M.leading_positions() # optional - sage.libs.pari [0, 0] - sage: M.leading_positions(return_degree=True) + sage: M.leading_positions(return_degree=True) # optional - sage.libs.pari ([0, 0], [1, 3]) - sage: M.leading_positions(shifts=[0,5,2], return_degree=True) + sage: M.leading_positions(shifts=[0,5,2], return_degree=True) # optional - sage.libs.pari ([2, 0], [0, 3]) - sage: M.leading_positions(row_wise=False, return_degree=True) + sage: M.leading_positions(row_wise=False, return_degree=True) # optional - sage.libs.pari ([1, -1, 0], [3, -1, 0]) - sage: M.leading_positions(shifts=[1,2], row_wise=False, - ....: return_degree=True) + sage: M.leading_positions(shifts=[1,2], row_wise=False, # optional - sage.libs.pari + ....: return_degree=True) ([1, -1, 0], [3, -1, 0]) In case several entries in the row (resp. column) reach the shifted row (resp. column) degree, the leading position is chosen as the rightmost (resp. bottommost) such entry:: - sage: M.leading_positions(shifts=[0,5,1],return_degree=True) + sage: M.leading_positions(shifts=[0,5,1], return_degree=True) # optional - sage.libs.pari ([2, 0], [0, 3]) - sage: M.leading_positions(shifts=[2,0], row_wise=False,return_degree=True) + sage: M.leading_positions(shifts=[2,0], row_wise=False, # optional - sage.libs.pari + ....: return_degree=True) ([1, -1, 0], [3, -1, 0]) The leading positions and pivot degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix( pR, 0, 3 ) - sage: M.leading_positions() + sage: M = Matrix(pR, 0, 3) # optional - sage.libs.pari + sage: M.leading_positions() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions - sage: M.leading_positions(row_wise=False) + sage: M.leading_positions(row_wise=False) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions - sage: M = Matrix( pR, 3, 0 ) - sage: M.leading_positions(row_wise=False) + sage: M = Matrix(pR, 3, 0) # optional - sage.libs.pari + sage: M.leading_positions(row_wise=False) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions @@ -1600,58 +1601,60 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix([ [x^3+3*x^2+6*x+6, 3*x^2+3*x+6, 4*x^2+x+3], + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix([ [x^3+3*x^2+6*x+6, 3*x^2+3*x+6, 4*x^2+x+3], # optional - sage.libs.pari ....: [5, 1, 0 ], ....: [2*x^2+2, 2*x+5, x^2+4*x+6] ]) - sage: M.is_weak_popov() + sage: M.is_weak_popov() # optional - sage.libs.pari True One can check whether the leading positions, in addition to being pairwise distinct, are actually in increasing order:: - sage: M.is_weak_popov(ordered=True) + sage: M.is_weak_popov(ordered=True) # optional - sage.libs.pari True - sage: N = M.with_swapped_rows(1,2) - sage: N.is_weak_popov() + sage: N = M.with_swapped_rows(1, 2) # optional - sage.libs.pari + sage: N.is_weak_popov() # optional - sage.libs.pari True - sage: N.is_weak_popov(ordered=True) + sage: N.is_weak_popov(ordered=True) # optional - sage.libs.pari False Shifts and orientation (row-wise or column-wise) are supported:: - sage: M.is_weak_popov(shifts=[2,3,1]) + sage: M.is_weak_popov(shifts=[2,3,1]) # optional - sage.libs.pari False - sage: M.is_weak_popov(shifts=[0,2,0],row_wise=False,ordered=True) + sage: M.is_weak_popov(shifts=[0,2,0], row_wise=False, # optional - sage.libs.pari + ....: ordered=True) True Rectangular matrices are supported:: - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.libs.pari ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.is_weak_popov(shifts=[0,2,1,3]) + sage: M.is_weak_popov(shifts=[0,2,1,3]) # optional - sage.libs.pari True - sage: M.is_weak_popov(shifts=[0,2,1,3],ordered=True) + sage: M.is_weak_popov(shifts=[0,2,1,3], ordered=True) # optional - sage.libs.pari True Zero rows (resp. columns) can be forbidden:: - sage: M = Matrix([ + sage: M = Matrix([ # optional - sage.libs.pari ....: [ 6*x+4, 0, 5*x+1, 0], ....: [ 2, 5*x + 1, 6*x^2+3*x+1, 0], ....: [2*x^2+5*x+5, 1, 2*x^3+4*x^2+6*x+4, 0] ....: ]) - sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, ordered=True) + sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, # optional - sage.libs.pari + ....: ordered=True) True - sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, - ....: include_zero_vectors=False) + sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, # optional - sage.libs.pari + ....: include_zero_vectors=False) False .. SEEALSO:: @@ -1738,60 +1741,60 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [x^4+6*x^3+4*x+4, 3*x+6, 3 ], - ....: [x^2+6*x+6, x^2+5*x+5, 2 ], - ....: [3*x, 6*x+5, x+5] ]) - sage: M.is_popov() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[x^4+6*x^3+4*x+4, 3*x+6, 3 ], # optional - sage.libs.pari + ....: [x^2+6*x+6, x^2+5*x+5, 2 ], + ....: [3*x, 6*x+5, x+5]]) + sage: M.is_popov() # optional - sage.libs.pari True - sage: M.is_popov(shifts=[0,1,2]) + sage: M.is_popov(shifts=[0,1,2]) # optional - sage.libs.pari True - sage: M[:,:2].is_popov() + sage: M[:,:2].is_popov() # optional - sage.libs.pari False - sage: M[:2,:].is_popov(shifts=[0,1,2]) + sage: M[:2,:].is_popov(shifts=[0,1,2]) # optional - sage.libs.pari True - sage: M = Matrix(pR, [ [x^4+3*x^3+x^2+2*x+6, x^3+5*x^2+5*x+1], - ....: [6*x+1, x^2+4*x+1 ], - ....: [6, 6 ] ]) - sage: M.is_popov(row_wise=False) + sage: M = Matrix(pR, [[x^4+3*x^3+x^2+2*x+6, x^3+5*x^2+5*x+1], # optional - sage.libs.pari + ....: [6*x+1, x^2+4*x+1 ], + ....: [6, 6 ]]) + sage: M.is_popov(row_wise=False) # optional - sage.libs.pari False - sage: M.is_popov(shifts=[0,2,3], row_wise=False) + sage: M.is_popov(shifts=[0,2,3], row_wise=False) # optional - sage.libs.pari True One can forbid zero rows (or columns if not working row-wise):: - sage: N = Matrix(pR, [ [x^4+3*x^3+x^2+2*x+6, 6*x+1 ], - ....: [5*x^2+5*x+1, x^2+4*x+1 ], - ....: [0, 0 ] ]) + sage: N = Matrix(pR, [[x^4+3*x^3+x^2+2*x+6, 6*x+1 ], # optional - sage.libs.pari + ....: [5*x^2+5*x+1, x^2+4*x+1 ], + ....: [0, 0 ]]) - sage: N.is_popov() + sage: N.is_popov() # optional - sage.libs.pari True - sage: N.is_popov(include_zero_vectors=False) + sage: N.is_popov(include_zero_vectors=False) # optional - sage.libs.pari False One can verify Popov form up to row permutation (or column permutation if not working row-wise):: - sage: M.swap_columns(0,1) - sage: M.is_popov(shifts=[0,2,3], row_wise=False) + sage: M.swap_columns(0, 1) # optional - sage.libs.pari + sage: M.is_popov(shifts=[0,2,3], row_wise=False) # optional - sage.libs.pari False - sage: M.is_popov(shifts=[0,2,3], row_wise=False, - ....: up_to_permutation=True) + sage: M.is_popov(shifts=[0,2,3], row_wise=False, # optional - sage.libs.pari + ....: up_to_permutation=True) # optional - sage.libs.pari True - sage: N.swap_rows(0,2) + sage: N.swap_rows(0, 2) # optional - sage.libs.pari - sage: N.is_popov() + sage: N.is_popov() # optional - sage.libs.pari False - sage: N.is_popov(up_to_permutation=True) + sage: N.is_popov(up_to_permutation=True) # optional - sage.libs.pari True """ # the matrix should be in weak Popov form (ordered except if @@ -1876,41 +1879,41 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ [x^4+6*x^3+4*x+4, 3*x+6, 3 ], - ....: [0, x^2+5*x+5, 2 ], - ....: [0, 0, x+5] ]) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [[x^4+6*x^3+4*x+4, 3*x+6, 3 ], # optional - sage.libs.pari + ....: [0, x^2+5*x+5, 2 ], + ....: [0, 0, x+5]]) - sage: M.is_hermite() + sage: M.is_hermite() # optional - sage.libs.pari True - sage: M.is_hermite(row_wise=False) + sage: M.is_hermite(row_wise=False) # optional - sage.libs.pari True - sage: M.is_hermite(row_wise=False, lower_echelon=True) + sage: M.is_hermite(row_wise=False, lower_echelon=True) # optional - sage.libs.pari False - sage: N = Matrix(pR, [ [x+5, 0, 0 ], - ....: [2, x^4+6*x^3+4*x+4, 0 ], - ....: [3, 3*x^3+6, x^2+5*x+5] ]) - sage: N.is_hermite() + sage: N = Matrix(pR, [[x+5, 0, 0 ], # optional - sage.libs.pari + ....: [2, x^4+6*x^3+4*x+4, 0 ], + ....: [3, 3*x^3+6, x^2+5*x+5]]) + sage: N.is_hermite() # optional - sage.libs.pari False - sage: N.is_hermite(lower_echelon=True) + sage: N.is_hermite(lower_echelon=True) # optional - sage.libs.pari True - sage: N.is_hermite(row_wise=False) + sage: N.is_hermite(row_wise=False) # optional - sage.libs.pari False - sage: N.is_hermite(row_wise=False, lower_echelon=True) + sage: N.is_hermite(row_wise=False, lower_echelon=True) # optional - sage.libs.pari False Rectangular matrices with zero rows are supported. Zero rows (resp. columns) can be forbidden, and otherwise they should be at the bottom (resp. the right-hand side) of the matrix:: - sage: N[:,1:].is_hermite(lower_echelon=True) + sage: N[:,1:].is_hermite(lower_echelon=True) # optional - sage.libs.pari False - sage: N[[1,2,0],1:].is_hermite(lower_echelon=True) + sage: N[[1,2,0],1:].is_hermite(lower_echelon=True) # optional - sage.libs.pari True - sage: N[:2,:].is_hermite(row_wise=False, lower_echelon=True) + sage: N[:2,:].is_hermite(row_wise=False, lower_echelon=True) # optional - sage.libs.pari True - sage: N[:2,:].is_hermite(row_wise=False, + sage: N[:2,:].is_hermite(row_wise=False, # optional - sage.libs.pari ....: lower_echelon=True, ....: include_zero_vectors=False) False @@ -1991,61 +1994,61 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ \ - [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], \ - [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [ # optional - sage.libs.pari + ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], + ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: P,U = M.weak_popov_form(transformation=True) - sage: P + sage: P, U = M.weak_popov_form(transformation=True) # optional - sage.libs.pari + sage: P # optional - sage.libs.pari [ 4 x^2 6*x^2 + x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: U + sage: U # optional - sage.libs.pari [2*x^2 + 1 4*x] [ 4*x 1] - sage: P.is_weak_popov() and U.is_invertible() and U*M==P + sage: P.is_weak_popov() and U.is_invertible() and U*M==P # optional - sage.libs.pari True Demonstrating the ``ordered`` option:: - sage: P.leading_positions() + sage: P.leading_positions() # optional - sage.libs.pari [2, 1] - sage: PP = M.weak_popov_form(ordered=True); PP + sage: PP = M.weak_popov_form(ordered=True); PP # optional - sage.libs.pari [ 2 4*x^2 + 2*x + 4 5] [ 4 x^2 6*x^2 + x + 2] - sage: PP.leading_positions() + sage: PP.leading_positions() # optional - sage.libs.pari [1, 2] Demonstrating shifts:: - sage: P = M.weak_popov_form(shifts=[0,2,4]); P + sage: P = M.weak_popov_form(shifts=[0,2,4]); P # optional - sage.libs.pari [ 6*x^2 + 6*x + 4 5*x^4 + 4*x^3 + 5*x^2 + 5*x 2*x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: P==M.weak_popov_form(shifts=[-10,-8,-6]) + sage: P == M.weak_popov_form(shifts=[-10,-8,-6]) # optional - sage.libs.pari True Column-wise form is the row-wise form of the transpose:: - sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T + sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T # optional - sage.libs.pari True Zero vectors can be discarded:: - sage: M.weak_popov_form(row_wise=False) + sage: M.weak_popov_form(row_wise=False) # optional - sage.libs.pari [x + 4 6 0] [ 5 1 0] - sage: P,U = M.weak_popov_form(transformation=True, \ - row_wise=False, \ - include_zero_vectors=False) - sage: P + sage: P, U = M.weak_popov_form(transformation=True, # optional - sage.libs.pari + ....: row_wise=False, + ....: include_zero_vectors=False) + sage: P # optional - sage.libs.pari [x + 4 6] [ 5 1] - sage: U + sage: U # optional - sage.libs.pari [ 5*x + 2 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 1 1 2*x + 1] [ 5*x + 5 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.libs.pari True .. SEEALSO:: @@ -2120,17 +2123,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: F. = GF(2^4,'a') - sage: PF. = F[] - sage: A = matrix(PF,[[1, a*x^17 + 1 ], + sage: F. = GF(2^4, 'a') # optional - sage.libs.pari + sage: PF. = F[] # optional - sage.libs.pari + sage: A = matrix(PF,[[1, a*x^17 + 1 ], # optional - sage.libs.pari ....: [0, a*x^11 + a^2*x^7 + 1 ]]) - sage: M = A.__copy__() - sage: U = M._weak_popov_form(transformation=True) - sage: U * A == M + sage: M = A.__copy__() # optional - sage.libs.pari + sage: U = M._weak_popov_form(transformation=True) # optional - sage.libs.pari + sage: U * A == M # optional - sage.libs.pari True - sage: M.is_weak_popov() + sage: M.is_weak_popov() # optional - sage.libs.pari True - sage: U.is_invertible() + sage: U.is_invertible() # optional - sage.libs.pari True sage: PF. = QQ[] @@ -2275,56 +2278,56 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: M = Matrix(pR, [ \ - [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], \ - [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: M = Matrix(pR, [ # optional - sage.libs.pari + ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], + ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: P,U = M.popov_form(transformation=True) - sage: P + sage: P, U = M.popov_form(transformation=True) # optional - sage.libs.pari + sage: P # optional - sage.libs.pari [ 4 x^2 + 4*x + 1 3] [ 0 4*x + 1 x^2 + 6*x + 1] - sage: U + sage: U # optional - sage.libs.pari [ x 2] [5*x^2 + x + 6 3*x + 2] - sage: P.is_popov() and U.is_invertible() and U*M==P + sage: P.is_popov() and U.is_invertible() and U*M == P # optional - sage.libs.pari True Demonstrating shifts and specific case of Hermite form:: - sage: P = M.popov_form(shifts=[0,2,4]); P + sage: P = M.popov_form(shifts=[0,2,4]); P # optional - sage.libs.pari [ 4*x^2 + 3*x + 4 x^4 + 3*x^3 + 5*x^2 + 5*x + 5 0] [ 6 5*x^2 + 6*x + 5 1] - sage: P.is_popov(shifts=[0,2,4]) + sage: P.is_popov(shifts=[0,2,4]) # optional - sage.libs.pari True - sage: P==M.popov_form(shifts=[-6,-4,-2]) + sage: P == M.popov_form(shifts=[-6,-4,-2]) # optional - sage.libs.pari True - sage: dd=sum(M.row_degrees())+1 - sage: M.popov_form(shifts=[2*dd,dd,0]) == M.hermite_form() + sage: dd = sum(M.row_degrees()) + 1 # optional - sage.libs.pari + sage: M.popov_form(shifts=[2*dd,dd,0]) == M.hermite_form() # optional - sage.libs.pari True Column-wise form is the row-wise form of the transpose:: - sage: M.popov_form() == M.T.popov_form(row_wise=False).T + sage: M.popov_form() == M.T.popov_form(row_wise=False).T # optional - sage.libs.pari True Zero vectors can be discarded:: - sage: M.popov_form(row_wise=False) + sage: M.popov_form(row_wise=False) # optional - sage.libs.pari [x + 2 6 0] [ 0 1 0] - sage: P,U = M.popov_form(transformation=True, \ - row_wise=False, \ - include_zero_vectors=False) - sage: P + sage: P, U = M.popov_form(transformation=True, # optional - sage.libs.pari + ....: row_wise=False, + ....: include_zero_vectors=False) + sage: P # optional - sage.libs.pari [x + 2 6] [ 0 1] - sage: U + sage: U # optional - sage.libs.pari [ 3*x^2 + 6*x + 3 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 3 1 2*x + 1] [ 5*x + 2 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.libs.pari True .. SEEALSO:: @@ -2466,40 +2469,40 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(3)[] - sage: A = matrix(pR,3,[x, x^2, x^3, - ....: x^2, x^1, 0, - ....: x^3, x^3, x^3]) - sage: R = A.reduced_form(); R + sage: pR. = GF(3)[] # optional - sage.libs.pari + sage: A = matrix(pR, 3, [x, x^2, x^3, # optional - sage.libs.pari + ....: x^2, x^1, 0, + ....: x^3, x^3, x^3]) + sage: R = A.reduced_form(); R # optional - sage.libs.pari [ x x^2 x^3] [ x^2 x 0] [ x^3 + 2*x x^3 + 2*x^2 0] - sage: R.is_reduced() + sage: R.is_reduced() # optional - sage.libs.pari True - sage: R2 = A.reduced_form(shifts=[6,3,0]); R2 + sage: R2 = A.reduced_form(shifts=[6,3,0]); R2 # optional - sage.libs.pari [ x x^2 x^3] [ 0 2*x^2 + x 2*x^4 + x^3] [ 0 0 2*x^5 + x^4 + x^3] - sage: R2.is_reduced(shifts=[6,3,0]) + sage: R2.is_reduced(shifts=[6,3,0]) # optional - sage.libs.pari True - sage: R2.is_reduced() + sage: R2.is_reduced() # optional - sage.libs.pari False If the matrix is an `n \times 1` matrix with at least one non-zero entry, `R` has a single non-zero entry and that entry is a scalar multiple of the greatest-common-divisor of the entries of the matrix:: - sage: A = matrix([[x*(x-1)*(x+1)],[x*(x-2)*(x+2)],[x]]) - sage: R = A.reduced_form() - sage: R + sage: A = matrix([[x*(x-1)*(x+1)], [x*(x-2)*(x+2)], [x]]) # optional - sage.libs.pari + sage: R = A.reduced_form() # optional - sage.libs.pari + sage: R # optional - sage.libs.pari [x] [0] [0] A zero matrix is already reduced:: - sage: A = matrix(pR, 2, [0,0,0,0]) - sage: A.reduced_form() + sage: A = matrix(pR, 2, [0,0,0,0]) # optional - sage.libs.pari + sage: A.reduced_form() # optional - sage.libs.pari [0 0] [0 0] @@ -2521,21 +2524,21 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): The last example shows the usage of the transformation parameter:: - sage: Fq. = GF(2^3) - sage: pR. = Fq[] + sage: Fq. = GF(2^3) # optional - sage.libs.pari + sage: pR. = Fq[] # optional - sage.libs.pari sage: A = matrix(pR, [[x^2+a, x^4+a], - ....: [ x^3, a*x^4]]) - sage: W,U = A.reduced_form(transformation=True) - sage: W,U + ....: [ x^3, a*x^4]]) # optional - sage.libs.pari + sage: W, U = A.reduced_form(transformation=True) # optional - sage.libs.pari + sage: W, U # optional - sage.libs.pari ( [ x^2 + a x^4 + a] [1 0] [x^3 + a*x^2 + a^2 a^2], [a 1] ) - sage: W.is_reduced() + sage: W.is_reduced() # optional - sage.libs.pari True - sage: U*W == A + sage: U*W == A # optional - sage.libs.pari True - sage: U.is_invertible() + sage: U.is_invertible() # optional - sage.libs.pari True .. SEEALSO:: @@ -2575,30 +2578,32 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: M. = GF(7)[] - sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) - sage: A.hermite_form() + sage: M. = GF(7)[] # optional - sage.libs.pari + sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) # optional - sage.libs.pari + sage: A.hermite_form() # optional - sage.libs.pari [ x 1 2*x] [ 0 x 5*x + 2] - sage: A.hermite_form(transformation=True) + sage: A.hermite_form(transformation=True) # optional - sage.libs.pari ( [ x 1 2*x] [1 0] [ 0 x 5*x + 2], [6 1] ) - sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) - sage: A.hermite_form(transformation=True, include_zero_rows=False) + sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) # optional - sage.libs.pari + sage: A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.libs.pari ([ x 1 2*x], [0 4]) - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True); H, U + sage: H, U = A.hermite_form(transformation=True, # optional - sage.libs.pari + ....: include_zero_rows=True); H, U ( [ x 1 2*x] [0 4] [ 0 0 0], [5 1] ) - sage: U * A == H + sage: U * A == H # optional - sage.libs.pari True - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False) - sage: U * A + sage: H, U = A.hermite_form(transformation=True, # optional - sage.libs.pari + ....: include_zero_rows=False) + sage: U * A # optional - sage.libs.pari [ x 1 2*x] - sage: U * A == H + sage: U * A == H # optional - sage.libs.pari True .. SEEALSO:: @@ -2635,26 +2640,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 3, 2, \ - [[ 3*x^3 + 3*x, 2*x^3 + 4], \ - [ 3*x^3 + 6*x + 5, 6*x^3 + 5*x^2 + 1], \ - [ 2*x^3 + 2*x + 6, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, \ - [[ 3, x + 3, 6], \ - [3*x^3 + 3*x + 1, 4*x^2 + 3*x, 6*x^3 + x + 4], \ - [ 4*x^2 + x + 4, 3*x^2 + 4*x, 3*x^2 + 3*x + 2]]) - sage: Q,R = A.left_quo_rem(B); (Q,R) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: A = Matrix(pR, 3, 2, # optional - sage.libs.pari + ....: [[ 3*x^3 + 3*x, 2*x^3 + 4], + ....: [ 3*x^3 + 6*x + 5, 6*x^3 + 5*x^2 + 1], + ....: [ 2*x^3 + 2*x + 6, 3*x^2 + 2*x + 2]]) + sage: B = Matrix(pR, 3, 3, + ....: [[ 3, x + 3, 6], # optional - sage.libs.pari + ....: [3*x^3 + 3*x + 1, 4*x^2 + 3*x, 6*x^3 + x + 4], + ....: [ 4*x^2 + x + 4, 3*x^2 + 4*x, 3*x^2 + 3*x + 2]]) + sage: Q, R = A.left_quo_rem(B); Q, R # optional - sage.libs.pari ( [2*x^2 + 4*x + 6 6*x^2 + 4*x + 1] [ 3 1] [ 3*x^2 + 5*x 2*x^2 + x + 5] [ 6 5*x^2 + 2*x + 3] [ 6*x^2 + 3*x 4*x^2 + 6*x + 1], [ 2*x + 3 6*x + 3] ) - sage: rdegR = R.row_degrees(); rdegB = B.row_degrees() - sage: A == B*Q+R and all([rdegR[i] < rdegB[i] for i in range(3)]) + sage: rdegR = R.row_degrees(); rdegB = B.row_degrees() # optional - sage.libs.pari + sage: A == B*Q+R and all(rdegR[i] < rdegB[i] for i in range(3)) # optional - sage.libs.pari True - sage: A[:2,:].left_quo_rem(B) + sage: A[:2,:].left_quo_rem(B) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: row dimension of self should be the row dimension of @@ -2664,19 +2669,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): no quotient and remainder (unless the matrix has full row rank, see :meth:`right_quo_rem`):: - sage: Q,R = A[:2,:].left_quo_rem(B[:2,:]); (Q,R) + sage: Q, R = A[:2,:].left_quo_rem(B[:2,:]); Q, R # optional - sage.libs.pari ( [ 3*x + 3 2*x + 1] [ 3*x^2 + 5*x 2*x^2 + x + 5] [ 5 0] [ 0 0], [4*x^2 + x + 2 4*x^2 + x] ) - sage: rdegR = R.row_degrees(); rdegB = B[:2,:].row_degrees() - sage: A[:2,:] == B[:2,:]*Q+R + sage: rdegR = R.row_degrees(); rdegB = B[:2,:].row_degrees() # optional - sage.libs.pari + sage: A[:2,:] == B[:2,:]*Q+R # optional - sage.libs.pari True - sage: all([rdegR[i] < rdegB[i] for i in range(len(rdegR))]) + sage: all([rdegR[i] < rdegB[i] for i in range(len(rdegR))]) # optional - sage.libs.pari True - sage: A.left_quo_rem(B[:,:2]) + sage: A.left_quo_rem(B[:,:2]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder @@ -2730,37 +2735,37 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Case where `B` is a square, column reduced matrix:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 2, 3, \ - [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], \ - [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: A = Matrix(pR, 2, 3, # optional - sage.libs.pari + ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], + ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, \ - [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], \ - [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) + sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], + ....: [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) + sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari True - sage: Q,R = A.right_quo_rem(B); (Q,R) + sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.libs.pari ( [ 4*x x + 2 6*x + 1] [ x + 2 6*x + 1 5*x + 4] [4*x + 3 x + 6 3*x + 4], [4*x + 2 2*x + 3 4*x + 3] ) - sage: A == Q*B+R and R.degree() < 2 + sage: A == Q*B+R and R.degree() < 2 # optional - sage.libs.pari True - sage: A[:,:2].right_quo_rem(B) + sage: A[:,:2].right_quo_rem(B) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: column dimension of self should be the column dimension of the input matrix - sage: B = Matrix(pR, 3, 3, \ - [[3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], \ - [x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) + sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], + ....: [x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) + sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari True - sage: Q,R = A.right_quo_rem(B); (Q,R) + sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.libs.pari ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2768,20 +2773,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari + sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) # optional - sage.libs.pari True With a nonsingular but also non-reduced matrix, there exists a solution, but it might not be unique:: - sage: B = Matrix(pR, 3, 3, \ - [[ 5, 0, 2*x + 6], \ - [ 4*x, 3*x^2 + 4*x + 5, x + 1], \ - [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) - sage: B.det() != 0 and (not B.is_reduced(row_wise=False)) + sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[ 5, 0, 2*x + 6], + ....: [ 4*x, 3*x^2 + 4*x + 5, x + 1], + ....: [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) + sage: B.det() != 0 and (not B.is_reduced(row_wise=False)) # optional - sage.libs.pari True - sage: Q,R = A.right_quo_rem(B); (Q,R) + sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.libs.pari ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2], @@ -2789,17 +2794,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 5 x^2 + 2*x + 1 2] [ 6*x + 3 5*x^2 + 6 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.libs.pari True - sage: Q2 = Matrix(pR, 2, 3, \ - [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], \ - [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) - sage: R2 = Matrix(pR, 2, 3, \ - [[ 5*x, 3*x + 4, 5], \ - [4*x + 6, 5*x, 4]]) - sage: A == Q2*B + R2 + sage: Q2 = Matrix(pR, 2, 3, # optional - sage.libs.pari + ....: [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], + ....: [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) + sage: R2 = Matrix(pR, 2, 3, # optional - sage.libs.pari + ....: [[ 5*x, 3*x + 4, 5], + ....: [4*x + 6, 5*x, 4]]) + sage: A == Q2*B + R2 # optional - sage.libs.pari True The same remark holds more generally for full column rank matrices: @@ -2807,8 +2812,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): other cases (rank-deficient matrix `B` or matrix `B` having strictly fewer rows than columns) there may be no solution:: - sage: C = B.stack(B[1,:] + B[2,:]) # matrix 4 x 3, full column rank - sage: Q,R = A.right_quo_rem(C); (Q,R) + sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # optional - sage.libs.pari + sage: Q, R = A.right_quo_rem(C); Q, R # optional - sage.libs.pari ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1 0] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2 0], @@ -2817,13 +2822,13 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 6*x + 3 5*x^2 + 6 3] ) - sage: A.right_quo_rem(B[:2,:]) # matrix 2 x 3, full row rank + sage: A.right_quo_rem(B[:2,:]) # matrix 2 x 3, full row rank # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder with the required degree property - sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular - sage: A.right_quo_rem(D) + sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # optional - sage.libs.pari + sage: A.right_quo_rem(D) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder @@ -2834,11 +2839,11 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): remainder, in which case this method will find it via normal form computation:: - sage: B = Matrix(pR, 1, 2, [[x, x]]) - sage: A = Matrix(pR, 1, 2, [[x, x+2]]) - sage: A.right_quo_rem(B) + sage: B = Matrix(pR, 1, 2, [[x, x]]) # optional - sage.libs.pari + sage: A = Matrix(pR, 1, 2, [[x, x+2]]) # optional - sage.libs.pari + sage: A.right_quo_rem(B) # optional - sage.libs.pari ([1], [0 2]) - sage: A == 1*B + Matrix([[0,2]]) + sage: A == 1*B + Matrix([[0,2]]) # optional - sage.libs.pari True .. SEEALSO:: @@ -2886,32 +2891,32 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 2, 3, \ - [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], \ - [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: A = Matrix(pR, 2, 3, # optional - sage.libs.pari + ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], + ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, \ - [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], \ - [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) + sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], + ....: [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) + sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari True - sage: Q,R = A._right_quo_rem_reduced(B); (Q,R) + sage: Q, R = A._right_quo_rem_reduced(B); Q, R # optional - sage.libs.pari ( [ 4*x x + 2 6*x + 1] [ x + 2 6*x + 1 5*x + 4] [4*x + 3 x + 6 3*x + 4], [4*x + 2 2*x + 3 4*x + 3] ) - sage: A == Q*B+R and R.degree() < 2 + sage: A == Q*B+R and R.degree() < 2 # optional - sage.libs.pari True - sage: B = Matrix(pR, 3, 3, \ - [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], \ - [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) + sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], + ....: [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) + sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari True - sage: Q,R = A._right_quo_rem_reduced(B); (Q,R) + sage: Q, R = A._right_quo_rem_reduced(B); Q, R # optional - sage.libs.pari ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2919,8 +2924,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.libs.pari True """ # Step 0: find parameter d (delta in above reference) @@ -2965,16 +2970,16 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: A = Matrix(pR, 2, 3, \ - [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], \ - [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: A = Matrix(pR, 2, 3, # optional - sage.libs.pari + ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], + ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, \ - [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], \ - [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], \ - [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: Q,R = A._right_quo_rem_solve(B); (Q,R) + sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], + ....: [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], + ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) + sage: Q, R = A._right_quo_rem_solve(B); Q, R # optional - sage.libs.pari ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2982,22 +2987,22 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: B.is_reduced(row_wise=False) + sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari True - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari + sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) # optional - sage.libs.pari True With a nonsingular but also non-reduced matrix, there exists a solution and one is found by this method, but it might not be unique:: - sage: B = Matrix(pR, 3, 3, \ - [[ 5, 0, 2*x + 6], \ - [ 4*x, 3*x^2 + 4*x + 5, x + 1], \ - [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) - sage: B.det() != 0 and (not B.is_reduced(row_wise=False)) + sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[ 5, 0, 2*x + 6], + ....: [ 4*x, 3*x^2 + 4*x + 5, x + 1], + ....: [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) + sage: B.det() != 0 and not B.is_reduced(row_wise=False) # optional - sage.libs.pari True - sage: Q,R = A._right_quo_rem_solve(B); (Q,R) + sage: Q, R = A._right_quo_rem_solve(B); Q, R # optional - sage.libs.pari ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2], @@ -3005,17 +3010,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 5 x^2 + 2*x + 1 2] [ 6*x + 3 5*x^2 + 6 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.libs.pari True - sage: Q2 = Matrix(pR, 2, 3, \ - [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], \ - [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) - sage: R2 = Matrix(pR, 2, 3, \ - [[ 5*x, 3*x + 4, 5], \ - [4*x + 6, 5*x, 4]]) - sage: A == Q2*B + R2 + sage: Q2 = Matrix(pR, 2, 3, # optional - sage.libs.pari + ....: [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], + ....: [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) + sage: R2 = Matrix(pR, 2, 3, # optional - sage.libs.pari + ....: [[ 5*x, 3*x + 4, 5], + ....: [4*x + 6, 5*x, 4]]) + sage: A == Q2*B + R2 # optional - sage.libs.pari True The same remark holds more generally for full column rank matrices: @@ -3023,8 +3028,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): other cases (rank-deficient or strictly fewer rows than columns) there might be no solution:: - sage: C = B.stack(B[1,:] + B[2,:]) # matrix 4 x 3, full column rank - sage: Q,R = A._right_quo_rem_solve(C); (Q,R) + sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # optional - sage.libs.pari + sage: Q, R = A._right_quo_rem_solve(C); Q, R # optional - sage.libs.pari ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1 0] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2 0], @@ -3033,12 +3038,12 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 6*x + 3 5*x^2 + 6 3] ) - sage: A._right_quo_rem_solve(B[:2,:]) # matrix 2 x 3, full row rank + sage: A._right_quo_rem_solve(B[:2,:]) # 2 x 3, full row rank # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution - sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular - sage: A._right_quo_rem_solve(D) + sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # optional - sage.libs.pari + sage: A._right_quo_rem_solve(D) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution @@ -3047,11 +3052,11 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): columns), even when there is a solution, this method might not find it:: - sage: B = Matrix(pR, 1, 2, [[x, x]]) - sage: A = Matrix(pR, 1, 2, [[x, x+2]]) - sage: A == 1*B + Matrix([[0,2]]) # a valid quo_rem + sage: B = Matrix(pR, 1, 2, [[x, x]]) # optional - sage.libs.pari + sage: A = Matrix(pR, 1, 2, [[x, x+2]]) # optional - sage.libs.pari + sage: A == 1*B + Matrix([[0,2]]) # a valid quo_rem # optional - sage.libs.pari True - sage: A._right_quo_rem_solve(B) + sage: A._right_quo_rem_solve(B) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution @@ -3132,24 +3137,24 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: B = Matrix(pR, [ \ - [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], \ - [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: A = Matrix(pR, 1, 3, [ \ - [3*x^4+3*x^3+4*x^2+5*x+1, x^4+x^3+5*x^2+4*x+4, 4*x^4+2*x^3+x]]) + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: B = Matrix(pR, [ # optional - sage.libs.pari + ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], + ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) + sage: A = Matrix(pR, 1, 3, [ # optional - sage.libs.pari + ....: [3*x^4+3*x^3+4*x^2+5*x+1, x^4+x^3+5*x^2+4*x+4, 4*x^4+2*x^3+x]]) - sage: (Q,R) = A.reduce(B,return_quotient=True); R + sage: Q, R = A.reduce(B,return_quotient=True); R # optional - sage.libs.pari [3*x^4 + 3*x^3 + 4*x + 3 2*x + 2 2*x + 6] - sage: A == Q*B + R + sage: A == Q*B + R # optional - sage.libs.pari True - sage: P = B.popov_form(); P.leading_positions(return_degree=True) + sage: P = B.popov_form(); P.leading_positions(return_degree=True) # optional - sage.libs.pari ([1, 2], [2, 2]) - sage: R.degree_matrix() + sage: R.degree_matrix() # optional - sage.libs.pari [4 1 1] - sage: A.reduce(P) == R + sage: A.reduce(P) == R # optional - sage.libs.pari True - sage: A.reduce(P[:,:2]) + sage: A.reduce(P[:,:2]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: column dimension of self should be the column @@ -3157,41 +3162,41 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Demonstrating shifts:: - sage: (Qs,Rs) = A.reduce(B,shifts=[0,2,4],return_quotient=True); Rs + sage: Qs, Rs = A.reduce(B, shifts=[0,2,4], return_quotient=True); Rs # optional - sage.libs.pari [3*x^4 + 3*x^3 + 6*x + 2 4*x^3 + 5*x 0] - sage: A == Qs*B + Rs + sage: A == Qs*B + Rs # optional - sage.libs.pari True - sage: Ps = B.popov_form(shifts=[0,2,4]) - sage: Ps.leading_positions(shifts=[0,2,4],return_degree=True) + sage: Ps = B.popov_form(shifts=[0,2,4]) # optional - sage.libs.pari + sage: Ps.leading_positions(shifts=[0,2,4], return_degree=True) # optional - sage.libs.pari ([1, 2], [4, 0]) - sage: Rs.degree_matrix() + sage: Rs.degree_matrix() # optional - sage.libs.pari [ 4 3 -1] - sage: A.reduce(Ps, shifts=[0,2,4]) == Rs + sage: A.reduce(Ps, shifts=[0,2,4]) == Rs # optional - sage.libs.pari True If ``return_quotient`` is ``False``, only the normal form is returned:: - sage: R == A.reduce(B) and Rs == A.reduce(B,shifts=[0,2,4]) + sage: R == A.reduce(B) and Rs == A.reduce(B, shifts=[0,2,4]) # optional - sage.libs.pari True Demonstrating column-wise normal forms, with a matrix `A` which has several columns, and a matrix `B` which does not have full column rank (its column-wise Popov form has a zero column):: - sage: A = Matrix(pR, 2, 2, \ - [[5*x^3 + 2*x^2 + 4*x + 1, x^3 + 4*x + 4], \ - [2*x^3 + 5*x^2 + 2*x + 4, 2*x^3 + 3*x + 2]]) - sage: (Q,R) = A.reduce(B,row_wise=False,return_quotient=True); R + sage: A = Matrix(pR, 2, 2, # optional - sage.libs.pari + ....: [[5*x^3 + 2*x^2 + 4*x + 1, x^3 + 4*x + 4], + ....: [2*x^3 + 5*x^2 + 2*x + 4, 2*x^3 + 3*x + 2]]) + sage: (Q,R) = A.reduce(B,row_wise=False, return_quotient=True); R # optional - sage.libs.pari [0 3] [0 0] - sage: A == B*Q + R + sage: A == B*Q + R # optional - sage.libs.pari True - sage: P = B.popov_form(row_wise=False); P + sage: P = B.popov_form(row_wise=False); P # optional - sage.libs.pari [x + 2 6 0] [ 0 1 0] - sage: P.leading_positions(row_wise=False, return_degree=True) + sage: P.leading_positions(row_wise=False, return_degree=True) # optional - sage.libs.pari ([0, 1, -1], [1, 0, -1]) - sage: R.degree_matrix() + sage: R.degree_matrix() # optional - sage.libs.pari [-1 0] [-1 -1] @@ -3291,26 +3296,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(97)[] + sage: pR. = GF(97)[] # optional - sage.libs.pari We consider the following example from [Arne Storjohann, Notes on computing minimal approximant bases, 2006]:: - sage: order = 8; shifts = [1,1,0,0,0] - sage: pmat = Matrix(pR, 5, 1, [ \ - pR([35, 0, 41, 87, 3, 42, 22, 90]), \ - pR([80, 15, 62, 87, 14, 93, 24, 0]), \ - pR([42, 57, 90, 87, 22, 80, 71, 53]), \ - pR([37, 72, 74, 6, 5, 75, 23, 47]), \ - pR([36, 10, 74, 1, 29, 44, 87, 74]) ]) - sage: appbas = Matrix(pR, [ \ - [x+47, 57, 58*x+44, 9*x+23, 93*x+76], \ - [ 15, x+18, 52*x+23, 15*x+58, 93*x+88], \ - [ 17, 86, x^2+77*x+16, 76*x+29, 90*x+78], \ - [ 44, 36, 3*x+42, x^2+50*x+26, 85*x+44], \ - [ 2, 22, 54*x+94, 73*x+24, x^2+2*x+25] ]) - sage: appbas.is_minimal_approximant_basis(pmat,\ - order, shifts, row_wise=True, normal_form=True) + sage: order = 8; shifts = [1,1,0,0,0] # optional - sage.libs.pari + sage: pmat = Matrix(pR, 5, 1, [ # optional - sage.libs.pari + ....: pR([35, 0, 41, 87, 3, 42, 22, 90]), + ....: pR([80, 15, 62, 87, 14, 93, 24, 0]), + ....: pR([42, 57, 90, 87, 22, 80, 71, 53]), + ....: pR([37, 72, 74, 6, 5, 75, 23, 47]), + ....: pR([36, 10, 74, 1, 29, 44, 87, 74])]) + sage: appbas = Matrix(pR, [ # optional - sage.libs.pari + ....: [x+47, 57, 58*x+44, 9*x+23, 93*x+76], + ....: [ 15, x+18, 52*x+23, 15*x+58, 93*x+88], + ....: [ 17, 86, x^2+77*x+16, 76*x+29, 90*x+78], + ....: [ 44, 36, 3*x+42, x^2+50*x+26, 85*x+44], + ....: [ 2, 22, 54*x+94, 73*x+24, x^2+2*x+25]]) + sage: appbas.is_minimal_approximant_basis( # optional - sage.libs.pari + ....: pmat, order, shifts, row_wise=True, normal_form=True) True The matrix `x^8 \mathrm{Id}_5` is square, nonsingular, in Popov form, @@ -3318,34 +3323,35 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): not an approximant basis since its rows generate a module strictly contained in the set of approximants for ``pmat`` at order 8:: - sage: (x^8*Matrix.identity(pR, 5)).is_minimal_approximant_basis(\ - pmat, 8) + sage: M = x^8 * Matrix.identity(pR, 5) # optional - sage.libs.pari + sage: M.is_minimal_approximant_basis(pmat, 8) # optional - sage.libs.pari False Since ``pmat`` is a single column, with nonzero constant coefficient, its column-wise approximant bases at order 8 are all `1\times 1` matrices `[c x^8]` for some nonzero field element `c`:: - sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, \ - 8, row_wise=False, normal_form=True) + sage: M = Matrix(pR, [x^8]) # optional - sage.libs.pari + sage: M.is_minimal_approximant_basis( # optional - sage.libs.pari + ....: pmat, 8, row_wise=False, normal_form=True) True Exceptions are raised if input dimensions are not sound:: - sage: appbas.is_minimal_approximant_basis(pmat, [8,8], shifts) + sage: appbas.is_minimal_approximant_basis(pmat, [8,8], shifts) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: order length should be the column dimension of the input matrix - sage: appbas.is_minimal_approximant_basis(pmat, \ - order, shifts, row_wise=False) + sage: appbas.is_minimal_approximant_basis( # optional - sage.libs.pari + ....: pmat, order, shifts, row_wise=False) Traceback (most recent call last): ... ValueError: shifts length should be the column dimension of the input matrix - sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, 8) + sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, 8) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: column dimension should be the row dimension of the @@ -3501,60 +3507,63 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.libs.pari sage: order = [4, 3]; shifts = [-1, 2, 0] - sage: F = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5*x^2 + 4*x + 1], \ - [ 2*x^2 + 2*x + 3, 6*x^2 + 6*x + 3], \ - [4*x^3 + x + 1, 4*x^2 + 2*x + 3] ]) - sage: P = F.minimal_approximant_basis(order, shifts) - sage: P.is_minimal_approximant_basis(F, order, shifts) + sage: F = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5*x^2 + 4*x + 1], # optional - sage.libs.pari + ....: [ 2*x^2 + 2*x + 3, 6*x^2 + 6*x + 3], + ....: [4*x^3 + x + 1, 4*x^2 + 2*x + 3]]) + sage: P = F.minimal_approximant_basis(order, shifts) # optional - sage.libs.pari + sage: P.is_minimal_approximant_basis(F, order, shifts) # optional - sage.libs.pari True By default, the computed basis is not required to be in normal form (and will not be except in rare special cases):: - sage: P.is_minimal_approximant_basis(F, order, shifts, \ - normal_form=True) + sage: P.is_minimal_approximant_basis(F, order, shifts, # optional - sage.libs.pari + ....: normal_form=True) False - sage: P = F.minimal_approximant_basis(order, shifts, normal_form=True) - sage: P.is_minimal_approximant_basis(F, order, shifts, \ - normal_form=True) + sage: P = F.minimal_approximant_basis(order, shifts, # optional - sage.libs.pari + ....: normal_form=True) + sage: P.is_minimal_approximant_basis(F, order, shifts, # optional - sage.libs.pari + ....: normal_form=True) True If shifts are not specified, they are chosen as uniform `[0,\ldots,0]` by default. Besides, if the orders are all the same, one can rather give a single integer:: - sage: F.minimal_approximant_basis(3) == \ - F.minimal_approximant_basis([3,3], shifts=None) + sage: (F.minimal_approximant_basis(3) == # optional - sage.libs.pari + ....: F.minimal_approximant_basis([3,3], shifts=None)) True One can work column-wise by specifying ``row_wise=False``:: - sage: P = F.minimal_approximant_basis([5,2,2], [0,1], row_wise=False) - sage: P.is_minimal_approximant_basis(F, [5,2,2], \ - shifts=[0,1], row_wise=False) + sage: P = F.minimal_approximant_basis([5,2,2], [0,1], # optional - sage.libs.pari + ....: row_wise=False) + sage: P.is_minimal_approximant_basis(F, [5,2,2], shifts=[0,1], # optional - sage.libs.pari + ....: row_wise=False) True - sage: F.minimal_approximant_basis(3, row_wise=True) == \ - F.transpose().minimal_approximant_basis(3, row_wise=False).transpose() + sage: (F.minimal_approximant_basis(3, row_wise=True) == # optional - sage.libs.pari + ....: F.transpose().minimal_approximant_basis( + ....: 3, row_wise=False).transpose() True Errors are raised if the input dimensions are not sound:: - sage: P = F.minimal_approximant_basis([4], shifts) + sage: P = F.minimal_approximant_basis([4], shifts) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: order length should be the column dimension - sage: P = F.minimal_approximant_basis(order, [0,0,0,0]) + sage: P = F.minimal_approximant_basis(order, [0,0,0,0]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: shifts length should be the row dimension An error is raised if order does not contain only positive integers:: - sage: P = F.minimal_approximant_basis([1,0], shifts) + sage: P = F.minimal_approximant_basis([1,0], shifts) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: order should consist of positive integers @@ -3651,31 +3660,31 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] + sage: pR. = GF(7)[] # optional - sage.libs.pari This method supports any number of columns or rows, as well as arbitrary shifts and orders:: - sage: order = [4, 1, 2]; shifts = [-3, 4] - sage: pmat = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5, 4], \ - [2*x^3 + 2*x^2 + 2*x + 3, 6, 6*x + 3]]) - sage: appbas,rdeg = pmat._approximant_basis_iterative(order, \ - shifts) - sage: appbas.is_minimal_approximant_basis(pmat, order, shifts) + sage: order = [4, 1, 2]; shifts = [-3, 4] # optional - sage.libs.pari + sage: pmat = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5, 4], # optional - sage.libs.pari + ....: [2*x^3 + 2*x^2 + 2*x + 3, 6, 6*x + 3]]) + sage: appbas, rdeg = pmat._approximant_basis_iterative(order, # optional - sage.libs.pari + ....: shifts) + sage: appbas.is_minimal_approximant_basis(pmat, order, shifts) # optional - sage.libs.pari True The returned list is the shifted row degrees of ``appbas``:: - sage: rdeg == appbas.row_degrees(shifts) + sage: rdeg == appbas.row_degrees(shifts) # optional - sage.libs.pari True Approximant bases for the zero matrix are all constant unimodular matrices; in fact, this algorithm returns the identity:: - sage: pmat = Matrix(pR, 3, 2) - sage: appbas,rdeg = pmat._approximant_basis_iterative([2,5], \ - [5,0,-4]) - sage: rdeg == [5,0,-4] and appbas == Matrix.identity(pR, 3) + sage: pmat = Matrix(pR, 3, 2) # optional - sage.libs.pari + sage: appbas,rdeg = pmat._approximant_basis_iterative([2,5], # optional - sage.libs.pari + ....: [5,0,-4]) + sage: rdeg == [5,0,-4] and appbas == Matrix.identity(pR, 3) # optional - sage.libs.pari True """ # Define parameters and perform some sanity checks @@ -3804,24 +3813,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(97)[] - sage: pmat = Matrix(pR, [[1],[x],[x**2]]) + sage: pR. = GF(97)[] # optional - sage.libs.pari + sage: pmat = Matrix(pR, [[1], [x], [x**2]]) # optional - sage.libs.pari - sage: kerbas = Matrix(pR, [[x,-1,0],[0,x,-1]]) - sage: kerbas.is_minimal_kernel_basis(pmat) + sage: kerbas = Matrix(pR, [[x,-1,0], [0,x,-1]]) # optional - sage.libs.pari + sage: kerbas.is_minimal_kernel_basis(pmat) # optional - sage.libs.pari True A matrix in Popov form which has the right rank, all rows in the kernel, but does not generate the kernel:: - sage: kerbas = Matrix(pR, [[x**2,0,-1],[0,x,-1]]) - sage: kerbas.is_minimal_kernel_basis(pmat) + sage: kerbas = Matrix(pR, [[x**2,0,-1], [0,x,-1]]) # optional - sage.libs.pari + sage: kerbas.is_minimal_kernel_basis(pmat) # optional - sage.libs.pari False Shifts and right kernel bases are supported (with ``row_wise``), and one can test whether the kernel basis is normalized in shifted-Popov form (with ``normal_form``):: - sage: kerbas = Matrix(pR, [[-x,-x**2],[1,0],[0,1]]) - sage: kerbas.is_minimal_kernel_basis(pmat.transpose(),row_wise=False,normal_form=True,shifts=[0,1,2]) + sage: kerbas = Matrix(pR, [[-x,-x**2], [1,0], [0,1]]) # optional - sage.libs.pari + sage: kerbas.is_minimal_kernel_basis( # optional - sage.libs.pari + ....: pmat.transpose(), row_wise=False, + ....: normal_form=True, shifts=[0,1,2]) True """ m = pmat.nrows() @@ -3924,25 +3935,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] - sage: pmat = Matrix([[(x+1)*(x+3)],[(x+1)*(x+3)+1]]) - sage: pmat.minimal_kernel_basis() + sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pmat = Matrix([[(x+1)*(x+3)], [(x+1)*(x+3)+1]]) # optional - sage.libs.pari + sage: pmat.minimal_kernel_basis() # optional - sage.libs.pari [6*x^2 + 3*x + 3 x^2 + 4*x + 3] - sage: pmat = Matrix([[(x+1)*(x+3)],[(x+1)*(x+4)]]) - sage: pmat.minimal_kernel_basis() + sage: pmat = Matrix([[(x+1)*(x+3)], [(x+1)*(x+4)]]) # optional - sage.libs.pari + sage: pmat.minimal_kernel_basis() # optional - sage.libs.pari [6*x + 3 x + 3] - sage: pmat.minimal_kernel_basis(row_wise=False) + sage: pmat.minimal_kernel_basis(row_wise=False) # optional - sage.libs.pari [] - sage: pmat = Matrix(pR, [[1,x,x**2]]) - sage: pmat.minimal_kernel_basis(row_wise=False,normal_form=True) + sage: pmat = Matrix(pR, [[1, x, x**2]]) # optional - sage.libs.pari + sage: pmat.minimal_kernel_basis(row_wise=False, normal_form=True) # optional - sage.libs.pari [x 0] [6 x] [0 6] - sage: pmat.minimal_kernel_basis(row_wise=False,normal_form=True,shifts=[0,1,2]) + sage: pmat.minimal_kernel_basis(row_wise=False, normal_form=True, # optional - sage.libs.pari + ....: shifts=[0,1,2]) [ 6*x 6*x^2] [ 1 0] [ 0 1] diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index f3952cecda7..a67311c9e9c 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -19,7 +19,7 @@ sage: matrix(RR,2,2,sparse=True) [0.000000000000000 0.000000000000000] [0.000000000000000 0.000000000000000] - sage: matrix(GF(11),2,2,sparse=True) + sage: matrix(GF(11), 2, 2, sparse=True) # optional - sage.libs.pari [0 0] [0 0] """ @@ -119,18 +119,18 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(ZZ, 3, 3, False, 'generic') - sage: get_matrix_class(GF(2^15), 3, 3, False, None) + sage: get_matrix_class(GF(2^15), 3, 3, False, None) # optional - sage.libs.pari - sage: get_matrix_class(GF(2^17), 3, 3, False, None) + sage: get_matrix_class(GF(2^17), 3, 3, False, None) # optional - sage.libs.pari - sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri') + sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri') # optional - sage.libs.pari - sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri') + sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri') # optional - sage.libs.pari - sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float') + sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float') # optional - sage.libs.pari - sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double') + sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double') # optional - sage.libs.pari sage: get_matrix_class(RDF, 2, 2, False, 'numpy') @@ -138,7 +138,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(CDF, 2, 3, False, 'numpy') - sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe + sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe # optional - sage.libs.pari sage: get_matrix_class(IntegerModRing(3), 4, 4, False, 'meataxe') # optional - meataxe @@ -146,7 +146,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): Traceback (most recent call last): ... ValueError: 'meataxe' matrix can only deal with finite fields of order < 256 - sage: get_matrix_class(GF(next_prime(255)), 4, 4, False, 'meataxe') + sage: get_matrix_class(GF(next_prime(255)), 4, 4, False, 'meataxe') # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: 'meataxe' matrix can only deal with finite fields of order < 256 @@ -155,7 +155,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): Traceback (most recent call last): ... ValueError: unknown matrix implementation 'crazy_matrix' over Integer Ring - sage: get_matrix_class(GF(3), 2, 2, False, 'm4ri') + sage: get_matrix_class(GF(3), 2, 2, False, 'm4ri') # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: 'm4ri' matrices are only available for fields of characteristic 2 and order <= 65536 @@ -174,15 +174,15 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: type(matrix(GF(7), 2, range(4))) - sage: type(matrix(GF(16007), 2, range(4))) + sage: type(matrix(GF(16007), 2, range(4))) # optional - sage.libs.pari sage: type(matrix(CBF, 2, range(4))) - sage: type(matrix(GF(2), 2, range(4))) + sage: type(matrix(GF(2), 2, range(4))) # optional - sage.libs.pari - sage: type(matrix(GF(64,'z'), 2, range(4))) + sage: type(matrix(GF(64, 'z'), 2, range(4))) # optional - sage.libs.pari - sage: type(matrix(GF(125,'z'), 2, range(4))) # optional - meataxe + sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe # optional - sage.libs.pari """ @@ -511,16 +511,16 @@ class MatrixSpace(UniqueRepresentation, Parent): Check that libgap matrices over finite fields are working properly:: - sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') - sage: M2.one() + sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') # optional - sage.libs.pari + sage: M2.one() # optional - sage.libs.pari [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: m = M2.random_element() - sage: M1 = MatrixSpace(GF(2), 5) - sage: M1(m * m) == M1(m) * M1(m) + sage: m = M2.random_element() # optional - sage.libs.pari + sage: M1 = MatrixSpace(GF(2), 5) # optional - sage.libs.pari + sage: M1(m * m) == M1(m) * M1(m) # optional - sage.libs.pari True """ @@ -727,7 +727,7 @@ def cardinality(self): EXAMPLES:: - sage: MatrixSpace(GF(3), 2, 3).cardinality() + sage: MatrixSpace(GF(3), 2, 3).cardinality() # optional - sage.libs.pari 729 sage: MatrixSpace(ZZ, 2).cardinality() +Infinity @@ -748,7 +748,7 @@ def characteristic(self): sage: MatrixSpace(ZZ, 2).characteristic() 0 - sage: MatrixSpace(GF(9), 0).characteristic() + sage: MatrixSpace(GF(9), 0).characteristic() # optional - sage.libs.pari 3 """ return self.base_ring().characteristic() @@ -773,11 +773,11 @@ def transposed(self): EXAMPLES:: - sage: MS = MatrixSpace(GF(3), 7, 10) - sage: MS.transposed + sage: MS = MatrixSpace(GF(3), 7, 10) # optional - sage.libs.pari + sage: MS.transposed # optional - sage.libs.pari Full MatrixSpace of 10 by 7 dense matrices over Finite Field of size 3 - sage: MS = MatrixSpace(GF(3), 7, 7) - sage: MS.transposed is MS + sage: MS = MatrixSpace(GF(3), 7, 7) # optional - sage.libs.pari + sage: MS.transposed is MS # optional - sage.libs.pari True sage: M = MatrixSpace(ZZ, 2, 3) @@ -795,15 +795,15 @@ def _copy_zero(self): EXAMPLES:: - sage: MS = MatrixSpace(GF(2),20,20) - sage: MS._copy_zero + sage: MS = MatrixSpace(GF(2), 20, 20) # optional - sage.libs.pari + sage: MS._copy_zero # optional - sage.libs.pari False - sage: MS = MatrixSpace(GF(3),20,20) - sage: MS._copy_zero + sage: MS = MatrixSpace(GF(3), 20, 20) # optional - sage.libs.pari + sage: MS._copy_zero # optional - sage.libs.pari True - sage: MS = MatrixSpace(GF(3),200,200) - sage: MS._copy_zero + sage: MS = MatrixSpace(GF(3), 200, 200) # optional - sage.libs.pari + sage: MS._copy_zero # optional - sage.libs.pari False sage: MS = MatrixSpace(ZZ,200,200) @@ -838,9 +838,10 @@ def _element_constructor_(self, entries, **kwds): EXAMPLES:: - sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])]) - sage: g = G.0 - sage: MatrixSpace(k,2)(g) + sage: k = GF(7) + sage: G = MatrixGroup([matrix(k, 2, [1,1,0,1]), matrix(k, 2, [1,0,0,2])]) # optional - sage.libs.pari + sage: g = G.0 # optional - sage.libs.pari + sage: MatrixSpace(k, 2)(g) # optional - sage.libs.pari [1 1] [0 1] @@ -890,14 +891,17 @@ def _element_constructor_(self, entries, **kwds): Ensure that :trac:`12020` is fixed:: + sage: rings = [ZZ, QQ, RealField(100), ComplexField(100), RDF, CDF] + sage: rings.append(PolynomialRing(QQ, 'x')) + sage: rings.append(PolynomialRing(CC, 2, 'x')) + sage: rings.append(SR) # optional - sage.symbolic + sage: rings.extend([GF(2), GF(11), GF(2^8,'a'), GF(3^19,'a')]) # optional - sage.libs.pari sage: x = polygen(QQ) - sage: for R in [ZZ, QQ, RealField(100), ComplexField(100), RDF, CDF, - ....: SR, GF(2), GF(11), GF(2^8,'a'), GF(3^19,'a'), - ....: NumberField(x^3+2,'a'), CyclotomicField(4), - ....: PolynomialRing(QQ,'x'), PolynomialRing(CC,2,'x')]: - ....: A = MatrixSpace(R,60,30,sparse=False)(0) + sage: rings.extend([NumberField(x^3+2, 'a'), CyclotomicField(4)] # optional - sage.rings.number_field + sage: for R in rings: + ....: A = MatrixSpace(R, 60, 30, sparse=False)(0) ....: B = A.augment(A) - ....: A = MatrixSpace(R,60,30,sparse=True)(0) + ....: A = MatrixSpace(R, 60, 30, sparse=True)(0) ....: B = A.augment(A) Check that :trac:`13012` is fixed:: @@ -958,8 +962,9 @@ def change_ring(self, R): EXAMPLES:: - sage: Mat(QQ,3,5).change_ring(GF(7)) - Full MatrixSpace of 3 by 5 dense matrices over Finite Field of size 7 + sage: Mat(QQ, 3, 5).change_ring(GF(7)) # optional - sage.libs.pari + Full MatrixSpace of 3 by 5 dense matrices + over Finite Field of size 7 """ try: return self.__change_ring[R] @@ -983,9 +988,9 @@ def base_extend(self, R): EXAMPLES:: - sage: Mat(ZZ,3,5).base_extend(QQ) + sage: Mat(ZZ, 3, 5).base_extend(QQ) Full MatrixSpace of 3 by 5 dense matrices over Rational Field - sage: Mat(QQ,3,5).base_extend(GF(7)) + sage: Mat(QQ, 3, 5).base_extend(GF(7)) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: no base extension defined @@ -1139,13 +1144,13 @@ def _coerce_map_from_(self, S): There are also coercions possible from matrix group and arithmetic subgroups:: - sage: MS = MatrixSpace(GF(3), 2, 2) - sage: MS.coerce_map_from(GL(2, 3)) + sage: MS = MatrixSpace(GF(3), 2, 2) # optional - sage.libs.pari + sage: MS.coerce_map_from(GL(2, 3)) # optional - sage.libs.pari Coercion map: From: General Linear Group of degree 2 over Finite Field of size 3 To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 - sage: MS.coerce_map_from(GL(2, 2)) - sage: MS.coerce_map_from(Gamma1(5)) + sage: MS.coerce_map_from(GL(2, 2)) # optional - sage.libs.pari + sage: MS.coerce_map_from(Gamma1(5)) # optional - sage.libs.pari Coercion map: From: Congruence Subgroup Gamma1(5) To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 @@ -1334,14 +1339,14 @@ def __len__(self): EXAMPLES:: - sage: len(MatrixSpace(GF(3),3,2)) + sage: len(MatrixSpace(GF(3), 3, 2)) # optional - sage.libs.pari 729 - sage: len(MatrixSpace(GF(3),2,3)) + sage: len(MatrixSpace(GF(3), 2, 3)) # optional - sage.libs.pari 729 - sage: 3^(2*3) + sage: 3^(2*3) # optional - sage.libs.pari 729 - sage: len(MatrixSpace(GF(2003),3,2)) + sage: len(MatrixSpace(GF(2003), 3, 2)) # optional - sage.libs.pari Traceback (most recent call last): ... OverflowError: cannot fit 'int' into an index-sized integer @@ -1367,20 +1372,20 @@ def __iter__(self): :: - sage: list( GF(5) ) + sage: list(GF(5)) # optional - sage.libs.pari [0, 1, 2, 3, 4] - sage: MS = MatrixSpace(GF(5), 2, 2) - sage: l = list(MS) + sage: MS = MatrixSpace(GF(5), 2, 2) # optional - sage.libs.pari + sage: l = list(MS) # optional - sage.libs.pari Then, consider the following matrices:: - sage: A = MS([2,1,0,1]); A + sage: A = MS([2,1,0,1]); A # optional - sage.libs.pari [2 1] [0 1] - sage: B = MS([1,2,1,0]); B + sage: B = MS([1,2,1,0]); B # optional - sage.libs.pari [1 2] [1 0] - sage: C = MS([1,2,0,0]); C + sage: C = MS([1,2,0,0]); C # optional - sage.libs.pari [1 2] [0 0] @@ -1389,9 +1394,9 @@ def __iter__(self): :: - sage: l.index(A) + sage: l.index(A) # optional - sage.libs.pari 41 - sage: l.index(B) + sage: l.index(B) # optional - sage.libs.pari 46 However, A would come after the matrix C since C has a lower weight @@ -1399,9 +1404,9 @@ def __iter__(self): :: - sage: l.index(A) + sage: l.index(A) # optional - sage.libs.pari 41 - sage: l.index(C) + sage: l.index(C) # optional - sage.libs.pari 19 The weights of matrices over other base rings are not as obvious. @@ -1428,11 +1433,11 @@ def __iter__(self): Some more examples:: - sage: MS = MatrixSpace(GF(2),2) - sage: a = list(MS) - sage: len(a) + sage: MS = MatrixSpace(GF(2), 2) # optional - sage.libs.pari + sage: a = list(MS) # optional - sage.libs.pari + sage: len(a) # optional - sage.libs.pari 16 - sage: for m in a: + sage: for m in a: # optional - sage.libs.pari ....: print(m) ....: print('-') [0 0] @@ -1486,11 +1491,11 @@ def __iter__(self): :: - sage: MS = MatrixSpace(GF(2),2, 3) - sage: a = list(MS) - sage: len(a) + sage: MS = MatrixSpace(GF(2), 2, 3) # optional - sage.libs.pari + sage: a = list(MS) # optional - sage.libs.pari + sage: len(a) # optional - sage.libs.pari 64 - sage: a[0] + sage: a[0] # optional - sage.libs.pari [0 0 0] [0 0 0] @@ -1512,11 +1517,11 @@ def __iter__(self): :: - sage: list( MatrixSpace(GF(2), 2, 0) ) + sage: list(MatrixSpace(GF(2), 2, 0)) # optional - sage.libs.pari [[]] - sage: list( MatrixSpace(GF(2), 0, 2) ) + sage: list(MatrixSpace(GF(2), 0, 2)) # optional - sage.libs.pari [[]] - sage: list( MatrixSpace(GF(2), 0, 0) ) + sage: list(MatrixSpace(GF(2), 0, 0)) # optional - sage.libs.pari [[]] If the base ring does not support iteration (for example, with the @@ -1586,13 +1591,15 @@ def __getitem__(self, x): EXAMPLES:: - sage: MS = MatrixSpace(GF(3), 2, 2) - sage: MS['x'] - Univariate Polynomial Ring in x over Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 - sage: MS[0] + sage: MS = MatrixSpace(GF(3), 2, 2) # optional - sage.libs.pari + sage: MS['x'] # optional - sage.libs.pari + Univariate Polynomial Ring in x + over Full MatrixSpace of 2 by 2 dense matrices + over Finite Field of size 3 + sage: MS[0] # optional - sage.libs.pari [0 0] [0 0] - sage: MS[9] + sage: MS[9] # optional - sage.libs.pari [0 2] [0 0] @@ -1887,9 +1894,9 @@ def is_sparse(self): EXAMPLES:: - sage: Mat(GF(2011),10000).is_sparse() + sage: Mat(GF(2011), 10000).is_sparse() # optional - sage.libs.pari False - sage: Mat(GF(2011),10000,sparse=True).is_sparse() + sage: Mat(GF(2011), 10000, sparse=True).is_sparse() # optional - sage.libs.pari True """ return self.__is_sparse @@ -1900,7 +1907,7 @@ def is_finite(self): EXAMPLES:: - sage: MatrixSpace(GF(101), 10000).is_finite() + sage: MatrixSpace(GF(101), 10000).is_finite() # optional - sage.libs.pari True sage: MatrixSpace(QQ, 2).is_finite() False @@ -1916,10 +1923,10 @@ def gen(self, n): EXAMPLES:: - sage: M = Mat(GF(7),10000,5); M.ngens() + sage: M = Mat(GF(7), 10000, 5); M.ngens() # optional - sage.libs.pari 50000 - sage: a = M.10 - sage: a[:4] + sage: a = M.10 # optional - sage.libs.pari + sage: a[:4] # optional - sage.libs.pari [0 0 0 0 0] [0 0 0 0 0] [1 0 0 0 0] @@ -1943,10 +1950,10 @@ def zero_matrix(self): EXAMPLES:: - sage: z = MatrixSpace(GF(7),2,4).zero_matrix(); z + sage: z = MatrixSpace(GF(7), 2, 4).zero_matrix(); z # optional - sage.libs.pari [0 0 0 0] [0 0 0 0] - sage: z.is_mutable() + sage: z.is_mutable() # optional - sage.libs.pari False TESTS:: @@ -1977,7 +1984,7 @@ def ngens(self): EXAMPLES:: - sage: M = Mat(GF(7),100,200); M.ngens() + sage: M = Mat(GF(7), 100, 200); M.ngens() # optional - sage.libs.pari 20000 """ return self.dimension() @@ -2091,10 +2098,10 @@ def matrix(self, x=None, **kwds): Converting sparse to dense matrices used to be too slow (:trac:`20470`). Check that this is fixed:: - sage: m = identity_matrix(GF(2), 2000, sparse=True) - sage: MS = MatrixSpace(GF(2), 2000, sparse=False) - sage: md = MS(m) # used to be slow - sage: md.parent() is MS + sage: m = identity_matrix(GF(2), 2000, sparse=True) # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(2), 2000, sparse=False) # optional - sage.libs.pari + sage: md = MS(m) # used to be slow # optional - sage.libs.pari + sage: md.parent() is MS # optional - sage.libs.pari True """ return self(x, **kwds) @@ -2107,12 +2114,12 @@ def matrix_space(self, nrows=None, ncols=None, sparse=False): EXAMPLES:: - sage: M = Mat(GF(7),100,200) - sage: M.matrix_space(5000) + sage: M = Mat(GF(7), 100, 200) # optional - sage.libs.pari + sage: M.matrix_space(5000) # optional - sage.libs.pari Full MatrixSpace of 5000 by 200 dense matrices over Finite Field of size 7 - sage: M.matrix_space(ncols=5000) + sage: M.matrix_space(ncols=5000) # optional - sage.libs.pari Full MatrixSpace of 100 by 5000 dense matrices over Finite Field of size 7 - sage: M.matrix_space(sparse=True) + sage: M.matrix_space(sparse=True) # optional - sage.libs.pari Full MatrixSpace of 100 by 200 sparse matrices over Finite Field of size 7 """ if nrows is None: @@ -2172,7 +2179,7 @@ def column_space(self): EXAMPLES:: - sage: M = Mat(GF(9,'a'),20,5,sparse=True); M.column_space() + sage: M = Mat(GF(9,'a'), 20, 5, sparse=True); M.column_space() # optional - sage.libs.pari Sparse vector space of dimension 20 over Finite Field in a of size 3^2 """ try: @@ -2231,8 +2238,8 @@ def random_element(self, density=None, *args, **kwds): sage: M = Mat(QQ, 3, sparse=True).random_element() sage: TestSuite(M).run() - sage: M = Mat(GF(9,'a'), 3, sparse=True).random_element() - sage: TestSuite(M).run() + sage: M = Mat(GF(9,'a'), 3, sparse=True).random_element() # optional - sage.libs.pari + sage: TestSuite(M).run() # optional - sage.libs.pari """ Z = self.zero_matrix().__copy__() if density is None: @@ -2264,8 +2271,8 @@ def _an_element_(self): Check that this works for large matrices and that it returns a matrix which is not too trivial:: - sage: M = MatrixSpace(GF(2), 100, 100).an_element() - sage: M.rank() >= 2 + sage: M = MatrixSpace(GF(2), 100, 100).an_element() # optional - sage.libs.pari + sage: M.rank() >= 2 # optional - sage.libs.pari True Check that this works for sparse matrices:: @@ -2365,9 +2372,9 @@ def _polymake_init_(self): EXAMPLES:: - sage: polymake(MatrixSpace(QQ,3)) # optional - jupymake + sage: polymake(MatrixSpace(QQ, 3)) # optional - jupymake Matrix - sage: polymake(MatrixSpace(QuadraticField(5),3)) # optional - jupymake + sage: polymake(MatrixSpace(QuadraticField(5), 3)) # optional - jupymake # optional - sage.rings.number_field Matrix """ from sage.interfaces.polymake import polymake @@ -2477,18 +2484,18 @@ def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, check sage: tinv(QQ, sparse=True) sage: tinv(QQ, sparse=False, implementation='flint') sage: tinv(QQ, sparse=False, implementation='generic') - sage: tinv(GF(11), sparse=True) - sage: tinv(GF(11), sparse=False) - sage: tinv(GF(2), sparse=True) - sage: tinv(GF(2), sparse=False) + sage: tinv(GF(11), sparse=True) # optional - sage.libs.pari + sage: tinv(GF(11), sparse=False) # optional - sage.libs.pari + sage: tinv(GF(2), sparse=True) # optional - sage.libs.pari + sage: tinv(GF(2), sparse=False) # optional - sage.libs.pari sage: tinv(SR, sparse=True) sage: tinv(SR, sparse=False) sage: tinv(RDF, sparse=True) sage: tinv(RDF, sparse=False) sage: tinv(CDF, sparse=True) sage: tinv(CDF, sparse=False) - sage: tinv(CyclotomicField(7), sparse=True) - sage: tinv(CyclotomicField(7), sparse=False) + sage: tinv(CyclotomicField(7), sparse=True) # optional - sage.rings.number_field + sage: tinv(CyclotomicField(7), sparse=False) # optional - sage.rings.number_field sage: tinv(QQ['x,y'], sparse=True) sage: tinv(QQ['x,y'], sparse=False) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index 1addeac9b83..df03aed59d5 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -1,3 +1,4 @@ + r""" Base class for sparse matrices """ @@ -635,13 +636,14 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: sage: m = matrix(ZZ, 3, range(9), sparse=True) - sage: phi = ZZ.hom(GF(5)) - sage: m.apply_morphism(phi) + sage: phi = ZZ.hom(GF(5)) # optional - sage.libs.pari + sage: m.apply_morphism(phi) # optional - sage.libs.pari [0 1 2] [3 4 0] [1 2 3] - sage: m.apply_morphism(phi).parent() - Full MatrixSpace of 3 by 3 sparse matrices over Finite Field of size 5 + sage: m.apply_morphism(phi).parent() # optional - sage.libs.pari + Full MatrixSpace of 3 by 3 sparse matrices + over Finite Field of size 5 """ R = phi.codomain() M = sage.matrix.matrix_space.MatrixSpace(R, self._nrows, @@ -670,22 +672,24 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: sage: m = matrix(ZZ, 10000, {(1,2): 17}, sparse=True) - sage: k. = GF(9) - sage: f = lambda x: k(x) - sage: n = m.apply_map(f) - sage: n.parent() - Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field in a of size 3^2 - sage: n[1,2] + sage: k. = GF(9) # optional - sage.libs.pari + sage: f = lambda x: k(x) # optional - sage.libs.pari + sage: n = m.apply_map(f) # optional - sage.libs.pari + sage: n.parent() # optional - sage.libs.pari + Full MatrixSpace of 10000 by 10000 sparse matrices + over Finite Field in a of size 3^2 + sage: n[1, 2] # optional - sage.libs.pari 2 An example where the codomain is explicitly specified. :: - sage: n = m.apply_map(lambda x:x%3, GF(3)) - sage: n.parent() - Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field of size 3 - sage: n[1,2] + sage: n = m.apply_map(lambda x:x%3, GF(3)) # optional - sage.libs.pari + sage: n.parent() # optional - sage.libs.pari + Full MatrixSpace of 10000 by 10000 sparse matrices + over Finite Field of size 3 + sage: n[1, 2] # optional - sage.libs.pari 2 If we did not specify the codomain, the resulting matrix in the @@ -694,7 +698,7 @@ cdef class Matrix_sparse(matrix.Matrix): sage: n = m.apply_map(lambda x:x%3) sage: n.parent() Full MatrixSpace of 10000 by 10000 sparse matrices over Integer Ring - sage: n[1,2] + sage: n[1, 2] 2 If self is subdivided, the result will be as well:: diff --git a/src/sage/matrix/symplectic_basis.py b/src/sage/matrix/symplectic_basis.py index 4caee7a6da6..d42d76a4543 100644 --- a/src/sage/matrix/symplectic_basis.py +++ b/src/sage/matrix/symplectic_basis.py @@ -188,7 +188,11 @@ def symplectic_basis_over_field(M): An example over a finite field:: - sage: E = matrix(GF(7), 8, 8, [0, -1/2, -2, 1/2, 2, 0, -2, 1, 1/2, 0, -1, -3, 0, 2, 5/2, -3, 2, 1, 0, 3/2, -1, 0, -1, -2, -1/2, 3, -3/2, 0, 1, 3/2, -1/2, -1/2, -2, 0, 1, -1, 0, 0, 1, -1, 0, -2, 0, -3/2, 0, 0, 1/2, -2, 2, -5/2, 1, 1/2, -1, -1/2, 0, -1, -1, 3, 2, 1/2, 1, 2, 1, 0]); E + sage: E = matrix(GF(7), 8, 8, [0, -1/2, -2, 1/2, 2, 0, -2, 1, 1/2, 0, -1, -3, 0, 2, 5/2, # optional - sage.libs.pari + ....: -3, 2, 1, 0, 3/2, -1, 0, -1, -2, -1/2, 3, -3/2, 0, 1, 3/2, + ....: -1/2, -1/2, -2, 0, 1, -1, 0, 0, 1, -1, 0, -2, 0, -3/2, 0, + ....: 0, 1/2, -2, 2, -5/2, 1, 1/2, -1, -1/2, 0, -1, -1, 3, 2, + ....: 1/2, 1, 2, 1, 0]); E [0 3 5 4 2 0 5 1] [4 0 6 4 0 2 6 4] [2 1 0 5 6 0 6 5] @@ -197,7 +201,7 @@ def symplectic_basis_over_field(M): [0 5 0 2 0 0 4 5] [2 1 1 4 6 3 0 6] [6 3 2 4 1 2 1 0] - sage: F, C = symplectic_basis_over_field(E); F + sage: F, C = symplectic_basis_over_field(E); F # optional - sage.libs.pari [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] @@ -206,12 +210,15 @@ def symplectic_basis_over_field(M): [0 6 0 0 0 0 0 0] [0 0 6 0 0 0 0 0] [0 0 0 6 0 0 0 0] - sage: F == C * E * C.transpose() + sage: F == C * E * C.transpose() # optional - sage.libs.pari True The tricky case of characteristic 2:: - sage: E = matrix(GF(2), 8, 8, [0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]); E + sage: E = matrix(GF(2), 8, 8, [0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, # optional - sage.libs.pari + ....: 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, + ....: 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, + ....: 0, 1, 0, 0]); E [0 0 1 1 0 1 0 1] [0 0 0 0 0 0 0 0] [1 0 0 0 0 0 1 1] @@ -220,7 +227,7 @@ def symplectic_basis_over_field(M): [1 0 0 0 1 0 1 1] [0 0 1 0 1 1 0 0] [1 0 1 1 0 1 0 0] - sage: F, C = symplectic_basis_over_field(E); F + sage: F, C = symplectic_basis_over_field(E); F # optional - sage.libs.pari [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] @@ -229,7 +236,7 @@ def symplectic_basis_over_field(M): [0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] - sage: F == C * E * C.transpose() + sage: F == C * E * C.transpose() # optional - sage.libs.pari True An inexact example:: diff --git a/src/sage/matrix/tests.py b/src/sage/matrix/tests.py index 21b7920307a..a42935d0e70 100644 --- a/src/sage/matrix/tests.py +++ b/src/sage/matrix/tests.py @@ -11,7 +11,7 @@ Vector space of degree 1 and dimension 1 over Rational Field Basis matrix: [1] - sage: matrix(GF(7),1,0).kernel() + sage: matrix(GF(7), 1, 0).kernel() # optional - sage.libs.pari Vector space of degree 1 and dimension 1 over Finite Field of size 7 Basis matrix: [1] @@ -28,7 +28,7 @@ Vector space of degree 0 and dimension 0 over Rational Field Basis matrix: [] - sage: matrix(GF(7),0,1).kernel() + sage: matrix(GF(7), 0, 1).kernel() # optional - sage.libs.pari Vector space of degree 0 and dimension 0 over Finite Field of size 7 Basis matrix: [] diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index b400cc4afd0..4064bcc5a30 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -523,7 +523,6 @@ def __mul__(self, right): Composite maps can be formed with matrix morphisms:: - sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^2 + 23) # optional - sage.rings.number_field sage: V, VtoK, KtoV = K.vector_space() # optional - sage.rings.number_field sage: f = V.hom([V.0 - V.1, V.0 + V.1])*KtoV; f # optional - sage.rings.number_field @@ -539,9 +538,9 @@ def __mul__(self, right): [ 1 1] Domain: Vector space of dimension 2 over Rational Field Codomain: Vector space of dimension 2 over Rational Field - sage: f(a) + sage: f(a) # optional - sage.rings.number_field (1, 1) - sage: V.hom([V.0 - V.1, V.0 + V.1], side="right")*KtoV + sage: V.hom([V.0 - V.1, V.0 + V.1], side="right")*KtoV # optional - sage.rings.number_field Composite map: From: Number Field in a with defining polynomial x^2 + 23 To: Vector space of dimension 2 over Rational Field @@ -976,22 +975,22 @@ def image(self): Basis matrix: [ 1 0 -1] [ 0 1 2] - sage: hom(GF(7)^3, GF(7)^2, zero_matrix(GF(7), 3, 2)).image() + sage: hom(GF(7)^3, GF(7)^2, zero_matrix(GF(7), 3, 2)).image() # optional - sage.libs.pari Vector space of degree 2 and dimension 0 over Finite Field of size 7 Basis matrix: [] - sage: m = matrix(3, [1, 0, 0, 1, 0, 0, 0, 0, 1]); m + sage: m = matrix(3, [1, 0, 0, 1, 0, 0, 0, 0, 1]); m # optional - sage.libs.pari [1 0 0] [1 0 0] [0 0 1] - sage: f1 = V.hom(m) - sage: f2 = V.hom(m, side="right") - sage: f1.image() + sage: f1 = V.hom(m) # optional - sage.libs.pari + sage: f2 = V.hom(m, side="right") # optional - sage.libs.pari + sage: f1.image() # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [1 0 0] [0 0 1] - sage: f2.image() + sage: f2.image() # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [1 1 0] From 8cb27b7fe8a97e6594ba7278ed7983ecac9bfeff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 26 Feb 2023 11:37:10 -0800 Subject: [PATCH 07/99] sage.modules, sage.matrix: Fix up # optional --- src/sage/matrix/matrix0.pyx | 4 ++-- src/sage/matrix/matrix2.pyx | 12 ++++++------ src/sage/matrix/matrix_polynomial_dense.pyx | 8 ++++---- src/sage/matrix/matrix_space.py | 2 +- src/sage/modules/free_module.py | 2 +- src/sage/modules/free_module_element.pyx | 8 ++++++-- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 8a4b0922d40..141332cde3b 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -916,8 +916,8 @@ cdef class Matrix(sage.structure.element.Matrix): over Finite Field of size 2 (using Matrix_generic_dense) sage: type(m[:2,:2]) # optional - sage.libs.pari - sage: parent(m[:2,:2]) - Full MatrixSpace of 2 by 2 dense matrices # optional - sage.libs.pari + sage: parent(m[:2,:2]) # optional - sage.libs.pari + Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 2 (using Matrix_generic_dense) """ cdef list row_list diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index dcbf73faa2a..0435473c6d2 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1927,7 +1927,7 @@ cdef class Matrix(Matrix1): This test addresses an issue raised at :trac:`20512`:: - sage: A.minors(0)[0].parent() == P + sage: A.minors(0)[0].parent() == P # optional - sage.libs.pari True """ from sage.combinat.combination import Combinations @@ -2816,7 +2816,7 @@ cdef class Matrix(Matrix1): The default variable name is `x`, but you can specify another name:: - sage: factor(A.minpoly('y')) + sage: factor(A.minpoly('y')) # optional - sage.libs.pari (y + 1) * (y + 2)^2 """ f = self.fetch('minpoly') @@ -4745,9 +4745,9 @@ cdef class Matrix(Matrix1): If the optional meataxe package is installed, we again have to make sure to work with a copy of B that has the same type as ``P.basis_matrix()``:: - sage: B.parent()(B.list())*P.basis_matrix().transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari + sage: B.parent()(B.list()) * P.basis_matrix().transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari True - sage: K == P + sage: K == P # optional - sage.libs.pari True Over number fields, PARI is used by default, but general-purpose code @@ -13871,7 +13871,7 @@ cdef class Matrix(Matrix1): True sage: L, d = A.indefinite_factorization() # optional - sage.libs.pari sage: D = diagonal_matrix(d) # optional - sage.libs.pari - sage: L + sage: L # optional - sage.libs.pari [ 1 0 0 0] [4*a^2 + 4*a + 3 1 0 0] [ 3 4*a^2 + a + 2 1 0] @@ -15152,7 +15152,7 @@ cdef class Matrix(Matrix1): numbers or finite fields which are not a quadratic extension:: sage: N = matrix(GF(5), 2, [0,1,2,3]) # optional - sage.libs.pari - sage: N.conjugate_transpose() + sage: N.conjugate_transpose() # optional - sage.libs.pari Traceback (most recent call last): ... AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object has no attribute 'conjugate' diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 4f409850406..3137ee206c5 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -2526,8 +2526,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: Fq. = GF(2^3) # optional - sage.libs.pari sage: pR. = Fq[] # optional - sage.libs.pari - sage: A = matrix(pR, [[x^2+a, x^4+a], - ....: [ x^3, a*x^4]]) # optional - sage.libs.pari + sage: A = matrix(pR, [[x^2+a, x^4+a], # optional - sage.libs.pari + ....: [ x^3, a*x^4]]) sage: W, U = A.reduced_form(transformation=True) # optional - sage.libs.pari sage: W, U # optional - sage.libs.pari ( @@ -2645,8 +2645,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): ....: [[ 3*x^3 + 3*x, 2*x^3 + 4], ....: [ 3*x^3 + 6*x + 5, 6*x^3 + 5*x^2 + 1], ....: [ 2*x^3 + 2*x + 6, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, - ....: [[ 3, x + 3, 6], # optional - sage.libs.pari + sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + ....: [[ 3, x + 3, 6], ....: [3*x^3 + 3*x + 1, 4*x^2 + 3*x, 6*x^3 + x + 4], ....: [ 4*x^2 + x + 4, 3*x^2 + 4*x, 3*x^2 + 3*x + 2]]) sage: Q, R = A.left_quo_rem(B); Q, R # optional - sage.libs.pari diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index a67311c9e9c..c4e2a9e3144 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -897,7 +897,7 @@ def _element_constructor_(self, entries, **kwds): sage: rings.append(SR) # optional - sage.symbolic sage: rings.extend([GF(2), GF(11), GF(2^8,'a'), GF(3^19,'a')]) # optional - sage.libs.pari sage: x = polygen(QQ) - sage: rings.extend([NumberField(x^3+2, 'a'), CyclotomicField(4)] # optional - sage.rings.number_field + sage: rings.extend([NumberField(x^3+2, 'a'), CyclotomicField(4)]) # optional - sage.rings.number_field sage: for R in rings: ....: A = MatrixSpace(R, 60, 30, sparse=False)(0) ....: B = A.augment(A) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index cd64ea4ce51..c6ec33ad5d0 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -6005,7 +6005,7 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category TESTS:: sage: A = FreeModule(PolynomialRing(GF(5),'x'), 3) # optional - sage.libs.pari - sage: TestSuite(A).run() + sage: TestSuite(A).run() # optional - sage.libs.pari """ FreeModule_ambient.__init__(self, base_ring, rank, sparse, coordinate_ring, category=category) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 8d3c829f28a..8f147226c2c 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -877,9 +877,13 @@ def random_vector(ring, degree=None, *args, **kwds): sage: w1 = vector(ZZ.random_element(distribution="1/n") for _ in range(20)) sage: w2 = vector(ZZ.random_element(x=-1000, y=1000) for _ in range(15)) sage: w3 = vector(QQ.random_element() for _ in range(10)) + sage: [v1, v2, v3] == [w1, w2, w3] + True sage: w4 = vector(FiniteField(17).random_element() for _ in range(10)) # optional - sage.libs.pari + sage: v4 == w4 # optional - sage.libs.pari + True sage: w5 = vector(RR.random_element() for _ in range(10)) - sage: [v1, v2, v3, v4, v5] == [w1, w2, w3, w4, w5] + sage: v5 == w5 True Inputs get checked before constructing the vector. :: @@ -2842,7 +2846,7 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: v.pairwise_product(w).parent() + sage: v.pairwise_product(w).parent() # optional - sage.libs.pari Vector space of dimension 3 over Finite Field of size 3 TESTS:: From d596f3088eff9f0e5398cad06e1c56bdb51bdc89 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 26 Feb 2023 15:08:21 -0800 Subject: [PATCH 08/99] src/sage/matrix/matrix_space.py: More try...import...except --- src/sage/matrix/matrix_space.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index c4e2a9e3144..7671e745458 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -250,11 +250,15 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): pass if isinstance(R, sage.rings.abc.IntegerModRing): - from . import matrix_modn_dense_double, matrix_modn_dense_float - if R.order() < matrix_modn_dense_float.MAX_MODULUS: - return matrix_modn_dense_float.Matrix_modn_dense_float - if R.order() < matrix_modn_dense_double.MAX_MODULUS: - return matrix_modn_dense_double.Matrix_modn_dense_double + try: + from . import matrix_modn_dense_double, matrix_modn_dense_float + except ImportError: + pass + else: + if R.order() < matrix_modn_dense_float.MAX_MODULUS: + return matrix_modn_dense_float.Matrix_modn_dense_float + if R.order() < matrix_modn_dense_double.MAX_MODULUS: + return matrix_modn_dense_double.Matrix_modn_dense_double if isinstance(R, sage.rings.abc.NumberField_cyclotomic): from . import matrix_cyclo_dense From 25a7b44aa6807ea491e2e0ec1665e2a1a1618ecf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 26 Feb 2023 15:32:17 -0800 Subject: [PATCH 09/99] src/sage/matrix/matrix2.pyx: More # optional --- src/sage/matrix/matrix2.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 0435473c6d2..6ac1605f226 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -2788,9 +2788,9 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: a = matrix(QQ, 4, 4, range(16)) - sage: a.minimal_polynomial('z') + sage: a.minimal_polynomial('z') # optional - sage.libs.pari z^3 - 30*z^2 - 80*z - sage: a.minpoly() + sage: a.minpoly() # optional - sage.libs.pari x^3 - 30*x^2 - 80*x """ return self.minpoly(var, **kwds) From 9e6aa04e9372225b30a85735fe6992e1e1bc1ca1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 Feb 2023 10:53:52 -0800 Subject: [PATCH 10/99] src/sage/matrix/matrix_polynomial_dense.pyx: Fix reformatted doctest --- src/sage/matrix/matrix_polynomial_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 3137ee206c5..9e8a2586fa0 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -3546,7 +3546,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): True sage: (F.minimal_approximant_basis(3, row_wise=True) == # optional - sage.libs.pari ....: F.transpose().minimal_approximant_basis( - ....: 3, row_wise=False).transpose() + ....: 3, row_wise=False).transpose()) True Errors are raised if the input dimensions are not sound:: From baa492e0b893dcda25a3ab201854bf59d2c35144 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 21:37:47 -0800 Subject: [PATCH 11/99] sage.matrix, sage.modules: Add # optional - numpy, fpylll, etc. --- src/sage/matrix/args.pyx | 10 +-- src/sage/matrix/constructor.pyx | 56 +++++++-------- src/sage/matrix/matrix1.pyx | 17 +++-- src/sage/matrix/special.py | 24 +++---- src/sage/modules/free_module_element.pyx | 86 ++++++++++++------------ src/sage/modules/free_module_integer.py | 8 +-- 6 files changed, 102 insertions(+), 99 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index eeeb9f47f09..dbc611208d7 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -217,23 +217,23 @@ cdef class MatrixArgs: > [1 2] [3 4] - sage: from numpy import array - sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized(); ma.matrix() + sage: from numpy import array # optional - numpy + sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized(); ma.matrix() # optional - numpy [1 2] [3 4] - sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() + sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() # optional - numpy [1.0 2.0] [3.0 4.0] - sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() + sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() # optional - numpy [1.0000 2.0000] [3.0000 4.0000] - sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized(); ma.matrix() + sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized(); ma.matrix() # optional - sage.graphs diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index 692d58aff5b..f8b70b56a26 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -172,9 +172,9 @@ def matrix(*args, **kwds): :: - sage: import numpy - sage: n = numpy.array([[1,2],[3,4]],float) - sage: m = matrix(n); m; m.parent() + sage: import numpy # optional - numpy + sage: n = numpy.array([[1,2], [3,4]], float) # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0] [3.0 4.0] Full MatrixSpace of 2 by 2 dense matrices over Real Double Field @@ -456,77 +456,77 @@ def matrix(*args, **kwds): Check conversion from numpy:: - sage: import numpy - sage: n = numpy.array([[complex(0,1),complex(0,2)],[3,4]],complex) - sage: m = matrix(n); m; m.parent() + sage: import numpy # optional - numpy + sage: n = numpy.array([[complex(0,1),complex(0,2)], [3,4]], complex) # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0*I 2.0*I] [ 3.0 4.0] Full MatrixSpace of 2 by 2 dense matrices over Complex Double Field - sage: n = numpy.array([[1,2],[3,4]],'int32') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.array([[1,2], [3,4]], 'int32') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1 2] [3 4] Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: n = numpy.array([[1,2,3],[4,5,6],[7,8,9]],'float32') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'float32') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Real Double Field - sage: n = numpy.matrix([[1,2,3],[4,5,6],[7,8,9]],'float64') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'float64') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Real Double Field - sage: n = numpy.array([[1,2,3],[4,5,6],[7,8,9]],'complex64') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'complex64') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Complex Double Field - sage: n = numpy.matrix([[1,2,3],[4,5,6],[7,8,9]],'complex128') - sage: m = matrix(n); m; m.parent() + sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'complex128') # optional - numpy + sage: m = matrix(n); m; m.parent() # optional - numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Complex Double Field - sage: a = matrix([[1,2],[3,4]]) - sage: b = matrix(a.numpy()); b + sage: a = matrix([[1,2], [3,4]]) + sage: b = matrix(a.numpy()); b # optional - numpy [1 2] [3 4] - sage: a == b + sage: a == b # optional - numpy True - sage: c = matrix(a.numpy('float32')); c + sage: c = matrix(a.numpy('float32')); c # optional - numpy [1.0 2.0] [3.0 4.0] - sage: matrix(numpy.array([[5]])) + sage: matrix(numpy.array([[5]])) # optional - numpy [5] - sage: matrix(numpy.matrix([[5]])) + sage: matrix(numpy.matrix([[5]])) # optional - numpy [5] A ring and a numpy array:: - sage: n = numpy.array([[1,2,3],[4,5,6],[7,8,9]],'float32') - sage: m = matrix(ZZ, n); m; m.parent() + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]],'float32') # optional - numpy + sage: m = matrix(ZZ, n); m; m.parent() # optional - numpy [1 2 3] [4 5 6] [7 8 9] Full MatrixSpace of 3 by 3 dense matrices over Integer Ring - sage: n = matrix(QQ, 2, 2, [1, 1/2, 1/3, 1/4]).numpy(); n + sage: n = matrix(QQ, 2, 2, [1, 1/2, 1/3, 1/4]).numpy(); n # optional - numpy array([[1. , 0.5 ], [0.33333333, 0.25 ]]) - sage: matrix(QQ, n) + sage: matrix(QQ, n) # optional - numpy [ 1 1/2] [1/3 1/4] The dimensions of a matrix may be given as numpy types:: - sage: matrix(numpy.int32(2), numpy.int32(3)) + sage: matrix(numpy.int32(2), numpy.int32(3)) # optional - numpy [0 0 0] [0 0 0] - sage: matrix(nrows=numpy.int32(2), ncols=numpy.int32(3)) + sage: matrix(nrows=numpy.int32(2), ncols=numpy.int32(3)) # optional - numpy [0 0 0] [0 0 0] diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index d11687cadb7..f62450e9379 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -699,23 +699,26 @@ cdef class Matrix(Matrix0): Type ``numpy.typecodes`` for a list of the possible typecodes:: - sage: import numpy - sage: sorted(numpy.typecodes.items()) - [('All', '?bhilqpBHILQPefdgFDGSUVOMm'), ('AllFloat', 'efdgFDG'), ('AllInteger', 'bBhHiIlLqQpP'), ('Character', 'c'), ('Complex', 'FDG'), ('Datetime', 'Mm'), ('Float', 'efdg'), ('Integer', 'bhilqp'), ('UnsignedInteger', 'BHILQP')] + sage: import numpy # optional - numpy + sage: sorted(numpy.typecodes.items()) # optional - numpy + [('All', '?bhilqpBHILQPefdgFDGSUVOMm'), ('AllFloat', 'efdgFDG'), + ('AllInteger', 'bBhHiIlLqQpP'), ('Character', 'c'), ('Complex', 'FDG'), + ('Datetime', 'Mm'), ('Float', 'efdg'), ('Integer', 'bhilqp'), + ('UnsignedInteger', 'BHILQP')] Alternatively, numpy automatically calls this function (via the magic :meth:`__array__` method) to convert Sage matrices to numpy arrays:: - sage: import numpy - sage: b=numpy.array(a); b + sage: import numpy # optional - numpy + sage: b = numpy.array(a); b # optional - numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) - sage: b.dtype + sage: b.dtype # optional - numpy dtype('int32') # 32-bit dtype('int64') # 64-bit - sage: b.shape + sage: b.shape # optional - numpy (3, 4) """ import numpy diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 840f4719b1c..26ea00b08a7 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -748,36 +748,36 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): NumPy arrays may be used as input. :: - sage: import numpy - sage: entries = numpy.array([1.2, 5.6]); entries + sage: import numpy # optional - numpy + sage: entries = numpy.array([1.2, 5.6]); entries # optional - numpy array([1.2, 5.6]) - sage: A = diagonal_matrix(3, entries); A + sage: A = diagonal_matrix(3, entries); A # optional - numpy [1.2 0.0 0.0] [0.0 5.6 0.0] [0.0 0.0 0.0] - sage: A.parent() + sage: A.parent() # optional - numpy Full MatrixSpace of 3 by 3 sparse matrices over Real Double Field sage: j = complex(0,1) - sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries + sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries # optional - numpy array([2. +1.j , 8.1+0.j , 3.4+2.6j]) - sage: A = diagonal_matrix(entries); A + sage: A = diagonal_matrix(entries); A # optional - numpy [2.0 + 1.0*I 0.0 0.0] [ 0.0 8.1 0.0] [ 0.0 0.0 3.4 + 2.6*I] - sage: A.parent() + sage: A.parent() # optional - numpy Full MatrixSpace of 3 by 3 sparse matrices over Complex Double Field - sage: entries = numpy.array([4, 5, 6]) - sage: A = diagonal_matrix(entries); A + sage: entries = numpy.array([4, 5, 6]) # optional - numpy + sage: A = diagonal_matrix(entries); A # optional - numpy [4 0 0] [0 5 0] [0 0 6] - sage: A.parent() + sage: A.parent() # optional - numpy Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring - sage: entries = numpy.array([4.1, 5.2, 6.3]) - sage: A = diagonal_matrix(ZZ, entries); A + sage: entries = numpy.array([4.1, 5.2, 6.3]) # optional - numpy + sage: A = diagonal_matrix(ZZ, entries); A # optional - numpy Traceback (most recent call last): ... TypeError: unable to convert 4.1 to an element of Integer Ring diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 8f147226c2c..fe8089eddaa 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -347,27 +347,27 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): must be contiguous, so column-wise slices of numpy matrices will raise an exception. :: - sage: import numpy - sage: x = numpy.random.randn(10) - sage: y = vector(x) - sage: parent(y) + sage: import numpy # optional - numpy + sage: x = numpy.random.randn(10) # optional - numpy + sage: y = vector(x) # optional - numpy + sage: parent(y) # optional - numpy Vector space of dimension 10 over Real Double Field - sage: parent(vector(RDF, x)) + sage: parent(vector(RDF, x)) # optional - numpy Vector space of dimension 10 over Real Double Field - sage: parent(vector(CDF, x)) + sage: parent(vector(CDF, x)) # optional - numpy Vector space of dimension 10 over Complex Double Field - sage: parent(vector(RR, x)) + sage: parent(vector(RR, x)) # optional - numpy Vector space of dimension 10 over Real Field with 53 bits of precision - sage: v = numpy.random.randn(10) * complex(0,1) - sage: w = vector(v) - sage: parent(w) + sage: v = numpy.random.randn(10) * complex(0,1) # optional - numpy + sage: w = vector(v) # optional - numpy + sage: parent(w) # optional - numpy Vector space of dimension 10 over Complex Double Field Multi-dimensional arrays are not supported:: - sage: import numpy as np - sage: a = np.array([[1, 2, 3], [4, 5, 6]], np.float64) - sage: vector(a) + sage: import numpy as np # optional - numpy + sage: a = np.array([[1, 2, 3], [4, 5, 6]], np.float64) # optional - numpy + sage: vector(a) # optional - numpy Traceback (most recent call last): ... TypeError: cannot convert 2-dimensional array to a vector @@ -392,21 +392,21 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): If the argument is a vector, it doesn't change the base ring. This fixes :trac:`6643`:: - sage: K. = QuadraticField(3) - sage: u = vector(K, (1/2, sqrt3/2) ) - sage: vector(u).base_ring() + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: u = vector(K, (1/2, sqrt3/2)) # optional - sage.rings.number_field + sage: vector(u).base_ring() # optional - sage.rings.number_field Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - sage: v = vector(K, (0, 1) ) - sage: vector(v).base_ring() + sage: v = vector(K, (0, 1)) # optional - sage.rings.number_field + sage: vector(v).base_ring() # optional - sage.rings.number_field Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? Constructing a vector from a numpy array behaves as expected:: - sage: import numpy - sage: a=numpy.array([1,2,3]) - sage: v=vector(a); v + sage: import numpy # optional - numpy + sage: a = numpy.array([1,2,3]) # optional - numpy + sage: v = vector(a); v # optional - numpy (1, 2, 3) - sage: parent(v) + sage: parent(v) # optional - numpy Ambient free module of rank 3 over the principal ideal domain Integer Ring Complex numbers can be converted naturally to a sequence of length 2. And @@ -452,14 +452,14 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): sage: v = vector(QQ, w, immutable=True) sage: v.is_immutable() True - sage: import numpy as np - sage: w = np.array([1, 2, pi], float) - sage: v = vector(w, immutable=True) - sage: v.is_immutable() + sage: import numpy as np # optional - numpy + sage: w = np.array([1, 2, pi], float) # optional - numpy + sage: v = vector(w, immutable=True) # optional - numpy + sage: v.is_immutable() # optional - numpy True - sage: w = np.array([i, 2, 3], complex) - sage: v = vector(w, immutable=True) - sage: v.is_immutable() + sage: w = np.array([i, 2, 3], complex) # optional - numpy + sage: v = vector(w, immutable=True) # optional - numpy + sage: v.is_immutable() # optional - numpy True TESTS: @@ -1074,48 +1074,48 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector([1,2,3]) - sage: v.numpy() + sage: v.numpy() # optional - numpy array([1, 2, 3], dtype=object) - sage: v.numpy() * v.numpy() + sage: v.numpy() * v.numpy() # optional - numpy array([1, 4, 9], dtype=object) - sage: vector(QQ, [1, 2, 5/6]).numpy() + sage: vector(QQ, [1, 2, 5/6]).numpy() # optional - numpy array([1, 2, 5/6], dtype=object) By default the ``object`` `dtype `_ is used. Alternatively, the desired dtype can be passed in as a parameter:: sage: v = vector(QQ, [1, 2, 5/6]) - sage: v.numpy() + sage: v.numpy() # optional - numpy array([1, 2, 5/6], dtype=object) - sage: v.numpy(dtype=float) + sage: v.numpy(dtype=float) # optional - numpy array([1. , 2. , 0.83333333]) - sage: v.numpy(dtype=int) + sage: v.numpy(dtype=int) # optional - numpy array([1, 2, 0]) - sage: import numpy - sage: v.numpy(dtype=numpy.uint8) + sage: import numpy # optional - numpy + sage: v.numpy(dtype=numpy.uint8) # optional - numpy array([1, 2, 0], dtype=uint8) Passing a dtype of None will let numpy choose a native type, which can be more efficient but may have unintended consequences:: - sage: v.numpy(dtype=None) + sage: v.numpy(dtype=None) # optional - numpy array([1. , 2. , 0.83333333]) sage: w = vector(ZZ, [0, 1, 2^63 -1]); w (0, 1, 9223372036854775807) - sage: wn = w.numpy(dtype=None); wn + sage: wn = w.numpy(dtype=None); wn # optional - numpy array([ 0, 1, 9223372036854775807]...) - sage: wn.dtype + sage: wn.dtype # optional - numpy dtype('int64') - sage: w.dot_product(w) + sage: w.dot_product(w) # optional - numpy 85070591730234615847396907784232501250 - sage: wn.dot(wn) # overflow + sage: wn.dot(wn) # overflow # optional - numpy 2 Numpy can give rather obscure errors; we wrap these to give a bit of context:: - sage: vector([1, 1/2, QQ['x'].0]).numpy(dtype=float) + sage: vector([1, 1/2, QQ['x'].0]).numpy(dtype=float) # optional - numpy Traceback (most recent call last): ... ValueError: Could not convert vector over Univariate Polynomial Ring in x over Rational Field to numpy array of type <... 'float'>: setting an array element with a sequence. diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index ef326ac0a7c..03b1d2813b2 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -156,10 +156,10 @@ def IntegerLattice(basis, lll_reduce=True): Sage also interfaces with fpylll's lattice generator:: sage: from sage.modules.free_module_integer import IntegerLattice - sage: from fpylll import IntegerMatrix - sage: A = IntegerMatrix.random(8, "simdioph", bits=20, bits2=10) - sage: A = A.to_matrix(matrix(ZZ, 8, 8)) - sage: IntegerLattice(A, lll_reduce=False) + sage: from fpylll import IntegerMatrix # optional - fpylll + sage: A = IntegerMatrix.random(8, "simdioph", bits=20, bits2=10) # optional - fpylll + sage: A = A.to_matrix(matrix(ZZ, 8, 8)) # optional - fpylll + sage: IntegerLattice(A, lll_reduce=False) # optional - fpylll Free module of degree 8 and rank 8 over Integer Ring User basis matrix: [ 1024 829556 161099 11567 521155 769480 639201 689979] From 77f06996077a3c480d1a897817bc8d418371b34b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 5 Mar 2023 21:38:40 -0800 Subject: [PATCH 12/99] Add # optional - numpy etc. --- src/sage/stats/basic_stats.py | 12 ++++++------ .../discrete_gaussian_polynomial.py | 4 ++-- src/sage/stats/time_series.pyx | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index d83f08111f0..eb77fe4acc6 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -216,9 +216,9 @@ def std(v, bias=False): + (5*sqrt(2) - 10*I + 3)^2 + (5*sqrt(2) + 5*I - 6)^2) sage: std([RIF(1.0103, 1.0103), RIF(2)]) 0.6998235813403261? - sage: import numpy - sage: x = numpy.array([1,2,3,4,5]) - sage: std(x, bias=False) + sage: import numpy # optional - numpy + sage: x = numpy.array([1,2,3,4,5]) # optional - numpy + sage: std(x, bias=False) # optional - numpy 1.5811388300841898 sage: x = stats.TimeSeries([1..100]) sage: std(x) @@ -295,9 +295,9 @@ def variance(v, bias=False): + 1/450*(5*sqrt(2) + 5*I - 6)^2 sage: variance([RIF(1.0103, 1.0103), RIF(2)]) 0.4897530450000000? - sage: import numpy - sage: x = numpy.array([1,2,3,4,5]) - sage: variance(x, bias=False) + sage: import numpy # optional - numpy + sage: x = numpy.array([1,2,3,4,5]) # optional - numpy + sage: variance(x, bias=False) # optional - numpy 2.5 sage: x = stats.TimeSeries([1..100]) sage: variance(x) diff --git a/src/sage/stats/distributions/discrete_gaussian_polynomial.py b/src/sage/stats/distributions/discrete_gaussian_polynomial.py index 0f4e7e59361..074c0312947 100644 --- a/src/sage/stats/distributions/discrete_gaussian_polynomial.py +++ b/src/sage/stats/distributions/discrete_gaussian_polynomial.py @@ -17,8 +17,8 @@ sage: sigma = 3.0; n=1000 sage: l = [DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], 64, sigma)() for _ in range(n)] sage: l = [vector(f).norm().n() for f in l] - sage: from numpy import mean - sage: mean(l), sqrt(64)*sigma # abs tol 5e-1 + sage: from numpy import mean # optional - numpy + sage: mean(l), sqrt(64)*sigma # abs tol 5e-1 # optional - numpy (24.0, 24.0) """ diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index bf4ffbc178e..1c98136a7d7 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -102,22 +102,22 @@ cdef class TimeSeries: Conversion from a NumPy 1-D array, which is very fast:: sage: v = stats.TimeSeries([1..5]) - sage: w = v.numpy() - sage: stats.TimeSeries(w) + sage: w = v.numpy() # optional - numpy + sage: stats.TimeSeries(w) # optional - numpy [1.0000, 2.0000, 3.0000, 4.0000, 5.0000] Conversion from an n-dimensional NumPy array also works:: - sage: import numpy - sage: v = numpy.array([[1,2], [3,4]], dtype=float); v + sage: import numpy # optional - numpy + sage: v = numpy.array([[1,2], [3,4]], dtype=float); v # optional - numpy array([[1., 2.], [3., 4.]]) - sage: stats.TimeSeries(v) + sage: stats.TimeSeries(v) # optional - numpy [1.0000, 2.0000, 3.0000, 4.0000] - sage: stats.TimeSeries(v[:,0]) + sage: stats.TimeSeries(v[:,0]) # optional - numpy [1.0000, 3.0000] - sage: u = numpy.array([[1,2],[3,4]]) - sage: stats.TimeSeries(u) + sage: u = numpy.array([[1,2],[3,4]]) # optional - numpy + sage: stats.TimeSeries(u) # optional - numpy [1.0000, 2.0000, 3.0000, 4.0000] For speed purposes we don't initialize (so value is garbage):: From acab7e5b97d896f4556a5be906e48c1acf42e747 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 8 Mar 2023 10:25:42 -0800 Subject: [PATCH 13/99] In # optional, no commas between tags --- src/sage/matrix/matrix2.pyx | 64 ++++++++++++------------ src/sage/matrix/operation_table.py | 8 +-- src/sage/modules/free_module_element.pyx | 2 +- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 6ac1605f226..e01f3200077 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -3709,12 +3709,12 @@ cdef class Matrix(Matrix1): sage: a = Q.gen(0) # optional - sage.rings.number_field sage: A = matrix(Q, [[ 2, 5-a, 15-a], # optional - sage.rings.number_field ....: [2+a, a, -7 + 5*a]]) - sage: result = A._right_kernel_matrix_over_number_field() # optional - sage.rings.number_field, sage.libs.pari - sage: result[0] # optional - sage.rings.number_field, sage.libs.pari + sage: result = A._right_kernel_matrix_over_number_field() # optional - sage.rings.number_field sage.libs.pari + sage: result[0] # optional - sage.rings.number_field sage.libs.pari 'pivot-pari-numberfield' - sage: P = result[1]; P # optional - sage.rings.number_field, sage.libs.pari + sage: P = result[1]; P # optional - sage.rings.number_field sage.libs.pari [-a -3 1] - sage: A*P.transpose() == zero_matrix(Q, 2, 1) # optional - sage.rings.number_field, sage.libs.pari + sage: A*P.transpose() == zero_matrix(Q, 2, 1) # optional - sage.rings.number_field sage.libs.pari True TESTS: @@ -3723,16 +3723,16 @@ cdef class Matrix(Matrix1): sage: Q = QuadraticField(-7) # optional - sage.rings.number_field sage: A = matrix(Q, 0, 2) # optional - sage.rings.number_field - sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field, sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field sage.libs.pari [1 0] [0 1] - sage: A = matrix(Q, 2, 0) # optional - sage.rings.number_field, sage.libs.pari - sage: A._right_kernel_matrix_over_number_field()[1].parent() # optional - sage.rings.number_field, sage.libs.pari + sage: A = matrix(Q, 2, 0) # optional - sage.rings.number_field sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1].parent() # optional - sage.rings.number_field sage.libs.pari Full MatrixSpace of 0 by 0 dense matrices over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I - sage: A = zero_matrix(Q, 4, 3) # optional - sage.rings.number_field, sage.libs.pari - sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field, sage.libs.pari + sage: A = zero_matrix(Q, 4, 3) # optional - sage.rings.number_field sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field sage.libs.pari [1 0 0] [0 1 0] [0 0 1] @@ -4078,10 +4078,10 @@ cdef class Matrix(Matrix1): [ -2 -a - 1 0 1] sage: A*C.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True - sage: P = A.right_kernel_matrix(algorithm='pari', basis='pivot'); P # optional - sage.rings.number_field, sage.libs.pari + sage: P = A.right_kernel_matrix(algorithm='pari', basis='pivot'); P # optional - sage.rings.number_field sage.libs.pari [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*P.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field, sage.libs.pari + sage: A*P.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field sage.libs.pari True sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E # optional - sage.rings.number_field [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] @@ -9552,10 +9552,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQbar, [[(1/sqrt(5))*(1+i), (1/sqrt(55))*(3+2*I), (1/sqrt(22))*(2+2*I)], # optional - sage.symbolic, sage.rings.number_field + sage: A = matrix(QQbar, [[(1/sqrt(5))*(1+i), (1/sqrt(55))*(3+2*I), (1/sqrt(22))*(2+2*I)], # optional - sage.symbolic sage.rings.number_field ....: [(1/sqrt(5))*(1-i), (1/sqrt(55))*(2+2*I), (1/sqrt(22))*(-3+I)], ....: [ (1/sqrt(5))*I, (1/sqrt(55))*(3-5*I), (1/sqrt(22))*(-2)]]) - sage: A.is_unitary() # optional - sage.symbolic, sage.rings.number_field + sage: A.is_unitary() # optional - sage.symbolic sage.rings.number_field True A permutation matrix is always orthogonal. :: @@ -9569,9 +9569,9 @@ cdef class Matrix(Matrix1): [0 0 0 1 0] sage: P.is_unitary() # optional - sage.combinat True - sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat, sage.libs.pari + sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat sage.libs.pari True - sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat, sage.libs.pari + sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat sage.libs.pari True A square matrix far from unitary. :: @@ -11954,9 +11954,9 @@ cdef class Matrix(Matrix1): algebraic closure of this field to find the change-of-basis matrix:: - sage: cox = posets.TamariLattice(3).coxeter_transformation() # optional - sage.graphs, sage.combinat, sage.libs.pari - sage: M = cox.change_ring(GF(3)) # optional - sage.graphs, sage.combinat, sage.libs.pari - sage: M.is_similar(M**3, True) # long time # optional - sage.graphs, sage.combinat, sage.libs.pari + sage: cox = posets.TamariLattice(3).coxeter_transformation() # optional - sage.graphs sage.combinat sage.libs.pari + sage: M = cox.change_ring(GF(3)) # optional - sage.graphs sage.combinat sage.libs.pari + sage: M.is_similar(M**3, True) # long time # optional - sage.graphs sage.combinat sage.libs.pari ( [1 0 0 0 0] [0 1 1 0 2] @@ -12912,32 +12912,32 @@ cdef class Matrix(Matrix1): A matrix containing real roots:: - sage: A = matrix(AA, [ [1, 0, sqrt(2)], + sage: A = matrix(AA, [ [1, 0, sqrt(2)], # optional - sage.rings.number_field sage.symbolic ....: [0, sqrt(3), 0 ], ....: [sqrt(2), 0, sqrt(5)] ]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # optional - sage.rings.number_field sage.symbolic True - sage: B = matrix(AA, [ [2*sqrt(5) + 5, 0, -sqrt(8*sqrt(5) + 18)], + sage: B = matrix(AA, [ [2*sqrt(5) + 5, 0, -sqrt(8*sqrt(5) + 18)], # optional - sage.rings.number_field sage.symbolic ....: [0, sqrt(1/3), 0], ....: [-sqrt(8*sqrt(5) + 18), 0, sqrt(5) + 2] ]) - sage: A.inverse_positive_definite() == B + sage: A.inverse_positive_definite() == B # optional - sage.rings.number_field sage.symbolic True - sage: A*B == A.matrix_space().identity_matrix() + sage: A*B == A.matrix_space().identity_matrix() # optional - sage.rings.number_field sage.symbolic True A Hermitian (but not symmetric) matrix with complex entries:: - sage: A = matrix(QQbar, [ [ 1, 0, I ], + sage: A = matrix(QQbar, [ [ 1, 0, I ], # optional - sage.rings.number_field sage.symbolic ....: [ 0, sqrt(5), 0 ], ....: [-I, 0, 3 ] ]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # optional - sage.rings.number_field sage.symbolic True - sage: B = matrix(QQbar, [ [ 3/2, 0, -I/2 ], + sage: B = matrix(QQbar, [ [ 3/2, 0, -I/2 ], # optional - sage.rings.number_field sage.symbolic ....: [ 0, sqrt(1/5), 0 ], ....: [ I/2, 0, 1/2 ] ]) - sage: A.inverse_positive_definite() == B + sage: A.inverse_positive_definite() == B # optional - sage.rings.number_field sage.symbolic True - sage: A*B == A.matrix_space().identity_matrix() + sage: A*B == A.matrix_space().identity_matrix() # optional - sage.rings.number_field sage.symbolic True TESTS: @@ -13356,11 +13356,11 @@ cdef class Matrix(Matrix1): absolute value must be handled carefully. This tests that situation in the case of cyclotomic fields. :: - sage: C = SymmetricGroup(5).character_table() # optional - sage.groups, sage.rings.number_field - sage: C.base_ring() # optional - sage.groups, sage.rings.number_field + sage: C = SymmetricGroup(5).character_table() # optional - sage.groups sage.rings.number_field + sage: C.base_ring() # optional - sage.groups sage.rings.number_field Cyclotomic Field of order 1 and degree 1 - sage: P, L, U = C.LU(pivot='partial') # optional - sage.groups, sage.rings.number_field - sage: C == P*L*U # optional - sage.groups, sage.rings.number_field + sage: P, L, U = C.LU(pivot='partial') # optional - sage.groups sage.rings.number_field + sage: C == P*L*U # optional - sage.groups sage.rings.number_field True Check that :trac:`32736` is solved:: diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index 79acaaf8390..bc24b94d35a 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -963,8 +963,8 @@ def color_table(self, element_names=True, cmap=None, **options): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # optional - sage.plot, sage.groups - sage: OTa.color_table() # optional - sage.plot, sage.groups + sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # optional - sage.plot sage.groups + sage: OTa.color_table() # optional - sage.plot sage.groups Graphics object consisting of 37 graphics primitives .. PLOT:: @@ -1023,8 +1023,8 @@ def gray_table(self, **options): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # optional - sage.plot, sage.groups - sage: OTa.gray_table() # optional - sage.plot, sage.groups + sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # optional - sage.plot sage.groups + sage: OTa.gray_table() # optional - sage.plot sage.groups Graphics object consisting of 37 graphics primitives .. PLOT:: diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index fe8089eddaa..05e3d2be8df 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -5064,7 +5064,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): (4, 5, 6) sage: parent(w[39893]) # optional - sage.libs.pari Finite Field of size 17 - sage: w[39893] = sqrt(2) # optional - sage.libs.pari, sage.symbolic + sage: w[39893] = sqrt(2) # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... TypeError: self must be a numeric expression From 9e02b45852bd47f69e79dc4f79865c78b47b3c4b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 14:47:11 -0800 Subject: [PATCH 14/99] sage.matrix: Add # optional --- src/sage/matrix/berlekamp_massey.py | 4 +- src/sage/matrix/matrix0.pyx | 116 +++++----- src/sage/matrix/matrix1.pyx | 56 ++--- src/sage/matrix/matrix_generic_dense.pyx | 26 +-- src/sage/matrix/matrix_generic_sparse.pyx | 7 +- src/sage/matrix/matrix_polynomial_dense.pyx | 78 +++---- src/sage/matrix/matrix_sparse.pyx | 10 +- src/sage/matrix/operation_table.py | 244 ++++++++++---------- 8 files changed, 271 insertions(+), 270 deletions(-) diff --git a/src/sage/matrix/berlekamp_massey.py b/src/sage/matrix/berlekamp_massey.py index 716ed428745..d101e1bed95 100644 --- a/src/sage/matrix/berlekamp_massey.py +++ b/src/sage/matrix/berlekamp_massey.py @@ -55,11 +55,11 @@ def berlekamp_massey(a): sage: from sage.matrix.berlekamp_massey import berlekamp_massey sage: berlekamp_massey([1,2,1,2,1,2]) x^2 - 1 - sage: berlekamp_massey([GF(7)(1),19,1,19]) + sage: berlekamp_massey([GF(7)(1), 19, 1, 19]) # optional - sage.libs.pari x^2 + 6 sage: berlekamp_massey([2,2,1,2,1,191,393,132]) x^4 - 36727/11711*x^3 + 34213/5019*x^2 + 7024942/35133*x - 335813/1673 - sage: berlekamp_massey(prime_range(2,38)) + sage: berlekamp_massey(prime_range(2, 38)) # optional - sage.libs.pari x^6 - 14/9*x^5 - 7/9*x^4 + 157/54*x^3 - 25/27*x^2 - 73/18*x + 37/9 TESTS:: diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 141332cde3b..2b4cb22cd47 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -543,11 +543,11 @@ cdef class Matrix(sage.structure.element.Matrix): TESTS:: - sage: class MyAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): + sage: class MyAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): # optional - sage.rings.number_fields ....: def __bool__(self): ....: raise ValueError - sage: mat = matrix(1,1,MyAlgebraicNumber(1)) - sage: bool(mat) + sage: mat = matrix(1, 1, MyAlgebraicNumber(1)) # optional - sage.rings.number_fields + sage: bool(mat) # optional - sage.rings.number_fields Traceback (most recent call last): ... ValueError @@ -2562,12 +2562,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M`` with it:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.permute_columns(sigma) - sage: M + sage: M.permute_columns(sigma) # optional - sage.groups + sage: M # optional - sage.groups [0 0 1 0 0] [2 0 0 0 0] [0 3 0 0 0] @@ -2613,11 +2613,11 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.with_permuted_columns(sigma) + sage: M.with_permuted_columns(sigma) # optional - sage.groups [0 0 1 0 0] [2 0 0 0 0] [0 3 0 0 0] @@ -2744,12 +2744,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.permute_rows(sigma) - sage: M + sage: M.permute_rows(sigma) # optional - sage.groups + sage: M # optional - sage.groups [0 2 0 0 0] [0 0 3 0 0] [1 0 0 0 0] @@ -2793,11 +2793,11 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.with_permuted_rows(sigma) + sage: M.with_permuted_rows(sigma) # optional - sage.groups [0 2 0 0 0] [0 0 3 0 0] [1 0 0 0 0] @@ -2851,12 +2851,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.permute_rows_and_columns(sigma,tau) - sage: M + sage: M.permute_rows_and_columns(sigma,tau) # optional - sage.groups + sage: M # optional - sage.groups [2 0 0 0 0] [0 3 0 0 0] [0 0 0 0 1] @@ -2896,11 +2896,11 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) - sage: sigma, tau = G.gens() - sage: sigma + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups + sage: sigma, tau = G.gens() # optional - sage.groups + sage: sigma # optional - sage.groups (1,2,3)(4,5) - sage: M.with_permuted_rows_and_columns(sigma,tau) + sage: M.with_permuted_rows_and_columns(sigma,tau) # optional - sage.groups [2 0 0 0 0] [0 3 0 0 0] [0 0 0 0 1] @@ -4170,7 +4170,7 @@ cdef class Matrix(sage.structure.element.Matrix): Rectangular matrices are never Hermitian. :: sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field - sage: A.is_hermitian() + sage: A.is_hermitian() # optional - sage.rings.number_field False A square, empty matrix is trivially Hermitian. :: @@ -4903,22 +4903,22 @@ cdef class Matrix(sage.structure.element.Matrix): Over `\ZZ`:: sage: m = matrix(ZZ,2,2,[-1,1,-1,0]) - sage: m.multiplicative_order() + sage: m.multiplicative_order() # optional - sage.groups 3 sage: m = posets.ChainPoset(6).coxeter_transformation() - sage: m.multiplicative_order() + sage: m.multiplicative_order() # optional - sage.groups 7 sage: P = posets.TamariLattice(4).coxeter_transformation() - sage: P.multiplicative_order() + sage: P.multiplicative_order() # optional - sage.groups 10 sage: M = matrix(ZZ, 2, 2, [1, 1, 0, 1]) - sage: M.multiplicative_order() + sage: M.multiplicative_order() # optional - sage.groups +Infinity - sage: for k in range(600): + sage: for k in range(600): # optional - sage.groups ....: m = SL2Z.random_element() ....: o = m.multiplicative_order() ....: if o != Infinity and m**o != SL2Z.one(): @@ -4933,7 +4933,7 @@ cdef class Matrix(sage.structure.element.Matrix): ....: else: ....: return ZZ.random_element(-100,100) sage: rnd = matrix(ZZ, 8, 8, val) - sage: (rnd * m24 * rnd.inverse_of_unit()).multiplicative_order() + sage: (rnd * m24 * rnd.inverse_of_unit()).multiplicative_order() # optional - sage.groups 24 TESTS:: @@ -4945,7 +4945,7 @@ cdef class Matrix(sage.structure.element.Matrix): ArithmeticError: self must be invertible ... sage: D = matrix(IntegerModRing(6),3,[5,5,3,0,2,5,5,4,0]) - sage: D.multiplicative_order() + sage: D.multiplicative_order() # optional - sage.groups Traceback (most recent call last): ... NotImplementedError: ... only ... over finite fields or ZZ @@ -5064,11 +5064,11 @@ cdef class Matrix(sage.structure.element.Matrix): Check that :trac:`8198` is fixed:: - sage: R = Qp(5, 5) - sage: x = R(5).add_bigoh(1) - sage: I = matrix(R, [[1, 0], [0, 1]]) - sage: v = vector(R, [1, x]) - sage: v*I + sage: R = Qp(5, 5) # optional - sage.rings.padics + sage: x = R(5).add_bigoh(1) # optional - sage.rings.padics + sage: I = matrix(R, [[1, 0], [0, 1]]) # optional - sage.rings.padics + sage: v = vector(R, [1, x]) # optional - sage.rings.padics + sage: v*I # optional - sage.rings.padics (1 + O(5^5), O(5)) """ @@ -5098,11 +5098,11 @@ cdef class Matrix(sage.structure.element.Matrix): Check that :trac:`8198` is fixed:: - sage: R = Qp(5, 5) - sage: x = R(5).add_bigoh(1) - sage: I = matrix(R, [[1, 0], [0, 1]]) - sage: v = vector(R, [1, x]) - sage: I*v + sage: R = Qp(5, 5) # optional - sage.rings.padics + sage: x = R(5).add_bigoh(1) # optional - sage.rings.padics + sage: I = matrix(R, [[1, 0], [0, 1]]) # optional - sage.rings.padics + sage: v = vector(R, [1, x]) # optional - sage.rings.padics + sage: I*v # optional - sage.rings.padics (1 + O(5^5), O(5)) """ @@ -5195,10 +5195,10 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) - sage: a = matrix(2,2, [1,2,x*y,y*x]) - sage: b = matrix(2,2, [1,2,y*x,y*x]) - sage: a+b # indirect doctest + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: a = matrix(2, 2, [1,2,x*y,y*x]) # optional - sage.combinat + sage: b = matrix(2, 2, [1,2,y*x,y*x]) # optional - sage.combinat + sage: a + b # indirect doctest # optional - sage.combinat [ 2 4] [x*y + y*x 2*y*x] @@ -5218,10 +5218,10 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) - sage: a = matrix(2,2, [1,2,x*y,y*x]) - sage: b = matrix(2,2, [1,2,y*x,y*x]) - sage: a-b # indirect doctest + sage: R. = FreeAlgebra(QQ,2) # optional - sage.combinat + sage: a = matrix(2, 2, [1,2,x*y,y*x]) # optional - sage.combinat + sage: b = matrix(2, 2, [1,2,y*x,y*x]) # optional - sage.combinat + sage: a-b # indirect doctest # optional - sage.combinat [ 0 0] [x*y - y*x 0] @@ -5384,9 +5384,9 @@ cdef class Matrix(sage.structure.element.Matrix): We verify that the matrix multiplies are correct by comparing them with what PARI gets:: - sage: gp(a)*gp(b) - gp(a*b) + sage: gp(a)*gp(b) - gp(a*b) # optional - sage.libs.pari [0, 0; 0, 0] - sage: gp(b)*gp(a) - gp(b*a) + sage: gp(b)*gp(a) - gp(b*a) # optional - sage.libs.pari [0, 0, 0; 0, 0, 0; 0, 0, 0] EXAMPLE of matrix times matrix over different base rings:: diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index f62450e9379..d00b3806e0d 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -40,11 +40,11 @@ cdef class Matrix(Matrix0): sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a [ x + 1 2/3] [1/2*x^2 x^3 + 1] - sage: b = gp(a); b # indirect doctest + sage: b = gp(a); b # indirect doctest # optional - sage.libs.pari [x + 1, 2/3; 1/2*x^2, x^3 + 1] sage: a.determinant() x^4 + x^3 - 1/3*x^2 + x + 1 - sage: b.matdet() + sage: b.matdet() # optional - sage.libs.pari x^4 + x^3 - 1/3*x^2 + x + 1 """ w = self.list() @@ -69,11 +69,11 @@ cdef class Matrix(Matrix0): sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a [ x + 1 2/3] [1/2*x^2 x^3 + 1] - sage: b = pari(a); b # indirect doctest + sage: b = pari(a); b # indirect doctest # optional - sage.libs.pari [x + 1, 2/3; 1/2*x^2, x^3 + 1] sage: a.determinant() x^4 + x^3 - 1/3*x^2 + x + 1 - sage: b.matdet() + sage: b.matdet() # optional - sage.libs.pari x^4 + x^3 - 1/3*x^2 + x + 1 This function preserves precision for entries of inexact type (e.g. @@ -97,14 +97,14 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: A = MatrixSpace(QQ,3,3)([0,1,2,3,4,5,6,7,8]) - sage: g = gap(A) # indirect doctest - sage: g + sage: g = gap(A) # indirect doctest # optional - sage.libs.gap + sage: g # optional - sage.libs.gap [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ] - sage: g.CharacteristicPolynomial() + sage: g.CharacteristicPolynomial() # optional - sage.libs.gap x_1^3-12*x_1^2-18*x_1 sage: A.characteristic_polynomial() x^3 - 12*x^2 - 18*x - sage: matrix(QQ, g) == A + sage: matrix(QQ, g) == A # optional - sage.libs.gap True Particularly difficult is the case of matrices over cyclotomic @@ -244,11 +244,11 @@ cdef class Matrix(Matrix0): [0 1 2] [3 4 5] [6 7 8] - sage: m._maxima_init_() + sage: m._maxima_init_() # optional - sage.symbolic 'matrix([0,1,2],[3,4,5],[6,7,8])' - sage: a = maxima(m); a + sage: a = maxima(m); a # optional - sage.symbolic matrix([0,1,2],[3,4,5],[6,7,8]) - sage: a.charpoly('x').expand() + sage: a.charpoly('x').expand() # optional - sage.symbolic ...-x^3...+12*x^2+18*x sage: m.charpoly() x^3 - 12*x^2 - 18*x @@ -485,7 +485,7 @@ cdef class Matrix(Matrix0): [1 2 3] [4 5 6] [7 8 9] - sage: a._scilab_init_() + sage: a._scilab_init_() # optional - sage.libs.pari '[1,2,3;4,5,6;7,8,9]' AUTHORS: @@ -540,37 +540,37 @@ cdef class Matrix(Matrix0): [1 2 3] [4 5 6] [7 8 9] - sage: sA = A._sympy_(); sA + sage: sA = A._sympy_(); sA # optional - sympy Matrix([ [1, 2, 3], [4, 5, 6], [7, 8, 9]]) - sage: type(sA) + sage: type(sA) # optional - sympy sage: I = MatrixSpace(QQ, 5, 5, sparse=True).identity_matrix() - sage: sI = I._sympy_(); sI + sage: sI = I._sympy_(); sI # optional - sympy Matrix([ [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]) - sage: type(sI) + sage: type(sI) # optional - sympy If ``self`` was immutable, then converting the result to Sage gives back ``self``:: sage: immA = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], immutable=True) - sage: immA._sympy_()._sage_() is immA + sage: immA._sympy_()._sage_() is immA # optional - sympy True If ``self`` was mutable, then converting back to Sage creates a new matrix:: - sage: sA._sage_() is A + sage: sA._sage_() is A # optional - sympy False - sage: sA._sage_() == A + sage: sA._sage_() == A # optional - sympy True Symbolic matrices are supported:: @@ -578,11 +578,11 @@ cdef class Matrix(Matrix0): sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M [ sin(x) cos(x)] [-cos(x) sin(x)] - sage: sM = M._sympy_(); sM + sage: sM = M._sympy_(); sM # optional - sympy Matrix([ [ sin(x), cos(x)], [-cos(x), sin(x)]]) - sage: sM.subs(x, pi/4) + sage: sM.subs(x, pi/4) # optional - sympy Matrix([ [ sqrt(2)/2, sqrt(2)/2], [-sqrt(2)/2, sqrt(2)/2]]) @@ -593,12 +593,12 @@ cdef class Matrix(Matrix0): sage: ZeroCol = matrix(QQ, 3, 0, sparse=False); ZeroCol [] - sage: sZeroCol = ZeroCol._sympy_(); sZeroCol + sage: sZeroCol = ZeroCol._sympy_(); sZeroCol # optional - sympy Matrix(3, 0, []) sage: ZeroRow = matrix(QQ, 0, 2, sparse=False); ZeroRow [] - sage: sZeroRow = ZeroRow._sympy_(); sZeroRow + sage: sZeroRow = ZeroRow._sympy_(); sZeroRow # optional - sympy Matrix(0, 2, []) """ @@ -678,20 +678,20 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: a = matrix(3,range(12)) - sage: a.numpy() + sage: a = matrix(3, range(12)) + sage: a.numpy() # optional - numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) - sage: a.numpy('f') + sage: a.numpy('f') # optional - numpy array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]], dtype=float32) - sage: a.numpy('d') + sage: a.numpy('d') # optional - numpy array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]]) - sage: a.numpy('B') + sage: a.numpy('B') # optional - numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], dtype=uint8) diff --git a/src/sage/matrix/matrix_generic_dense.pyx b/src/sage/matrix/matrix_generic_dense.pyx index da22ca12175..2057b6b1460 100644 --- a/src/sage/matrix/matrix_generic_dense.pyx +++ b/src/sage/matrix/matrix_generic_dense.pyx @@ -69,12 +69,12 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): We check that the problem related to :trac:`9049` is not an issue any more:: - sage: S.=PolynomialRing(QQ) - sage: F.=QQ.extension(t^4+1) - sage: R.=PolynomialRing(F) - sage: M = MatrixSpace(R, 1, 2) + sage: S. = PolynomialRing(QQ) + sage: F. = QQ.extension(t^4 + 1) # optional - sage.rings.number_field + sage: R. = PolynomialRing(F) # optional - sage.rings.number_field + sage: M = MatrixSpace(R, 1, 2) # optional - sage.rings.number_field sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense - sage: Matrix_generic_dense(M, (x, y), True, True) + sage: Matrix_generic_dense(M, (x, y), True, True) # optional - sage.rings.number_field [x y] """ ma = MatrixArgs_init(parent, entries) @@ -214,10 +214,10 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) - sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) - sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) - sage: a._add_(b) + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) # optional - sage.combinat + sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) # optional - sage.combinat + sage: a._add_(b) # optional - sage.combinat [ 2 4] [x*y + y*x 2*y*x] """ @@ -237,10 +237,10 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) - sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) - sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) - sage: a._sub_(b) + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) # optional - sage.combinat + sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) # optional - sage.combinat + sage: a._sub_(b) # optional - sage.combinat [ 0 0] [x*y - y*x 0] """ diff --git a/src/sage/matrix/matrix_generic_sparse.pyx b/src/sage/matrix/matrix_generic_sparse.pyx index df138cfab3f..0a2f8f52cc9 100644 --- a/src/sage/matrix/matrix_generic_sparse.pyx +++ b/src/sage/matrix/matrix_generic_sparse.pyx @@ -4,8 +4,9 @@ Sparse Matrices over a general ring EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: M = MatrixSpace(QQ['x'],2,3,sparse=True); M - Full MatrixSpace of 2 by 3 sparse matrices over Univariate Polynomial Ring in x over Rational Field + sage: M = MatrixSpace(QQ['x'], 2, 3, sparse=True); M + Full MatrixSpace of 2 by 3 sparse matrices over + Univariate Polynomial Ring in x over Rational Field sage: a = M(range(6)); a [0 1 2] [3 4 5] @@ -15,7 +16,7 @@ EXAMPLES:: sage: a * b.transpose() [ 2*x^2 + x 2*x^5 + x^4] [ 5*x^2 + 4*x + 3 5*x^5 + 4*x^4 + 3*x^3] - sage: pari(a)*pari(b.transpose()) + sage: pari(a)*pari(b.transpose()) # optional - sage.libs.pari [2*x^2 + x, 2*x^5 + x^4; 5*x^2 + 4*x + 3, 5*x^5 + 4*x^4 + 3*x^3] sage: c = copy(b); c [ 1 x x^2] diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 9e8a2586fa0..e1db8a63c9f 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -1999,56 +1999,56 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: P, U = M.weak_popov_form(transformation=True) # optional - sage.libs.pari - sage: P # optional - sage.libs.pari + sage: P, U = M.weak_popov_form(transformation=True) # optional - sage.combinat sage.libs.pari + sage: P # optional - sage.combinat sage.libs.pari [ 4 x^2 6*x^2 + x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: U # optional - sage.libs.pari + sage: U # optional - sage.combinat sage.libs.pari [2*x^2 + 1 4*x] [ 4*x 1] - sage: P.is_weak_popov() and U.is_invertible() and U*M==P # optional - sage.libs.pari + sage: P.is_weak_popov() and U.is_invertible() and U*M == P # optional - sage.combinat sage.libs.pari True Demonstrating the ``ordered`` option:: - sage: P.leading_positions() # optional - sage.libs.pari + sage: P.leading_positions() # optional - sage.combinat sage.libs.pari [2, 1] - sage: PP = M.weak_popov_form(ordered=True); PP # optional - sage.libs.pari + sage: PP = M.weak_popov_form(ordered=True); PP # optional - sage.combinat sage.libs.pari [ 2 4*x^2 + 2*x + 4 5] [ 4 x^2 6*x^2 + x + 2] - sage: PP.leading_positions() # optional - sage.libs.pari + sage: PP.leading_positions() # optional - sage.combinat sage.libs.pari [1, 2] Demonstrating shifts:: - sage: P = M.weak_popov_form(shifts=[0,2,4]); P # optional - sage.libs.pari + sage: P = M.weak_popov_form(shifts=[0,2,4]); P # optional - sage.combinat sage.libs.pari [ 6*x^2 + 6*x + 4 5*x^4 + 4*x^3 + 5*x^2 + 5*x 2*x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: P == M.weak_popov_form(shifts=[-10,-8,-6]) # optional - sage.libs.pari + sage: P == M.weak_popov_form(shifts=[-10,-8,-6]) # optional - sage.combinat sage.libs.pari True Column-wise form is the row-wise form of the transpose:: - sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T # optional - sage.libs.pari + sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T # optional - sage.combinat sage.libs.pari True Zero vectors can be discarded:: - sage: M.weak_popov_form(row_wise=False) # optional - sage.libs.pari + sage: M.weak_popov_form(row_wise=False) # optional - sage.combinat sage.libs.pari [x + 4 6 0] [ 5 1 0] - sage: P, U = M.weak_popov_form(transformation=True, # optional - sage.libs.pari + sage: P, U = M.weak_popov_form(transformation=True, # optional - sage.combinat sage.libs.pari ....: row_wise=False, ....: include_zero_vectors=False) - sage: P # optional - sage.libs.pari + sage: P # optional - sage.combinat sage.libs.pari [x + 4 6] [ 5 1] - sage: U # optional - sage.libs.pari + sage: U # optional - sage.combinat sage.libs.pari [ 5*x + 2 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 1 1 2*x + 1] [ 5*x + 5 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.libs.pari + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.combinat sage.libs.pari True .. SEEALSO:: @@ -2128,29 +2128,29 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: A = matrix(PF,[[1, a*x^17 + 1 ], # optional - sage.libs.pari ....: [0, a*x^11 + a^2*x^7 + 1 ]]) sage: M = A.__copy__() # optional - sage.libs.pari - sage: U = M._weak_popov_form(transformation=True) # optional - sage.libs.pari - sage: U * A == M # optional - sage.libs.pari + sage: U = M._weak_popov_form(transformation=True) # optional - sage.combinat sage.libs.pari + sage: U * A == M # optional - sage.combinat sage.libs.pari True - sage: M.is_weak_popov() # optional - sage.libs.pari + sage: M.is_weak_popov() # optional - sage.combinat sage.libs.pari True - sage: U.is_invertible() # optional - sage.libs.pari + sage: U.is_invertible() # optional - sage.combinat sage.libs.pari True sage: PF. = QQ[] sage: A = matrix(PF,3,[x, x^2, x^3, ....: x^2, x^1, 0, ....: x^3, x^3, x^3]) - sage: A.weak_popov_form() + sage: A.weak_popov_form() # optional - sage.combinat [ x x^2 x^3] [ x^2 x 0] [ x^3 - x x^3 - x^2 0] - sage: M = A.__copy__() - sage: U = M._weak_popov_form(transformation=True, shifts=[16,8,0]) - sage: M + sage: M = A.__copy__() # optional - sage.combinat + sage: U = M._weak_popov_form(transformation=True, shifts=[16,8,0]) # optional - sage.combinat + sage: M # optional - sage.combinat [ x x^2 x^3] [ 0 -x^2 + x -x^4 + x^3] [ 0 0 -x^5 + x^4 + x^3] - sage: U * A == M + sage: U * A == M # optional - sage.combinat True """ cdef Py_ssize_t i, j @@ -2283,51 +2283,51 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: P, U = M.popov_form(transformation=True) # optional - sage.libs.pari - sage: P # optional - sage.libs.pari + sage: P, U = M.popov_form(transformation=True) # optional - sage.combinat sage.libs.pari + sage: P # optional - sage.combinat sage.libs.pari [ 4 x^2 + 4*x + 1 3] [ 0 4*x + 1 x^2 + 6*x + 1] - sage: U # optional - sage.libs.pari + sage: U # optional - sage.combinat sage.libs.pari [ x 2] [5*x^2 + x + 6 3*x + 2] - sage: P.is_popov() and U.is_invertible() and U*M == P # optional - sage.libs.pari + sage: P.is_popov() and U.is_invertible() and U*M == P # optional - sage.combinat sage.libs.pari True Demonstrating shifts and specific case of Hermite form:: - sage: P = M.popov_form(shifts=[0,2,4]); P # optional - sage.libs.pari + sage: P = M.popov_form(shifts=[0,2,4]); P # optional - sage.combinat sage.libs.pari [ 4*x^2 + 3*x + 4 x^4 + 3*x^3 + 5*x^2 + 5*x + 5 0] [ 6 5*x^2 + 6*x + 5 1] - sage: P.is_popov(shifts=[0,2,4]) # optional - sage.libs.pari + sage: P.is_popov(shifts=[0,2,4]) # optional - sage.combinat sage.libs.pari True - sage: P == M.popov_form(shifts=[-6,-4,-2]) # optional - sage.libs.pari + sage: P == M.popov_form(shifts=[-6,-4,-2]) # optional - sage.combinat sage.libs.pari True - sage: dd = sum(M.row_degrees()) + 1 # optional - sage.libs.pari - sage: M.popov_form(shifts=[2*dd,dd,0]) == M.hermite_form() # optional - sage.libs.pari + sage: dd = sum(M.row_degrees()) + 1 # optional - sage.combinat sage.libs.pari + sage: M.popov_form(shifts=[2*dd,dd,0]) == M.hermite_form() # optional - sage.combinat sage.libs.pari True Column-wise form is the row-wise form of the transpose:: - sage: M.popov_form() == M.T.popov_form(row_wise=False).T # optional - sage.libs.pari + sage: M.popov_form() == M.T.popov_form(row_wise=False).T # optional - sage.combinat sage.libs.pari True Zero vectors can be discarded:: - sage: M.popov_form(row_wise=False) # optional - sage.libs.pari + sage: M.popov_form(row_wise=False) # optional - sage.combinat sage.libs.pari [x + 2 6 0] [ 0 1 0] - sage: P, U = M.popov_form(transformation=True, # optional - sage.libs.pari + sage: P, U = M.popov_form(transformation=True, # optional - sage.combinat sage.libs.pari ....: row_wise=False, ....: include_zero_vectors=False) - sage: P # optional - sage.libs.pari + sage: P # optional - sage.combinat sage.libs.pari [x + 2 6] [ 0 1] - sage: U # optional - sage.libs.pari + sage: U # optional - sage.combinat sage.libs.pari [ 3*x^2 + 6*x + 3 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 3 1 2*x + 1] [ 5*x + 2 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.libs.pari + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.combinat sage.libs.pari True .. SEEALSO:: diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index df03aed59d5..def5795d1ee 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -1178,10 +1178,10 @@ cdef class Matrix_sparse(matrix.Matrix): Check that the bug in :trac:`13854` has been fixed:: - sage: A. = FreeAlgebra(QQ, 2) - sage: P. = A.g_algebra(relations={y*x:-x*y}, order = 'lex') - sage: M = Matrix([[x]], sparse=True) - sage: w = vector([y]) + sage: A. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: P. = A.g_algebra(relations={y*x: -x*y}, order='lex') # optional - sage.combinat + sage: M = Matrix([[x]], sparse=True) # optional - sage.combinat + sage: w = vector([y]) # optional - sage.combinat doctest:...: UserWarning: You are constructing a free module over a noncommutative ring. Sage does not have a concept of left/right and both sided modules, so be careful. @@ -1192,7 +1192,7 @@ cdef class Matrix_sparse(matrix.Matrix): of left/right and both sided modules, so be careful. It's also not guaranteed that all multiplications are done from the right side. - sage: M*w + sage: M*w # optional - sage.combinat (x*y) """ cdef int i, j diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index bc24b94d35a..b97ddd38d55 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -81,8 +81,8 @@ class OperationTable(SageObject): In its most basic use, the table needs a structure and an operation:: sage: from sage.matrix.operation_table import OperationTable - sage: G=SymmetricGroup(3) - sage: OperationTable(G, operation=operator.mul) + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: OperationTable(G, operation=operator.mul) # optional - sage.groups * a b c d e f +------------ a| a b c d e f @@ -96,7 +96,7 @@ class OperationTable(SageObject): want:: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(6) + sage: R = Integers(6) sage: OperationTable(R, operation=operator.add) + a b c d e f +------------ @@ -112,8 +112,8 @@ class OperationTable(SageObject): 26 elements. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=DihedralGroup(14) - sage: OperationTable(G, operator.mul, names='letters') + sage: G = DihedralGroup(14) # optional - sage.groups + sage: OperationTable(G, operator.mul, names='letters') # optional - sage.groups * aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb +------------------------------------------------------------------------------------ aa| aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb @@ -149,8 +149,8 @@ class OperationTable(SageObject): zeros to make a common width. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(4) - sage: OperationTable(G, operator.mul, names='digits') + sage: G = AlternatingGroup(4) # optional - sage.groups + sage: OperationTable(G, operator.mul, names='digits') # optional - sage.groups * 00 01 02 03 04 05 06 07 08 09 10 11 +------------------------------------ 00| 00 01 02 03 04 05 06 07 08 09 10 11 @@ -171,8 +171,8 @@ class OperationTable(SageObject): of the elements can be used. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: OperationTable(G, operator.mul, names='elements') + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: OperationTable(G, operator.mul, names='elements') # optional - sage.groups * () (1,2,3) (1,3,2) +------------------------ ()| () (1,2,3) (1,3,2) @@ -185,15 +185,15 @@ class OperationTable(SageObject): method. :: sage: from sage.matrix.operation_table import OperationTable - sage: G = QuaternionGroup() - sage: T = OperationTable(G, operator.mul) - sage: T.column_keys() + sage: G = QuaternionGroup() # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.column_keys() # optional - sage.groups ((), (1,2,3,4)(5,6,7,8), ..., (1,8,3,6)(2,7,4,5)) - sage: names=['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] - sage: T.change_names(names=names) - sage: sorted(T.translation().items()) + sage: names=['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] # optional - sage.groups + sage: T.change_names(names=names) # optional - sage.groups + sage: sorted(T.translation().items()) # optional - sage.groups [('-1', (1,3)(2,4)(5,7)(6,8)), ..., ('K', (1,8,3,6)(2,7,4,5))] - sage: T + sage: T # optional - sage.groups * 1 I -1 -I J -K -J K +------------------------ 1| 1 I -1 -I J -K -J K @@ -278,10 +278,10 @@ class OperationTable(SageObject): odd. The LaTeX version works much better. :: sage: from sage.matrix.operation_table import OperationTable - sage: L=FiniteSemigroups().example(()) + sage: L = FiniteSemigroups().example(()) sage: L An example of a finite semigroup: the left regular band generated by () - sage: T=OperationTable(L, operation=operator.mul) + sage: T = OperationTable(L, operation=operator.mul) sage: T * + @@ -302,11 +302,11 @@ class OperationTable(SageObject): Here we demonstrate the proper use first:: sage: from sage.matrix.operation_table import OperationTable - sage: H=CyclicPermutationGroup(4) - sage: H.list() + sage: H = CyclicPermutationGroup(4) # optional - sage.groups + sage: H.list() # optional - sage.groups [(), (1,2,3,4), (1,3)(2,4), (1,4,3,2)] - sage: elts = ['()', '(1,3)(2,4)'] - sage: OperationTable(H, operator.mul, elements=elts) + sage: elts = ['()', '(1,3)(2,4)'] # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups * a b +---- a| a b @@ -315,11 +315,11 @@ class OperationTable(SageObject): This can be rewritten so as to pass the actual elements of the group ``H``, using a simple ``for`` loop:: - sage: L = H.list() #list of elements of the group H - sage: elts = [L[i] for i in {0, 2}] - sage: elts + sage: L = H.list() #list of elements of the group H # optional - sage.groups + sage: elts = [L[i] for i in {0, 2}] # optional - sage.groups + sage: elts # optional - sage.groups [(), (1,3)(2,4)] - sage: OperationTable(H, operator.mul, elements=elts) + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups * a b +---- a| a b @@ -327,31 +327,31 @@ class OperationTable(SageObject): Here are a couple of improper uses:: - sage: elts.append(5) - sage: OperationTable(H, operator.mul, elements=elts) + sage: elts.append(5) # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to coerce 5 into Cyclic group of order 4 as a permutation group - sage: elts[2] = '(1,3,2,4)' - sage: OperationTable(H, operator.mul, elements=elts) + sage: elts[2] = '(1,3,2,4)' # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to coerce (1,3,2,4) into Cyclic group of order 4 as a permutation group - sage: elts[2] = '(1,2,3,4)' - sage: OperationTable(H, operator.mul, elements=elts) + sage: elts[2] = '(1,2,3,4)' # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups Traceback (most recent call last): ... ValueError: (1,3)(2,4)*(1,2,3,4)=(1,4,3,2), and so the set is not closed Unusable functions should be recognized as such:: - sage: H=CyclicPermutationGroup(4) - sage: OperationTable(H, operator.add) + sage: H = CyclicPermutationGroup(4) # optional - sage.groups + sage: OperationTable(H, operator.add) # optional - sage.groups Traceback (most recent call last): ... TypeError: elements () and () of Cyclic group of order 4 as a permutation group are incompatible with operation: - sage: from operator import xor - sage: OperationTable(H, xor) + sage: from operator import xor # optional - sage.groups + sage: OperationTable(H, xor) # optional - sage.groups Traceback (most recent call last): ... TypeError: elements () and () of Cyclic group of order 4 as a permutation group are incompatible with operation: @@ -359,9 +359,9 @@ class OperationTable(SageObject): We construct the multiplication table for a finite finitely presented group, where there is no normalization done when computing the hash:: - sage: GU. = FreeGroup() - sage: gr0 = GU / (s^(-2)*t*s*t, t^(-2)*s*t*s, s*t*s*t) - sage: gr0.multiplication_table() + sage: GU. = FreeGroup() # optional - sage.groups + sage: gr0 = GU / (s^(-2)*t*s*t, t^(-2)*s*t*s, s*t*s*t) # optional - sage.groups + sage: gr0.multiplication_table() # optional - sage.groups * a b c d e f g h i j k l +------------------------ a| a b c d e f g h i j k l @@ -510,14 +510,14 @@ def _name_maker(self, names): the nature of the output here. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=SymmetricGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: w, l, d = T._name_maker('letters') - sage: w + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: w, l, d = T._name_maker('letters') # optional - sage.groups + sage: w # optional - sage.groups 1 - sage: l[0] + sage: l[0] # optional - sage.groups 'a' - sage: d['a'] + sage: d['a'] # optional - sage.groups () TESTS: @@ -527,17 +527,17 @@ def _name_maker(self, names): methods that rely on this one. :: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T._name_maker(['x']) + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T._name_maker(['x']) # optional - sage.groups Traceback (most recent call last): ... ValueError: list of element names must be the same size as the set, 1 != 3 - sage: T._name_maker(['x', 'y', 4]) + sage: T._name_maker(['x', 'y', 4]) # optional - sage.groups Traceback (most recent call last): ... ValueError: list of element names must only contain strings, not 4 - sage: T._name_maker('blatzo') + sage: T._name_maker('blatzo') # optional - sage.groups Traceback (most recent call last): ... ValueError: element names must be a list, or one of the keywords: 'letters', 'digits', 'elements' @@ -608,31 +608,31 @@ def __getitem__(self, pair): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=DiCyclicGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T.column_keys() + sage: G = DiCyclicGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.column_keys() # optional - sage.groups ((), (5,6,7), ..., (1,4,2,3)(5,7)) - sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)')] + sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)')] # optional - sage.groups (1,4,2,3)(5,6) TESTS:: sage: from sage.matrix.operation_table import OperationTable - sage: G = DiCyclicGroup(3) - sage: T = OperationTable(G, operator.mul) - sage: T[G('(1,2)(3,4)(5,6,7)')] + sage: G = DiCyclicGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T[G('(1,2)(3,4)(5,6,7)')] # optional - sage.groups Traceback (most recent call last): ... TypeError: indexing into an operation table requires exactly two elements - sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)'), G('(1,3,2,4)(5,7)')] + sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)'), G('(1,3,2,4)(5,7)')] # optional - sage.groups Traceback (most recent call last): ... TypeError: indexing into an operation table requires exactly two elements - sage: T[2, 3] + sage: T[2, 3] # optional - sage.groups Traceback (most recent call last): ... IndexError: invalid indices of operation table: (2, 3) - sage: T['(1,512)', '(1,3,2,4)(5,7)'] + sage: T['(1,512)', '(1,3,2,4)(5,7)'] # optional - sage.groups Traceback (most recent call last): ... IndexError: invalid indices of operation table: ((1,512), (1,3,2,4)(5,7)) @@ -663,13 +663,13 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=CyclicPermutationGroup(6) - sage: H=CyclicPermutationGroup(3) - sage: P=OperationTable(G, operator.mul) - sage: Q=OperationTable(G, operator.mul) - sage: R=OperationTable(H, operator.mul) - sage: S=OperationTable(G, operator.truediv) - sage: P == P, P == Q, P == R, P == S + sage: G = CyclicPermutationGroup(6) # optional - sage.groups + sage: H = CyclicPermutationGroup(3) # optional - sage.groups + sage: P = OperationTable(G, operator.mul) # optional - sage.groups + sage: Q = OperationTable(G, operator.mul) # optional - sage.groups + sage: R = OperationTable(H, operator.mul) # optional - sage.groups + sage: S = OperationTable(G, operator.truediv) # optional - sage.groups + sage: P == P, P == Q, P == R, P == S # optional - sage.groups (True, True, False, False) """ return (self._elts == other._elts) and (self._operation == other._operation) @@ -681,13 +681,13 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=CyclicPermutationGroup(6) - sage: H=CyclicPermutationGroup(3) - sage: P=OperationTable(G, operator.mul) - sage: Q=OperationTable(G, operator.mul) - sage: R=OperationTable(H, operator.mul) - sage: S=OperationTable(G, operator.truediv) - sage: P != P, P != Q, P != R, P != S + sage: G = CyclicPermutationGroup(6) # optional - sage.groups + sage: H = CyclicPermutationGroup(3) # optional - sage.groups + sage: P = OperationTable(G, operator.mul) # optional - sage.groups + sage: Q = OperationTable(G, operator.mul) # optional - sage.groups + sage: R = OperationTable(H, operator.mul) # optional - sage.groups + sage: S = OperationTable(G, operator.truediv) # optional - sage.groups + sage: P != P, P != Q, P != R, P != S # optional - sage.groups (False, False, True, True) """ return not self == other @@ -699,8 +699,8 @@ def _repr_(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(5) - sage: T=OperationTable(R, operation=operator.add) + sage: R = Integers(5) + sage: T = OperationTable(R, operation=operator.add) sage: print(T._repr_()) + a b c d e +---------- @@ -725,32 +725,32 @@ def set_print_symbols(self, ascii, latex): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T.set_print_symbols('@', '\\times') - sage: T + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.set_print_symbols('@', '\\times') # optional - sage.groups + sage: T # optional - sage.groups @ a b c +------ a| a b c b| b c a c| c a b - sage: T._latex_() + sage: T._latex_() # optional - sage.groups '{\\setlength{\\arraycolsep}{2ex}\n\\begin{array}{r|*{3}{r}}\n\\multicolumn{1}{c|}{\\times}&a&b&c\\\\\\hline\n{}a&a&b&c\\\\\n{}b&b&c&a\\\\\n{}c&c&a&b\\\\\n\\end{array}}' TESTS:: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T.set_print_symbols('@', 5) + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.set_print_symbols('@', 5) # optional - sage.groups Traceback (most recent call last): ... ValueError: LaTeX symbol must be a string, not 5 - sage: T.set_print_symbols('@x@', '\\times') + sage: T.set_print_symbols('@x@', '\\times') # optional - sage.groups Traceback (most recent call last): ... ValueError: ASCII symbol should be a single character, not @x@ - sage: T.set_print_symbols(5, '\\times') + sage: T.set_print_symbols(5, '\\times') # optional - sage.groups Traceback (most recent call last): ... ValueError: ASCII symbol should be a single character, not 5 @@ -781,9 +781,9 @@ def column_keys(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: T.column_keys() + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.column_keys() # optional - sage.groups ((), (1,2,3), (1,3,2)) """ return self._elts @@ -807,9 +807,9 @@ def translation(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G=AlternatingGroup(3) - sage: T=OperationTable(G, operator.mul, names=['p','q','r']) - sage: T.translation() + sage: G = AlternatingGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul, names=['p','q','r']) # optional - sage.groups + sage: T.translation() # optional - sage.groups {'p': (), 'q': (1,2,3), 'r': (1,3,2)} """ return self._name_dict @@ -828,9 +828,9 @@ def table(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: C=CyclicPermutationGroup(3) - sage: T=OperationTable(C, operator.mul) - sage: T.table() + sage: C = CyclicPermutationGroup(3) # optional - sage.groups + sage: T=OperationTable(C, operator.mul) # optional - sage.groups + sage: T.table() # optional - sage.groups [[0, 1, 2], [1, 2, 0], [2, 0, 1]] """ return self._table @@ -870,46 +870,46 @@ def change_names(self, names): operation table uses the same routine. :: sage: from sage.matrix.operation_table import OperationTable - sage: D=DihedralGroup(2) - sage: T=OperationTable(D, operator.mul) - sage: T + sage: D = DihedralGroup(2) # optional - sage.groups + sage: T = OperationTable(D, operator.mul) # optional - sage.groups + sage: T # optional - sage.groups * a b c d +-------- a| a b c d b| b a d c c| c d a b d| d c b a - sage: T.translation()['c'] + sage: T.translation()['c'] # optional - sage.groups (1,2) - sage: T.change_names('digits') - sage: T + sage: T.change_names('digits') # optional - sage.groups + sage: T # optional - sage.groups * 0 1 2 3 +-------- 0| 0 1 2 3 1| 1 0 3 2 2| 2 3 0 1 3| 3 2 1 0 - sage: T.translation()['2'] + sage: T.translation()['2'] # optional - sage.groups (1,2) - sage: T.change_names('elements') - sage: T + sage: T.change_names('elements') # optional - sage.groups + sage: T # optional - sage.groups * () (3,4) (1,2) (1,2)(3,4) +-------------------------------------------- ()| () (3,4) (1,2) (1,2)(3,4) (3,4)| (3,4) () (1,2)(3,4) (1,2) (1,2)| (1,2) (1,2)(3,4) () (3,4) (1,2)(3,4)| (1,2)(3,4) (1,2) (3,4) () - sage: T.translation()['(1,2)'] + sage: T.translation()['(1,2)'] # optional - sage.groups (1,2) - sage: T.change_names(['w', 'x', 'y', 'z']) - sage: T + sage: T.change_names(['w', 'x', 'y', 'z']) # optional - sage.groups + sage: T # optional - sage.groups * w x y z +-------- w| w x y z x| x w z y y| y z w x z| z y x w - sage: T.translation()['y'] + sage: T.translation()['y'] # optional - sage.groups (1,2) """ self._width, self._names, self._name_dict = self._name_maker(names) @@ -927,16 +927,16 @@ def matrix_of_variables(self): ``cayley_table()`` method for permutation groups. :: sage: from sage.matrix.operation_table import OperationTable - sage: G = PermutationGroup(['(1,2,3)', '(2,3)']) - sage: T = OperationTable(G, operator.mul) - sage: T.matrix_of_variables() + sage: G = PermutationGroup(['(1,2,3)', '(2,3)']) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: T.matrix_of_variables() # optional - sage.groups [x0 x1 x2 x3 x4 x5] [x1 x0 x3 x2 x5 x4] [x2 x4 x0 x5 x1 x3] [x3 x5 x1 x4 x0 x2] [x4 x2 x5 x0 x3 x1] [x5 x3 x4 x1 x2 x0] - sage: T.column_keys()[2]*T.column_keys()[2] == T.column_keys()[0] + sage: T.column_keys()[2]*T.column_keys()[2] == T.column_keys()[0] # optional - sage.groups True """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -1043,8 +1043,8 @@ def _ascii_table(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(5) - sage: T=OperationTable(R, operator.add) + sage: R = Integers(5) + sage: T = OperationTable(R, operator.add) sage: print(T._ascii_table()) + a b c d e +---------- @@ -1058,8 +1058,8 @@ def _ascii_table(self): strings used to represent elements. :: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(10) - sage: T=OperationTable(R, operator.mul, names='digits') + sage: R = Integers(10) + sage: T = OperationTable(R, operator.mul, names='digits') sage: print(T._ascii_table()) * 0 1 2 3 4 5 6 7 8 9 +-------------------- @@ -1077,8 +1077,8 @@ def _ascii_table(self): :: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(11) - sage: T=OperationTable(R, operator.mul, names='digits') + sage: R = Integers(11) + sage: T = OperationTable(R, operator.mul, names='digits') sage: print(T._ascii_table()) * 00 01 02 03 04 05 06 07 08 09 10 +--------------------------------- @@ -1097,8 +1097,8 @@ def _ascii_table(self): :: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(4) - sage: T=OperationTable(R, operator.mul, names=['x','y','wwww', 'z']) + sage: R = Integers(4) + sage: T = OperationTable(R, operator.mul, names=['x','y','wwww', 'z']) sage: print(T._ascii_table()) * x y wwww z +-------------------- @@ -1135,8 +1135,8 @@ def _latex_(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: R=Integers(2) - sage: T=OperationTable(R, operation=operator.mul) + sage: R = Integers(2) + sage: T = OperationTable(R, operation=operator.mul) sage: T._latex_() '{\\setlength{\\arraycolsep}{2ex}\n\\begin{array}{r|*{2}{r}}\n\\multicolumn{1}{c|}{\\ast}&a&b\\\\\\hline\n{}a&a&a\\\\\n{}b&a&b\\\\\n\\end{array}}' """ From 7f20bb796ae0452cd5ec486da9444e399c178474 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 9 Mar 2023 22:17:40 -0800 Subject: [PATCH 15/99] sage.matrix, sage.modules: Add # optional --- src/sage/matrix/action.pyx | 14 +- src/sage/matrix/args.pyx | 18 +- src/sage/matrix/matrix0.pyx | 66 +- src/sage/matrix/matrix1.pyx | 24 +- src/sage/matrix/matrix2.pyx | 862 +++++++++--------- src/sage/matrix/matrix_cdv.pyx | 18 +- src/sage/matrix/matrix_dense.pyx | 12 +- src/sage/matrix/matrix_space.py | 38 +- src/sage/matrix/matrix_sparse.pyx | 2 +- src/sage/matrix/operation_table.py | 6 +- src/sage/matrix/tests.py | 2 +- src/sage/modules/finite_submodule_iter.pyx | 1 + src/sage/modules/fp_graded/element.py | 1 + src/sage/modules/fp_graded/free_module.py | 1 + src/sage/modules/fp_graded/homspace.py | 1 + src/sage/modules/fp_graded/module.py | 1 + src/sage/modules/fp_graded/morphism.py | 1 + src/sage/modules/free_module.py | 108 ++- src/sage/modules/free_module_element.pyx | 490 +++++----- src/sage/modules/free_module_morphism.py | 50 +- src/sage/modules/free_quadratic_module.py | 36 +- src/sage/modules/matrix_morphism.py | 14 +- src/sage/modules/quotient_module.py | 53 +- src/sage/modules/vector_integer_dense.pyx | 6 +- src/sage/modules/vector_modn_dense.pyx | 58 +- src/sage/modules/vector_space_homspace.py | 14 +- src/sage/modules/with_basis/cell_module.py | 1 + .../modules/with_basis/indexed_element.pyx | 152 +-- src/sage/modules/with_basis/invariant.py | 1 + src/sage/modules/with_basis/representation.py | 1 + 30 files changed, 1041 insertions(+), 1011 deletions(-) diff --git a/src/sage/matrix/action.pyx b/src/sage/matrix/action.pyx index 48bbd1159d6..af0c92786d0 100644 --- a/src/sage/matrix/action.pyx +++ b/src/sage/matrix/action.pyx @@ -209,23 +209,23 @@ cdef class MatrixMatrixAction(MatrixMulAction): Respects compatible subdivisions:: - sage: M = matrix(5, 5, prime_range(100)) - sage: M.subdivide(2,3); M + sage: M = matrix(5, 5, prime_range(100)) # optional - sage.libs.pari + sage: M.subdivide(2, 3); M # optional - sage.libs.pari [ 2 3 5| 7 11] [13 17 19|23 29] [--------+-----] [31 37 41|43 47] [53 59 61|67 71] [73 79 83|89 97] - sage: N = matrix(5,2,[n^2 for n in range(10)]) - sage: N.subdivide(3,1); N + sage: N = matrix(5, 2, [n^2 for n in range(10)]) + sage: N.subdivide(3, 1); N [ 0| 1] [ 4| 9] [16|25] [--+--] [36|49] [64|81] - sage: M*N + sage: M*N # optional - sage.libs.pari [ 1048| 1388] [ 3056| 4117] [-----+-----] @@ -235,7 +235,7 @@ cdef class MatrixMatrixAction(MatrixMulAction): Note that this is just like block matrix multiplication:: - sage: M.subdivision(0,0) * N.subdivision(0,0) + M.subdivision(0,1) * N.subdivision(1,0) + sage: M.subdivision(0,0) * N.subdivision(0,0) + M.subdivision(0,1) * N.subdivision(1,0) # optional - sage.libs.pari [1048] [3056] @@ -249,7 +249,7 @@ cdef class MatrixMatrixAction(MatrixMulAction): [16|25] [36|49] [64|81] - sage: M*N + sage: M*N # optional - sage.libs.pari [ 1048 1388] [ 3056 4117] [ 5360 7303] diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index dbc611208d7..d527151a4e5 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -83,7 +83,7 @@ cdef class SparseEntry: sage: from sage.matrix.args import SparseEntry sage: SparseEntry(123, 456, "abc") SparseEntry(123, 456, 'abc') - sage: SparseEntry(1/3, 2/3, x) + sage: SparseEntry(1/3, 2/3, x) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert rational 1/3 to an integer @@ -176,7 +176,7 @@ cdef class MatrixArgs: [3.141592653589793 0.0] [ 0.0 3.141592653589793] - sage: ma = MatrixArgs(2, 2, entries=pi); ma.finalized(); ma.matrix() + sage: ma = MatrixArgs(2, 2, entries=pi); ma.finalized(); ma.matrix() # optional - sage.symbolic [pi 0] [ 0 pi] @@ -192,15 +192,15 @@ cdef class MatrixArgs: [1 2] [3 4] - sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized(); ma.matrix() + sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized(); ma.matrix() # optional - sage.libs.pari [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized(); ma.matrix() + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized(); ma.matrix() # optional - sage.libs.pari [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized(); ma.matrix() + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized(); ma.matrix() # optional - sage.libs.pari [3/5 0] [ 0 3/5] @@ -458,8 +458,8 @@ cdef class MatrixArgs: Sparse examples:: - sage: ma = MatrixArgs(3, 3, pi) - sage: list(ma.iter(sparse=True)) + sage: ma = MatrixArgs(3, 3, pi) # optional - sage.symbolic + sage: list(ma.iter(sparse=True)) # optional - sage.symbolic [SparseEntry(0, 0, pi), SparseEntry(1, 1, pi), SparseEntry(2, 2, pi)] sage: ma = MatrixArgs(2, 3) sage: list(ma.iter(sparse=True)) @@ -819,11 +819,11 @@ cdef class MatrixArgs: EXAMPLES:: sage: from sage.matrix.args import MatrixArgs - sage: MatrixArgs(pi).finalized() + sage: MatrixArgs(pi).finalized() # optional - sage.symbolic Traceback (most recent call last): ... TypeError: the dimensions of the matrix must be specified - sage: MatrixArgs(RR, pi).finalized() + sage: MatrixArgs(RR, pi).finalized() # optional - sage.symbolic Traceback (most recent call last): ... TypeError: the dimensions of the matrix must be specified diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 2b4cb22cd47..3b6b278a773 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -2934,10 +2934,11 @@ cdef class Matrix(sage.structure.element.Matrix): If not, we get an error message:: - sage: a.add_multiple_of_row(1,0,SR.I()) + sage: a.add_multiple_of_row(1, 0, SR.I()) # optional - sage.symbolic Traceback (most recent call last): ... - TypeError: Multiplying row by Symbolic Ring element cannot be done over Rational Field, use change_ring or with_added_multiple_of_row instead. + TypeError: Multiplying row by Symbolic Ring element cannot be done over + Rational Field, use change_ring or with_added_multiple_of_row instead. """ self.check_row_bounds_and_mutability(i,j) try: @@ -3018,10 +3019,11 @@ cdef class Matrix(sage.structure.element.Matrix): If not, we get an error message:: - sage: a.add_multiple_of_column(1,0,SR.I()) + sage: a.add_multiple_of_column(1, 0, SR.I()) # optional - sage.symbolic Traceback (most recent call last): ... - TypeError: Multiplying column by Symbolic Ring element cannot be done over Rational Field, use change_ring or with_added_multiple_of_column instead. + TypeError: Multiplying column by Symbolic Ring element cannot be done over + Rational Field, use change_ring or with_added_multiple_of_column instead. """ self.check_column_bounds_and_mutability(i,j) try: @@ -4906,12 +4908,12 @@ cdef class Matrix(sage.structure.element.Matrix): sage: m.multiplicative_order() # optional - sage.groups 3 - sage: m = posets.ChainPoset(6).coxeter_transformation() - sage: m.multiplicative_order() # optional - sage.groups + sage: m = posets.ChainPoset(6).coxeter_transformation() # optional - sage.combinat sage.graphs + sage: m.multiplicative_order() # optional - sage.combinat sage.graphs sage.groups 7 - sage: P = posets.TamariLattice(4).coxeter_transformation() - sage: P.multiplicative_order() # optional - sage.groups + sage: P = posets.TamariLattice(4).coxeter_transformation() # optional - sage.combinat sage.graphs + sage: P.multiplicative_order() # optional - sage.combinat sage.graphs sage.groups 10 sage: M = matrix(ZZ, 2, 2, [1, 1, 0, 1]) @@ -5294,11 +5296,11 @@ cdef class Matrix(sage.structure.element.Matrix): [ x*y x^2*y x*y^2] [ -x^2*y^2 x^2*y + x*y^2 x^2*y - x*y^2] - sage: R. = FreeAlgebra(ZZ,2) - sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a + sage: R. = FreeAlgebra(ZZ,2) # optional - sage.combinat + sage: a = matrix(R, 2, 3,[1,x,y, -x*y,x+y,x-y]); a # optional - sage.combinat [ 1 x y] [ -x*y x + y x - y] - sage: (x*y) * a # indirect doctest + sage: (x*y) * a # indirect doctest # optional - sage.combinat [ x*y x*y*x x*y^2] [ -x*y*x*y x*y*x + x*y^2 x*y*x - x*y^2] """ @@ -5327,22 +5329,22 @@ cdef class Matrix(sage.structure.element.Matrix): An example in which the base ring is not commutative:: - sage: F. = FreeAlgebra(QQ,2) - sage: a = matrix(2,[x,y,x^2,y^2]); a + sage: F. = FreeAlgebra(QQ,2) # optional - sage.combinat + sage: a = matrix(2, [x,y, x^2,y^2]); a # optional - sage.combinat [ x y] [x^2 y^2] - sage: x * a # indirect doctest + sage: x * a # indirect doctest # optional - sage.combinat [ x^2 x*y] [ x^3 x*y^2] - sage: a * y + sage: a * y # optional - sage.combinat [ x*y y^2] [x^2*y y^3] - sage: R. = FreeAlgebra(ZZ,2) - sage: a = matrix(R,2,3,[1,x,y,-x*y,x+y,x-y]); a + sage: R. = FreeAlgebra(ZZ,2) # optional - sage.combinat + sage: a = matrix(R, 2, 3,[1,x,y, -x*y,x+y,x-y]); a # optional - sage.combinat [ 1 x y] [ -x*y x + y x - y] - sage: a * (x*y) + sage: a * (x*y) # optional - sage.combinat [ x*y x^2*y y*x*y] [ -x*y*x*y x^2*y + y*x*y x^2*y - y*x*y] """ @@ -5434,15 +5436,15 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLE of matrix multiplication over a noncommutative base ring:: - sage: R. = FreeAlgebra(QQ,2) - sage: x*y - y*x + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat + sage: x*y - y*x # optional - sage.combinat x*y - y*x - sage: a = matrix(2,2, [1,2,x,y]) - sage: b = matrix(2,2, [x,y,x^2,y^2]) - sage: a*b + sage: a = matrix(2, 2, [1,2, x,y]) # optional - sage.combinat + sage: b = matrix(2, 2, [x,y, x^2,y^2]) # optional - sage.combinat + sage: a*b # optional - sage.combinat [ x + 2*x^2 y + 2*y^2] [x^2 + y*x^2 x*y + y^3] - sage: b*a + sage: b*a # optional - sage.combinat [ x + y*x 2*x + y^2] [x^2 + y^2*x 2*x^2 + y^3] @@ -5510,15 +5512,15 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLE of scalar multiplication in the noncommutative case:: - sage: R. = FreeAlgebra(ZZ,2) - sage: a = matrix(2,[x,y,x^2,y^2]) - sage: a * x + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat + sage: a = matrix(2, [x,y, x^2,y^2]) # optional - sage.combinat + sage: a * x # optional - sage.combinat [ x^2 y*x] [ x^3 y^2*x] - sage: x * a + sage: x * a # optional - sage.combinat [ x^2 x*y] [ x^3 x*y^2] - sage: a*x - x*a + sage: a*x - x*a # optional - sage.combinat [ 0 -x*y + y*x] [ 0 -x*y^2 + y^2*x] """ @@ -5894,9 +5896,9 @@ cdef class Matrix(sage.structure.element.Matrix): Non-integer (symbolic) exponents are also supported:: - sage: k = var('k') - sage: A = matrix([[2, -1], [1, 0]]) - sage: A^(2*k+1) + sage: k = var('k') # optional - sage.symbolic + sage: A = matrix([[2, -1], [1, 0]]) # optional - sage.symbolic + sage: A^(2*k+1) # optional - sage.symbolic [ 2*k + 2 -2*k - 1] [ 2*k + 1 -2*k] """ diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index d00b3806e0d..3670adf1a6b 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -102,7 +102,7 @@ cdef class Matrix(Matrix0): [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ] sage: g.CharacteristicPolynomial() # optional - sage.libs.gap x_1^3-12*x_1^2-18*x_1 - sage: A.characteristic_polynomial() + sage: A.characteristic_polynomial() # optional - sage.libs.gap x^3 - 12*x^2 - 18*x sage: matrix(QQ, g) == A # optional - sage.libs.gap True @@ -153,9 +153,9 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: libgap(identity_matrix(ZZ, 2)) + sage: libgap(identity_matrix(ZZ, 2)) # optional - sage.libs.gap [ [ 1, 0 ], [ 0, 1 ] ] - sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # optional - sage.libs.pari + sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # optional - sage.libs.gap sage.libs.pari [ [ Z(3)^0, Z(3) ], [ 0*Z(3), Z(3)^0 ] ] """ from sage.libs.gap.libgap import libgap @@ -192,9 +192,9 @@ cdef class Matrix(Matrix0): :: - sage: y = var('y') - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) - sage: M == fricas(M).sage() # optional - fricas + sage: y = var('y') # optional - sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic + sage: M == fricas(M).sage() # optional - fricas # optional - sage.symbolic True """ s = ','.join('[' + ','.join(cf._fricas_init_() for cf in row) + ']' @@ -389,9 +389,9 @@ cdef class Matrix(Matrix0): sage: maple(M) # optional - maple Matrix(2, 2, [[-9*x^2-2*x+2,x-1],[x^2+8*x,-3*x^2+5]]) - sage: y = var('y') - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) - sage: M == maple(M).sage() # optional - maple + sage: y = var('y') # optional - sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic + sage: M == maple(M).sage() # optional - maple # optional - sage.symbolic True """ s = ','.join('[' + ','.join(cf._maple_init_() for cf in row) + ']' @@ -575,14 +575,14 @@ cdef class Matrix(Matrix0): Symbolic matrices are supported:: - sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M + sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M # optional - sage.symbolic [ sin(x) cos(x)] [-cos(x) sin(x)] - sage: sM = M._sympy_(); sM # optional - sympy + sage: sM = M._sympy_(); sM # optional - sage.symbolic sympy Matrix([ [ sin(x), cos(x)], [-cos(x), sin(x)]]) - sage: sM.subs(x, pi/4) # optional - sympy + sage: sM.subs(x, pi/4) # optional - sage.symbolic sympy Matrix([ [ sqrt(2)/2, sqrt(2)/2], [-sqrt(2)/2, sqrt(2)/2]]) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index e01f3200077..1d12814aceb 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -167,16 +167,16 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: var('a,b,d,e') + sage: var('a,b,d,e') # optional - sage.symbolic (a, b, d, e) - sage: m = matrix([[a,b], [d,e]]) - sage: m.substitute(a=1) + sage: m = matrix([[a,b], [d,e]]) # optional - sage.symbolic + sage: m.substitute(a=1) # optional - sage.symbolic [1 b] [d e] - sage: m.subs(a=b, b=d) + sage: m.subs(a=b, b=d) # optional - sage.symbolic [b d] [d e] - sage: m.subs({a: 3, b:2, d:1, e:-1}) + sage: m.subs({a: 3, b:2, d:1, e:-1}) # optional - sage.symbolic [ 3 2] [ 1 -1] @@ -1143,13 +1143,13 @@ cdef class Matrix(Matrix1): Non-commutative rings behave as expected. These are the usual quaternions. :: - sage: R. = QuaternionAlgebra(-1, -1) - sage: A = matrix(R, 2, [1,i,j,k]) - sage: B = matrix(R, 2, [i,i,i,i]) - sage: A.elementwise_product(B) + sage: R. = QuaternionAlgebra(-1, -1) # optional - sage.combinat + sage: A = matrix(R, 2, [1,i,j,k]) # optional - sage.combinat + sage: B = matrix(R, 2, [i,i,i,i]) # optional - sage.combinat + sage: A.elementwise_product(B) # optional - sage.combinat [ i -1] [-k j] - sage: B.elementwise_product(A) + sage: B.elementwise_product(A) # optional - sage.combinat [ i -1] [ k -j] @@ -2018,9 +2018,9 @@ cdef class Matrix(Matrix1): TESTS:: - sage: A = matrix(5, 5, [next_prime(i^2) for i in range(25)]) - sage: B = MatrixSpace(ZZ['x'], 5, 5)(A) - sage: A.det() - B.det() + sage: A = matrix(5, 5, [next_prime(i^2) for i in range(25)]) # optional - sage.libs.pari + sage: B = MatrixSpace(ZZ['x'], 5, 5)(A) # optional - sage.libs.pari + sage: A.det() - B.det() # optional - sage.libs.pari 0 We verify that :trac:`5569` is resolved (otherwise the following @@ -2565,7 +2565,7 @@ cdef class Matrix(Matrix1): TESTS:: - sage: A = random_matrix(ZZ[x], 6) + sage: A = random_matrix(ZZ['x'], 6) sage: A = A - A.transpose() sage: A.pfaffian(algorithm='bfl') == A._pf_perfect_matchings() True @@ -2776,7 +2776,7 @@ cdef class Matrix(Matrix1): sage: a = matrix(QQ, 2,2, [1,2,3,4]); a [1 2] [3 4] - sage: a.characteristic_polynomial('T') + sage: a.characteristic_polynomial('T') # optional - sage.libs.pari T^2 - 5*T - 2 """ return self.charpoly(*args, **kwds) @@ -2863,8 +2863,8 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: a = matrix([[1,2],[3,4]]) - sage: a._test_minpoly() + sage: a = matrix([[1,2], [3,4]]) # optional - sage.libs.pari + sage: a._test_minpoly() # optional - sage.libs.pari """ if self.nrows() == self.ncols() and self.base_ring().is_exact(): tester = self._tester(**options) @@ -2924,8 +2924,8 @@ cdef class Matrix(Matrix1): An example over `\QQ`:: - sage: A = MatrixSpace(QQ,3)(range(9)) - sage: A.charpoly('x') + sage: A = MatrixSpace(QQ, 3)(range(9)) + sage: A.charpoly('x') # optional - sage.libs.pari x^3 - 12*x^2 - 18*x sage: A.trace() 12 @@ -2936,7 +2936,7 @@ cdef class Matrix(Matrix1): polynomial ring `\ZZ[a]`:: sage: R. = PolynomialRing(ZZ) - sage: M = MatrixSpace(R,2)([a,1, a,a+1]); M + sage: M = MatrixSpace(R, 2)([a,1, a,a+1]); M [ a 1] [ a a + 1] sage: f = M.charpoly('x'); f @@ -3239,10 +3239,10 @@ cdef class Matrix(Matrix1): sage: M = MatrixSpace(QQ,3,3) sage: A = M([1,9,-7,4/5,4,3,6,4,3]) - sage: A.fcp() + sage: A.fcp() # optional - sage.libs.pari x^3 - 8*x^2 + 209/5*x - 286 sage: A = M([3, 0, -2, 0, -2, 0, 0, 0, 0]) - sage: A.fcp('T') + sage: A.fcp('T') # optional - sage.libs.pari (T - 3) * T * (T + 2) """ return self.charpoly(var).factor() @@ -4772,9 +4772,9 @@ cdef class Matrix(Matrix1): Basis matrix: [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: B*G.basis_matrix().transpose() == zero_matrix(Q, 2, 2) + sage: B*G.basis_matrix().transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field True - sage: K == G + sage: K == G # optional - sage.rings.number_field True For matrices over the integers, several options are possible. @@ -5151,7 +5151,7 @@ cdef class Matrix(Matrix1): [ 0 2 0 -1] [ 0 1 -2 0] [ 0 2 0 -2] - sage: t.fcp() + sage: t.fcp() # optional - sage.libs.pari (x - 39) * (x + 2) * (x^2 - 2) sage: s = (t-39)*(t^2-2) sage: V = s.kernel(); V @@ -5465,11 +5465,11 @@ cdef class Matrix(Matrix1): [198 209 220 231 242 253] [264 275 286 297 308 319] [330 341 352 363 374 385] - sage: A.decomposition() + sage: A.decomposition() # optional - sage.libs.pari [ (Ambient free module of rank 4 over the principal ideal domain Integer Ring, True) ] - sage: B.decomposition() + sage: B.decomposition() # optional - sage.libs.pari [ (Vector space of degree 6 and dimension 2 over Rational Field Basis matrix: @@ -5658,14 +5658,14 @@ cdef class Matrix(Matrix1): [ 3 0 -2] [ 0 -2 0] [ 0 0 0] - sage: t.fcp('X') # factored charpoly + sage: t.fcp('X') # factored charpoly # optional - sage.libs.pari (X - 3) * X * (X + 2) sage: v = kernel(t*(t+2)); v # an invariant subspace Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [0 1 0] [0 0 1] - sage: D = t.decomposition_of_subspace(v); D + sage: D = t.decomposition_of_subspace(v); D # optional - sage.libs.pari [ (Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: @@ -5674,15 +5674,15 @@ cdef class Matrix(Matrix1): Basis matrix: [0 1 0], True) ] - sage: t.restrict(D[0][0]) + sage: t.restrict(D[0][0]) # optional - sage.libs.pari [0] - sage: t.restrict(D[1][0]) + sage: t.restrict(D[1][0]) # optional - sage.libs.pari [-2] We do a decomposition over ZZ:: sage: a = matrix(ZZ,6,[0, 0, -2, 0, 2, 0, 2, -4, -2, 0, 2, 0, 0, 0, -2, -2, 0, 0, 2, 0, -2, -4, 2, -2, 0, 2, 0, -2, -2, 0, 0, 2, 0, -2, 0, 0]) - sage: a.decomposition_of_subspace(ZZ^6) + sage: a.decomposition_of_subspace(ZZ^6) # optional - sage.libs.pari [ (Free module of degree 6 and rank 2 over Integer Ring Echelon basis matrix: @@ -5699,7 +5699,7 @@ cdef class Matrix(Matrix1): TESTS:: sage: t = matrix(QQ, 3, [3, 0, -2, 0, -2, 0, 0, 0, 0]) - sage: t.decomposition_of_subspace(v, check_restrict = False) == t.decomposition_of_subspace(v) + sage: t.decomposition_of_subspace(v, check_restrict = False) == t.decomposition_of_subspace(v) # optional - sage.libs.pari True """ if not sage.modules.free_module.is_FreeModule(M): @@ -5973,7 +5973,7 @@ cdef class Matrix(Matrix1): [6 7 8] sage: t.wiedemann(0) x^2 - 12*x - 18 - sage: t.charpoly() + sage: t.charpoly() # optional - sage.libs.pari x^3 - 12*x^2 - 18*x """ i = int(i); t=int(t) @@ -6282,13 +6282,13 @@ cdef class Matrix(Matrix1): [ 0.897878732... 0.278434036... -0.341010658...] [ 0.408248290... -0.816496580... 0.408248290...] - sage: x, y = var('x y') - sage: S = matrix([[x, y], [y, 3*x^2]]) - sage: em = S.eigenmatrix_left() - sage: eigenvalues = em[0]; eigenvalues + sage: x, y = var('x y') # optional - sage.symbolic + sage: S = matrix([[x, y], [y, 3*x^2]]) # optional - sage.symbolic + sage: em = S.eigenmatrix_left() # optional - sage.symbolic + sage: eigenvalues = em[0]; eigenvalues # optional - sage.symbolic [3/2*x^2 + 1/2*x - 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2) 0] [ 0 3/2*x^2 + 1/2*x + 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2)] - sage: eigenvectors = em[1]; eigenvectors + sage: eigenvectors = em[1]; eigenvectors # optional - sage.symbolic [ 1 1/2*(3*x^2 - x - sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] [ 1 1/2*(3*x^2 - x + sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] @@ -6550,13 +6550,13 @@ cdef class Matrix(Matrix1): [ 0.505774475... 0.104205787... -0.816496580...] [ 0.846785134... -0.591288087... 0.408248290...] - sage: x, y = var('x y') - sage: S = matrix([[x, y], [y, 3*x^2]]) - sage: em = S.eigenmatrix_right() - sage: eigenvalues = em[0]; eigenvalues + sage: x, y = var('x y') # optional - sage.symbolic + sage: S = matrix([[x, y], [y, 3*x^2]]) # optional - sage.symbolic + sage: em = S.eigenmatrix_right() # optional - sage.symbolic + sage: eigenvalues = em[0]; eigenvalues # optional - sage.symbolic [3/2*x^2 + 1/2*x - 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2) 0] [ 0 3/2*x^2 + 1/2*x + 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2)] - sage: eigenvectors = em[1]; eigenvectors + sage: eigenvectors = em[1]; eigenvectors # optional - sage.symbolic [ 1 1] [1/2*(3*x^2 - x - sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y 1/2*(3*x^2 - x + sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] @@ -7337,8 +7337,8 @@ cdef class Matrix(Matrix1): sage: M.eigenvalue_multiplicity(1) 0 - sage: M = posets.DiamondPoset(5).coxeter_transformation() - sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] + sage: M = posets.DiamondPoset(5).coxeter_transformation() # optional - sage.combinat, sage.graphs + sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] # optional - sage.combinat, sage.graphs [3, 2] TESTS:: @@ -7869,13 +7869,13 @@ cdef class Matrix(Matrix1): sage: a._echelon('classical') [ 1 0 -1] [ 0 1 2] - sage: R = ZpCA(5,5,print_mode='val-unit') - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) - sage: A + sage: R = ZpCA(5, 5, print_mode='val-unit') # optional - sage.rings.padics + sage: A = matrix(R, 3, 3, [250,2369,1147, 106,927,362, 90,398,2483]) # optional - sage.rings.padics + sage: A # optional - sage.rings.padics [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: A._echelon('partial_pivoting') + sage: A._echelon('partial_pivoting') # optional - sage.rings.padics [1 + O(5^5) O(5^5) O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5)] @@ -7948,13 +7948,13 @@ cdef class Matrix(Matrix1): sage: P = a._echelon_in_place('classical'); a [ 1 0 -1] [ 0 1 2] - sage: R = ZpCA(5,5,print_mode='val-unit') - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) - sage: A + sage: R = ZpCA(5, 5, print_mode='val-unit') # optional - sage.rings.padics + sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) # optional - sage.rings.padics + sage: A # optional - sage.rings.padics [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: P = A._echelon_in_place('partial_pivoting'); A + sage: P = A._echelon_in_place('partial_pivoting'); A # optional - sage.rings.padics [1 + O(5^5) O(5^5) O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5)] @@ -8326,14 +8326,14 @@ cdef class Matrix(Matrix1): [ 6 1/4] [ 8 -5] - sage: B = M.as_bipartite_graph() - sage: B + sage: B = M.as_bipartite_graph() # optional - sage.graphs + sage: B # optional - sage.graphs Bipartite graph on 5 vertices - sage: B.edges(sort=True) + sage: B.edges(sort=True) # optional - sage.graphs [(1, 4, 1/3), (1, 5, 7), (2, 4, 6), (2, 5, 1/4), (3, 4, 8), (3, 5, -5)] - sage: len(B.left) == M.nrows() + sage: len(B.left) == M.nrows() # optional - sage.graphs True - sage: len(B.right) == M.ncols() + sage: len(B.right) == M.ncols() # optional - sage.graphs True """ from sage.graphs.bipartite_graph import BipartiteGraph @@ -8360,18 +8360,18 @@ cdef class Matrix(Matrix1): [1 0] [1 0] [0 1] - sage: A = M.automorphisms_of_rows_and_columns() - sage: A + sage: A = M.automorphisms_of_rows_and_columns() # optional - sage.groups + sage: A # optional - sage.groups [((), ()), ((1,2), ())] - sage: M = matrix(ZZ,[[1,1,1,1],[1,1,1,1]]) - sage: A = M.automorphisms_of_rows_and_columns() - sage: len(A) + sage: M = matrix(ZZ,[[1,1,1,1],[1,1,1,1]]) # optional - sage.groups + sage: A = M.automorphisms_of_rows_and_columns() # optional - sage.groups + sage: len(A) # optional - sage.groups 48 One can now apply these automorphisms to ``M`` to show that it leaves it invariant:: - sage: all(M.with_permuted_rows_and_columns(*i) == M for i in A) + sage: all(M.with_permuted_rows_and_columns(*i) == M for i in A) # optional - sage.groups True Check that :trac:`25426` is fixed:: @@ -8381,7 +8381,7 @@ cdef class Matrix(Matrix1): ....: (1, 0, 3, 0, 2), ....: (0, 1, 0, 2, 1), ....: (0, 0, 2, 1, 2)]) - sage: j.automorphisms_of_rows_and_columns() + sage: j.automorphisms_of_rows_and_columns() # optional - sage.groups [((), ()), ((1,3)(2,5), (1,3)(2,5))] """ from sage.groups.perm_gps.constructor import \ @@ -8439,7 +8439,7 @@ cdef class Matrix(Matrix1): [-1 5] [ 2 4] - sage: M.permutation_normal_form(check=True) + sage: M.permutation_normal_form(check=True) # optional - sage.graphs ( [ 5 -1] [ 4 2] @@ -8450,7 +8450,7 @@ cdef class Matrix(Matrix1): TESTS:: sage: M = matrix(ZZ, [[3, 4, 5], [3, 4, 5], [3, 5, 4], [2, 0,1]]) - sage: M.permutation_normal_form() + sage: M.permutation_normal_form() # optional - sage.graphs [5 4 3] [5 4 3] [4 5 3] @@ -8591,47 +8591,47 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(ZZ,[[1,2,3],[3,5,3],[2,6,4]]) + sage: M = matrix(ZZ, [[1,2,3], [3,5,3], [2,6,4]]) sage: M [1 2 3] [3 5 3] [2 6 4] - sage: N = matrix(ZZ,[[1,2,3],[2,6,4],[3,5,3]]) + sage: N = matrix(ZZ, [[1,2,3], [2,6,4], [3,5,3]]) sage: N [1 2 3] [2 6 4] [3 5 3] - sage: M.is_permutation_of(N) + sage: M.is_permutation_of(N) # optional - sage.graphs True Some examples that are not permutations of each other:: - sage: N = matrix(ZZ,[[1,2,3],[4,5,6],[7,8,9]]) + sage: N = matrix(ZZ, [[1,2,3], [4,5,6], [7,8,9]]) sage: N [1 2 3] [4 5 6] [7 8 9] - sage: M.is_permutation_of(N) + sage: M.is_permutation_of(N) # optional - sage.graphs False - sage: N = matrix(ZZ,[[1,2],[3,4]]) + sage: N = matrix(ZZ, [[1,2], [3,4]]) sage: N [1 2] [3 4] - sage: M.is_permutation_of(N) + sage: M.is_permutation_of(N) # optional - sage.graphs False And for when ``check`` is True:: - sage: N = matrix(ZZ,[[3,5,3],[2,6,4],[1,2,3]]) + sage: N = matrix(ZZ, [[3,5,3], [2,6,4], [1,2,3]]) sage: N [3 5 3] [2 6 4] [1 2 3] - sage: r = M.is_permutation_of(N, check=True) - sage: r + sage: r = M.is_permutation_of(N, check=True) # optional - sage.graphs + sage: r # optional - sage.graphs (True, ((1,2,3), ())) - sage: p = r[1] - sage: M.with_permuted_rows_and_columns(*p) == N + sage: p = r[1] # optional - sage.graphs + sage: M.with_permuted_rows_and_columns(*p) == N # optional - sage.graphs True """ ncols = self.ncols() @@ -8849,26 +8849,26 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(5, 5, prime_range(100)) - sage: M.subdivide(2,3); M + sage: M = matrix(5, 5, prime_range(100)) # optional - sage.libs.pari + sage: M.subdivide(2,3); M # optional - sage.libs.pari [ 2 3 5| 7 11] [13 17 19|23 29] [--------+-----] [31 37 41|43 47] [53 59 61|67 71] [73 79 83|89 97] - sage: M.subdivision(0,0) + sage: M.subdivision(0,0) # optional - sage.libs.pari [ 2 3 5] [13 17 19] - sage: M.subdivision(1,0) + sage: M.subdivision(1,0) # optional - sage.libs.pari [31 37 41] [53 59 61] [73 79 83] - sage: M.subdivision_entry(1,0,0,0) + sage: M.subdivision_entry(1,0,0,0) # optional - sage.libs.pari 31 - sage: M.subdivisions() + sage: M.subdivisions() # optional - sage.libs.pari ([2], [3]) - sage: M.subdivide(None, [1,3]); M + sage: M.subdivide(None, [1,3]); M # optional - sage.libs.pari [ 2| 3 5| 7 11] [13|17 19|23 29] [31|37 41|43 47] @@ -8877,7 +8877,7 @@ cdef class Matrix(Matrix1): Degenerate cases work too:: - sage: M.subdivide([2,5], [0,1,3]); M + sage: M.subdivide([2,5], [0,1,3]); M # optional - sage.libs.pari [| 2| 3 5| 7 11] [|13|17 19|23 29] [+--+-----+-----] @@ -8885,12 +8885,12 @@ cdef class Matrix(Matrix1): [|53|59 61|67 71] [|73|79 83|89 97] [+--+-----+-----] - sage: M.subdivision(0,0) + sage: M.subdivision(0,0) # optional - sage.libs.pari [] - sage: M.subdivision(0,1) + sage: M.subdivision(0,1) # optional - sage.libs.pari [ 2] [13] - sage: M.subdivide([2,2,3], [0,0,1,1]); M + sage: M.subdivide([2,2,3], [0,0,1,1]); M # optional - sage.libs.pari [|| 2|| 3 5 7 11] [||13||17 19 23 29] [++--++-----------] @@ -8899,14 +8899,14 @@ cdef class Matrix(Matrix1): [++--++-----------] [||53||59 61 67 71] [||73||79 83 89 97] - sage: M.subdivision(0,0) + sage: M.subdivision(0,0) # optional - sage.libs.pari [] - sage: M.subdivision(2,4) + sage: M.subdivision(2,4) # optional - sage.libs.pari [37 41 43 47] Indices do not need to be in the right order (:trac:`14064`):: - sage: M.subdivide([4, 2], [3, 1]); M + sage: M.subdivide([4, 2], [3, 1]); M # optional - sage.libs.pari [ 2| 3 5| 7 11] [13|17 19|23 29] [--+-----+-----] @@ -9794,19 +9794,19 @@ cdef class Matrix(Matrix1): try to deduce the decomposition from the matrix :: sage: L = [] - sage: L.append((9,Permutation([4, 1, 3, 5, 2]))) - sage: L.append((6,Permutation([5, 3, 4, 1, 2]))) - sage: L.append((3,Permutation([3, 1, 4, 2, 5]))) - sage: L.append((2,Permutation([1, 4, 2, 3, 5]))) - sage: M = sum([c * p.to_matrix() for (c,p) in L]) - sage: decomp = sage.combinat.permutation.bistochastic_as_sum_of_permutations(M) - sage: print(decomp) + sage: L.append((9, Permutation([4, 1, 3, 5, 2]))) # optional - sage.combinat + sage: L.append((6, Permutation([5, 3, 4, 1, 2]))) # optional - sage.combinat + sage: L.append((3, Permutation([3, 1, 4, 2, 5]))) # optional - sage.combinat + sage: L.append((2, Permutation([1, 4, 2, 3, 5]))) # optional - sage.combinat + sage: M = sum([c * p.to_matrix() for (c,p) in L]) # optional - sage.combinat + sage: decomp = sage.combinat.permutation.bistochastic_as_sum_of_permutations(M) # optional - sage.combinat + sage: print(decomp) # optional - sage.combinat 2*B[[1, 4, 2, 3, 5]] + 3*B[[3, 1, 4, 2, 5]] + 9*B[[4, 1, 3, 5, 2]] + 6*B[[5, 3, 4, 1, 2]] An exception is raised when the matrix is not bistochastic:: sage: M = Matrix([[2,3],[2,2]]) - sage: decomp = sage.combinat.permutation.bistochastic_as_sum_of_permutations(M) + sage: decomp = sage.combinat.permutation.bistochastic_as_sum_of_permutations(M) # optional - sage.combinat Traceback (most recent call last): ... ValueError: The matrix is not bistochastic @@ -10140,8 +10140,8 @@ cdef class Matrix(Matrix1): presence of non-integral powers of the variable `x` (:trac:`14403`):: - sage: x = var('x') - sage: Matrix([[sqrt(x),x],[1,0]]).adjugate() + sage: x = var('x') # optional - sage.symbolic + sage: Matrix([[sqrt(x),x], [1,0]]).adjugate() # optional - sage.symbolic [ 0 -x] [ -1 sqrt(x)] @@ -10216,58 +10216,58 @@ cdef class Matrix(Matrix1): For a nonsingular matrix, the QR decomposition is unique. :: - sage: A = matrix(QQbar, [[-2, 0, -4, -1, -1], + sage: A = matrix(QQbar, [[-2, 0, -4, -1, -1], # optional - sage.rings.number_field ....: [-2, 1, -6, -3, -1], ....: [1, 1, 7, 4, 5], ....: [3, 0, 8, 3, 3], ....: [-1, 1, -6, -6, 5]]) - sage: Q, R = A.QR() - sage: Q + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ -0.4588314677411235? -0.1260506983326509? 0.3812120831224489? -0.394573711338418? -0.6874400625964?] [ -0.4588314677411235? 0.4726901187474409? -0.05198346588033394? 0.7172941251646595? -0.2209628772631?] [ 0.2294157338705618? 0.6617661662464172? 0.6619227988762521? -0.1808720937375480? 0.1964114464561?] [ 0.6882472016116853? 0.1890760474989764? -0.2044682991293135? 0.0966302966543065? -0.6628886317894?] [ -0.2294157338705618? 0.5357154679137663? -0.609939332995919? -0.536422031427112? 0.0245514308070?] - sage: R + sage: R # optional - sage.rings.number_field [ 4.358898943540674? -0.4588314677411235? 13.07669683062202? 6.194224814505168? 2.982404540317303?] [ 0 1.670171752907625? 0.5987408170800917? -1.292019657909672? 6.207996892883057?] [ 0 0 5.444401659866974? 5.468660610611130? -0.6827161852283857?] [ 0 0 0 1.027626039419836? -3.619300149686620?] [ 0 0 0 0 0.024551430807012?] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [1.000000000000000? 0.?e-18 0.?e-17 0.?e-16 0.?e-13] [ 0.?e-18 1.000000000000000? 0.?e-17 0.?e-16 0.?e-13] [ 0.?e-17 0.?e-17 1.000000000000000? 0.?e-16 0.?e-13] [ 0.?e-16 0.?e-16 0.?e-16 1.000000000000000? 0.?e-13] [ 0.?e-13 0.?e-13 0.?e-13 0.?e-13 1.0000000000000?] - sage: Q*R == A + sage: Q*R == A # optional - sage.rings.number_field True An example with complex numbers in ``QQbar``, the field of algebraic numbers. :: - sage: A = matrix(QQbar, [[-8, 4*I + 1, -I + 2, 2*I + 1], + sage: A = matrix(QQbar, [[-8, 4*I + 1, -I + 2, 2*I + 1], # optional - sage.rings.number_field ....: [1, -2*I - 1, -I + 3, -I + 1], ....: [I + 7, 2*I + 1, -2*I + 7, -I + 1], ....: [I + 2, 0, I + 12, -1]]) - sage: Q, R = A.QR() - sage: Q + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ -0.7302967433402215? 0.2070566455055649? + 0.5383472783144687?*I 0.2463049809998642? - 0.0764456358723292?*I 0.2381617683194332? - 0.1036596032779695?*I] [ 0.0912870929175277? -0.2070566455055649? - 0.3778783780476559?*I 0.3786559533863033? - 0.1952221495524667?*I 0.701244450214469? - 0.3643711650986595?*I] [ 0.6390096504226938? + 0.0912870929175277?*I 0.1708217325420910? + 0.6677576817554466?*I -0.03411475806452072? + 0.04090198741767143?*I 0.3140171085506764? - 0.0825191718705412?*I] [ 0.1825741858350554? + 0.0912870929175277?*I -0.03623491296347385? + 0.0724698259269477?*I 0.8632284069415110? + 0.06322839976356195?*I -0.4499694867611521? - 0.0116119181208918?*I] - sage: R + sage: R # optional - sage.rings.number_field [ 10.95445115010333? 0.?e-18 - 1.917028951268082?*I 5.385938482134133? - 2.190890230020665?*I -0.2738612787525831? - 2.190890230020665?*I] [ 0 4.829596256417300? + 0.?e-18*I -0.869637911123373? - 5.864879483945125?*I 0.993871898426712? - 0.3054085521207082?*I] [ 0 0 12.00160760935814? + 0.?e-16*I -0.2709533402297273? + 0.4420629644486323?*I] [ 0 0 0 1.942963944258992? + 0.?e-16*I] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [1.000000000000000? + 0.?e-19*I 0.?e-18 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-18 + 0.?e-17*I 1.000000000000000? + 0.?e-17*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-17 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 1.000000000000000? + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 1.000000000000000? + 0.?e-16*I] - sage: Q*R - A + sage: Q*R - A # optional - sage.rings.number_field [ 0.?e-17 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] [ 0.?e-18 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] [0.?e-17 + 0.?e-18*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] @@ -10275,58 +10275,58 @@ cdef class Matrix(Matrix1): A rank-deficient rectangular matrix, with both values of the ``full`` keyword. :: - sage: A = matrix(QQbar, [[2, -3, 3], + sage: A = matrix(QQbar, [[2, -3, 3], # optional - sage.rings.number_field ....: [-1, 1, -1], ....: [-1, 3, -3], ....: [-5, 1, -1]]) - sage: Q, R = A.QR() - sage: Q + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ 0.3592106040535498? -0.5693261797050169? 0.7239227659930268? 0.1509015305256380?] [ -0.1796053020267749? 0.1445907757980996? 0 0.9730546968377341?] [ -0.1796053020267749? 0.7048800320157352? 0.672213996993525? -0.1378927778941174?] [ -0.8980265101338745? -0.3976246334447737? 0.1551263069985058? -0.10667177157846818?] - sage: R + sage: R # optional - sage.rings.number_field [ 5.567764362830022? -2.694079530401624? 2.694079530401624?] [ 0 3.569584777515583? -3.569584777515583?] [ 0 0 0] [ 0 0 0] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [ 1 0.?e-18 0.?e-18 0.?e-18] [ 0.?e-18 1 0.?e-18 0.?e-18] [ 0.?e-18 0.?e-18 1.000000000000000? 0.?e-18] [ 0.?e-18 0.?e-18 0.?e-18 1.000000000000000?] - sage: Q, R = A.QR(full=False) - sage: Q + sage: Q, R = A.QR(full=False) # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ 0.3592106040535498? -0.5693261797050169?] [-0.1796053020267749? 0.1445907757980996?] [-0.1796053020267749? 0.7048800320157352?] [-0.8980265101338745? -0.3976246334447737?] - sage: R + sage: R # optional - sage.rings.number_field [ 5.567764362830022? -2.694079530401624? 2.694079530401624?] [ 0 3.569584777515583? -3.569584777515583?] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [ 1 0.?e-18] [0.?e-18 1] Another rank-deficient rectangular matrix, with complex entries, as a reduced decomposition. :: - sage: A = matrix(QQbar, [[-3*I - 3, I - 3, -12*I + 1, -2], + sage: A = matrix(QQbar, [[-3*I - 3, I - 3, -12*I + 1, -2], # optional - sage.rings.number_field ....: [-I - 1, -2, 5*I - 1, -I - 2], ....: [-4*I - 4, I - 5, -7*I, -I - 4]]) - sage: Q, R = A.QR(full=False) - sage: Q + sage: Q, R = A.QR(full=False) # optional - sage.rings.number_field + sage: Q # optional - sage.rings.number_field [ -0.4160251471689219? - 0.4160251471689219?*I 0.5370861555295747? + 0.1790287185098583?*I] [ -0.1386750490563073? - 0.1386750490563073?*I -0.7519206177414046? - 0.2506402059138015?*I] [ -0.5547001962252291? - 0.5547001962252291?*I -0.2148344622118299? - 0.07161148740394329?*I] - sage: R + sage: R # optional - sage.rings.number_field [ 7.211102550927979? 3.328201177351375? - 5.269651864139676?*I 7.904477796209515? + 8.45917799243475?*I 4.021576422632911? - 2.634825932069838?*I] [ 0 1.074172311059150? -1.611258466588724? - 9.13046464400277?*I 1.611258466588724? + 0.5370861555295747?*I] - sage: Q.conjugate_transpose()*Q + sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field [1 0] [0 1] - sage: Q*R-A + sage: Q*R - A # optional - sage.rings.number_field [0 0 0 0] [0 0 0 0] [0 0 0 0] @@ -10334,29 +10334,29 @@ cdef class Matrix(Matrix1): Results of full decompositions are cached and thus returned immutable. :: - sage: A = random_matrix(QQbar, 2, 2) - sage: Q, R = A.QR() - sage: Q.is_mutable() + sage: A = random_matrix(QQbar, 2, 2) # optional - sage.rings.number_field + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q.is_mutable() # optional - sage.rings.number_field False - sage: R.is_mutable() + sage: R.is_mutable() # optional - sage.rings.number_field False Trivial cases return trivial results of the correct size, and we check `Q` itself in one case. :: - sage: A = zero_matrix(QQbar, 0, 10) - sage: Q, R = A.QR() - sage: Q.nrows(), Q.ncols() + sage: A = zero_matrix(QQbar, 0, 10) # optional - sage.rings.number_field + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q.nrows(), Q.ncols() # optional - sage.rings.number_field (0, 0) - sage: R.nrows(), R.ncols() + sage: R.nrows(), R.ncols() # optional - sage.rings.number_field (0, 10) - sage: A = zero_matrix(QQbar, 3, 0) - sage: Q, R = A.QR() - sage: Q.nrows(), Q.ncols() + sage: A = zero_matrix(QQbar, 3, 0) # optional - sage.rings.number_field + sage: Q, R = A.QR() # optional - sage.rings.number_field + sage: Q.nrows(), Q.ncols() # optional - sage.rings.number_field (3, 3) - sage: R.nrows(), R.ncols() + sage: R.nrows(), R.ncols() # optional - sage.rings.number_field (3, 0) - sage: Q + sage: Q # optional - sage.rings.number_field [1 0 0] [0 1 0] [0 0 1] @@ -10994,27 +10994,27 @@ cdef class Matrix(Matrix1): [ 0 1 0 0] [ 1 -1 1 0] [ 1 -1 1 2] - sage: a.jordan_form() + sage: a.jordan_form() # optional - sage.combinat [2|0 0|0] [-+---+-] [0|1 1|0] [0|0 1|0] [-+---+-] [0|0 0|1] - sage: a.jordan_form(subdivide=False) + sage: a.jordan_form(subdivide=False) # optional - sage.combinat [2 0 0 0] [0 1 1 0] [0 0 1 0] [0 0 0 1] - sage: b = matrix(ZZ,3,3,range(9)); b + sage: b = matrix(ZZ,3,3,range(9)); b # optional - sage.combinat [0 1 2] [3 4 5] [6 7 8] - sage: b.jordan_form() + sage: b.jordan_form() # optional - sage.combinat Traceback (most recent call last): ... RuntimeError: Some eigenvalue does not exist in Rational Field. - sage: b.jordan_form(RealField(15)) + sage: b.jordan_form(RealField(15)) # optional - sage.combinat Traceback (most recent call last): ... ValueError: Jordan normal form not implemented over inexact rings. @@ -11022,8 +11022,8 @@ cdef class Matrix(Matrix1): Here we need to specify a field, since the eigenvalues are not defined in the smallest ring containing the matrix entries (:trac:`14508`):: - sage: c = matrix([[0,1,0],[0,0,1],[1,0,0]]) - sage: c.jordan_form(CyclotomicField(3)) # optional - sage.rings.number_field + sage: c = matrix([[0,1,0], [0,0,1], [1,0,0]]) + sage: c.jordan_form(CyclotomicField(3)) # optional - sage.combinat sage.rings.number_field [ 1| 0| 0] [----------+----------+----------] [ 0| zeta3| 0] @@ -11033,20 +11033,20 @@ cdef class Matrix(Matrix1): If you need the transformation matrix as well as the Jordan form of ``self``, then pass the option ``transformation=True``. For example:: - sage: m = matrix([[5,4,2,1],[0,1,-1,-1],[-1,-1,3,0],[1,1,-1,2]]); m + sage: m = matrix([[5,4,2,1], [0,1,-1,-1], [-1,-1,3,0], [1,1,-1,2]]); m [ 5 4 2 1] [ 0 1 -1 -1] [-1 -1 3 0] [ 1 1 -1 2] - sage: jf, p = m.jordan_form(transformation=True) - sage: jf + sage: jf, p = m.jordan_form(transformation=True) # optional - sage.combinat + sage: jf # optional - sage.combinat [2|0|0 0] [-+-+---] [0|1|0 0] [-+-+---] [0|0|4 1] [0|0|0 4] - sage: ~p * m * p + sage: ~p * m * p # optional - sage.combinat [2 0 0 0] [0 1 0 0] [0 0 4 1] @@ -11056,7 +11056,7 @@ cdef class Matrix(Matrix1): compute the Jordan normal form, since it is not numerically stable:: - sage: b = matrix(ZZ,3,3,range(9)) + sage: b = matrix(ZZ, 3, 3, range(9)) sage: jf, p = b.jordan_form(RealField(15), transformation=True) Traceback (most recent call last): ... @@ -11068,7 +11068,7 @@ cdef class Matrix(Matrix1): [1 1 1] [1 1 1] [1 1 1] - sage: c.jordan_form(subdivide=False) + sage: c.jordan_form(subdivide=False) # optional - sage.combinat [3 0 0] [0 0 0] [0 0 0] @@ -11081,12 +11081,12 @@ cdef class Matrix(Matrix1): sage: p = random_matrix(ZZ,n,n) sage: while p.rank() != n: p = random_matrix(ZZ,n,n) sage: m = p * jf * ~p - sage: mjf, mp = m.jordan_form(transformation=True) - sage: mjf == jf + sage: mjf, mp = m.jordan_form(transformation=True) # optional - sage.combinat + sage: mjf == jf # optional - sage.combinat True sage: m = diagonal_matrix([1,1,0,0]) - sage: jf,P = m.jordan_form(transformation=True) - sage: jf == ~P*m*P + sage: jf, P = m.jordan_form(transformation=True) # optional - sage.combinat + sage: jf == ~P*m*P # optional - sage.combinat True We verify that the bug from :trac:`6942` is fixed:: @@ -11094,8 +11094,8 @@ cdef class Matrix(Matrix1): sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1], [1,0,0,1,1,1,0], [1,1,0,1,1,1,1], # optional - sage.libs.pari ....: [1,1,1,0,1,1,1], [1,1,1,0,0,1,0], [1,1,1,0,1,0,0], ....: [1,1,1,1,1,1,0]]) - sage: J, T = M.jordan_form(transformation=True) # optional - sage.libs.pari - sage: J # optional - sage.libs.pari + sage: J, T = M.jordan_form(transformation=True) # optional - sage.combinat sage.libs.pari + sage: J # optional - sage.combinat sage.libs.pari [1 1|0 0|0 0|0] [0 1|0 0|0 0|0] [---+---+---+-] @@ -11106,17 +11106,17 @@ cdef class Matrix(Matrix1): [0 0|0 0|0 1|0] [---+---+---+-] [0 0|0 0|0 0|1] - sage: M * T == T * J # optional - sage.libs.pari + sage: M * T == T * J # optional - sage.combinat sage.libs.pari True - sage: T.rank() # optional - sage.libs.pari + sage: T.rank() # optional - sage.combinat sage.libs.pari 7 - sage: M.rank() # optional - sage.libs.pari + sage: M.rank() # optional - sage.combinat sage.libs.pari 7 We verify that the bug from :trac:`6932` is fixed:: - sage: M=Matrix(1,1,[1]) - sage: M.jordan_form(transformation=True) + sage: M = Matrix(1, 1, [1]) # optional - sage.combinat + sage: M.jordan_form(transformation=True) # optional - sage.combinat ([1], [1]) We now go through three `10 \times 10` matrices to exhibit cases where @@ -11133,7 +11133,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -66 -199/3 -42 -41/3 0 13/3 -55/3 -2/3] [ 18 57 -9 -54 -57 0 0 0 -15 0] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J + sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat [3 1 0|0 0 0|0 0 0|0] [0 3 1|0 0 0|0 0 0|0] [0 0 3|0 0 0|0 0 0|0] @@ -11147,9 +11147,9 @@ cdef class Matrix(Matrix1): [0 0 0|0 0 0|0 0 3|0] [-----+-----+-----+-] [0 0 0|0 0 0|0 0 0|3] - sage: T * J * T**(-1) == A + sage: T * J * T**(-1) == A # optional - sage.combinat True - sage: T.rank() + sage: T.rank() # optional - sage.combinat 10 :: @@ -11165,7 +11165,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -66 -28/3 -42 -41/3 0 13/3 2/3 82/3] [ 18 57 -9 0 -57 0 0 0 3 28] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J + sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat [3 1 0|0 0 0|0 0|0 0] [0 3 1|0 0 0|0 0|0 0] [0 0 3|0 0 0|0 0|0 0] @@ -11179,9 +11179,9 @@ cdef class Matrix(Matrix1): [-----+-----+---+---] [0 0 0|0 0 0|0 0|3 1] [0 0 0|0 0 0|0 0|0 3] - sage: T * J * T**(-1) == A + sage: T * J * T**(-1) == A # optional - sage.combinat True - sage: T.rank() + sage: T.rank() # optional - sage.combinat 10 :: @@ -11197,7 +11197,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -30 -199/3 -42 -14/3 70 13/3 -55/3 -2/3] [ 18 57 -9 -54 -57 0 63 0 -15 0] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J + sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat [3 1 0|0 0|0 0|0 0|0] [0 3 1|0 0|0 0|0 0|0] [0 0 3|0 0|0 0|0 0|0] @@ -11212,7 +11212,7 @@ cdef class Matrix(Matrix1): [0 0 0|0 0|0 0|0 3|0] [-----+---+---+---+-] [0 0 0|0 0|0 0|0 0|3] - sage: T * J * T**(-1) == A + sage: T * J * T**(-1) == A # optional - sage.combinat True sage: T.rank() 10 @@ -11220,9 +11220,9 @@ cdef class Matrix(Matrix1): Verify that we smoothly move to QQ from ZZ (:trac:`12693`), i.e. we work in the vector space over the field:: - sage: M = matrix(((2,2,2),(0,0,0),(-2,-2,-2))) - sage: J, P = M.jordan_form(transformation=True) - sage: J; P + sage: M = matrix(((2,2,2), (0,0,0), (-2,-2,-2))) + sage: J, P = M.jordan_form(transformation=True) # optional - sage.combinat + sage: J; P # optional - sage.combinat [0 1|0] [0 0|0] [---+-] @@ -11230,15 +11230,15 @@ cdef class Matrix(Matrix1): [ 2 1 0] [ 0 0 1] [-2 0 -1] - sage: J - ~P * M * P + sage: J - ~P * M * P # optional - sage.combinat [0 0 0] [0 0 0] [0 0 0] - sage: parent(M) + sage: parent(M) # optional - sage.combinat Full MatrixSpace of 3 by 3 dense matrices over Integer Ring - sage: parent(J) == parent(P) == MatrixSpace(QQ, 3) + sage: parent(J) == parent(P) == MatrixSpace(QQ, 3) # optional - sage.combinat True - sage: M.jordan_form(transformation=True) == (M/1).jordan_form(transformation=True) + sage: M.jordan_form(transformation=True) == (M/1).jordan_form(transformation=True) # optional - sage.combinat True By providing eigenvalues ourselves, we can compute the Jordan form even @@ -11247,16 +11247,16 @@ cdef class Matrix(Matrix1): sage: Qx = PolynomialRing(QQ, 'x11, x12, x13, x21, x22, x23, x31, x32, x33') sage: x11, x12, x13, x21, x22, x23, x31, x32, x33 = Qx.gens() sage: M = matrix(Qx, [[0, 0, x31], [0, 0, x21], [0, 0, 0]]) # This is a nilpotent matrix. - sage: M.jordan_form(eigenvalues=[(0, 3)]) + sage: M.jordan_form(eigenvalues=[(0, 3)]) # optional - sage.combinat [0 1|0] [0 0|0] [---+-] [0 0|0] - sage: M.jordan_form(eigenvalues=[(0, 2)]) + sage: M.jordan_form(eigenvalues=[(0, 2)]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: The provided list of eigenvalues is not correct. - sage: M.jordan_form(transformation=True, eigenvalues=[(0, 3)]) + sage: M.jordan_form(transformation=True, eigenvalues=[(0, 3)]) # optional - sage.combinat ( [0 1|0] [0 0|0] [x31 0 1] @@ -11268,17 +11268,17 @@ cdef class Matrix(Matrix1): and it needs to be implemented. :: sage: A = matrix(Integers(6), 2, 2, range(4)) - sage: A.jordan_form() + sage: A.jordan_form() # optional - sage.combinat Traceback (most recent call last): ... ValueError: Matrix entries must be from a field, not Ring of integers modulo 6 Test for :trac:`10563`:: - sage: R = FractionField(PolynomialRing(RationalField(),'a')) + sage: R = FractionField(PolynomialRing(RationalField(), 'a')) sage: a = R.gen() - sage: A = matrix(R,[[1,a],[a,1]]) - sage: A.jordan_form() + sage: A = matrix(R, [[1,a], [a,1]]) # optional - sage.combinat + sage: A.jordan_form() # optional - sage.combinat [ a + 1| 0] [------+------] [ 0|-a + 1] @@ -11451,31 +11451,31 @@ cdef class Matrix(Matrix1): [-3 5 3 3] [ 3 -6 -4 -3] [-3 6 3 2] - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari True - sage: A.diagonalization() + sage: A.diagonalization() # optional - sage.libs.pari ( [ 2 0 0 0] [ 1 1 0 0] [ 0 -1 0 0] [ 1 0 1 0] [ 0 0 -1 0] [-1 0 0 1] [ 0 0 0 -1], [ 1 1 -2 -1] ) - sage: D, P = A.diagonalization() - sage: P^-1*A*P == D + sage: D, P = A.diagonalization() # optional - sage.libs.pari + sage: P^-1*A*P == D # optional - sage.libs.pari True sage: A = matrix(QQ, 2, [0, 2, 1, 0]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari False - sage: A.is_diagonalizable(QQbar) + sage: A.is_diagonalizable(QQbar) # optional - sage.libs.pari sage.rings.number_field True - sage: D, P = A.diagonalization(QQbar) - sage: P^-1*A*P == D + sage: D, P = A.diagonalization(QQbar) # optional - sage.libs.pari sage.rings.number_field + sage: P^-1*A*P == D # optional - sage.libs.pari sage.rings.number_field True Matrices may fail to be diagonalizable for various reasons:: - sage: A = matrix(QQ, 2, [1,2,3,4,5,6]) + sage: A = matrix(QQ, 2, [1,2,3, 4,5,6]) sage: A [1 2 3] [4 5 6] @@ -11602,9 +11602,9 @@ cdef class Matrix(Matrix1): ....: [ 9, -8, 11, -12, 51], ....: [ 3, -4, 0, -1, 9], ....: [-1, 0, -4, 4, -12]]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari True - sage: A.diagonalization() + sage: A.diagonalization() # optional - sage.libs.pari ( [ 2 0 0 0 0] [ 1 1 0 1 0] [ 0 3 0 0 0] [ 1/2 0 1 0 1] @@ -11621,9 +11621,9 @@ cdef class Matrix(Matrix1): ....: [-2, -14, 0, 0, 10], ....: [3, 13, -2, 0, -11], ....: [-1, 6, 1, -3, 1]]) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari False - sage: A.jordan_form(subdivide=False) + sage: A.jordan_form(subdivide=False) # optional - sage.libs.pari [-1 1 0 0 0] [ 0 -1 0 0 0] [ 0 0 2 1 0] @@ -11841,18 +11841,18 @@ cdef class Matrix(Matrix1): sage: B = matrix(ZZ, [[ 1, 12, 3], ....: [-1, -6, -1], ....: [ 0, 6, 1]]) - sage: A.is_similar(B) + sage: A.is_similar(B) # optional - sage.libs.pari True - sage: _, T = A.is_similar(B, transformation=True) - sage: T + sage: _, T = A.is_similar(B, transformation=True) # optional - sage.libs.pari + sage: T # optional - sage.libs.pari [ 1.00000000000000? + 0.?e-14*I 0.?e-14 + 0.?e-14*I 0.?e-14 + 0.?e-14*I] [-0.66666666666667? + 0.?e-15*I 0.166666666666667? + 0.?e-15*I -0.83333333333334? + 0.?e-14*I] [ 0.66666666666667? + 0.?e-14*I 0.?e-14 + 0.?e-14*I -0.33333333333333? + 0.?e-14*I] - sage: T.change_ring(QQ) + sage: T.change_ring(QQ) # optional - sage.libs.pari [ 1 0 0] [-2/3 1/6 -5/6] [ 2/3 0 -1/3] - sage: A == T.inverse()*B*T + sage: A == T.inverse()*B*T # optional - sage.libs.pari True Other exact fields are supported. :: @@ -11887,9 +11887,9 @@ cdef class Matrix(Matrix1): ....: [-1, 2, -3, -7], ....: [-2, 3, -4, -7], ....: [ 0, -1, 0, 0]]) - sage: A.eigenvalues() == B.eigenvalues() + sage: A.eigenvalues() == B.eigenvalues() # optional - sage.rings.number_field False - sage: A.is_similar(B, transformation=True) + sage: A.is_similar(B, transformation=True) # optional - sage.libs.pari (False, None) Similarity is an equivalence relation, so this routine computes @@ -12415,7 +12415,7 @@ cdef class Matrix(Matrix1): ... TypeError: first input should be a vector, not junk - sage: A.cyclic_subspace(v, var=sin(x)) + sage: A.cyclic_subspace(v, var=sin(x)) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: polynomial variable must be a string or polynomial ring generator, not sin(x) @@ -12602,15 +12602,15 @@ cdef class Matrix(Matrix1): ....: [ -2, -18, -38, 15]]) sage: A.is_symmetric() True - sage: L = A.cholesky() - sage: L + sage: L = A.cholesky() # optional - sage.rings.number_field + sage: L # optional - sage.rings.number_field [ 8.83176086632785? 0 0 0] [ -3.396831102433787? 9.51112708681461? 0 0] [ -4.189425026335004? 17.32383862241232? 2.886751345948129? 0] [-0.2264554068289192? -1.973397116652010? -1.649572197684645? 2.886751345948129?] - sage: L.parent() + sage: L.parent() # optional - sage.rings.number_field Full MatrixSpace of 4 by 4 dense matrices over Algebraic Real Field - sage: L*L.transpose() == A + sage: L*L.transpose() == A # optional - sage.rings.number_field True Some subfields of the complex numbers, such as this number @@ -13100,47 +13100,47 @@ cdef class Matrix(Matrix1): ....: [2, 0, 1, 4, 2, 6, 0], ....: [1, 0, -1, 8, -1, -1, -3], ....: [1, 1, 2, -2, -1, 1, 3]]) - sage: P, L, U = A.LU(pivot='partial') - sage: P + sage: P, L, U = A.LU(pivot='partial') # optional - sage.combinat + sage: P # optional - sage.combinat [0 0 0 0 1] [1 0 0 0 0] [0 0 0 1 0] [0 0 1 0 0] [0 1 0 0 0] - sage: L + sage: L # optional - sage.combinat [ 1 0 0 0 0] [ 1/2 1 0 0 0] [ 1/2 1/3 1 0 0] [ 1 2/3 1/5 1 0] [ 1/2 -1/3 -2/5 0 1] - sage: U + sage: U # optional - sage.combinat [ 2 -1 0 6 4 8 -2] [ 0 3/2 2 -5 -3 -3 4] [ 0 0 -5/3 20/3 -2 -4 -10/3] [ 0 0 0 0 2/5 4/5 0] [ 0 0 0 0 1/5 2/5 0] - sage: A == P*L*U + sage: A == P*L*U # optional - sage.combinat True - sage: P, L, U = A.LU(pivot='nonzero') - sage: P + sage: P, L, U = A.LU(pivot='nonzero') # optional - sage.combinat + sage: P # optional - sage.combinat [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: L + sage: L # optional - sage.combinat [ 1 0 0 0 0] [ 2 1 0 0 0] [ 2 2 1 0 0] [ 1 1 -1 1 0] [ 1 2 2 0 1] - sage: U + sage: U # optional - sage.combinat [ 1 -1 0 2 4 7 -1] [ 0 1 0 2 -4 -6 0] [ 0 0 1 -4 2 4 2] [ 0 0 0 0 1 2 0] [ 0 0 0 0 -1 -2 0] - sage: A == P*L*U + sage: A == P*L*U # optional - sage.combinat True An example of the compact format. :: @@ -13150,10 +13150,10 @@ cdef class Matrix(Matrix1): ....: [-1, -4, -6, -6], ....: [ 0, -2, -5, -8], ....: [-2, -6, -6, -2]]) - sage: perm, M = B.LU(format='compact') - sage: perm + sage: perm, M = B.LU(format='compact') # optional - sage.combinat + sage: perm # optional - sage.combinat (4, 3, 0, 1, 2) - sage: M + sage: M # optional - sage.combinat [ -2 -6 -6 -2] [ 0 -2 -5 -8] [-1/2 0 2 4] @@ -13167,13 +13167,13 @@ cdef class Matrix(Matrix1): ....: [ 1, -2, 1, 3], ....: [-4, 7, -3, -8], ....: [-3, 8, -1, -5]]) - sage: P, L, U = C.LU(format='plu') - sage: perm, M = C.LU(format='compact') - sage: (L - identity_matrix(4)) + U == M + sage: P, L, U = C.LU(format='plu') # optional - sage.combinat + sage: perm, M = C.LU(format='compact') # optional - sage.combinat + sage: (L - identity_matrix(4)) + U == M # optional - sage.combinat True - sage: p = [perm[i]+1 for i in range(len(perm))] - sage: PP = Permutation(p).to_matrix() - sage: PP == P + sage: p = [perm[i]+1 for i in range(len(perm))] # optional - sage.combinat + sage: PP = Permutation(p).to_matrix() # optional - sage.combinat + sage: PP == P # optional - sage.combinat True For a nonsingular matrix, and the 'nonzero' pivot @@ -13189,29 +13189,29 @@ cdef class Matrix(Matrix1): ....: [-2, 2, -3, 2, 1, 0], ....: [ 0, -1, -1, 0, 2, 5], ....: [-1, 2, -4, -1, 5, -3]]) - sage: P, L, U = D.LU(pivot='nonzero') - sage: P + sage: P, L, U = D.LU(pivot='nonzero') # optional - sage.combinat + sage: P # optional - sage.combinat [1 0 0 0 0 0] [0 1 0 0 0 0] [0 0 1 0 0 0] [0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] - sage: L + sage: L # optional - sage.combinat [ 1 0 0 0 0 0] [ 3 1 0 0 0 0] [ -4 -1 1 0 0 0] [ -2 -1 -1 1 0 0] [ 0 1/2 1/4 1/2 1 0] [ -1 -1 -5/2 -2 -6 1] - sage: U + sage: U # optional - sage.combinat [ 1 0 2 0 -2 -1] [ 0 -2 -3 -1 6 9] [ 0 0 2 0 -3 -3] [ 0 0 0 1 0 4] [ 0 0 0 0 -1/4 -3/4] [ 0 0 0 0 0 1] - sage: D == L*U + sage: D == L*U # optional - sage.combinat True The base ring of the matrix may be any field, or a ring @@ -13241,19 +13241,19 @@ cdef class Matrix(Matrix1): Traceback (most recent call last): ... TypeError: cannot take absolute value of matrix entries, try 'pivot=nonzero' - sage: P, L, U = B.LU(pivot='nonzero') - sage: P + sage: P, L, U = B.LU(pivot='nonzero') # optional - sage.combinat + sage: P # optional - sage.combinat [1 0] [0 1] - sage: L + sage: L # optional - sage.combinat [ 1 0] [y^2/(y + 1) 1] - sage: U + sage: U # optional - sage.combinat [ y + 1 y^2 + y] [ 0 0] - sage: L.base_ring() + sage: L.base_ring() # optional - sage.combinat Fraction Field of Univariate Polynomial Ring in y over Rational Field - sage: B == P*L*U + sage: B == P*L*U # optional - sage.combinat True sage: F. = FiniteField(5^2) # optional - sage.libs.pari @@ -13261,25 +13261,25 @@ cdef class Matrix(Matrix1): ....: [3, 2*a + 4, 2*a + 4, 2*a + 1], ....: [3*a + 1, a + 3, 2*a + 4, 4*a + 3], ....: [a, 3, 3*a + 1, a]]) - sage: P, L, U = C.LU(pivot='nonzero') # optional - sage.libs.pari - sage: P # optional - sage.libs.pari + sage: P, L, U = C.LU(pivot='nonzero') # optional - sage.combinat sage.libs.pari + sage: P # optional - sage.combinat sage.libs.pari [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] - sage: L # optional - sage.libs.pari + sage: L # optional - sage.combinat sage.libs.pari [ 1 0 0 0] [3*a + 3 1 0 0] [ 2*a 4*a + 2 1 0] [2*a + 3 2 2*a + 4 1] - sage: U # optional - sage.libs.pari + sage: U # optional - sage.combinat sage.libs.pari [ a + 3 4*a + 4 2 4*a + 2] [ 0 a + 1 a + 3 2*a + 4] [ 0 0 1 4*a + 2] [ 0 0 0 0] - sage: L.base_ring() # optional - sage.libs.pari + sage: L.base_ring() # optional - sage.combinat sage.libs.pari Finite Field in a of size 5^2 - sage: C == P*L*U # optional - sage.libs.pari + sage: C == P*L*U # optional - sage.combinat sage.libs.pari True With no pivoting strategy given (i.e. ``pivot=None``) @@ -13291,10 +13291,10 @@ cdef class Matrix(Matrix1): sage: entries = [3, 20, 11, 7, 16, 28, 5, 15, 21, 23, 22, 18, 8, 23, 15, 2] sage: A = matrix(Integers(29), 4, 4, entries) - sage: perm, _ = A.LU(format='compact'); perm + sage: perm, _ = A.LU(format='compact'); perm # optional - sage.combinat (0, 1, 2, 3) sage: B = matrix(QQ, 4, 4, entries) - sage: perm, _ = B.LU(format='compact'); perm + sage: perm, _ = B.LU(format='compact'); perm # optional - sage.combinat (2, 0, 1, 3) The `U` matrix is only guaranteed to be upper-triangular. @@ -13306,8 +13306,8 @@ cdef class Matrix(Matrix1): ....: [ 0, 0, 1, -4, -1, -3, 6, -5, -6], ....: [-2, 8, -1, -4, 2, -4, 1, -8, -7], ....: [ 1, -4, 2, -4, -3, 2, 5, 6, 4]]) - sage: P, L, U = A.LU() - sage: U + sage: P, L, U = A.LU() # optional - sage.combinat + sage: U # optional - sage.combinat [ -2 8 -1 -4 2 -4 1 -8 -7] [ 0 0 1/2 -2 -1 -2 9/2 -3 -7/2] [ 0 0 3/2 -6 -2 0 11/2 2 1/2] @@ -13340,15 +13340,15 @@ cdef class Matrix(Matrix1): components of the 'plu' format are not. :: sage: A = matrix(ZZ, 2, range(4)) - sage: perm, M = A.LU(format='compact') - sage: perm[0] = 25 + sage: perm, M = A.LU(format='compact') # optional - sage.combinat + sage: perm[0] = 25 # optional - sage.combinat Traceback (most recent call last): ... TypeError: 'tuple' object does not support item assignment - sage: M.is_immutable() + sage: M.is_immutable() # optional - sage.combinat True - sage: P, L, U = A.LU(format='plu') - sage: all(A.is_mutable() for A in [P, L, U]) + sage: P, L, U = A.LU(format='plu') # optional - sage.combinat + sage: all(A.is_mutable() for A in [P, L, U]) # optional - sage.combinat True Partial pivoting is based on the absolute values of entries @@ -13359,15 +13359,15 @@ cdef class Matrix(Matrix1): sage: C = SymmetricGroup(5).character_table() # optional - sage.groups sage.rings.number_field sage: C.base_ring() # optional - sage.groups sage.rings.number_field Cyclotomic Field of order 1 and degree 1 - sage: P, L, U = C.LU(pivot='partial') # optional - sage.groups sage.rings.number_field - sage: C == P*L*U # optional - sage.groups sage.rings.number_field + sage: P, L, U = C.LU(pivot='partial') # optional - sage.combinat sage.groups sage.rings.number_field + sage: C == P*L*U # optional - sage.combinat sage.groups sage.rings.number_field True Check that :trac:`32736` is solved:: sage: M = Matrix(FiniteField(11), [[2,3],[4,5]]) # optional - sage.libs.pari - sage: P, L, U = M.LU() # optional - sage.libs.pari - sage: P.base_ring() # optional - sage.libs.pari + sage: P, L, U = M.LU() # optional - sage.combinat sage.libs.pari + sage: P.base_ring() # optional - sage.combinat sage.libs.pari Finite Field of size 11 """ if pivot not in [None, 'partial', 'nonzero']: @@ -14569,7 +14569,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, [ [2,1], ....: [1,2] ] ) - sage: A.eigenvalues() + sage: A.eigenvalues() # optional - sage.rings.number_field [3, 1] sage: A.is_positive_semidefinite() True @@ -15281,32 +15281,32 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: d = matrix([[3, 0],[0,sqrt(2)]]) - sage: b = matrix([[1, -1], [2, 2]]) ; e = b * d * b.inverse();e + sage: d = matrix([[3, 0], [0,sqrt(2)]]) # optional - sage.symbolic + sage: b = matrix([[1, -1], [2, 2]]); e = b * d * b.inverse(); e # optional - sage.symbolic [ 1/2*sqrt(2) + 3/2 -1/4*sqrt(2) + 3/4] [ -sqrt(2) + 3 1/2*sqrt(2) + 3/2] :: - sage: e.numerical_approx(53) + sage: e.numerical_approx(53) # optional - sage.symbolic [ 2.20710678118655 0.396446609406726] [ 1.58578643762690 2.20710678118655] :: - sage: e.numerical_approx(20) + sage: e.numerical_approx(20) # optional - sage.symbolic [ 2.2071 0.39645] [ 1.5858 2.2071] :: - sage: (e-I).numerical_approx(20) + sage: (e - I).numerical_approx(20) # optional - sage.symbolic [2.2071 - 1.0000*I 0.39645] [ 1.5858 2.2071 - 1.0000*I] :: - sage: M=matrix(QQ,4,[i/(i+1) for i in range(12)]);M + sage: M = matrix(QQ, 4, [i/(i+1) for i in range(12)]); M [ 0 1/2 2/3] [ 3/4 4/5 5/6] [ 6/7 7/8 8/9] @@ -15322,7 +15322,7 @@ cdef class Matrix(Matrix1): :: - sage: matrix(SR, 2, 2, range(4)).n() # optional - sage.symbolic + sage: matrix(SR, 2, 2, range(4)).n() # optional - sage.symbolic [0.000000000000000 1.00000000000000] [ 2.00000000000000 3.00000000000000] @@ -15336,9 +15336,9 @@ cdef class Matrix(Matrix1): We check that :trac:`29700` is fixed:: - sage: M = matrix(3,[1,1,1,1,0,0,0,1,0]) - sage: A,B = M.diagonalization(QQbar) - sage: _ = A.n() + sage: M = matrix(3, [1,1,1,1,0,0,0,1,0]) + sage: A, B = M.diagonalization(QQbar) # optional - sage.rings.number_field + sage: _ = A.n() # optional - sage.rings.number_field """ from sage.rings.real_mpfr import RealField @@ -15373,7 +15373,7 @@ cdef class Matrix(Matrix1): A matrix over ZZ colored with different grey levels:: sage: A = matrix([[1,3,5,1],[2,4,5,6],[1,3,5,7]]) - sage: A.plot() + sage: A.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive Here we make a random matrix over ``RR`` and use ``cmap='hsv'`` to color @@ -15381,13 +15381,13 @@ cdef class Matrix(Matrix1): ``matrix_plot`` for more information on cmaps):: sage: A = random_matrix(RDF, 50) - sage: plot(A, cmap='hsv') + sage: plot(A, cmap='hsv') # optional - sage.plot Graphics object consisting of 1 graphics primitive Another random plot, but over GF(389):: - sage: A = random_matrix(GF(389), 10) # optional - sage.libs.pari - sage: A.plot(cmap='Oranges') # optional - sage.libs.pari + sage: A = random_matrix(GF(389), 10) # optional - sage.libs.pari + sage: A.plot(cmap='Oranges') # optional - sage.libs.pari sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.matrix_plot import matrix_plot @@ -15403,17 +15403,17 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: v = vector([1,x,x^2]) - sage: v.derivative(x) + sage: v = vector([1,x,x^2]) # optional - sage.symbolic + sage: v.derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) + sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic True - sage: v = vector([1,x,x^2], sparse=True) - sage: v.derivative(x) + sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic + sage: v.derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) + sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic True - sage: v.derivative(x,x) + sage: v.derivative(x,x) # optional - sage.symbolic (0, 0, 2) """ from sage.misc.derivative import multi_derivative @@ -15438,24 +15438,24 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: a=matrix([[1,2],[3,4]]) - sage: a.exp() + sage: a = matrix([[1,2], [3,4]]) + sage: a.exp() # optional - sage.symbolic [-1/22*((sqrt(33) - 11)*e^sqrt(33) - sqrt(33) - 11)*e^(-1/2*sqrt(33) + 5/2) 2/33*(sqrt(33)*e^sqrt(33) - sqrt(33))*e^(-1/2*sqrt(33) + 5/2)] [ 1/11*(sqrt(33)*e^sqrt(33) - sqrt(33))*e^(-1/2*sqrt(33) + 5/2) 1/22*((sqrt(33) + 11)*e^sqrt(33) - sqrt(33) + 11)*e^(-1/2*sqrt(33) + 5/2)] - sage: type(a.exp()) + sage: type(a.exp()) # optional - sage.symbolic - sage: a=matrix([[1/2,2/3],[3/4,4/5]]) - sage: a.exp() + sage: a = matrix([[1/2,2/3], [3/4,4/5]]) + sage: a.exp() # optional - sage.symbolic [-1/418*((3*sqrt(209) - 209)*e^(1/10*sqrt(209)) - 3*sqrt(209) - 209)*e^(-1/20*sqrt(209) + 13/20) 20/627*(sqrt(209)*e^(1/10*sqrt(209)) - sqrt(209))*e^(-1/20*sqrt(209) + 13/20)] [ 15/418*(sqrt(209)*e^(1/10*sqrt(209)) - sqrt(209))*e^(-1/20*sqrt(209) + 13/20) 1/418*((3*sqrt(209) + 209)*e^(1/10*sqrt(209)) - 3*sqrt(209) + 209)*e^(-1/20*sqrt(209) + 13/20)] - sage: a=matrix(RR,[[1,pi.n()],[1e2,1e-2]]) - sage: a.exp() + sage: a = matrix(RR, [[1,pi.n()], [1e2,1e-2]]) + sage: a.exp() # optional - sage.symbolic [ 1/11882424341266*((11*sqrt(227345670387496707609) + 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) + 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) 445243650/75781890129165569203*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] [ 10000/53470909535697*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) -1/11882424341266*((11*sqrt(227345670387496707609) - 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) - 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] - sage: a.change_ring(RDF).exp() # rel tol 1e-14 + sage: a.change_ring(RDF).exp() # rel tol 1e-14 # optional - sage.symbolic [42748127.31532951 7368259.244159399] [234538976.1381042 40426191.45156228] @@ -15466,7 +15466,7 @@ cdef class Matrix(Matrix1): sage: matrix.diagonal([0], sparse=True).exp() # not tested, requires patched maxima [1] - sage: matrix.zero(CBF, 2, sparse=True).exp() + sage: matrix.zero(CBF, 2, sparse=True).exp() # optional - sage.symbolic [1.000000000000000 0] [ 0 1.000000000000000] """ @@ -16414,7 +16414,7 @@ cdef class Matrix(Matrix1): sage: U.inverse()*B*U == Z True - sage: A.jordan_form() == B.jordan_form() + sage: A.jordan_form() == B.jordan_form() # optional - sage.combinat True Two more examples, illustrating the two extremes of the zig-zag @@ -16475,7 +16475,7 @@ cdef class Matrix(Matrix1): sage: U.inverse()*D*U == Z True - sage: C.jordan_form() == D.jordan_form() + sage: C.jordan_form() == D.jordan_form() # optional - sage.combinat True ZigZag form is achieved entirely with the operations of the field, so @@ -16677,13 +16677,13 @@ cdef class Matrix(Matrix1): sage: invariants [[4, -4, 1], [-12, 4, 9, -6, 1], [216, -108, -306, 271, 41, -134, 64, -13, 1]] sage: polys = [R(p) for p in invariants] - sage: [p.factor() for p in polys] + sage: [p.factor() for p in polys] # optional - sage.libs.pari [(x - 2)^2, (x - 3) * (x + 1) * (x - 2)^2, (x + 1)^2 * (x - 3)^3 * (x - 2)^3] sage: all(polys[i].divides(polys[i+1]) for i in range(len(polys)-1)) True - sage: polys[-1] == A.minimal_polynomial(var='x') + sage: polys[-1] == A.minimal_polynomial(var='x') # optional - sage.libs.pari True - sage: prod(polys) == A.characteristic_polynomial(var='x') + sage: prod(polys) == A.characteristic_polynomial(var='x') # optional - sage.libs.pari True Rational form is a canonical form. Any two matrices are similar @@ -16701,9 +16701,9 @@ cdef class Matrix(Matrix1): ....: [0, -42, 14, 8, 167, -17, -84, 13], ....: [0, -50, 17, 10, 199, -23, -98, 14], ....: [0, 15, -5, -2, -59, 7, 30, -2]]) - sage: C.minimal_polynomial().factor() + sage: C.minimal_polynomial().factor() # optional - sage.libs.pari (x - 2)^2 - sage: C.characteristic_polynomial().factor() + sage: C.characteristic_polynomial().factor() # optional - sage.libs.pari (x - 2)^8 sage: C.rational_form() [ 0 -4| 0 0| 0 0| 0 0] @@ -16726,9 +16726,9 @@ cdef class Matrix(Matrix1): ....: [ 31, -18, 135, 38, 12, 47, 155, -147], ....: [-33, 19, -138, -39, -13, -45, -156, 151], ....: [ -7, 4, -29, -8, -3, -10, -34, 34]]) - sage: D.minimal_polynomial().factor() + sage: D.minimal_polynomial().factor() # optional - sage.libs.pari (x - 2)^2 - sage: D.characteristic_polynomial().factor() + sage: D.characteristic_polynomial().factor() # optional - sage.libs.pari (x - 2)^8 sage: D.rational_form() [ 0 -4| 0 0| 0 0| 0 0] @@ -16751,9 +16751,9 @@ cdef class Matrix(Matrix1): ....: [-3, -7, 5, -6, -1, 5, -4, 14], ....: [ 6, 18, -10, 14, 4, -10, 10, -28], ....: [-2, -6, 4, -5, -1, 3, -3, 13]]) - sage: E.minimal_polynomial().factor() + sage: E.minimal_polynomial().factor() # optional - sage.libs.pari (x - 2)^3 - sage: E.characteristic_polynomial().factor() + sage: E.characteristic_polynomial().factor() # optional - sage.libs.pari (x - 2)^8 sage: E.rational_form() [ 2| 0 0| 0 0| 0 0 0] @@ -17052,47 +17052,47 @@ cdef class Matrix(Matrix1): Nonnegative matrices are positive operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = random_matrix(QQ,3).apply_map(abs) - sage: L.is_positive_operator_on(K) + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = random_matrix(QQ, 3).apply_map(abs) + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [0, e, 0 ], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [0, e, 0 ], # optional - sage.symbolic ....: [0, 2, pi], ....: [sqrt(2), 0, 0 ] ]) - sage: L.is_positive_operator_on(K) + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic True Your matrix can be over any exact ring, for example the ring of univariate polynomials with rational coefficients:: - sage: K = Cone([(1,0),(-1,0),(0,1),(0,-1)]) - sage: K.is_full_space() + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) # optional - sage.geometry.polyhedron + sage: K.is_full_space() # optional - sage.geometry.polyhedron True sage: x = polygen(ZZ, 'x') sage: L = matrix(QQ[x], [[x,0],[0,1]]) - sage: L.is_positive_operator_on(K) + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron True TESTS: The identity matrix is always a positive operator:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = identity_matrix(R, K.lattice_dim()) - sage: L.is_positive_operator_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron True The zero matrix is always a positive operator:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = zero_matrix(R, K.lattice_dim()) - sage: L.is_positive_operator_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron True Everything in ``K1.positive_operators_gens(K2)`` should be @@ -17100,11 +17100,10 @@ cdef class Matrix(Matrix1): the underlying ring symbolic (the usual case is tested by the ``positive_operators_gens`` method):: - sage: K1 = random_cone(max_ambient_dim=5) - sage: K2 = random_cone(max_ambient_dim=5) - sage: results = ( L.change_ring(SR).is_positive_operator_on(K1, K2) - ....: for L in K1.positive_operators_gens(K2) ) - sage: all(results) # long time + sage: K1 = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: K2 = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: all(L.change_ring(SR).is_positive_operator_on(K1, K2) # long time # optional - sage.geometry.polyhedron sage.symbolic + ....: for L in K1.positive_operators_gens(K2)) True Technically we could test this, but for now only closed convex cones @@ -17119,9 +17118,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(RR,3) - sage: L.is_positive_operator_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(RR, 3) + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17129,11 +17128,11 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR + sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(SCR, 3) - sage: L.is_positive_operator_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic + sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic True """ import sage.geometry.abc @@ -17211,38 +17210,38 @@ cdef class Matrix(Matrix1): Negative Z-matrices are cross-positive operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [-1, 2, 0], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, 2, 0], # optional - sage.symbolic ....: [ 0, 2, 7], ....: [ 3, 0, 3] ]) - sage: L.is_cross_positive_on(K) + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [-1, e, 0 ], + sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, e, 0 ], # optional - sage.symbolic ....: [ 0, 2, pi], ....: [ sqrt(2), 0, 3 ] ]) - sage: L.is_cross_positive_on(K) + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always cross-positive:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = identity_matrix(R, K.lattice_dim()) - sage: L.is_cross_positive_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron True The zero matrix is always cross-positive:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = zero_matrix(R, K.lattice_dim()) - sage: L.is_cross_positive_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron True Everything in ``K.cross_positive_operators_gens()`` should be @@ -17250,10 +17249,9 @@ cdef class Matrix(Matrix1): symbolic (the usual case is tested by the ``cross_positive_operators_gens`` method):: - sage: K = random_cone(max_ambient_dim=5) - sage: results = ( L.change_ring(SR).is_cross_positive_on(K) - ....: for L in K.cross_positive_operators_gens() ) - sage: all(results) # long time + sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: all(L.change_ring(SR).is_cross_positive_on(K) # long time # optional - sage.geometry.polyhedron sage.symbolic + ....: for L in K.cross_positive_operators_gens()) True Technically we could test this, but for now only closed convex cones @@ -17268,9 +17266,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(RR,3) - sage: L.is_cross_positive_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(RR, 3) + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17278,11 +17276,11 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR + sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(SCR, 3) - sage: L.is_cross_positive_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic + sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic True """ import sage.geometry.abc @@ -17349,46 +17347,46 @@ cdef class Matrix(Matrix1): Z-matrices are Z-operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [-1, -2, 0], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, -2, 0], # optional - sage.symbolic ....: [ 0, 2, -7], ....: [-3, 0, 3] ]) - sage: L.is_Z_operator_on(K) + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [-1, -e, 0 ], + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, -e, 0 ], # optional - sage.symbolic ....: [ 0, 2, -pi], ....: [-sqrt(2), 0, 3 ] ]) - sage: L.is_Z_operator_on(K) + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always a Z-operator:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = identity_matrix(R, K.lattice_dim()) - sage: L.is_Z_operator_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron True The zero matrix is always a Z-operator:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = zero_matrix(R, K.lattice_dim()) - sage: L.is_Z_operator_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron True Everything in ``K.Z_operators_gens()`` should be a Z-operator on ``K``, , even if we make the underlying ring symbolic (the usual case is tested by the ``Z_operators_gens`` method):: - sage: K = random_cone(max_ambient_dim=5) - sage: all(L.change_ring(SR).is_Z_operator_on(K) # long time + sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: all(L.change_ring(SR).is_Z_operator_on(K) # long time # optional - sage.geometry.polyhedron sage.symbolic ....: for L in K.Z_operators_gens()) True @@ -17404,9 +17402,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(RR,3) - sage: L.is_Z_operator_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(RR, 3) + sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17468,36 +17466,36 @@ cdef class Matrix(Matrix1): Diagonal matrices are Lyapunov-like operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = diagonal_matrix(random_vector(QQ,3)) - sage: L.is_lyapunov_like_on(K) + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = diagonal_matrix(random_vector(QQ, 3)) + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) - sage: L = matrix(SR, [ [e, 0, 0 ], + sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) # optional - sage.geometry.polyhedron + sage: L = matrix(SR, [ [e, 0, 0 ], # optional - sage.symbolic ....: [0, pi, 0 ], ....: [0, 0, sqrt(2)] ]) - sage: L.is_lyapunov_like_on(K) + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always Lyapunov-like:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = identity_matrix(R, K.lattice_dim()) - sage: L.is_lyapunov_like_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron True The zero matrix is always Lyapunov-like:: - sage: K = random_cone(max_ambient_dim=8) - sage: R = K.lattice().vector_space().base_ring() - sage: L = zero_matrix(R, K.lattice_dim()) - sage: L.is_lyapunov_like_on(K) + sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron True Everything in ``K.lyapunov_like_basis()`` should be @@ -17505,8 +17503,8 @@ cdef class Matrix(Matrix1): symbolic (the usual case is tested by the ``lyapunov_like_basis`` method):: - sage: K = random_cone(max_ambient_dim=5) - sage: all(L.change_ring(SR).is_lyapunov_like_on(K) # long time + sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: all(L.change_ring(SR).is_lyapunov_like_on(K) # long time # optional - sage.geometry.polyhedron sage.symbolic ....: for L in K.lyapunov_like_basis()) True @@ -17522,9 +17520,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(RR,3) - sage: L.is_lyapunov_like_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(RR, 3) + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17532,23 +17530,23 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR + sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) - sage: L = identity_matrix(SCR, 3) - sage: L.is_lyapunov_like_on(K) + sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic + sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron sage.symbolic True A matrix is Lyapunov-like on a cone if and only if both the matrix and its negation are cross-positive on the cone:: - sage: K = random_cone(max_ambient_dim=5) - sage: R = K.lattice().vector_space().base_ring() - sage: L = random_matrix(R, K.lattice_dim()) - sage: actual = L.is_lyapunov_like_on(K) # long time - sage: expected = (L.is_cross_positive_on(K) and # long time + sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron + sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron + sage: L = random_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron + sage: actual = L.is_lyapunov_like_on(K) # long time # optional - sage.geometry.polyhedron + sage: expected = (L.is_cross_positive_on(K) and # long time # optional - sage.geometry.polyhedron ....: (-L).is_cross_positive_on(K)) - sage: actual == expected # long time + sage: actual == expected # long time # optional - sage.geometry.polyhedron True """ import sage.geometry.abc @@ -17609,9 +17607,9 @@ cdef class Matrix(Matrix1): Create a Gram matrix and LLL-reduce it:: sage: M = Matrix(ZZ, 2, 2, [5, 3, 3, 2]) - sage: U = M.LLL_gram() - sage: MM = U.transpose() * M * U - sage: M, U, MM + sage: U = M.LLL_gram() # optional - sage.libs.pari + sage: MM = U.transpose() * M * U # optional - sage.libs.pari + sage: M, U, MM # optional - sage.libs.pari ( [5 3] [-1 1] [1 0] [3 2], [ 1 -2], [0 1] @@ -17623,28 +17621,28 @@ cdef class Matrix(Matrix1): preserve orientation). :: sage: M = Matrix(RDF, 2, 2, [1, 0, 0, 1e-5]) - sage: M.LLL_gram() + sage: M.LLL_gram() # optional - sage.libs.pari [ 0 -1] [ 1 0] The algorithm might work for some semidefinite and indefinite forms:: - sage: Matrix(ZZ, 2, 2, [2, 6, 6, 3]).LLL_gram() + sage: Matrix(ZZ, 2, 2, [2, 6, 6, 3]).LLL_gram() # optional - sage.libs.pari [-3 -1] [ 1 0] - sage: Matrix(ZZ, 2, 2, [1, 0, 0, -1]).LLL_gram() + sage: Matrix(ZZ, 2, 2, [1, 0, 0, -1]).LLL_gram() # optional - sage.libs.pari [ 0 -1] [ 1 0] However, it might fail for others, either raising a ``ValueError``:: - sage: Matrix(ZZ, 1, 1, [0]).LLL_gram() + sage: Matrix(ZZ, 1, 1, [0]).LLL_gram() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram did not return a square matrix, perhaps the matrix is not positive definite - sage: Matrix(ZZ, 2, 2, [0, 1, 1, 0]).LLL_gram() + sage: Matrix(ZZ, 2, 2, [0, 1, 1, 0]).LLL_gram() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram did not return a square matrix, @@ -17652,14 +17650,14 @@ cdef class Matrix(Matrix1): or running forever:: - sage: Matrix(ZZ, 2, 2, [-5, -1, -1, -5]).LLL_gram() # not tested + sage: Matrix(ZZ, 2, 2, [-5, -1, -1, -5]).LLL_gram() # not tested # optional - sage.libs.pari Traceback (most recent call last): ... RuntimeError: infinite loop while calling qflllgram Nonreal input leads to a value error:: - sage: Matrix(2, 2, [CDF(1, 1), 0, 0, 1]).LLL_gram() + sage: Matrix(2, 2, [CDF(1, 1), 0, 0, 1]).LLL_gram() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram failed, perhaps the matrix is not positive definite @@ -18145,27 +18143,27 @@ def _matrix_power_symbolic(A, n): General power of a two by two matrix:: - sage: n = SR.var('n') + sage: n = SR.var('n') # optional - sage.symbolic sage: A = matrix(QQ, [[2, -1], [1, 0]]) - sage: B = A^n; B + sage: B = A^n; B # optional - sage.symbolic [ n + 1 -n] [ n -n + 1] - sage: all(A^k == B.subs({n: k}) for k in range(8)) + sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic True General power of a three by three matrix in Jordan form:: - sage: n = SR.var('n') + sage: n = SR.var('n') # optional - sage.symbolic sage: A = matrix(QQ, 3, [[2, 1, 0], [0, 2, 0], [0, 0, 3]]) sage: A [2 1 0] [0 2 0] [0 0 3] - sage: B = A^n; B + sage: B = A^n; B # optional - sage.symbolic [ 2^n 2^(n - 1)*n 0] [ 0 2^n 0] [ 0 0 3^n] - sage: all(A^k == B.subs({n: k}) for k in range(8)) + sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic True General power of a three by three matrix not in Jordan form:: @@ -18175,26 +18173,26 @@ def _matrix_power_symbolic(A, n): [ 4 1 2] [ 0 2 -4] [ 0 1 6] - sage: B = A^n; B + sage: B = A^n; B # optional - sage.symbolic [ 4^n 4^(n - 1)*n 2*4^(n - 1)*n] [ 0 -2*4^(n - 1)*n + 4^n -4*4^(n - 1)*n] [ 0 4^(n - 1)*n 2*4^(n - 1)*n + 4^n] - sage: [B.subs({n: k}) for k in range(4)] + sage: [B.subs({n: k}) for k in range(4)] # optional - sage.symbolic [ [1 0 0] [ 4 1 2] [ 16 8 16] [ 64 48 96] [0 1 0] [ 0 2 -4] [ 0 0 -32] [ 0 -32 -192] [0 0 1], [ 0 1 6], [ 0 8 32], [ 0 48 160] ] - sage: all(A^k == B.subs({n: k}) for k in range(8)) + sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic True TESTS: Testing exponentiation in the symbolic ring:: - sage: n = var('n') - sage: A = matrix([[pi, e],[0, -2*I]]) - sage: (A^n).list() + sage: n = var('n') # optional - sage.symbolic + sage: A = matrix([[pi, e],[0, -2*I]]) # optional - sage.symbolic + sage: (A^n).list() # optional - sage.symbolic [pi^n, -(-2*I)^n/(pi*e^(-1) + 2*I*e^(-1)) + pi^n/(pi*e^(-1) + 2*I*e^(-1)), 0, @@ -18217,8 +18215,8 @@ def _matrix_power_symbolic(A, n): Check if :trac:`23215` is fixed:: - sage: a, b, k = var('a, b, k') - sage: (matrix(2, [a, b, -b, a])^k).list() + sage: a, b, k = var('a, b, k') # optional - sage.symbolic + sage: (matrix(2, [a, b, -b, a])^k).list() # optional - sage.symbolic [1/2*(a + I*b)^k + 1/2*(a - I*b)^k, -1/2*I*(a + I*b)^k + 1/2*I*(a - I*b)^k, 1/2*I*(a + I*b)^k - 1/2*I*(a - I*b)^k, diff --git a/src/sage/matrix/matrix_cdv.pyx b/src/sage/matrix/matrix_cdv.pyx index 43421c74cb9..85347031d3b 100644 --- a/src/sage/matrix/matrix_cdv.pyx +++ b/src/sage/matrix/matrix_cdv.pyx @@ -35,29 +35,29 @@ cpdef hessenbergize_cdvf(Matrix_generic_dense H): TESTS:: - sage: K = Qp(5, print_mode="digits", prec=5) - sage: H = matrix(K, 3, 3, range(9)) - sage: H + sage: K = Qp(5, print_mode="digits", prec=5) # optional - sage.rings.padics + sage: H = matrix(K, 3, 3, range(9)) # optional - sage.rings.padics + sage: H # optional - sage.rings.padics [ 0 ...00001 ...00002] [ ...00003 ...00004 ...000010] [ ...00011 ...00012 ...00013] - sage: H.hessenbergize() - sage: H + sage: H.hessenbergize() # optional - sage.rings.padics + sage: H # optional - sage.rings.padics [ 0 ...00010 ...00002] [ ...00003 ...00024 ...000010] [ ...00000 ...44440 ...44443] :: - sage: M = random_matrix(K, 6, 6) - sage: M.charpoly()[0] == M.determinant() + sage: M = random_matrix(K, 6, 6) # optional - sage.rings.padics + sage: M.charpoly()[0] == M.determinant() # optional - sage.rings.padics True We check that :trac:`31753` is resolved:: - sage: R. = GF(5)[[]] + sage: R. = GF(5)[[]] # optional - sage.libs.pari sage: M = matrix(3, 3, [ 1, t + O(t^3), t^2, 1 + t + O(t^3), 2 + t^2, 3 + 2*t + O(t^3), t - t^2, 2*t, 1 + t ]) - sage: M.charpoly() + sage: M.charpoly() # optional - sage.libs.pari x^3 + (1 + 4*t + 4*t^2 + O(t^3))*x^2 + (t + 2*t^2 + O(t^3))*x + 3 + 2*t^2 + O(t^3) """ cdef Py_ssize_t n, i, j, k diff --git a/src/sage/matrix/matrix_dense.pyx b/src/sage/matrix/matrix_dense.pyx index 164846caba1..e76047c2f0a 100644 --- a/src/sage/matrix/matrix_dense.pyx +++ b/src/sage/matrix/matrix_dense.pyx @@ -74,11 +74,11 @@ cdef class Matrix_dense(matrix.Matrix): Check :trac:`27629`:: - sage: var('x') + sage: var('x') # optional - sage.symbolic x - sage: assume(x, 'real') - sage: M = matrix([[0, -x], [x, 0]]) - sage: M.transpose() == M + sage: assume(x, 'real') # optional - sage.symbolic + sage: M = matrix([[0, -x], [x, 0]]) # optional - sage.symbolic + sage: M.transpose() == M # optional - sage.symbolic False """ other = right @@ -270,8 +270,8 @@ cdef class Matrix_dense(matrix.Matrix): EXAMPLES:: - sage: m = matrix(2, [x^i for i in range(4)]) - sage: m._derivative(x) + sage: m = matrix(2, [x^i for i in range(4)]) # optional - sage.symbolic + sage: m._derivative(x) # optional - sage.symbolic [ 0 1] [ 2*x 3*x^2] """ diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 7671e745458..92723218ae5 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -495,7 +495,7 @@ class MatrixSpace(UniqueRepresentation, Parent): Check that different implementations play together as expected:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') sage: type(M1(range(4))) @@ -539,13 +539,13 @@ def __classcall__(cls, base_ring, nrows, ncols=None, sparse=False, implementatio sage: M1 = MatrixSpace(QQ, 2) sage: M2 = MatrixSpace(QQ, 2) - sage: M3 = MatrixSpace(QQ, 2, implementation='flint') + sage: M3 = MatrixSpace(QQ, 2, implementation='flint') # optional - sage.libs.flint sage: M1 is M2 and M1 is M3 True :: - sage: M = MatrixSpace(ZZ, 10, implementation="flint") + sage: M = MatrixSpace(ZZ, 10, implementation="flint") # optional - sage.libs.flint sage: M Full MatrixSpace of 10 by 10 dense matrices over Integer Ring sage: loads(M.dumps()) is M @@ -842,7 +842,7 @@ def _element_constructor_(self, entries, **kwds): EXAMPLES:: - sage: k = GF(7) + sage: k = GF(7) # optional - sage.libs.pari sage: G = MatrixGroup([matrix(k, 2, [1,1,0,1]), matrix(k, 2, [1,0,0,2])]) # optional - sage.libs.pari sage: g = G.0 # optional - sage.libs.pari sage: MatrixSpace(k, 2)(g) # optional - sage.libs.pari @@ -1288,7 +1288,7 @@ def _repr_(self): sage: MS Full MatrixSpace of 2 by 4 sparse matrices over Integer Ring - sage: MatrixSpace(ZZ, 2, implementation='flint') + sage: MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint Full MatrixSpace of 2 by 2 dense matrices over Integer Ring sage: MatrixSpace(ZZ, 2, implementation='generic') Full MatrixSpace of 2 by 2 dense matrices over Integer Ring (using Matrix_generic_dense) @@ -1804,10 +1804,10 @@ def identity_matrix(self): Check different implementations:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1.identity_matrix()) + sage: type(M1.identity_matrix()) # optional - sage.libs.flint sage: type(M2.identity_matrix()) @@ -2340,8 +2340,8 @@ def some_elements(self): [ 1/2 -1/2 2] [1 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0] [0 0 0] [ -2 0 1], [0 0 0], [0 0 0], [0 0 0], [1 0 0], [0 1 0], [0 0 1] ) - sage: M = MatrixSpace(SR, 2, 2) - sage: tuple(M.some_elements()) + sage: M = MatrixSpace(SR, 2, 2) # optional - sage.symbolic + sage: tuple(M.some_elements()) # optional - sage.symbolic ( [some_variable some_variable] [1 0] [0 1] [0 0] [0 0] [some_variable some_variable], [0 0], [0 0], [1 0], [0 1] @@ -2483,23 +2483,23 @@ def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, check sage: from sage.matrix.matrix_space import _test_trivial_matrices_inverse as tinv sage: tinv(ZZ, sparse=True) - sage: tinv(ZZ, sparse=False, implementation='flint') + sage: tinv(ZZ, sparse=False, implementation='flint') # optional - sage.libs.flint sage: tinv(ZZ, sparse=False, implementation='generic') sage: tinv(QQ, sparse=True) - sage: tinv(QQ, sparse=False, implementation='flint') + sage: tinv(QQ, sparse=False, implementation='flint') # optional - sage.libs.flint sage: tinv(QQ, sparse=False, implementation='generic') - sage: tinv(GF(11), sparse=True) # optional - sage.libs.pari - sage: tinv(GF(11), sparse=False) # optional - sage.libs.pari - sage: tinv(GF(2), sparse=True) # optional - sage.libs.pari - sage: tinv(GF(2), sparse=False) # optional - sage.libs.pari - sage: tinv(SR, sparse=True) - sage: tinv(SR, sparse=False) + sage: tinv(GF(11), sparse=True) # optional - sage.libs.pari + sage: tinv(GF(11), sparse=False) # optional - sage.libs.pari + sage: tinv(GF(2), sparse=True) # optional - sage.libs.pari + sage: tinv(GF(2), sparse=False) # optional - sage.libs.pari + sage: tinv(SR, sparse=True) # optional - sage.symbolic + sage: tinv(SR, sparse=False) # optional - sage.symbolic sage: tinv(RDF, sparse=True) sage: tinv(RDF, sparse=False) sage: tinv(CDF, sparse=True) sage: tinv(CDF, sparse=False) - sage: tinv(CyclotomicField(7), sparse=True) # optional - sage.rings.number_field - sage: tinv(CyclotomicField(7), sparse=False) # optional - sage.rings.number_field + sage: tinv(CyclotomicField(7), sparse=True) # optional - sage.rings.number_field + sage: tinv(CyclotomicField(7), sparse=False) # optional - sage.rings.number_field sage: tinv(QQ['x,y'], sparse=True) sage: tinv(QQ['x,y'], sparse=False) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index def5795d1ee..e1c9b43fc70 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -809,7 +809,7 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: - sage: m = matrix(2, [x^i for i in range(4)], sparse=True) + sage: m = matrix(2, [x^i for i in range(4)], sparse=True) # optional - sage.symbolic sage: m._derivative(x) [ 0 1] [ 2*x 3*x^2] diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index b97ddd38d55..0d19218849d 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -388,9 +388,9 @@ def __init__(self, S, operation, names='letters', elements=None): TESTS:: sage: from sage.matrix.operation_table import OperationTable - sage: G=SymmetricGroup(3) - sage: T=OperationTable(G, operator.mul) - sage: TestSuite(T).run() + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: T = OperationTable(G, operator.mul) # optional - sage.groups + sage: TestSuite(T).run() # optional - sage.groups """ # Determine the elements of S, specified or not # If elements are given, we check if they are all in S diff --git a/src/sage/matrix/tests.py b/src/sage/matrix/tests.py index a42935d0e70..f4ed51c68b6 100644 --- a/src/sage/matrix/tests.py +++ b/src/sage/matrix/tests.py @@ -45,7 +45,7 @@ sage: matrix(QQ, 2, 2, [1, 1, 1, 1]) / (1/2) [2 2] [2 2] - sage: matrix(QQ['x,y'], 2, 2, [1, 1, 1, 1]) / x + sage: matrix(QQ['x,y'], 2, 2, [1, 1, 1, 1]) / x # optional - sage.symbolic [1/x 1/x] [1/x 1/x] sage: A = matrix(CC, 2, 2, [1, 1, 1, 1]) / I; A diff --git a/src/sage/modules/finite_submodule_iter.pyx b/src/sage/modules/finite_submodule_iter.pyx index eb433546f23..babfbdf7dbc 100644 --- a/src/sage/modules/finite_submodule_iter.pyx +++ b/src/sage/modules/finite_submodule_iter.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari r""" Iterators over finite submodules of a `\ZZ`-module diff --git a/src/sage/modules/fp_graded/element.py b/src/sage/modules/fp_graded/element.py index e4f288f3264..a4055b3e3b5 100755 --- a/src/sage/modules/fp_graded/element.py +++ b/src/sage/modules/fp_graded/element.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Elements of finitely presented graded modules diff --git a/src/sage/modules/fp_graded/free_module.py b/src/sage/modules/fp_graded/free_module.py index 3f87d6b9c6f..cb1caa3581c 100755 --- a/src/sage/modules/fp_graded/free_module.py +++ b/src/sage/modules/fp_graded/free_module.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Finitely generated free graded left modules over connected graded algebras diff --git a/src/sage/modules/fp_graded/homspace.py b/src/sage/modules/fp_graded/homspace.py index 08e30a17dba..985cb1d727b 100755 --- a/src/sage/modules/fp_graded/homspace.py +++ b/src/sage/modules/fp_graded/homspace.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Homsets of finitely presented graded modules diff --git a/src/sage/modules/fp_graded/module.py b/src/sage/modules/fp_graded/module.py index 914a4ad1dc1..a61f1d08d49 100755 --- a/src/sage/modules/fp_graded/module.py +++ b/src/sage/modules/fp_graded/module.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Finitely presented graded modules diff --git a/src/sage/modules/fp_graded/morphism.py b/src/sage/modules/fp_graded/morphism.py index fde00303230..75eacd961e7 100755 --- a/src/sage/modules/fp_graded/morphism.py +++ b/src/sage/modules/fp_graded/morphism.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Homomorphisms of finitely presented graded modules diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index c6ec33ad5d0..64f69204fe5 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -25,10 +25,10 @@ Basis matrix: [ 1 0 -7] [ 0 1 7] - sage: C = VectorSpaces(FiniteField(7)) - sage: C + sage: C = VectorSpaces(FiniteField(7)) # optional - sage.libs.pari + sage: C # optional - sage.libs.pari Category of vector spaces over Finite Field of size 7 - sage: C(W) + sage: C(W) # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 0] @@ -37,11 +37,11 @@ :: sage: M = ZZ^3 - sage: C = VectorSpaces(FiniteField(7)) - sage: C(M) + sage: C = VectorSpaces(FiniteField(7)) # optional - sage.libs.pari + sage: C(M) # optional - sage.libs.pari Vector space of dimension 3 over Finite Field of size 7 - sage: W = M.submodule([[1,2,7], [8,8,0]]) - sage: C(W) + sage: W = M.submodule([[1,2,7], [8,8,0]]) # optional - sage.libs.pari + sage: C(W) # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 0] @@ -613,8 +613,9 @@ def span(gens, base_ring=None, check=True, already_echelonized=False): [ 1 0 -3] [ 0 1 4] - sage: span([V.gen(0)], QuadraticField(-7,'a')) - Vector space of degree 3 and dimension 1 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + sage: span([V.gen(0)], QuadraticField(-7,'a')) # optional - sage.rings.number_field + Vector space of degree 3 and dimension 1 over Number Field in a + with defining polynomial x^2 + 7 with a = 2.645751311064591?*I Basis matrix: [ 1 0 -3] @@ -1013,8 +1014,8 @@ def some_elements(self): ... (46/103823, -46/103823, 103823/46)) - sage: F = FreeModule(SR, 2) - sage: tuple(F.some_elements()) + sage: F = FreeModule(SR, 2) # optional - sage.symbolic + sage: tuple(F.some_elements()) # optional - sage.symbolic ((1, 0), (some_variable, some_variable)) """ yield self.an_element() @@ -2465,15 +2466,15 @@ def cardinality(self): EXAMPLES:: - sage: k. = FiniteField(9) - sage: V = VectorSpace(k,3) - sage: V.cardinality() + sage: k. = FiniteField(9) # optional - sage.libs.pari + sage: V = VectorSpace(k, 3) # optional - sage.libs.pari + sage: V.cardinality() # optional - sage.libs.pari 729 - sage: W = V.span([[1,2,1],[0,1,1]]) - sage: W.cardinality() + sage: W = V.span([[1,2,1], [0,1,1]]) # optional - sage.libs.pari + sage: W.cardinality() # optional - sage.libs.pari 81 sage: R = IntegerModRing(12) - sage: M = FreeModule(R,2) + sage: M = FreeModule(R, 2) sage: M.cardinality() 144 sage: (QQ^3).cardinality() @@ -2809,9 +2810,9 @@ def dimension(self): EXAMPLES:: - sage: M = FreeModule(FiniteField(19), 100) - sage: W = M.submodule([M.gen(50)]) - sage: W.dimension() + sage: M = FreeModule(FiniteField(19), 100) # optional - sage.libs.pari + sage: W = M.submodule([M.gen(50)]) # optional - sage.libs.pari + sage: W.dimension() # optional - sage.libs.pari 1 """ return self.rank() @@ -4303,7 +4304,7 @@ def __init__(self, base_field, dimension, degree, sparse=False, category=None): sage: FreeModule(QQ, 2) Vector space of dimension 2 over Rational Field - sage: FreeModule(FiniteField(2), 7) + sage: FreeModule(FiniteField(2), 7) # optional - sage.libs.pari Vector space of dimension 7 over Finite Field of size 2 We test that objects of this type are initialised correctly; @@ -4985,23 +4986,23 @@ def linear_dependence(self, vectors, zeros='left', check=True): linearly independent vectors and add in two linear combinations to make a linearly dependent set of five vectors. :: - sage: F = FiniteField(17) - sage: v1 = vector(F, [1, 2, 3, 4, 5]) - sage: v2 = vector(F, [2, 4, 8, 16, 15]) - sage: v3 = vector(F, [1, 0, 0, 0, 1]) - sage: (F^5).linear_dependence([v1, v2, v3]) == [] + sage: F = FiniteField(17) # optional - sage.libs.pari + sage: v1 = vector(F, [1, 2, 3, 4, 5]) # optional - sage.libs.pari + sage: v2 = vector(F, [2, 4, 8, 16, 15]) # optional - sage.libs.pari + sage: v3 = vector(F, [1, 0, 0, 0, 1]) # optional - sage.libs.pari + sage: (F^5).linear_dependence([v1, v2, v3]) == [] # optional - sage.libs.pari True - sage: L = [v1, v2, v3, 2*v1+v2, 3*v2+6*v3] - sage: (F^5).linear_dependence(L) + sage: L = [v1, v2, v3, 2*v1+v2, 3*v2+6*v3] # optional - sage.libs.pari + sage: (F^5).linear_dependence(L) # optional - sage.libs.pari [ (1, 0, 16, 8, 3), (0, 1, 2, 0, 11) ] - sage: v1 + 16*v3 + 8*(2*v1+v2) + 3*(3*v2+6*v3) + sage: v1 + 16*v3 + 8*(2*v1+v2) + 3*(3*v2+6*v3) # optional - sage.libs.pari (0, 0, 0, 0, 0) - sage: v2 + 2*v3 + 11*(3*v2+6*v3) + sage: v2 + 2*v3 + 11*(3*v2+6*v3) # optional - sage.libs.pari (0, 0, 0, 0, 0) - sage: (F^5).linear_dependence(L, zeros='right') + sage: (F^5).linear_dependence(L, zeros='right') # optional - sage.libs.pari [ (15, 16, 0, 1, 0), (0, 14, 11, 0, 1) @@ -5970,9 +5971,9 @@ def _sympy_(self): EXAMPLES:: - sage: sZZ3 = (ZZ^3)._sympy_(); sZZ3 + sage: sZZ3 = (ZZ^3)._sympy_(); sZZ3 # optional - sympy ProductSet(Integers, Integers, Integers) - sage: (1, 2, 3) in sZZ3 + sage: (1, 2, 3) in sZZ3 # optional - sympy True """ from sympy import ProductSet @@ -6465,8 +6466,8 @@ def __init__(self, ambient, basis, check=True, :trac:`10250` is solved as well:: sage: V = (QQ^2).span_of_basis([[1,1]]) - sage: w = sqrt(2) * V([1,1]) - sage: 3 * w + sage: w = sqrt(2) * V([1,1]) # optional - sage.symbolic + sage: 3 * w # optional - sage.symbolic (3*sqrt(2), 3*sqrt(2)) TESTS: @@ -6686,9 +6687,9 @@ def _echelonized_basis(self, ambient, basis): sage: W = V.submodule_with_basis([[1,1,0],[0,2,1]]) sage: W._echelonized_basis(V,W.basis()) [(1, 0, -1/2), (0, 1, 1/2)] - sage: V = SR^3 - sage: W = V.submodule_with_basis([[1,0,1]]) - sage: W._echelonized_basis(V,W.basis()) + sage: V = SR^3 # optional - sage.symbolic + sage: W = V.submodule_with_basis([[1,0,1]]) # optional - sage.symbolic + sage: W._echelonized_basis(V, W.basis()) # optional - sage.symbolic [(1, 0, 1)] """ # Return the first rank rows (i.e., the nonzero rows). @@ -8141,8 +8142,8 @@ def element_class(R, is_sparse): EXAMPLES:: - sage: FF = FiniteField(2) - sage: P = PolynomialRing(FF,'x') + sage: FF = FiniteField(2) # optional - sage.libs.pari + sage: P = PolynomialRing(FF,'x') # optional - sage.libs.pari sage: sage.modules.free_module.element_class(QQ, is_sparse=True) sage: sage.modules.free_module.element_class(QQ, is_sparse=False) @@ -8151,15 +8152,15 @@ def element_class(R, is_sparse): sage: sage.modules.free_module.element_class(ZZ, is_sparse=False) - sage: sage.modules.free_module.element_class(FF, is_sparse=True) + sage: sage.modules.free_module.element_class(FF, is_sparse=True) # optional - sage.libs.pari - sage: sage.modules.free_module.element_class(FF, is_sparse=False) + sage: sage.modules.free_module.element_class(FF, is_sparse=False) # optional - sage.libs.pari sage: sage.modules.free_module.element_class(GF(7), is_sparse=False) # optional - sage.libs.pari - sage: sage.modules.free_module.element_class(P, is_sparse=True) + sage: sage.modules.free_module.element_class(P, is_sparse=True) # optional - sage.libs.pari - sage: sage.modules.free_module.element_class(P, is_sparse=False) + sage: sage.modules.free_module.element_class(P, is_sparse=False) # optional - sage.libs.pari """ import sage.rings.integer_ring @@ -8170,14 +8171,21 @@ def element_class(R, is_sparse): from .vector_rational_dense import Vector_rational_dense return Vector_rational_dense elif isinstance(R, sage.rings.abc.IntegerModRing) and not is_sparse: - from .vector_mod2_dense import Vector_mod2_dense if R.order() == 2: - return Vector_mod2_dense - from .vector_modn_dense import Vector_modn_dense, MAX_MODULUS - if R.order() < MAX_MODULUS: - return Vector_modn_dense + try: + from .vector_mod2_dense import Vector_mod2_dense + except ImportError: + pass + else: + return Vector_mod2_dense + try: + from .vector_modn_dense import Vector_modn_dense, MAX_MODULUS + except ImportError: + pass else: - return free_module_element.FreeModuleElement_generic_dense + if R.order() < MAX_MODULUS: + return Vector_modn_dense + return free_module_element.FreeModuleElement_generic_dense elif isinstance(R, sage.rings.abc.RealDoubleField) and not is_sparse: try: from sage.modules.vector_real_double_dense import Vector_real_double_dense diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 05e3d2be8df..26d0e9ba67a 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -973,15 +973,15 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(range(4)) - sage: v.__pari__() + sage: v.__pari__() # optional - sage.libs.pari [0, 1, 2, 3] - sage: v.__pari__().type() + sage: v.__pari__().type() # optional - sage.libs.pari 't_VEC' A list of vectors:: sage: L = [vector(i^n for i in range(4)) for n in [1,3,5]] - sage: pari(L) + sage: pari(L) # optional - sage.libs.pari [[0, 1, 2, 3], [0, 1, 8, 27], [0, 1, 32, 243]] """ from sage.libs.pari.all import pari @@ -999,7 +999,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(range(4)) - sage: v._pari_init_() + sage: v._pari_init_() # optional - sage.libs.pari '[0,1,2,3]' Create the multiplication table of `GF(4)` using GP:: @@ -1133,13 +1133,13 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) - sage: v.__hash__() + sage: v = vector([1,2/3,pi]) # optional - sage.symbolic + sage: v.__hash__() # optional - sage.symbolic Traceback (most recent call last): ... TypeError: mutable vectors are unhashable - sage: v.set_immutable() - sage: v.__hash__() # random output + sage: v.set_immutable() # optional - sage.symbolic + sage: v.__hash__() # random output # optional - sage.symbolic """ if not self._is_immutable: raise TypeError("mutable vectors are unhashable") @@ -1381,10 +1381,10 @@ cdef class FreeModuleElement(Vector): # abstract base class then taking a transpose. Notice that supplying a vector to the matrix constructor demonstrates Sage's preference for rows. :: - sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) - sage: x.row() == matrix(x) + sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # optional - sage.symbolic + sage: x.row() == matrix(x) # optional - sage.symbolic True - sage: x.row() == x.column().transpose() + sage: x.row() == x.column().transpose() # optional - sage.symbolic True Sparse or dense implementations are preserved. :: @@ -1453,10 +1453,10 @@ cdef class FreeModuleElement(Vector): # abstract base class then taking a transpose. Notice that supplying a vector to the matrix constructor demonstrates Sage's preference for rows. :: - sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) - sage: x.column() == matrix(x).transpose() + sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # optional - sage.libs.pari + sage: x.column() == matrix(x).transpose() # optional - sage.libs.pari True - sage: x.column() == x.row().transpose() + sage: x.column() == x.row().transpose() # optional - sage.libs.pari True Sparse or dense implementations are preserved. :: @@ -1523,12 +1523,12 @@ cdef class FreeModuleElement(Vector): # abstract base class """ EXAMPLES:: - sage: var('a,b,d,e') + sage: var('a,b,d,e') # optional - sage.symbolic (a, b, d, e) - sage: v = vector([a, b, d, e]) - sage: v.substitute(a=1) + sage: v = vector([a, b, d, e]) # optional - sage.symbolic + sage: v.substitute(a=1) # optional - sage.symbolic (1, b, d, e) - sage: v.subs(a=b, b=d) + sage: v.subs(a=b, b=d) # optional - sage.symbolic (b, d, d, e) """ return self.parent()([ a.subs(in_dict, **kwds) for a in self.list() ]) @@ -1616,17 +1616,17 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) - sage: v.items() + sage: v = vector([1,2/3,pi]) # optional - sage.symbolic + sage: v.items() # optional - sage.symbolic - sage: list(v.items()) + sage: list(v.items()) # optional - sage.symbolic [(0, 1), (1, 2/3), (2, pi)] TESTS: Using iteritems as an alias:: - sage: list(v.iteritems()) + sage: list(v.iteritems()) # optional - sage.symbolic [(0, 1), (1, 2/3), (2, pi)] """ cdef dict d = self.dict(copy=False) @@ -1641,7 +1641,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1..5]); abs(v) + sage: v = vector([1..5]); abs(v) # optional - sage.symbolic sqrt(55) sage: v = vector(RDF, [1..5]); abs(v) 7.416198487095663 @@ -1668,14 +1668,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector([1,2,-3]) - sage: v.norm(5) + sage: v.norm(5) # optional - sage.symbolic 276^(1/5) The default is the usual Euclidean norm. :: - sage: v.norm() + sage: v.norm() # optional - sage.symbolic sqrt(14) - sage: v.norm(2) + sage: v.norm(2) # optional - sage.symbolic sqrt(14) The infinity norm is the maximum size (in absolute value) @@ -1691,10 +1691,10 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v=vector(RDF,[1,2,3]) sage: v.norm(5) 3.077384885394063 - sage: v.norm(pi/2) #abs tol 1e-15 + sage: v.norm(pi/2) #abs tol 1e-15 # optional - sage.symbolic 4.216595864704748 - sage: _=var('a b c d p'); v=vector([a, b, c, d]) - sage: v.norm(p) + sage: _=var('a b c d p'); v=vector([a, b, c, d]) # optional - sage.symbolic + sage: v.norm(p) # optional - sage.symbolic (abs(a)^p + abs(b)^p + abs(c)^p + abs(d)^p)^(1/p) Notice that the result may be a symbolic expression, owing to @@ -1708,13 +1708,13 @@ cdef class FreeModuleElement(Vector): # abstract base class Rational Field sage: v = vector(QQ, [3, 5]) - sage: nrm = v.norm(); nrm + sage: nrm = v.norm(); nrm # optional - sage.symbolic sqrt(34) - sage: nrm.parent() + sage: nrm.parent() # optional - sage.symbolic Symbolic Ring - sage: numeric = N(nrm); numeric + sage: numeric = N(nrm); numeric # optional - sage.symbolic 5.83095189484... - sage: numeric.parent() + sage: numeric.parent() # optional - sage.symbolic Real Field with 53 bits of precision TESTS: @@ -1731,7 +1731,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Norm works with Python integers (see :trac:`13502`). :: sage: v = vector(QQ, [1,2]) - sage: v.norm(int(2)) + sage: v.norm(int(2)) # optional - sage.symbolic sqrt(5) """ abs_self = [abs(x) for x in self] @@ -1747,17 +1747,17 @@ cdef class FreeModuleElement(Vector): # abstract base class """ EXAMPLES:: - sage: v = vector(SR, [0,0,0,0]) - sage: v == 0 + sage: v = vector(SR, [0,0,0,0]) # optional - sage.symbolic + sage: v == 0 # optional - sage.symbolic True - sage: v == 1 + sage: v == 1 # optional - sage.symbolic False - sage: v == v + sage: v == v # optional - sage.symbolic True - sage: w = vector(SR, [-1,x,pi,0]) - sage: bool(w < v) + sage: w = vector(SR, [-1,x,pi,0]) # optional - sage.symbolic + sage: bool(w < v) # optional - sage.symbolic True - sage: bool(w > v) + sage: bool(w > v) # optional - sage.symbolic False TESTS:: @@ -1772,14 +1772,14 @@ cdef class FreeModuleElement(Vector): # abstract base class Verify that :trac:`33697` is fixed:: - sage: v = vector(SR, [x]) - sage: w = vector(SR, [1]) - sage: v == w + sage: v = vector(SR, [x]) # optional - sage.symbolic + sage: w = vector(SR, [1]) # optional - sage.symbolic + sage: v == w # optional - sage.symbolic False - sage: assume(x > 0) - sage: v == w + sage: assume(x > 0) # optional - sage.symbolic + sage: v == w # optional - sage.symbolic False - sage: forget() + sage: forget() # optional - sage.symbolic """ cdef Py_ssize_t i for i in range(left._degree): @@ -1836,7 +1836,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector(SR, [1/2,2/5,0]).get(0) + sage: vector(SR, [1/2,2/5,0]).get(0) # optional - sage.symbolic 1/2 """ return self.get_unsafe(i) @@ -1899,9 +1899,9 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector(SR, [1/2,2/5,0]); v + sage: v = vector(SR, [1/2,2/5,0]); v # optional - sage.symbolic (1/2, 2/5, 0) - sage: v.set(2, pi); v + sage: v.set(2, pi); v # optional - sage.symbolic (1/2, 2/5, pi) """ assert value.parent() is self.coordinate_ring() @@ -1914,7 +1914,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector([1,2/3,pi]).__invert__() + sage: vector([1,2/3,pi]).__invert__() # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError @@ -1996,8 +1996,8 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) - sage: v.list_from_positions([0,0,0,2,1]) + sage: v = vector([1,2/3,pi]) # optional - sage.symbolic + sage: v.list_from_positions([0,0,0,2,1]) # optional - sage.symbolic [1, 1, 1, pi, 2/3] """ cdef Py_ssize_t i @@ -2111,10 +2111,10 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: x = var('x') - sage: v = vector([x/(2*x)+sqrt(2)+var('theta')^3,x/(2*x)]); v + sage: x = var('x') # optional - sage.symbolic + sage: v = vector([x/(2*x)+sqrt(2)+var('theta')^3,x/(2*x)]); v # optional - sage.symbolic (theta^3 + sqrt(2) + 1/2, 1/2) - sage: v._repr_() + sage: v._repr_() # optional - sage.symbolic '(theta^3 + sqrt(2) + 1/2, 1/2)' """ cdef Py_ssize_t d = self._degree @@ -2288,84 +2288,84 @@ cdef class FreeModuleElement(Vector): # abstract base class The following both plot the given vector:: sage: v = vector(RDF, (1,2)) - sage: A = plot(v) - sage: B = v.plot() - sage: A+B # should just show one vector + sage: A = plot(v) # optional - sage.plot + sage: B = v.plot() # optional - sage.plot + sage: A+B # should just show one vector # optional - sage.plot Graphics object consisting of 2 graphics primitives Examples of the plot types:: - sage: A = plot(v, plot_type='arrow') - sage: B = plot(v, plot_type='point', color='green', size=20) - sage: C = plot(v, plot_type='step') # calls v.plot_step() - sage: A+B+C + sage: A = plot(v, plot_type='arrow') # optional - sage.plot + sage: B = plot(v, plot_type='point', color='green', size=20) # optional - sage.plot + sage: C = plot(v, plot_type='step') # calls v.plot_step() # optional - sage.plot + sage: A+B+C # optional - sage.plot Graphics object consisting of 3 graphics primitives You can use the optional arguments for :meth:`plot_step`:: - sage: eps = 0.1 - sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) + sage: eps = 0.1 # optional - sage.plot + sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive Three-dimensional examples:: sage: v = vector(RDF, (1,2,1)) - sage: plot(v) # defaults to an arrow plot + sage: plot(v) # defaults to an arrow plot # optional - sage.plot Graphics3d Object :: - sage: plot(v, plot_type='arrow') + sage: plot(v, plot_type='arrow') # optional - sage.plot Graphics3d Object :: - sage: from sage.plot.plot3d.shapes2 import frame3d - sage: plot(v, plot_type='point')+frame3d((0,0,0), v.list()) + sage: from sage.plot.plot3d.shapes2 import frame3d # optional - sage.plot + sage: plot(v, plot_type='point')+frame3d((0,0,0), v.list()) # optional - sage.plot Graphics3d Object :: - sage: plot(v, plot_type='step') # calls v.plot_step() + sage: plot(v, plot_type='step') # calls v.plot_step() # optional - sage.plot Graphics object consisting of 1 graphics primitive :: - sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) + sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive With greater than three coordinates, it defaults to a step plot:: sage: v = vector(RDF, (1,2,3,4)) - sage: plot(v) + sage: plot(v) # optional - sage.plot Graphics object consisting of 1 graphics primitive One dimensional vectors are plotted along the horizontal axis of the coordinate plane:: - sage: plot(vector([1])) + sage: plot(vector([1])) # optional - sage.plot Graphics object consisting of 1 graphics primitive An optional start argument may also be specified by a tuple, list, or vector:: sage: u = vector([1,2]); v = vector([2,5]) - sage: plot(u, start=v) + sage: plot(u, start=v) # optional - sage.plot Graphics object consisting of 1 graphics primitive TESTS:: - sage: u = vector([1,1]); v = vector([2,2,2]); z=(3,3,3) - sage: plot(u) #test when start=None + sage: u = vector([1,1]); v = vector([2,2,2]); z=(3,3,3) # optional - sage.plot + sage: plot(u) #test when start=None # optional - sage.plot Graphics object consisting of 1 graphics primitive :: - sage: plot(u, start=v) #test when coordinate dimension mismatch exists + sage: plot(u, start=v) #test when coordinate dimension mismatch exists # optional - sage.plot Traceback (most recent call last): ... ValueError: vector coordinates are not of the same dimension - sage: P = plot(v, start=z) #test when start coordinates are passed as a tuple - sage: P = plot(v, start=list(z)) #test when start coordinates are passed as a list + sage: P = plot(v, start=z) # test when start coordinates are passed as a tuple # optional - sage.plot + sage: P = plot(v, start=list(z)) # test when start coordinates are passed as a list # optional - sage.plot """ # Give sensible defaults based on the vector length if plot_type is None: @@ -2436,9 +2436,9 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: eps=0.1 - sage: v = vector(RDF, [sin(n*eps) for n in range(100)]) - sage: v.plot_step(eps=eps, xmax=5, hue=0) + sage: eps = 0.1 + sage: v = vector(RDF, [sin(n*eps) for n in range(100)]) # optional - sage.plot + sage: v.plot_step(eps=eps, xmax=5, hue=0) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ import math @@ -2564,7 +2564,7 @@ cdef class FreeModuleElement(Vector): # abstract base class The dot product of a vector with itself is the 2-norm, squared. :: sage: v = vector(QQ, [3, 4, 7]) - sage: v.dot_product(v) - v.norm()^2 + sage: v.dot_product(v) - v.norm()^2 # optional - sage.symbolic 0 TESTS: @@ -2851,8 +2851,6 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: x, y = var('x, y') - :: sage: parent(vector(ZZ,[1,2]).pairwise_product(vector(ZZ,[1,2]))) @@ -2932,12 +2930,12 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: R. = QQ[] sage: vector([x, y, 3])._variables() [x, y, z] - sage: vector(SR, [x, y, 3])._variables() + sage: vector(SR, [x, y, 3])._variables() # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: v(x, y, z) = (-y, x, 0) - sage: v._variables() + sage: v(x, y, z) = (-y, x, 0) # optional - sage.symbolic + sage: v._variables() # optional - sage.symbolic [(x, y, z) |--> x, (x, y, z) |--> y, (x, y, z) |--> z] """ R = self._parent.base_ring() @@ -2970,11 +2968,11 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: vector([x*y, y*z, z*x]).div([x, y, w]) y + z - sage: vector(SR, [x*y, y*z, z*x]).div() + sage: vector(SR, [x*y, y*z, z*x]).div() # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: vector(SR, [x*y, y*z, z*x]).div([x, y, z]) + sage: vector(SR, [x*y, y*z, z*x]).div([x, y, z]) # optional - sage.symbolic x + y + z .. SEEALSO:: @@ -3011,18 +3009,18 @@ cdef class FreeModuleElement(Vector): # abstract base class For rings where the variable order is not well defined, it must be defined explicitly:: - sage: v = vector(SR, [-y, x, 0]) - sage: v.curl() + sage: v = vector(SR, [-y, x, 0]) # optional - sage.symbolic + sage: v.curl() # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: v.curl([x, y, z]) + sage: v.curl([x, y, z]) # optional - sage.symbolic (0, 0, 2) Note that callable vectors have well defined variable orderings:: - sage: v(x, y, z) = (-y, x, 0) - sage: v.curl() + sage: v(x, y, z) = (-y, x, 0) # optional - sage.symbolic + sage: v.curl() # optional - sage.symbolic (x, y, z) |--> (0, 0, 2) In two-dimensions, this returns a scalar value:: @@ -3107,14 +3105,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(QQ, [4, 1, 3, 2]) - sage: v.normalized() + sage: v.normalized() # optional - sage.symbolic (2/15*sqrt(30), 1/30*sqrt(30), 1/10*sqrt(30), 1/15*sqrt(30)) sage: sum(v.normalized(1)) 1 Note that normalizing the vector may change the base ring:: - sage: v.base_ring() == v.normalized().base_ring() + sage: v.base_ring() == v.normalized().base_ring() # optional - sage.symbolic False sage: u = vector(RDF, [-3, 4, 6, 9]) sage: u.base_ring() == u.normalized().base_ring() @@ -3152,11 +3150,11 @@ cdef class FreeModuleElement(Vector): # abstract base class such as the cyclotomic fields. This example uses such a field containing a primitive 7-th root of unity named ``a``. :: - sage: F. = CyclotomicField(7) - sage: v = vector(F, [a^i for i in range(7)]) - sage: v + sage: F. = CyclotomicField(7) # optional - sage.rings.number_field + sage: v = vector(F, [a^i for i in range(7)]) # optional - sage.rings.number_field + sage: v # optional - sage.rings.number_field (1, a, a^2, a^3, a^4, a^5, -a^5 - a^4 - a^3 - a^2 - a - 1) - sage: v.conjugate() + sage: v.conjugate() # optional - sage.rings.number_field (1, -a^5 - a^4 - a^3 - a^2 - a - 1, a^5, a^4, a^3, a^2, a) Sparse vectors are returned as such. :: @@ -3633,16 +3631,16 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v = vector([1, 2, 3]); v (1, 2, 3) - sage: sv = v._sympy_(); sv + sage: sv = v._sympy_(); sv # optional - sympy Matrix([ [1], [2], [3]]) - sage: type(sv) + sage: type(sv) # optional - sympy sage: w = vector({1: 1, 5: -1}, sparse=True) - sage: sw = w._sympy_(); sw + sage: sw = w._sympy_(); sw # optional - sympy Matrix([ [ 0], [ 1], @@ -3650,26 +3648,26 @@ cdef class FreeModuleElement(Vector): # abstract base class [ 0], [ 0], [-1]]) - sage: type(sw) + sage: type(sw) # optional - sympy If ``self`` was immutable, then converting the result to Sage gives back ``self``:: sage: immv = vector([1, 2, 3], immutable=True) - sage: immv._sympy_()._sage_() is immv + sage: immv._sympy_()._sage_() is immv # optional - sympy True If ``self`` was mutable, then converting back to Sage creates a new matrix (column vector):: - sage: sv._sage_() + sage: sv._sage_() # optional - sympy [1] [2] [3] - sage: sv._sage_() is v + sage: sv._sage_() is v # optional - sympy False - sage: sv._sage_() == v + sage: sv._sage_() == v # optional - sympy False """ from sage.interfaces.sympy import sympy_init @@ -3822,10 +3820,10 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: m = vector([1,x,sin(x+1)]) - sage: m.apply_map(lambda x: x^2) + sage: m = vector([1,x,sin(x+1)]) # optional - sage.symbolic + sage: m.apply_map(lambda x: x^2) # optional - sage.symbolic (1, x^2, sin(x + 1)^2) - sage: m.apply_map(sin) + sage: m.apply_map(sin) # optional - sage.symbolic (sin(1), sin(x), sin(sin(x + 1))) :: @@ -3878,7 +3876,7 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: m = vector(SR,[]) + sage: m = vector(SR,[]) # optional - sage.symbolic sage: m.apply_map(lambda x: x*x) == m True @@ -3956,31 +3954,31 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,x,x^2]) - sage: v._derivative(x) + sage: v = vector([1,x,x^2]) # optional - sage.symbolic + sage: v._derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v._derivative(x)) == type(v) + sage: type(v._derivative(x)) == type(v) # optional - sage.symbolic True - sage: v = vector([1,x,x^2], sparse=True) - sage: v._derivative(x) + sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic + sage: v._derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v._derivative(x)) == type(v) + sage: type(v._derivative(x)) == type(v) # optional - sage.symbolic True If no variables are specified and the vector contains callable symbolic expressions, then calculate the matrix derivative (i.e., the Jacobian matrix):: - sage: T(r,theta)=[r*cos(theta),r*sin(theta)] - sage: T + sage: T(r,theta) = [r*cos(theta), r*sin(theta)] # optional - sage.symbolic + sage: T # optional - sage.symbolic (r, theta) |--> (r*cos(theta), r*sin(theta)) - sage: T.diff() # matrix derivative + sage: T.diff() # matrix derivative # optional - sage.symbolic [ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)] [ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)] - sage: diff(T) # matrix derivative again + sage: diff(T) # matrix derivative again # optional - sage.symbolic [ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)] [ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)] - sage: T.diff().det() # Jacobian + sage: T.diff().det() # Jacobian # optional - sage.symbolic (r, theta) |--> r*cos(theta)^2 + r*sin(theta)^2 """ if var is None: @@ -4004,17 +4002,17 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,x,x^2]) - sage: v.derivative(x) + sage: v = vector([1,x,x^2]) # optional - sage.symbolic + sage: v.derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) + sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic True - sage: v = vector([1,x,x^2], sparse=True) - sage: v.derivative(x) + sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic + sage: v.derivative(x) # optional - sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) + sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic True - sage: v.derivative(x,x) + sage: v.derivative(x,x) # optional - sage.symbolic (0, 0, 2) """ from sage.misc.derivative import multi_derivative @@ -4030,13 +4028,13 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: t=var('t') - sage: r=vector([t,t^2,sin(t)]) - sage: r.integral(t) + sage: t = var('t') # optional - sage.symbolic + sage: r = vector([t,t^2,sin(t)]) # optional - sage.symbolic + sage: r.integral(t) # optional - sage.symbolic (1/2*t^2, 1/3*t^3, -cos(t)) - sage: integrate(r,t) + sage: integrate(r, t) # optional - sage.symbolic (1/2*t^2, 1/3*t^3, -cos(t)) - sage: r.integrate(t,0,1) + sage: r.integrate(t, 0, 1) # optional - sage.symbolic (1/2, 1/3, -cos(1) + 1) """ @@ -4056,19 +4054,23 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: t=var('t') - sage: r=vector([t,t^2,sin(t)]) - sage: vec,answers=r.nintegral(t,0,1) - sage: vec # abs tol 1e-15 + sage: t = var('t') # optional - sage.symbolic + sage: r = vector([t,t^2,sin(t)]) # optional - sage.symbolic + sage: vec, answers = r.nintegral(t,0,1) # optional - sage.symbolic + sage: vec # abs tol 1e-15 # optional - sage.symbolic (0.5, 0.3333333333333334, 0.4596976941318602) - sage: type(vec) + sage: type(vec) # optional - sage.symbolic - sage: answers - [(0.5, 5.55111512312578...e-15, 21, 0), (0.3333333333333..., 3.70074341541719...e-15, 21, 0), (0.45969769413186..., 5.10366964392284...e-15, 21, 0)] + sage: answers # optional - sage.symbolic + [(0.5, 5.55111512312578...e-15, 21, 0), + (0.3333333333333..., 3.70074341541719...e-15, 21, 0), + (0.45969769413186..., 5.10366964392284...e-15, 21, 0)] - sage: r=vector([t,0,1], sparse=True) - sage: r.nintegral(t,0,1) - ((0.5, 0.0, 1.0), {0: (0.5, 5.55111512312578...e-15, 21, 0), 2: (1.0, 1.11022302462515...e-14, 21, 0)}) + sage: r = vector([t,0,1], sparse=True) # optional - sage.symbolic + sage: r.nintegral(t, 0, 1) # optional - sage.symbolic + ((0.5, 0.0, 1.0), + {0: (0.5, 5.55111512312578...e-15, 21, 0), + 2: (1.0, 1.11022302462515...e-14, 21, 0)}) """ # If Cython supported lambda functions, we would just do @@ -4156,15 +4158,15 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): :: - sage: v = vector([1,2/3,pi]) - sage: v == v + sage: v = vector([1,2/3,pi]) # optional - sage.symbolic + sage: v == v # optional - sage.symbolic True :: - sage: v = vector(RR, [1,2/3,pi]) - sage: v.set_immutable() - sage: isinstance(hash(v), int) + sage: v = vector(RR, [1,2/3,pi]) # optional - sage.symbolic + sage: v.set_immutable() # optional - sage.symbolic + sage: isinstance(hash(v), int) # optional - sage.symbolic True """ cdef _new_c(self, object v): @@ -4197,19 +4199,19 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: v = vector([-1,0,3,pi]) - sage: type(v) + sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic + sage: type(v) # optional - sage.symbolic - sage: v.__copy__() + sage: v.__copy__() # optional - sage.symbolic (-1, 0, 3, pi) - sage: v.__copy__() is v + sage: v.__copy__() is v # optional - sage.symbolic False - sage: copy(v) + sage: copy(v) # optional - sage.symbolic (-1, 0, 3, pi) - sage: copy(v) == v + sage: copy(v) == v # optional - sage.symbolic True - sage: copy(v) is v + sage: copy(v) is v # optional - sage.symbolic False """ return self._new_c(list(self._entries)) @@ -4224,11 +4226,11 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): We can initialize with lists, tuples and derived types:: sage: from sage.modules.free_module_element import FreeModuleElement_generic_dense - sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo]) + sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo]) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_dense(RR^5, (-1,0,2/3,pi,oo)) + sage: FreeModuleElement_generic_dense(RR^5, (-1,0,2/3,pi,oo)) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_dense(RR^5, Sequence([-1,0,2/3,pi,oo])) + sage: FreeModuleElement_generic_dense(RR^5, Sequence([-1,0,2/3,pi,oo])) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) sage: FreeModuleElement_generic_dense(RR^0, 0) () @@ -4237,26 +4239,26 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): Disabling coercion can lead to illegal objects:: - sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo], coerce=False) + sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo], coerce=False) # optional - sage.symbolic (-1, 0, 2/3, pi, +Infinity) We test the ``copy`` flag:: sage: from sage.modules.free_module_element import FreeModuleElement_generic_dense - sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] - sage: FreeModuleElement_generic_dense(RR^5, tuple(L), coerce=False, copy=False) + sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # optional - sage.symbolic + sage: FreeModuleElement_generic_dense(RR^5, tuple(L), coerce=False, copy=False) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=False) - sage: L[4] = 42.0 - sage: v # last entry changed since we didn't copy + sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=False) # optional - sage.symbolic + sage: L[4] = 42.0 # optional - sage.symbolic + sage: v # last entry changed since we didn't copy # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, 42.0000000000000) :: - sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] - sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=True) - sage: L[4] = 42.0 - sage: v # last entry did not change + sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # optional - sage.symbolic + sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=True) # optional - sage.symbolic + sage: L[4] = 42.0 # optional - sage.symbolic + sage: v # last entry did not change # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) Check that :trac:`11751` is fixed:: @@ -4314,8 +4316,8 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi]); w = vector([-2/3,pi^2,1]) - sage: v._add_(w) + sage: v = vector([1,2/3,pi]); w = vector([-2/3,pi^2,1]) # optional - sage.symbolic + sage: v._add_(w) # optional - sage.symbolic (1/3, pi^2 + 2/3, pi + 1) """ cdef list a = left._entries @@ -4361,10 +4363,10 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,3,pi]) - sage: v._lmul_(2/3) + sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic + sage: v._lmul_(2/3) # optional - sage.symbolic (-2/3, 0, 2, 2/3*pi) - sage: v * (2/3) + sage: v * (2/3) # optional - sage.symbolic (-2/3, 0, 2, 2/3*pi) """ if right._parent is self._parent._base: @@ -4397,9 +4399,10 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,3,pi]) - sage: v.__reduce__() - (, (Vector space of dimension 4 over Symbolic Ring, [-1, 0, 3, pi], 4, True)) + sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic + sage: v.__reduce__() # optional - sage.symbolic + (, + (Vector space of dimension 4 over Symbolic Ring, [-1, 0, 3, pi], 4, True)) """ return (make_FreeModuleElement_generic_dense_v1, (self._parent, self._entries, self._degree, not self._is_immutable)) @@ -4410,8 +4413,8 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector(RR, [-1,0,2/3,pi]) - sage: v.get(3) + sage: v = vector(RR, [-1,0,2/3,pi]) # optional - sage.symbolic + sage: v.get(3) # optional - sage.symbolic 3.14159265358979 :: @@ -4490,20 +4493,20 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: x, y = var('x,y') - sage: f = x^2 + y^2 - sage: g = f.gradient() - sage: g + sage: x, y = var('x,y') # optional - sage.symbolic + sage: f = x^2 + y^2 # optional - sage.symbolic + sage: g = f.gradient() # optional - sage.symbolic + sage: g # optional - sage.symbolic (2*x, 2*y) - sage: type(g) + sage: type(g) # optional - sage.symbolic - sage: g(y=2, x=3) + sage: g(y=2, x=3) # optional - sage.symbolic (6, 4) - sage: f(x,y) = x^2 + y^2 - sage: g = f.gradient() - sage: g(3,2) + sage: f(x,y) = x^2 + y^2 # optional - sage.symbolic + sage: g = f.gradient() # optional - sage.symbolic + sage: g(3,2) # optional - sage.symbolic (6, 4) - sage: g(x=3, y=2) + sage: g(x=3, y=2) # optional - sage.symbolic (6, 4) """ return vector([e(*args, **kwargs) for e in self]) @@ -4514,28 +4517,28 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: x,y=var('x,y') - sage: v=vector([x,y,x*sin(y)]) - sage: w=v.function([x,y]); w + sage: x, y = var('x,y') # optional - sage.symbolic + sage: v = vector([x,y,x*sin(y)]) # optional - sage.symbolic + sage: w = v.function([x,y]); w # optional - sage.symbolic (x, y) |--> (x, y, x*sin(y)) - sage: w.coordinate_ring() + sage: w.coordinate_ring() # optional - sage.symbolic Callable function ring with arguments (x, y) - sage: w(1,2) + sage: w(1,2) # optional - sage.symbolic (1, 2, sin(2)) - sage: w(2,1) + sage: w(2,1) # optional - sage.symbolic (2, 1, 2*sin(1)) - sage: w(y=1,x=2) + sage: w(y=1,x=2) # optional - sage.symbolic (2, 1, 2*sin(1)) :: - sage: x,y=var('x,y') - sage: v=vector([x,y,x*sin(y)]) - sage: w=v.function([x]); w + sage: x,y = var('x,y') # optional - sage.symbolic + sage: v = vector([x,y,x*sin(y)]) # optional - sage.symbolic + sage: w = v.function([x]); w # optional - sage.symbolic x |--> (x, y, x*sin(y)) - sage: w.coordinate_ring() + sage: w.coordinate_ring() # optional - sage.symbolic Callable function ring with argument x - sage: w(4) + sage: w(4) # optional - sage.symbolic (4, y, 4*sin(y)) """ from sage.symbolic.callable import CallableSymbolicExpressionRing @@ -4587,9 +4590,9 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): TESTS:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v.set_immutable() - sage: isinstance(hash(v), int) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.set_immutable() # optional - sage.symbolic + sage: isinstance(hash(v), int) # optional - sage.symbolic True Pickling works:: @@ -4639,8 +4642,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v.__copy__() + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.__copy__() # optional - sage.symbolic (1, 2/3, pi) """ return self._new_c(dict(self._entries)) @@ -4659,13 +4662,13 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): sage: from sage.modules.free_module_element import FreeModuleElement_generic_sparse sage: def S(R,n): ....: return FreeModule(R, n, sparse=True) - sage: FreeModuleElement_generic_sparse(S(RR,5), {0:-1, 2:2/3, 3:pi, 4:oo}) + sage: FreeModuleElement_generic_sparse(S(RR,5), {0:-1, 2:2/3, 3:pi, 4:oo}) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), [-1,0,2/3,pi,oo]) + sage: FreeModuleElement_generic_sparse(S(RR,5), [-1,0,2/3,pi,oo]) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), (-1,0,2/3,pi,oo)) + sage: FreeModuleElement_generic_sparse(S(RR,5), (-1,0,2/3,pi,oo)) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), Sequence([-1,0,2/3,pi,oo])) + sage: FreeModuleElement_generic_sparse(S(RR,5), Sequence([-1,0,2/3,pi,oo])) # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) sage: FreeModuleElement_generic_sparse(S(RR,0), 0) () @@ -4763,8 +4766,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v._add_(v) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v._add_(v) # optional - sage.symbolic (2, 4/3, 2*pi) """ cdef dict v = dict((right)._entries) @@ -4783,8 +4786,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v._sub_(v) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v._sub_(v) # optional - sage.symbolic (0, 0, 0) """ cdef dict v = dict(left._entries) # dict to make a copy @@ -4803,8 +4806,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v._lmul_(SR(3)) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v._lmul_(SR(3)) # optional - sage.symbolic (3, 2, 3*pi) """ cdef dict v = {} @@ -4819,8 +4822,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v._rmul_(SR(3)) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v._rmul_(SR(3)) # optional - sage.symbolic (3, 2, 3*pi) """ cdef dict v = {} @@ -4887,8 +4890,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True); w = vector([-2/3,pi^2,1],sparse=True) - sage: v._pairwise_product_(w) + sage: v = vector([1,2/3,pi], sparse=True); w = vector([-2/3,pi^2,1],sparse=True) # optional - sage.symbolic + sage: v._pairwise_product_(w) # optional - sage.symbolic (-2/3, 2/3*pi^2, pi) """ # Component wise vector * vector multiplication. @@ -4912,9 +4915,9 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): TESTS:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: w = vector([1,2/3,pi], sparse=True) - sage: w == v + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: w = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: w == v # optional - sage.symbolic True Check that the bug in :trac:`13929` has been fixed:: @@ -4936,17 +4939,17 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: next(v.items()) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: next(v.items()) # optional - sage.symbolic (0, 1) - sage: list(v.items()) + sage: list(v.items()) # optional - sage.symbolic [(0, 1), (1, 2/3), (2, pi)] TESTS: Using iteritems as an alias:: - sage: list(v.iteritems()) + sage: list(v.iteritems()) # optional - sage.symbolic [(0, 1), (1, 2/3), (2, pi)] """ return iter(self._entries.iteritems()) @@ -4957,9 +4960,10 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v.__reduce__() - (, (Sparse vector space of dimension 3 over Symbolic Ring, {0: 1, 1: 2/3, 2: pi}, 3, True)) + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.__reduce__() # optional - sage.symbolic + (, + (Sparse vector space of dimension 3 over Symbolic Ring, {0: 1, 1: 2/3, 2: pi}, 3, True)) """ return (make_FreeModuleElement_generic_sparse_v1, (self._parent, self._entries, self._degree, not self._is_immutable)) @@ -5035,15 +5039,15 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,2/3,pi], sparse=True) - sage: v.get(1) + sage: v = vector([-1,0,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.get(1) # optional - sage.symbolic 0 - sage: v.get(2) + sage: v.get(2) # optional - sage.symbolic 2/3 For this class, 0 is returned if the access is out of bounds:: - sage: v.get(10) + sage: v.get(10) # optional - sage.symbolic 0 """ try: @@ -5071,21 +5075,21 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): :: - sage: v = vector([1,2/3,pi], sparse=True) - sage: v.set(1, pi^3) - sage: v + sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic + sage: v.set(1, pi^3) # optional - sage.symbolic + sage: v # optional - sage.symbolic (1, pi^3, pi) - sage: v.set(2, SR(0)) - sage: v + sage: v.set(2, SR(0)) # optional - sage.symbolic + sage: v # optional - sage.symbolic (1, pi^3, 0) This assignment is illegal:: - sage: v.set(10, pi) + sage: v.set(10, pi) # optional - sage.symbolic This lack of bounds checking causes trouble later:: - sage: v + sage: v # optional - sage.symbolic ) failed: IndexError: list assignment index out of range> """ if value: diff --git a/src/sage/modules/free_module_morphism.py b/src/sage/modules/free_module_morphism.py index f7508ebeb97..a437bd278fa 100644 --- a/src/sage/modules/free_module_morphism.py +++ b/src/sage/modules/free_module_morphism.py @@ -214,7 +214,7 @@ def change_ring(self, R): Basis matrix: [1 0] [0 1] - sage: f = h.change_ring(GF(7)); f + sage: f = h.change_ring(GF(7)); f # optional - sage.libs.pari Vector space morphism represented by the matrix: [4 4] [4 4] @@ -414,17 +414,17 @@ def lift(self, x): This works for vector spaces, too:: - sage: V = VectorSpace(GF(3), 2) - sage: W = VectorSpace(GF(3), 3) - sage: f = V.hom([W.1, W.1 - W.0]) - sage: f.lift(W.1) + sage: V = VectorSpace(GF(3), 2) # optional - sage.libs.pari + sage: W = VectorSpace(GF(3), 3) # optional - sage.libs.pari + sage: f = V.hom([W.1, W.1 - W.0]) # optional - sage.libs.pari + sage: f.lift(W.1) # optional - sage.libs.pari (1, 0) - sage: f.lift(W.2) + sage: f.lift(W.2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: element is not in the image - sage: w = W((17, -2, 0)) - sage: f(f.lift(w)) == w + sage: w = W((17, -2, 0)) # optional - sage.libs.pari + sage: f(f.lift(w)) == w # optional - sage.libs.pari True This example illustrates the use of the ``preimage_representative`` @@ -473,7 +473,7 @@ def lift(self, x): preimage_representative = lift - def eigenvalues(self,extend=True): + def eigenvalues(self, extend=True): r""" Returns a list with the eigenvalues of the endomorphism of vector spaces. @@ -486,15 +486,15 @@ def eigenvalues(self,extend=True): We compute the eigenvalues of an endomorphism of `\QQ^3`:: - sage: V=QQ^3 - sage: H=V.endomorphism_ring()([[1,-1,0],[-1,1,1],[0,3,1]]) - sage: H.eigenvalues() + sage: V = QQ^3 + sage: H = V.endomorphism_ring()([[1,-1,0], [-1,1,1], [0,3,1]]) + sage: H.eigenvalues() # optional - sage.rings.number_field [3, 1, -1] Note the effect of the ``extend`` option:: - sage: V=QQ^2 - sage: H=V.endomorphism_ring()([[0,-1],[1,0]]) + sage: V = QQ^2 + sage: H = V.endomorphism_ring()([[0,-1], [1,0]]) sage: H.eigenvalues() [-1*I, 1*I] sage: H.eigenvalues(extend=False) @@ -508,7 +508,7 @@ def eigenvalues(self,extend=True): else: raise NotImplementedError("module must be a vector space") - def eigenvectors(self,extend=True): + def eigenvectors(self, extend=True): """ Computes the subspace of eigenvectors of a given eigenvalue. @@ -527,7 +527,7 @@ def eigenvectors(self,extend=True): sage: V=(QQ^4).subspace([[0,2,1,4],[1,2,5,0],[1,1,1,1]]) sage: H=(V.Hom(V))(matrix(QQ, [[0,1,0],[-1,0,0],[0,0,3]])) - sage: H.eigenvectors() + sage: H.eigenvectors() # optional - sage.rings.number_field [(3, [ (0, 0, 1, -6/7) ], 1), (-1*I, [ @@ -587,7 +587,7 @@ def eigenvectors(self,extend=True): else: raise NotImplementedError("module must be a vector space") - def eigenspaces(self,extend=True): + def eigenspaces(self, extend=True): """ Compute a list of subspaces formed by eigenvectors of ``self``. @@ -603,8 +603,8 @@ def eigenspaces(self,extend=True): EXAMPLES:: sage: V = QQ^3 - sage: h = V.hom([[1,0,0],[0,0,1],[0,-1,0]], V) - sage: h.eigenspaces() + sage: h = V.hom([[1,0,0], [0,0,1], [0,-1,0]], V) + sage: h.eigenspaces() # optional - sage.rings.number_field [(1, Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: @@ -676,9 +676,9 @@ def minimal_polynomial(self,var='x'): Compute the minimal polynomial, and check it. :: - sage: V=GF(7)^3 - sage: H=V.Hom(V)([[0,1,2],[-1,0,3],[2,4,1]]) - sage: H + sage: V=GF(7)^3 # optional - sage.libs.pari + sage: H=V.Hom(V)([[0,1,2],[-1,0,3],[2,4,1]]) # optional - sage.libs.pari + sage: H # optional - sage.libs.pari Vector space morphism represented by the matrix: [0 1 2] [6 0 3] @@ -686,13 +686,13 @@ def minimal_polynomial(self,var='x'): Domain: Vector space of dimension 3 over Finite Field of size 7 Codomain: Vector space of dimension 3 over Finite Field of size 7 - sage: H.minpoly() + sage: H.minpoly() # optional - sage.libs.pari x^3 + 6*x^2 + 6*x + 1 - sage: H.minimal_polynomial() + sage: H.minimal_polynomial() # optional - sage.libs.pari x^3 + 6*x^2 + 6*x + 1 - sage: H^3 + (H^2)*6 + H*6 + 1 + sage: H^3 + (H^2)*6 + H*6 + 1 # optional - sage.libs.pari Vector space morphism represented by the matrix: [0 0 0] [0 0 0] diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index b512db6ffbc..ca25ce9ed58 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -124,9 +124,9 @@ def FreeQuadraticModule(base_ring, rank, inner_product_matrix, Check for :trac:`10577`:: - sage: m = matrix.diagonal(GF(2), [1,1]) - sage: V2 = VectorSpace(GF(2), 2, inner_product_matrix=m) - sage: deepcopy(V2) + sage: m = matrix.diagonal(GF(2), [1,1]) # optional - sage.libs.pari + sage: V2 = VectorSpace(GF(2), 2, inner_product_matrix=m) # optional - sage.libs.pari + sage: deepcopy(V2) # optional - sage.libs.pari Ambient quadratic space of dimension 2 over Finite Field of size 2 Inner product matrix: [1 0] @@ -702,7 +702,7 @@ def __init__(self, base_field, dimension, degree, inner_product_matrix, sparse=F Inner product matrix: [2 1] [1 2] - sage: FreeModule(FiniteField(2), 7, inner_product_matrix=1) + sage: FreeModule(FiniteField(2), 7, inner_product_matrix=1) # optional - sage.libs.pari Ambient quadratic space of dimension 7 over Finite Field of size 2 Inner product matrix: [1 0 0 0 0 0 0] @@ -739,12 +739,12 @@ def span(self, gens, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari + sage: W = V.subspace([[2,3,4]]); W # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span([[1,1,1]]) + sage: W.span([[1,1,1]]) # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 1] @@ -779,12 +779,12 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) - sage: W = V.subspace([[2,3,4]]); W + sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari + sage: W = V.subspace([[2,3,4]]); W # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span_of_basis([[2,2,2], [3,3,0]]) + sage: W.span_of_basis([[2,2,2], [3,3,0]]) # optional - sage.libs.pari Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -793,7 +793,7 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): The basis vectors must be linearly independent or a ``ValueError`` exception is raised:: - sage: W.span_of_basis([[2,2,2], [3,3,3]]) + sage: W.span_of_basis([[2,2,2], [3,3,3]]) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -876,7 +876,7 @@ def _latex_(self): sage: latex(QQ^3) # indirect doctest \Bold{Q}^{3} - sage: A = GF(5)^20; latex(A) + sage: A = GF(5)^20; latex(A) # optional - sage.libs.pari \Bold{F}_{5}^{20} sage: A = PolynomialRing(QQ,3,'x')^20; latex(A) @@ -943,7 +943,7 @@ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): """ EXAMPLES:: - sage: FreeModule(PolynomialRing(GF(5),'x'), 3) + sage: FreeModule(PolynomialRing(GF(5),'x'), 3) # optional - sage.libs.pari Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 5 """ @@ -1141,8 +1141,8 @@ def __init__(self, base_field, dimension, inner_product_matrix, sparse=False): Check for :trac:`10606`:: sage: D = matrix.diagonal(ZZ, [1,1]) - sage: V = VectorSpace(GF(46349), 2, inner_product_matrix=D) - sage: deepcopy(V) + sage: V = VectorSpace(GF(46349), 2, inner_product_matrix=D) # optional - sage.libs.pari + sage: deepcopy(V) # optional - sage.libs.pari Ambient quadratic space of dimension 2 over Finite Field of size 46349 Inner product matrix: @@ -1356,7 +1356,7 @@ def change_ring(self, R): Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [ 1 1/4 1/2] - sage: W.change_ring(GF(7)) + sage: W.change_ring(GF(7)) # optional - sage.libs.pari Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 2 4] @@ -1365,8 +1365,8 @@ def change_ring(self, R): sage: N.inner_product_matrix() [ 1 -1] [ 2 5] - sage: Np = N.change_ring(RDF) - sage: Np.inner_product_matrix() + sage: Np = N.change_ring(RDF) # optional - sage.libs.pari + sage: Np.inner_product_matrix() # optional - sage.libs.pari [ 1.0 -1.0] [ 2.0 5.0] """ diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index 4064bcc5a30..0a9a466e158 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -21,13 +21,13 @@ [0 0 1] sage: is_MatrixMorphism(m) True - sage: m.charpoly('x') + sage: m.charpoly('x') # optional - sage.libs.pari x^3 - 3*x^2 + 3*x - 1 sage: m.base_ring() Rational Field sage: m.det() 1 - sage: m.fcp('x') + sage: m.fcp('x') # optional - sage.libs.pari (x - 1)^3 sage: m.matrix() [1 0 0] @@ -835,7 +835,7 @@ def decomposition(self, *args, **kwds): EXAMPLES:: sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) - sage: phi.decomposition() + sage: phi.decomposition() # optional - sage.libs.pari [ Free module of degree 2 and rank 1 over Integer Ring Echelon basis matrix: @@ -845,7 +845,7 @@ def decomposition(self, *args, **kwds): [ 1 -1] ] sage: phi2 = V.hom(phi.matrix(), side="right") - sage: phi2.decomposition() + sage: phi2.decomposition() # optional - sage.libs.pari [ Free module of degree 2 and rank 1 over Integer Ring Echelon basis matrix: @@ -905,9 +905,9 @@ def fcp(self, var='x'): EXAMPLES:: sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) - sage: phi.fcp() + sage: phi.fcp() # optional - sage.libs.pari (x - 2) * (x - 1) - sage: phi.fcp('T') + sage: phi.fcp('T') # optional - sage.libs.pari (T - 2) * (T - 1) """ return self.charpoly(var).factor() @@ -1740,7 +1740,7 @@ def is_surjective(self): An example over a PID that is not `\ZZ`. :: - sage: R = PolynomialRing(QQ, 'x') + sage: R. = PolynomialRing(QQ) sage: A = R^2 sage: B = R^2 sage: H = A.hom([B([x^2-1, 1]), B([x^2, 1])]) diff --git a/src/sage/modules/quotient_module.py b/src/sage/modules/quotient_module.py index 10db2189997..b5af2323b3e 100644 --- a/src/sage/modules/quotient_module.py +++ b/src/sage/modules/quotient_module.py @@ -307,45 +307,54 @@ class FreeModule_ambient_field_quotient(FreeModule_ambient_field): EXAMPLES:: - sage: k. = QuadraticField(-1) - sage: A = k^3; V = A.span([[1,0,i], [2,i,0]]) - sage: W = A.span([[3,i,i]]) - sage: U = V/W; U - Vector space quotient V/W of dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I where - V: Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + sage: k. = QuadraticField(-1) # optional - sage.rings.number_field + sage: A = k^3; V = A.span([[1,0,i], [2,i,0]]) # optional - sage.rings.number_field + sage: W = A.span([[3,i,i]]) # optional - sage.rings.number_field + sage: U = V/W; U # optional - sage.rings.number_field + Vector space quotient V/W of dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I where + V: Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 0 i] [ 0 1 -2] - W: Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + W: Vector space of degree 3 and dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 1/3*i 1/3*i] - sage: U.V() - Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + sage: U.V() # optional - sage.rings.number_field + Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 0 i] [ 0 1 -2] - sage: U.W() - Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + sage: U.W() # optional - sage.rings.number_field + Vector space of degree 3 and dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 1/3*i 1/3*i] - sage: U.quotient_map() + sage: U.quotient_map() # optional - sage.rings.number_field Vector space morphism represented by the matrix: [ 1] [3*i] - Domain: Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + Domain: Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 0 i] [ 0 1 -2] - Codomain: Vector space quotient V/W of dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I where - V: Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + Codomain: Vector space quotient V/W of dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I where + V: Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 0 i] [ 0 1 -2] - W: Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I + W: Vector space of degree 3 and dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 1/3*i 1/3*i] - sage: Z = V.quotient(W) - sage: Z == U + sage: Z = V.quotient(W) # optional - sage.rings.number_field + sage: Z == U # optional - sage.rings.number_field True We create three quotient spaces and compare them:: @@ -432,19 +441,19 @@ def _repr_(self): We create a quotient vector space over a finite field:: - sage: k. = GF(9); A = k^3; V = A.span_of_basis([[1,0,a], [a,a,1]]); W = V.span([V.1]) - sage: Q = V/W + sage: k. = GF(9); A = k^3; V = A.span_of_basis([[1,0,a], [a,a,1]]); W = V.span([V.1]) # optional - sage.libs.pari + sage: Q = V/W # optional - sage.libs.pari Note the type:: - sage: type(Q) + sage: type(Q) # optional - sage.libs.pari The string representation mentions that this is a quotient `V/W`, that the quotient has dimension 1 and is over a finite field, and also describes `V` and `W`:: - sage: Q._repr_() + sage: Q._repr_() # optional - sage.libs.pari 'Vector space quotient V/W of dimension 1 over Finite Field in a of size 3^2 where\nV: Vector space of degree 3 and dimension 2 over Finite Field in a of size 3^2\nUser basis matrix:\n[1 0 a]\n[a a 1]\nW: Vector space of degree 3 and dimension 1 over Finite Field in a of size 3^2\nBasis matrix:\n[ 1 1 a + 2]' """ return "%s space quotient V/W of dimension %s over %s where\nV: %s\nW: %s" % ( diff --git a/src/sage/modules/vector_integer_dense.pyx b/src/sage/modules/vector_integer_dense.pyx index 22709019993..593de691422 100644 --- a/src/sage/modules/vector_integer_dense.pyx +++ b/src/sage/modules/vector_integer_dense.pyx @@ -314,10 +314,10 @@ cdef class Vector_integer_dense(free_module_element.FreeModuleElement): sage: A = random_matrix(ZZ,1,3) sage: v = A.row(0) - sage: vs = singular(v) - sage: vs._repr_() == '{},\n{},\n{}'.format(*v) + sage: vs = singular(v) # optional - sage.libs.singular + sage: vs._repr_() == '{},\n{},\n{}'.format(*v) # optional - sage.libs.singular True - sage: vs.type() + sage: vs.type() # optional - sage.libs.singular 'intvec' """ if singular is None: diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index 7b4123709e7..ebaaca87540 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -45,9 +45,9 @@ We make a large zero vector:: We multiply a vector by a matrix:: - sage: a = (GF(97)^5)(range(5)) - sage: m = matrix(GF(97),5,range(25)) - sage: a*m + sage: a = (GF(97)^5)(range(5)) # optional - sage.libs.pari + sage: m = matrix(GF(97), 5, range(25)) # optional - sage.libs.pari + sage: a*m # optional - sage.libs.pari (53, 63, 73, 83, 93) TESTS:: @@ -58,41 +58,41 @@ TESTS:: sage: v = vector(Integers(389), [1,2,3,4,5]) sage: loads(dumps(v)) == v True - sage: v = vector(Integers(next_prime(10^20)), [1,2,3,4,5]) - sage: loads(dumps(v)) == v + sage: v = vector(Integers(next_prime(10^20)), [1,2,3,4,5]) # optional - sage.libs.pari + sage: loads(dumps(v)) == v # optional - sage.libs.pari True - sage: K = GF(previous_prime(2^31)) - sage: v = vector(K, [42]); type(v[0]) + sage: K = GF(previous_prime(2^31)) # optional - sage.libs.pari + sage: v = vector(K, [42]); type(v[0]) # optional - sage.libs.pari - sage: ~v[0] + sage: ~v[0] # optional - sage.libs.pari 2096353084 - sage: K = GF(next_prime(2^31)) - sage: v = vector(K, [42]); type(v[0]) + sage: K = GF(next_prime(2^31)) # optional - sage.libs.pari + sage: v = vector(K, [42]); type(v[0]) # optional - sage.libs.pari - sage: ~v[0] + sage: ~v[0] # optional - sage.libs.pari 1482786336 - sage: w = vector(GF(11), [-1,0,0,0]) - sage: w.set_immutable() - sage: isinstance(hash(w), int) + sage: w = vector(GF(11), [-1,0,0,0]) # optional - sage.libs.pari + sage: w.set_immutable() # optional - sage.libs.pari + sage: isinstance(hash(w), int) # optional - sage.libs.pari True Test that :trac:`28042` is fixed:: sage: p = 193379 - sage: K = GF(p) - sage: a = K(1) - sage: b = K(191495) - sage: c = K(109320) - sage: d = K(167667) - sage: e = 103937 - sage: a*c+b*d-e + sage: K = GF(p) # optional - sage.libs.pari + sage: a = K(1) # optional - sage.libs.pari + sage: b = K(191495) # optional - sage.libs.pari + sage: c = K(109320) # optional - sage.libs.pari + sage: d = K(167667) # optional - sage.libs.pari + sage: e = 103937 # optional - sage.libs.pari + sage: a*c + b*d - e 102041 - sage: vector([a,b]) * vector([c,d]) - e + sage: vector([a,b]) * vector([c,d]) - e # optional - sage.libs.pari 102041 - sage: type(vector([a,b]) * vector([c,d])) + sage: type(vector([a,b]) * vector([c,d])) # optional - sage.libs.pari AUTHOR: @@ -197,15 +197,15 @@ cdef class Vector_modn_dense(free_module_element.FreeModuleElement): """ EXAMPLES:: - sage: v = vector(GF(5), [0,0,0,0]) - sage: v == 0 + sage: v = vector(GF(5), [0,0,0,0]) # optional - sage.libs.pari + sage: v == 0 # optional - sage.libs.pari True - sage: v == 1 + sage: v == 1 # optional - sage.libs.pari False - sage: v == v + sage: v == v # optional - sage.libs.pari True - sage: w = vector(GF(11), [-1,0,0,0]) - sage: w == w + sage: w = vector(GF(11), [-1,0,0,0]) # optional - sage.libs.pari + sage: w == w # optional - sage.libs.pari True """ cdef Py_ssize_t i diff --git a/src/sage/modules/vector_space_homspace.py b/src/sage/modules/vector_space_homspace.py index c15f0f59285..8d6dafafa67 100644 --- a/src/sage/modules/vector_space_homspace.py +++ b/src/sage/modules/vector_space_homspace.py @@ -38,9 +38,9 @@ a list of matrix representations, where these matrix representatives are relative to the bases of the domain and codomain. :: - sage: K = Hom(GF(3)^2, GF(3)^2) - sage: B = K.basis() - sage: for f in B: + sage: K = Hom(GF(3)^2, GF(3)^2) # optional - sage.libs.pari + sage: B = K.basis() # optional - sage.libs.pari + sage: for f in B: # optional - sage.libs.pari ....: print(f) ....: print("\n") Vector space morphism represented by the matrix: @@ -359,10 +359,10 @@ def __call__(self, A, check=True, **kwds): TESTS:: - sage: V = GF(3)^0 - sage: W = GF(3)^1 - sage: H = V.Hom(W) - sage: H.zero().is_zero() + sage: V = GF(3)^0 # optional - sage.libs.pari + sage: W = GF(3)^1 # optional - sage.libs.pari + sage: H = V.Hom(W) # optional - sage.libs.pari + sage: H.zero().is_zero() # optional - sage.libs.pari True Previously the above code resulted in a TypeError because the diff --git a/src/sage/modules/with_basis/cell_module.py b/src/sage/modules/with_basis/cell_module.py index c51d43c32b6..8c2fe5a3ac4 100644 --- a/src/sage/modules/with_basis/cell_module.py +++ b/src/sage/modules/with_basis/cell_module.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.combinat r""" Cell modules """ diff --git a/src/sage/modules/with_basis/indexed_element.pyx b/src/sage/modules/with_basis/indexed_element.pyx index d5f2159b9e8..4b784a5a5d7 100644 --- a/src/sage/modules/with_basis/indexed_element.pyx +++ b/src/sage/modules/with_basis/indexed_element.pyx @@ -77,9 +77,9 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: [i for i in sorted(f)] [('a', 1), ('c', 3)] - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1]) + s([3]) - sage: [i for i in sorted(a)] + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s([2,1]) + s([3]) # optional - sage.combinat + sage: [i for i in sorted(a)] # optional - sage.combinat [([2, 1], 1), ([3], 1)] """ return iter(self._monomial_coefficients.items()) @@ -102,11 +102,11 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: 'b' in f False - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1]) + s([3]) - sage: Partition([2,1]) in a + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s([2,1]) + s([3]) # optional - sage.combinat + sage: Partition([2,1]) in a # optional - sage.combinat True - sage: Partition([1,1,1]) in a + sage: Partition([1,1,1]) in a # optional - sage.combinat False """ deprecation(34509, "using 'index in vector' is deprecated; use 'index in vector.support()' instead") @@ -128,11 +128,11 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: hash(f) == hash(B['a'] + 4*B['c']) False - sage: F = RootSystem(['A',2]).ambient_space() - sage: f = F.simple_root(0) - sage: hash(f) == hash(F.simple_root(0)) + sage: F = RootSystem(['A',2]).ambient_space() # optional - sage.combinat + sage: f = F.simple_root(0) # optional - sage.combinat + sage: hash(f) == hash(F.simple_root(0)) # optional - sage.combinat True - sage: hash(f) == hash(F.simple_root(1)) + sage: hash(f) == hash(F.simple_root(1)) # optional - sage.combinat False This uses the recipe that was proposed for frozendicts in @@ -259,14 +259,14 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1])+2*s([3,2]) - sage: d = a.monomial_coefficients() - sage: type(d) + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s([2,1])+2*s([3,2]) # optional - sage.combinat + sage: d = a.monomial_coefficients() # optional - sage.combinat + sage: type(d) # optional - sage.combinat <... 'dict'> - sage: d[ Partition([2,1]) ] + sage: d[ Partition([2,1]) ] # optional - sage.combinat 1 - sage: d[ Partition([3,2]) ] + sage: d[ Partition([3,2]) ] # optional - sage.combinat 2 """ if copy: @@ -342,17 +342,17 @@ cdef class IndexedFreeModuleElement(ModuleElement): """ TESTS:: - sage: M = QuasiSymmetricFunctions(QQ).M() - sage: ascii_art(M[1,3]**2) # indirect doctest + sage: M = QuasiSymmetricFunctions(QQ).M() # optional - sage.combinat + sage: ascii_art(M[1,3]**2) # indirect doctest # optional - sage.combinat 4*M + 2*M + 2*M + 2*M + 2*M + M *** ****** *** *** *** ****** *** * * **** *** ** * * *** * ** * * - sage: ascii_art(M.zero()) + sage: ascii_art(M.zero()) # optional - sage.combinat 0 - sage: DA = DescentAlgebra(QQ, 4) - sage: ascii_art(DA.an_element()) + sage: DA = DescentAlgebra(QQ, 4) # optional - sage.combinat + sage: ascii_art(DA.an_element()) # optional - sage.combinat 2*B + 2*B + 3*B * ** * * * ** @@ -419,8 +419,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): """ TESTS:: - sage: M = QuasiSymmetricFunctions(QQ).M() - sage: unicode_art(M[1,1]**2) # indirect doctest + sage: M = QuasiSymmetricFunctions(QQ).M() # optional - sage.combinat + sage: unicode_art(M[1,1]**2) # indirect doctest # optional - sage.combinat 6*M + 2*M + 2*M + 2*M + M ┌┐ ┌┬┐ ┌┐ ┌┐ ┌┬┐ ├┤ ├┼┘ ┌┼┤ ├┤ ┌┼┼┘ @@ -430,7 +430,7 @@ cdef class IndexedFreeModuleElement(ModuleElement): The following test failed before :trac:`26850`:: - sage: unicode_art([M.zero()]) # indirect doctest + sage: unicode_art([M.zero()]) # indirect doctest # optional - sage.combinat [ 0 ] """ from sage.misc.repr import coeff_repr @@ -501,9 +501,9 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: QS3 = SymmetricGroupAlgebra(QQ,3) - sage: a = 2 + QS3([2,1,3]) - sage: latex(a) #indirect doctest + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat + sage: a = 2 + QS3([2,1,3]) # optional - sage.combinat + sage: latex(a) #indirect doctest # optional - sage.combinat 2 [1, 2, 3] + [2, 1, 3] :: @@ -563,10 +563,10 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s([2,1]) - sage: b = s([1,1,1]) - sage: a == b + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s([2,1]) # optional - sage.combinat + sage: b = s([1,1,1]) # optional - sage.combinat + sage: a == b # optional - sage.combinat False .. TODO:: @@ -590,20 +590,20 @@ cdef class IndexedFreeModuleElement(ModuleElement): Traceback (most recent call last): ... TypeError: do not know how to make x (= 0) an element of self (=Free module generated by {1, 2, 3} over Rational Field) - sage: F = AlgebrasWithBasis(QQ).example() - sage: F.one() == 1 + sage: F = AlgebrasWithBasis(QQ).example() # optional - sage.combinat + sage: F.one() == 1 # optional - sage.combinat True - sage: 1 == F.one() + sage: 1 == F.one() # optional - sage.combinat True - sage: 2 * F.one() == int(2) + sage: 2 * F.one() == int(2) # optional - sage.combinat True - sage: int(2) == 2 * F.one() + sage: int(2) == 2 * F.one() # optional - sage.combinat True - sage: S = SymmetricFunctions(QQ); s = S.s(); p = S.p() - sage: p[2] == s[2] - s[1, 1] + sage: S = SymmetricFunctions(QQ); s = S.s(); p = S.p() # optional - sage.combinat + sage: p[2] == s[2] - s[1, 1] # optional - sage.combinat True - sage: p[2] == s[2] + sage: p[2] == s[2] # optional - sage.combinat False This feature is disputable, in particular since it can make @@ -613,19 +613,19 @@ cdef class IndexedFreeModuleElement(ModuleElement): can vary because their indices are incomparable with ``cmp``. The following test did fail before :trac:`12489` :: - sage: F = CombinatorialFreeModule(QQ, Subsets([1,2,3])) - sage: x = F.an_element() - sage: (x+F.zero()).terms() # random + sage: F = CombinatorialFreeModule(QQ, Subsets([1,2,3])) # optional - sage.combinat + sage: x = F.an_element() # optional - sage.combinat + sage: (x+F.zero()).terms() # random # optional - sage.combinat [2*B[{1}], 3*B[{2}], B[{}]] - sage: x.terms() # random + sage: x.terms() # random # optional - sage.combinat [2*B[{1}], B[{}], 3*B[{2}]] - sage: x+F.zero() == x + sage: x+F.zero() == x # optional - sage.combinat True TESTS:: sage: TestSuite(F1).run() - sage: TestSuite(F).run() + sage: TestSuite(F).run() # optional - sage.combinat """ cdef IndexedFreeModuleElement elt = other @@ -653,11 +653,11 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: s([2,1]) + s([5,4]) # indirect doctest + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: s([2,1]) + s([5,4]) # indirect doctest # optional - sage.combinat s[2, 1] + s[5, 4] - sage: a = s([2,1]) + 0 - sage: len(a.monomial_coefficients()) + sage: a = s([2,1]) + 0 # optional - sage.combinat + sage: len(a.monomial_coefficients()) # optional - sage.combinat 1 """ return type(self)(self._parent, @@ -676,8 +676,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: -s([2,1]) # indirect doctest + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: -s([2,1]) # indirect doctest # optional - sage.combinat -s[2, 1] """ return type(self)(self._parent, negate(self._monomial_coefficients)) @@ -693,8 +693,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() - sage: s([2,1]) - s([5,4]) # indirect doctest + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: s([2,1]) - s([5,4]) # indirect doctest # optional - sage.combinat s[2, 1] - s[5, 4] """ return type(self)(self._parent, @@ -708,15 +708,15 @@ cdef class IndexedFreeModuleElement(ModuleElement): EXAMPLES:: - sage: p = Partition([2,1]) - sage: q = Partition([1,1,1]) - sage: s = SymmetricFunctions(QQ).schur() - sage: a = s(p) - sage: a[p] + sage: p = Partition([2,1]) # optional - sage.combinat + sage: q = Partition([1,1,1]) # optional - sage.combinat + sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat + sage: a = s(p) # optional - sage.combinat + sage: a[p] # optional - sage.combinat 1 - sage: a[q] + sage: a[q] # optional - sage.combinat 0 - sage: a[[2,1]] + sage: a[[2,1]] # optional - sage.combinat Traceback (most recent call last): ... TypeError: unhashable type: 'list' @@ -765,23 +765,23 @@ cdef class IndexedFreeModuleElement(ModuleElement): More examples:: - sage: QS3 = SymmetricGroupAlgebra(QQ, 3) - sage: a = 2*QS3([1,2,3]) + 4*QS3([3,2,1]) - sage: a._vector_() + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat + sage: a = 2*QS3([1,2,3]) + 4*QS3([3,2,1]) # optional - sage.combinat + sage: a._vector_() # optional - sage.combinat (2, 0, 0, 0, 0, 4) - sage: a.to_vector() + sage: a.to_vector() # optional - sage.combinat (2, 0, 0, 0, 0, 4) - sage: vector(a) + sage: vector(a) # optional - sage.combinat (2, 0, 0, 0, 0, 4) - sage: a == QS3.from_vector(a.to_vector()) + sage: a == QS3.from_vector(a.to_vector()) # optional - sage.combinat True - sage: a.to_vector(sparse=True) + sage: a.to_vector(sparse=True) # optional - sage.combinat (2, 0, 0, 0, 0, 4) If ``new_base_ring`` is specified, then a vector over ``new_base_ring`` is returned:: - sage: a._vector_(RDF) + sage: a._vector_(RDF) # optional - sage.combinat (2.0, 0.0, 0.0, 0.0, 0.0, 4.0) .. NOTE:: @@ -859,18 +859,18 @@ cdef class IndexedFreeModuleElement(ModuleElement): example with polynomials or fraction fields (:trac:`8832`):: sage: P. = QQ['q'] - sage: V = CombinatorialFreeModule(P, Permutations()) - sage: el = V(Permutation([3,1,2])) - sage: (3/2)*el + sage: V = CombinatorialFreeModule(P, Permutations()) # optional - sage.combinat + sage: el = V(Permutation([3,1,2])) # optional - sage.combinat + sage: (3/2)*el # optional - sage.combinat 3/2*B[[3, 1, 2]] sage: P. = QQ['q'] sage: F = FractionField(P) - sage: V = CombinatorialFreeModule(F, Words()) - sage: w = Words()('abc') - sage: (1+q)*V(w) + sage: V = CombinatorialFreeModule(F, Words()) # optional - sage.combinat + sage: w = Words()('abc') # optional - sage.combinat + sage: (1+q)*V(w) # optional - sage.combinat (q+1)*B[word: abc] - sage: ((1+q)/q)*V(w) + sage: ((1+q)/q)*V(w) # optional - sage.combinat ((q+1)/q)*B[word: abc] .. TODO:: diff --git a/src/sage/modules/with_basis/invariant.py b/src/sage/modules/with_basis/invariant.py index 12565a411e2..1fa4c20c23f 100644 --- a/src/sage/modules/with_basis/invariant.py +++ b/src/sage/modules/with_basis/invariant.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups r""" Invariant modules """ diff --git a/src/sage/modules/with_basis/representation.py b/src/sage/modules/with_basis/representation.py index 44b9f6115e2..1ee49a740f7 100644 --- a/src/sage/modules/with_basis/representation.py +++ b/src/sage/modules/with_basis/representation.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups """ Representations of a semigroup From b8b2c0899bb13d456d91ce2373c054359fee30bc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 11 Mar 2023 00:09:30 -0800 Subject: [PATCH 16/99] sage.modules: More # optional --- src/sage/modules/filtered_vector_space.py | 40 +-- src/sage/modules/free_module.py | 6 +- src/sage/modules/free_module_element.pyx | 6 +- src/sage/modules/free_module_homspace.py | 2 +- src/sage/modules/free_module_integer.py | 6 +- src/sage/modules/free_module_morphism.py | 24 +- ...free_quadratic_module_integer_symmetric.py | 255 +++++++++--------- src/sage/modules/tensor_operations.py | 32 +-- src/sage/modules/torsion_quadratic_module.py | 36 +-- src/sage/modules/vector_modn_dense.pyx | 2 +- src/sage/modules/vector_space_morphism.py | 142 +++++----- 11 files changed, 277 insertions(+), 274 deletions(-) diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index f30b3f058c6..60362fdcbd7 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -83,17 +83,17 @@ Any field can be used as the vector space base. For example a finite field:: - sage: F. = GF(5^3) - sage: r1 = (a, 0, F(5)); r1 + sage: F. = GF(5^3) # optional - sage.libs.pari + sage: r1 = (a, 0, F(5)); r1 # optional - sage.libs.pari (a, 0, 0) - sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=F) + sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=F) # optional - sage.libs.pari GF(125)^2 >= GF(125)^1 in GF(125)^3 Or the algebraic field:: - sage: r1 = (1, 0, 1+QQbar(I)); r1 + sage: r1 = (1, 0, 1+QQbar(I)); r1 # optional - sage.rings.number_field (1, 0, I + 1) - sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=QQbar) + sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=QQbar) # optional - sage.rings.number_field Vector space of dimension 2 over Algebraic Field >= Vector space of dimension 1 over Algebraic Field in Vector space of dimension 3 over Algebraic Field @@ -784,11 +784,11 @@ def _repr_field_name(self): sage: FilteredVectorSpace(2, base_ring=QQ)._repr_field_name() 'QQ' - sage: F. = GF(9) - sage: FilteredVectorSpace(2, base_ring=F)._repr_field_name() + sage: F. = GF(9) # optional - sage.libs.pari + sage: FilteredVectorSpace(2, base_ring=F)._repr_field_name() # optional - sage.libs.pari 'GF(9)' - sage: FilteredVectorSpace(2, base_ring=AA)._repr_field_name() + sage: FilteredVectorSpace(2, base_ring=AA)._repr_field_name() # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError @@ -822,11 +822,11 @@ def _repr_vector_space(self, dim): sage: F = FilteredVectorSpace(3, base_ring=RDF) sage: F._repr_vector_space(1234) 'RDF^1234' - sage: F3 = FilteredVectorSpace(3, base_ring=GF(3)) - sage: F3._repr_vector_space(1234) + sage: F3 = FilteredVectorSpace(3, base_ring=GF(3)) # optional - sage.libs.pari + sage: F3._repr_vector_space(1234) # optional - sage.libs.pari 'GF(3)^1234' - sage: F3 = FilteredVectorSpace(3, base_ring=AA) - sage: F3._repr_vector_space(1234) + sage: F3 = FilteredVectorSpace(3, base_ring=AA) # optional - sage.rings.number_field + sage: F3._repr_vector_space(1234) # optional - sage.rings.number_field 'Vector space of dimension 1234 over Algebraic Real Field' """ if dim == 0: @@ -880,9 +880,9 @@ def _repr_(self): QQ^1 in QQ^2 sage: FilteredVectorSpace(rays, {0:[3]}) QQ^1 >= 0 in QQ^2 - sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=GF(3)) + sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=GF(3)) # optional - sage.libs.pari GF(3)^2 >= GF(3)^1 >= GF(3)^1 >= 0 - sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=AA) + sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=AA) # optional - sage.rings.number_field Vector space of dimension 2 over Algebraic Real Field >= Vector space of dimension 1 over Algebraic Real Field >= Vector space of dimension 1 over Algebraic Real Field >= 0 @@ -926,7 +926,7 @@ def __eq__(self, other): sage: S1._filt[0].is_isomorphic(S2._filt[0]) # known bug True - sage: FilteredVectorSpace(2, base_ring=QQ) == FilteredVectorSpace(2, base_ring=GF(5)) + sage: FilteredVectorSpace(2, base_ring=QQ) == FilteredVectorSpace(2, base_ring=GF(5)) # optional - sage.libs.pari False """ if type(self) is not type(other): @@ -1107,7 +1107,7 @@ def _power_operation(self, n, operation): QQ^2 >= QQ^1 >= 0 sage: F._power_operation(2, 'symmetric') QQ^3 >= QQ^2 >= QQ^1 >= 0 - sage: F._power_operation(2, 'antisymmetric') + sage: F._power_operation(2, 'antisymmetric') # optional - sage.groups QQ^1 >= 0 """ from sage.modules.tensor_operations import VectorCollection, TensorOperation @@ -1147,13 +1147,13 @@ def exterior_power(self, n): sage: F = FilteredVectorSpace(1, 1) + FilteredVectorSpace(1, 2); F QQ^2 >= QQ^1 >= 0 - sage: F.exterior_power(1) + sage: F.exterior_power(1) # optional - sage.groups QQ^2 >= QQ^1 >= 0 - sage: F.exterior_power(2) + sage: F.exterior_power(2) # optional - sage.groups QQ^1 >= 0 - sage: F.exterior_power(3) + sage: F.exterior_power(3) # optional - sage.groups 0 - sage: F.wedge(2) + sage: F.wedge(2) # optional - sage.groups QQ^1 >= 0 """ return self._power_operation(n, 'antisymmetric') diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 64f69204fe5..abcf7deebe9 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -4206,9 +4206,9 @@ def vector_space_span(self, gens, check=True): :: sage: R. = QQ[] - sage: K = NumberField(x^2 + 1, 'a'); a = K.gen() - sage: V = VectorSpace(K, 3) - sage: V.vector_space_span([2*V.gen(0) + 3*V.gen(2)]) + sage: K = NumberField(x^2 + 1, 'a'); a = K.gen() # optional - sage.rings.number_field + sage: V = VectorSpace(K, 3) # optional - sage.rings.number_field + sage: V.vector_space_span([2*V.gen(0) + 3*V.gen(2)]) # optional - sage.rings.number_field Vector space of degree 3 and dimension 1 over Number Field in a with defining polynomial x^2 + 1 Basis matrix: [ 1 0 3/2] diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 26d0e9ba67a..a30ee533bd3 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -944,20 +944,20 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(ZZ, 4, range(4)) - sage: giac(v)+v + sage: giac(v) + v # optional - sage.libs.giac [0,2,4,6] :: sage: v = vector(QQ, 3, [2/3, 0, 5/4]) - sage: giac(v) + sage: giac(v) # optional - sage.libs.giac [2/3,0,5/4] :: sage: P. = ZZ[] sage: v = vector(P, 3, [x^2 + 2, 2*x + 1, -2*x^2 + 4*x]) - sage: giac(v) + sage: giac(v) # optional - sage.libs.giac [sageVARx^2+2,2*sageVARx+1,-2*sageVARx^2+4*sageVARx] """ return self.list() diff --git a/src/sage/modules/free_module_homspace.py b/src/sage/modules/free_module_homspace.py index f019bee9ba8..bcbe44f0d6b 100644 --- a/src/sage/modules/free_module_homspace.py +++ b/src/sage/modules/free_module_homspace.py @@ -54,7 +54,7 @@ See :trac:`13321`:: - sage: (GF(7)^2).hom([[20,0],[0,21]],ZZ^2) + sage: (GF(7)^2).hom([[20, 0], [0, 21]], ZZ^2) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: nontrivial morphisms require a coercion map from the base ring diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index 03b1d2813b2..8d8f99930b9 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -369,10 +369,10 @@ def LLL(self, *args, **kwds): ... sage: L.reduced_basis == A True - sage: old = L.reduced_basis[0].norm().n() + sage: old = L.reduced_basis[0].norm().n() # optional - sage.symbolic sage: _ = L.LLL() - sage: new = L.reduced_basis[0].norm().n() - sage: new <= old + sage: new = L.reduced_basis[0].norm().n() # optional - sage.symbolic + sage: new <= old # optional - sage.symbolic True """ basis = self.reduced_basis diff --git a/src/sage/modules/free_module_morphism.py b/src/sage/modules/free_module_morphism.py index a437bd278fa..aa1925415f3 100644 --- a/src/sage/modules/free_module_morphism.py +++ b/src/sage/modules/free_module_morphism.py @@ -495,9 +495,9 @@ def eigenvalues(self, extend=True): sage: V = QQ^2 sage: H = V.endomorphism_ring()([[0,-1], [1,0]]) - sage: H.eigenvalues() + sage: H.eigenvalues() # optional - sage.rings.number_field [-1*I, 1*I] - sage: H.eigenvalues(extend=False) + sage: H.eigenvalues(extend=False) # optional - sage.libs.pari [] """ if self.base_ring().is_field(): @@ -535,18 +535,18 @@ def eigenvectors(self, extend=True): ], 1), (1*I, [ (1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I) ], 1)] - sage: H.eigenvectors(extend=False) + sage: H.eigenvectors(extend=False) # optional - sage.rings.number_field [(3, [ (0, 0, 1, -6/7) ], 1)] sage: H1=(V.Hom(V))(matrix(QQ, [[2,1,0],[0,2,0],[0,0,3]])) - sage: H1.eigenvectors() + sage: H1.eigenvectors() # optional - sage.rings.number_field [(3, [ (0, 0, 1, -6/7) ], 1), (2, [ (0, 1, 0, 17/7) ], 2)] - sage: H1.eigenvectors(extend=False) + sage: H1.eigenvectors(extend=False) # optional - sage.rings.number_field [(3, [ (0, 0, 1, -6/7) ], 1), (2, [ @@ -557,13 +557,13 @@ def eigenvectors(self, extend=True): sage: V = QQ^2 sage: m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").eigenvectors() + sage: V.hom(m, side="right").eigenvectors() # optional - sage.rings.number_field [(1, [ (1, 0) ], 2)] - sage: V.hom(m).eigenvectors() + sage: V.hom(m).eigenvectors() # optional - sage.rings.number_field [(1, [ (0, 1) @@ -618,14 +618,14 @@ def eigenspaces(self, extend=True): Basis matrix: [ 0 1 -1*I])] - sage: h.eigenspaces(extend=False) + sage: h.eigenspaces(extend=False) # optional - sage.rings.number_field [(1, Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [1 0 0])] sage: h = V.hom([[2,1,0], [0,2,0], [0,0,-1]], V) - sage: h.eigenspaces() + sage: h.eigenspaces() # optional - sage.rings.number_field [(-1, Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [0 0 1]), @@ -634,7 +634,7 @@ def eigenspaces(self, extend=True): [0 1 0])] sage: h = V.hom([[2,1,0], [0,2,0], [0,0,2]], V) - sage: h.eigenspaces() + sage: h.eigenspaces() # optional - sage.rings.number_field [(2, Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [0 1 0] @@ -643,12 +643,12 @@ def eigenspaces(self, extend=True): :: sage: V = QQ^2; m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").eigenspaces() + sage: V.hom(m, side="right").eigenspaces() # optional - sage.rings.number_field [(1, Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: [1 0])] - sage: V.hom(m).eigenspaces() + sage: V.hom(m).eigenspaces() # optional - sage.rings.number_field [(1, Vector space of degree 2 and dimension 1 over Rational Field Basis matrix: diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index cc1576ab626..e6fea95e51f 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -155,7 +155,7 @@ def IntegralLattice(data, basis=None): (see :mod:`Cartan types ` and :class:`CartanMatrix`):: - sage: IntegralLattice(["E", 7]) + sage: IntegralLattice(["E", 7]) # optional - sage.combinat Lattice of degree 7 and rank 7 over Integer Ring Standard basis Inner product matrix: @@ -166,20 +166,20 @@ def IntegralLattice(data, basis=None): [ 0 0 0 -1 2 -1 0] [ 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 -1 2] - sage: IntegralLattice(["A", 2]) + sage: IntegralLattice(["A", 2]) # optional - sage.combinat Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: [ 2 -1] [-1 2] - sage: IntegralLattice("D3") + sage: IntegralLattice("D3") # optional - sage.combinat Lattice of degree 3 and rank 3 over Integer Ring Standard basis Inner product matrix: [ 2 -1 -1] [-1 2 0] [-1 0 2] - sage: IntegralLattice(["D", 4]) + sage: IntegralLattice(["D", 4]) # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -199,7 +199,7 @@ def IntegralLattice(data, basis=None): Inner product matrix: [0 1] [1 0] - sage: IntegralLattice(["A", 3], [[1,1,1]]) + sage: IntegralLattice(["A", 3], [[1,1,1]]) # optional - sage.combinat Lattice of degree 3 and rank 1 over Integer Ring Basis matrix: [1 1 1] @@ -212,7 +212,7 @@ def IntegralLattice(data, basis=None): Basis matrix: [1 1 1 1] Standard scalar product - sage: IntegralLattice("A2", [[1,1]]) + sage: IntegralLattice("A2", [[1,1]]) # optional - sage.combinat Lattice of degree 2 and rank 1 over Integer Ring Basis matrix: [1 1] @@ -222,11 +222,11 @@ def IntegralLattice(data, basis=None): TESTS:: - sage: IntegralLattice(["A", 1, 1]) + sage: IntegralLattice(["A", 1, 1]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: lattices must be nondegenerate; use FreeQuadraticModule instead - sage: IntegralLattice(["D", 3, 1]) + sage: IntegralLattice(["D", 3, 1]) # optional - sage.combinat Traceback (most recent call last): ... ValueError: lattices must be nondegenerate; use FreeQuadraticModule instead @@ -272,11 +272,11 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): EXAMPLES:: sage: from sage.modules.free_quadratic_module_integer_symmetric import IntegralLatticeDirectSum - sage: L1 = IntegralLattice("D4") - sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) - sage: L3 = IntegralLattice("A4", [[0, 1, 1, 2], [1, 2, 3, 1]]) - sage: Lattices = [L1, L2, L3] - sage: IntegralLatticeDirectSum([L1, L2, L3]) + sage: L1 = IntegralLattice("D4") # optional - sage.combinat + sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.combinat + sage: L3 = IntegralLattice("A4", [[0, 1, 1, 2], [1, 2, 3, 1]]) # optional - sage.combinat + sage: Lattices = [L1, L2, L3] # optional - sage.combinat + sage: IntegralLatticeDirectSum([L1, L2, L3]) # optional - sage.combinat Lattice of degree 11 and rank 7 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0 0 0 0] @@ -298,17 +298,17 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): [ 0 0 0 0 0 0 0 -1 2 -1 0] [ 0 0 0 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 0 0 0 -1 2] - sage: [L, phi] = IntegralLatticeDirectSum([L1, L2, L3], True) - sage: LL3 = L.sublattice(phi[2].image().basis_matrix()) - sage: L3.discriminant() == LL3.discriminant() + sage: [L, phi] = IntegralLatticeDirectSum([L1, L2, L3], True) # optional - sage.combinat + sage: LL3 = L.sublattice(phi[2].image().basis_matrix()) # optional - sage.combinat + sage: L3.discriminant() == LL3.discriminant() # optional - sage.combinat True - sage: x = L3([1, 2, 3, 1]) - sage: phi[2](x).inner_product(phi[2](x)) == x.inner_product(x) + sage: x = L3([1, 2, 3, 1]) # optional - sage.combinat + sage: phi[2](x).inner_product(phi[2](x)) == x.inner_product(x) # optional - sage.combinat True TESTS:: - sage: IntegralLatticeDirectSum([IntegralLattice("D4")]) + sage: IntegralLatticeDirectSum([IntegralLattice("D4")]) # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -318,9 +318,9 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): [ 0 -1 0 2] sage: L1 = IntegralLattice(2 * matrix.identity(2), [[1/2, 1/2]]) - sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) - sage: [L, phi] = IntegralLatticeDirectSum([L1, L2], True) - sage: L + sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.combinat + sage: [L, phi] = IntegralLatticeDirectSum([L1, L2], True) # optional - sage.combinat + sage: L # optional - sage.combinat Lattice of degree 5 and rank 2 over Integer Ring Basis matrix: [1/2 1/2 0 0 0] @@ -416,18 +416,18 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Inner product matrix: [4]]] - sage: L1 = IntegralLattice([[2]]) - sage: L2 = IntegralLattice([[2]]) - sage: AL1 = L1.discriminant_group() - sage: AL2 = L2.discriminant_group() - sage: AL1 + sage: L1 = IntegralLattice([[2]]) # optional - sage.combinat + sage: L2 = IntegralLattice([[2]]) # optional - sage.combinat + sage: AL1 = L1.discriminant_group() # optional - sage.combinat + sage: AL2 = L2.discriminant_group() # optional - sage.combinat + sage: AL1 # optional - sage.combinat Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1/2] - sage: g1 = L1.discriminant_group().gens()[0] - sage: g2 = L2.discriminant_group().gens()[0] - sage: glue = [[g1, g2]] - sage: IntegralLatticeGluing([L1, L2], glue) + sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.combinat + sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.combinat + sage: glue = [[g1, g2]] # optional - sage.combinat + sage: IntegralLatticeGluing([L1, L2], glue) # optional - sage.combinat Lattice of degree 2 and rank 2 over Integer Ring Basis matrix: [1/2 1/2] @@ -436,13 +436,13 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [2 0] [0 2] - sage: L1 = IntegralLattice("A4") - sage: L2 = IntegralLattice("A4") - sage: g1 = L1.discriminant_group().gens()[0] - sage: g2 = L2.discriminant_group().gens()[0] - sage: glue = [[g1, 2 * g2]] - sage: [V, phi] = IntegralLatticeGluing([L1, L2], glue, True) - sage: V + sage: L1 = IntegralLattice("A4") # optional - sage.combinat + sage: L2 = IntegralLattice("A4") # optional - sage.combinat + sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.combinat + sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.combinat + sage: glue = [[g1, 2 * g2]] # optional - sage.combinat + sage: [V, phi] = IntegralLatticeGluing([L1, L2], glue, True) # optional - sage.combinat + sage: V # optional - sage.combinat Lattice of degree 8 and rank 8 over Integer Ring Basis matrix: [1/5 2/5 3/5 4/5 2/5 4/5 1/5 3/5] @@ -462,7 +462,7 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [ 0 0 0 0 -1 2 -1 0] [ 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 -1 2] - sage: V.sublattice(phi[0].image().basis_matrix()) + sage: V.sublattice(phi[0].image().basis_matrix()) # optional - sage.combinat Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -481,8 +481,8 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Different gluings can be composed:: - sage: D4 = IntegralLattice("D4") - sage: D4.discriminant_group() + sage: D4 = IntegralLattice("D4") # optional - sage.combinat + sage: D4.discriminant_group() # optional - sage.combinat Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] @@ -493,23 +493,23 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Gram matrix of the quadratic form with values in Q/2Z: [1/2 0] [ 0 1/2] - sage: g1 = D4.discriminant_group().gens()[0] + sage: g1 = D4.discriminant_group().gens()[0] # optional - sage.combinat sage: g2 = L2.discriminant_group().gens()[0] + L2.discriminant_group().gens()[1] - sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) - sage: AD6 = D6.discriminant_group() - sage: AD6.normal_form() + sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) # optional - sage.combinat + sage: AD6 = D6.discriminant_group() # optional - sage.combinat + sage: AD6.normal_form() # optional - sage.combinat Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [3/2 0] [ 0 3/2] - sage: f1, g1 = AD6.normal_form().gens() + sage: f1, g1 = AD6.normal_form().gens() # optional - sage.combinat sage: f2, g2 = L2.discriminant_group().gens() - sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) - sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) - sage: x = D4([1, 0, 0, 0]) - sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x)))==x.inner_product(x) + sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) # optional - sage.combinat + sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) # optional - sage.combinat + sage: x = D4([1, 0, 0, 0]) # optional - sage.combinat + sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x))) == x.inner_product(x) # optional - sage.combinat True - sage: D4embed + sage: D4embed # optional - sage.combinat Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -528,27 +528,27 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): The input may be a list of three or more lattices:: - sage: A7 = IntegralLattice("A7") - sage: D5 = IntegralLattice("D5") - sage: gA7 = A7.discriminant_group().gens()[0] - sage: gD5 = D5.discriminant_group().gens()[0] - sage: [L, phi] = IntegralLatticeGluing([A7, A7, D5, D5], + sage: A7 = IntegralLattice("A7") # optional - sage.combinat + sage: D5 = IntegralLattice("D5") # optional - sage.combinat + sage: gA7 = A7.discriminant_group().gens()[0] # optional - sage.combinat + sage: gD5 = D5.discriminant_group().gens()[0] # optional - sage.combinat + sage: [L, phi] = IntegralLatticeGluing([A7, A7, D5, D5], # optional - sage.combinat ....: [[gA7, gA7, gD5, 2 * gD5], ....: [gA7, 7 * gA7, 2 * gD5, gD5]], True) - sage: L.determinant() + sage: L.determinant() # optional - sage.combinat 1 - sage: B = phi[0].matrix() - sage: B*L.gram_matrix()*B.transpose()==A7.gram_matrix() + sage: B = phi[0].matrix() # optional - sage.combinat + sage: B*L.gram_matrix()*B.transpose() == A7.gram_matrix() # optional - sage.combinat True The gluing takes place in the direct sum of the respective ambient spaces:: - sage: L1 = IntegralLattice("D4", [[1, 1, 0, 0], [0, 1, 1, 0]]) - sage: L2 = IntegralLattice("E6", [[0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1]]) - sage: [f1, f2] = L1.discriminant_group().gens() - sage: [g1, g2] = L2.discriminant_group().gens() - sage: [L, phi] = IntegralLatticeGluing([L1, L2], [[f1, g1], [f2, 2 * g2]], True) - sage: phi[0] + sage: L1 = IntegralLattice("D4", [[1, 1, 0, 0], [0, 1, 1, 0]]) # optional - sage.combinat + sage: L2 = IntegralLattice("E6", [[0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1]]) # optional - sage.combinat + sage: [f1, f2] = L1.discriminant_group().gens() # optional - sage.combinat + sage: [g1, g2] = L2.discriminant_group().gens() # optional - sage.combinat + sage: [L, phi] = IntegralLatticeGluing([L1, L2], [[f1, g1], [f2, 2 * g2]], True) # optional - sage.combinat + sage: phi[0] # optional - sage.combinat Free module morphism defined by the matrix [ 2 2 -2 -1] [ 0 2 -1 0] @@ -578,8 +578,8 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [ 0 0 0 0 0 -1 -1 2 -1 0] [ 0 0 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 0 0 -1 2] - sage: B = phi[0].matrix() - sage: B * L.gram_matrix() * B.transpose()==L1.gram_matrix() + sage: B = phi[0].matrix() # optional - sage.combinat + sage: B * L.gram_matrix() * B.transpose() == L1.gram_matrix() # optional - sage.combinat True """ [direct_sum, phi] = IntegralLatticeDirectSum(Lattices, return_embeddings=True) @@ -695,8 +695,8 @@ def _repr_(self): EXAMPLES:: - sage: A2 = IntegralLattice("A2") - sage: A2 + sage: A2 = IntegralLattice("A2") # optional - sage.combinat + sage: A2 # optional - sage.combinat Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: @@ -731,7 +731,7 @@ def is_even(self): sage: L = IntegralLattice(G) sage: L.is_even() False - sage: L = IntegralLattice("A2") + sage: L = IntegralLattice("A2") # optional - sage.combinat sage: L.is_even() True """ @@ -750,8 +750,8 @@ def dual_lattice(self): EXAMPLES:: - sage: L = IntegralLattice("A2") - sage: Ldual = L.dual_lattice(); Ldual + sage: L = IntegralLattice("A2") # optional - sage.combinat + sage: Ldual = L.dual_lattice(); Ldual # optional - sage.combinat Free module of degree 2 and rank 2 over Integer Ring Echelon basis matrix: [1/3 2/3] @@ -759,7 +759,7 @@ def dual_lattice(self): Since our lattices are always integral, a lattice is contained in its dual:: - sage: L.is_submodule(Ldual) + sage: L.is_submodule(Ldual) # optional - sage.combinat True """ return self.span(self.gram_matrix().inverse()*self.basis_matrix()) @@ -807,13 +807,13 @@ def discriminant_group(self, s=0): sage: import gc sage: gc.freeze() - sage: L = IntegralLattice("A2") - sage: for k in range(1,500): # long time + sage: L = IntegralLattice("A2") # optional - sage.combinat + sage: for k in range(1,500): # long time # optional - sage.combinat ....: G = L.twist(k) ....: D = G.discriminant_group() - sage: tmp = gc.collect() - sage: tmp = gc.collect() - sage: len([a for a in gc.get_objects() if type(a)==type(L)])<=300 + sage: tmp = gc.collect() # optional - sage.combinat + sage: tmp = gc.collect() # optional - sage.combinat + sage: len([a for a in gc.get_objects() if type(a) == type(L)]) <= 300 # optional - sage.combinat True sage: gc.unfreeze() """ @@ -849,8 +849,8 @@ def signature_pair(self): EXAMPLES:: - sage: A2 = IntegralLattice("A2") - sage: A2.signature_pair() + sage: A2 = IntegralLattice("A2") # optional - sage.combinat + sage: A2.signature_pair() # optional - sage.combinat (2, 0) """ from sage.quadratic_forms.quadratic_form import QuadraticForm @@ -1029,12 +1029,12 @@ def maximal_overlattice(self, p=None): EXAMPLES:: - sage: L = IntegralLattice("A4").twist(25*89) - sage: L.maximal_overlattice().determinant() + sage: L = IntegralLattice("A4").twist(25*89) # optional - sage.combinat + sage: L.maximal_overlattice().determinant() # optional - sage.combinat 5 - sage: L.maximal_overlattice(89).determinant().factor() + sage: L.maximal_overlattice(89).determinant().factor() # optional - sage.combinat 5^9 - sage: L.maximal_overlattice(5).determinant().factor() + sage: L.maximal_overlattice(5).determinant().factor() # optional - sage.combinat 5 * 89^4 TESTS:: @@ -1164,8 +1164,8 @@ def orthogonal_group(self, gens=None, is_finite=None): EXAMPLES:: - sage: A4 = IntegralLattice("A4") - sage: Aut = A4.orthogonal_group(); Aut + sage: A4 = IntegralLattice("A4") # optional - sage.combinat + sage: Aut = A4.orthogonal_group(); Aut # optional - sage.combinat Group of isometries with 4 generators ( [0 0 0 1] [-1 -1 -1 0] [ 1 0 0 0] [ 1 0 0 0] [0 0 1 0] [ 0 0 0 -1] [-1 -1 -1 -1] [ 0 1 0 0] @@ -1175,35 +1175,36 @@ def orthogonal_group(self, gens=None, is_finite=None): The group acts from the right on the lattice and its discriminant group:: - sage: x = A4.an_element() - sage: g = Aut.an_element(); g + sage: x = A4.an_element() # optional - sage.combinat + sage: g = Aut.an_element(); g # optional - sage.combinat [-1 -1 -1 0] [ 0 0 1 0] [ 0 0 -1 -1] [ 0 1 1 1] - sage: x*g + sage: x*g # optional - sage.combinat (-1, -1, -1, 0) - sage: (x*g).parent() == A4 + sage: (x*g).parent() == A4 # optional - sage.combinat True - sage: (g*x).parent() + sage: (g*x).parent() # optional - sage.combinat Vector space of dimension 4 over Rational Field - sage: y = A4.discriminant_group().an_element() - sage: y*g + sage: y = A4.discriminant_group().an_element() # optional - sage.combinat + sage: y*g # optional - sage.combinat (4) If the group is finite we can compute the usual things:: - sage: Aut.order() + sage: Aut.order() # optional - sage.combinat 240 - sage: conj = Aut.conjugacy_classes_representatives() - sage: len(conj) + sage: conj = Aut.conjugacy_classes_representatives() # optional - sage.combinat + sage: len(conj) # optional - sage.combinat 14 - sage: Aut.structure_description() + sage: Aut.structure_description() # optional - sage.combinat 'C2 x S5' The lattice can live in a larger ambient space:: - sage: A2 = IntegralLattice(matrix.identity(3), Matrix(ZZ, 2, 3, [1,-1,0,0,1,-1])) + sage: A2 = IntegralLattice(matrix.identity(3), + ....: Matrix(ZZ, 2, 3, [1,-1,0, 0,1,-1])) sage: A2.orthogonal_group() Group of isometries with 2 generators ( [ 2/3 2/3 -1/3] [1 0 0] @@ -1213,7 +1214,7 @@ def orthogonal_group(self, gens=None, is_finite=None): It can be negative definite as well:: - sage: A2m = IntegralLattice(-Matrix(ZZ, 2, [2,1,1,2])) + sage: A2m = IntegralLattice(-Matrix(ZZ, 2, [2,1, 1,2])) sage: G = A2m.orthogonal_group() sage: G.order() 12 @@ -1221,7 +1222,7 @@ def orthogonal_group(self, gens=None, is_finite=None): If the lattice is indefinite, sage does not know how to compute generators. Can you teach it?:: - sage: U = IntegralLattice(Matrix(ZZ, 2, [0,1,1,0])) + sage: U = IntegralLattice(Matrix(ZZ, 2, [0,1, 1,0])) sage: U.orthogonal_group() Traceback (most recent call last): ... @@ -1231,7 +1232,7 @@ def orthogonal_group(self, gens=None, is_finite=None): But we can define subgroups:: sage: S = IntegralLattice(Matrix(ZZ, 2, [2, 3, 3, 2])) - sage: f = Matrix(ZZ, 2, [0,1,-1,3]) + sage: f = Matrix(ZZ, 2, [0,1, -1,3]) sage: S.orthogonal_group([f]) Group of isometries with 1 generator ( [ 0 1] @@ -1324,8 +1325,8 @@ def tensor_product(self, other, discard_basis=False): EXAMPLES:: - sage: L = IntegralLattice("D3", [[1,-1,0], [0,1,-1]]) - sage: L1 = L.tensor_product(L); L1 + sage: L = IntegralLattice("D3", [[1,-1,0], [0,1,-1]]) # optional - sage.combinat + sage: L1 = L.tensor_product(L); L1 # optional - sage.combinat Lattice of degree 9 and rank 4 over Integer Ring Basis matrix: [ 1 -1 0 -1 1 0 0 0 0] @@ -1342,12 +1343,12 @@ def tensor_product(self, other, discard_basis=False): [-2 1 1 0 0 0 4 -2 -2] [ 1 -2 0 0 0 0 -2 4 0] [ 1 0 -2 0 0 0 -2 0 4] - sage: L1.gram_matrix() + sage: L1.gram_matrix() # optional - sage.combinat [ 36 -12 -12 4] [-12 24 4 -8] [-12 4 24 -8] [ 4 -8 -8 16] - sage: L2 = L.tensor_product(L, True); L2 + sage: L2 = L.tensor_product(L, True); L2 # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -1378,8 +1379,8 @@ def quadratic_form(self): EXAMPLES:: - sage: L = IntegralLattice("A2") - sage: q = L.quadratic_form(); q + sage: L = IntegralLattice("A2") # optional - sage.combinat + sage: q = L.quadratic_form(); q # optional - sage.combinat Quadratic form in 2 variables over Integer Ring with coefficients: [ 2 -2 ] [ * 2 ] @@ -1398,10 +1399,10 @@ def minimum(self): EXAMPLES:: - sage: L = IntegralLattice('A2') - sage: L.minimum() + sage: L = IntegralLattice('A2') # optional - sage.combinat + sage: L.minimum() # optional - sage.combinat 2 - sage: L.twist(-1).minimum() + sage: L.twist(-1).minimum() # optional - sage.combinat -Infinity """ p, n = self.signature_pair() @@ -1424,10 +1425,10 @@ def maximum(self): EXAMPLES:: - sage: L = IntegralLattice('A2') - sage: L.maximum() + sage: L = IntegralLattice('A2') # optional - sage.combinat + sage: L.maximum() # optional - sage.combinat +Infinity - sage: L.twist(-1).maximum() + sage: L.twist(-1).maximum() # optional - sage.combinat -2 """ if self.rank() == 0: @@ -1448,8 +1449,8 @@ def LLL(self): EXAMPLES:: - sage: L = IntegralLattice('A2') - sage: L.lll() == L + sage: L = IntegralLattice('A2') # optional - sage.combinat + sage: L.lll() == L # optional - sage.combinat True sage: G = matrix(ZZ, 3, [0,1,0, 1,0,0, 0,0,7]) sage: V = matrix(ZZ, 3, [-14,-15,-15, -4,1,16, -5,-5,-4]) @@ -1495,10 +1496,10 @@ def short_vectors(self, n, **kwargs): EXAMPLES:: - sage: A2 = IntegralLattice('A2') - sage: A2.short_vectors(3) + sage: A2 = IntegralLattice('A2') # optional - sage.combinat + sage: A2.short_vectors(3) # optional - sage.combinat [[(0, 0)], [], [(1, 1), (-1, -1), (0, 1), (0, -1), (1, 0), (-1, 0)]] - sage: A2.short_vectors(3,up_to_sign_flag=True) + sage: A2.short_vectors(3,up_to_sign_flag=True) # optional - sage.combinat [[(0, 0)], [], [(1, 1), (0, 1), (1, 0)]] """ p, m = self.signature_pair() @@ -1525,8 +1526,8 @@ def twist(self, s, discard_basis=False): EXAMPLES:: - sage: L = IntegralLattice("A4") - sage: L.twist(3) + sage: L = IntegralLattice("A4") # optional - sage.combinat + sage: L.twist(3) # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -1588,15 +1589,15 @@ def local_modification(M, G, p, check=True): EXAMPLES:: sage: from sage.modules.free_quadratic_module_integer_symmetric import local_modification - sage: L = IntegralLattice("A3").twist(15) - sage: M = L.maximal_overlattice() - sage: for p in prime_divisors(L.determinant()): + sage: L = IntegralLattice("A3").twist(15) # optional - sage.combinat + sage: M = L.maximal_overlattice() # optional - sage.combinat + sage: for p in prime_divisors(L.determinant()): # optional - sage.combinat ....: M = local_modification(M, L.gram_matrix(), p) - sage: M.genus() == L.genus() + sage: M.genus() == L.genus() # optional - sage.combinat True - sage: L = IntegralLattice("D4").twist(3*4) - sage: M = L.maximal_overlattice() - sage: local_modification(M, L.gram_matrix(), 2) + sage: L = IntegralLattice("D4").twist(3*4) # optional - sage.combinat + sage: M = L.maximal_overlattice() # optional - sage.combinat + sage: local_modification(M, L.gram_matrix(), 2) # optional - sage.combinat Lattice of degree 4 and rank 4 over Integer Ring Basis matrix: [1/3 0 2/3 2/3] diff --git a/src/sage/modules/tensor_operations.py b/src/sage/modules/tensor_operations.py index fafd5cc3a89..e82c5a4341a 100644 --- a/src/sage/modules/tensor_operations.py +++ b/src/sage/modules/tensor_operations.py @@ -119,7 +119,7 @@ def antisymmetrized_coordinate_sums(dim, n): EXAMPLES:: sage: from sage.modules.tensor_operations import antisymmetrized_coordinate_sums - sage: antisymmetrized_coordinate_sums(3, 2) + sage: antisymmetrized_coordinate_sums(3, 2) # optional - sage.groups ((0, 1) - (1, 0), (0, 2) - (2, 0), (1, 2) - (2, 1)) """ from sage.structure.formal_sum import FormalSum @@ -379,8 +379,8 @@ def _init_power_operation_vectors(self, i, linear_combinations): sage: Sym2_R = TensorOperation([R,R], operation='symmetric') sage: Sym2_R.vectors() # indirect doctest ((1, 0, 0), (1, 2, 0), (-1, -2, 0), (1, 4, 4), (-1, -4, -4)) - sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') - sage: Alt2_R.vectors() # indirect doctest + sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # optional - sage.groups + sage: Alt2_R.vectors() # indirect doctest # optional - sage.groups ((2), (-2)) """ rays = [self._V[j].vectors()[k] for j, k in enumerate(i)] @@ -453,8 +453,8 @@ def _init_antisymmetric(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (1,2), (-1,-2)], QQ, 2) - sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # indirect doctest - sage: sorted(Alt2_R._index_map.items()) + sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # indirect doctest # optional - sage.groups + sage: sorted(Alt2_R._index_map.items()) # optional - sage.groups [((0, 1), 0), ((0, 2), 1)] """ n = len(self._V) @@ -517,17 +517,17 @@ def index_map(self, *i): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') - sage: detR.index_map(1, 0) + sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups + sage: detR.index_map(1, 0) # optional - sage.groups 0 - sage: detR.index_map(0, 1) + sage: detR.index_map(0, 1) # optional - sage.groups 0 TESTS:: - sage: sorted(detR._index_map.items()) + sage: sorted(detR._index_map.items()) # optional - sage.groups [((0, 1), 0), ((0, 2), 1), ((1, 2), 2)] - sage: detR.vectors() + sage: detR.vectors() # optional - sage.groups ((1), (-3), (2)) """ if len(i) == 1 and isinstance(i[0], (list, tuple)): @@ -553,10 +553,10 @@ def preimage(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') - sage: sorted(detR.preimage()) + sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups + sage: sorted(detR.preimage()) # optional - sage.groups [(0, 1), (0, 2), (1, 2)] - sage: sorted(detR.codomain()) + sage: sorted(detR.codomain()) # optional - sage.groups [0, 1, 2] """ return self._index_map.keys() @@ -574,10 +574,10 @@ def codomain(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') - sage: sorted(detR.preimage()) + sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups + sage: sorted(detR.preimage()) # optional - sage.groups [(0, 1), (0, 2), (1, 2)] - sage: sorted(detR.codomain()) + sage: sorted(detR.codomain()) # optional - sage.groups [0, 1, 2] """ return self._index_map.values() diff --git a/src/sage/modules/torsion_quadratic_module.py b/src/sage/modules/torsion_quadratic_module.py index 1b9825703f3..15a9788ea12 100644 --- a/src/sage/modules/torsion_quadratic_module.py +++ b/src/sage/modules/torsion_quadratic_module.py @@ -375,8 +375,8 @@ def all_submodules(self): EXAMPLES:: - sage: D = IntegralLattice("D4").discriminant_group() - sage: D.all_submodules() + sage: D = IntegralLattice("D4").discriminant_group() # optional - sage.combinat + sage: D.all_submodules() # optional - sage.combinat [Finite quadratic module over Integer Ring with invariants () Gram matrix of the quadratic form with values in Q/2Z: [], @@ -429,9 +429,9 @@ def brown_invariant(self): EXAMPLES:: - sage: L = IntegralLattice("D4") - sage: D = L.discriminant_group() - sage: D.brown_invariant() + sage: L = IntegralLattice("D4") # optional - sage.combinat + sage: D = L.discriminant_group() # optional - sage.combinat + sage: D.brown_invariant() # optional - sage.combinat 4 We require the quadratic form to be defined modulo `2 \ZZ`:: @@ -588,7 +588,7 @@ def genus(self, signature_pair): We can also compute the genus of an odd lattice from its discriminant form:: - sage: L = IntegralLattice(matrix.diagonal(range(1,5))) + sage: L = IntegralLattice(matrix.diagonal(range(1, 5))) sage: D = L.discriminant_group() sage: D.genus((4,0)) # optional - sage.libs.pari Genus of @@ -755,18 +755,18 @@ def is_genus(self, signature_pair, even=True): EXAMPLES:: - sage: L3 = IntegralLattice(3 * Matrix(ZZ, 2, [2,1,1,2])) - sage: L = IntegralLattice("D4").direct_sum(L3) - sage: D = L.discriminant_group() - sage: D.is_genus((6,0)) + sage: L3 = IntegralLattice(3 * Matrix(ZZ, 2, [2,1,1,2])) # optional - sage.combinat + sage: L = IntegralLattice("D4").direct_sum(L3) # optional - sage.combinat + sage: D = L.discriminant_group() # optional - sage.combinat + sage: D.is_genus((6,0)) # optional - sage.combinat True Let us see if there is a lattice in the genus defined by the same discriminant form but with a different signature:: - sage: D.is_genus((4,2)) + sage: D.is_genus((4,2)) # optional - sage.combinat False - sage: D.is_genus((16,2)) + sage: D.is_genus((16,2)) # optional - sage.combinat True """ s_plus = ZZ(signature_pair[0]) @@ -990,13 +990,13 @@ def normal_form(self, partial=False): EXAMPLES:: sage: L1 = IntegralLattice(matrix([[-2,0,0], [0,1,0], [0,0,4]])) - sage: L1.discriminant_group().normal_form() + sage: L1.discriminant_group().normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4) Gram matrix of the quadratic form with values in Q/Z: [1/2 0] [ 0 1/4] sage: L2 = IntegralLattice(matrix([[-2,0,0], [0,1,0], [0,0,-4]])) - sage: L2.discriminant_group().normal_form() + sage: L2.discriminant_group().normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4) Gram matrix of the quadratic form with values in Q/Z: [1/2 0] @@ -1008,13 +1008,13 @@ def normal_form(self, partial=False): sage: AL1 = L1.discriminant_group() sage: L2 = IntegralLattice(matrix([[-4,0,0], [0,-4,0], [0,0,2]])) sage: AL2 = L2.discriminant_group() - sage: AL1.normal_form() + sage: AL1.normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] [ 0 1/4 0] [ 0 0 5/4] - sage: AL2.normal_form() + sage: AL2.normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] @@ -1034,7 +1034,7 @@ def normal_form(self, partial=False): [ 1/12 1/6 1/36 1/9] [ 5/36 1/36 1/36 11/72] [ 1/36 1/9 11/72 1/36] - sage: T.normal_form() + sage: T.normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/3)Z: [ 1/6 1/12 0 0 0 0 0 0] @@ -1051,7 +1051,7 @@ def normal_form(self, partial=False): A degenerate case:: sage: T = TorsionQuadraticModule((1/6)*D4dual, D4, modulus=1/36) - sage: T.normal_form() + sage: T.normal_form() # optional - sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/18)Z: [1/36 1/72 0 0 0 0 0 0] diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index ebaaca87540..c36e1d96f0a 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -88,7 +88,7 @@ Test that :trac:`28042` is fixed:: sage: c = K(109320) # optional - sage.libs.pari sage: d = K(167667) # optional - sage.libs.pari sage: e = 103937 # optional - sage.libs.pari - sage: a*c + b*d - e + sage: a*c + b*d - e # optional - sage.libs.pari 102041 sage: vector([a,b]) * vector([c,d]) - e # optional - sage.libs.pari 102041 diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 8044ed8dd4c..81200afbb1d 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -41,12 +41,12 @@ sage: F = Integers(13) sage: D = F^3 sage: C = F^2 - sage: x, y, z = var('x y z') - sage: f(x, y, z) = [2*x + 3*y + 5*z, x + z] - sage: rho = linear_transformation(D, C, f) - sage: f(1, 2, 3) + sage: x, y, z = var('x y z') # optional - sage.symbolic + sage: f(x, y, z) = [2*x + 3*y + 5*z, x + z] # optional - sage.symbolic + sage: rho = linear_transformation(D, C, f) # optional - sage.symbolic + sage: f(1, 2, 3) # optional - sage.symbolic (23, 4) - sage: rho([1, 2, 3]) + sage: rho([1, 2, 3]) # optional - sage.symbolic (10, 4) A "vector space homspace" is the set of all linear transformations @@ -70,19 +70,21 @@ A homomorphism may also be created via a method on the domain. :: - sage: F = QQ[sqrt(3)] - sage: a = F.gen(0) - sage: D = F^2 - sage: C = F^2 - sage: A = matrix(F, [[a, 1], [2*a, 2]]) - sage: psi = D.hom(A, C) - sage: psi + sage: F = QQ[sqrt(3)] # optional - sage.rings.number_field sage.symbolic + sage: a = F.gen(0) # optional - sage.rings.number_field sage.symbolic + sage: D = F^2 # optional - sage.rings.number_field sage.symbolic + sage: C = F^2 # optional - sage.rings.number_field sage.symbolic + sage: A = matrix(F, [[a, 1], [2*a, 2]]) # optional - sage.rings.number_field sage.symbolic + sage: psi = D.hom(A, C) # optional - sage.rings.number_field sage.symbolic + sage: psi # optional - sage.rings.number_field sage.symbolic Vector space morphism represented by the matrix: [ sqrt3 1] [2*sqrt3 2] - Domain: Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - Codomain: Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - sage: psi([1, 4]) + Domain: Vector space of dimension 2 over Number Field in sqrt3 + with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? + Codomain: Vector space of dimension 2 over Number Field in sqrt3 + with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? + sage: psi([1, 4]) # optional - sage.rings.number_field sage.symbolic (9*sqrt3, 9) Properties @@ -149,10 +151,10 @@ matrix representation used to represent linear transformations are relative to the bases of both the domain and codomain. :: - sage: A = graphs.PetersenGraph().adjacency_matrix() + sage: A = graphs.PetersenGraph().adjacency_matrix() # optional - sage.graphs sage: V = QQ^10 - sage: phi = linear_transformation(V, V, A) - sage: phi + sage: phi = linear_transformation(V, V, A) # optional - sage.graphs + sage: phi # optional - sage.graphs Vector space morphism represented by the matrix: [0 1 0 0 1 1 0 0 0 0] [1 0 1 0 0 0 1 0 0 0] @@ -167,13 +169,13 @@ Domain: Vector space of dimension 10 over Rational Field Codomain: Vector space of dimension 10 over Rational Field - sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] - sage: B2 = [V.gen(0)] + [-V.gen(i-1) + V.gen(i) for i in range(1,10)] - sage: D = V.subspace_with_basis(B1) - sage: C = V.subspace_with_basis(B2) - sage: rho = phi.restrict_codomain(C) - sage: zeta = rho.restrict_domain(D) - sage: zeta + sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] # optional - sage.graphs + sage: B2 = [V.gen(0)] + [-V.gen(i-1) + V.gen(i) for i in range(1,10)] # optional - sage.graphs + sage: D = V.subspace_with_basis(B1) # optional - sage.graphs + sage: C = V.subspace_with_basis(B2) # optional - sage.graphs + sage: rho = phi.restrict_codomain(C) # optional - sage.graphs + sage: zeta = rho.restrict_domain(D) # optional - sage.graphs + sage: zeta # optional - sage.graphs Vector space morphism represented by the matrix: [6 5 4 3 3 2 1 0 0 0] [6 5 4 3 2 2 2 1 0 0] @@ -215,16 +217,16 @@ matrix that has well-behaved eigenvalues, as part of showing that these do not change as the representation changes. :: - sage: A = graphs.PetersenGraph().adjacency_matrix() + sage: A = graphs.PetersenGraph().adjacency_matrix() # optional - sage.graphs sage: V = QQ^10 - sage: phi = linear_transformation(V, V, A) - sage: phi.eigenvalues() + sage: phi = linear_transformation(V, V, A) # optional - sage.graphs + sage: phi.eigenvalues() # optional - sage.graphs [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] - sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] - sage: C = V.subspace_with_basis(B1) - sage: zeta = phi.restrict(C) - sage: zeta + sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] # optional - sage.graphs + sage: C = V.subspace_with_basis(B1) # optional - sage.graphs + sage: zeta = phi.restrict(C) # optional - sage.graphs + sage: zeta # optional - sage.graphs Vector space morphism represented by the matrix: [ 1 0 1 -1 2 -1 2 -2 2 -2] [ 1 0 1 0 0 0 1 0 0 0] @@ -261,7 +263,7 @@ [0 0 0 0 0 0 0 0 1 1] [0 0 0 0 0 0 0 0 0 1] - sage: zeta.eigenvalues() + sage: zeta.eigenvalues() # optional - sage.graphs [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] Equality @@ -495,10 +497,10 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field - sage: x, y, z = var('x y z') - sage: h(x, y, z) = [2*x + z, 5*y] - sage: zeta = linear_transformation(QQ^3, QQ^2, h) - sage: zeta + sage: x, y, z = var('x y z') # optional - sage.symbolic + sage: h(x, y, z) = [2*x + z, 5*y] # optional - sage.symbolic + sage: zeta = linear_transformation(QQ^3, QQ^2, h) # optional - sage.symbolic + sage: zeta # optional - sage.symbolic Vector space morphism represented by the matrix: [2 0] [0 5] @@ -508,7 +510,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): sage: phi == rho True - sage: rho == zeta + sage: rho == zeta # optional - sage.symbolic True @@ -536,10 +538,10 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): [2 5] [3 7] - sage: s, t = var('s t') - sage: h(s, t) = [(-4/5)*s + (1/5)*t, (97/5)*s + (-13/5)*t] - sage: zeta = linear_transformation(D, C, h) - sage: zeta.matrix() + sage: s, t = var('s t') # optional - sage.symbolic + sage: h(s, t) = [(-4/5)*s + (1/5)*t, (97/5)*s + (-13/5)*t] # optional - sage.symbolic + sage: zeta = linear_transformation(D, C, h) # optional - sage.symbolic + sage: zeta.matrix() # optional - sage.symbolic [2 5] [3 7] @@ -547,21 +549,21 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): elements of the domain. :: sage: x = polygen(QQ) - sage: F. = NumberField(x^3+x+1) - sage: u = vector(F, [1, a, a^2]) - sage: v = vector(F, [a, a^2, 2]) - sage: w = u + v - sage: D = F^3 - sage: C = F^3 - sage: rho = linear_transformation(D, C, [u, v, w]) - sage: rho.matrix() + sage: F. = NumberField(x^3 + x + 1) # optional - sage.rings.number_field + sage: u = vector(F, [1, a, a^2]) # optional - sage.rings.number_field + sage: v = vector(F, [a, a^2, 2]) # optional - sage.rings.number_field + sage: w = u + v # optional - sage.rings.number_field + sage: D = F^3 # optional - sage.rings.number_field + sage: C = F^3 # optional - sage.rings.number_field + sage: rho = linear_transformation(D, C, [u, v, w]) # optional - sage.rings.number_field + sage: rho.matrix() # optional - sage.rings.number_field [ 1 a a^2] [ a a^2 2] [ a + 1 a^2 + a a^2 + 2] - sage: C = (F^3).subspace_with_basis([u, v]) - sage: D = (F^3).subspace_with_basis([u, v]) - sage: psi = linear_transformation(C, D, [u+v, u-v]) - sage: psi.matrix() + sage: C = (F^3).subspace_with_basis([u, v]) # optional - sage.rings.number_field + sage: D = (F^3).subspace_with_basis([u, v]) # optional - sage.rings.number_field + sage: psi = linear_transformation(C, D, [u+v, u-v]) # optional - sage.rings.number_field + sage: psi.matrix() # optional - sage.rings.number_field [ 1 1] [ 1 -1] @@ -655,30 +657,30 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): A Sage symbolic function can come in a variety of forms that are not representative of a linear transformation. :: - sage: x, y = var('x, y') - sage: f(x, y) = [y, x, y] - sage: linear_transformation(QQ^3, QQ^3, f) + sage: x, y = var('x, y') # optional - sage.symbolic + sage: f(x, y) = [y, x, y] # optional - sage.symbolic + sage: linear_transformation(QQ^3, QQ^3, f) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function has the wrong number of inputs for domain - sage: linear_transformation(QQ^2, QQ^2, f) + sage: linear_transformation(QQ^2, QQ^2, f) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function has the wrong number of outputs for codomain - sage: x, y = var('x y') - sage: f(x, y) = [y, x*y] - sage: linear_transformation(QQ^2, QQ^2, f) + sage: x, y = var('x y') # optional - sage.symbolic + sage: f(x, y) = [y, x*y] # optional - sage.symbolic + sage: linear_transformation(QQ^2, QQ^2, f) # optional - sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function must be linear in all the inputs: unable to convert y to a rational - sage: x, y = var('x y') - sage: f(x, y) = [x, 2*y] + sage: x, y = var('x y') # optional - sage.symbolic + sage: f(x, y) = [x, 2*y] # optional - sage.symbolic sage: C = (QQ^2).span([vector(QQ, [1, 1])]) - sage: linear_transformation(QQ^2, C, f) + sage: linear_transformation(QQ^2, C, f) # optional - sage.symbolic Traceback (most recent call last): ... ArithmeticError: some image of the function is not in the codomain, because @@ -902,15 +904,15 @@ def is_invertible(self): A non-invertible linear transformation, an endomorphism of a vector space over a finite field. :: - sage: F. = GF(11^2) - sage: A = matrix(F, [[6*a + 3, 8*a + 2, 10*a + 3], + sage: F. = GF(11^2) # optional - sage.libs.pari + sage: A = matrix(F, [[6*a + 3, 8*a + 2, 10*a + 3], # optional - sage.libs.pari ....: [2*a + 7, 4*a + 3, 2*a + 3], ....: [9*a + 2, 10*a + 10, 3*a + 3]]) - sage: A.nullity() + sage: A.nullity() # optional - sage.libs.pari 1 - sage: E = End(F^3) - sage: zeta = E(A) - sage: zeta.is_invertible() + sage: E = End(F^3) # optional - sage.libs.pari + sage: zeta = E(A) # optional - sage.libs.pari + sage: zeta.is_invertible() # optional - sage.libs.pari False """ # endomorphism or not, this is equivalent to invertibility of From 17f94a84c52ca51f1093a17b58c95e655fe83ed5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 11 Mar 2023 00:10:59 -0800 Subject: [PATCH 17/99] sage.matrix: More # optional --- src/sage/matrix/compute_J_ideal.py | 1 + src/sage/matrix/matrix0.pyx | 10 +- src/sage/matrix/matrix1.pyx | 20 +- src/sage/matrix/matrix2.pyx | 245 ++++++++++---------- src/sage/matrix/matrix_cdv.pyx | 4 +- src/sage/matrix/matrix_polynomial_dense.pyx | 20 +- src/sage/matrix/matrix_space.py | 24 +- src/sage/matrix/matrix_sparse.pyx | 2 +- 8 files changed, 169 insertions(+), 157 deletions(-) diff --git a/src/sage/matrix/compute_J_ideal.py b/src/sage/matrix/compute_J_ideal.py index 55dcb5e7072..ad20c0ebd15 100644 --- a/src/sage/matrix/compute_J_ideal.py +++ b/src/sage/matrix/compute_J_ideal.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.pari (for charpoly, minimal_polynomial in __init__) r""" `J`-ideals of matrices diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 3b6b278a773..a064c26f0cb 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -2364,17 +2364,17 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: f(x,y) = x^2+y - sage: m = matrix([[f,f*f],[f^3,f^4]]); m + sage: f(x,y) = x^2 + y # optional - sage.symbolic + sage: m = matrix([[f, f*f], [f^3, f^4]]); m # optional - sage.symbolic [ (x, y) |--> x^2 + y (x, y) |--> (x^2 + y)^2] [(x, y) |--> (x^2 + y)^3 (x, y) |--> (x^2 + y)^4] - sage: m(1,2) + sage: m(1, 2) # optional - sage.symbolic [ 3 9] [27 81] - sage: m(y=2,x=1) + sage: m(y=2, x=1) # optional - sage.symbolic [ 3 9] [27 81] - sage: m(2,1) + sage: m(2, 1) # optional - sage.symbolic [ 5 25] [125 625] """ diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 3670adf1a6b..b0d39125770 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -212,22 +212,22 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: M = matrix(ZZ,2,range(4)) - sage: giac(M) + sage: M = matrix(ZZ, 2, range(4)) + sage: giac(M) # optional - sage.libs.giac [[0,1],[2,3]] - sage: M = matrix(QQ,3,[1,2,3,4/3,5/3,6/4,7,8,9]) - sage: giac(M) + sage: M = matrix(QQ, 3, [1,2,3, 4/3,5/3,6/4, 7,8,9]) + sage: giac(M) # optional - sage.libs.giac [[1,2,3],[4/3,5/3,3/2],[7,8,9]] sage: P. = ZZ[] sage: M = matrix(P, 2, [-9*x^2-2*x+2, x-1, x^2+8*x, -3*x^2+5]) - sage: giac(M) + sage: giac(M) # optional - sage.libs.giac [[-9*sageVARx^2-2*sageVARx+2,sageVARx-1],[sageVARx^2+8*sageVARx,-3*sageVARx^2+5]] - sage: y = var('y') - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) - sage: giac(M).det().sage() + sage: y = var('y') # optional - sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic + sage: giac(M).det().sage() # optional - sage.libs.giac sage.symbolic (y^2*dilog(y) + y*dilog(y)*sin(y) - y + 4)/y """ s = ','.join('[' + ','.join(cf._giac_init_() for cf in row) + ']' @@ -976,13 +976,13 @@ cdef class Matrix(Matrix0): sage: matrix(3, [1..9]).columns() [(1, 4, 7), (2, 5, 8), (3, 6, 9)] - sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).columns() + sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).columns() # optional - sage.symbolic [(1.41421356237310, 2.71828182845905), (3.14159265358979, 0.000000000000000)] sage: matrix(RR, 0, 2, []).columns() [(), ()] sage: matrix(RR, 2, 0, []).columns() [] - sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) + sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) # optional - sage.symbolic sage: parent(m.columns()[0]) Sparse vector space of dimension 3 over Real Field with 53 bits of precision diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 1d12814aceb..f27aaa25198 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -594,39 +594,39 @@ cdef class Matrix(Matrix1): sage: A = Matrix(Zmod(6), 3, 2, [1,2,3,4,5,6]) sage: B = vector(Zmod(6), [1,1,1]) - sage: A.solve_right(B) + sage: A.solve_right(B) # optional - sage.libs.pari (5, 1) sage: B = vector(Zmod(6), [5,1,1]) - sage: A.solve_right(B) + sage: A.solve_right(B) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matrix equation has no solutions sage: A = Matrix(Zmod(128), 2, 3, [23,11,22,4,1,0]) sage: B = Matrix(Zmod(128), 2, 1, [1,0]) - sage: A.solve_right(B) + sage: A.solve_right(B) # optional - sage.libs.pari [ 5] [108] [127] sage: B = B.column(0) - sage: A.solve_right(B) + sage: A.solve_right(B) # optional - sage.libs.pari (5, 108, 127) sage: A = Matrix(Zmod(15), 3,4, range(12)) sage: B = Matrix(Zmod(15), 3,3, range(3,12)) - sage: X = A.solve_right(B) - sage: A*X == B + sage: X = A.solve_right(B) # optional - sage.libs.pari + sage: A*X == B # optional - sage.libs.pari True Solving a system over the p-adics:: - sage: k = Qp(5,4) - sage: a = matrix(k, 3, [1,7,3,2,5,4,1,1,2]); a + sage: k = Qp(5, 4) # optional - sage.rings.padics + sage: a = matrix(k, 3, [1,7,3, 2,5,4, 1,1,2]); a # optional - sage.rings.padics [ 1 + O(5^4) 2 + 5 + O(5^4) 3 + O(5^4)] [ 2 + O(5^4) 5 + O(5^5) 4 + O(5^4)] [ 1 + O(5^4) 1 + O(5^4) 2 + O(5^4)] - sage: v = vector(k, 3, [1,2,3]) - sage: x = a \ v; x + sage: v = vector(k, 3, [1,2,3]) # optional - sage.rings.padics + sage: x = a \ v; x # optional - sage.rings.padics (4 + 5 + 5^2 + 3*5^3 + O(5^4), 2 + 5 + 3*5^2 + 5^3 + O(5^4), 1 + 5 + O(5^4)) - sage: a * x == v + sage: a * x == v # optional - sage.rings.padics True Solving a system of linear equations symbolically using symbolic @@ -736,7 +736,7 @@ cdef class Matrix(Matrix1): sage: A = Matrix(Zmod(6), 3, 2, [1,2,3,4,5,6]) sage: b = vector(ZZ, [1,1,1]) - sage: A.solve_right(b).base_ring() is Zmod(6) + sage: A.solve_right(b).base_ring() is Zmod(6) # optional - sage.libs.pari True Check that the coercion mechanism gives consistent results @@ -2424,7 +2424,7 @@ cdef class Matrix(Matrix1): In that case, the definition by perfect matchings is used instead:: - sage: A.pfaffian() # optional - sage.libs.pari + sage: A.pfaffian() # optional - sage.combinat sage.libs.pari 2 """ @@ -2509,7 +2509,7 @@ cdef class Matrix(Matrix1): ....: (2, -1, 0, 0, 1, 5/2), ....: (-2, 1, -3/2, -1, 0, 1/2), ....: (1/2, -3/2, -1, -5/2, -1/2, 0)]) - sage: A._pf_perfect_matchings() + sage: A._pf_perfect_matchings() # optional - sage.combinat -1/2 """ @@ -2567,7 +2567,7 @@ cdef class Matrix(Matrix1): sage: A = random_matrix(ZZ['x'], 6) sage: A = A - A.transpose() - sage: A.pfaffian(algorithm='bfl') == A._pf_perfect_matchings() + sage: A.pfaffian(algorithm='bfl') == A._pf_perfect_matchings() # optional - sage.combinat True """ @@ -3909,14 +3909,14 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: A = matrix(Zmod(24480), [[1,2,3,4,5],[7,7,7,7,7]]) - sage: result = A._right_kernel_matrix_over_integer_mod_ring() - sage: result[0] + sage: result = A._right_kernel_matrix_over_integer_mod_ring() # optional - sage.libs.pari + sage: result[0] # optional - sage.libs.pari 'computed-pari-matkermod' - sage: P = result[1]; P + sage: P = result[1]; P # optional - sage.libs.pari [ 1 24478 1 0 0] [ 2 24477 0 1 0] [ 3 24476 0 0 1] - sage: A*P.transpose() == 0 + sage: A*P.transpose() == 0 # optional - sage.libs.pari True """ R = self.base_ring() @@ -6037,17 +6037,17 @@ cdef class Matrix(Matrix1): of finite fields:: sage: A = matrix(QQ, 2, range(4)) - sage: A._eigenspace_format(None) == 'all' + sage: A._eigenspace_format(None) == 'all' # optional - sage.rings.number_field True - sage: B = matrix(GF(13), 2, range(4)) # optional - sage.libs.pari - sage: B._eigenspace_format(None) # optional - sage.libs.pari + sage: B = matrix(GF(13), 2, range(4)) # optional - sage.libs.pari + sage: B._eigenspace_format(None) # optional - sage.libs.pari 'all' Subrings are promoted to fraction fields and then checked for the existence of algebraic closures. :: sage: A = matrix(ZZ, 2, range(4)) - sage: A._eigenspace_format(None) == 'all' + sage: A._eigenspace_format(None) == 'all' # optional - sage.rings.number_field True """ if format not in [None, 'all', 'galois']: @@ -6127,11 +6127,11 @@ cdef class Matrix(Matrix1): Then we request just one eigenspace per irreducible factor of the characteristic polynomial with the `galois` keyword. :: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenspaces_left(format='all'); es + sage: es = A.eigenspaces_left(format='all'); es # optional - sage.rings.number_field [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6144,7 +6144,7 @@ cdef class Matrix(Matrix1): [ 1 1.289897948556636? 1.579795897113272?]) ] - sage: es = A.eigenspaces_left(format='galois'); es + sage: es = A.eigenspaces_left(format='galois'); es # optional - sage.rings.number_field [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6153,7 +6153,7 @@ cdef class Matrix(Matrix1): User basis matrix: [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) ] - sage: es = A.eigenspaces_left(format='galois', algebraic_multiplicity=True); es + sage: es = A.eigenspaces_left(format='galois', algebraic_multiplicity=True); es # optional - sage.rings.number_field [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6162,18 +6162,18 @@ cdef class Matrix(Matrix1): User basis matrix: [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5], 1) ] - sage: e, v, n = es[0]; v = v.basis()[0] - sage: delta = e*v - v*A - sage: abs(abs(delta)) < 1e-10 + sage: e, v, n = es[0]; v = v.basis()[0] # optional - sage.rings.number_field + sage: delta = e*v - v*A # optional - sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field True The same computation, but with implicit base change to a field. :: - sage: A = matrix(ZZ,3,3,range(9)); A + sage: A = matrix(ZZ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_left(format='galois') + sage: A.eigenspaces_left(format='galois') # optional - sage.rings.number_field [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6470,11 +6470,11 @@ cdef class Matrix(Matrix1): We compute the right eigenspaces of a `3\times 3` rational matrix. :: - sage: A = matrix(QQ, 3 ,3, range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_right() + sage: A.eigenspaces_right() # optional - sage.rings.number_field [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6486,7 +6486,7 @@ cdef class Matrix(Matrix1): User basis matrix: [ 1 3.069693845669907? 5.139387691339814?]) ] - sage: es = A.eigenspaces_right(format='galois'); es + sage: es = A.eigenspaces_right(format='galois'); es # optional - sage.rings.number_field [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6495,7 +6495,7 @@ cdef class Matrix(Matrix1): User basis matrix: [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) ] - sage: es = A.eigenspaces_right(format='galois', algebraic_multiplicity=True); es + sage: es = A.eigenspaces_right(format='galois', algebraic_multiplicity=True); es # optional - sage.rings.number_field [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6504,9 +6504,9 @@ cdef class Matrix(Matrix1): User basis matrix: [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5], 1) ] - sage: e, v, n = es[0]; v = v.basis()[0] - sage: delta = v*e - A*v - sage: abs(abs(delta)) < 1e-10 + sage: e, v, n = es[0]; v = v.basis()[0] # optional - sage.rings.number_field + sage: delta = v*e - A*v # optional - sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field True The same computation, but with implicit base change to a field:: @@ -6515,7 +6515,7 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_right(format='galois') + sage: A.eigenspaces_right(format='galois') # optional - sage.rings.number_field [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6684,7 +6684,7 @@ cdef class Matrix(Matrix1): sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) sage: M.eigenvalues() # optional - sage.rings.number_field [2, -1*I, 1*I] - sage: M.eigenvalues(extend=False) + sage: M.eigenvalues(extend=False) # optional - sage.rings.number_field [2] The method also works for matrices over finite fields:: @@ -6773,31 +6773,31 @@ cdef class Matrix(Matrix1): :: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenvectors_left(); es + sage: es = A.eigenvectors_left(); es # optional - sage.rings.number_field [(0, [ (1, -2, 1) ], 1), (-1.348469228349535?, [(1, 0.3101020514433644?, -0.3797958971132713?)], 1), (13.34846922834954?, [(1, 1.289897948556636?, 1.579795897113272?)], 1)] - sage: eval, [evec], mult = es[0] - sage: delta = eval*evec - evec*A - sage: abs(abs(delta)) < 1e-10 + sage: eval, [evec], mult = es[0] # optional - sage.rings.number_field + sage: delta = eval*evec - evec*A # optional - sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field True Notice the difference between considering ring extensions or not. :: - sage: M=matrix(QQ,[[0,-1,0],[1,0,0],[0,0,2]]) - sage: M.eigenvectors_left() + sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) + sage: M.eigenvectors_left() # optional - sage.rings.number_field [(2, [ (0, 0, 1) ], 1), (-1*I, [(1, -1*I, 0)], 1), (1*I, [(1, 1*I, 0)], 1)] - sage: M.eigenvectors_left(extend=False) + sage: M.eigenvectors_left(extend=False) # optional - sage.rings.number_field [(2, [ (0, 0, 1) ], 1)] @@ -6814,7 +6814,7 @@ cdef class Matrix(Matrix1): Check the deprecation:: - sage: matrix(QQ, [[1, 2], [3, 4]]).eigenvectors_left(False) + sage: matrix(QQ, [[1, 2], [3, 4]]).eigenvectors_left(False) # optional - sage.rings.number_field doctest:...: DeprecationWarning: "extend" should be used as keyword argument See https://github.com/sagemath/sage/issues/29243 for details. [] @@ -6907,23 +6907,23 @@ cdef class Matrix(Matrix1): :: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenvectors_right(); es + sage: es = A.eigenvectors_right(); es # optional - sage.rings.number_field [(0, [ (1, -2, 1) ], 1), (-1.348469228349535?, [(1, 0.1303061543300932?, -0.7393876913398137?)], 1), (13.34846922834954?, [(1, 3.069693845669907?, 5.139387691339814?)], 1)] - sage: A.eigenvectors_right(extend=False) + sage: A.eigenvectors_right(extend=False) # optional - sage.rings.number_field [(0, [ (1, -2, 1) ], 1)] - sage: eval, [evec], mult = es[0] - sage: delta = eval*evec - A*evec - sage: abs(abs(delta)) < 1e-10 + sage: eval, [evec], mult = es[0] # optional - sage.rings.number_field + sage: delta = eval*evec - A*evec # optional - sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field True TESTS:: @@ -6979,27 +6979,27 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: D, P = A.eigenmatrix_left() - sage: D + sage: D, P = A.eigenmatrix_left() # optional - sage.rings.number_field + sage: D # optional - sage.rings.number_field [ 0 0 0] [ 0 -1.348469228349535? 0] [ 0 0 13.34846922834954?] - sage: P + sage: P # optional - sage.rings.number_field [ 1 -2 1] [ 1 0.3101020514433644? -0.3797958971132713?] [ 1 1.289897948556636? 1.579795897113272?] - sage: P*A == D*P + sage: P*A == D*P # optional - sage.rings.number_field True Because `P` is invertible, `A` is diagonalizable. :: - sage: A == (~P)*D*P + sage: A == (~P)*D*P # optional - sage.rings.number_field True The matrix `P` may contain zero rows corresponding to eigenvalues for @@ -7008,20 +7008,20 @@ cdef class Matrix(Matrix1): :: - sage: A = jordan_block(2,3); A + sage: A = jordan_block(2, 3); A [2 1 0] [0 2 1] [0 0 2] - sage: D, P = A.eigenmatrix_left() - sage: D + sage: D, P = A.eigenmatrix_left() # optional - sage.rings.number_field + sage: D # optional - sage.rings.number_field [2 0 0] [0 2 0] [0 0 2] - sage: P + sage: P # optional - sage.rings.number_field [0 0 1] [0 0 0] [0 0 0] - sage: P*A == D*P + sage: P*A == D*P # optional - sage.rings.number_field True A generalized eigenvector decomposition:: @@ -7106,21 +7106,23 @@ cdef class Matrix(Matrix1): the algebraic multiplicity. The following examples show that these cases are detected (:trac:`27842`):: - sage: A = matrix(SR, [(225/548, 0, -175/274*sqrt(193/1446)), # optional - sage.symbolic + sage: A = matrix(SR, [(225/548, 0, -175/274*sqrt(193/1446)), # optional - sage.symbolic ....: (0, 1/2, 0), ....: (-63/548*sqrt(723/386), 0, 49/548)]) - sage: A.eigenmatrix_left() # optional - sage.symbolic + sage: A.eigenmatrix_left() # optional - sage.symbolic Traceback (most recent call last): ... - RuntimeError: failed to compute eigenvectors for eigenvalue ..., check eigenvectors_left() for partial results - sage: B = matrix(SR, [(1/2, -7/2*sqrt(1/386), 0, 49/2*sqrt(1/279078)), # optional - sage.symbolic + RuntimeError: failed to compute eigenvectors for eigenvalue ..., + check eigenvectors_left() for partial results + sage: B = matrix(SR, [(1/2, -7/2*sqrt(1/386), 0, 49/2*sqrt(1/279078)), # optional - sage.symbolic ....: (-7/2*sqrt(1/386), 211/772, 0, -8425/772*sqrt(1/723)), ....: (0, 0, 1/2, 0), ....: (49/2*sqrt(1/279078), -8425/772*sqrt(1/723), 0, 561/772)]) - sage: B.eigenmatrix_left() # long time (1.2 seconds) # optional - sage.symbolic + sage: B.eigenmatrix_left() # long time (1.2 seconds) # optional - sage.symbolic Traceback (most recent call last): ... - RuntimeError: failed to compute eigenvectors for eigenvalue ..., check eigenvectors_left() for partial results + RuntimeError: failed to compute eigenvectors for eigenvalue ..., + check eigenvectors_left() for partial results The following example shows that :trac:`12595` has been resolved:: @@ -7195,27 +7197,27 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQ,3,3,range(9)); A + sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: D, P = A.eigenmatrix_right() - sage: D + sage: D, P = A.eigenmatrix_right() # optional - sage.rings.number_field + sage: D # optional - sage.rings.number_field [ 0 0 0] [ 0 -1.348469228349535? 0] [ 0 0 13.34846922834954?] - sage: P + sage: P # optional - sage.rings.number_field [ 1 1 1] [ -2 0.1303061543300932? 3.069693845669907?] [ 1 -0.7393876913398137? 5.139387691339814?] - sage: A*P == P*D + sage: A*P == P*D # optional - sage.rings.number_field True Because `P` is invertible, `A` is diagonalizable. :: - sage: A == P*D*(~P) + sage: A == P*D*(~P) # optional - sage.rings.number_field True The matrix `P` may contain zero columns corresponding to eigenvalues @@ -7224,12 +7226,12 @@ cdef class Matrix(Matrix1): :: - sage: A = jordan_block(2,3); A + sage: A = jordan_block(2, 3); A [2 1 0] [0 2 1] [0 0 2] - sage: D, P = A.eigenmatrix_right() - sage: D + sage: D, P = A.eigenmatrix_right() # optional - sage.rings.number_field + sage: D # optional - sage.rings.number_field [2 0 0] [0 2 0] [0 0 2] @@ -7237,7 +7239,7 @@ cdef class Matrix(Matrix1): [1 0 0] [0 0 0] [0 0 0] - sage: A*P == P*D + sage: A*P == P*D # optional - sage.rings.number_field True A generalized eigenvector decomposition:: @@ -10006,10 +10008,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = Matrix(ZZ,2,2,[5,2,3,4]) ; M + sage: M = Matrix(ZZ,2,2,[5,2,3,4]); M [5 2] [3 4] - sage: N = M.adjugate() ; N + sage: N = M.adjugate(); N [ 4 -2] [-3 5] sage: M * N @@ -10018,25 +10020,25 @@ cdef class Matrix(Matrix1): sage: N * M [14 0] [ 0 14] - sage: M = Matrix(QQ,2,2,[5/3,2/56,33/13,41/10]) ; M + sage: M = Matrix(QQ, 2, 2, [5/3,2/56, 33/13,41/10]); M [ 5/3 1/28] [33/13 41/10] - sage: N = M.adjugate() ; N + sage: N = M.adjugate(); N # optional - sage.libs.pari [ 41/10 -1/28] [-33/13 5/3] - sage: M * N + sage: M * N # optional - sage.libs.pari [7363/1092 0] [ 0 7363/1092] An alias is :meth:`adjoint_classical`, which replaces the deprecated :meth:`adjoint` method:: - sage: M.adjoint() + sage: M.adjoint() # optional - sage.libs.pari ...: DeprecationWarning: adjoint is deprecated. Please use adjugate instead. See https://github.com/sagemath/sage/issues/10501 for details. [ 41/10 -1/28] [-33/13 5/3] - sage: M.adjoint_classical() + sage: M.adjoint_classical() # optional - sage.libs.pari [ 41/10 -1/28] [-33/13 5/3] @@ -11642,9 +11644,9 @@ cdef class Matrix(Matrix1): sage: [e in QQ for e in A.eigenvalues()] # optional - sage.rings.number_field [False, False, False, False, False] - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari False - sage: A.diagonalization() + sage: A.diagonalization() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: not diagonalizable over Rational Field @@ -11905,7 +11907,7 @@ cdef class Matrix(Matrix1): sage: B = matrix(QQ, [[-38, -63, 42], ....: [ 14, 25, -14], ....: [-14, -21, 18]]) - sage: A.charpoly() == B.charpoly() + sage: A.charpoly() == B.charpoly() # optional - sage.libs.pari True sage: A.rational_form() [ 0 0 -48] @@ -15594,16 +15596,17 @@ cdef class Matrix(Matrix1): [ 1 0] [ 1 0] [ 1 -w] [ 0 -w + 9], [-w 1], [ 0 1] ) - sage: u * m * v == d + sage: u * m * v == d # optional - sage.rings.number_field True - sage: u.base_ring() == v.base_ring() == d.base_ring() == OE + sage: u.base_ring() == v.base_ring() == d.base_ring() == OE # optional - sage.rings.number_field True - sage: u.det().is_unit() and v.det().is_unit() + sage: u.det().is_unit() and v.det().is_unit() # optional - sage.rings.number_field True An example over the polynomial ring QQ[x]:: - sage: R. = QQ[]; m=x*matrix(R,2,2,1) - matrix(R, 2,2,[3,-4,1,-1]); m.smith_form() + sage: R. = QQ[]; m = x*matrix(R, 2, 2, 1) - matrix(R, 2, 2, [3,-4,1,-1]) + sage: m.smith_form() ( [ 1 0] [ 0 -1] [ 1 x + 1] [ 0 x^2 - 2*x + 1], [ 1 x - 3], [ 0 1] @@ -15611,13 +15614,13 @@ cdef class Matrix(Matrix1): An example over a field:: - sage: m = matrix(GF(17), 3, 3, [11,5,1,3,6,8,1,16,0]) # optional - sage.libs.pari - sage: d,u,v = m.smith_form() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari + sage: m = matrix(GF(17), 3, 3, [11,5,1, 3,6,8, 1,16,0]) # optional - sage.libs.pari + sage: d,u,v = m.smith_form() # optional - sage.libs.pari + sage: d # optional - sage.libs.pari [1 0 0] [0 1 0] [0 0 0] - sage: u*m*v == d # optional - sage.libs.pari + sage: u*m*v == d # optional - sage.libs.pari True When the base ring has a ``ring_of_integers`` method and supports denominators, @@ -15637,45 +15640,49 @@ cdef class Matrix(Matrix1): Some examples over non-PID's work anyway:: - sage: R. = EquationOrder(x^2 + 5) # class number 2 - sage: A = matrix(R, 2, 2, [s-1,-s,-s,2*s+1]) - sage: D, U, V = A.smith_form() - sage: D, U, V + sage: R. = EquationOrder(x^2 + 5) # class number 2 # optional - sage.rings.number_field + sage: A = matrix(R, 2, 2, [s-1, -s, -s, 2*s+1]) # optional - sage.rings.number_field + sage: D, U, V = A.smith_form() # optional - sage.rings.number_field + sage: D, U, V # optional - sage.rings.number_field ( [ 1 0] [ 4 s + 4] [ 1 -5*s + 6] [ 0 -s - 6], [ s s - 1], [ 0 1] ) - sage: D == U*A*V + sage: D == U*A*V # optional - sage.rings.number_field True Others don't, but they fail quite constructively:: - sage: matrix(R,2,2,[s-1,-s-2,-2*s,-s-2]).smith_form() + sage: matrix(R, 2, 2, [s-1, -s-2, -2*s, -s-2]).smith_form() # optional - sage.rings.number_field Traceback (most recent call last): ... ArithmeticError: Ideal Fractional ideal (2, s + 1) not principal Empty matrices are handled safely:: - sage: m = MatrixSpace(OE, 2,0)(0); d,u,v=m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 2,0)(0); d, u, v = m.smith_form(); u*m*v == d True - sage: m = MatrixSpace(OE, 0,2)(0); d,u,v=m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 0,2)(0); d, u, v = m.smith_form(); u*m*v == d True - sage: m = MatrixSpace(OE, 0,0)(0); d,u,v=m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 0,0)(0); d, u, v = m.smith_form(); u*m*v == d True Some pathological cases that crashed earlier versions:: - sage: m = Matrix(OE, [[2*w,2*w-1,-w+1],[2*w+2,-2*w-1,w-1],[-2*w-1,-2*w-2,2*w-1]]); d, u, v = m.smith_form(); u * m * v == d + sage: m = Matrix(OE, [[2*w, 2*w-1, -w+1], # optional - sage.rings.number_field + ....: [2*w+2, -2*w-1, w-1], + ....: [-2*w-1, -2*w-2, 2*w-1]]) + sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field True - sage: m = matrix(OE, 3, 3, [-5*w-1,-2*w-2,4*w-10,8*w,-w,w-1,-1,1,-8]); d,u,v = m.smith_form(); u*m*v == d + sage: m = matrix(OE, 3, 3, [-5*w-1,-2*w-2,4*w-10, 8*w,-w,w-1, -1,1,-8]) # optional - sage.rings.number_field + sage: d, u, v = m.smith_form(); u*m*v == d # optional - sage.rings.number_field True Over local fields, we can request the transformation matrices to be integral:; - sage: K = Qp(2, 5, print_mode='terse') - sage: M = matrix(K, 2, 3, [1/2, 1, 2, 1/3, 1, 3]) - sage: M.smith_form(integral=True) + sage: K = Qp(2, 5, print_mode='terse') # optional - sage.rings.padics + sage: M = matrix(K, 2, 3, [1/2, 1, 2, 1/3, 1, 3]) # optional - sage.rings.padics + sage: M.smith_form(integral=True) # optional - sage.rings.padics ( [1/2 + O(2^4) 0 0] [ 1 + O(2^5) 0] [ 0 1 + O(2^5) 0], [42 + O(2^6) 1 + O(2^5)], @@ -16790,9 +16797,9 @@ cdef class Matrix(Matrix1): ....: [ 139, -35, 99, -49, -18, 236, -41, -70, 370, -118, -377, -619], ....: [ 243, 9, 81, -72, -81, 386, 43, -105, 508, -124, -564, -911], ....: [-155, -3, -55, 45, 50, -245, -27, 65, -328, 77, 365, 583]]) - sage: A.characteristic_polynomial().factor() + sage: A.characteristic_polynomial().factor() # optional - sage.libs.pari (x^2 - 2)^2 * (x^2 + 2*x + 5)^4 - sage: A.eigenvalues(extend=False) + sage: A.eigenvalues(extend=False) # optional - sage.rings.number_field [] sage: A.rational_form() [ 0 -5| 0 0 0 0| 0 0 0 0 0 0] @@ -17760,7 +17767,7 @@ def _smith_diag(d, transformation=True): [1 0] [2 1] [ 1 -3] [0 6], [3 2], [-1 4] ) - sage: D == U*A*V + sage: D == U*A*V # optional - sage.rings.number_field True sage: m = matrix(GF(7), 2, [3,0,0,6]); d,u,v = _smith_diag(m); d # optional - sage.libs.pari [1 0] @@ -17945,7 +17952,7 @@ def _smith_onestep(m): [ 1 0 0] [ 0 w w + 3] [ 0 0 -56*w - 85] - sage: a * m * c == b + sage: a * m * c == b # optional - sage.rings.number_field True """ diff --git a/src/sage/matrix/matrix_cdv.pyx b/src/sage/matrix/matrix_cdv.pyx index 85347031d3b..c67936f6e4c 100644 --- a/src/sage/matrix/matrix_cdv.pyx +++ b/src/sage/matrix/matrix_cdv.pyx @@ -56,7 +56,9 @@ cpdef hessenbergize_cdvf(Matrix_generic_dense H): We check that :trac:`31753` is resolved:: sage: R. = GF(5)[[]] # optional - sage.libs.pari - sage: M = matrix(3, 3, [ 1, t + O(t^3), t^2, 1 + t + O(t^3), 2 + t^2, 3 + 2*t + O(t^3), t - t^2, 2*t, 1 + t ]) + sage: M = matrix(3, 3, [ 1, t + O(t^3), t^2, # optional - sage.libs.pari + ....: 1 + t + O(t^3), 2 + t^2, 3 + 2*t + O(t^3), + ....: t - t^2, 2*t, 1 + t ]) sage: M.charpoly() # optional - sage.libs.pari x^3 + (1 + 4*t + 4*t^2 + O(t^3))*x^2 + (t + 2*t^2 + O(t^3))*x + 3 + 2*t^2 + O(t^3) """ diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index e1db8a63c9f..ebfc9bc6e3e 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -2021,34 +2021,34 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Demonstrating shifts:: - sage: P = M.weak_popov_form(shifts=[0,2,4]); P # optional - sage.combinat sage.libs.pari + sage: P = M.weak_popov_form(shifts=[0,2,4]); P # optional - sage.combinat sage.libs.pari [ 6*x^2 + 6*x + 4 5*x^4 + 4*x^3 + 5*x^2 + 5*x 2*x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: P == M.weak_popov_form(shifts=[-10,-8,-6]) # optional - sage.combinat sage.libs.pari + sage: P == M.weak_popov_form(shifts=[-10,-8,-6]) # optional - sage.combinat sage.libs.pari True Column-wise form is the row-wise form of the transpose:: - sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T # optional - sage.combinat sage.libs.pari + sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T # optional - sage.combinat sage.libs.pari True Zero vectors can be discarded:: - sage: M.weak_popov_form(row_wise=False) # optional - sage.combinat sage.libs.pari + sage: M.weak_popov_form(row_wise=False) # optional - sage.combinat sage.libs.pari [x + 4 6 0] [ 5 1 0] - sage: P, U = M.weak_popov_form(transformation=True, # optional - sage.combinat sage.libs.pari + sage: P, U = M.weak_popov_form(transformation=True, # optional - sage.combinat sage.libs.pari ....: row_wise=False, ....: include_zero_vectors=False) - sage: P # optional - sage.combinat sage.libs.pari + sage: P # optional - sage.combinat sage.libs.pari [x + 4 6] [ 5 1] - sage: U # optional - sage.combinat sage.libs.pari + sage: U # optional - sage.combinat sage.libs.pari [ 5*x + 2 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 1 1 2*x + 1] [ 5*x + 5 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.combinat sage.libs.pari + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.combinat sage.libs.pari True .. SEEALSO:: @@ -2516,10 +2516,10 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [0 0 x] sage: A.is_reduced() True - sage: W = A.reduced_form(); W + sage: W = A.reduced_form(); W # optional - sage.combinat [ x x x] [-x -x 0] - sage: W.is_weak_popov() + sage: W.is_weak_popov() # optional - sage.combinat True The last example shows the usage of the transformation parameter:: diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 92723218ae5..cba7a23a96f 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -498,15 +498,15 @@ class MatrixSpace(UniqueRepresentation, Parent): sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1(range(4))) + sage: type(M1(range(4))) # optional - sage.libs.flint sage: type(M2(range(4))) - sage: M1(M2.an_element()) + sage: M1(M2.an_element()) # optional - sage.libs.flint [ 0 1] [-1 2] - sage: M2(M1.an_element()) + sage: M2(M1.an_element()) # optional - sage.libs.flint [ 0 1] [-1 2] @@ -515,16 +515,16 @@ class MatrixSpace(UniqueRepresentation, Parent): Check that libgap matrices over finite fields are working properly:: - sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') # optional - sage.libs.pari - sage: M2.one() # optional - sage.libs.pari + sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') # optional - sage.libs.gap sage.libs.pari + sage: M2.one() # optional - sage.libs.gap sage.libs.pari [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: m = M2.random_element() # optional - sage.libs.pari - sage: M1 = MatrixSpace(GF(2), 5) # optional - sage.libs.pari - sage: M1(m * m) == M1(m) * M1(m) # optional - sage.libs.pari + sage: m = M2.random_element() # optional - sage.libs.gap sage.libs.pari + sage: M1 = MatrixSpace(GF(2), 5) # optional - sage.libs.pari + sage: M1(m * m) == M1(m) * M1(m) # optional - sage.libs.pari True """ @@ -539,8 +539,10 @@ def __classcall__(cls, base_ring, nrows, ncols=None, sparse=False, implementatio sage: M1 = MatrixSpace(QQ, 2) sage: M2 = MatrixSpace(QQ, 2) + sage: M1 is M2 + True sage: M3 = MatrixSpace(QQ, 2, implementation='flint') # optional - sage.libs.flint - sage: M1 is M2 and M1 is M3 + sage: M1 is M3 # optional - sage.libs.flint True :: @@ -1862,10 +1864,10 @@ def diagonal_matrix(self, entries): Check different implementations:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1.diagonal_matrix([1, 2])) + sage: type(M1.diagonal_matrix([1, 2])) # optional - sage.libs.flint sage: type(M2.diagonal_matrix([1, 2])) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index e1c9b43fc70..de62df71f60 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -810,7 +810,7 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: sage: m = matrix(2, [x^i for i in range(4)], sparse=True) # optional - sage.symbolic - sage: m._derivative(x) + sage: m._derivative(x) # optional - sage.symbolic [ 0 1] [ 2*x 3*x^2] """ From 7b6e851f7a7566e580fe26f8e9b4362d3311cfc0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 11 Mar 2023 00:15:24 -0800 Subject: [PATCH 18/99] sage.matrix, sage.modules: Move some imports into methods --- src/sage/matrix/matrix2.pyx | 4 +++- src/sage/modules/filtered_vector_space.py | 6 +++++- src/sage/modules/torsion_quadratic_module.py | 5 +++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index f27aaa25198..c517b99444d 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -18118,11 +18118,13 @@ def _jordan_form_vector_in_difference(V, W): sage: sage.matrix.matrix2._jordan_form_vector_in_difference([v,w], [u]) (1, 0, 0, 0) """ + from sage.modules.free_module import span + if not V: return None if not W: return V[0] - W_space = sage.all.span(W) + W_space = span(W) for v in V: if v not in W_space: return v diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index 60362fdcbd7..7a267935241 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -111,7 +111,6 @@ from sage.rings.rational_field import QQ from sage.rings.integer_ring import ZZ from sage.rings.real_double import RDF -from sage.rings.real_mpfr import RR from sage.rings.integer import Integer from sage.rings.infinity import InfinityRing, infinity, minus_infinity from sage.categories.fields import Fields @@ -119,6 +118,11 @@ from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method +try: + from sage.rings.real_mpfr import RR +except ImportError: + RR = None + def is_FilteredVectorSpace(X): """ diff --git a/src/sage/modules/torsion_quadratic_module.py b/src/sage/modules/torsion_quadratic_module.py index 15a9788ea12..21e8a49b82c 100644 --- a/src/sage/modules/torsion_quadratic_module.py +++ b/src/sage/modules/torsion_quadratic_module.py @@ -21,7 +21,6 @@ from sage.modules.free_quadratic_module import FreeQuadraticModule from sage.arith.misc import gcd from sage.rings.integer_ring import ZZ -from sage.rings.padics.factory import Zp from sage.rings.rational_field import QQ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.groups.additive_abelian.qmodnz import QmodnZ @@ -1063,8 +1062,10 @@ def normal_form(self, partial=False): [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0] """ - gens = [] from sage.quadratic_forms.genera.normal_form import p_adic_normal_form, _normalize + from sage.rings.padics.factory import Zp + + gens = [] for p in self.annihilator().gen().prime_divisors(): D_p = self.primary_part(p) q_p = D_p.gram_matrix_quadratic() From 092d217217e2a7f25bc99069eb1457248b9c648c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Mar 2023 00:32:00 -0800 Subject: [PATCH 19/99] sage.matrix: More # optional --- src/sage/matrix/matrix_space.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index cba7a23a96f..e32eca0ad50 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -510,7 +510,8 @@ class MatrixSpace(UniqueRepresentation, Parent): [ 0 1] [-1 2] - sage: all(((A.get_action(B) is not None) == (A is B)) for A in [M1,M2] for B in [M1,M2]) + sage: all((A.get_action(B) is not None) == (A is B) # optional - sage.libs.flint + ....: for A in [M1, M2] for B in [M1, M2]) True Check that libgap matrices over finite fields are working properly:: @@ -548,9 +549,9 @@ def __classcall__(cls, base_ring, nrows, ncols=None, sparse=False, implementatio :: sage: M = MatrixSpace(ZZ, 10, implementation="flint") # optional - sage.libs.flint - sage: M + sage: M # optional - sage.libs.flint Full MatrixSpace of 10 by 10 dense matrices over Integer Ring - sage: loads(M.dumps()) is M + sage: loads(M.dumps()) is M # optional - sage.libs.flint True sage: MatrixSpace(ZZ, 10, implementation="foobar") From 86211ad95aa07171c4393691165ea406ababf700 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Mar 2023 00:35:46 -0800 Subject: [PATCH 20/99] sage.tensor: Move import from sage.groups into method --- src/sage/tensor/modules/tensor_with_indices.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/tensor/modules/tensor_with_indices.py b/src/sage/tensor/modules/tensor_with_indices.py index e1efd0e53c2..13b7ec2fc61 100644 --- a/src/sage/tensor/modules/tensor_with_indices.py +++ b/src/sage/tensor/modules/tensor_with_indices.py @@ -19,7 +19,6 @@ #****************************************************************************** from sage.structure.sage_object import SageObject -from sage.groups.perm_gps.permgroup import PermutationGroup import re from itertools import combinations @@ -957,6 +956,8 @@ def swap(param,N): return L # Construction of the permutation group generated by swaps + from sage.groups.perm_gps.permgroup import PermutationGroup + perm_group = PermutationGroup( [swap(param, self._tensor.tensor_rank()) for param in swap_params], canonicalize=False From 14409828f194ff4bf7a019c1f22582e0ece4643c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Mar 2023 13:34:18 -0700 Subject: [PATCH 21/99] sage.modules: More # optional --- src/sage/modules/free_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index abcf7deebe9..526cacec934 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -385,7 +385,7 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m Vector space of dimension 10 over Rational Field sage: FreeModule(ZZ,10) Ambient free module of rank 10 over the principal ideal domain Integer Ring - sage: FreeModule(FiniteField(5),10) + sage: FreeModule(FiniteField(5),10) # optional - sage.libs.pari Vector space of dimension 10 over Finite Field of size 5 sage: FreeModule(Integers(7),10) Vector space of dimension 10 over Ring of integers modulo 7 From f758f711ea98bee9e362dbda05dfb5309c66042d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Mar 2023 22:59:50 -0700 Subject: [PATCH 22/99] src/sage/matrix/matrix2.pyx: Fix imports --- src/sage/matrix/matrix2.pyx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index c517b99444d..a3ae969adca 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -105,13 +105,14 @@ from sage.matrix.matrix_misc import permanental_minor_polynomial # used to deprecate only adjoint method from sage.misc.superseded import deprecated_function_alias + # temporary hack to silence the warnings from #34806 -from sage.rings.number_field.order import Order as NumberFieldOrder def ideal_or_fractional(R, *args): - if isinstance(R, NumberFieldOrder): + if isinstance(R, sage.rings.abc.Order): R = R.number_field() return R.ideal(*args) + _Fields = Fields() cdef class Matrix(Matrix1): From 7d6b71f703d9c68c72b82a17dce7da5c12814b80 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 13 Mar 2023 01:27:46 -0700 Subject: [PATCH 23/99] sage.matrix: More # optional --- src/sage/matrix/matrix2.pyx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index a3ae969adca..2f020a88b0e 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -3128,8 +3128,8 @@ cdef class Matrix(Matrix1): Test that :trac:`27937` is fixed:: - sage: R = FreeAbelianMonoid('u,v').algebra(QQ) - sage: matrix(4, 4, lambda i, j: R.an_element())._charpoly_df() + sage: R = FreeAbelianMonoid('u,v').algebra(QQ) # optional - sage.groups + sage: matrix(4, 4, lambda i, j: R.an_element())._charpoly_df() # optional - sage.groups B[1]*x^4 - 4*B[u]*x^3 .. NOTE:: @@ -7236,7 +7236,7 @@ cdef class Matrix(Matrix1): [2 0 0] [0 2 0] [0 0 2] - sage: P + sage: P # optional - sage.rings.number_field [1 0 0] [0 0 0] [0 0 0] @@ -10108,19 +10108,19 @@ cdef class Matrix(Matrix1): not an integral domain:: sage: R. = QQ[] - sage: S. = R.quo((b^3)) - sage: A = matrix(S, [[x*y^2,2*x],[2,x^10*y]]) - sage: A + sage: S. = R.quo((b^3)) # optional - sage.libs.singular + sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) # optional - sage.libs.singular + sage: A # optional - sage.libs.singular [ x*y^2 2*x] [ 2 x^10*y] - sage: A.det() + sage: A.det() # optional - sage.libs.singular -4*x - sage: A.charpoly('T') + sage: A.charpoly('T') # optional - sage.libs.singular T^2 + (-x^10*y - x*y^2)*T - 4*x - sage: A.adjugate() + sage: A.adjugate() # optional - sage.libs.singular [x^10*y -2*x] [ -2 x*y^2] - sage: A.adjugate() * A + sage: A.adjugate() * A # optional - sage.libs.singular [-4*x 0] [ 0 -4*x] @@ -11693,7 +11693,7 @@ cdef class Matrix(Matrix1): A trivial matrix is diagonalizable, trivially. :: sage: A = matrix(QQ, 0, 0) - sage: A.is_diagonalizable() + sage: A.is_diagonalizable() # optional - sage.libs.pari True A matrix must be square to be diagonalizable. :: @@ -16819,7 +16819,7 @@ cdef class Matrix(Matrix1): [ 0 0| 0 0 0 0| 0 0 0 0 1 -4] sage: F. = QQ[] sage: polys = A.rational_form(format='invariants') - sage: [F(p).factor() for p in polys] + sage: [F(p).factor() for p in polys] # optional - sage.libs.pari [x^2 + 2*x + 5, (x^2 - 2) * (x^2 + 2*x + 5), (x^2 - 2) * (x^2 + 2*x + 5)^2] Rational form may be computed over any field. The matrix below is From 87c567bada5ef120bd33c0bf9dd3c5ef63541f63 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 13 Mar 2023 01:29:30 -0700 Subject: [PATCH 24/99] sage.modules: More # optional --- src/sage/modules/free_module.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 526cacec934..3c06f181f2f 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -243,11 +243,11 @@ def create_object(self, version, key): sage: R. = QQ[] sage: Q = R.quo(R.ideal([x^2 - y^2 - 1])) - sage: Q.is_integral_domain() + sage: Q.is_integral_domain() # optional - sage.libs.singular True - sage: Q2 = FreeModule(Q, 2) - sage: from sage.modules.free_module import FreeModule_ambient_domain - sage: isinstance(Q2, FreeModule_ambient_domain) + sage: Q2 = FreeModule(Q, 2) # optional - sage.libs.singular + sage: from sage.modules.free_module import FreeModule_ambient_domain # optional - sage.libs.singular + sage: isinstance(Q2, FreeModule_ambient_domain) # optional - sage.libs.singular True """ base_ring, rank, sparse, inner_product_matrix = key @@ -1811,10 +1811,10 @@ def free_resolution(self, *args, **kwds): sage: S. = PolynomialRing(QQ) sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) - sage: res = N.free_resolution() - sage: res + sage: res = N.free_resolution() # optional - sage.libs.singular + sage: res # optional - sage.libs.singular S^2 <-- S^2 <-- 0 - sage: ascii_art(res.chain_complex()) + sage: ascii_art(res.chain_complex()) # optional - sage.libs.singular [x - y y*z] [ z x*z] 0 <-- C_0 <-------------- C_1 <-- 0 @@ -1843,13 +1843,13 @@ def graded_free_resolution(self, *args, **kwds): sage: S. = PolynomialRing(QQ) sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) - sage: N.graded_free_resolution(shifts=[1, -1]) + sage: N.graded_free_resolution(shifts=[1, -1]) # optional - sage.libs.singular S(-1)⊕S(1) <-- S(-2)⊕S(-3) <-- 0 - sage: N.graded_free_resolution(shifts=[2, 3]) + sage: N.graded_free_resolution(shifts=[2, 3]) # optional - sage.libs.singular S(-2)⊕S(-3) <-- S(-3)⊕S(-4) <-- 0 sage: N = M.submodule([vector([x^3 - y^6, z^2]), vector([y * z, x])]) - sage: N.graded_free_resolution(degrees=[2, 1, 3], shifts=[2, 3]) + sage: N.graded_free_resolution(degrees=[2, 1, 3], shifts=[2, 3]) # optional - sage.libs.singular S(-2)⊕S(-3) <-- S(-6)⊕S(-8) <-- 0 """ from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular From 334c01cc76b472ac03add9eb1370091b872ed415 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 17 Mar 2023 21:51:27 -0700 Subject: [PATCH 25/99] sage.matrix: More # optional --- src/sage/matrix/matrix0.pyx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index a064c26f0cb..814d7d2b023 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -5776,19 +5776,19 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: sage: R. = ZZ[] - sage: RR = R.quotient(a*d-b*c-1) - sage: a,b,c,d = RR.gens() - sage: m = matrix(2, [a,b,c,d]) - sage: n = m.inverse_of_unit() - sage: m * n + sage: RR = R.quotient(a*d - b*c - 1) # optional - sage.libs.singular + sage: a,b,c,d = RR.gens() # optional - sage.libs.singular + sage: m = matrix(2, [a,b, c,d]) # optional - sage.libs.singular + sage: n = m.inverse_of_unit() # optional - sage.libs.singular + sage: m * n # optional - sage.libs.singular [1 0] [0 1] - sage: matrix(RR, 2, 1, [a,b]).inverse_of_unit() + sage: matrix(RR, 2, 1, [a,b]).inverse_of_unit() # optional - sage.libs.singular Traceback (most recent call last): ... ArithmeticError: self must be a square matrix - sage: matrix(RR, 1, 1, [2]).inverse_of_unit() + sage: matrix(RR, 1, 1, [2]).inverse_of_unit() # optional - sage.libs.singular Traceback (most recent call last): ... NotImplementedError: Lifting of multivariate polynomials over non-fields is not implemented. @@ -5801,9 +5801,9 @@ cdef class Matrix(sage.structure.element.Matrix): Tests for :trac:`28570`:: - sage: P = posets.TamariLattice(7) - sage: M = P._hasse_diagram._leq_matrix - sage: M.inverse_of_unit() # this was very slow, now 1s + sage: P = posets.TamariLattice(7) # optional - sage.combinat sage.graphs + sage: M = P._hasse_diagram._leq_matrix # optional - sage.combinat sage.graphs + sage: M.inverse_of_unit() # this was very slow, now 1s # optional - sage.combinat sage.graphs 429 x 429 sparse matrix over Integer Ring... sage: m = matrix(Zmod(2**2), 1, 1, [1], sparse=True) From 58bb75560ebaf61cad37de4993b2aa56f6fa1a2a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 24 Apr 2023 20:11:48 -0700 Subject: [PATCH 26/99] sage.{matrix,modules}: More # optional --- src/sage/matrix/benchmark.py | 3 +- src/sage/matrix/matrix1.pyx | 31 +++++++++++---------- src/sage/matrix/matrix_polynomial_dense.pyx | 10 +++---- src/sage/modules/free_module_element.pyx | 6 ++-- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/sage/matrix/benchmark.py b/src/sage/matrix/benchmark.py index 51fad23a874..ee89df9c6dd 100644 --- a/src/sage/matrix/benchmark.py +++ b/src/sage/matrix/benchmark.py @@ -18,13 +18,14 @@ """ from .constructor import random_matrix, Matrix +from sage.misc.lazy_import import lazy_import from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.misc.timing import cputime from cysignals.alarm import AlarmInterrupt, alarm, cancel_alarm -from sage.interfaces.magma import magma +lazy_import('sage.interfaces.magma', 'magma') verbose = False diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index b0d39125770..3ac5351adae 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -1032,7 +1032,7 @@ cdef class Matrix(Matrix0): sage: matrix(3, [1..9]).rows() [(1, 2, 3), (4, 5, 6), (7, 8, 9)] - sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).rows() + sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).rows() # optional - sage.symbolic [(1.41421356237310, 3.14159265358979), (2.71828182845905, 0.000000000000000)] sage: matrix(RR, 0, 2, []).rows() [] @@ -1613,18 +1613,20 @@ cdef class Matrix(Matrix0): ``A.stack(B)`` and ``B.stack(A)`` should be equal:: sage: A = matrix(QQ, 1, 2, [1,2]) - sage: B = matrix(RR, 1, 2, [sin(1.1), sin(2.2)]) - sage: C = A.stack(B); C + sage: B = matrix(RR, 1, 2, [sin(1.1), sin(2.2)]) # optional - sage.symbolic + sage: C = A.stack(B); C # optional - sage.symbolic [ 1.00000000000000 2.00000000000000] [0.891207360061435 0.808496403819590] - sage: C.parent() - Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision + sage: C.parent() # optional - sage.symbolic + Full MatrixSpace of 2 by 2 dense matrices + over Real Field with 53 bits of precision - sage: D = B.stack(A); D + sage: D = B.stack(A); D # optional - sage.symbolic [0.891207360061435 0.808496403819590] [ 1.00000000000000 2.00000000000000] - sage: D.parent() - Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision + sage: D.parent() # optional - sage.symbolic + Full MatrixSpace of 2 by 2 dense matrices + over Real Field with 53 bits of precision :: @@ -1881,18 +1883,19 @@ cdef class Matrix(Matrix0): elements of ``right`` into the base ring of ``self``. :: sage: A = matrix(QQ, 2, [1,2]) - sage: B = matrix(RR, 2, [sin(1.1), sin(2.2)]) - sage: C = A.augment(B); C + sage: B = matrix(RR, 2, [sin(1.1), sin(2.2)]) # optional - sage.symbolic + sage: C = A.augment(B); C # optional - sage.symbolic [ 1 183017397/205358938] [ 2 106580492/131825561] - sage: C.parent() + sage: C.parent() # optional - sage.symbolic Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: D = B.augment(A); D + sage: D = B.augment(A); D # optional - sage.symbolic [0.89120736006... 1.00000000000000] [0.80849640381... 2.00000000000000] - sage: D.parent() - Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision + sage: D.parent() # optional - sage.symbolic + Full MatrixSpace of 2 by 2 dense matrices + over Real Field with 53 bits of precision Sometimes it is not possible to coerce into the base ring of ``self``. A solution is to change the base ring of ``self`` to diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index ebfc9bc6e3e..3c672f0be13 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -3961,22 +3961,22 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Some particular cases (matrix is zero, dimension is zero, column is zero):: - sage: Matrix(pR, 2, 1).minimal_kernel_basis() + sage: Matrix(pR, 2, 1).minimal_kernel_basis() # optional - sage.rings.finite_rings [1 0] [0 1] - sage: Matrix(pR, 2, 0).minimal_kernel_basis() + sage: Matrix(pR, 2, 0).minimal_kernel_basis() # optional - sage.rings.finite_rings [1 0] [0 1] - sage: Matrix(pR, 0, 2).minimal_kernel_basis() + sage: Matrix(pR, 0, 2).minimal_kernel_basis() # optional - sage.rings.finite_rings [] - sage: Matrix(pR, 3, 2, [[1,0],[1,0],[1,0]]).minimal_kernel_basis() + sage: Matrix(pR, 3, 2, [[1,0],[1,0],[1,0]]).minimal_kernel_basis() # optional - sage.rings.finite_rings [6 1 0] [6 0 1] - sage: Matrix(pR, 3, 2, [[x,0],[1,0],[x+1,0]]).minimal_kernel_basis() + sage: Matrix(pR, 3, 2, [[x,0],[1,0],[x+1,0]]).minimal_kernel_basis() # optional - sage.rings.finite_rings [6 x 0] [6 6 1] """ diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index a30ee533bd3..f3682725f49 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -4450,9 +4450,9 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector(RR, [-1,0,2/3,pi]) - sage: v.set(3, RR(1)) - sage: v + sage: v = vector(RR, [-1, 0, 2/3, pi]) # optional - sage.symbolic + sage: v.set(3, RR(1)) # optional - sage.symbolic + sage: v # optional - sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 1.00000000000000) """ self._entries[i] = value From 1c4a858dc6f24a18d671a90d7cef4fd779f1f0d2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 28 Apr 2023 12:01:47 -0700 Subject: [PATCH 27/99] sage.{geometry,matrix,modules,repl,sets}: More # optional --- src/sage/matrix/matrix2.pyx | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 2f020a88b0e..9667d7c02ac 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -12583,8 +12583,7 @@ cdef class Matrix(Matrix1): ....: [ 2, -7, 4, 7]]) sage: A.is_symmetric() True - sage: L = A.cholesky() - sage: L + sage: L = A.cholesky(); L [ 2 0 0 0] [-1 3 0 0] [ 2 0 2 0] @@ -12605,8 +12604,7 @@ cdef class Matrix(Matrix1): ....: [ -2, -18, -38, 15]]) sage: A.is_symmetric() True - sage: L = A.cholesky() # optional - sage.rings.number_field - sage: L # optional - sage.rings.number_field + sage: L = A.cholesky(); L # optional - sage.rings.number_field [ 8.83176086632785? 0 0 0] [ -3.396831102433787? 9.51112708681461? 0 0] [ -4.189425026335004? 17.32383862241232? 2.886751345948129? 0] @@ -12627,8 +12625,7 @@ cdef class Matrix(Matrix1): ....: [ -21*I, -7*I + 15, -24*I + 6, 28]]) sage: A.is_hermitian() # optional - sage.rings.number_field True - sage: L = A.cholesky() # optional - sage.rings.number_field - sage: L + sage: L = A.cholesky(); L # optional - sage.rings.number_field [ 4.79...? 0 0 0] [ 0.62...? - 3.54...?*I 5.00...? 0 0] [ 5.21...? - 5.00...?*I 13.58...? + 10.72...?*I 24.98...? 0] @@ -15479,20 +15476,24 @@ cdef class Matrix(Matrix1): from sage.symbolic.ring import SR return self.change_ring(SR).exp() - def elementary_divisors(self): + def elementary_divisors(self, algorithm=None): r""" - If self is a matrix over a principal ideal domain R, return + If ``self`` is a matrix over a principal ideal domain `R`, return elements `d_i` for `1 \le i \le k = \min(r,s)` where `r` and `s` are the number of rows and - columns of self, such that the cokernel of self is isomorphic to + columns of self, such that the cokernel of ``self`` is isomorphic to .. MATH:: R/(d_1) \oplus R/(d_2) \oplus R/(d_k) with `d_i \mid d_{i+1}` for all `i`. These are - the diagonal entries of the Smith form of self (see - :meth:`smith_form()`). + the diagonal entries of the Smith form of ``self`` (see + :meth:`smith_form`). + + INPUT: + + - ``algorithm`` -- ignored EXAMPLES:: @@ -15911,7 +15912,8 @@ cdef class Matrix(Matrix1): sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) # optional - sage.libs.pari sage: A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.libs.pari ([ x 1 2*x], [1 0]) - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True); H, U # optional - sage.libs.pari + sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True) # optional - sage.rings.finite_rings + sage: H, U # optional - sage.rings.finite_rings ( [ x 1 2*x] [1 0] [ 0 0 0], [5 1] From 31795e72323ca9a9b319394f17f09c4eebcd318a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 28 Apr 2023 12:21:54 -0700 Subject: [PATCH 28/99] More optional --- src/sage/modules/free_module.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 3c06f181f2f..82ff49e6e58 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -3381,46 +3381,46 @@ def _magma_init_(self, magma): Inner product matrix: [ 1 0] [ 0 -1] - sage: n = magma(N); n # optional - magma + sage: n = magma(N); n # optional - magma Full Vector space of degree 2 over Rational Field Inner Product Matrix: [ 1 0] [ 0 -1] - sage: n.Type() # optional - magma + sage: n.Type() # optional - magma ModTupFld - sage: n.sage() # optional - magma + sage: n.sage() # optional - magma Ambient quadratic space of dimension 2 over Rational Field Inner product matrix: [ 1 0] [ 0 -1] - sage: n.sage() is N # optional - magma + sage: n.sage() is N # optional - magma True How about some inexact fields:: - sage: v = vector(RR, [1, pi, 5/6]) - sage: F = v.parent() - sage: M = magma(F); M # optional - magma + sage: v = vector(RR, [1, pi, 5/6]) # optional - sage.symbolic + sage: F = v.parent() # optional - sage.symbolic + sage: M = magma(F); M # optional - magma # optional - sage.symbolic Full Vector space of degree 3 over Real field of precision 15 - sage: M.Type() # optional - magma + sage: M.Type() # optional - magma # optional - sage.symbolic ModTupFld - sage: m = M.sage(); m # optional - magma + sage: m = M.sage(); m # optional - magma # optional - sage.symbolic Vector space of dimension 3 over Real Field with 53 bits of precision - sage: m is F # optional - magma + sage: m is F # optional - magma # optional - sage.symbolic True For interval fields, we can convert to Magma but there is no interval field in Magma so we cannot convert back:: - sage: v = vector(RealIntervalField(100), [1, pi, 0.125]) - sage: F = v.parent() - sage: M = magma(v.parent()); M # optional - magma + sage: v = vector(RealIntervalField(100), [1, pi, 0.125]) # optional - sage.symbolic + sage: F = v.parent() # optional - sage.symbolic + sage: M = magma(v.parent()); M # optional - magma # optional - sage.symbolic Full Vector space of degree 3 over Real field of precision 30 - sage: M.Type() # optional - magma + sage: M.Type() # optional - magma # optional - sage.symbolic ModTupFld - sage: m = M.sage(); m # optional - magma + sage: m = M.sage(); m # optional - magma # optional - sage.symbolic Vector space of dimension 3 over Real Field with 100 bits of precision - sage: m is F # optional - magma + sage: m is F # optional - magma # optional - sage.symbolic False """ K = magma(self.base_ring()) From c5e226611df49b887006c1234c39b45a0987067a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 12 May 2023 20:01:52 -0700 Subject: [PATCH 29/99] Fix # optional --- src/sage/matrix/args.pyx | 4 ++-- src/sage/matrix/matrix2.pyx | 26 +++++++++++++++----------- src/sage/matrix/matrix_space.py | 6 +++--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index d527151a4e5..a9c98734754 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -1232,11 +1232,11 @@ cdef class MatrixArgs: Constructing a matrix from a PARI ``t_VEC`` or ``t_COL`` with ``t_VEC`` or ``t_COL`` elements is currently not supported:: - sage: M(pari([1, a, 0, 1])) # optional - sage.libs.pari + sage: M(pari([1, a, 0, 1])) # optional - sage.libs.pari sage.rings.finite_rings Traceback (most recent call last): ... NameError: name 'a' is not defined - sage: M(pari([[1, a], [0, 1]])) # optional - sage.libs.pari + sage: M(pari([[1, a], [0, 1]])) # optional - sage.libs.pari sage.rings.finite_rings Traceback (most recent call last): ... NameError: name 'a' is not defined diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 9667d7c02ac..5fabac92ea8 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -10866,12 +10866,13 @@ cdef class Matrix(Matrix1): A complex subfield of the complex numbers. :: - sage: C. = CyclotomicField(5) - sage: A = matrix(C, [[ -z^3 - 2*z, -z^3 - 1, 2*z^3 - 2*z^2 + 2*z, 1], - ....: [ z^3 - 2*z^2 + 1, -z^3 + 2*z^2 - z - 1, -1, z^2 + z], - ....: [-1/2*z^3 - 2*z^2 + z + 1, -z^3 + z - 2, -2*z^3 + 1/2*z^2, 2*z^2 - z + 2]]) - sage: G, M = A.gram_schmidt(orthonormal=False) - sage: G + sage: C. = CyclotomicField(5) # optional - sage.rings.number_field + sage: A = matrix(C, # optional - sage.rings.number_field + ....: [[ -z^3 - 2*z, -z^3 - 1, 2*z^3 - 2*z^2 + 2*z, 1], + ....: [ z^3 - 2*z^2 + 1, -z^3 + 2*z^2 - z - 1, -1, z^2 + z], + ....: [-1/2*z^3 - 2*z^2 + z + 1, -z^3 + z - 2, -2*z^3 + 1/2*z^2, 2*z^2 - z + 2]]) + sage: G, M = A.gram_schmidt(orthonormal=False) # optional - sage.rings.number_field + sage: G # optional - sage.rings.number_field [ -z^3 - 2*z -z^3 - 1 2*z^3 - 2*z^2 + 2*z 1] [ 155/139*z^3 - 161/139*z^2 + 31/139*z + 13/139 -175/139*z^3 + 180/139*z^2 - 125/139*z - 142/139 230/139*z^3 + 124/139*z^2 + 6/139*z + 19/139 -14/139*z^3 + 92/139*z^2 - 6/139*z - 95/139] [-10359/19841*z^3 - 36739/39682*z^2 + 24961/39682*z - 11879/39682 -28209/39682*z^3 - 3671/19841*z^2 + 51549/39682*z - 38613/39682 -42769/39682*z^3 - 615/39682*z^2 - 1252/19841*z - 14392/19841 4895/19841*z^3 + 57885/39682*z^2 - 46094/19841*z + 65747/39682] @@ -11217,7 +11218,7 @@ cdef class Matrix(Matrix1): [0 0 0|0 0|0 0|0 0|3] sage: T * J * T**(-1) == A # optional - sage.combinat True - sage: T.rank() + sage: T.rank() # optional - sage.combinat 10 Verify that we smoothly move to QQ from ZZ (:trac:`12693`), i.e. @@ -15110,7 +15111,7 @@ cdef class Matrix(Matrix1): There is also a shortcut for the conjugate transpose, or "Hermitian transpose":: - sage: M.H + sage: M.H # optional - sage.symbolic [ I + 2 6*I + 9] [-4*I + 3 -5*I] @@ -15662,11 +15663,14 @@ cdef class Matrix(Matrix1): Empty matrices are handled safely:: - sage: m = MatrixSpace(OE, 2,0)(0); d, u, v = m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 2,0)(0) # optional - sage.rings.number_field + sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field True - sage: m = MatrixSpace(OE, 0,2)(0); d, u, v = m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 0,2)(0) # optional - sage.rings.number_field + sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field True - sage: m = MatrixSpace(OE, 0,0)(0); d, u, v = m.smith_form(); u*m*v == d + sage: m = MatrixSpace(OE, 0,0)(0) # optional - sage.rings.number_field + sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field True Some pathological cases that crashed earlier versions:: diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index e32eca0ad50..44612458ad7 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -523,9 +523,9 @@ class MatrixSpace(UniqueRepresentation, Parent): [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: m = M2.random_element() # optional - sage.libs.gap sage.libs.pari - sage: M1 = MatrixSpace(GF(2), 5) # optional - sage.libs.pari - sage: M1(m * m) == M1(m) * M1(m) # optional - sage.libs.pari + sage: m = M2.random_element() # optional - sage.libs.gap sage.rings.finite_rings + sage: M1 = MatrixSpace(GF(2), 5) # optional - sage.rings.finite_rings + sage: M1(m * m) == M1(m) * M1(m) # optional - sage.libs.gap sage.rings.finite_rings True """ From 1acb3bb2cd3005d1b5fd1f1d423d2f46e57d0e0c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 13 May 2023 11:57:59 -0700 Subject: [PATCH 30/99] Fix # optional --- src/sage/matrix/matrix2.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 5fabac92ea8..90771cb8aa7 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -18217,15 +18217,15 @@ def _matrix_power_symbolic(A, n): If the base ring is inexact, the Jordan normal form is not available:: sage: A = matrix(RDF, [[2, -1], [1, 0]]) - sage: A^n + sage: A^n # optional - sage.symbolic Traceback (most recent call last): ... ValueError: Jordan normal form not implemented over inexact rings. Testing exponentiation in the integer ring:: - sage: A = matrix(ZZ, [[1,-1],[-1,1]]) - sage: A^(2*n+1) + sage: A = matrix(ZZ, [[1,-1], [-1,1]]) + sage: A^(2*n+1) # optional - sage.symbolic [ 1/2*2^(2*n + 1) -1/2*2^(2*n + 1)] [-1/2*2^(2*n + 1) 1/2*2^(2*n + 1)] From c247f12d87e1bfff786a4968621ce454f6c43168 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 15 May 2023 14:12:13 -0700 Subject: [PATCH 31/99] sage.matrix: Add # optional --- src/sage/matrix/args.pyx | 6 ++++-- src/sage/matrix/matrix1.pyx | 8 ++++---- src/sage/matrix/matrix2.pyx | 8 ++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index a9c98734754..3a44e30d3d1 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -176,8 +176,10 @@ cdef class MatrixArgs: [3.141592653589793 0.0] [ 0.0 3.141592653589793] - sage: ma = MatrixArgs(2, 2, entries=pi); ma.finalized(); ma.matrix() # optional - sage.symbolic - + sage: ma = MatrixArgs(2, 2, entries=pi); ma.finalized() # optional - sage.symbolic + + sage: ma.matrix() # optional - sage.symbolic [pi 0] [ 0 pi] sage: ma = MatrixArgs(ZZ, 2, 2, entries={(0,0):7}); ma.finalized(); ma.matrix() diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 3ac5351adae..49babe96d46 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -282,10 +282,10 @@ cdef class Matrix(Matrix0): :: - sage: a = matrix([[pi, sin(x)], [cos(x), 1/e]]); a + sage: a = matrix([[pi, sin(x)], [cos(x), 1/e]]); a # optional - sage.symbolic [ pi sin(x)] [cos(x) e^(-1)] - sage: a._mathematica_init_() + sage: a._mathematica_init_() # optional - sage.symbolic '{{Pi, Sin[x]}, {Cos[x], Exp[-1]}}' """ return '{' + ', '.join([v._mathematica_init_() for v in self.rows()]) + '}' @@ -568,9 +568,9 @@ cdef class Matrix(Matrix0): If ``self`` was mutable, then converting back to Sage creates a new matrix:: - sage: sA._sage_() is A # optional - sympy + sage: sA._sage_() is A # optional - sage.symbolic sympy False - sage: sA._sage_() == A # optional - sympy + sage: sA._sage_() == A # optional - sage.symbolic sympy True Symbolic matrices are supported:: diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 90771cb8aa7..8a782fd7068 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -721,8 +721,8 @@ cdef class Matrix(Matrix1): (:trac:`12406`):: sage: A = matrix(QQ, 2, [1, 2, 3, 4]) - sage: b = vector(RDF, [pi, e]) - sage: A.solve_right(b) # tol 1e-15 + sage: b = vector(RDF, [pi, e]) # optional - sage.symbolic + sage: A.solve_right(b) # tol 1e-15 # optional - sage.symbolic (-3.564903478720541, 3.353248066155167) sage: R. = ZZ[] sage: b = vector(R, [1, t]) @@ -1709,7 +1709,7 @@ cdef class Matrix(Matrix1): These numbers are the coefficients of a modified Laguerre polynomial:: sage: x = polygen(QQ) - sage: factorial(8) * laguerre(8,-x) + sage: factorial(8) * laguerre(8,-x) # optional - sage.symbolic x^8 + 64*x^7 + 1568*x^6 + 18816*x^5 + 117600*x^4 + 376320*x^3 + 564480*x^2 + 322560*x + 40320 @@ -10386,7 +10386,7 @@ cdef class Matrix(Matrix1): roots, though some small cases pass through. :: sage: A = matrix(ZZ, 3, 3, range(9)) - sage: A.QR() + sage: A.QR() # optional - sage.symbolic Traceback (most recent call last): ... TypeError: QR decomposition unable to compute square roots in Rational Field From 1fa65eb0654d2ccb1e38c66b814906b000735e25 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 May 2023 13:20:30 -0700 Subject: [PATCH 32/99] Massive modularization fixes --- src/sage/matrix/matrix_complex_ball_dense.pyx | 2 +- src/sage/matrix/special.py | 24 ++++++++-------- src/sage/modules/free_module.py | 25 ++++++++--------- src/sage/modules/free_module_element.pyx | 28 +++++++++---------- src/sage/modules/matrix_morphism.py | 1 + .../modules/vector_complex_double_dense.pyx | 18 ++++++------ src/sage/modules/vector_double_dense.pyx | 13 ++++----- src/sage/modules/vector_real_double_dense.pyx | 13 ++++----- .../probability/probability_distribution.pyx | 2 +- src/sage/quadratic_forms/special_values.py | 12 ++++---- .../discrete_gaussian_integer.pyx | 2 +- .../discrete_gaussian_lattice.py | 2 +- src/sage/stats/hmm/distributions.pyx | 2 +- src/sage/stats/hmm/hmm.pyx | 4 +-- src/sage/stats/intlist.pyx | 7 +++-- src/sage/stats/time_series.pyx | 20 ++++++------- 16 files changed, 88 insertions(+), 87 deletions(-) diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index ad57de71deb..17ec254070b 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -945,7 +945,7 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): EXAMPLES:: - sage: matrix(CBF, [[i*pi, 1], [0, i*pi]]).exp() + sage: matrix(CBF, [[i*pi, 1], [0, i*pi]]).exp() # optional - sage.symbolic [[-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I [-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I] [ 0 [-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I] sage: matrix(CBF, [[1/2, 1/3]]).exp() diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 26ea00b08a7..a2fcc5e8c1d 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -819,7 +819,7 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): Types for the entries need to be iterable (tuple, list, vector, NumPy array, etc):: - sage: diagonal_matrix(x^2) + sage: diagonal_matrix(x^2) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: 'sage.symbolic.expression.Expression' object is not iterable @@ -2273,17 +2273,19 @@ def companion_matrix(poly, format='right'): [ 1 0 -8] [ 0 1 4] - sage: y = var('y') - sage: q = y^3 -2*y + 1 - sage: companion_matrix(q) + sage: y = var('y') # optional - sage.symbolic + sage: q = y^3 - 2*y + 1 # optional - sage.symbolic + sage: companion_matrix(q) # optional - sage.symbolic Traceback (most recent call last): ... - TypeError: input must be a polynomial (not a symbolic expression, see docstring), or other iterable, not y^3 - 2*y + 1 + TypeError: input must be a polynomial (not a symbolic expression, see docstring), + or other iterable, not y^3 - 2*y + 1 - sage: coeff_list = [q(y=0)] + [q.coefficient(y^k) for k in range(1, q.degree(y)+1)] - sage: coeff_list + sage: coeff_list = [q(y=0)] + [q.coefficient(y^k) # optional - sage.symbolic + ....: for k in range(1, q.degree(y)+1)] + sage: coeff_list # optional - sage.symbolic [1, -2, 0, 1] - sage: companion_matrix(coeff_list) + sage: companion_matrix(coeff_list) # optional - sage.symbolic [ 0 0 -1] [ 1 0 2] [ 0 1 0] @@ -2319,7 +2321,7 @@ def companion_matrix(poly, format='right'): ... ValueError: format must be 'right', 'left', 'top' or 'bottom', not junk - sage: companion_matrix(sin(x)) + sage: companion_matrix(sin(x)) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: input must be a polynomial (not a symbolic expression, see docstring), or other iterable, not sin(x) @@ -2329,8 +2331,8 @@ def companion_matrix(poly, format='right'): ... ValueError: polynomial (or the polynomial implied by coefficients) must be monic, not a leading coefficient of 896 - sage: F. = GF(2^2) - sage: companion_matrix([4/3, a+1, 1]) + sage: F. = GF(2^2) # optional - sage.rings.finite_rings + sage: companion_matrix([4/3, a+1, 1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to find common ring for coefficients from polynomial diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 82ff49e6e58..797302ded50 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -1197,11 +1197,11 @@ def __richcmp__(self, other, op): False sage: V1 <= V2 False - sage: R2 = GF(5)[x] # optional - sage.libs.pari - sage: F3 = R2^3 # optional - sage.libs.pari - sage: V3 = F3.span([[x^5-1, 1+x+x^2+x^3+x^4, 0]]) # optional - sage.libs.pari - sage: W3 = F3.span([[1,1,0], [0,4,0]]) # optional - sage.libs.pari - sage: V3 <= W3 # optional - sage.libs.pari + sage: R2. = GF(5)[] # optional - sage.rings.finite_rings + sage: F3 = R2^3 # optional - sage.rings.finite_rings + sage: V3 = F3.span([[x^5 - 1, 1 + x + x^2 + x^3 + x^4, 0]]) # optional - sage.rings.finite_rings + sage: W3 = F3.span([[1,1,0], [0,4,0]]) # optional - sage.rings.finite_rings + sage: V3 <= W3 # optional - sage.rings.finite_rings True sage: W3 <= V3 # optional - sage.libs.pari False @@ -1643,14 +1643,14 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 1 0] - sage: v = V((1, pi, log(2))); v + sage: v = V((1, pi, log(2))); v # optional - sage.symbolic (1.0, 3.141592653589793, 0.6931471805599453) - sage: W.span([v], base_ring=GF(7)) # optional - sage.libs.pari + sage: W.span([v], base_ring=GF(7)) # optional - sage.rings.finite_rings sage.symbolic Traceback (most recent call last): ... ValueError: argument gens (= [(1.0, 3.141592653589793, 0.6931471805599453)]) is not compatible with base_ring (= Finite Field of size 7) - sage: W = V.submodule([v]) - sage: W.span([V.gen(2)], base_ring=GF(7)) # optional - sage.libs.pari + sage: W = V.submodule([v]) # optional - sage.symbolic + sage: W.span([V.gen(2)], base_ring=GF(7)) # optional - sage.rings.finite_rings sage.symbolic Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 0 1] @@ -4809,10 +4809,9 @@ def complement(self): we can get complements which are only isomorphic to a vector space decomposition complement. :: - sage: F2 = GF(2, x) # optional - sage.libs.pari - sage: V = F2^6 # optional - sage.libs.pari - sage: W = V.span([[1,1,0,0,0,0]]) # optional - sage.libs.pari - sage: W # optional - sage.libs.pari + sage: F2 = GF(2, 'x') # optional - sage.rings.finite_rings + sage: V = F2^6 # optional - sage.rings.finite_rings + sage: W = V.span([[1,1,0,0,0,0]]); W # optional - sage.rings.finite_rings Vector space of degree 6 and dimension 1 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index f3682725f49..9aa2d2b0ff5 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -452,10 +452,10 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): sage: v = vector(QQ, w, immutable=True) sage: v.is_immutable() True - sage: import numpy as np # optional - numpy - sage: w = np.array([1, 2, pi], float) # optional - numpy - sage: v = vector(w, immutable=True) # optional - numpy - sage: v.is_immutable() # optional - numpy + sage: import numpy as np # optional - numpy + sage: w = np.array([1, 2, pi], float) # optional - numpy sage.symbolic + sage: v = vector(w, immutable=True) # optional - numpy sage.symbolic + sage: v.is_immutable() # optional - numpy sage.symbolic True sage: w = np.array([i, 2, 3], complex) # optional - numpy sage: v = vector(w, immutable=True) # optional - numpy @@ -746,7 +746,7 @@ def zero_vector(arg0, arg1=None): Garbage instead of a ring will be recognized as such. :: - sage: zero_vector(x^2, 5) + sage: zero_vector(x^2, 5) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: first argument must be a ring @@ -1192,7 +1192,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: from sage.misc.sage_input import SageInputBuilder sage: vector(ZZ, [42, 389])._sage_input_(SageInputBuilder(), False) {call: {atomic:vector}({atomic:ZZ}, {list: ({atomic:42}, {atomic:389})})} - sage: vector(RDF, {1:pi, 1000:e})._sage_input_(SageInputBuilder(), False) + sage: vector(RDF, {1:pi, 1000:e})._sage_input_(SageInputBuilder(), False) # optional - sage.symbolic {call: {atomic:vector}({atomic:RDF}, {dict: {{atomic:1}:{atomic:3.1415926535897931}, {atomic:1000}:{atomic:2.718281828459045...}}})} """ # Not a lot of room for prettiness here. @@ -1453,10 +1453,10 @@ cdef class FreeModuleElement(Vector): # abstract base class then taking a transpose. Notice that supplying a vector to the matrix constructor demonstrates Sage's preference for rows. :: - sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # optional - sage.libs.pari - sage: x.column() == matrix(x).transpose() # optional - sage.libs.pari + sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # optional - sage.libs.pari sage.symbolic + sage: x.column() == matrix(x).transpose() # optional - sage.libs.pari sage.symbolic True - sage: x.column() == x.row().transpose() # optional - sage.libs.pari + sage: x.column() == x.row().transpose() # optional - sage.libs.pari sage.symbolic True Sparse or dense implementations are preserved. :: @@ -3171,10 +3171,10 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: sage: n = 15 - sage: x = vector(CDF, [sin(i*pi/n)+cos(i*pi/n)*I for i in range(n)]) - sage: x + x.conjugate() in RDF^n + sage: x = vector(CDF, [sin(i*pi/n)+cos(i*pi/n)*I for i in range(n)]) # optional - sage.symbolic + sage: x + x.conjugate() in RDF^n # optional - sage.symbolic True - sage: I*(x - x.conjugate()) in RDF^n + sage: I*(x - x.conjugate()) in RDF^n # optional - sage.symbolic True The parent of the conjugate is the same as that of the original vector. @@ -3877,7 +3877,7 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: sage: m = vector(SR,[]) # optional - sage.symbolic - sage: m.apply_map(lambda x: x*x) == m + sage: m.apply_map(lambda x: x*x) == m # optional - sage.symbolic True Check that we don't unnecessarily apply phi to 0 in the sparse case:: @@ -4220,7 +4220,7 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: type(vector(RR, [-1,0,2/3,pi,oo])) + sage: type(vector(RR, [-1,0,2/3,pi,oo])) # optional - sage.symbolic We can initialize with lists, tuples and derived types:: diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index 0a9a466e158..fd52d96d3c1 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -523,6 +523,7 @@ def __mul__(self, right): Composite maps can be formed with matrix morphisms:: + sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^2 + 23) # optional - sage.rings.number_field sage: V, VtoK, KtoV = K.vector_space() # optional - sage.rings.number_field sage: f = V.hom([V.0 - V.1, V.0 + V.1])*KtoV; f # optional - sage.rings.number_field diff --git a/src/sage/modules/vector_complex_double_dense.pyx b/src/sage/modules/vector_complex_double_dense.pyx index 43f3322d627..4cba2e7726b 100644 --- a/src/sage/modules/vector_complex_double_dense.pyx +++ b/src/sage/modules/vector_complex_double_dense.pyx @@ -3,17 +3,16 @@ Dense complex double vectors using a NumPy backend EXAMPLES:: - sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]) - sage: v + sage: v = vector(CDF, [(1,-1), (2,pi), (3,5)]), v # optional - sage.symbolic (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: type(v) + sage: type(v) # optional - sage.symbolic - sage: parent(v) + sage: parent(v) # optional - sage.symbolic Vector space of dimension 3 over Complex Double Field - sage: v[0] = 5 - sage: v + sage: v[0] = 5 # optional - sage.symbolic + sage: v # optional - sage.symbolic (5.0, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: loads(dumps(v)) == v + sage: loads(dumps(v)) == v # optional - sage.symbolic True TESTS:: @@ -54,10 +53,9 @@ cdef class Vector_complex_double_dense(Vector_double_dense): EXAMPLES:: - sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]) - sage: v + sage: v = vector(CDF, [(1,-1), (2,pi), (3,5)]); v # optional - sage.symbolic (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: v*v # rel tol 1e-15 + sage: v*v # rel tol 1e-15 # optional - sage.symbolic -21.86960440108936 + 40.56637061435917*I """ def __cinit__(self, parent, entries, coerce=True, copy=True): diff --git a/src/sage/modules/vector_double_dense.pyx b/src/sage/modules/vector_double_dense.pyx index 2d581606980..a6981fde9fb 100644 --- a/src/sage/modules/vector_double_dense.pyx +++ b/src/sage/modules/vector_double_dense.pyx @@ -6,17 +6,16 @@ Complex Double Field EXAMPLES:: - sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]) - sage: v + sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]); v # optional - sage.symbolic (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: type(v) + sage: type(v) # optional - sage.symbolic - sage: parent(v) + sage: parent(v) # optional - sage.symbolic Vector space of dimension 3 over Complex Double Field - sage: v[0] = 5 - sage: v + sage: v[0] = 5 # optional - sage.symbolic + sage: v # optional - sage.symbolic (5.0, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: loads(dumps(v)) == v + sage: loads(dumps(v)) == v # optional - sage.symbolic True sage: v = vector(RDF, [1,2,3,4]); v (1.0, 2.0, 3.0, 4.0) diff --git a/src/sage/modules/vector_real_double_dense.pyx b/src/sage/modules/vector_real_double_dense.pyx index 7a3d674e1eb..948ea384881 100644 --- a/src/sage/modules/vector_real_double_dense.pyx +++ b/src/sage/modules/vector_real_double_dense.pyx @@ -3,17 +3,16 @@ Dense real double vectors using a NumPy backend EXAMPLES:: - sage: v = vector(RDF,[1, pi, sqrt(2)]) - sage: v + sage: v = vector(RDF, [1, pi, sqrt(2)]); v # optional - sage.symbolic (1.0, 3.141592653589793, 1.414213562373095) - sage: type(v) + sage: type(v) # optional - sage.symbolic - sage: parent(v) + sage: parent(v) # optional - sage.symbolic Vector space of dimension 3 over Real Double Field - sage: v[0] = 5 - sage: v + sage: v[0] = 5 # optional - sage.symbolic + sage: v # optional - sage.symbolic (5.0, 3.141592653589793, 1.414213562373095) - sage: loads(dumps(v)) == v + sage: loads(dumps(v)) == v # optional - sage.symbolic True AUTHORS: diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index 53f99fc4fd8..21665139231 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -957,7 +957,7 @@ cdef class RealDistribution(ProbabilityDistribution): EXAMPLES:: sage: T = RealDistribution('uniform', [0, 2]) - sage: P = T.plot() + sage: P = T.plot() # optional - sage.plot """ from sage.plot.plot import plot return plot(self.distribution_function, *args, **kwds) diff --git a/src/sage/quadratic_forms/special_values.py b/src/sage/quadratic_forms/special_values.py index 93a56c45c8c..6a734c5754b 100644 --- a/src/sage/quadratic_forms/special_values.py +++ b/src/sage/quadratic_forms/special_values.py @@ -105,8 +105,9 @@ def zeta__exact(n): Let us test the accuracy for negative special values:: sage: RR = RealField(100) - sage: for i in range(1,10): - ....: print("zeta({}): {}".format(1-2*i, RR(zeta__exact(1-2*i)) - zeta(RR(1-2*i)))) + sage: for i in range(1,10): # optional - sage.symbolic + ....: print("zeta({}): {}".format(1 - 2*i, + ....: RR(zeta__exact(1-2*i)) - zeta(RR(1-2*i)))) zeta(-1): 0.00000000000000000000000000000 zeta(-3): 0.00000000000000000000000000000 zeta(-5): 0.00000000000000000000000000000 @@ -119,7 +120,8 @@ def zeta__exact(n): Let us test the accuracy for positive special values:: - sage: all(abs(RR(zeta__exact(2*i)) - zeta(RR(2*i))) < 10**(-28) for i in range(1,10)) + sage: all(abs(RR(zeta__exact(2*i)) - zeta(RR(2*i))) < 10**(-28) # optional - sage.symbolic + ....: for i in range(1,10)) True TESTS:: @@ -270,7 +272,7 @@ def quadratic_L_function__numerical(n, d, num_terms=1000): First, let us test several values for a given character:: sage: RR = RealField(100) - sage: for i in range(5): + sage: for i in range(5): # optional - sage.symbolic ....: print("L({}, (-4/.)): {}".format(1+2*i, ....: RR(quadratic_L_function__exact(1+2*i, -4)) ....: - quadratic_L_function__numerical(RR(1+2*i), -4, 10000))) @@ -291,7 +293,7 @@ def quadratic_L_function__numerical(n, d, num_terms=1000): Test for several characters that the result agrees with the exact value, to a given accuracy :: - sage: for d in range(-20,0): # long time (2s on sage.math 2014) + sage: for d in range(-20,0): # long time (2s on sage.math 2014) # optional - sage.symbolic ....: if abs(RR(quadratic_L_function__numerical(1, d, 10000) ....: - quadratic_L_function__exact(1, d))) > 0.001: ....: print("We have a problem at d = {}: exact = {}, numerical = {}".format(d, diff --git a/src/sage/stats/distributions/discrete_gaussian_integer.pyx b/src/sage/stats/distributions/discrete_gaussian_integer.pyx index 87fbe6ca5cd..f87915b4e4f 100644 --- a/src/sage/stats/distributions/discrete_gaussian_integer.pyx +++ b/src/sage/stats/distributions/discrete_gaussian_integer.pyx @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.symbolic # # distutils: sources = sage/stats/distributions/dgs_gauss_mp.c sage/stats/distributions/dgs_gauss_dp.c sage/stats/distributions/dgs_bern.c # distutils: depends = sage/stats/distributions/dgs_gauss.h sage/stats/distributions/dgs_bern.h sage/stats/distributions/dgs_misc.h diff --git a/src/sage/stats/distributions/discrete_gaussian_lattice.py b/src/sage/stats/distributions/discrete_gaussian_lattice.py index f140d18f4c5..d77f9e30d09 100644 --- a/src/sage/stats/distributions/discrete_gaussian_lattice.py +++ b/src/sage/stats/distributions/discrete_gaussian_lattice.py @@ -139,7 +139,7 @@ class DiscreteGaussianDistributionLatticeSampler(SageObject): sage: D = DiscreteGaussianDistributionLatticeSampler(identity_matrix(2), 3.0) sage: S = [D() for _ in range(2^12)] sage: l = [vector(v.list() + [S.count(v)]) for v in set(S)] - sage: list_plot3d(l, point_list=True, interpolation='nn') + sage: list_plot3d(l, point_list=True, interpolation='nn') # optional - sage.plot Graphics3d Object REFERENCES: diff --git a/src/sage/stats/hmm/distributions.pyx b/src/sage/stats/hmm/distributions.pyx index 0cc9823a38f..27d12982c73 100644 --- a/src/sage/stats/hmm/distributions.pyx +++ b/src/sage/stats/hmm/distributions.pyx @@ -133,7 +133,7 @@ cdef class Distribution: EXAMPLES:: sage: P = hmm.GaussianMixtureDistribution([(.2,-10,.5),(.6,1,1),(.2,20,.5)]) - sage: P.plot(-10,30) + sage: P.plot(-10,30) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.all import plot diff --git a/src/sage/stats/hmm/hmm.pyx b/src/sage/stats/hmm/hmm.pyx index 8f2eee8bebc..5fb6e0af596 100644 --- a/src/sage/stats/hmm/hmm.pyx +++ b/src/sage/stats/hmm/hmm.pyx @@ -135,7 +135,7 @@ cdef class HiddenMarkovModel: Looped digraph on 3 vertices sage: G.edges(sort=True) [(0, 0, 0.3), (0, 2, 0.7), (1, 2, 1.0), (2, 0, 0.5), (2, 1, 0.5)] - sage: G.plot() + sage: G.plot() # optional - sage.plot Graphics object consisting of 11 graphics primitives """ cdef int i, j @@ -291,7 +291,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): Initial probabilities: [0.0000, 1.0000] sage: m.sample(10) [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] - sage: m.graph().plot() + sage: m.graph().plot() # optional - sage.plot Graphics object consisting of 6 graphics primitives A 3-state model that happens to always outputs 'b':: diff --git a/src/sage/stats/intlist.pyx b/src/sage/stats/intlist.pyx index cf6cccaf537..21bdeb59a68 100644 --- a/src/sage/stats/intlist.pyx +++ b/src/sage/stats/intlist.pyx @@ -517,9 +517,10 @@ cdef class IntList: EXAMPLES:: - sage: stats.IntList([3,7,19,-2]).plot() + sage: stats.IntList([3,7,19,-2]).plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: stats.IntList([3,7,19,-2]).plot(color='red',pointsize=50,points=True) + sage: stats.IntList([3,7,19,-2]).plot(color='red', # optional - sage.plot + ....: pointsize=50, points=True) Graphics object consisting of 1 graphics primitive """ return self.time_series().plot(*args, **kwds) @@ -532,7 +533,7 @@ cdef class IntList: EXAMPLES:: - sage: stats.IntList([1..15]).plot_histogram() + sage: stats.IntList([1..15]).plot_histogram() # optional - sage.plot Graphics object consisting of 50 graphics primitives """ return self.time_series().plot_histogram(*args, **kwds) diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 1c98136a7d7..9321ed51463 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -96,7 +96,7 @@ cdef class TimeSeries: This implicitly calls init:: - sage: stats.TimeSeries([pi, 3, 18.2]) + sage: stats.TimeSeries([pi, 3, 18.2]) # optional - sage.symbolic [3.1416, 3.0000, 18.2000] Conversion from a NumPy 1-D array, which is very fast:: @@ -1030,7 +1030,7 @@ cdef class TimeSeries: Draw a plot of a time series:: - sage: stats.TimeSeries([1..10]).show() + sage: stats.TimeSeries([1..10]).show() # optional - sage.plot Graphics object consisting of 1 graphics primitive """ return self.plot(*args, **kwds) @@ -1056,13 +1056,13 @@ cdef class TimeSeries: sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000] - sage: v.plot() + sage: v.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: v.plot(points=True) + sage: v.plot(points=True) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: v.plot() + v.plot(points=True, rgbcolor='red') + sage: v.plot() + v.plot(points=True, rgbcolor='red') # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: v.plot() + v.plot(points=True, rgbcolor='red', pointsize=50) + sage: v.plot() + v.plot(points=True, rgbcolor='red', pointsize=50) # optional - sage.plot Graphics object consisting of 2 graphics primitives """ from sage.plot.all import line, point @@ -1987,12 +1987,12 @@ cdef class TimeSeries: EXAMPLES:: sage: v = stats.TimeSeries([1..50]) - sage: v.plot_histogram(bins=10) + sage: v.plot_histogram(bins=10) # optional - sage.plot Graphics object consisting of 10 graphics primitives :: - sage: v.plot_histogram(bins=3,normalize=False,aspect_ratio=1) + sage: v.plot_histogram(bins=3,normalize=False,aspect_ratio=1) # optional - sage.plot Graphics object consisting of 3 graphics primitives """ from sage.plot.all import polygon @@ -2031,7 +2031,7 @@ cdef class TimeSeries: Here we look at the candlestick plot for Brownian motion:: sage: v = stats.TimeSeries(1000).randomize() - sage: v.plot_candlestick(bins=20) + sage: v.plot_candlestick(bins=20) # optional - sage.plot Graphics object consisting of 40 graphics primitives """ from sage.plot.all import line, polygon, Graphics @@ -2394,7 +2394,7 @@ cdef class TimeSeries: sage: v = stats.TimeSeries(10^6) sage: v.randomize('lognormal').mean() 1.647351973... - sage: exp(0.5) + sage: exp(0.5) # optional - sage.symbolic 1.648721270... A log-normal distribution can be simply thought of as the logarithm From 91eaee7e1c4f23e7019bd76a1ec3c3f698b0314e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 May 2023 18:53:11 -0700 Subject: [PATCH 33/99] More fixes --- src/sage/modules/free_module_integer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index 8d8f99930b9..9b77d3d9f28 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -781,7 +781,7 @@ def projection(M, v): def CVPP_2V(t, V, voronoi_cell): t_new = t while not voronoi_cell.contains(t_new.list()): - v = max(V, key=lambda v: t_new * v / v.norm() ** 2) + v = max(V, key=lambda v: t_new * v / v.dot_product(v)) t_new = t_new - v return t - t_new From ac604c202b9394558d40845ed9ba9ed9b8a9ad3e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 20 May 2023 22:49:07 -0700 Subject: [PATCH 34/99] Fixups --- src/sage/modules/vector_complex_double_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/vector_complex_double_dense.pyx b/src/sage/modules/vector_complex_double_dense.pyx index 4cba2e7726b..7366acb560a 100644 --- a/src/sage/modules/vector_complex_double_dense.pyx +++ b/src/sage/modules/vector_complex_double_dense.pyx @@ -3,7 +3,7 @@ Dense complex double vectors using a NumPy backend EXAMPLES:: - sage: v = vector(CDF, [(1,-1), (2,pi), (3,5)]), v # optional - sage.symbolic + sage: v = vector(CDF, [(1,-1), (2,pi), (3,5)]); v # optional - sage.symbolic (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) sage: type(v) # optional - sage.symbolic From 9d18fb3fc0858a857e8b796f6d0985db0b292855 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 1 Jun 2023 23:01:08 -0700 Subject: [PATCH 35/99] sage.matrix: Add # optional --- src/sage/matrix/matrix1.pyx | 4 ++-- src/sage/matrix/matrix2.pyx | 2 +- src/sage/matrix/special.py | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 49babe96d46..a19a3c73ab0 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -83,7 +83,7 @@ cdef class Matrix(Matrix0): sage: a = matrix(R, 2, [1, 2, 3, 1]); a [1.0 2.0] [3.0 1.0] - sage: b = pari(a); b + sage: b = pari(a); b # optional - sage.libs.pari [1.000000000, 2.000000000; 3.000000000, 1.000000000] # 32-bit [1.00000000000000, 2.00000000000000; 3.00000000000000, 1.00000000000000] # 64-bit """ @@ -271,7 +271,7 @@ cdef class Matrix(Matrix0): sage: A = MatrixSpace(QQ,3)([1,2,3,4/3,5/3,6/4,7,8,9]) sage: g = mathematica(A); g # optional - mathematica {{1, 2, 3}, {4/3, 5/3, 3/2}, {7, 8, 9}} - sage: A._mathematica_init_() + sage: A._mathematica_init_() # optional - sage.symbolic '{{1/1, 2/1, 3/1}, {4/3, 5/3, 3/2}, {7/1, 8/1, 9/1}}' :: diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 8a782fd7068..2f4a649f2f9 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1720,7 +1720,7 @@ cdef class Matrix(Matrix1): sage: A = identity_matrix(21) sage: A.rook_vector(complement=True)[-1] 18795307255050944540 - sage: Derangements(21).cardinality() + sage: Derangements(21).cardinality() # optional - sage.combinat 18795307255050944540 An other example that we convert into a rook polynomial:: diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index a2fcc5e8c1d..58bd22be6df 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -739,11 +739,11 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): Format 4: ring, size and list of entries. :: - sage: A = diagonal_matrix(FiniteField(3), 3, [2, 16]); A + sage: A = diagonal_matrix(FiniteField(3), 3, [2, 16]); A # optional - sage.rings.finite_rings [2 0 0] [0 1 0] [0 0 0] - sage: A.parent() + sage: A.parent() # optional - sage.rings.finite_rings Full MatrixSpace of 3 by 3 sparse matrices over Finite Field of size 3 NumPy arrays may be used as input. :: @@ -1506,24 +1506,24 @@ def circulant(v, sparse=None): EXAMPLES:: - sage: v=[1,2,3,4,8] + sage: v = [1,2,3,4,8] sage: matrix.circulant(v) [1 2 3 4 8] [8 1 2 3 4] [4 8 1 2 3] [3 4 8 1 2] [2 3 4 8 1] - sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=True)); m + sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=True)); m # optional - sage.rings.finite_rings [0 1 2] [2 0 1] [1 2 0] - sage: m.is_sparse() + sage: m.is_sparse() # optional - sage.rings.finite_rings True TESTS:: - sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=False)) - sage: m.is_sparse() + sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=False)) # optional - sage.rings.finite_rings + sage: m.is_sparse() # optional - sage.rings.finite_rings False sage: matrix.circulant([0,1,-1]).is_sparse() False From 18f8100a231cdd7e51ad952f01b364523e37cf06 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 1 Jun 2023 23:01:44 -0700 Subject: [PATCH 36/99] sage.modules: More # optional --- src/sage/modules/diamond_cutting.py | 1 + src/sage/modules/tutorial_free_modules.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/modules/diamond_cutting.py b/src/sage/modules/diamond_cutting.py index b18fc315754..7f71b6a671a 100644 --- a/src/sage/modules/diamond_cutting.py +++ b/src/sage/modules/diamond_cutting.py @@ -1,3 +1,4 @@ +# optional - sage.geometry.polyhedron """ Diamond cutting implementation diff --git a/src/sage/modules/tutorial_free_modules.py b/src/sage/modules/tutorial_free_modules.py index d58acd4ae9f..d5dd60d00bf 100644 --- a/src/sage/modules/tutorial_free_modules.py +++ b/src/sage/modules/tutorial_free_modules.py @@ -40,7 +40,8 @@ sage: F = CombinatorialFreeModule(ZZ, CC); F.an_element() B[1.00000000000000*I] - sage: F = CombinatorialFreeModule(ZZ, Partitions(NonNegativeIntegers(), max_part=3)); F.an_element() + sage: F = CombinatorialFreeModule(ZZ, Partitions(NonNegativeIntegers(), # optional - sage.combinat + ....: max_part=3)); F.an_element() 2*B[[]] + 2*B[[1]] + 3*B[[2]] sage: F = CombinatorialFreeModule(ZZ, ['spam', 'eggs', '42']); F.an_element() 3*B['42'] + 2*B['eggs'] + 2*B['spam'] @@ -89,7 +90,9 @@ module:: sage: a = F.basis(); a - Lazy family (Term map from Ring of integers modulo 5 to Free module generated by Ring of integers modulo 5 over Integer Ring(i))_{i in Ring of integers modulo 5} + Lazy family (Term map from Ring of integers modulo 5 + to Free module generated by Ring of integers modulo 5 + over Integer Ring(i))_{i in Ring of integers modulo 5} This gadget models the :class:`family ` `(B_i)_{i \in \ZZ_5}`. In particular, one can run through its elements:: From 3d55279390441c989385e27beb2df30ec2bd51e4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 1 Jun 2023 23:03:13 -0700 Subject: [PATCH 37/99] Add # optional --- src/sage/quadratic_forms/quadratic_form.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 4eb377365fc..84a00cd8418 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -100,25 +100,24 @@ def quadratic_form_from_invariants(F, rk, det, P, sminus): EXAMPLES:: sage: P = [3,5] - sage: q = quadratic_form_from_invariants(QQ,2,-15,P,1) - sage: q + sage: q = quadratic_form_from_invariants(QQ,2,-15,P,1); q # optional - sage.rings.padics Quadratic form in 2 variables over Rational Field with coefficients: [ 5 0 ] [ * -3 ] - sage: all(q.hasse_invariant(p) == -1 for p in P) + sage: all(q.hasse_invariant(p) == -1 for p in P) # optional - sage.rings.padics True TESTS: This shows that :trac:`28955` is fixed:: - sage: quadratic_form_from_invariants(QQ,3,2,[2],2) + sage: quadratic_form_from_invariants(QQ,3,2,[2],2) # optional - sage.rings.padics Quadratic form in 3 variables over Rational Field with coefficients: [ -1 0 0 ] [ * 1 0 ] [ * * -2 ] - sage: quadratic_form_from_invariants(QQ,4,2,[2],4) + sage: quadratic_form_from_invariants(QQ,4,2,[2],4) # optional - sage.rings.padics Traceback (most recent call last): ... ValueError: invariants do not define a rational quadratic form From 8f930bbb1e728cc76550c5b082d66bddcc662dfc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 1 Jun 2023 23:35:47 -0700 Subject: [PATCH 38/99] Fix # optional --- src/sage/modules/diamond_cutting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/diamond_cutting.py b/src/sage/modules/diamond_cutting.py index 7f71b6a671a..97363f37e5b 100644 --- a/src/sage/modules/diamond_cutting.py +++ b/src/sage/modules/diamond_cutting.py @@ -1,4 +1,4 @@ -# optional - sage.geometry.polyhedron +# sage.doctest: optional - sage.geometry.polyhedron """ Diamond cutting implementation From a104978e71d7d7a88cbea099c16841bd8807f3a0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 3 Jun 2023 16:35:35 -0700 Subject: [PATCH 39/99] sage.quadratic_forms: More # optional --- src/sage/quadratic_forms/binary_qf.py | 28 +++++++++---------- .../quadratic_form__equivalence_testing.py | 26 ++++++++--------- .../quadratic_form__ternary_Tornaria.py | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index f678dc6b3b1..db8da67ff80 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -868,7 +868,7 @@ def reduced_form(self, transformation=False, algorithm="default"): [ 1 -1] x^2 + 2*y^2, [ 0 1] ) - sage: BinaryQF([-225, -743, -743]).reduced_form().is_reduced() + sage: BinaryQF([-225, -743, -743]).reduced_form().is_reduced() # optional - sage.libs.pari True Some randomized testing:: @@ -881,17 +881,17 @@ def reduced_form(self, transformation=False, algorithm="default"): sage: if f.discriminant() > 0: ....: algos.append('sage') sage: a = choice(algos) - sage: g = f.reduced_form(algorithm=a) - sage: g.is_reduced() + sage: g = f.reduced_form(algorithm=a) # optional - sage.libs.pari + sage: g.is_reduced() # optional - sage.libs.pari True - sage: g.is_equivalent(f) + sage: g.is_equivalent(f) # optional - sage.libs.pari True - sage: g,M = f.reduced_form(transformation=True, algorithm=a) - sage: g.is_reduced() + sage: g,M = f.reduced_form(transformation=True, algorithm=a) # optional - sage.libs.pari + sage: g.is_reduced() # optional - sage.libs.pari True - sage: g.is_equivalent(f) + sage: g.is_equivalent(f) # optional - sage.libs.pari True - sage: f * M == g + sage: f * M == g # optional - sage.libs.pari True """ if self.is_reduced(): @@ -1578,9 +1578,9 @@ def solve_integer(self, n, *, algorithm="general"): sage: Q = BinaryQF([1, 0, 12345]) sage: n = 2^99 + 5273 - sage: Q.solve_integer(n) + sage: Q.solve_integer(n) # optional - sage.libs.pari (-67446480057659, 7139620553488) - sage: Q.solve_integer(n, algorithm='cornacchia') + sage: Q.solve_integer(n, algorithm='cornacchia') # optional - sage.libs.pari (67446480057659, 7139620553488) sage: timeit('Q.solve_integer(n)') # not tested 125 loops, best of 3: 3.13 ms per loop @@ -1616,11 +1616,11 @@ def solve_integer(self, n, *, algorithm="general"): sage: n = random_prime(10^9) sage: if randrange(2): ....: n *= 4 - sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') - sage: xy1 is None or Q(*xy1) == n + sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') # optional - sage.libs.pari + sage: xy1 is None or Q(*xy1) == n # optional - sage.libs.pari True - sage: xy2 = Q.solve_integer(n) - sage: (xy1 is None) == (xy2 is None) + sage: xy2 = Q.solve_integer(n) # optional - sage.libs.pari + sage: (xy1 is None) == (xy2 is None) # optional - sage.libs.pari True Test for square discriminants specifically (:trac:`33026`):: diff --git a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py index 5b0ff64b778..9766f1f4b96 100644 --- a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py +++ b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py @@ -47,10 +47,10 @@ def is_globally_equivalent_to(self, other, return_matrix=False): sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: M = Matrix(ZZ, 4, 4, [1,2,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]) sage: Q1 = Q(M) - sage: Q.is_globally_equivalent_to(Q1) + sage: Q.is_globally_equivalent_to(Q1) # optional - sage.libs.pari True - sage: MM = Q.is_globally_equivalent_to(Q1, return_matrix=True) - sage: Q(MM) == Q1 + sage: MM = Q.is_globally_equivalent_to(Q1, return_matrix=True) # optional - sage.libs.pari + sage: Q(MM) == Q1 # optional - sage.libs.pari True :: @@ -58,23 +58,23 @@ def is_globally_equivalent_to(self, other, return_matrix=False): sage: Q1 = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) sage: Q2 = QuadraticForm(ZZ, 3, [2, 1, 2, 2, 1, 3]) sage: Q3 = QuadraticForm(ZZ, 3, [8, 6, 5, 3, 4, 2]) - sage: Q1.is_globally_equivalent_to(Q2) + sage: Q1.is_globally_equivalent_to(Q2) # optional - sage.libs.pari False - sage: Q1.is_globally_equivalent_to(Q2, return_matrix=True) + sage: Q1.is_globally_equivalent_to(Q2, return_matrix=True) # optional - sage.libs.pari False - sage: Q1.is_globally_equivalent_to(Q3) + sage: Q1.is_globally_equivalent_to(Q3) # optional - sage.libs.pari True - sage: M = Q1.is_globally_equivalent_to(Q3, True); M + sage: M = Q1.is_globally_equivalent_to(Q3, True); M # optional - sage.libs.pari [-1 -1 0] [ 1 1 1] [-1 0 0] - sage: Q1(M) == Q3 + sage: Q1(M) == Q3 # optional - sage.libs.pari True :: sage: Q = DiagonalQuadraticForm(ZZ, [1, -1]) - sage: Q.is_globally_equivalent_to(Q) + sage: Q.is_globally_equivalent_to(Q) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: not a definite form in QuadraticForm.is_globally_equivalent_to() @@ -88,9 +88,9 @@ def is_globally_equivalent_to(self, other, return_matrix=False): sage: Q = QuadraticForm(ZZ, 2, [2, 3, 5]) sage: P = QuadraticForm(ZZ, 2, [8, 6, 5]) - sage: Q.is_globally_equivalent_to(P) + sage: Q.is_globally_equivalent_to(P) # optional - sage.libs.pari False - sage: P.is_globally_equivalent_to(Q) + sage: P.is_globally_equivalent_to(Q) # optional - sage.libs.pari False """ from sage.quadratic_forms.quadratic_form import QuadraticForm @@ -132,9 +132,9 @@ def is_locally_equivalent_to(self, other, check_primes_only=False, force_jordan_ sage: Q1 = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) sage: Q2 = QuadraticForm(ZZ, 3, [2, 1, 2, 2, 1, 3]) - sage: Q1.is_globally_equivalent_to(Q2) + sage: Q1.is_globally_equivalent_to(Q2) # optional - sage.libs.pari False - sage: Q1.is_locally_equivalent_to(Q2) + sage: Q1.is_locally_equivalent_to(Q2) # optional - sage.libs.pari True """ # TO IMPLEMENT: diff --git a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py index 9b8dfcecf7b..3651c8dfddc 100644 --- a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +++ b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py @@ -509,7 +509,7 @@ def lll(self): sage: Q = QuadraticForm(ZZ, 4, range(1,11)) sage: Q.is_definite() True - sage: Q.lll() + sage: Q.lll() # optional - sage.libs.pari Quadratic form in 4 variables over Integer Ring with coefficients: [ 1 0 1 0 ] [ * 4 3 3 ] From c65c36fc8cd6842ed3cac7200f5b00e55ef71afd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 4 Jun 2023 15:27:44 -0700 Subject: [PATCH 40/99] More # optional --- src/sage/modules/free_module_element.pyx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 9aa2d2b0ff5..a4985a216e4 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -2601,7 +2601,10 @@ cdef class FreeModuleElement(Vector): # abstract base class Check for :trac:`33814`:: - sage: for R in [ZZ, QQ, RDF, RR, GF(2), GF(3), GF(4), ZZ['x']]: + sage: rings = [ZZ, QQ, RDF, ZZ['x']] + sage: rings += [RR] # optional - sage.rings.real_mpfr + sage: rings += [GF(2), GF(3), GF(4)] # optional - sage.rings.finite_rings + sage: for R in rings: ....: _ = (R**0)().dot_product((R**0)()) """ cdef FreeModuleElement r = right From e1e5f6051bd5c18031e993392391500f05d7aa57 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 18:06:20 -0700 Subject: [PATCH 41/99] More # optional --- src/sage/matrix/matrix2.pyx | 112 ++++++++++-------- .../tensor/modules/tensor_with_indices.py | 2 +- 2 files changed, 64 insertions(+), 50 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 2f4a649f2f9..4e63b6507a3 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1744,7 +1744,7 @@ cdef class Matrix(Matrix1): [1, 8, 20, 16, 4] sage: A.rook_vector(algorithm="Ryser") [1, 8, 20, 16, 4] - sage: A.rook_vector(algorithm="Godsil") + sage: A.rook_vector(algorithm="Godsil") # optional - sage.graphs [1, 8, 20, 16, 4] When the matrix `A` has more ones then zeroes it is usually faster @@ -1788,11 +1788,13 @@ cdef class Matrix(Matrix1): [1, 0, 0] sage: matrix.ones(4, 2).rook_vector("Ryser") [1, 8, 12] - sage: matrix.ones(4, 2).rook_vector("Godsil") + sage: matrix.ones(4, 2).rook_vector("Godsil") # optional - sage.graphs [1, 8, 12] sage: m = matrix(ZZ,4,5) sage: m[:4,:4] = identity_matrix(4) - sage: for algorithm in ("Godsil","Ryser","ButeraPernici"): + sage: algos = ["Ryser", "ButeraPernici"] + sage: algos += ["Godsil"] # optional - sage.graphs + sage: for algorithm in algos: ....: v = m.rook_vector(complement=True, use_complement=True, algorithm=algorithm) ....: if v != [1, 16, 78, 128, 53]: ....: print("ERROR with algorithm={} use_complement=True".format(algorithm)) @@ -6188,7 +6190,7 @@ cdef class Matrix(Matrix1): `T_2` on level 43 modular symbols, both with all eigenvalues (the default) and with one subspace per factor. :: - sage: A = ModularSymbols(43).T(2).matrix(); A + sage: A = ModularSymbols(43).T(2).matrix(); A # optional - sage.modular [ 3 0 0 0 0 0 -1] [ 0 -2 1 0 0 0 0] [ 0 -1 1 1 0 -1 0] @@ -6196,59 +6198,70 @@ cdef class Matrix(Matrix1): [ 0 -1 0 1 1 -1 1] [ 0 0 -2 0 2 -2 1] [ 0 0 -1 0 1 0 -1] - sage: A.base_ring() + sage: A.base_ring() # optional - sage.modular Rational Field - sage: f = A.charpoly(); f + sage: f = A.charpoly(); f # optional - sage.modular x^7 + x^6 - 12*x^5 - 16*x^4 + 36*x^3 + 52*x^2 - 32*x - 48 - sage: factor(f) + sage: factor(f) # optional - sage.modular (x - 3) * (x + 2)^2 * (x^2 - 2)^2 - sage: A.eigenspaces_left(algebraic_multiplicity=True) - [ - (3, Vector space of degree 7 and dimension 1 over Rational Field - User basis matrix: - [ 1 0 1/7 0 -1/7 0 -2/7], 1), - (-2, Vector space of degree 7 and dimension 2 over Rational Field - User basis matrix: - [ 0 1 0 1 -1 1 -1] - [ 0 0 1 0 -1 2 -1], 2), - (-1.414213562373095?, Vector space of degree 7 and dimension 2 over Algebraic Field - User basis matrix: - [ 0 1 0 -1 0.4142135623730951? 1 -1] - [ 0 0 1 0 -1 0 2.414213562373095?], 2), - (1.414213562373095?, Vector space of degree 7 and dimension 2 over Algebraic Field - User basis matrix: - [ 0 1 0 -1 -2.414213562373095? 1 -1] - [ 0 0 1 0 -1 0 -0.4142135623730951?], 2) - ] - sage: A.eigenspaces_left(format='galois', algebraic_multiplicity=True) - [ - (3, Vector space of degree 7 and dimension 1 over Rational Field - User basis matrix: - [ 1 0 1/7 0 -1/7 0 -2/7], 1), - (-2, Vector space of degree 7 and dimension 2 over Rational Field - User basis matrix: - [ 0 1 0 1 -1 1 -1] - [ 0 0 1 0 -1 2 -1], 2), - (a2, Vector space of degree 7 and dimension 2 over Number Field in a2 with defining polynomial x^2 - 2 - User basis matrix: - [ 0 1 0 -1 -a2 - 1 1 -1] - [ 0 0 1 0 -1 0 -a2 + 1], 2) - ] + sage: A.eigenspaces_left(algebraic_multiplicity=True) # optional - sage.modular + [ (3, + Vector space of degree 7 and dimension 1 over Rational Field + User basis matrix: + [ 1 0 1/7 0 -1/7 0 -2/7], + 1), + (-2, + Vector space of degree 7 and dimension 2 over Rational Field + User basis matrix: + [ 0 1 0 1 -1 1 -1] + [ 0 0 1 0 -1 2 -1], + 2), + (-1.414213562373095?, + Vector space of degree 7 and dimension 2 over Algebraic Field + User basis matrix: + [ 0 1 0 -1 0.4142135623730951? 1 -1] + [ 0 0 1 0 -1 0 2.414213562373095?], + 2), + (1.414213562373095?, + Vector space of degree 7 and dimension 2 over Algebraic Field + User basis matrix: + [ 0 1 0 -1 -2.414213562373095? 1 -1] + [ 0 0 1 0 -1 0 -0.4142135623730951?], + 2) ] + sage: A.eigenspaces_left(format='galois', algebraic_multiplicity=True) # optional - sage.modular + [ (3, + Vector space of degree 7 and dimension 1 over Rational Field + User basis matrix: + [ 1 0 1/7 0 -1/7 0 -2/7], + 1), + (-2, + Vector space of degree 7 and dimension 2 over Rational Field + User basis matrix: + [ 0 1 0 1 -1 1 -1] + [ 0 0 1 0 -1 2 -1], + 2), + (a2, + Vector space of degree 7 and dimension 2 + over Number Field in a2 with defining polynomial x^2 - 2 + User basis matrix: + [ 0 1 0 -1 -a2 - 1 1 -1] + [ 0 0 1 0 -1 0 -a2 + 1], + 2) ] Next we compute the left eigenspaces over the finite field of order 11. :: - sage: A = ModularSymbols(43, base_ring=GF(11), sign=1).T(2).matrix(); A # optional - sage.libs.pari + sage: A = ModularSymbols(43, base_ring=GF(11), sign=1).T(2).matrix(); A # optional - sage.modular sage.rings.finite_rings [ 3 0 9 0] [ 0 9 0 10] [ 0 0 10 1] [ 0 0 1 1] - sage: A.base_ring() # optional - sage.libs.pari + sage: A.base_ring() # optional - sage.modular sage.rings.finite_rings Finite Field of size 11 - sage: A.charpoly() # optional - sage.libs.pari + sage: A.charpoly() # optional - sage.modular sage.rings.finite_rings x^4 + 10*x^3 + 3*x^2 + 2*x + 1 - sage: A.eigenspaces_left(format='galois', var='beta') # optional - sage.libs.pari - [ - (9, Vector space of degree 4 and dimension 1 over Finite Field of size 11 + sage: A.eigenspaces_left(format='galois', var='beta') # optional - sage.modular sage.rings.finite_rings + [ (9, + Vector space of degree 4 and dimension 1 over Finite Field of size 11 User basis matrix: [0 1 5 6]), (3, Vector space of degree 4 and dimension 1 over Finite Field of size 11 User basis matrix: [1 0 1 6]), @@ -6316,9 +6329,10 @@ cdef class Matrix(Matrix1): We make sure that :trac:`13308` is fixed. :: - sage: M = ModularSymbols(Gamma1(23), sign=1) - sage: m = M.cuspidal_subspace().hecke_matrix(2) - sage: [j*m==i[0]*j for i in m.eigenspaces_left(format='all') for j in i[1].basis()] # long time (4s) + sage: M = ModularSymbols(Gamma1(23), sign=1) # optional - sage.modular + sage: m = M.cuspidal_subspace().hecke_matrix(2) # optional - sage.modular + sage: [j*m == i[0]*j # long time (4s) # optional - sage.modular + ....: for i in m.eigenspaces_left(format='all') for j in i[1].basis()] [True, True, True, True, True, True, True, True, True, True, True, True] sage: B = matrix(QQ, 2, 3, range(6)) @@ -6849,7 +6863,6 @@ cdef class Matrix(Matrix1): warn("Using generic algorithm for an inexact ring, which may result in garbage from numerical precision issues.") V = [] - from sage.rings.qqbar import QQbar from sage.categories.homset import hom eigenspaces = self.eigenspaces_left(format='galois', algebraic_multiplicity=True) evec_list=[] @@ -6865,6 +6878,7 @@ cdef class Matrix(Matrix1): evec_eval_list.append((eigval, eigbasis, eigmult)) else: try: + from sage.rings.qqbar import QQbar eigval_conj = eigval.galois_conjugates(QQbar) except AttributeError: raise NotImplementedError("eigenvectors are not implemented for matrices with eigenvalues that are not in the fraction field of the base ring or in QQbar") diff --git a/src/sage/tensor/modules/tensor_with_indices.py b/src/sage/tensor/modules/tensor_with_indices.py index 13b7ec2fc61..03b160bf37f 100644 --- a/src/sage/tensor/modules/tensor_with_indices.py +++ b/src/sage/tensor/modules/tensor_with_indices.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.groups r""" Index notation for tensors From e10a2d9aaa5e28a575cede10fae5d2dcdf301fc1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 9 Jun 2023 00:55:41 -0700 Subject: [PATCH 42/99] More # optional --- src/sage/matrix/matrix0.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 814d7d2b023..d429a04892f 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -1926,10 +1926,10 @@ cdef class Matrix(sage.structure.element.Matrix): Prior to :trac:`11544` this could take a full minute to run (2011). :: sage: A = matrix(QQ, 4, 4, [1, 2, -2, 2, 1, 0, -1, -1, 0, -1, 1, 1, -1, 2, 1/2, 0]) - sage: e = A.eigenvalues()[3] - sage: K = (A-e).kernel() - sage: P = K.basis_matrix() - sage: P.str() + sage: e = A.eigenvalues()[3] # optional - sage.rings.number_field + sage: K = (A - e).kernel() # optional - sage.rings.number_field + sage: P = K.basis_matrix() # optional - sage.rings.number_field + sage: P.str() # optional - sage.rings.number_field '[ 1.000000000000000? + 0.?e-17*I -2.116651487479748? + 0.0255565807096352?*I -0.2585224251020429? + 0.2886023409047535?*I -0.4847545623533090? - 1.871890760086142?*I]' Use single-row delimiters where appropriate:: From 11f8d18bfc117187c9442e084563222e9bd9687d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 23:39:34 -0700 Subject: [PATCH 43/99] sage.probability, sage.stats: Docstring cosmetics --- .../probability/probability_distribution.pyx | 38 +- src/sage/stats/basic_stats.py | 106 +++--- src/sage/stats/hmm/chmm.pyx | 309 +++++++++------- src/sage/stats/hmm/distributions.pyx | 86 ++--- src/sage/stats/hmm/hmm.pyx | 334 ++++++++++-------- src/sage/stats/hmm/util.pyx | 39 +- src/sage/stats/intlist.pyx | 42 ++- src/sage/stats/r.py | 8 +- src/sage/stats/time_series.pyx | 76 ++-- 9 files changed, 573 insertions(+), 465 deletions(-) diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index 21665139231..07b93a2812c 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -3,12 +3,12 @@ Probability Distributions This module provides three types of probability distributions: -- ``RealDistribution``: various real-valued probability distributions. +- :class:`RealDistribution`: various real-valued probability distributions. -- ``SphericalDistribution``: uniformly distributed points on the +- :class:`SphericalDistribution`: uniformly distributed points on the surface of an `n-1` sphere in `n` dimensional euclidean space. -- ``GeneralDiscreteDistribution``: user-defined discrete distributions. +- :class:`GeneralDiscreteDistribution`: user-defined discrete distributions. AUTHORS: @@ -151,12 +151,12 @@ cdef class ProbabilityDistribution: INPUT: - - ``name`` - file to save the histogram plot (as a PNG). + - ``name`` -- file to save the histogram plot (as a PNG). - - ``num_samples`` - (optional) number of times to sample from + - ``num_samples`` -- (optional) number of times to sample from the probability distribution - - ``bins`` - (optional) number of bins to divide the samples + - ``bins`` -- (optional) number of bins to divide the samples into. EXAMPLES: @@ -167,7 +167,7 @@ cdef class ProbabilityDistribution: sage: import tempfile sage: P = [0.3, 0.4, 0.3] sage: X = GeneralDiscreteDistribution(P) - sage: with tempfile.NamedTemporaryFile() as f: + sage: with tempfile.NamedTemporaryFile() as f: # optional - sage.plot ....: X.generate_histogram_plot(f.name) """ import pylab @@ -179,11 +179,11 @@ cdef class ProbabilityDistribution: cdef class SphericalDistribution(ProbabilityDistribution): """ This class is capable of producing random points uniformly distributed - on the surface of an ``n-1`` sphere in ``n`` dimensional euclidean space. The - dimension, ``n`` is selected via the keyword ``dimension``. The random + on the surface of an `(n-1)`-sphere in `n`-dimensional euclidean space. The + dimension `n` is selected via the keyword ``dimension``. The random number generator which drives it can be selected using the keyword - ``rng``. Valid choices are ``default`` which uses the Mersenne-Twister, - ``luxury`` which uses RANDLXS, and ``taus`` which uses the tausworth + ``rng``. Valid choices are ``'default'`` which uses the Mersenne-Twister, + ``'luxury'`` which uses RANDLXS, and ``'taus'`` which uses the tausworth generator. The default dimension is ``3``. EXAMPLES:: @@ -319,10 +319,16 @@ cdef class SphericalDistribution(ProbabilityDistribution): sage: T = SphericalDistribution(seed = 0) sage: [T.get_random_element() for _ in range(4)] # rel tol 4e-16 - [(0.07961564104639995, -0.05237671627581255, 0.9954486572862178), (0.4123599490593727, 0.5606817859360097, -0.7180495855658982), (-0.9619860891623148, -0.2726473494040498, -0.015690351211529927), (0.5674297579435619, -0.011206783800420301, -0.8233455397322326)] + [(0.07961564104639995, -0.05237671627581255, 0.9954486572862178), + (0.4123599490593727, 0.5606817859360097, -0.7180495855658982), + (-0.9619860891623148, -0.2726473494040498, -0.015690351211529927), + (0.5674297579435619, -0.011206783800420301, -0.8233455397322326)] sage: T.reset_distribution() sage: [T.get_random_element() for _ in range(4)] # rel tol 4e-16 - [(0.07961564104639995, -0.05237671627581255, 0.9954486572862178), (0.4123599490593727, 0.5606817859360097, -0.7180495855658982), (-0.9619860891623148, -0.2726473494040498, -0.015690351211529927), (0.5674297579435619, -0.011206783800420301, -0.8233455397322326)] + [(0.07961564104639995, -0.05237671627581255, 0.9954486572862178), + (0.4123599490593727, 0.5606817859360097, -0.7180495855658982), + (-0.9619860891623148, -0.2726473494040498, -0.015690351211529927), + (0.5674297579435619, -0.011206783800420301, -0.8233455397322326)] """ if self.r != NULL: gsl_rng_free(self.r) @@ -332,7 +338,7 @@ cdef class SphericalDistribution(ProbabilityDistribution): cdef class RealDistribution(ProbabilityDistribution): """ - The ``RealDistribution`` class provides a number of routines for sampling + The :class:`RealDistribution` class provides a number of routines for sampling from and analyzing and visualizing probability distributions. For precise definitions of the distributions and their parameters see the gsl reference manuals chapter on random number generators @@ -597,8 +603,8 @@ cdef class RealDistribution(ProbabilityDistribution): def set_random_number_generator(self, rng = 'default'): """ - Set the gsl random number generator to be one of ``default``, - ``luxury``, or ``taus``. + Set the gsl random number generator to be one of ``'default'``, + ``'luxury'``, or ``'taus'``. EXAMPLES:: diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index eb77fe4acc6..f4ae105c421 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -6,22 +6,22 @@ When calling a function on data, there are checks for functions already defined for that data type. -The ``mean`` function returns the arithmetic mean (the sum of all the members +The :func:`mean` function returns the arithmetic mean (the sum of all the members of a list, divided by the number of members). Further revisions may include -the geometric and harmonic mean. The ``median`` function returns the number -separating the higher half of a sample from the lower half. The ``mode`` +the geometric and harmonic mean. The :func:`median` function returns the number +separating the higher half of a sample from the lower half. The :func:`mode` returns the most common occurring member of a sample, plus the number of times it occurs. If entries occur equally common, the smallest of a list of the most -common entries is returned. The ``moving_average`` is a finite impulse +common entries is returned. The :func:`moving_average` is a finite impulse response filter, creating a series of averages using a user-defined number of -subsets of the full data set. The ``std`` and the ``variance`` return a +subsets of the full data set. The :func:`std` and the :func:`variance` return a measurement of how far data points tend to be from the arithmetic mean. -Functions are available in the namespace ``stats``, i.e. you can use them by +Functions are available in the namespace :mod:`stats`, i.e. you can use them by typing ``stats.mean``, ``stats.median``, etc. REMARK: If all the data you are working with are floating point -numbers, you may find ``stats.TimeSeries`` helpful, since it is +numbers, you may find :class:`stats.TimeSeries` helpful, since it is extremely fast and offers many of the same descriptive statistics as in the module. @@ -52,12 +52,12 @@ def mean(v): We define the mean of the empty list to be the (symbolic) NaN, following the convention of MATLAB, Scipy, and R. - This function is deprecated. Use ``numpy.mean`` or ``numpy.nanmean`` + This function is deprecated. Use :func:`numpy.mean` or :func:`numpy.nanmean` instead. INPUT: - - `v` -- a list of numbers + - ``v`` -- a list of numbers OUTPUT: @@ -65,14 +65,15 @@ def mean(v): EXAMPLES:: - sage: mean([pi, e]) + sage: mean([pi, e]) # optional - sage.symbolic doctest:warning... - DeprecationWarning: sage.stats.basic_stats.mean is deprecated; use numpy.mean or numpy.nanmean instead + DeprecationWarning: sage.stats.basic_stats.mean is deprecated; + use numpy.mean or numpy.nanmean instead See https://github.com/sagemath/sage/issues/29662 for details. 1/2*pi + 1/2*e sage: mean([]) NaN - sage: mean([I, sqrt(2), 3/5]) + sage: mean([I, sqrt(2), 3/5]) # optional - sage.symbolic 1/3*sqrt(2) + 1/3*I + 1/5 sage: mean([RIF(1.0103,1.0103), RIF(2)]) 1.5051500000000000? @@ -103,8 +104,8 @@ def mode(v): in `v`, then the mode is the list of elements of `v` that occur `n` times. The list is sorted if possible. - This function is deprecated. Use ``scipy.stats.mode`` or - ``statistics.mode`` instead. + This function is deprecated. Use :func:`scipy.stats.mode` or + :func:`statistics.mode` instead. .. NOTE:: @@ -112,7 +113,7 @@ def mode(v): INPUT: - - `v` -- a list + - ``v`` -- a list OUTPUT: @@ -123,7 +124,8 @@ def mode(v): sage: v = [1,2,4,1,6,2,6,7,1] sage: mode(v) doctest:warning... - DeprecationWarning: sage.stats.basic_stats.mode is deprecated; use scipy.stats.mode or statistics.mode instead + DeprecationWarning: sage.stats.basic_stats.mode is deprecated; + use scipy.stats.mode or statistics.mode instead See https://github.com/sagemath/sage/issues/29662 for details. [1] sage: v.count(1) @@ -176,17 +178,16 @@ def std(v, bias=False): We define the standard deviation of the empty list to be NaN, following the convention of MATLAB, Scipy, and R. - This function is deprecated. Use ``numpy.std`` or ``numpy.nanstd`` + This function is deprecated. Use :func:`numpy.std` or :func:`numpy.nanstd` instead. INPUT: - - `v` -- a list of numbers + - ``v`` -- a list of numbers - - ``bias`` -- bool (default: False); if False, divide by - len(v) - 1 instead of len(v) - to give a less biased estimator (sample) for the - standard deviation. + - ``bias`` -- bool (default: ``False``); if ``False``, divide by + ``len(v) - 1`` instead of ``len(v)` to give a less biased + estimator (sample) for the standard deviation. OUTPUT: @@ -196,22 +197,25 @@ def std(v, bias=False): sage: std([1..6], bias=True) doctest:warning... - DeprecationWarning: sage.stats.basic_stats.std is deprecated; use numpy.std or numpy.nanstd instead + DeprecationWarning: sage.stats.basic_stats.std is deprecated; + use numpy.std or numpy.nanstd instead See https://github.com/sagemath/sage/issues/29662 for details. doctest:warning... - DeprecationWarning: sage.stats.basic_stats.variance is deprecated; use numpy.var or numpy.nanvar instead + DeprecationWarning: sage.stats.basic_stats.variance is deprecated; + use numpy.var or numpy.nanvar instead See https://github.com/sagemath/sage/issues/29662 for details. doctest:warning... - DeprecationWarning: sage.stats.basic_stats.mean is deprecated; use numpy.mean or numpy.nanmean instead + DeprecationWarning: sage.stats.basic_stats.mean is deprecated; + use numpy.mean or numpy.nanmean instead See https://github.com/sagemath/sage/issues/29662 for details. 1/2*sqrt(35/3) sage: std([1..6], bias=False) sqrt(7/2) - sage: std([e, pi]) + sage: std([e, pi]) # optional - sage.symbolic sqrt(1/2)*abs(pi - e) sage: std([]) NaN - sage: std([I, sqrt(2), 3/5]) + sage: std([I, sqrt(2), 3/5]) # optional - sage.symbolic 1/15*sqrt(1/2)*sqrt((10*sqrt(2) - 5*I - 3)^2 + (5*sqrt(2) - 10*I + 3)^2 + (5*sqrt(2) + 5*I - 6)^2) sage: std([RIF(1.0103, 1.0103), RIF(2)]) @@ -261,17 +265,16 @@ def variance(v, bias=False): We define the variance of the empty list to be NaN, following the convention of MATLAB, Scipy, and R. - This function is deprecated. Use ``numpy.var`` or ``numpy.nanvar`` + This function is deprecated. Use :func:`numpy.var` or :func:`numpy.nanvar` instead. INPUT: - - `v` -- a list of numbers + - ``v`` -- a list of numbers - - ``bias`` -- bool (default: False); if False, divide by - len(v) - 1 instead of len(v) - to give a less biased estimator (sample) for the - standard deviation. + - ``bias`` -- bool (default: ``False``); if ``False``, divide by + ``len(v) - 1`` instead of ``len(v)`` to give a less biased + estimator (sample) for the standard deviation. OUTPUT: @@ -281,16 +284,17 @@ def variance(v, bias=False): sage: variance([1..6]) doctest:warning... - DeprecationWarning: sage.stats.basic_stats.variance is deprecated; use numpy.var or numpy.nanvar instead + DeprecationWarning: sage.stats.basic_stats.variance is deprecated; + use numpy.var or numpy.nanvar instead See https://github.com/sagemath/sage/issues/29662 for details. 7/2 sage: variance([1..6], bias=True) 35/12 - sage: variance([e, pi]) + sage: variance([e, pi]) # optional - sage.symbolic 1/2*(pi - e)^2 sage: variance([]) NaN - sage: variance([I, sqrt(2), 3/5]) + sage: variance([I, sqrt(2), 3/5]) # optional - sage.symbolic 1/450*(10*sqrt(2) - 5*I - 3)^2 + 1/450*(5*sqrt(2) - 10*I + 3)^2 + 1/450*(5*sqrt(2) + 5*I - 6)^2 sage: variance([RIF(1.0103, 1.0103), RIF(2)]) @@ -305,7 +309,7 @@ def variance(v, bias=False): sage: variance(x, bias=True) 833.25 sage: class MyClass: - ....: def variance(self, bias = False): + ....: def variance(self, bias=False): ....: return 1 sage: stats.variance(MyClass()) 1 @@ -369,15 +373,15 @@ def median(v): If `v` is empty, we define the median to be NaN, which is consistent with NumPy (note that R returns NULL). - If `v` is comprised of strings, TypeError occurs. - For elements other than numbers, the median is a result of ``sorted()``. + If `v` is comprised of strings, :class:`TypeError` occurs. + For elements other than numbers, the median is a result of :func:`sorted`. - This function is deprecated. Use ``numpy.median`` or ``numpy.nanmedian`` + This function is deprecated. Use :func:`numpy.median` or :func:`numpy.nanmedian` instead. INPUT: - - `v` -- a list + - ``v`` -- a list OUTPUT: @@ -387,10 +391,11 @@ def median(v): sage: median([1,2,3,4,5]) doctest:warning... - DeprecationWarning: sage.stats.basic_stats.median is deprecated; use numpy.median or numpy.nanmedian instead + DeprecationWarning: sage.stats.basic_stats.median is deprecated; + use numpy.median or numpy.nanmedian instead See https://github.com/sagemath/sage/issues/29662 for details. 3 - sage: median([e, pi]) + sage: median([e, pi]) # optional - sage.symbolic 1/2*pi + 1/2*e sage: median(['sage', 'linux', 'python']) 'python' @@ -427,13 +432,13 @@ def moving_average(v, n): If `v` is empty, we define the entries of the moving average to be NaN. - This method is deprecated. Use ``pandas.Series.rolling`` instead. + This method is deprecated. Use :meth:`pandas.Series.rolling` instead. INPUT: - - `v` -- a list + - ``v`` -- a list - - `n` -- the number of values used in computing each average. + - ``n`` -- the number of values used in computing each average. OUTPUT: @@ -443,21 +448,22 @@ def moving_average(v, n): sage: moving_average([1..10], 1) doctest:warning... - DeprecationWarning: sage.stats.basic_stats.moving_average is deprecated; use pandas.Series.rolling instead + DeprecationWarning: sage.stats.basic_stats.moving_average is deprecated; + use pandas.Series.rolling instead See https://github.com/sagemath/sage/issues/29662 for details. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] sage: moving_average([1..10], 4) [5/2, 7/2, 9/2, 11/2, 13/2, 15/2, 17/2] sage: moving_average([], 1) [] - sage: moving_average([pi, e, I, sqrt(2), 3/5], 2) + sage: moving_average([pi, e, I, sqrt(2), 3/5], 2) # optional - sage.symbolic [1/2*pi + 1/2*e, 1/2*e + 1/2*I, 1/2*sqrt(2) + 1/2*I, 1/2*sqrt(2) + 3/10] We check if the input is a time series, and if so use the - optimized ``simple_moving_average`` method, but with (slightly + optimized :meth:`simple_moving_average` method, but with (slightly different) meaning as defined above (the point is that the - ``simple_moving_average`` on time series returns `n` values:: + :meth:`simple_moving_average` on time series returns `n` values:: sage: a = stats.TimeSeries([1..10]) sage: stats.moving_average(a, 3) diff --git a/src/sage/stats/hmm/chmm.pyx b/src/sage/stats/hmm/chmm.pyx index eb2d4ed6856..8a065a6378e 100644 --- a/src/sage/stats/hmm/chmm.pyx +++ b/src/sage/stats/hmm/chmm.pyx @@ -43,13 +43,13 @@ cdef double random_normal(double mean, double std, randstate rstate): INPUT: - - ``mean`` -- double - - ``std`` -- double, standard deviation - - ``rstate`` -- a randstate object + - ``mean`` -- double + - ``std`` -- double, standard deviation + - ``rstate`` -- a randstate object OUTPUT: - - a double + - a double """ # Ported from http://users.tkk.fi/~nbeijar/soft/terrain/source_o2/boxmuller.c # This the box muller algorithm. @@ -68,22 +68,22 @@ cdef double random_normal(double mean, double std, randstate rstate): cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): """ - GaussianHiddenMarkovModel(A, B, pi) - Gaussian emissions Hidden Markov Model. INPUT: - - ``A`` -- matrix; the N x N transition matrix - - ``B`` -- list of pairs (mu,sigma) that define the distributions - - ``pi`` -- initial state probabilities - - ``normalize`` --bool (default: True) + - ``A`` -- matrix; the `N \times N` transition matrix + - ``B`` -- list of pairs ``(mu, sigma)`` that define the distributions + - ``pi`` -- initial state probabilities + - ``normalize`` -- bool (default: ``True``) EXAMPLES: We illustrate the primary functions with an example 2-state Gaussian HMM:: - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,1), (-1,1)], [.5,.5]); m + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,1), (-1,1)], + ....: [.5,.5]); m Gaussian Hidden Markov Model with 2 States Transition matrix: [0.1 0.9] @@ -148,7 +148,8 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): [ 0.4154981366185841 0.584501863381416] [ 0.9999993174253741 6.825746258991804e-07] Emission parameters: - [(0.4178882427119503, 0.5173109664360919), (-1.5025208631331122, 0.5085512836055119)] + [(0.4178882427119503, 0.5173109664360919), + (-1.5025208631331122, 0.5085512836055119)] Initial probabilities: [0.0000, 1.0000] """ cdef TimeSeries B, prob @@ -162,22 +163,22 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - A -- a list of lists or a square N x N matrix, whose - (i,j) entry gives the probability of transitioning from - state i to state j. + - A -- a list of lists or a square N x N matrix, whose + (i,j) entry gives the probability of transitioning from + state i to state j. - - B -- a list of N pairs (mu,std), where if B[i]=(mu,std), - then the probability distribution associated with state i - normal with mean mu and standard deviation std. + - B -- a list of N pairs (mu,std), where if B[i]=(mu,std), + then the probability distribution associated with state i + normal with mean mu and standard deviation std. - - pi -- the probabilities of starting in each initial - state, i.e,. pi[i] is the probability of starting in - state i. + - pi -- the probabilities of starting in each initial + state, i.e,. pi[i] is the probability of starting in + state i. - - normalize --bool (default: True); if given, input is - normalized to define valid probability distributions, - e.g., the entries of A are made nonnegative and the rows - sum to 1. + - normalize --bool (default: True); if given, input is + normalized to define valid probability distributions, + e.g., the entries of A are made nonnegative and the rows + sum to 1. EXAMPLES:: @@ -305,13 +306,16 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): OUTPUT: - - a list B of pairs B[i] = (mu, std), such that the - distribution associated to state i is normal with mean - mu and standard deviation std. + - a list ``B`` of pairs ``B[i] = (mu, std)``, such that the + distribution associated to state `i` is normal with mean + ``mu`` and standard deviation ``std``. EXAMPLES:: - sage: hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,.5), (-1,3)], [.1,.9]).emission_parameters() + sage: M = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,.5), (-1,3)], + ....: [.1,.9]) + sage: M.emission_parameters() [(1.0, 0.5), (-1.0, 3.0)] """ cdef Py_ssize_t i @@ -340,20 +344,22 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - length -- positive integer - - starting_state -- int (or None); if specified then generate - a sequence using this model starting with the given state - instead of the initial probabilities to determine the - starting state. + - ``length`` -- positive integer + - ``starting_state`` -- int (or ``None``); if specified then generate + a sequence using this model starting with the given state + instead of the initial probabilities to determine the + starting state. OUTPUT: - - an IntList or list of emission symbols - - TimeSeries of emissions + - an :class:`IntList` or list of emission symbols + - :class:`TimeSeries` of emissions EXAMPLES:: - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,.5), (-1,3)], [.1,.9]) + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,.5), (-1,3)], + ....: [.1,.9]) sage: m.generate_sequence(5) # random ([-3.0505, 0.5317, -4.5065, 0.6521, 1.0435], [1, 0, 1, 0, 1]) sage: m.generate_sequence(0) @@ -528,15 +534,17 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- sequence of observations + - ``obs`` -- sequence of observations OUTPUT: - - float + - float EXAMPLES:: - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,.5), (-1,3)], [.1,.9]) + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,.5), (-1,3)], + ....: [.1,.9]) sage: m.log_likelihood([1,1,1]) -4.297880766072486 sage: s = m.sample(20) @@ -555,12 +563,12 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- an integer list of observation states. + - obs -- an integer list of observation states. OUTPUT: - - float -- the log of the probability that the model - produced this sequence + - float -- the log of the probability that the model + produced this sequence EXAMPLES:: @@ -614,28 +622,32 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - seq -- sequence of emitted ints or symbols + - seq -- sequence of emitted ints or symbols OUTPUT: - - list -- "the" most probable sequence of hidden states, i.e., - the Viterbi path. + - list -- "the" most probable sequence of hidden states, i.e., + the Viterbi path. - - float -- log of probability that the observed sequence - was produced by the Viterbi sequence of states. + - float -- log of probability that the observed sequence + was produced by the Viterbi sequence of states. EXAMPLES: We find the optimal state sequence for a given model:: - sage: m = hmm.GaussianHiddenMarkovModel([[0.5,0.5],[0.5,0.5]], [(0,1),(10,1)], [0.5,0.5]) + sage: m = hmm.GaussianHiddenMarkovModel([[0.5,0.5],[0.5,0.5]], + ....: [(0,1),(10,1)], + ....: [0.5,0.5]) sage: m.viterbi([0,1,10,10,1]) ([0, 0, 1, 1, 0], -9.0604285688230...) Another example in which the most likely states change based on the last observation:: - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,.5), (-1,3)], [.1,.9]) + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,.5), (-1,3)], + ....: [.1,.9]) sage: m.viterbi([-2,-1,.1,0.1]) ([1, 1, 0, 1], -9.61823698847639...) sage: m.viterbi([-2,-1,.1,0.3]) @@ -716,13 +728,13 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- TimeSeries - - scale -- TimeSeries + - obs -- TimeSeries + - scale -- TimeSeries OUTPUT: - - TimeSeries beta such that beta_t(i) = beta[t*N + i] - - scale is also changed by this function + - TimeSeries beta such that beta_t(i) = beta[t*N + i] + - scale is also changed by this function """ cdef Py_ssize_t t, T = obs._length cdef int N = self.N, i, j @@ -756,14 +768,14 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- TimeSeries + - obs -- TimeSeries OUTPUT: - - TimeSeries alpha with alpha_t(i) = alpha[t*N + i] - - TimeSeries scale with scale[t] the scaling at step t - - float -- log_probability of the observation sequence - being produced by the model. + - TimeSeries alpha with alpha_t(i) = alpha[t*N + i] + - TimeSeries scale with scale[t] the scaling at step t + - float -- log_probability of the observation sequence + being produced by the model. """ cdef Py_ssize_t i, j, t, T = len(obs) cdef int N = self.N @@ -817,13 +829,13 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - alpha -- TimeSeries as output by the scaled forward algorithm - - beta -- TimeSeries as output by the scaled backward algorithm - - obs -- TimeSeries of observations + - alpha -- TimeSeries as output by the scaled forward algorithm + - beta -- TimeSeries as output by the scaled backward algorithm + - obs -- TimeSeries of observations OUTPUT: - - TimeSeries xi such that xi[t*N*N + i*N + j] = xi_t(i,j). + - TimeSeries xi such that xi[t*N*N + i*N + j] = xi_t(i,j). """ cdef int i, j, N = self.N cdef double sum @@ -849,31 +861,33 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- a time series of emissions + - ``obs`` -- a time series of emissions - - max_iter -- integer (default: 500) maximum number - of Baum-Welch steps to take + - ``max_iter`` -- integer (default: 500) maximum number + of Baum-Welch steps to take - - log_likelihood_cutoff -- positive float (default: 1e-4); - the minimal improvement in likelihood with respect to - the last iteration required to continue. Relative value - to log likelihood. + - ``log_likelihood_cutoff`` -- positive float (default: 1e-4); + the minimal improvement in likelihood with respect to + the last iteration required to continue. Relative value + to log likelihood. - - min_sd -- positive float (default: 0.01); when - reestimating, the standard deviation of emissions is not - allowed to be less than min_sd. + - ``min_sd`` -- positive float (default: 0.01); when + reestimating, the standard deviation of emissions is not + allowed to be less than ``min_sd``. - - fix_emissions -- bool (default: False); if True, do not - change emissions when updating + - ``fix_emissions`` -- bool (default: ``False``); if ``True``, do not + change emissions when updating OUTPUT: - - changes the model in places, and returns the log - likelihood and number of iterations. + - changes the model in places, and returns the log + likelihood and number of iterations. EXAMPLES:: - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,.5), (-1,3)], [.1,.9]) + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,.5), (-1,3)], + ....: [.1,.9]) sage: m.log_likelihood([-2,-1,.1,0.1]) -8.858282215986275 sage: m.baum_welch([-2,-1,.1,0.1]) @@ -890,9 +904,11 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): Initial probabilities: [0.0000, 1.0000] We illustrate bounding the standard deviation below. Note that above we had - different emission parameters when the min_sd was the default of 0.01:: + different emission parameters when the ``min_sd`` was the default of 0.01:: - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,.5), (-1,3)], [.1,.9]) + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,.5), (-1,3)], + ....: [.1,.9]) sage: m.baum_welch([-2,-1,.1,0.1], min_sd=1) (-4.07939572755..., 32) sage: m.emission_parameters() @@ -900,27 +916,36 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): We watch the log likelihoods of the model converge, step by step:: - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,.5), (-1,3)], [.1,.9]) + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,.5), (-1,3)], + ....: [.1,.9]) sage: v = m.sample(10) - sage: l = stats.TimeSeries([m.baum_welch(v,max_iter=1)[0] for _ in range(len(v))]) + sage: l = stats.TimeSeries([m.baum_welch(v, max_iter=1)[0] + ....: for _ in range(len(v))]) sage: all(l[i] <= l[i+1] + 0.0001 for i in range(9)) True sage: l # random - [-20.1167, -17.7611, -16.9814, -16.9364, -16.9314, -16.9309, -16.9309, -16.9309, -16.9309, -16.9309] + [-20.1167, -17.7611, -16.9814, -16.9364, -16.9314, + -16.9309, -16.9309, -16.9309, -16.9309, -16.9309] We illustrate fixing emissions:: - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.9,.1]], [(1,2),(-1,.5)], [.3,.7]) + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.9,.1]], + ....: [(1,2),(-1,.5)], + ....: [.3,.7]) sage: set_random_seed(0); v = m.sample(100) sage: m.baum_welch(v,fix_emissions=True) (-164.72944548204..., 23) sage: m.emission_parameters() [(1.0, 2.0), (-1.0, 0.5)] - sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.9,.1]], [(1,2),(-1,.5)], [.3,.7]) + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.9,.1]], + ....: [(1,2),(-1,.5)], + ....: [.3,.7]) sage: m.baum_welch(v) (-162.854370397998..., 49) sage: m.emission_parameters() # rel tol 3e-14 - [(1.2722419172602375, 2.371368751761901), (-0.9486174675179113, 0.5762360385123765)] + [(1.2722419172602375, 2.371368751761901), + (-0.9486174675179113, 0.5762360385123765)] """ if not isinstance(obs, TimeSeries): obs = TimeSeries(obs) @@ -1022,29 +1047,27 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): """ - GaussianMixtureHiddenMarkovModel(A, B, pi) - Gaussian mixture Hidden Markov Model. INPUT: - - ``A`` -- matrix; the N x N transition matrix + - ``A`` -- matrix; the `N \times N` transition matrix - - ``B`` -- list of mixture definitions for each state. Each - state may have a varying number of gaussians with selection - probabilities that sum to 1 and encoded as (p,(mu,sigma)) + - ``B`` -- list of mixture definitions for each state. Each + state may have a varying number of gaussians with selection + probabilities that sum to 1 and encoded as ``(p, (mu,sigma))`` - - ``pi`` -- initial state probabilities + - ``pi`` -- initial state probabilities - - ``normalize`` --bool (default: True); if given, input is - normalized to define valid probability distributions, - e.g., the entries of A are made nonnegative and the rows - sum to 1, and the probabilities in pi are normalized. + - ``normalize`` -- bool (default: ``True``); if given, input is + normalized to define valid probability distributions, + e.g., the entries of `A` are made nonnegative and the rows + sum to 1, and the probabilities in ``pi`` are normalized. EXAMPLES:: - sage: A = [[0.5,0.5],[0.5,0.5]] - sage: B = [[(0.9,(0.0,1.0)), (0.1,(1,10000))],[(1,(1,1)), (0,(0,0.1))]] + sage: A = [[0.5,0.5],[0.5,0.5]] + sage: B = [[(0.9,(0.0,1.0)), (0.1,(1,10000))],[(1,(1,1)), (0,(0,0.1))]] sage: hmm.GaussianMixtureHiddenMarkovModel(A, B, [1,0]) Gaussian Mixture Hidden Markov Model with 2 States Transition matrix: @@ -1215,11 +1238,13 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): OUTPUT: - - list of Gaussian mixtures + - list of Gaussian mixtures EXAMPLES:: - sage: m = hmm.GaussianMixtureHiddenMarkovModel([[.9,.1],[.4,.6]], [[(.4,(0,1)), (.6,(1,0.1))],[(1,(0,1))]], [.7,.3]) + sage: m = hmm.GaussianMixtureHiddenMarkovModel([[.9,.1],[.4,.6]], + ....: [[(.4,(0,1)), (.6,(1,0.1))], [(1,(0,1))]], + ....: [.7,.3]) sage: m.emission_parameters() [0.4*N(0.0,1.0) + 0.6*N(1.0,0.1), 1.0*N(0.0,1.0)] """ @@ -1236,12 +1261,12 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): INPUT: - - state -- integer - - rstate -- randstate instance + - state -- integer + - rstate -- randstate instance OUTPUT: - - double + - double """ cdef GaussianMixtureDistribution G = self.mixture[state] return G._sample(rstate) @@ -1257,12 +1282,12 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): INPUT: - - state -- integer - - observation -- double + - state -- integer + - observation -- double OUTPUT: - - double + - double """ cdef GaussianMixtureDistribution G = self.mixture[state] return G.prob(observation) @@ -1278,14 +1303,14 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): INPUT: - - alpha -- TimeSeries - - beta -- TimeSeries - - obs -- TimeSeries - - j -- int + - alpha -- TimeSeries + - beta -- TimeSeries + - obs -- TimeSeries + - j -- int OUTPUT: - - TimeSeries + - TimeSeries """ cdef int i, k, m, N = self.N cdef Py_ssize_t t, T = alpha._length//N @@ -1323,34 +1348,38 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): def baum_welch(self, obs, int max_iter=1000, double log_likelihood_cutoff=1e-12, double min_sd=0.01, bint fix_emissions=False): """ - Given an observation sequence obs, improve this HMM using the - Baum-Welch algorithm to increase the probability of observing obs. + Given an observation sequence ``obs``, improve this HMM using the + Baum-Welch algorithm to increase the probability of observing ``obs``. INPUT: - - obs -- a time series of emissions - - max_iter -- integer (default: 1000) maximum number - of Baum-Welch steps to take - - log_likelihood_cutoff -- positive float (default: 1e-12); - the minimal improvement in likelihood with respect to - the last iteration required to continue. Relative value - to log likelihood. - - min_sd -- positive float (default: 0.01); when - reestimating, the standard deviation of emissions is not - allowed to be less than min_sd. - - fix_emissions -- bool (default: False); if True, do not - change emissions when updating + - ``obs`` -- a time series of emissions + - ``max_iter`` -- integer (default: 1000) maximum number + of Baum-Welch steps to take + - ``log_likelihood_cutoff`` -- positive float (default: 1e-12); + the minimal improvement in likelihood with respect to + the last iteration required to continue. Relative value + to log likelihood. + - ``min_sd`` -- positive float (default: 0.01); when + reestimating, the standard deviation of emissions is not + allowed to be less than ``min_sd``. + - ``fix_emissions`` -- bool (default: ``False``); if ``True``, do not + change emissions when updating OUTPUT: - - changes the model in places, and returns the log - likelihood and number of iterations. + - changes the model in places, and returns the log + likelihood and number of iterations. EXAMPLES:: - sage: m = hmm.GaussianMixtureHiddenMarkovModel([[.9,.1],[.4,.6]], [[(.4,(0,1)), (.6,(1,0.1))],[(1,(0,1))]], [.7,.3]) + sage: m = hmm.GaussianMixtureHiddenMarkovModel( + ....: [[.9,.1],[.4,.6]], + ....: [[(.4,(0,1)), (.6,(1,0.1))], [(1,(0,1))]], + ....: [.7,.3]) sage: set_random_seed(0); v = m.sample(10); v - [0.3576, -0.9365, 0.9449, -0.6957, 1.0217, 0.9644, 0.9987, -0.5950, -1.0219, 0.6477] + [0.3576, -0.9365, 0.9449, -0.6957, 1.0217, + 0.9644, 0.9987, -0.5950, -1.0219, 0.6477] sage: m.log_likelihood(v) -8.31408655939536... sage: m.baum_welch(v) @@ -1363,26 +1392,36 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): [ 0.8746363339773399 0.12536366602266016] [ 1.0 1.451685202290174e-40] Emission parameters: - [0.500161629343*N(-0.812298726239,0.173329026744) + 0.499838370657*N(0.982433690378,0.029719932009), 1.0*N(0.503260056832,0.145881515324)] + [0.500161629343*N(-0.812298726239,0.173329026744) + + 0.499838370657*N(0.982433690378,0.029719932009), + 1.0*N(0.503260056832,0.145881515324)] Initial probabilities: [0.0000, 1.0000] We illustrate bounding the standard deviation below. Note that above we had different emission parameters when the min_sd was the default of 0.01:: - sage: m = hmm.GaussianMixtureHiddenMarkovModel([[.9,.1],[.4,.6]], [[(.4,(0,1)), (.6,(1,0.1))],[(1,(0,1))]], [.7,.3]) + sage: m = hmm.GaussianMixtureHiddenMarkovModel( + ....: [[.9,.1],[.4,.6]], + ....: [[(.4,(0,1)), (.6,(1,0.1))], [(1,(0,1))]], + ....: [.7,.3]) sage: m.baum_welch(v, min_sd=1) (-12.617885761692..., 1000) sage: m.emission_parameters() # rel tol 6e-12 - [0.503545634447*N(0.200166509595,1.0) + 0.496454365553*N(0.200166509595,1.0), 1.0*N(0.0543433426535,1.0)] + [0.503545634447*N(0.200166509595,1.0) + 0.496454365553*N(0.200166509595,1.0), + 1.0*N(0.0543433426535,1.0)] We illustrate fixing all emissions:: - sage: m = hmm.GaussianMixtureHiddenMarkovModel([[.9,.1],[.4,.6]], [[(.4,(0,1)), (.6,(1,0.1))],[(1,(0,1))]], [.7,.3]) + sage: m = hmm.GaussianMixtureHiddenMarkovModel( + ....: [[.9,.1],[.4,.6]], + ....: [[(.4,(0,1)), (.6,(1,0.1))], [(1,(0,1))]], + ....: [.7,.3]) sage: set_random_seed(0); v = m.sample(10) sage: m.baum_welch(v, fix_emissions=True) (-7.58656858997..., 36) sage: m.emission_parameters() - [0.4*N(0.0,1.0) + 0.6*N(1.0,0.1), 1.0*N(0.0,1.0)] + [0.4*N(0.0,1.0) + 0.6*N(1.0,0.1), + 1.0*N(0.0,1.0)] """ if not isinstance(obs, TimeSeries): obs = TimeSeries(obs) diff --git a/src/sage/stats/hmm/distributions.pyx b/src/sage/stats/hmm/distributions.pyx index 27d12982c73..070f99c35a7 100644 --- a/src/sage/stats/hmm/distributions.pyx +++ b/src/sage/stats/hmm/distributions.pyx @@ -41,13 +41,13 @@ cdef double random_normal(double mean, double std, randstate rstate): INPUT: - - mean -- float; the mean - - std -- float; the standard deviation - - rstate -- randstate; the random number generator state + - ``mean`` -- float; the mean + - ``std`` -- float; the standard deviation + - ``rstate`` -- randstate; the random number generator state OUTPUT: - - double + - double """ # Ported from http://users.tkk.fi/~nbeijar/soft/terrain/source_o2/boxmuller.c # This the box muller algorithm. @@ -71,16 +71,16 @@ cdef class Distribution: """ def sample(self, n=None): """ - Return either a single sample (the default) or n samples from + Return either a single sample (the default) or `n` samples from this probability distribution. INPUT: - - n -- None or a positive integer + - ``n`` -- ``None`` or a positive integer OUTPUT: - - a single sample if n is 1; otherwise many samples + - a single sample if `n` is 1; otherwise many samples EXAMPLES: @@ -96,15 +96,15 @@ cdef class Distribution: def prob(self, x): """ - The probability density function evaluated at x. + The probability density function evaluated at `x`. INPUT: - - x -- object + - ``x`` -- object OUTPUT: - - float + - float EXAMPLES: @@ -124,11 +124,11 @@ cdef class Distribution: INPUT: - - args and kwds, passed to the Sage plot function + - ``args`` and ``kwds``, passed to the Sage :func:`plot` function OUTPUT: - - a Graphics object + - a :class:`Graphics` object EXAMPLES:: @@ -165,14 +165,14 @@ cdef class GaussianMixtureDistribution(Distribution): """ INPUT: - - `B` -- a list of triples `(c_i, mean_i, std_i)`, where - the `c_i` and `std_i` are positive and the sum of the - `c_i` is `1`. + - `B` -- a list of triples `(c_i, mean_i, std_i)`, where + the `c_i` and `std_i` are positive and the sum of the + `c_i` is `1`. - - eps -- positive real number; any standard deviation in B - less than eps is replaced by eps. + - eps -- positive real number; any standard deviation in B + less than eps is replaced by eps. - - normalize -- if True, ensure that the c_i are nonnegative + - normalize -- if True, ensure that the c_i are nonnegative EXAMPLES:: @@ -202,15 +202,15 @@ cdef class GaussianMixtureDistribution(Distribution): def __getitem__(self, Py_ssize_t i): """ - Returns triple (coefficient, mu, std). + Return triple (coefficient, mu, std). INPUT: - - i -- integer + - i -- integer OUTPUT: - - triple of floats + - triple of floats EXAMPLES:: @@ -283,13 +283,13 @@ cdef class GaussianMixtureDistribution(Distribution): cpdef is_fixed(self, i=None): """ - Return whether or not this GaussianMixtureDistribution is + Return whether or not this :class:`GaussianMixtureDistribution` is fixed when using Baum-Welch to update the corresponding HMM. INPUT: - - i -- None (default) or integer; if given, only return - whether the i-th component is fixed + - ``i`` -- ``None`` (default) or integer; if given, only return + whether the `i`-th component is fixed EXAMPLES:: @@ -312,14 +312,14 @@ cdef class GaussianMixtureDistribution(Distribution): def fix(self, i=None): """ - Set that this GaussianMixtureDistribution (or its ith + Set that this :class:`GaussianMixtureDistribution` (or its `i`-th component) is fixed when using Baum-Welch to update the corresponding HMM. INPUT: - - i -- None (default) or integer; if given, only fix the - i-th component + - ``i`` -- ``None`` (default) or integer; if given, only fix the + `i`-th component EXAMPLES:: @@ -340,14 +340,14 @@ cdef class GaussianMixtureDistribution(Distribution): def unfix(self, i=None): """ - Set that this GaussianMixtureDistribution (or its ith + Set that this :class:`GaussianMixtureDistribution` (or its `i`-th component) is not fixed when using Baum-Welch to update the corresponding HMM. INPUT: - - i -- None (default) or integer; if given, only fix the - i-th component + - ``i`` -- ``None`` (default) or integer; if given, only fix the + `i`-th component EXAMPLES:: @@ -384,15 +384,15 @@ cdef class GaussianMixtureDistribution(Distribution): def sample(self, n=None): """ Return a single sample from this distribution (by default), or - if n>1, return a TimeSeries of samples. + if `n>1`, return a :class:`TimeSeries` of samples. INPUT: - - n -- integer or None (default: None) + - ``n`` -- integer or ``None`` (default: ``None``) OUTPUT: - - float if n is None (default); otherwise a TimeSeries + - float if ``n`` is ``None`` (default); otherwise a :class:`TimeSeries` EXAMPLES:: @@ -439,11 +439,11 @@ cdef class GaussianMixtureDistribution(Distribution): INPUT: - - rstate -- a randstate object + - rstate -- a randstate object OUTPUT: - - double + - double """ cdef double accum, r cdef int n @@ -460,18 +460,18 @@ cdef class GaussianMixtureDistribution(Distribution): cpdef double prob(self, double x): """ - Return the probability of x. + Return the probability of `x`. Since this is a continuous distribution, this is defined to be the limit of the p's such that the probability of [x,x+h] is p*h. INPUT: - - x -- float + - ``x`` -- float OUTPUT: - - float + - float EXAMPLES:: @@ -496,16 +496,16 @@ cdef class GaussianMixtureDistribution(Distribution): cpdef double prob_m(self, double x, int m): """ - Return the probability of x using just the m-th summand. + Return the probability of `x` using just the `m`-th summand. INPUT: - - x -- float - - m -- integer + - ``x`` -- float + - ``m`` -- integer OUTPUT: - - float + - float EXAMPLES:: @@ -526,7 +526,7 @@ cdef class GaussianMixtureDistribution(Distribution): def unpickle_gaussian_mixture_distribution_v1(TimeSeries c0, TimeSeries c1, TimeSeries param, IntList fixed): """ - Used in unpickling GaussianMixtureDistribution's. + Used in unpickling :class:`GaussianMixtureDistribution` objects. EXAMPLES:: diff --git a/src/sage/stats/hmm/hmm.pyx b/src/sage/stats/hmm/hmm.pyx index 5fb6e0af596..48455002d0a 100644 --- a/src/sage/stats/hmm/hmm.pyx +++ b/src/sage/stats/hmm/hmm.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules """ Hidden Markov Models @@ -7,10 +8,10 @@ Gaussian emissions. The best references for the basic HMM algorithms implemented here are: - - Tapas Kanungo's "Hidden Markov Models" +- Tapas Kanungo's "Hidden Markov Models" - - Jackson's HMM tutorial: - http://personal.ee.surrey.ac.uk/Personal/P.Jackson/tutorial/ +- Jackson's HMM tutorial: + http://personal.ee.surrey.ac.uk/Personal/P.Jackson/tutorial/ LICENSE: Some of the code in this file is based on reading Kanungo's GPLv2+ implementation of discrete HMM's, hence the present code must @@ -36,7 +37,6 @@ from cysignals.signals cimport sig_on, sig_off from sage.stats.time_series cimport TimeSeries from sage.structure.element import is_Matrix -from sage.matrix.constructor import matrix from sage.misc.randstate cimport current_randstate, randstate from cpython.object cimport PyObject_RichCompare @@ -52,19 +52,21 @@ cdef class HiddenMarkovModel: """ def initial_probabilities(self): """ - Return the initial probabilities, which as a TimeSeries of - length N, where N is the number of states of the Markov model. + Return the initial probabilities as a :class:`TimeSeries` of + length `N`, where `N` is the number of states of the Markov model. EXAMPLES:: - sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8]) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], + ....: [[0.1,0.9],[0.5,0.5]], + ....: [.2,.8]) sage: pi = m.initial_probabilities(); pi [0.2000, 0.8000] sage: type(pi) <... 'sage.stats.time_series.TimeSeries'> The returned time series is a copy, so changing it does not - change the model. + change the model:: sage: pi[0] = .1; pi[1] = .9 sage: m.initial_probabilities() @@ -72,9 +74,16 @@ cdef class HiddenMarkovModel: Some other models:: - sage: hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,1), (-1,1)], [.1,.9]).initial_probabilities() + sage: m = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,1), (-1,1)], + ....: [.1,.9]) + sage: m.initial_probabilities() [0.1000, 0.9000] - sage: hmm.GaussianMixtureHiddenMarkovModel([[.9,.1],[.4,.6]], [[(.4,(0,1)), (.6,(1,0.1))],[(1,(0,1))]], [.7,.3]).initial_probabilities() + sage: m = hmm.GaussianMixtureHiddenMarkovModel( + ....: [[.9,.1],[.4,.6]], + ....: [[(.4,(0,1)), (.6,(1,0.1))], [(1,(0,1))]], + ....: [.7,.3]) + sage: m.initial_probabilities() [0.7000, 0.3000] """ return TimeSeries(self.pi) @@ -83,13 +92,13 @@ cdef class HiddenMarkovModel: """ Return the state transition matrix. - OUTPUT: - - - a Sage matrix with real double precision (RDF) entries. + OUTPUT: a Sage matrix with real double precision (RDF) entries. EXAMPLES:: - sage: M = hmm.DiscreteHiddenMarkovModel([[0.7,0.3],[0.9,0.1]], [[0.5,.5],[.1,.9]], [0.3,0.7]) + sage: M = hmm.DiscreteHiddenMarkovModel([[0.7,0.3],[0.9,0.1]], + ....: [[0.5,.5],[.1,.9]], + ....: [0.3,0.7]) sage: T = M.transition_matrix(); T [0.7 0.3] [0.9 0.1] @@ -104,10 +113,17 @@ cdef class HiddenMarkovModel: Transition matrices for other types of models:: - sage: hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,1), (-1,1)], [.5,.5]).transition_matrix() + sage: M = hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], + ....: [(1,1), (-1,1)], + ....: [.5,.5]) + sage: M.transition_matrix() [0.1 0.9] [0.5 0.5] - sage: hmm.GaussianMixtureHiddenMarkovModel([[.9,.1],[.4,.6]], [[(.4,(0,1)), (.6,(1,0.1))],[(1,(0,1))]], [.7,.3]).transition_matrix() + sage: M = hmm.GaussianMixtureHiddenMarkovModel( + ....: [[.9,.1],[.4,.6]], + ....: [[(.4,(0,1)), (.6,(1,0.1))],[(1,(0,1))]], + ....: [.7,.3]) + sage: M.transition_matrix() [0.9 0.1] [0.4 0.6] """ @@ -118,24 +134,24 @@ cdef class HiddenMarkovModel: def graph(self, eps=1e-3): """ Create a weighted directed graph from the transition matrix, - not including any edge with a probability less than eps. + not including any edge with a probability less than ``eps``. INPUT: - - eps -- nonnegative real number - - OUTPUT: + - eps -- nonnegative real number - - a digraph + OUTPUT: a digraph EXAMPLES:: - sage: m = hmm.DiscreteHiddenMarkovModel([[.3,0,.7],[0,0,1],[.5,.5,0]], [[.5,.5,.2]]*3, [1/3]*3) - sage: G = m.graph(); G + sage: m = hmm.DiscreteHiddenMarkovModel([[.3,0,.7],[0,0,1],[.5,.5,0]], + ....: [[.5,.5,.2]]*3, + ....: [1/3]*3) + sage: G = m.graph(); G # optional - sage.graphs Looped digraph on 3 vertices - sage: G.edges(sort=True) + sage: G.edges(sort=True) # optional - sage.graphs [(0, 0, 0.3), (0, 2, 0.7), (1, 2, 1.0), (2, 0, 0.5), (2, 1, 0.5)] - sage: G.plot() # optional - sage.plot + sage: G.plot() # optional - sage.graphs sage.plot Graphics object consisting of 11 graphics primitives """ cdef int i, j @@ -153,24 +169,28 @@ cdef class HiddenMarkovModel: INPUT: - - ``length`` -- positive integer - - ``number`` -- (default: None) if given, compute list of this many sample sequences - - ``starting_state`` -- int (or None); if specified then generate - a sequence using this model starting with the given state - instead of the initial probabilities to determine the - starting state. + - ``length`` -- positive integer + - ``number`` -- (default: ``None``) if given, compute list of this many sample sequences + - ``starting_state`` -- int (or ``None``); if specified, generate + a sequence using this model starting with the given state + instead of the initial probabilities to determine the + starting state. OUTPUT: - - if number is not given, return a single TimeSeries. - - if number is given, return a list of TimeSeries. + - if ``number`` is not given, return a single :class:`TimeSeries`. + - if ``number`` is given, return a list of :class:`TimeSeries`. EXAMPLES:: sage: set_random_seed(0) - sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]], [[1,0],[0,1]], [0,1]) + sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]], + ....: [[1,0],[0,1]], + ....: [0,1]) sage: print(a.sample(10, 3)) - [[1, 0, 1, 1, 1, 1, 0, 1, 1, 1], [1, 1, 0, 0, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 0, 1, 1, 1]] + [[1, 0, 1, 1, 1, 1, 0, 1, 1, 1], + [1, 1, 0, 0, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 0, 1, 0, 1, 1, 1]] sage: a.sample(15) [1, 1, 1, 1, 0 ... 1, 1, 1, 1, 1] sage: a.sample(3, 1) @@ -181,7 +201,9 @@ cdef class HiddenMarkovModel: If the emission symbols are set:: sage: set_random_seed(0) - sage: a = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.1,0.9]], [[1,0],[0,1]], [0,1], ['up', 'down']) + sage: a = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.1,0.9]], + ....: [[1,0],[0,1]], [0,1], + ....: ['up', 'down']) sage: a.sample(10) ['down', 'up', 'down', 'down', 'down', 'down', 'up', 'up', 'up', 'up'] @@ -211,12 +233,10 @@ cdef class HiddenMarkovModel: INPUT: - - ``alpha`` -- TimeSeries as output by the scaled forward algorithm - - ``beta`` -- TimeSeries as output by the scaled backward algorithm - - OUTPUT: + - ``alpha`` -- :class:`TimeSeries` as output by the scaled forward algorithm + - ``beta`` -- :class:`TimeSeries` as output by the scaled backward algorithm - - TimeSeries gamma such that gamma[t*N+j] is gamma_t(j). + OUTPUT: :class:`TimeSeries` gamma such that gamma[t*N+j] is gamma_t(j). """ cdef int j, N = self.N cdef Py_ssize_t t, T = alpha._length//N @@ -241,31 +261,33 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``A`` -- a list of lists or a square N x N matrix, whose - (i,j) entry gives the probability of transitioning from - state i to state j. + - ``A`` -- a list of lists or a square `N \times N` matrix, whose + `(i,j)` entry gives the probability of transitioning from + state `i` to state `j`. - - ``B`` -- a list of N lists or a matrix with N rows, such that - B[i,k] gives the probability of emitting symbol k while - in state i. + - ``B`` -- a list of `N` lists or a matrix with `N` rows, such that + `B[i,k]` gives the probability of emitting symbol `k` while + in state `i`. - - ``pi`` -- the probabilities of starting in each initial - state, i.e,. pi[i] is the probability of starting in - state i. + - ``pi`` -- the probabilities of starting in each initial + state, i.e., ``pi[i]`` is the probability of starting in + state `i`. - - ``emission_symbols`` -- None or list (default: None); if - None, the emission_symbols are the ints [0..N-1], where N - is the number of states. Otherwise, they are the entries - of the list emissions_symbols, which must all be hashable. + - ``emission_symbols`` -- ``None`` or list (default: ``None``); if + None, the emission_symbols are the ints ``[0..N-1]``, where `N` + is the number of states. Otherwise, they are the entries + of the list ``emissions_symbols``, which must all be hashable. - - ``normalize`` --bool (default: True); if given, input is - normalized to define valid probability distributions, - e.g., the entries of A are made nonnegative and the rows - sum to 1, and the probabilities in pi are normalized. + - ``normalize`` -- bool (default: ``True``); if given, input is + normalized to define valid probability distributions, + e.g., the entries of `A` are made nonnegative and the rows + sum to 1, and the probabilities in ``pi`` are normalized. EXAMPLES:: - sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.5,.5]); m + sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], + ....: [[0.1,0.9],[0.5,0.5]], + ....: [.5,.5]); m Discrete Hidden Markov Model with 2 States and 2 Emissions Transition matrix: [0.4 0.6] @@ -382,20 +404,20 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): def emission_matrix(self): """ - Return the matrix whose i-th row specifies the emission - probability distribution for the i-th state. + Return the matrix whose `i`-th row specifies the emission + probability distribution for the `i`-th state. More precisely, - the i,j entry of the matrix is the probability of the Markov - model outputting the j-th symbol when it is in the i-th state. + the `i,j` entry of the matrix is the probability of the Markov + model outputting the `j`-th symbol when it is in the `i`-th state. - OUTPUT: - - - a Sage matrix with real double precision (RDF) entries. + OUTPUT: a Sage matrix with real double precision (RDF) entries. EXAMPLES:: - sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.5,.5]) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], + ....: [[0.1,0.9],[0.5,0.5]], + ....: [.5,.5]) sage: E = m.emission_matrix(); E [0.1 0.9] [0.5 0.5] @@ -434,15 +456,13 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): def _emission_symbols_to_IntList(self, obs): """ - Internal function used to convert a list of emission symbols to an IntList. + Internal function used to convert a list of emission symbols to an :class:`IntList`. INPUT: - - obs -- a list of objects - - OUTPUT: + - obs -- a list of objects - - an IntList + OUTPUT: an IntList EXAMPLES:: @@ -459,11 +479,9 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- a list of objects + - obs -- a list of objects - OUTPUT: - - - an IntList + OUTPUT: an IntList EXAMPLES:: @@ -481,16 +499,18 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- sequence of observations + - ``obs`` -- sequence of observations - - ``scale`` -- boolean (default: True); if True, use rescaling - to overoid loss of precision due to the very limited - dynamic range of floats. You should leave this as True - unless the obs sequence is very small. + - ``scale`` -- boolean (default: ``True``); if ``True``, use rescaling + to overoid loss of precision due to the very limited + dynamic range of floats. You should leave this as ``True`` + unless the ``obs`` sequence is very small. EXAMPLES:: - sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8]) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], + ....: [[0.1,0.9],[0.5,0.5]], + ....: [.2,.8]) sage: m.log_likelihood([0, 1, 0, 1, 1, 0, 1, 0, 0, 0]) -7.3301308009370825 sage: m.log_likelihood([0, 1, 0, 1, 1, 0, 1, 0, 0, 0], scale=False) @@ -498,7 +518,9 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): sage: m.log_likelihood([]) 0.0 - sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8], ['happy','sad']) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], + ....: [[0.1,0.9],[0.5,0.5]], + ....: [.2,.8], ['happy','sad']) sage: m.log_likelihood(['happy','happy']) -1.6565295199679506 sage: m.log_likelihood(['happy','sad']) @@ -506,7 +528,9 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): Overflow from not using the scale option:: - sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.1,0.9],[0.5,0.5]], [.2,.8]) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], + ....: [[0.1,0.9],[0.5,0.5]], + ....: [.2,.8]) sage: m.log_likelihood([0,1]*1000, scale=True) -1433.820666652728 sage: m.log_likelihood([0,1]*1000, scale=False) @@ -529,11 +553,11 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- an integer list of observation states. + - ``obs`` -- an integer list of observation states. OUTPUT: - - ``float`` -- the log of the probability that the model produced this sequence + - ``float`` -- the log of the probability that the model produced this sequence EXAMPLES:: @@ -584,11 +608,11 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- an integer list of observation states. + - ``obs`` -- an integer list of observation states. OUTPUT: - - ``float`` -- the log of the probability that the model produced this sequence + - ``float`` -- the log of the probability that the model produced this sequence EXAMPLES:: @@ -673,25 +697,27 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``length`` -- positive integer - - ``starting_state`` -- int (or None); if specified then generate - a sequence using this model starting with the given state - instead of the initial probabilities to determine the - starting state. + - ``length`` -- positive integer + - ``starting_state`` -- int (or ``None``); if specified, generate + a sequence using this model starting with the given state + instead of the initial probabilities to determine the + starting state. OUTPUT: - - an IntList or list of emission symbols - - IntList of the actual states the model was in when - emitting the corresponding symbols + - an :class:`IntList` or list of emission symbols + - :class:`IntList` of the actual states the model was in when + emitting the corresponding symbols EXAMPLES: In this example, the emission symbols are not set:: sage: set_random_seed(0) - sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]], [[1,0],[0,1]], [0,1]) + sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]], + ....: [[1,0],[0,1]], + ....: [0,1]) sage: a.generate_sequence(5) ([1, 0, 1, 1, 1], [1, 0, 1, 1, 1]) sage: list(a.generate_sequence(1000)[0]).count(0) @@ -700,7 +726,9 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): Here the emission symbols are set:: sage: set_random_seed(0) - sage: a = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.1,0.9]], [[1,0],[0,1]], [0,1], ['up', 'down']) + sage: a = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.1,0.9]], + ....: [[1,0],[0,1]], + ....: [0,1], ['up', 'down']) sage: a.generate_sequence(5) (['down', 'up', 'down', 'down', 'down'], [1, 0, 1, 1, 1]) @@ -789,8 +817,8 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``q`` -- a nonnegative integer, which specifies a state - - ``r`` -- a real number between 0 and 1 + - ``q`` -- a nonnegative integer, which specifies a state + - ``r`` -- a real number between 0 and 1 OUTPUT: @@ -827,28 +855,32 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``seq`` -- sequence of emitted ints or symbols + - ``seq`` -- sequence of emitted ints or symbols - - ``log_scale`` -- bool (default: True) whether to scale the - sequence in order to avoid numerical overflow. + - ``log_scale`` -- bool (default: ``True``) whether to scale the + sequence in order to avoid numerical overflow. OUTPUT: - - ``list`` -- "the" most probable sequence of hidden states, i.e., - the Viterbi path. + - ``list`` -- "the" most probable sequence of hidden states, i.e., + the Viterbi path. - - ``float`` -- log of probability that the observed sequence - was produced by the Viterbi sequence of states. + - ``float`` -- log of probability that the observed sequence + was produced by the Viterbi sequence of states. EXAMPLES:: - sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]], [[0.9,0.1],[0.1,0.9]], [0.5,0.5]) + sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]], + ....: [[0.9,0.1],[0.1,0.9]], + ....: [0.5,0.5]) sage: a.viterbi([1,0,0,1,0,0,1,1]) ([1, 0, 0, 1, ..., 0, 1, 1], -11.06245322477221...) We predict the state sequence when the emissions are 3/4 and 'abc'.:: - sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]], [[0.9,0.1],[0.1,0.9]], [0.5,0.5], [3/4, 'abc']) + sage: a = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.1,0.9]], + ....: [[0.9,0.1],[0.1,0.9]], + ....: [0.5,0.5], [3/4, 'abc']) Note that state 0 is common below, despite the model trying hard to switch to state 1:: @@ -872,14 +904,14 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- IntList + - ``obs`` -- IntList OUTPUT: - - IntList (most likely state sequence) + - IntList (most likely state sequence) - - log of probability that the observed sequence was - produced by the Viterbi sequence of states. + - log of probability that the observed sequence was + produced by the Viterbi sequence of states. EXAMPLES:: @@ -951,14 +983,14 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- IntList + - obs -- IntList OUTPUT: - - IntList (most likely state sequence) + - IntList (most likely state sequence) - - log of probability that the observed sequence was - produced by the Viterbi sequence of states. + - log of probability that the observed sequence was + produced by the Viterbi sequence of states. EXAMPLES:: @@ -1045,15 +1077,15 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- IntList - - ``scale`` -- series that is *changed* in place, so that - after calling this function, scale[t] is value that is - used to scale each of the `\beta_t(i)`. + - ``obs`` -- IntList + - ``scale`` -- series that is *changed* in place, so that + after calling this function, scale[t] is value that is + used to scale each of the `\beta_t(i)`. OUTPUT: - - a TimeSeries of values beta_t(i). - - the input object scale is modified + - a TimeSeries of values beta_t(i). + - the input object scale is modified """ cdef Py_ssize_t t, T = obs._length cdef int N = self.N, i, j @@ -1083,14 +1115,14 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- IntList + - ``obs`` -- IntList OUTPUT: - - TimeSeries alpha with alpha_t(i) = alpha[t*N + i] - - TimeSeries scale with scale[t] the scaling at step t - - float -- log_probability of the observation sequence - being produced by the model. + - TimeSeries alpha with alpha_t(i) = alpha[t*N + i] + - TimeSeries scale with scale[t] the scaling at step t + - float -- log_probability of the observation sequence + being produced by the model. """ cdef Py_ssize_t i, j, t, T = len(obs) cdef int N = self.N @@ -1144,13 +1176,13 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``alpha`` -- TimeSeries as output by the scaled forward algorithm - - ``beta`` -- TimeSeries as output by the scaled backward algorithm - - ``obs ``-- IntList of observations + - ``alpha`` -- TimeSeries as output by the scaled forward algorithm + - ``beta`` -- TimeSeries as output by the scaled backward algorithm + - ``obs ``-- IntList of observations OUTPUT: - - TimeSeries xi such that xi[t*N*N + i*N + j] = xi_t(i,j). + - TimeSeries xi such that xi[t*N*N + i*N + j] = xi_t(i,j). """ cdef int i, j, N = self.N cdef double sum @@ -1177,27 +1209,29 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``obs`` -- list of emissions + - ``obs`` -- list of emissions - - ``max_iter`` -- integer (default: 100) maximum number - of Baum-Welch steps to take + - ``max_iter`` -- integer (default: 100) maximum number + of Baum-Welch steps to take - - ``log_likelihood_cutoff`` -- positive float (default: 1e-4); - the minimal improvement in likelihood with respect to - the last iteration required to continue. Relative value - to log likelihood. + - ``log_likelihood_cutoff`` -- positive float (default: 1e-4); + the minimal improvement in likelihood with respect to + the last iteration required to continue. Relative value + to log likelihood. - - ``fix_emissions`` -- bool (default: False); if True, do not - change emissions when updating + - ``fix_emissions`` -- bool (default: ``False``); if ``True``, do not + change emissions when updating OUTPUT: - - changes the model in places, and returns the log - likelihood and number of iterations. + - changes the model in places, and returns the log + likelihood and number of iterations. EXAMPLES:: - sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]], [[.5,.5],[0,1]], [.2,.8]) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]], + ....: [[.5,.5],[0,1]], + ....: [.2,.8]) sage: m.baum_welch([1,0]*20, log_likelihood_cutoff=0) (0.0, 4) sage: m # rel tol 1e-14 @@ -1214,7 +1248,9 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): optimizer, i.e., the above model is far more likely to produce the sequence [1,0]*20 than the one we get below:: - sage: m = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.5,0.5]], [[.5,.5],[.5,.5]], [.5,.5]) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.5,0.5],[0.5,0.5]], + ....: [[.5,.5],[.5,.5]], + ....: [.5,.5]) sage: m.baum_welch([1,0]*20, log_likelihood_cutoff=0) (-27.725887222397784, 1) sage: m @@ -1229,14 +1265,18 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): We illustrate fixing emissions:: - sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]], [[.5,.5],[.2,.8]], [.2,.8]) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]], + ....: [[.5,.5],[.2,.8]], + ....: [.2,.8]) sage: set_random_seed(0); v = m.sample(100) sage: m.baum_welch(v,fix_emissions=True) (-66.98630856918774, 100) sage: m.emission_matrix() [0.5 0.5] [0.2 0.8] - sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]], [[.5,.5],[.2,.8]], [.2,.8]) + sage: m = hmm.DiscreteHiddenMarkovModel([[0.1,0.9],[0.9,0.1]], + ....: [[.5,.5],[.2,.8]], + ....: [.2,.8]) sage: m.baum_welch(v) (-66.782360659293..., 100) sage: m.emission_matrix() # rel tol 1e-14 diff --git a/src/sage/stats/hmm/util.pyx b/src/sage/stats/hmm/util.pyx index a5eb8f728d4..bc37413bb13 100644 --- a/src/sage/stats/hmm/util.pyx +++ b/src/sage/stats/hmm/util.pyx @@ -33,13 +33,13 @@ cdef class HMM_Util: INPUT: - - T -- a TimeSeries - - i -- nonnegative integer - - j -- nonnegative integer + - ``T`` -- a :class:`TimeSeries` + - ``i`` -- nonnegative integer + - ``j`` -- nonnegative integer OUTPUT: - - T is modified + - ``T`` is modified EXAMPLES:: @@ -92,14 +92,15 @@ cdef class HMM_Util: INPUT: - - pi -- vector, list, or TimeSeries - - normalize -- if True, replace negative entries by 0 and - rescale to ensure that the sum of the entries in each row is - equal to 1. If the sum of the entries in a row is 0, replace them - all by 1/N. + - ``pi`` -- vector, list, or :class:`TimeSeries` + - ``normalize`` -- if ``True``, replace negative entries by 0 and + rescale to ensure that the sum of the entries in each row is + equal to 1. If the sum of the entries in a row is 0, replace them + all by `1/N`. OUTPUT: - - a TimeSeries of length N + + - a :class:`TimeSeries` of length `N` EXAMPLES:: @@ -125,22 +126,22 @@ cdef class HMM_Util: cpdef TimeSeries state_matrix_to_TimeSeries(self, A, int N, bint normalize): """ - This function is used internally by the __init__ methods of - Hidden Markov Models to make a transition matrix from A. + This function is used internally by the ``__init__`` methods of + Hidden Markov Models to make a transition matrix from ``A``. INPUT: - - A -- matrix, list, list of lists, or TimeSeries - - N -- number of states - - normalize -- if True, replace negative entries by 0 and - rescale to ensure that the sum of the entries in each row is - equal to 1. If the sum of the entries in a row is 0, replace them - all by 1/N. + - ``A`` -- matrix, list, list of lists, or :class:`TimeSeries` + - ``N`` -- number of states + - ``normalize`` -- if ``True``, replace negative entries by 0 and + rescale to ensure that the sum of the entries in each row is + equal to 1. If the sum of the entries in a row is 0, replace them + all by `1/N`. OUTPUT: - - a TimeSeries + - a :class:`TimeSeries` EXAMPLES:: diff --git a/src/sage/stats/intlist.pyx b/src/sage/stats/intlist.pyx index 21bdeb59a68..4acb315366a 100644 --- a/src/sage/stats/intlist.pyx +++ b/src/sage/stats/intlist.pyx @@ -306,7 +306,7 @@ cdef class IntList: def list(self): """ - Return Python list version of self with Python ints as entries. + Return Python list version of ``self`` with Python ints as entries. EXAMPLES:: @@ -324,7 +324,7 @@ cdef class IntList: cpdef int sum(self): """ - Return the sum of the entries of self. + Return the sum of the entries of ``self``. EXAMPLES:: @@ -348,7 +348,7 @@ cdef class IntList: cpdef int prod(self): """ - Return the product of the entries of self. + Return the product of the entries of ``self``. EXAMPLES:: @@ -416,18 +416,18 @@ cdef class IntList: def min(self, bint index=False): """ Return the smallest value in this integer list. If this - series has length 0 we raise a ValueError. + series has length 0 we raise a :class:`ValueError`. INPUT: - - index -- bool (default: False); if True, also return - index of minimal entry. + - ``index`` -- bool (default: ``False``); if ``True``, also return + index of minimal entry. OUTPUT: - - float -- smallest value - - integer -- index of smallest value; only returned if - index=True + - float -- smallest value + - integer -- index of smallest value; only returned if + ``index=True`` EXAMPLES:: @@ -454,17 +454,17 @@ cdef class IntList: def max(self, bint index=False): """ Return the largest value in this time series. If this series - has length 0 we raise a ValueError + has length 0 we raise a :class:`ValueError` INPUT: - - index -- bool (default: False); if True, also return - index of maximum entry. + - ``index`` -- bool (default: ``False``); if ``True``, also return + index of maximum entry. OUTPUT: - - int -- largest value - - int -- index of largest value; only returned if index=True + - int -- largest value + - int -- index of largest value; only returned if ``index=True`` EXAMPLES:: @@ -489,7 +489,7 @@ cdef class IntList: def time_series(self): """ - Return TimeSeries version of self, which involves changing + Return :class:`TimeSeries` version of ``self``, which involves changing each entry to a double. EXAMPLES:: @@ -511,8 +511,10 @@ cdef class IntList: def plot(self, *args, **kwds): """ - Return a plot of this IntList. This just constructs the - corresponding double-precision floating point TimeSeries + Return a plot of this :class:`IntList`. + + This just constructs the + corresponding double-precision floating point :class:`TimeSeries` object, passing on all arguments. EXAMPLES:: @@ -527,8 +529,10 @@ cdef class IntList: def plot_histogram(self, *args, **kwds): """ - Return a histogram plot of this IntList. This just constructs - the corresponding double-precision floating point TimeSeries object, + Return a histogram plot of this :class:`IntList`. + + This just constructs + the corresponding double-precision floating point :class:`TimeSeries` object, and plots it, passing on all arguments. EXAMPLES:: diff --git a/src/sage/stats/r.py b/src/sage/stats/r.py index 5d644b7f54e..47f492eff61 100644 --- a/src/sage/stats/r.py +++ b/src/sage/stats/r.py @@ -26,18 +26,18 @@ def ttest(x, y, conf_level=0.95, **kw): """ T-Test using R - Arguments: + INPUT: - - x, y -- vectors of same length + - ``x``, ``y`` -- vectors of same length - conf_level -- confidence level of the interval, [0,1) in percent - Result: + OUTPUT: Tuple: (p-value, R return object) EXAMPLES:: - sage: a, b = ttest([1,2,3,4,5],[1,2,3,3.5,5.121]); a # abs tol 1e-12 # optional - rpy2 + sage: a, b = ttest([1,2,3,4,5],[1,2,3,3.5,5.121]); a # abs tol 1e-12 # optional - rpy2 0.9410263720274274 """ if len(x) != len(y): diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 9321ed51463..8dc64d427fb 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -626,7 +626,7 @@ cdef class TimeSeries: def autoregressive_forecast(self, filter): """ Given the autoregression coefficients as outputted by the - ``autoregressive_fit`` command, compute the forecast for the next + :meth:`autoregressive_fit` command, compute the forecast for the next term in the series. INPUT: @@ -942,7 +942,7 @@ cdef class TimeSeries: .. NOTE:: - To add componentwise, use the ``add_entries`` method. + To add componentwise, use the :meth:`add_entries` method. INPUT: @@ -981,7 +981,7 @@ cdef class TimeSeries: OUTPUT: - A time series with length the maxima of the lengths of + A time series with length the maximum of the lengths of ``self`` and ``t``. EXAMPLES:: @@ -1023,8 +1023,9 @@ cdef class TimeSeries: def show(self, *args, **kwds): """ - Calls plot and passes all arguments onto the plot function. This is - thus just an alias for plot. + Return a plot of this time series. + + This is an alias of :meth:`plot`. EXAMPLES: @@ -1037,7 +1038,9 @@ cdef class TimeSeries: def plot(self, Py_ssize_t plot_points=1000, points=False, **kwds): r""" - Return a plot of this time series as a line or points through + Return a plot of this time series. + + The plot shows a line or points through `(i,T(i))`, where `i` ranges over nonnegative integers up to the length of ``self``. @@ -1089,11 +1092,12 @@ cdef class TimeSeries: def simple_moving_average(self, Py_ssize_t k): """ - Return the moving average time series over the last ``k`` time units. + Return the moving average time series over the last `k` time units. + Assumes the input time series was constant with its starting value - for negative time. The t-th step of the output is the sum of - the previous ``k - 1`` steps of ``self`` and the ``k``-th step - divided by ``k``. Thus ``k`` values are averaged at each point. + for negative time. The `t`-th step of the output is the sum of + the previous `k - 1` steps of ``self`` and the `k`-th step + divided by `k`. Thus `k` values are averaged at each point. INPUT: @@ -1139,10 +1143,12 @@ cdef class TimeSeries: def exponential_moving_average(self, double alpha): """ - Return the exponential moving average time series. Assumes - the input time series was constant with its starting value for - negative time. The t-th step of the output is the sum of the - previous k-1 steps of ``self`` and the k-th step divided by k. + Return the exponential moving average time series. + + Assumes the input time series was constant with its starting + value for negative time. The `t`-th step of the output is the + sum of the previous `k-1` steps of ``self`` and the `k`-th + step divided by `k`. The 0-th term is formally undefined, so we define it to be 0, and we define the first term to be ``self[0]``. @@ -1217,8 +1223,9 @@ cdef class TimeSeries: cpdef double sum(self): """ - Return the sum of all the entries of ``self``. If ``self`` has - length 0, returns 0. + Return the sum of all the entries of ``self``. + + If ``self`` has length 0, returns 0. OUTPUT: @@ -1239,8 +1246,9 @@ cdef class TimeSeries: def prod(self): """ - Return the product of all the entries of ``self``. If ``self`` has - length 0, returns 1. + Return the product of all the entries of ``self``. + + If ``self`` has length 0, returns 1. OUTPUT: @@ -1279,8 +1287,8 @@ cdef class TimeSeries: def pow(self, double k): """ - Return a new time series with every elements of ``self`` raised to the - k-th power. + Return a new time series with all elements of ``self`` raised to the + `k`-th power. INPUT: @@ -1305,8 +1313,8 @@ cdef class TimeSeries: def moment(self, int k): """ - Return the k-th moment of ``self``, which is just the - mean of the k-th powers of the elements of ``self``. + Return the `k`-th moment of ``self``, which is just the + mean of the `k`-th powers of the elements of ``self``. INPUT: @@ -1337,8 +1345,8 @@ cdef class TimeSeries: def central_moment(self, int k): """ - Return the k-th central moment of ``self``, which is just the mean - of the k-th powers of the differences ``self[i] - mu``, where ``mu`` is + Return the `k`-th central moment of ``self``, which is just the mean + of the `k`-th powers of the differences ``self[i] - mu``, where ``mu`` is the mean of ``self``. INPUT: @@ -1405,7 +1413,8 @@ cdef class TimeSeries: def autocovariance(self, Py_ssize_t k=0): r""" - Return the k-th autocovariance function `\gamma(k)` of ``self``. + Return the `k`-th autocovariance function `\gamma(k)` of ``self``. + This is the covariance of ``self`` with ``self`` shifted by `k`, i.e., .. MATH:: @@ -1436,7 +1445,8 @@ cdef class TimeSeries: 14.4 sage: v.autocovariance(1) -2.7 - sage: mu = v.mean(); sum([(v[i]-mu)*(v[i+1]-mu) for i in range(len(v)-1)])/len(v) + sage: mu = v.mean() + sage: sum((v[i]-mu)*(v[i+1]-mu) for i in range(len(v)-1)])/len(v) -2.7 sage: v.autocovariance(1) -2.7 @@ -1449,7 +1459,8 @@ cdef class TimeSeries: sage: set_random_seed(0) sage: v = stats.TimeSeries(10^6) sage: v.randomize('normal', 0, 5) - [3.3835, -2.0055, 1.7882, -2.9319, -4.6827 ... -5.1868, 9.2613, 0.9274, -6.2282, -8.7652] + [3.3835, -2.0055, 1.7882, -2.9319, -4.6827 ... + -5.1868, 9.2613, 0.9274, -6.2282, -8.7652] sage: v.autocovariance(0) 24.95410689... sage: v.autocovariance(1) @@ -1491,7 +1502,7 @@ cdef class TimeSeries: def autocorrelation(self, Py_ssize_t k=1): r""" - Return the k-th sample autocorrelation of this time series + Return the `k`-th sample autocorrelation of this time series `x_i`. Let `\mu` be the sample mean. Then the sample autocorrelation @@ -1503,7 +1514,7 @@ cdef class TimeSeries: {\sum_{t=0}^{n-1} (x_t - \mu)^2}. Note that the variance must be nonzero or you will get a - ``ZeroDivisionError``. + :class:`ZeroDivisionError`. INPUT: @@ -1617,7 +1628,7 @@ cdef class TimeSeries: statistics of disjoint blocks of size ``b``. Let `\sigma` be the standard deviation of the sequence of - differences of ``self``, and let `Y_k` be the k-th term of ``self``. + differences of ``self``, and let `Y_k` be the `k`-th term of ``self``. Let `n` be the number of terms of ``self``, and set `Z_k = Y_k - ((k+1)/n) \cdot Y_n`. Then @@ -1684,7 +1695,8 @@ cdef class TimeSeries: sage: set_random_seed(0) sage: bm = stats.TimeSeries(10^5).randomize('normal').sums(); bm - [0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... 152.2437, 151.5327, 152.7629, 152.9169, 152.9084] + [0.6767, 0.2756, 0.6332, 0.0469, -0.8897 ... + 152.2437, 151.5327, 152.7629, 152.9169, 152.9084] sage: bm.hurst_exponent() 0.527450972... @@ -1788,7 +1800,7 @@ cdef class TimeSeries: def max(self, bint index=False): """ Return the largest value in this time series. If this series - has length 0 we raise a ``ValueError``. + has length 0 we raise a :class:`ValueError`. INPUT: From be8163b483ecdb523b34e6b16db622826c69a899 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 10:51:26 -0700 Subject: [PATCH 44/99] src/sage/stats/hmm/hmm.pyx: Fix up import --- src/sage/stats/hmm/hmm.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/stats/hmm/hmm.pyx b/src/sage/stats/hmm/hmm.pyx index 48455002d0a..13ee3682615 100644 --- a/src/sage/stats/hmm/hmm.pyx +++ b/src/sage/stats/hmm/hmm.pyx @@ -37,6 +37,7 @@ from cysignals.signals cimport sig_on, sig_off from sage.stats.time_series cimport TimeSeries from sage.structure.element import is_Matrix +from sage.matrix.constructor import matrix from sage.misc.randstate cimport current_randstate, randstate from cpython.object cimport PyObject_RichCompare From 2566945d12f8ad9416dfbf5d2307eba7110a2109 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 10:51:37 -0700 Subject: [PATCH 45/99] More # optional --- src/sage/matrix/matrix2.pyx | 2 +- src/sage/probability/random_variable.py | 2 +- src/sage/quadratic_forms/binary_qf.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 4e63b6507a3..5bfc466c0ac 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1784,7 +1784,7 @@ cdef class Matrix(Matrix1): [1, 0, 0] sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Ryser") [1, 0, 0] - sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Godsil") + sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Godsil") # optional - sage.graphs [1, 0, 0] sage: matrix.ones(4, 2).rook_vector("Ryser") [1, 8, 12] diff --git a/src/sage/probability/random_variable.py b/src/sage/probability/random_variable.py index 11dc4ca3cf7..696681356fc 100644 --- a/src/sage/probability/random_variable.py +++ b/src/sage/probability/random_variable.py @@ -326,7 +326,7 @@ def __init__(self, X, P, codomain=None, check=False): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) sage: X.set() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} - sage: X.entropy().n() + sage: X.entropy().n() # optional - sage.libs.pari 1.99993896484375 A probability space can be defined on any list of elements:: diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index db8da67ff80..ba34c3e0e08 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -1454,7 +1454,7 @@ def complex_point(self): EXAMPLES:: sage: Q = BinaryQF([1, 0, 1]) - sage: Q.complex_point() + sage: Q.complex_point() # optional - sage.libs.pari 1.00000000000000*I """ if self.discriminant() >= 0: @@ -1613,8 +1613,8 @@ def solve_integer(self, n, *, algorithm="general"): sage: abc = [1, 0, randrange(1,10^3)] sage: Q = BinaryQF(abc) - sage: n = random_prime(10^9) - sage: if randrange(2): + sage: n = random_prime(10^9) # optional - sage.libs.pari + sage: if randrange(2): # optional - sage.libs.pari ....: n *= 4 sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') # optional - sage.libs.pari sage: xy1 is None or Q(*xy1) == n # optional - sage.libs.pari From b1ad8cd9f2014ec07a68d86ab95510caf2b435ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 11 Jun 2023 14:37:23 -0700 Subject: [PATCH 46/99] More # optional --- src/sage/probability/random_variable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/probability/random_variable.py b/src/sage/probability/random_variable.py index 696681356fc..eb2aebe102e 100644 --- a/src/sage/probability/random_variable.py +++ b/src/sage/probability/random_variable.py @@ -337,7 +337,7 @@ def __init__(self, X, P, codomain=None, check=False): sage: X = DiscreteProbabilitySpace(S,P) sage: X Discrete probability space defined by {'A': 1/2, 'B': 1/4, 'C': 1/4} - sage: X.entropy().n() + sage: X.entropy().n() # optional - sage.libs.pari 1.50000000000000 """ if codomain is None: From b204f7191cdfc0d61a1d3b71bdd0a9d6e9dc39d6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Jun 2023 20:59:16 -0700 Subject: [PATCH 47/99] More # optional --- src/sage/probability/probability_distribution.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index 07b93a2812c..19233136f9a 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -114,8 +114,8 @@ cdef class ProbabilityDistribution: sage: from sage.probability.probability_distribution import GeneralDiscreteDistribution sage: P = [0.3, 0.4, 0.3] sage: X = GeneralDiscreteDistribution(P) - sage: h, b = X.generate_histogram_data(bins = 10) - sage: h # rel tol 1e-08 + sage: h, b = X.generate_histogram_data(bins=10) # optional - sage.plot + sage: h # rel tol 1e-08 # optional - sage.plot [1.6299999999999999, 0.0, 0.0, @@ -126,7 +126,7 @@ cdef class ProbabilityDistribution: 0.0, 0.0, 1.4650000000000003] - sage: b + sage: b # optional - sage.plot [0.0, 0.2, 0.4, From 6794d856f265f58ce8b8305bf9ec778445d1362e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 14 Jun 2023 21:38:43 -0700 Subject: [PATCH 48/99] More # optional --- .../matrix/matrix_complex_double_dense.pyx | 1 + src/sage/matrix/matrix_numpy_dense.pyx | 1 + .../matrix/matrix_numpy_integer_dense.pyx | 1 + src/sage/matrix/matrix_real_double_dense.pyx | 1 + src/sage/matrix/matrix_space.py | 8 ++--- .../modules/vector_complex_double_dense.pyx | 1 + src/sage/modules/vector_double_dense.pyx | 1 + src/sage/modules/vector_numpy_dense.pyx | 1 + .../modules/vector_numpy_integer_dense.pyx | 1 + src/sage/modules/vector_real_double_dense.pyx | 1 + src/sage/stats/basic_stats.py | 13 +++---- .../discrete_gaussian_lattice.py | 34 ++++++++++++------- .../discrete_gaussian_polynomial.py | 11 +++--- src/sage/stats/hmm/chmm.pyx | 1 + src/sage/stats/hmm/distributions.pyx | 1 + src/sage/stats/hmm/util.pyx | 1 + src/sage/stats/intlist.pyx | 1 + src/sage/stats/time_series.pyx | 17 +++++----- 18 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/sage/matrix/matrix_complex_double_dense.pyx b/src/sage/matrix/matrix_complex_double_dense.pyx index 9f8b8ec9fc8..162332eb44e 100644 --- a/src/sage/matrix/matrix_complex_double_dense.pyx +++ b/src/sage/matrix/matrix_complex_double_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ Dense matrices over the Complex Double Field using NumPy diff --git a/src/sage/matrix/matrix_numpy_dense.pyx b/src/sage/matrix/matrix_numpy_dense.pyx index 17867f9a65c..31ffaa0a51c 100644 --- a/src/sage/matrix/matrix_numpy_dense.pyx +++ b/src/sage/matrix/matrix_numpy_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ Dense matrices using a NumPy backend diff --git a/src/sage/matrix/matrix_numpy_integer_dense.pyx b/src/sage/matrix/matrix_numpy_integer_dense.pyx index bc605df9b92..8c449a86abf 100644 --- a/src/sage/matrix/matrix_numpy_integer_dense.pyx +++ b/src/sage/matrix/matrix_numpy_integer_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy r""" Dense integer matrices using a NumPy backend diff --git a/src/sage/matrix/matrix_real_double_dense.pyx b/src/sage/matrix/matrix_real_double_dense.pyx index 39bb0fcdbab..eeff7658041 100644 --- a/src/sage/matrix/matrix_real_double_dense.pyx +++ b/src/sage/matrix/matrix_real_double_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ Dense matrices over the Real Double Field using NumPy diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 44612458ad7..2fa34122a49 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -878,8 +878,8 @@ def _element_constructor_(self, entries, **kwds): [3 4] sage: MS = MatrixSpace(ZZ, 2) - sage: g = Gamma0(5)([1,1,0,1]) - sage: MS(g) + sage: g = Gamma0(5)([1,1,0,1]) # optional - sage.modular + sage: MS(g) # optional - sage.modular [1 1] [0 1] @@ -904,7 +904,7 @@ def _element_constructor_(self, entries, **kwds): sage: rings.append(SR) # optional - sage.symbolic sage: rings.extend([GF(2), GF(11), GF(2^8,'a'), GF(3^19,'a')]) # optional - sage.libs.pari sage: x = polygen(QQ) - sage: rings.extend([NumberField(x^3+2, 'a'), CyclotomicField(4)]) # optional - sage.rings.number_field + sage: rings.extend([NumberField(x^3 + 2, 'a'), CyclotomicField(4)]) # optional - sage.rings.number_field sage: for R in rings: ....: A = MatrixSpace(R, 60, 30, sparse=False)(0) ....: B = A.augment(A) @@ -1181,7 +1181,7 @@ def _coerce_map_from_(self, S): sage: m = R([[1, 0], [0, 1]]) sage: m in G True - sage: m in list(G) + sage: m in list(G) # optional - sage.libs.gap True sage: m == G(m) True diff --git a/src/sage/modules/vector_complex_double_dense.pyx b/src/sage/modules/vector_complex_double_dense.pyx index 7366acb560a..3f7b31bc787 100644 --- a/src/sage/modules/vector_complex_double_dense.pyx +++ b/src/sage/modules/vector_complex_double_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy r""" Dense complex double vectors using a NumPy backend diff --git a/src/sage/modules/vector_double_dense.pyx b/src/sage/modules/vector_double_dense.pyx index a6981fde9fb..557ebc3ed8a 100644 --- a/src/sage/modules/vector_double_dense.pyx +++ b/src/sage/modules/vector_double_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy r""" Dense vectors using a NumPy backend diff --git a/src/sage/modules/vector_numpy_dense.pyx b/src/sage/modules/vector_numpy_dense.pyx index 6c72c98c0c2..f0e2224b96d 100644 --- a/src/sage/modules/vector_numpy_dense.pyx +++ b/src/sage/modules/vector_numpy_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy r""" Dense vectors using a NumPy backend. diff --git a/src/sage/modules/vector_numpy_integer_dense.pyx b/src/sage/modules/vector_numpy_integer_dense.pyx index b5cca74081f..ba3537436d5 100644 --- a/src/sage/modules/vector_numpy_integer_dense.pyx +++ b/src/sage/modules/vector_numpy_integer_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy r""" Dense integer vectors using a NumPy backend. diff --git a/src/sage/modules/vector_real_double_dense.pyx b/src/sage/modules/vector_real_double_dense.pyx index 948ea384881..55b04c08834 100644 --- a/src/sage/modules/vector_real_double_dense.pyx +++ b/src/sage/modules/vector_real_double_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy r""" Dense real double vectors using a NumPy backend diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index f4ae105c421..3d4de517f49 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -71,7 +71,7 @@ def mean(v): use numpy.mean or numpy.nanmean instead See https://github.com/sagemath/sage/issues/29662 for details. 1/2*pi + 1/2*e - sage: mean([]) + sage: mean([]) # optional - sage.symbolic NaN sage: mean([I, sqrt(2), 3/5]) # optional - sage.symbolic 1/3*sqrt(2) + 1/3*I + 1/5 @@ -79,7 +79,7 @@ def mean(v): 1.5051500000000000? sage: mean(range(4)) 3/2 - sage: v = stats.TimeSeries([1..100]) + sage: v = stats.TimeSeries([1..100]) # optional - numpy sage: mean(v) 50.5 """ @@ -224,8 +224,8 @@ def std(v, bias=False): sage: x = numpy.array([1,2,3,4,5]) # optional - numpy sage: std(x, bias=False) # optional - numpy 1.5811388300841898 - sage: x = stats.TimeSeries([1..100]) - sage: std(x) + sage: x = stats.TimeSeries([1..100]) # optional - numpy + sage: std(x) # optional - numpy 29.011491975882016 TESTS:: @@ -242,8 +242,6 @@ def std(v, bias=False): if hasattr(v, 'standard_deviation'): return v.standard_deviation(bias=bias) - import numpy - if isinstance(v, numpy.ndarray): # accounts for numpy arrays if bias: @@ -339,7 +337,6 @@ def variance(v, bias=False): if hasattr(v, 'variance'): return v.variance(bias=bias) - import numpy x = 0 if isinstance(v, numpy.ndarray): @@ -399,7 +396,7 @@ def median(v): 1/2*pi + 1/2*e sage: median(['sage', 'linux', 'python']) 'python' - sage: median([]) + sage: median([]) # optional - sage.symbolic NaN sage: class MyClass: ....: def median(self): diff --git a/src/sage/stats/distributions/discrete_gaussian_lattice.py b/src/sage/stats/distributions/discrete_gaussian_lattice.py index d77f9e30d09..73d1a269f9c 100644 --- a/src/sage/stats/distributions/discrete_gaussian_lattice.py +++ b/src/sage/stats/distributions/discrete_gaussian_lattice.py @@ -197,7 +197,7 @@ def _normalisation_factor_zz(self, tau=3): INPUT: - ``tau`` -- all vectors `v` with `|v|_∞ ≤ τ·σ` are enumerated - (default: ``3``). + (default: ``3``). EXAMPLES:: @@ -205,7 +205,7 @@ def _normalisation_factor_zz(self, tau=3): sage: n = 3; sigma = 1.0 sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^n, sigma) sage: f = D.f - sage: c = D._normalisation_factor_zz(); c + sage: c = D._normalisation_factor_zz(); c # optional - sage.symbolic 15.528... sage: from collections import defaultdict @@ -219,15 +219,19 @@ def _normalisation_factor_zz(self, tau=3): sage: v = vector(ZZ, n, (0, 0, 0)) sage: v.set_immutable() - sage: while v not in counter: add_samples(1000) + sage: while v not in counter: + ....: add_samples(1000) - sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: add_samples(1000) + sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # optional - sage.symbolic + ....: add_samples(1000) sage: v = vector(ZZ, n, (-1, 2, 3)) sage: v.set_immutable() - sage: while v not in counter: add_samples(1000) + sage: while v not in counter: + ....: add_samples(1000) - sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.2: add_samples(1000) # long time + sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.2: # long time, optional - sage.symbolic + ....: add_samples(1000) """ if self.B != identity_matrix(ZZ, self.B.nrows()): raise NotImplementedError("This function is only implemented when B is an identity matrix.") @@ -261,7 +265,7 @@ def __init__(self, B, sigma=1, c=None, precision=None): sage: n = 2; sigma = 3.0 sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^n, sigma) sage: f = D.f - sage: c = D._normalisation_factor_zz(); c + sage: c = D._normalisation_factor_zz(); c # optional - sage.symbolic 56.2162803067524 sage: from collections import defaultdict @@ -275,23 +279,27 @@ def __init__(self, B, sigma=1, c=None, precision=None): sage: v = vector(ZZ, n, (-3, -3)) sage: v.set_immutable() - sage: while v not in counter: add_samples(1000) - sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: add_samples(1000) + sage: while v not in counter: + ....: add_samples(1000) + sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # optional - sage.symbolic + ....: add_samples(1000) sage: v = vector(ZZ, n, (0, 0)) sage: v.set_immutable() - sage: while v not in counter: add_samples(1000) - sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: add_samples(1000) + sage: while v not in counter: + ....: add_samples(1000) + sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # optional - sage.symbolic + ....: add_samples(1000) sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler sage: qf = QuadraticForm(matrix(3, [2, 1, 1, 1, 2, 1, 1, 1, 2])) - sage: D = DiscreteGaussianDistributionLatticeSampler(qf, 3.0); D + sage: D = DiscreteGaussianDistributionLatticeSampler(qf, 3.0); D # optional - sage.symbolic Discrete Gaussian sampler with σ = 3.000000, c=(0, 0, 0) over lattice with basis [2 1 1] [1 2 1] [1 1 2] - sage: D().parent() is D.c.parent() + sage: D().parent() is D.c.parent() # optional - sage.symbolic True """ precision = DiscreteGaussianDistributionLatticeSampler.compute_precision(precision, sigma) diff --git a/src/sage/stats/distributions/discrete_gaussian_polynomial.py b/src/sage/stats/distributions/discrete_gaussian_polynomial.py index 074c0312947..fa975ebab69 100644 --- a/src/sage/stats/distributions/discrete_gaussian_polynomial.py +++ b/src/sage/stats/distributions/discrete_gaussian_polynomial.py @@ -14,11 +14,12 @@ EXAMPLES:: sage: from sage.stats.distributions.discrete_gaussian_polynomial import DiscreteGaussianDistributionPolynomialSampler - sage: sigma = 3.0; n=1000 - sage: l = [DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], 64, sigma)() for _ in range(n)] - sage: l = [vector(f).norm().n() for f in l] - sage: from numpy import mean # optional - numpy - sage: mean(l), sqrt(64)*sigma # abs tol 5e-1 # optional - numpy + sage: sigma = 3.0; n = 1000 + sage: l = [DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], 64, sigma)() + ....: for _ in range(n)] + sage: l = [vector(f).norm().n() for f in l] # optional - sage.symbolic + sage: from numpy import mean # optional - numpy + sage: mean(l), sqrt(64)*sigma # abs tol 5e-1 # optional - numpy sage.symbolic (24.0, 24.0) """ diff --git a/src/sage/stats/hmm/chmm.pyx b/src/sage/stats/hmm/chmm.pyx index 8a065a6378e..69b05b6c860 100644 --- a/src/sage/stats/hmm/chmm.pyx +++ b/src/sage/stats/hmm/chmm.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ Continuous Emission Hidden Markov Models diff --git a/src/sage/stats/hmm/distributions.pyx b/src/sage/stats/hmm/distributions.pyx index 070f99c35a7..a6380cf6b9f 100644 --- a/src/sage/stats/hmm/distributions.pyx +++ b/src/sage/stats/hmm/distributions.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ Distributions used in implementing Hidden Markov Models diff --git a/src/sage/stats/hmm/util.pyx b/src/sage/stats/hmm/util.pyx index bc37413bb13..553eb997364 100644 --- a/src/sage/stats/hmm/util.pyx +++ b/src/sage/stats/hmm/util.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ Hidden Markov Models -- Utility functions diff --git a/src/sage/stats/intlist.pyx b/src/sage/stats/intlist.pyx index 4acb315366a..0b39a0ebfad 100644 --- a/src/sage/stats/intlist.pyx +++ b/src/sage/stats/intlist.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ C Int Lists diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 8dc64d427fb..1d8dde6899c 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ Time Series @@ -102,22 +103,22 @@ cdef class TimeSeries: Conversion from a NumPy 1-D array, which is very fast:: sage: v = stats.TimeSeries([1..5]) - sage: w = v.numpy() # optional - numpy - sage: stats.TimeSeries(w) # optional - numpy + sage: w = v.numpy() + sage: stats.TimeSeries(w) [1.0000, 2.0000, 3.0000, 4.0000, 5.0000] Conversion from an n-dimensional NumPy array also works:: - sage: import numpy # optional - numpy - sage: v = numpy.array([[1,2], [3,4]], dtype=float); v # optional - numpy + sage: import numpy + sage: v = numpy.array([[1,2], [3,4]], dtype=float); v array([[1., 2.], [3., 4.]]) - sage: stats.TimeSeries(v) # optional - numpy + sage: stats.TimeSeries(v) [1.0000, 2.0000, 3.0000, 4.0000] - sage: stats.TimeSeries(v[:,0]) # optional - numpy + sage: stats.TimeSeries(v[:,0]) [1.0000, 3.0000] - sage: u = numpy.array([[1,2],[3,4]]) # optional - numpy - sage: stats.TimeSeries(u) # optional - numpy + sage: u = numpy.array([[1,2],[3,4]]) + sage: stats.TimeSeries(u) [1.0000, 2.0000, 3.0000, 4.0000] For speed purposes we don't initialize (so value is garbage):: From 412ad36a08f78cf6bc34dcca01200bcd1f30a69a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 17 Jun 2023 10:57:25 -0700 Subject: [PATCH 49/99] src/sage/stats/basic_stats.py: Fix rst markup --- src/sage/stats/basic_stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index 3d4de517f49..ad7166a65e0 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -186,7 +186,7 @@ def std(v, bias=False): - ``v`` -- a list of numbers - ``bias`` -- bool (default: ``False``); if ``False``, divide by - ``len(v) - 1`` instead of ``len(v)` to give a less biased + ``len(v) - 1`` instead of ``len(v)`` to give a less biased estimator (sample) for the standard deviation. OUTPUT: From e895621292ee475841f54002c451b4ee60912e8a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 17 Jun 2023 16:03:20 -0700 Subject: [PATCH 50/99] Conditionalize tests to avoid timeouts/infinite recursion in sagemath-modules tests: --- src/sage/matrix/benchmark.py | 1 + src/sage/matrix/constructor.pyx | 2 +- src/sage/matrix/matrix_space.py | 2 +- src/sage/matrix/special.py | 12 ++++++------ src/sage/modules/fg_pid/fgp_module.py | 6 +++--- src/sage/modules/free_module_integer.py | 12 ++++++------ .../free_quadratic_module_integer_symmetric.py | 2 +- 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/sage/matrix/benchmark.py b/src/sage/matrix/benchmark.py index ee89df9c6dd..1b9b846d3a8 100644 --- a/src/sage/matrix/benchmark.py +++ b/src/sage/matrix/benchmark.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.flint """ Benchmarks for matrices diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index f8b70b56a26..b33e84086c7 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -577,7 +577,7 @@ def matrix(*args, **kwds): Check :trac:`24459`:: - sage: Matrix(ZZ, sys.maxsize, sys.maxsize) + sage: Matrix(ZZ, sys.maxsize, sys.maxsize) # optional - sage.libs.flint Traceback (most recent call last): ... RuntimeError... diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 2fa34122a49..c022e414ae5 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -682,7 +682,7 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): 200 x 1 dense matrix over Rational Field (use the '.str()' method to see the entries) sage: A = MatrixSpace(RDF,1000,1000).random_element() sage: B = MatrixSpace(RDF,1000,1000).random_element() - sage: C = A * B + sage: C = A * B # optional - sage.libs.flint We check that :trac:`18186` is fixed:: diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 58bd22be6df..40eb1bffa7d 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -362,28 +362,28 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation sage: expected_density = (1 - (4/5)^3) sage: float(expected_density) 0.488 - sage: while abs(density_sum/total_count - expected_density) > 0.001: + sage: while abs(density_sum/total_count - expected_density) > 0.001: # optional - sage.libs.flint (o/w timeout) ....: add_sample(ZZ, 5, x=-10, y=10, density=0.75) sage: density_sum = 0.0 sage: total_count = 0.0 sage: add_sample(ZZ, 5, x=20, y=30, density=0.75) - sage: while abs(density_sum/total_count - expected_density) > 0.001: + sage: while abs(density_sum/total_count - expected_density) > 0.001: # optional - sage.libs.flint ....: add_sample(ZZ, 5, x=20, y=30, density=0.75) sage: density_sum = 0.0 sage: total_count = 0.0 - sage: add_sample(ZZ, 100, x=20, y=30, density=0.75) + sage: add_sample(ZZ, 100, x=20, y=30, density=0.75) # optional - sage.libs.flint sage: expected_density = (1 - (99/100)^75) sage: float(expected_density) 0.529... - sage: while abs(density_sum/total_count - expected_density) > 0.001: + sage: while abs(density_sum/total_count - expected_density) > 0.001: # optional - sage.libs.flint ....: add_sample(ZZ, 100, x=20, y=30, density=0.75) For a matrix with low density it may be advisable to insist on a sparse representation, as this representation is not selected automatically. :: - sage: A=random_matrix(ZZ, 5, 5) + sage: A = random_matrix(ZZ, 5, 5) sage: A.is_sparse() False sage: A = random_matrix(ZZ, 5, 5, sparse=True) @@ -393,7 +393,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation For algorithm testing you might want to control the number of bits, say 10,000 entries, each limited to 16 bits. :: - sage: A = random_matrix(ZZ, 100, 100, x=2^16); A + sage: A = random_matrix(ZZ, 100, 100, x=2^16); A # optional - sage.libs.flint 100 x 100 dense matrix over Integer Ring (use the '.str()' method to see the entries) One can prescribe a specific matrix implementation:: diff --git a/src/sage/modules/fg_pid/fgp_module.py b/src/sage/modules/fg_pid/fgp_module.py index c0e9181a141..02b50c82203 100644 --- a/src/sage/modules/fg_pid/fgp_module.py +++ b/src/sage/modules/fg_pid/fgp_module.py @@ -1867,7 +1867,7 @@ def construction(self): sage: T2 = A2 / B2 sage: t1 = T1.an_element() sage: t2 = T2.an_element() - sage: t1 + t2 + sage: t1 + t2 # optional - sage.libs.flint (o/w infinite recursion) (1, 1) """ from sage.modules.module_functors import QuotientModuleFunctor @@ -2068,8 +2068,8 @@ def _test_morphism_0(*args, **kwds): sage: set_random_seed(s); v = [fgp._test_morphism_0(1) for _ in range(30)] sage: set_random_seed(s); v = [fgp._test_morphism_0(2) for _ in range(30)] sage: set_random_seed(s); v = [fgp._test_morphism_0(3) for _ in range(10)] - sage: set_random_seed(s); v = [fgp._test_morphism_0(i) for i in range(1,20)] - sage: set_random_seed(s); v = [fgp._test_morphism_0(4) for _ in range(50)] # long time + sage: set_random_seed(s); v = [fgp._test_morphism_0(i) for i in range(1,20)] # optional - sage.libs.flint (o/w timeout) + sage: set_random_seed(s); v = [fgp._test_morphism_0(4) for _ in range(50)] # long time, optional - sage.libs.flint """ phi = random_fgp_morphism_0(*args, **kwds) K = phi.kernel() diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index 9b77d3d9f28..d9a96197d23 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -404,20 +404,20 @@ def BKZ(self, *args, **kwds): sage: from sage.modules.free_module_integer import IntegerLattice sage: A = sage.crypto.gen_lattice(type='random', n=1, m=60, q=2^60, seed=42) - sage: L = IntegerLattice(A, lll_reduce=False) - sage: min(v.norm().n() for v in L.reduced_basis) + sage: L = IntegerLattice(A, lll_reduce=False) # optional - sage.libs.flint + sage: min(v.norm().n() for v in L.reduced_basis) # optional - sage.libs.flint 4.17330740711759e15 - sage: L.LLL() + sage: L.LLL() # optional - sage.libs.flint 60 x 60 dense matrix over Integer Ring (use the '.str()' method to see the entries) - sage: min(v.norm().n() for v in L.reduced_basis) + sage: min(v.norm().n() for v in L.reduced_basis) # optional - sage.libs.flint 5.19615242270663 - sage: L.BKZ(block_size=10) + sage: L.BKZ(block_size=10) # optional - sage.libs.flint 60 x 60 dense matrix over Integer Ring (use the '.str()' method to see the entries) - sage: min(v.norm().n() for v in L.reduced_basis) + sage: min(v.norm().n() for v in L.reduced_basis) # optional - sage.libs.flint 4.12310562561766 .. NOTE:: diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index e6fea95e51f..0096873b42c 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -1040,7 +1040,7 @@ def maximal_overlattice(self, p=None): TESTS:: sage: L = IntegralLattice(matrix.diagonal([2,4,4,8])) - sage: L.maximal_overlattice().is_even() + sage: L.maximal_overlattice().is_even() # optional - sage.libs.flint True """ From 29dc0e8f671c8f114eb5d13c6741f0f7c13d279c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 17 Jun 2023 21:02:21 -0700 Subject: [PATCH 51/99] More # optional --- src/sage/matrix/matrix_space.py | 12 ++++---- src/sage/matrix/special.py | 53 +++++++++++++++++---------------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index c022e414ae5..0fe101d612a 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -1198,11 +1198,11 @@ def _coerce_map_from_(self, S): Verify which coercion maps are allowed (this should form a poset):: - sage: M1 = MatrixSpace(ZZ, 3, implementation='flint') - sage: M2 = MatrixSpace(ZZ, 3, implementation='generic') - sage: M3 = MatrixSpace(ZZ, 3, implementation='gap') - sage: M4 = MatrixSpace(ZZ, 3, sparse=True) - sage: S = [M1, M2, M3, M4] + sage: S = [] + sage: S += [MatrixSpace(ZZ, 3, implementation='flint')] # optional - sage.libs.flint + sage: S += [MatrixSpace(ZZ, 3, implementation='generic')] + sage: S += [MatrixSpace(ZZ, 3, implementation='gap')] # optional - sage.libs.gap + sage: S += [MatrixSpace(ZZ, 3, sparse=True)] sage: mult = '' sage: for A in S: ....: for B in S: @@ -1211,7 +1211,7 @@ def _coerce_map_from_(self, S): ....: else: ....: mult += ' ' ....: mult += '\n' - sage: print(mult) + sage: print(mult) # optional - sage.libs.flint sage.libs.gap XXXX X X XX diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 40eb1bffa7d..2530bd25898 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -2444,16 +2444,17 @@ def random_rref_matrix(parent, num_pivots): Matrices can be generated over other exact rings. :: - sage: B = random_matrix(FiniteField(7), 4, 4, algorithm='echelon_form', num_pivots=3); B # random + sage: B = random_matrix(FiniteField(7), 4, 4, # random # optional - sage.rings.finite_rings + ....: algorithm='echelon_form', num_pivots=3); B [1 0 0 0] [0 1 0 6] [0 0 1 4] [0 0 0 0] - sage: B.rank() == 3 + sage: B.rank() == 3 # optional - sage.rings.finite_rings True - sage: B.base_ring() + sage: B.base_ring() # optional - sage.rings.finite_rings Finite Field of size 7 - sage: B == B.rref() + sage: B == B.rref() # optional - sage.rings.finite_rings True TESTS: @@ -2617,7 +2618,7 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): An example with default settings (i.e. no entry size control). :: - sage: C=random_matrix(QQ, 6, 7, algorithm='echelonizable', rank=5) + sage: C = random_matrix(QQ, 6, 7, algorithm='echelonizable', rank=5) sage: C.rank() 5 sage: C.rref() == C.rref().change_ring(ZZ) @@ -2625,7 +2626,7 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): A matrix without size control may have very large entry sizes. :: - sage: D=random_matrix(ZZ, 7, 8, algorithm='echelonizable', rank=6); D # random + sage: D = random_matrix(ZZ, 7, 8, algorithm='echelonizable', rank=6); D # random [ 1 2 8 -35 -178 -239 -284 778] [ 4 9 37 -163 -827 -1111 -1324 3624] [ 5 6 21 -88 -454 -607 -708 1951] @@ -2636,11 +2637,12 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): Matrices can be generated over any exact ring. :: - sage: F.=GF(2^3) - sage: B = random_matrix(F, 4, 5, algorithm='echelonizable', rank=4, upper_bound=None) - sage: B.rank() + sage: F. = GF(2^3) # optional - sage.rings.finite_rings + sage: B = random_matrix(F, 4, 5, algorithm='echelonizable', rank=4, # optional - sage.rings.finite_rings + ....: upper_bound=None) + sage: B.rank() # optional - sage.rings.finite_rings 4 - sage: B.base_ring() is F + sage: B.base_ring() is F # optional - sage.rings.finite_rings True Square matrices over ZZ or QQ with full rank are always unimodular. :: @@ -2679,7 +2681,7 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): Works for rank==1, too. :: - sage: random_matrix( QQ, 3, 3, algorithm='echelonizable', rank=1).ncols() + sage: random_matrix(QQ, 3, 3, algorithm='echelonizable', rank=1).ncols() 3 @@ -2981,11 +2983,11 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): A matrix over the number Field in `y` with defining polynomial `y^2-2y-2`. :: sage: y = polygen(ZZ, 'y') - sage: K = NumberField(y^2 - 2*y - 2, 'y') - sage: C = random_matrix(K, 3, algorithm='unimodular') - sage: det(C) + sage: K = NumberField(y^2 - 2*y - 2, 'y') # optional - sage.rings.number_field + sage: C = random_matrix(K, 3, algorithm='unimodular') # optional - sage.rings.number_field + sage: det(C) # optional - sage.rings.number_field 1 - sage: C.base_ring() is K + sage: C.base_ring() is K # optional - sage.rings.number_field True TESTS: @@ -2999,8 +3001,8 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): Only matrices over ZZ and QQ can have size control. :: - sage: F.=GF(5^7) - sage: random_matrix(F, 5, algorithm='unimodular', upper_bound=20) + sage: F. = GF(5^7) # optional - sage.rings.finite_rings + sage: random_matrix(F, 5, algorithm='unimodular', upper_bound=20) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: only matrices over ZZ or QQ can have size control. @@ -3036,11 +3038,11 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): If eigenvalues and dimensions are not specified in a list, they will be assigned randomly. - - ``parent`` - the desired size of the square matrix. + - ``parent`` -- the desired size of the square matrix. - - ``eigenvalues`` - the list of desired eigenvalues (default=None). + - ``eigenvalues`` -- the list of desired eigenvalues (default=None). - - ``dimensions`` - the list of dimensions corresponding to each + - ``dimensions`` -- the list of dimensions corresponding to each eigenspace (default=None). OUTPUT: @@ -3064,10 +3066,10 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): sage: from sage.matrix.constructor import random_diagonalizable_matrix sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5) sage: A = random_diagonalizable_matrix(matrix_space) - sage: eigenvalues = A.eigenvalues() - sage: S = A.right_eigenmatrix()[1] - sage: eigenvalues2 = (S.inverse()*A*S).diagonal() - sage: sorted(eigenvalues) == sorted(eigenvalues2) + sage: eigenvalues = A.eigenvalues() # optional - sage.rings.number_field + sage: S = A.right_eigenmatrix()[1] # optional - sage.rings.number_field + sage: eigenvalues2 = (S.inverse()*A*S).diagonal() # optional - sage.rings.number_field + sage: sorted(eigenvalues) == sorted(eigenvalues2) # optional - sage.rings.number_field True A diagonalizable matrix with eigenvalues and dimensions designated, @@ -3075,7 +3077,8 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): entries would all be integers. :: sage: eigenvalues = [ZZ.random_element() for _ in range(3)] - sage: B = random_matrix(QQ, 6, algorithm='diagonalizable', eigenvalues=eigenvalues, dimensions=[2,3,1]) + sage: B = random_matrix(QQ, 6, algorithm='diagonalizable', + ....: eigenvalues=eigenvalues, dimensions=[2,3,1]) sage: all(x in ZZ for x in (B-(-12*identity_matrix(6))).rref().list()) True sage: all(x in ZZ for x in (B-(4*identity_matrix(6))).rref().list()) From 6331b172951682269165467391546af4f94eab85 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 18 Jun 2023 09:39:49 -0700 Subject: [PATCH 52/99] src/sage/stats/basic_stats.py: Update uses of numpy.ndarray --- src/sage/stats/basic_stats.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index ad7166a65e0..abda35be598 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -242,7 +242,7 @@ def std(v, bias=False): if hasattr(v, 'standard_deviation'): return v.standard_deviation(bias=bias) - if isinstance(v, numpy.ndarray): + if isinstance(v, numpy_ndarray): # accounts for numpy arrays if bias: return v.std() @@ -339,7 +339,7 @@ def variance(v, bias=False): return v.variance(bias=bias) x = 0 - if isinstance(v, numpy.ndarray): + if isinstance(v, numpy_ndarray): # accounts for numpy arrays if bias: return v.var() From 95b62a067d7b10644d57e0c8ea744a02211a50db Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 18 Jun 2023 13:24:32 -0700 Subject: [PATCH 53/99] More # optional --- src/sage/matrix/special.py | 51 ++++++++++--------- src/sage/modules/filtered_vector_space.py | 12 ++--- src/sage/modules/free_module_element.pyx | 8 +-- src/sage/stats/basic_stats.py | 2 +- .../tensor/modules/free_module_morphism.py | 2 +- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 2530bd25898..5797fc9f6ee 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -398,10 +398,10 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation One can prescribe a specific matrix implementation:: - sage: K. = FiniteField(2^8) - sage: type(random_matrix(K, 2, 5)) + sage: K. = FiniteField(2^8) # optional - sage.rings.finite_rings + sage: type(random_matrix(K, 2, 5)) # optional - sage.rings.finite_rings - sage: type(random_matrix(K, 2, 5, implementation="generic")) + sage: type(random_matrix(K, 2, 5, implementation="generic")) # optional - sage.rings.finite_rings Random rational matrices. Now ``num_bound`` and ``den_bound`` control the @@ -421,7 +421,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation ....: for a in A.list()) True - sage: A = random_matrix(QQ, 4, density = 0.5, sparse=True) + sage: A = random_matrix(QQ, 4, density=0.5, sparse=True) sage: type(A) sage: A.density() <= 0.5 @@ -460,11 +460,11 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation randomisation when using the optional meataxe package, we have to make sure that we use the default implementation in this test:: - sage: K.=FiniteField(3^2) - sage: A = random_matrix(K, 2, 5, implementation='generic') - sage: type(A) + sage: K. = FiniteField(3^2) # optional - sage.rings.finite_rings + sage: A = random_matrix(K, 2, 5, implementation='generic') # optional - sage.rings.finite_rings + sage: type(A) # optional - sage.rings.finite_rings - sage: A.base_ring() is K + sage: A.base_ring() is K # optional - sage.rings.finite_rings True sage: TestSuite(A).run() @@ -544,12 +544,13 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation When the eigenvalues and dimensions are not specified the result will have randomly generated values for both that fit with the designated size. :: - sage: A = random_matrix(QQ, 5, algorithm='diagonalizable', eigenvalues=[2,3,-1], dimensions=[1,2,2]); A # random - sage: all(x in ZZ for x in (A-(2*identity_matrix(5))).rref().list()) + sage: A = random_matrix(QQ, 5, algorithm='diagonalizable', # random + ....: eigenvalues=[2,3,-1], dimensions=[1,2,2]); A + sage: all(x in ZZ for x in (A - (2*identity_matrix(5))).rref().list()) True - sage: all(x in ZZ for x in (A-(3*identity_matrix(5))).rref().list()) + sage: all(x in ZZ for x in (A - 3*identity_matrix(5)).rref().list()) True - sage: all(x in ZZ for x in (A-(-1*identity_matrix(5))).rref().list()) + sage: all(x in ZZ for x in (A - (-1)*identity_matrix(5)).rref().list()) True sage: A.jordan_form() [ 2| 0| 0| 0| 0] @@ -575,14 +576,14 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation contain only integer entries. If ``rank``, is not set, the rank of the matrix will be generated randomly. :: - sage: B = random_matrix(QQ, 5, 6, algorithm='subspaces', rank=3); B #random - sage: B_expanded=B.augment(identity_matrix(5)).rref() + sage: B = random_matrix(QQ, 5, 6, algorithm='subspaces', rank=3); B # random + sage: B_expanded = B.augment(identity_matrix(5)).rref() sage: (B.nrows(), B.ncols()) (5, 6) sage: all(x in ZZ for x in B_expanded.list()) True - sage: C=B_expanded.submatrix(0,0,B.nrows()-B.nullity(),B.ncols()) - sage: L=B_expanded.submatrix(B.nrows()-B.nullity(),B.ncols()) + sage: C = B_expanded.submatrix(0, 0, B.nrows() - B.nullity(), B.ncols()) + sage: L = B_expanded.submatrix(B.nrows() - B.nullity(), B.ncols()) sage: B.right_kernel() == C.right_kernel() True sage: B.row_space() == C.row_space() @@ -604,7 +605,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation or ``QQ`` the result has integer entries, whose magnitudes can be limited by the value of ``upper_bound``. :: - sage: C=random_matrix(QQ, 5, algorithm='unimodular', upper_bound=70); C # random + sage: C = random_matrix(QQ, 5, algorithm='unimodular', upper_bound=70); C # random sage: det(C) 1 sage: C.base_ring() @@ -624,7 +625,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation We return an error for a bogus value of ``algorithm``:: - sage: random_matrix(ZZ, 5, algorithm = 'bogus') + sage: random_matrix(ZZ, 5, algorithm='bogus') Traceback (most recent call last): ... ValueError: random matrix algorithm "bogus" is not recognized @@ -2298,9 +2299,9 @@ def companion_matrix(poly, format='right'): sage: t = polygen(QQ, 't') sage: p = t^12 - 7*t^4 + 28*t^2 - 456 sage: C = companion_matrix(p, format='top') - sage: q = C.minpoly(var='t'); q + sage: q = C.minpoly(var='t'); q # optional - sage.libs.pari t^12 - 7*t^4 + 28*t^2 - 456 - sage: p == q + sage: p == q # optional - sage.libs.pari True sage: p = t^3 + 3*t - 8 @@ -2309,9 +2310,9 @@ def companion_matrix(poly, format='right'): ....: companion_matrix(p^2), ....: companion_matrix(q), ....: companion_matrix(q) ) - sage: A.charpoly(var='t').factor() + sage: A.charpoly(var='t').factor() # optional - sage.libs.pari (t^3 + 3*t - 8)^3 * (t^5 + t - 17)^2 - sage: A.minpoly(var='t').factor() + sage: A.minpoly(var='t').factor() # optional - sage.libs.pari (t^3 + 3*t - 8)^2 * (t^5 + t - 17) TESTS:: @@ -2324,12 +2325,14 @@ def companion_matrix(poly, format='right'): sage: companion_matrix(sin(x)) # optional - sage.symbolic Traceback (most recent call last): ... - TypeError: input must be a polynomial (not a symbolic expression, see docstring), or other iterable, not sin(x) + TypeError: input must be a polynomial (not a symbolic expression, see docstring), + or other iterable, not sin(x) sage: companion_matrix([2, 3, 896]) Traceback (most recent call last): ... - ValueError: polynomial (or the polynomial implied by coefficients) must be monic, not a leading coefficient of 896 + ValueError: polynomial (or the polynomial implied by coefficients) must be monic, + not a leading coefficient of 896 sage: F. = GF(2^2) # optional - sage.rings.finite_rings sage: companion_matrix([4/3, a+1, 1]) # optional - sage.rings.finite_rings diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index 7a267935241..8611d2d78dc 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -922,12 +922,12 @@ def __eq__(self, other): TESTS:: - sage: P = toric_varieties.P2() - sage: T_P = P.sheaves.tangent_bundle() - sage: O_P = P.sheaves.trivial_bundle(1) - sage: S1 = T_P + O_P - sage: S2 = O_P + T_P - sage: S1._filt[0].is_isomorphic(S2._filt[0]) # known bug + sage: P = toric_varieties.P2() # optional - sage.geometry.polyhedron sage.schemes + sage: T_P = P.sheaves.tangent_bundle() # optional - sage.geometry.polyhedron sage.schemes + sage: O_P = P.sheaves.trivial_bundle(1) # optional - sage.geometry.polyhedron sage.schemes + sage: S1 = T_P + O_P # optional - sage.geometry.polyhedron sage.schemes + sage: S2 = O_P + T_P # optional - sage.geometry.polyhedron sage.schemes + sage: S1._filt[0].is_isomorphic(S2._filt[0]) # known bug # optional - sage.geometry.polyhedron sage.schemes True sage: FilteredVectorSpace(2, base_ring=QQ) == FilteredVectorSpace(2, base_ring=GF(5)) # optional - sage.libs.pari diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index a4985a216e4..f144706bb30 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -3610,13 +3610,13 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector((1,2,3), QQ)._mathematica_init_() + sage: vector((1,2,3), QQ)._mathematica_init_() # optional - sage.symbolic '{1/1, 2/1, 3/1}' - sage: mathematica(vector((1,2,3), QQ)) # optional - mathematica + sage: mathematica(vector((1,2,3), QQ)) # optional - mathematica sage.symbolic {1, 2, 3} - sage: a = vector(SR, 5, [1, x, x^2, sin(x), pi]); a + sage: a = vector(SR, 5, [1, x, x^2, sin(x), pi]); a # optional - sage.symbolic (1, x, x^2, sin(x), pi) - sage: a._mathematica_init_() + sage: a._mathematica_init_() # optional - mathematica sage.symbolic '{1, x, (x)^(2), Sin[x], Pi}' """ return '{' + ', '.join(x._mathematica_init_() for x in self.list()) + '}' diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index abda35be598..e4276b05561 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -80,7 +80,7 @@ def mean(v): sage: mean(range(4)) 3/2 sage: v = stats.TimeSeries([1..100]) # optional - numpy - sage: mean(v) + sage: mean(v) # optional - numpy 50.5 """ deprecation(29662, 'sage.stats.basic_stats.mean is deprecated; use numpy.mean or numpy.nanmean instead') diff --git a/src/sage/tensor/modules/free_module_morphism.py b/src/sage/tensor/modules/free_module_morphism.py index 2f6c6fd4643..3430172033a 100644 --- a/src/sage/tensor/modules/free_module_morphism.py +++ b/src/sage/tensor/modules/free_module_morphism.py @@ -1058,7 +1058,7 @@ def matrix(self, basis1=None, basis2=None): sage: phi.matrix(e, f) # given bases [-1 2 0] [ 5 1 2] - sage: type(phi.matrix()) + sage: type(phi.matrix()) # optional - sage.libs.flint Matrix in bases different from those in which the homomorphism has From a70f77f85b48dbc2ff273ecde49d6bd2b8465245 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 19 Jun 2023 23:43:13 -0700 Subject: [PATCH 54/99] More # optional --- src/sage/matrix/matrix2.pyx | 2 +- src/sage/matrix/special.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 5bfc466c0ac..8088b5a29fe 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -8456,7 +8456,7 @@ cdef class Matrix(Matrix1): [-1 5] [ 2 4] - sage: M.permutation_normal_form(check=True) # optional - sage.graphs + sage: M.permutation_normal_form(check=True) # optional - sage.graphs sage.groups ( [ 5 -1] [ 4 2] diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 5797fc9f6ee..fa2a1fd2c4d 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -3088,9 +3088,9 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): True sage: all(x in ZZ for x in (B-(6*identity_matrix(6))).rref().list()) True - sage: S = B.right_eigenmatrix()[1] - sage: eigenvalues2 = (S.inverse()*B*S).diagonal() - sage: all(e in eigenvalues for e in eigenvalues2) + sage: S = B.right_eigenmatrix()[1] # optional - sage.rings.number_field + sage: eigenvalues2 = (S.inverse()*B*S).diagonal() # optional - sage.rings.number_field + sage: all(e in eigenvalues for e in eigenvalues2) # optional - sage.rings.number_field True TESTS: From e54998867ef37b1eb712070677cff470a2c89bb4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 20 Jun 2023 15:20:32 -0700 Subject: [PATCH 55/99] More # optional --- src/sage/matrix/matrix2.pyx | 2 +- src/sage/matrix/matrix_double_dense.pyx | 1 + src/sage/stats/basic_stats.py | 10 ++++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 8088b5a29fe..645e6907be1 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -9862,7 +9862,7 @@ cdef class Matrix(Matrix1): sage: M = random_matrix(CC, 5, 7) sage: for i in range(5): M[i,i] = 0 sage: M[4, 0] = M[0, 6] = M[4, 6] = 0 - sage: img = M.visualize_structure(); img + sage: img = M.visualize_structure(); img # optional - pillow 7x5px 24-bit RGB image You can use :meth:`~sage.repl.image.Image.save` to save the diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx index 4515e01978e..ac9a6223542 100644 --- a/src/sage/matrix/matrix_double_dense.pyx +++ b/src/sage/matrix/matrix_double_dense.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - numpy """ Dense matrices using a NumPy backend diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index e4276b05561..03d4f003ce5 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -40,10 +40,13 @@ ###################################################################### from sage.rings.integer_ring import ZZ -from sage.symbolic.constants import NaN from sage.misc.functional import sqrt from sage.misc.superseded import deprecation +lazy_import("sage.symbolic.constants", "NaN") +lazy_import("numpy", "ndarray", as_="numpy_ndarray") +lazy_import("sage.stats.time_series", "TimeSeries") + def mean(v): """ @@ -195,7 +198,7 @@ def std(v, bias=False): EXAMPLES:: - sage: std([1..6], bias=True) + sage: std([1..6], bias=True) # optional - sage.symbolic doctest:warning... DeprecationWarning: sage.stats.basic_stats.std is deprecated; use numpy.std or numpy.nanstd instead @@ -213,7 +216,7 @@ def std(v, bias=False): sqrt(7/2) sage: std([e, pi]) # optional - sage.symbolic sqrt(1/2)*abs(pi - e) - sage: std([]) + sage: std([]) # optional - sage.symbolic NaN sage: std([I, sqrt(2), 3/5]) # optional - sage.symbolic 1/15*sqrt(1/2)*sqrt((10*sqrt(2) - 5*I - 3)^2 @@ -473,7 +476,6 @@ def moving_average(v, n): if not v: return v - from .time_series import TimeSeries if isinstance(v, TimeSeries): return v.simple_moving_average(n)[n - 1:] n = int(n) From ed16bb2878431642487bf1ddf581fe5099ba9203 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 24 Jun 2023 22:36:33 -0700 Subject: [PATCH 56/99] src/sage/stats/basic_stats.py: Add # optional --- src/sage/stats/basic_stats.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index 03d4f003ce5..b004477d87e 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -465,10 +465,10 @@ def moving_average(v, n): different) meaning as defined above (the point is that the :meth:`simple_moving_average` on time series returns `n` values:: - sage: a = stats.TimeSeries([1..10]) - sage: stats.moving_average(a, 3) + sage: a = stats.TimeSeries([1..10]) # optional - numpy + sage: stats.moving_average(a, 3) # optional - numpy [2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000] - sage: stats.moving_average(list(a), 3) + sage: stats.moving_average(list(a), 3) # optional - numpy [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] """ From 1d2ac69ad026c227c97391391f82ed81b5d8aece Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 24 Jun 2023 23:29:27 -0700 Subject: [PATCH 57/99] src/sage/modules/free_quadratic_module_integer_symmetric.py: Update # optional --- ...free_quadratic_module_integer_symmetric.py | 273 +++++++++--------- 1 file changed, 137 insertions(+), 136 deletions(-) diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index 0096873b42c..fd53a367b54 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -155,7 +155,7 @@ def IntegralLattice(data, basis=None): (see :mod:`Cartan types ` and :class:`CartanMatrix`):: - sage: IntegralLattice(["E", 7]) # optional - sage.combinat + sage: IntegralLattice(["E", 7]) # optional - sage.graphs Lattice of degree 7 and rank 7 over Integer Ring Standard basis Inner product matrix: @@ -166,20 +166,20 @@ def IntegralLattice(data, basis=None): [ 0 0 0 -1 2 -1 0] [ 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 -1 2] - sage: IntegralLattice(["A", 2]) # optional - sage.combinat + sage: IntegralLattice(["A", 2]) # optional - sage.graphs Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: [ 2 -1] [-1 2] - sage: IntegralLattice("D3") # optional - sage.combinat + sage: IntegralLattice("D3") # optional - sage.graphs Lattice of degree 3 and rank 3 over Integer Ring Standard basis Inner product matrix: [ 2 -1 -1] [-1 2 0] [-1 0 2] - sage: IntegralLattice(["D", 4]) # optional - sage.combinat + sage: IntegralLattice(["D", 4]) # optional - sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -199,7 +199,7 @@ def IntegralLattice(data, basis=None): Inner product matrix: [0 1] [1 0] - sage: IntegralLattice(["A", 3], [[1,1,1]]) # optional - sage.combinat + sage: IntegralLattice(["A", 3], [[1,1,1]]) # optional - sage.graphs Lattice of degree 3 and rank 1 over Integer Ring Basis matrix: [1 1 1] @@ -212,7 +212,7 @@ def IntegralLattice(data, basis=None): Basis matrix: [1 1 1 1] Standard scalar product - sage: IntegralLattice("A2", [[1,1]]) # optional - sage.combinat + sage: IntegralLattice("A2", [[1,1]]) # optional - sage.graphs Lattice of degree 2 and rank 1 over Integer Ring Basis matrix: [1 1] @@ -222,11 +222,11 @@ def IntegralLattice(data, basis=None): TESTS:: - sage: IntegralLattice(["A", 1, 1]) # optional - sage.combinat + sage: IntegralLattice(["A", 1, 1]) # optional - sage.graphs Traceback (most recent call last): ... ValueError: lattices must be nondegenerate; use FreeQuadraticModule instead - sage: IntegralLattice(["D", 3, 1]) # optional - sage.combinat + sage: IntegralLattice(["D", 3, 1]) # optional - sage.graphs Traceback (most recent call last): ... ValueError: lattices must be nondegenerate; use FreeQuadraticModule instead @@ -272,11 +272,11 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): EXAMPLES:: sage: from sage.modules.free_quadratic_module_integer_symmetric import IntegralLatticeDirectSum - sage: L1 = IntegralLattice("D4") # optional - sage.combinat - sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.combinat - sage: L3 = IntegralLattice("A4", [[0, 1, 1, 2], [1, 2, 3, 1]]) # optional - sage.combinat - sage: Lattices = [L1, L2, L3] # optional - sage.combinat - sage: IntegralLatticeDirectSum([L1, L2, L3]) # optional - sage.combinat + sage: L1 = IntegralLattice("D4") # optional - sage.graphs + sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.graphs + sage: L3 = IntegralLattice("A4", [[0, 1, 1, 2], [1, 2, 3, 1]]) # optional - sage.graphs + sage: Lattices = [L1, L2, L3] # optional - sage.graphs + sage: IntegralLatticeDirectSum([L1, L2, L3]) # optional - sage.graphs Lattice of degree 11 and rank 7 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0 0 0 0] @@ -298,17 +298,17 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): [ 0 0 0 0 0 0 0 -1 2 -1 0] [ 0 0 0 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 0 0 0 -1 2] - sage: [L, phi] = IntegralLatticeDirectSum([L1, L2, L3], True) # optional - sage.combinat - sage: LL3 = L.sublattice(phi[2].image().basis_matrix()) # optional - sage.combinat - sage: L3.discriminant() == LL3.discriminant() # optional - sage.combinat + sage: [L, phi] = IntegralLatticeDirectSum([L1, L2, L3], True) # optional - sage.graphs + sage: LL3 = L.sublattice(phi[2].image().basis_matrix()) # optional - sage.graphs + sage: L3.discriminant() == LL3.discriminant() # optional - sage.graphs True - sage: x = L3([1, 2, 3, 1]) # optional - sage.combinat - sage: phi[2](x).inner_product(phi[2](x)) == x.inner_product(x) # optional - sage.combinat + sage: x = L3([1, 2, 3, 1]) # optional - sage.graphs + sage: phi[2](x).inner_product(phi[2](x)) == x.inner_product(x) # optional - sage.graphs True TESTS:: - sage: IntegralLatticeDirectSum([IntegralLattice("D4")]) # optional - sage.combinat + sage: IntegralLatticeDirectSum([IntegralLattice("D4")]) # optional - sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -318,9 +318,9 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): [ 0 -1 0 2] sage: L1 = IntegralLattice(2 * matrix.identity(2), [[1/2, 1/2]]) - sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.combinat - sage: [L, phi] = IntegralLatticeDirectSum([L1, L2], True) # optional - sage.combinat - sage: L # optional - sage.combinat + sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.graphs + sage: [L, phi] = IntegralLatticeDirectSum([L1, L2], True) # optional - sage.graphs + sage: L # optional - sage.graphs Lattice of degree 5 and rank 2 over Integer Ring Basis matrix: [1/2 1/2 0 0 0] @@ -416,18 +416,18 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Inner product matrix: [4]]] - sage: L1 = IntegralLattice([[2]]) # optional - sage.combinat - sage: L2 = IntegralLattice([[2]]) # optional - sage.combinat - sage: AL1 = L1.discriminant_group() # optional - sage.combinat - sage: AL2 = L2.discriminant_group() # optional - sage.combinat - sage: AL1 # optional - sage.combinat + sage: L1 = IntegralLattice([[2]]) # optional - sage.graphs + sage: L2 = IntegralLattice([[2]]) # optional - sage.graphs + sage: AL1 = L1.discriminant_group() # optional - sage.graphs + sage: AL2 = L2.discriminant_group() # optional - sage.graphs + sage: AL1 # optional - sage.graphs Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1/2] - sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.combinat - sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.combinat - sage: glue = [[g1, g2]] # optional - sage.combinat - sage: IntegralLatticeGluing([L1, L2], glue) # optional - sage.combinat + sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.graphs + sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.graphs + sage: glue = [[g1, g2]] # optional - sage.graphs + sage: IntegralLatticeGluing([L1, L2], glue) # optional - sage.graphs Lattice of degree 2 and rank 2 over Integer Ring Basis matrix: [1/2 1/2] @@ -436,13 +436,13 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [2 0] [0 2] - sage: L1 = IntegralLattice("A4") # optional - sage.combinat - sage: L2 = IntegralLattice("A4") # optional - sage.combinat - sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.combinat - sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.combinat - sage: glue = [[g1, 2 * g2]] # optional - sage.combinat - sage: [V, phi] = IntegralLatticeGluing([L1, L2], glue, True) # optional - sage.combinat - sage: V # optional - sage.combinat + sage: L1 = IntegralLattice("A4") # optional - sage.graphs + sage: L2 = IntegralLattice("A4") # optional - sage.graphs + sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.graphs + sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.graphs + sage: glue = [[g1, 2 * g2]] # optional - sage.graphs + sage: [V, phi] = IntegralLatticeGluing([L1, L2], glue, True) # optional - sage.graphs + sage: V # optional - sage.graphs Lattice of degree 8 and rank 8 over Integer Ring Basis matrix: [1/5 2/5 3/5 4/5 2/5 4/5 1/5 3/5] @@ -462,7 +462,7 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [ 0 0 0 0 -1 2 -1 0] [ 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 -1 2] - sage: V.sublattice(phi[0].image().basis_matrix()) # optional - sage.combinat + sage: V.sublattice(phi[0].image().basis_matrix()) # optional - sage.graphs Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -481,8 +481,8 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Different gluings can be composed:: - sage: D4 = IntegralLattice("D4") # optional - sage.combinat - sage: D4.discriminant_group() # optional - sage.combinat + sage: D4 = IntegralLattice("D4") # optional - sage.graphs + sage: D4.discriminant_group() # optional - sage.graphs Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] @@ -493,23 +493,23 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Gram matrix of the quadratic form with values in Q/2Z: [1/2 0] [ 0 1/2] - sage: g1 = D4.discriminant_group().gens()[0] # optional - sage.combinat + sage: g1 = D4.discriminant_group().gens()[0] # optional - sage.graphs sage: g2 = L2.discriminant_group().gens()[0] + L2.discriminant_group().gens()[1] - sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) # optional - sage.combinat - sage: AD6 = D6.discriminant_group() # optional - sage.combinat - sage: AD6.normal_form() # optional - sage.combinat + sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) # optional - sage.graphs + sage: AD6 = D6.discriminant_group() # optional - sage.graphs + sage: AD6.normal_form() # optional - sage.graphs Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [3/2 0] [ 0 3/2] - sage: f1, g1 = AD6.normal_form().gens() # optional - sage.combinat + sage: f1, g1 = AD6.normal_form().gens() # optional - sage.graphs sage: f2, g2 = L2.discriminant_group().gens() - sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) # optional - sage.combinat - sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) # optional - sage.combinat - sage: x = D4([1, 0, 0, 0]) # optional - sage.combinat - sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x))) == x.inner_product(x) # optional - sage.combinat + sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) # optional - sage.graphs + sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) # optional - sage.graphs + sage: x = D4([1, 0, 0, 0]) # optional - sage.graphs + sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x))) == x.inner_product(x) # optional - sage.graphs True - sage: D4embed # optional - sage.combinat + sage: D4embed # optional - sage.graphs Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -528,27 +528,28 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): The input may be a list of three or more lattices:: - sage: A7 = IntegralLattice("A7") # optional - sage.combinat - sage: D5 = IntegralLattice("D5") # optional - sage.combinat - sage: gA7 = A7.discriminant_group().gens()[0] # optional - sage.combinat - sage: gD5 = D5.discriminant_group().gens()[0] # optional - sage.combinat - sage: [L, phi] = IntegralLatticeGluing([A7, A7, D5, D5], # optional - sage.combinat + sage: A7 = IntegralLattice("A7") # optional - sage.graphs + sage: D5 = IntegralLattice("D5") # optional - sage.graphs + sage: gA7 = A7.discriminant_group().gens()[0] # optional - sage.graphs + sage: gD5 = D5.discriminant_group().gens()[0] # optional - sage.graphs + sage: [L, phi] = IntegralLatticeGluing([A7, A7, D5, D5], # optional - sage.graphs ....: [[gA7, gA7, gD5, 2 * gD5], ....: [gA7, 7 * gA7, 2 * gD5, gD5]], True) - sage: L.determinant() # optional - sage.combinat + sage: L.determinant() # optional - sage.graphs 1 - sage: B = phi[0].matrix() # optional - sage.combinat - sage: B*L.gram_matrix()*B.transpose() == A7.gram_matrix() # optional - sage.combinat + sage: B = phi[0].matrix() # optional - sage.graphs + sage: B*L.gram_matrix()*B.transpose() == A7.gram_matrix() # optional - sage.graphs True The gluing takes place in the direct sum of the respective ambient spaces:: - sage: L1 = IntegralLattice("D4", [[1, 1, 0, 0], [0, 1, 1, 0]]) # optional - sage.combinat - sage: L2 = IntegralLattice("E6", [[0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1]]) # optional - sage.combinat - sage: [f1, f2] = L1.discriminant_group().gens() # optional - sage.combinat - sage: [g1, g2] = L2.discriminant_group().gens() # optional - sage.combinat - sage: [L, phi] = IntegralLatticeGluing([L1, L2], [[f1, g1], [f2, 2 * g2]], True) # optional - sage.combinat - sage: phi[0] # optional - sage.combinat + sage: L1 = IntegralLattice("D4", [[1, 1, 0, 0], [0, 1, 1, 0]]) # optional - sage.graphs + sage: L2 = IntegralLattice("E6", [[0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1]]) # optional - sage.graphs + sage: [f1, f2] = L1.discriminant_group().gens() # optional - sage.graphs + sage: [g1, g2] = L2.discriminant_group().gens() # optional - sage.graphs + sage: [L, phi] = IntegralLatticeGluing([L1, L2], # optional - sage.graphs + ....: [[f1, g1], [f2, 2 * g2]], True) + sage: phi[0] # optional - sage.graphs Free module morphism defined by the matrix [ 2 2 -2 -1] [ 0 2 -1 0] @@ -578,8 +579,8 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [ 0 0 0 0 0 -1 -1 2 -1 0] [ 0 0 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 0 0 -1 2] - sage: B = phi[0].matrix() # optional - sage.combinat - sage: B * L.gram_matrix() * B.transpose() == L1.gram_matrix() # optional - sage.combinat + sage: B = phi[0].matrix() # optional - sage.graphs + sage: B * L.gram_matrix() * B.transpose() == L1.gram_matrix() # optional - sage.graphs True """ [direct_sum, phi] = IntegralLatticeDirectSum(Lattices, return_embeddings=True) @@ -695,8 +696,8 @@ def _repr_(self): EXAMPLES:: - sage: A2 = IntegralLattice("A2") # optional - sage.combinat - sage: A2 # optional - sage.combinat + sage: A2 = IntegralLattice("A2") # optional - sage.graphs + sage: A2 # optional - sage.graphs Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: @@ -731,8 +732,8 @@ def is_even(self): sage: L = IntegralLattice(G) sage: L.is_even() False - sage: L = IntegralLattice("A2") # optional - sage.combinat - sage: L.is_even() + sage: L = IntegralLattice("A2") # optional - sage.graphs + sage: L.is_even() # optional - sage.graphs True """ return all(d % 2 == 0 for d in self.gram_matrix().diagonal()) @@ -750,8 +751,8 @@ def dual_lattice(self): EXAMPLES:: - sage: L = IntegralLattice("A2") # optional - sage.combinat - sage: Ldual = L.dual_lattice(); Ldual # optional - sage.combinat + sage: L = IntegralLattice("A2") # optional - sage.graphs + sage: Ldual = L.dual_lattice(); Ldual # optional - sage.graphs Free module of degree 2 and rank 2 over Integer Ring Echelon basis matrix: [1/3 2/3] @@ -759,7 +760,7 @@ def dual_lattice(self): Since our lattices are always integral, a lattice is contained in its dual:: - sage: L.is_submodule(Ldual) # optional - sage.combinat + sage: L.is_submodule(Ldual) # optional - sage.graphs True """ return self.span(self.gram_matrix().inverse()*self.basis_matrix()) @@ -807,13 +808,13 @@ def discriminant_group(self, s=0): sage: import gc sage: gc.freeze() - sage: L = IntegralLattice("A2") # optional - sage.combinat - sage: for k in range(1,500): # long time # optional - sage.combinat + sage: L = IntegralLattice("A2") # optional - sage.graphs + sage: for k in range(1,500): # long time # optional - sage.graphs ....: G = L.twist(k) ....: D = G.discriminant_group() - sage: tmp = gc.collect() # optional - sage.combinat - sage: tmp = gc.collect() # optional - sage.combinat - sage: len([a for a in gc.get_objects() if type(a) == type(L)]) <= 300 # optional - sage.combinat + sage: tmp = gc.collect() # optional - sage.graphs + sage: tmp = gc.collect() # optional - sage.graphs + sage: len([a for a in gc.get_objects() if type(a) == type(L)]) <= 300 # optional - sage.graphs True sage: gc.unfreeze() """ @@ -849,8 +850,8 @@ def signature_pair(self): EXAMPLES:: - sage: A2 = IntegralLattice("A2") # optional - sage.combinat - sage: A2.signature_pair() # optional - sage.combinat + sage: A2 = IntegralLattice("A2") # optional - sage.graphs + sage: A2.signature_pair() # optional - sage.graphs (2, 0) """ from sage.quadratic_forms.quadratic_form import QuadraticForm @@ -1029,12 +1030,12 @@ def maximal_overlattice(self, p=None): EXAMPLES:: - sage: L = IntegralLattice("A4").twist(25*89) # optional - sage.combinat - sage: L.maximal_overlattice().determinant() # optional - sage.combinat + sage: L = IntegralLattice("A4").twist(25*89) # optional - sage.graphs + sage: L.maximal_overlattice().determinant() # optional - sage.graphs 5 - sage: L.maximal_overlattice(89).determinant().factor() # optional - sage.combinat + sage: L.maximal_overlattice(89).determinant().factor() # optional - sage.graphs 5^9 - sage: L.maximal_overlattice(5).determinant().factor() # optional - sage.combinat + sage: L.maximal_overlattice(5).determinant().factor() # optional - sage.graphs 5 * 89^4 TESTS:: @@ -1164,8 +1165,8 @@ def orthogonal_group(self, gens=None, is_finite=None): EXAMPLES:: - sage: A4 = IntegralLattice("A4") # optional - sage.combinat - sage: Aut = A4.orthogonal_group(); Aut # optional - sage.combinat + sage: A4 = IntegralLattice("A4") # optional - sage.graphs + sage: Aut = A4.orthogonal_group(); Aut # optional - sage.graphs sage.libs.gap Group of isometries with 4 generators ( [0 0 0 1] [-1 -1 -1 0] [ 1 0 0 0] [ 1 0 0 0] [0 0 1 0] [ 0 0 0 -1] [-1 -1 -1 -1] [ 0 1 0 0] @@ -1175,37 +1176,37 @@ def orthogonal_group(self, gens=None, is_finite=None): The group acts from the right on the lattice and its discriminant group:: - sage: x = A4.an_element() # optional - sage.combinat - sage: g = Aut.an_element(); g # optional - sage.combinat + sage: x = A4.an_element() # optional - sage.graphs + sage: g = Aut.an_element(); g # optional - sage.graphs sage.libs.gap [-1 -1 -1 0] [ 0 0 1 0] [ 0 0 -1 -1] [ 0 1 1 1] - sage: x*g # optional - sage.combinat + sage: x*g # optional - sage.graphs sage.libs.gap (-1, -1, -1, 0) - sage: (x*g).parent() == A4 # optional - sage.combinat + sage: (x*g).parent() == A4 # optional - sage.graphs sage.libs.gap True - sage: (g*x).parent() # optional - sage.combinat + sage: (g*x).parent() # optional - sage.graphs sage.libs.gap Vector space of dimension 4 over Rational Field - sage: y = A4.discriminant_group().an_element() # optional - sage.combinat - sage: y*g # optional - sage.combinat + sage: y = A4.discriminant_group().an_element() # optional - sage.graphs sage.libs.gap + sage: y*g # optional - sage.graphs sage.libs.gap (4) If the group is finite we can compute the usual things:: - sage: Aut.order() # optional - sage.combinat + sage: Aut.order() # optional - sage.graphs sage.libs.gap 240 - sage: conj = Aut.conjugacy_classes_representatives() # optional - sage.combinat - sage: len(conj) # optional - sage.combinat + sage: conj = Aut.conjugacy_classes_representatives() # optional - sage.graphs sage.libs.gap + sage: len(conj) # optional - sage.graphs sage.libs.gap 14 - sage: Aut.structure_description() # optional - sage.combinat + sage: Aut.structure_description() # optional - sage.graphs sage.libs.gap 'C2 x S5' The lattice can live in a larger ambient space:: sage: A2 = IntegralLattice(matrix.identity(3), - ....: Matrix(ZZ, 2, 3, [1,-1,0, 0,1,-1])) - sage: A2.orthogonal_group() + ....: Matrix(ZZ, 2, 3, [1,-1,0,0,1,-1])) + sage: A2.orthogonal_group() # optional - sage.libs.gap Group of isometries with 2 generators ( [ 2/3 2/3 -1/3] [1 0 0] [ 2/3 -1/3 2/3] [0 0 1] @@ -1214,16 +1215,16 @@ def orthogonal_group(self, gens=None, is_finite=None): It can be negative definite as well:: - sage: A2m = IntegralLattice(-Matrix(ZZ, 2, [2,1, 1,2])) - sage: G = A2m.orthogonal_group() - sage: G.order() + sage: A2m = IntegralLattice(-Matrix(ZZ, 2, [2,1,1,2])) + sage: G = A2m.orthogonal_group() # optional - sage.libs.gap + sage: G.order() # optional - sage.libs.gap 12 If the lattice is indefinite, sage does not know how to compute generators. Can you teach it?:: - sage: U = IntegralLattice(Matrix(ZZ, 2, [0,1, 1,0])) - sage: U.orthogonal_group() + sage: U = IntegralLattice(Matrix(ZZ, 2, [0,1,1,0])) + sage: U.orthogonal_group() # optional - sage.libs.gap Traceback (most recent call last): ... NotImplementedError: currently, we can only compute generators @@ -1232,8 +1233,8 @@ def orthogonal_group(self, gens=None, is_finite=None): But we can define subgroups:: sage: S = IntegralLattice(Matrix(ZZ, 2, [2, 3, 3, 2])) - sage: f = Matrix(ZZ, 2, [0,1, -1,3]) - sage: S.orthogonal_group([f]) + sage: f = Matrix(ZZ, 2, [0,1,-1,3]) + sage: S.orthogonal_group([f]) # optional - sage.libs.gap Group of isometries with 1 generator ( [ 0 1] [-1 3] @@ -1244,7 +1245,7 @@ def orthogonal_group(self, gens=None, is_finite=None): We can handle the trivial group:: sage: S = IntegralLattice(Matrix(ZZ, 2, [2, 3, 3, 2])) - sage: S.orthogonal_group([]) + sage: S.orthogonal_group([]) # optional - sage.libs.gap Group of isometries with 1 generator ( [1 0] [0 1] @@ -1303,7 +1304,7 @@ def genus(self): EXAMPLES:: sage: L = IntegralLattice("U") - sage: L.genus() + sage: L.genus() # optional - sage.padics Genus of [0 1] [1 0] @@ -1325,8 +1326,8 @@ def tensor_product(self, other, discard_basis=False): EXAMPLES:: - sage: L = IntegralLattice("D3", [[1,-1,0], [0,1,-1]]) # optional - sage.combinat - sage: L1 = L.tensor_product(L); L1 # optional - sage.combinat + sage: L = IntegralLattice("D3", [[1,-1,0], [0,1,-1]]) # optional - sage.graphs + sage: L1 = L.tensor_product(L); L1 # optional - sage.graphs Lattice of degree 9 and rank 4 over Integer Ring Basis matrix: [ 1 -1 0 -1 1 0 0 0 0] @@ -1343,12 +1344,12 @@ def tensor_product(self, other, discard_basis=False): [-2 1 1 0 0 0 4 -2 -2] [ 1 -2 0 0 0 0 -2 4 0] [ 1 0 -2 0 0 0 -2 0 4] - sage: L1.gram_matrix() # optional - sage.combinat + sage: L1.gram_matrix() # optional - sage.graphs [ 36 -12 -12 4] [-12 24 4 -8] [-12 4 24 -8] [ 4 -8 -8 16] - sage: L2 = L.tensor_product(L, True); L2 # optional - sage.combinat + sage: L2 = L.tensor_product(L, True); L2 # optional - sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -1379,8 +1380,8 @@ def quadratic_form(self): EXAMPLES:: - sage: L = IntegralLattice("A2") # optional - sage.combinat - sage: q = L.quadratic_form(); q # optional - sage.combinat + sage: L = IntegralLattice("A2") # optional - sage.graphs + sage: q = L.quadratic_form(); q # optional - sage.graphs Quadratic form in 2 variables over Integer Ring with coefficients: [ 2 -2 ] [ * 2 ] @@ -1399,10 +1400,10 @@ def minimum(self): EXAMPLES:: - sage: L = IntegralLattice('A2') # optional - sage.combinat - sage: L.minimum() # optional - sage.combinat + sage: L = IntegralLattice('A2') # optional - sage.graphs + sage: L.minimum() # optional - sage.graphs 2 - sage: L.twist(-1).minimum() # optional - sage.combinat + sage: L.twist(-1).minimum() # optional - sage.graphs -Infinity """ p, n = self.signature_pair() @@ -1425,10 +1426,10 @@ def maximum(self): EXAMPLES:: - sage: L = IntegralLattice('A2') # optional - sage.combinat - sage: L.maximum() # optional - sage.combinat + sage: L = IntegralLattice('A2') # optional - sage.graphs + sage: L.maximum() # optional - sage.graphs +Infinity - sage: L.twist(-1).maximum() # optional - sage.combinat + sage: L.twist(-1).maximum() # optional - sage.graphs -2 """ if self.rank() == 0: @@ -1449,13 +1450,13 @@ def LLL(self): EXAMPLES:: - sage: L = IntegralLattice('A2') # optional - sage.combinat - sage: L.lll() == L # optional - sage.combinat + sage: L = IntegralLattice('A2') # optional - sage.graphs + sage: L.lll() == L # optional - sage.graphs True sage: G = matrix(ZZ, 3, [0,1,0, 1,0,0, 0,0,7]) sage: V = matrix(ZZ, 3, [-14,-15,-15, -4,1,16, -5,-5,-4]) sage: L = IntegralLattice(V * G * V.T) - sage: L.lll().gram_matrix() + sage: L.lll().gram_matrix() # optional - sage.libs.gap [0 0 1] [0 7 0] [1 0 0] @@ -1496,10 +1497,10 @@ def short_vectors(self, n, **kwargs): EXAMPLES:: - sage: A2 = IntegralLattice('A2') # optional - sage.combinat - sage: A2.short_vectors(3) # optional - sage.combinat + sage: A2 = IntegralLattice('A2') # optional - sage.graphs + sage: A2.short_vectors(3) # optional - sage.graphs [[(0, 0)], [], [(1, 1), (-1, -1), (0, 1), (0, -1), (1, 0), (-1, 0)]] - sage: A2.short_vectors(3,up_to_sign_flag=True) # optional - sage.combinat + sage: A2.short_vectors(3,up_to_sign_flag=True) # optional - sage.graphs [[(0, 0)], [], [(1, 1), (0, 1), (1, 0)]] """ p, m = self.signature_pair() @@ -1526,8 +1527,8 @@ def twist(self, s, discard_basis=False): EXAMPLES:: - sage: L = IntegralLattice("A4") # optional - sage.combinat - sage: L.twist(3) # optional - sage.combinat + sage: L = IntegralLattice("A4") # optional - sage.graphs + sage: L.twist(3) # optional - sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -1589,15 +1590,15 @@ def local_modification(M, G, p, check=True): EXAMPLES:: sage: from sage.modules.free_quadratic_module_integer_symmetric import local_modification - sage: L = IntegralLattice("A3").twist(15) # optional - sage.combinat - sage: M = L.maximal_overlattice() # optional - sage.combinat - sage: for p in prime_divisors(L.determinant()): # optional - sage.combinat + sage: L = IntegralLattice("A3").twist(15) # optional - sage.graphs + sage: M = L.maximal_overlattice() # optional - sage.graphs + sage: for p in prime_divisors(L.determinant()): # optional - sage.graphs ....: M = local_modification(M, L.gram_matrix(), p) - sage: M.genus() == L.genus() # optional - sage.combinat + sage: M.genus() == L.genus() # optional - sage.graphs True - sage: L = IntegralLattice("D4").twist(3*4) # optional - sage.combinat - sage: M = L.maximal_overlattice() # optional - sage.combinat - sage: local_modification(M, L.gram_matrix(), 2) # optional - sage.combinat + sage: L = IntegralLattice("D4").twist(3*4) # optional - sage.graphs + sage: M = L.maximal_overlattice() # optional - sage.graphs + sage: local_modification(M, L.gram_matrix(), 2) # optional - sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Basis matrix: [1/3 0 2/3 2/3] From adbf73efaeafe40a9063b57da2d0ecb1fbca57dc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 25 Jun 2023 22:55:43 -0700 Subject: [PATCH 58/99] More # optional --- src/sage/modules/module.pyx | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/sage/modules/module.pyx b/src/sage/modules/module.pyx index 20c51d19079..8400252adf9 100644 --- a/src/sage/modules/module.pyx +++ b/src/sage/modules/module.pyx @@ -27,7 +27,8 @@ A minimal example of a module:: ....: def _repr_(self): ....: return repr(self.x) - sage: class MyModule(sage.modules.module.Module): + sage: from sage.modules.module import Module + sage: class MyModule(Module): ....: Element = MyElement ....: def _element_constructor_(self, x): ....: if isinstance(x, MyElement): x = x.x @@ -106,10 +107,10 @@ cdef class Module(Parent): We check that :trac:`8119` has been resolved:: - sage: M = ZZ^3 - sage: h = M.__hash__() - sage: M.rename('toto') - sage: h == M.__hash__() + sage: M = ZZ^3 # optional - sage.modules + sage: h = M.__hash__() # optional - sage.modules + sage: M.rename('toto') # optional - sage.modules + sage: h == M.__hash__() # optional - sage.modules True """ @@ -161,7 +162,7 @@ cdef class Module(Parent): Make sure :trac:`3638` is fixed:: - sage: vector(ZZ,[1,2,11])==vector(Zmod(8),[1,2,3]) + sage: vector(ZZ,[1,2,11]) == vector(Zmod(8),[1,2,3]) # optional - sage.modules True AUTHORS: @@ -212,8 +213,8 @@ cdef class Module(Parent): EXAMPLES:: - sage: V = ZZ^7 - sage: V.base_extend(QQ) + sage: V = ZZ^7 # optional - sage.modules + sage: V.base_extend(QQ) # optional - sage.modules Vector space of dimension 7 over Rational Field TESTS:: @@ -278,8 +279,8 @@ def is_Module(x): EXAMPLES:: sage: from sage.modules.module import is_Module - sage: M = FreeModule(RationalField(),30) - sage: is_Module(M) + sage: M = FreeModule(RationalField(),30) # optional - sage.modules + sage: is_Module(M) # optional - sage.modules True sage: is_Module(10) False @@ -298,13 +299,13 @@ def is_VectorSpace(x): EXAMPLES:: sage: from sage.modules.module import is_Module, is_VectorSpace - sage: M = FreeModule(RationalField(),30) - sage: is_VectorSpace(M) + sage: M = FreeModule(RationalField(),30) # optional - sage.modules + sage: is_VectorSpace(M) # optional - sage.modules True - sage: M = FreeModule(IntegerRing(),30) - sage: is_Module(M) + sage: M = FreeModule(IntegerRing(),30) # optional - sage.modules + sage: is_Module(M) # optional - sage.modules True - sage: is_VectorSpace(M) + sage: is_VectorSpace(M) # optional - sage.modules False """ From 9056a12f3bf80338164d7fd20585a6ba8f17dde5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 27 Jun 2023 18:08:55 -0700 Subject: [PATCH 59/99] sage.modules: ./sage -fixdoctests --long --distribution 'sagemath-modules' --only-tags --probe=sage.rings.finite_rings --overwrite src/sage/modules/*.{py,pyx} --- src/sage/modules/filtered_vector_space.py | 8 +- src/sage/modules/free_module.py | 234 +++++++++++----------- src/sage/modules/free_module_element.pyx | 154 +++++++------- src/sage/modules/free_module_homspace.py | 2 +- src/sage/modules/free_quadratic_module.py | 32 +-- src/sage/modules/vector_modn_dense.pyx | 38 ++-- src/sage/modules/vector_space_homspace.py | 14 +- 7 files changed, 241 insertions(+), 241 deletions(-) diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index 8611d2d78dc..b81e228111d 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -826,8 +826,8 @@ def _repr_vector_space(self, dim): sage: F = FilteredVectorSpace(3, base_ring=RDF) sage: F._repr_vector_space(1234) 'RDF^1234' - sage: F3 = FilteredVectorSpace(3, base_ring=GF(3)) # optional - sage.libs.pari - sage: F3._repr_vector_space(1234) # optional - sage.libs.pari + sage: F3 = FilteredVectorSpace(3, base_ring=GF(3)) + sage: F3._repr_vector_space(1234) 'GF(3)^1234' sage: F3 = FilteredVectorSpace(3, base_ring=AA) # optional - sage.rings.number_field sage: F3._repr_vector_space(1234) # optional - sage.rings.number_field @@ -884,7 +884,7 @@ def _repr_(self): QQ^1 in QQ^2 sage: FilteredVectorSpace(rays, {0:[3]}) QQ^1 >= 0 in QQ^2 - sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=GF(3)) # optional - sage.libs.pari + sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=GF(3)) GF(3)^2 >= GF(3)^1 >= GF(3)^1 >= 0 sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=AA) # optional - sage.rings.number_field Vector space of dimension 2 over Algebraic Real Field @@ -930,7 +930,7 @@ def __eq__(self, other): sage: S1._filt[0].is_isomorphic(S2._filt[0]) # known bug # optional - sage.geometry.polyhedron sage.schemes True - sage: FilteredVectorSpace(2, base_ring=QQ) == FilteredVectorSpace(2, base_ring=GF(5)) # optional - sage.libs.pari + sage: FilteredVectorSpace(2, base_ring=QQ) == FilteredVectorSpace(2, base_ring=GF(5)) False """ if type(self) is not type(other): diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 797302ded50..2e671b6658f 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -25,10 +25,10 @@ Basis matrix: [ 1 0 -7] [ 0 1 7] - sage: C = VectorSpaces(FiniteField(7)) # optional - sage.libs.pari - sage: C # optional - sage.libs.pari + sage: C = VectorSpaces(FiniteField(7)) + sage: C Category of vector spaces over Finite Field of size 7 - sage: C(W) # optional - sage.libs.pari + sage: C(W) Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 0] @@ -37,11 +37,11 @@ :: sage: M = ZZ^3 - sage: C = VectorSpaces(FiniteField(7)) # optional - sage.libs.pari - sage: C(M) # optional - sage.libs.pari + sage: C = VectorSpaces(FiniteField(7)) + sage: C(M) Vector space of dimension 3 over Finite Field of size 7 - sage: W = M.submodule([[1,2,7], [8,8,0]]) # optional - sage.libs.pari - sage: C(W) # optional - sage.libs.pari + sage: W = M.submodule([[1,2,7], [8,8,0]]) + sage: C(W) Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 0] @@ -385,7 +385,7 @@ def FreeModule(base_ring, rank_or_basis_keys=None, sparse=False, inner_product_m Vector space of dimension 10 over Rational Field sage: FreeModule(ZZ,10) Ambient free module of rank 10 over the principal ideal domain Integer Ring - sage: FreeModule(FiniteField(5),10) # optional - sage.libs.pari + sage: FreeModule(FiniteField(5), 10) Vector space of dimension 10 over Finite Field of size 5 sage: FreeModule(Integers(7),10) Vector space of dimension 10 over Ring of integers modulo 7 @@ -619,7 +619,7 @@ def span(gens, base_ring=None, check=True, already_echelonized=False): Basis matrix: [ 1 0 -3] - sage: span([[1,2,3], [2,2,2], [1,2,5]], GF(2)) # optional - sage.libs.pari + sage: span([[1,2,3], [2,2,2], [1,2,5]], GF(2)) Vector space of degree 3 and dimension 1 over Finite Field of size 2 Basis matrix: [1 0 1] @@ -1109,15 +1109,15 @@ def relations_matrix(self): EXAMPLES:: - sage: V = GF(2)^2 # optional - sage.libs.pari - sage: V.relations_matrix() # optional - sage.libs.pari + sage: V = GF(2)^2 + sage: V.relations_matrix() [] - sage: W = V.subspace([[1, 0]]) # optional - sage.libs.pari - sage: W.relations_matrix() # optional - sage.libs.pari + sage: W = V.subspace([[1, 0]]) + sage: W.relations_matrix() [] - sage: Q = V / W # optional - sage.libs.pari - sage: Q.relations_matrix() # optional - sage.libs.pari + sage: Q = V / W + sage: Q.relations_matrix() [1 0] sage: S. = PolynomialRing(QQ) @@ -1197,13 +1197,13 @@ def __richcmp__(self, other, op): False sage: V1 <= V2 False - sage: R2. = GF(5)[] # optional - sage.rings.finite_rings - sage: F3 = R2^3 # optional - sage.rings.finite_rings - sage: V3 = F3.span([[x^5 - 1, 1 + x + x^2 + x^3 + x^4, 0]]) # optional - sage.rings.finite_rings - sage: W3 = F3.span([[1,1,0], [0,4,0]]) # optional - sage.rings.finite_rings - sage: V3 <= W3 # optional - sage.rings.finite_rings + sage: R2. = GF(5)[] + sage: F3 = R2^3 + sage: V3 = F3.span([[x^5 - 1, 1 + x + x^2 + x^3 + x^4, 0]]) + sage: W3 = F3.span([[1,1,0], [0,4,0]]) + sage: V3 <= W3 True - sage: W3 <= V3 # optional - sage.libs.pari + sage: W3 <= V3 False We compare a one dimensional space to a two dimensional space:: @@ -1568,12 +1568,12 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari - sage: W = V.subspace([[2, 3, 4]]); W # optional - sage.libs.pari + sage: V = VectorSpace(GF(7), 3) + sage: W = V.subspace([[2, 3, 4]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span([[1, 1, 1]]) # optional - sage.libs.pari + sage: W.span([[1, 1, 1]]) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 1] @@ -1639,7 +1639,7 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): sage: V = FreeModule(RDF, 3) sage: W = V.submodule([V.gen(0)]) - sage: W.span([V.gen(1)], base_ring=GF(7)) # optional - sage.libs.pari + sage: W.span([V.gen(1)], base_ring=GF(7)) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 1 0] @@ -1896,13 +1896,13 @@ class FreeModule_generic(Module_free_ambient): sage: PolynomialRing(QQ,3,'x')^3 Ambient free module of rank 3 over the integral domain Multivariate Polynomial Ring in x0, x1, x2 over Rational Field - sage: FreeModule(GF(7), 3).category() # optional - sage.libs.pari + sage: FreeModule(GF(7), 3).category() Category of enumerated finite dimensional vector spaces with basis over (finite enumerated fields and subquotients of monoids and quotients of semigroups) sage: V = QQ^4; V.category() Category of finite dimensional vector spaces with basis over (number fields and quotient fields and metric spaces) - sage: V = GF(5)**20; V.category() # optional - sage.libs.pari + sage: V = GF(5)**20; V.category() Category of enumerated finite dimensional vector spaces with basis over (finite enumerated fields and subquotients of monoids and quotients of semigroups) sage: FreeModule(ZZ,3).category() @@ -2383,8 +2383,8 @@ def __iter__(self): TESTS:: - sage: V = VectorSpace(GF(2, 'a'), 2) # optional - sage.libs.pari - sage: V.list() # optional - sage.libs.pari + sage: V = VectorSpace(GF(2, 'a'), 2) + sage: V.list() [(0, 0), (1, 0), (0, 1), (1, 1)] Test ``iter(ZZ^n)`` and the like:: @@ -2537,19 +2537,19 @@ def basis_matrix(self, ring=None): :: - sage: M = FreeModule(GF(7), 3).span([[2,3,4], [1,1,1]]); M # optional - sage.libs.pari + sage: M = FreeModule(GF(7), 3).span([[2,3,4], [1,1,1]]); M Vector space of degree 3 and dimension 2 over Finite Field of size 7 Basis matrix: [1 0 6] [0 1 2] - sage: M.basis_matrix() # optional - sage.libs.pari + sage: M.basis_matrix() [1 0 6] [0 1 2] :: - sage: M = FreeModule(GF(7), 3).span_of_basis([[2,3,4], [1,1,1]]) # optional - sage.libs.pari - sage: M.basis_matrix() # optional - sage.libs.pari + sage: M = FreeModule(GF(7), 3).span_of_basis([[2,3,4], [1,1,1]]) + sage: M.basis_matrix() [2 3 4] [1 1 1] @@ -2810,9 +2810,9 @@ def dimension(self): EXAMPLES:: - sage: M = FreeModule(FiniteField(19), 100) # optional - sage.libs.pari - sage: W = M.submodule([M.gen(50)]) # optional - sage.libs.pari - sage: W.dimension() # optional - sage.libs.pari + sage: M = FreeModule(FiniteField(19), 100) + sage: W = M.submodule([M.gen(50)]) + sage: W.dimension() 1 """ return self.rank() @@ -2867,11 +2867,11 @@ def base_field(self): EXAMPLES:: - sage: FreeModule(GF(3), 2).base_field() # optional - sage.libs.pari + sage: FreeModule(GF(3), 2).base_field() Finite Field of size 3 - sage: FreeModule(ZZ, 2).base_field() # optional - sage.libs.pari + sage: FreeModule(ZZ, 2).base_field() Rational Field - sage: FreeModule(PolynomialRing(GF(7), 'x'), 2).base_field() # optional - sage.libs.pari + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2).base_field() Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 7 """ @@ -3532,10 +3532,10 @@ def _mul_(self, other, switch_sides=False): Check that :trac:`17705` is fixed:: - sage: V = GF(2)^2 # optional - sage.libs.pari - sage: W = V.subspace([[1, 0]]) # optional - sage.libs.pari - sage: x = matrix(GF(2), [[1, 1], [0, 1]]) # optional - sage.libs.pari - sage: W*x # optional - sage.libs.pari + sage: V = GF(2)^2 + sage: W = V.subspace([[1, 0]]) + sage: x = matrix(GF(2), [[1, 1], [0, 1]]) + sage: W*x Vector space of degree 2 and dimension 1 over Finite Field of size 2 Basis matrix: @@ -3552,15 +3552,15 @@ def relations(self): EXAMPLES:: - sage: V = GF(2)^2 # optional - sage.libs.pari - sage: V.relations() == V.zero_submodule() # optional - sage.libs.pari + sage: V = GF(2)^2 + sage: V.relations() == V.zero_submodule() True - sage: W = V.subspace([[1, 0]]) # optional - sage.libs.pari - sage: W.relations() == V.zero_submodule() # optional - sage.libs.pari + sage: W = V.subspace([[1, 0]]) + sage: W.relations() == V.zero_submodule() True - sage: Q = V / W # optional - sage.libs.pari - sage: Q.relations() == W # optional - sage.libs.pari + sage: Q = V / W + sage: Q.relations() == W True """ return self.zero_submodule() @@ -3579,7 +3579,7 @@ def __init__(self, base_ring, rank, degree, sparse=False, coordinate_ring=None, sage: FreeModule(ZZ, 2) Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: FreeModule(PolynomialRing(GF(7), 'x'), 2) # optional - sage.libs.pari + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2) Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 7 @@ -3676,7 +3676,7 @@ def __init__(self, base_ring, rank, degree, sparse=False, coordinate_ring=None, sage: FreeModule(ZZ, 2) Ambient free module of rank 2 over the principal ideal domain Integer Ring - sage: FreeModule(PolynomialRing(GF(7), 'x'), 2) # optional - sage.libs.pari + sage: FreeModule(PolynomialRing(GF(7), 'x'), 2) Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 7 @@ -4304,7 +4304,7 @@ def __init__(self, base_field, dimension, degree, sparse=False, category=None): sage: FreeModule(QQ, 2) Vector space of dimension 2 over Rational Field - sage: FreeModule(FiniteField(2), 7) # optional - sage.libs.pari + sage: FreeModule(FiniteField(2), 7) Vector space of dimension 7 over Finite Field of size 2 We test that objects of this type are initialised correctly; @@ -4594,12 +4594,12 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari - sage: W = V.subspace([[2,3,4]]); W # optional - sage.libs.pari + sage: V = VectorSpace(GF(7), 3) + sage: W = V.subspace([[2,3,4]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span_of_basis([[2,2,2], [3,3,0]]) # optional - sage.libs.pari + sage: W.span_of_basis([[2,2,2], [3,3,0]]) Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -4608,7 +4608,7 @@ def span_of_basis(self, basis, base_ring=None, check=True, already_echelonized=F The basis vectors must be linearly independent or a ``ValueError`` exception is raised:: - sage: W.span_of_basis([[2,2,2], [3,3,3]]) # optional - sage.libs.pari + sage: W.span_of_basis([[2,2,2], [3,3,3]]) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -4649,8 +4649,8 @@ def subspace(self, gens, check=True, already_echelonized=False): ambient `3`-dimensional space over the finite field of order `7`:: - sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari - sage: W = V.subspace([[2,3,4]]); W # optional - sage.libs.pari + sage: V = VectorSpace(GF(7), 3) + sage: W = V.subspace([[2,3,4]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] @@ -4659,7 +4659,7 @@ def subspace(self, gens, check=True, already_echelonized=False): ``check=False``. This is just equivalent to computing the span of the element:: - sage: W.subspace([[1,1,0]], check=False) # optional - sage.libs.pari + sage: W.subspace([[1,1,0]], check=False) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 0] @@ -4667,7 +4667,7 @@ def subspace(self, gens, check=True, already_echelonized=False): With ``check=True`` (the default) the mistake is correctly detected and reported with an ``ArithmeticError`` exception:: - sage: W.subspace([[1,1,0]], check=True) # optional - sage.libs.pari + sage: W.subspace([[1,1,0]], check=True) Traceback (most recent call last): ... ArithmeticError: argument gens (= [[1, 1, 0]]) does not generate a submodule of self @@ -4684,25 +4684,25 @@ def subspaces(self, dim): EXAMPLES:: - sage: V = VectorSpace(GF(3), 5) # optional - sage.libs.pari - sage: len(list(V.subspaces(0))) # optional - sage.libs.pari + sage: V = VectorSpace(GF(3), 5) + sage: len(list(V.subspaces(0))) 1 - sage: len(list(V.subspaces(1))) # optional - sage.libs.pari + sage: len(list(V.subspaces(1))) 121 - sage: len(list(V.subspaces(2))) # optional - sage.libs.pari + sage: len(list(V.subspaces(2))) 1210 - sage: len(list(V.subspaces(3))) # optional - sage.libs.pari + sage: len(list(V.subspaces(3))) 1210 - sage: len(list(V.subspaces(4))) # optional - sage.libs.pari + sage: len(list(V.subspaces(4))) 121 - sage: len(list(V.subspaces(5))) # optional - sage.libs.pari + sage: len(list(V.subspaces(5))) 1 :: - sage: V = VectorSpace(GF(3), 5) # optional - sage.libs.pari - sage: V = V.subspace([V([1,1,0,0,0]), V([0,0,1,1,0])]) # optional - sage.libs.pari - sage: list(V.subspaces(1)) # optional - sage.libs.pari + sage: V = VectorSpace(GF(3), 5) + sage: V = V.subspace([V([1,1,0,0,0]), V([0,0,1,1,0])]) + sage: list(V.subspaces(1)) [Vector space of degree 5 and dimension 1 over Finite Field of size 3 Basis matrix: [1 1 0 0 0], @@ -4733,8 +4733,8 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari - sage: W = V.subspace_with_basis([[2,2,2], [1,2,3]]); W # optional - sage.libs.pari + sage: V = VectorSpace(GF(7), 3) + sage: W = V.subspace_with_basis([[2,2,2], [1,2,3]]); W Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -4744,7 +4744,7 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: W1 = W.subspace_with_basis([[3,4,5]]); W1 # optional - sage.libs.pari + sage: W1 = W.subspace_with_basis([[3,4,5]]); W1 Vector space of degree 3 and dimension 1 over Finite Field of size 7 User basis matrix: [3 4 5] @@ -4754,14 +4754,14 @@ def subspace_with_basis(self, gens, check=True, already_echelonized=False): :: - sage: W2 = W.subspace([[3,4,5]]); W2 # optional - sage.libs.pari + sage: W2 = W.subspace([[3,4,5]]); W2 Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 6 4] Nonetheless the two subspaces are equal (as mathematical objects):: - sage: W1 == W2 # optional - sage.libs.pari + sage: W1 == W2 True """ return self.submodule_with_basis(gens, check=check, already_echelonized=already_echelonized) @@ -4809,13 +4809,13 @@ def complement(self): we can get complements which are only isomorphic to a vector space decomposition complement. :: - sage: F2 = GF(2, 'x') # optional - sage.rings.finite_rings - sage: V = F2^6 # optional - sage.rings.finite_rings - sage: W = V.span([[1,1,0,0,0,0]]); W # optional - sage.rings.finite_rings + sage: F2 = GF(2, 'x') + sage: V = F2^6 + sage: W = V.span([[1,1,0,0,0,0]]); W Vector space of degree 6 and dimension 1 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] - sage: W.complement() # optional - sage.libs.pari + sage: W.complement() Vector space of degree 6 and dimension 5 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] @@ -4823,7 +4823,7 @@ def complement(self): [0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] - sage: W.intersection(W.complement()) # optional - sage.libs.pari + sage: W.intersection(W.complement()) Vector space of degree 6 and dimension 1 over Finite Field of size 2 Basis matrix: [1 1 0 0 0 0] @@ -4985,23 +4985,23 @@ def linear_dependence(self, vectors, zeros='left', check=True): linearly independent vectors and add in two linear combinations to make a linearly dependent set of five vectors. :: - sage: F = FiniteField(17) # optional - sage.libs.pari - sage: v1 = vector(F, [1, 2, 3, 4, 5]) # optional - sage.libs.pari - sage: v2 = vector(F, [2, 4, 8, 16, 15]) # optional - sage.libs.pari - sage: v3 = vector(F, [1, 0, 0, 0, 1]) # optional - sage.libs.pari - sage: (F^5).linear_dependence([v1, v2, v3]) == [] # optional - sage.libs.pari + sage: F = FiniteField(17) + sage: v1 = vector(F, [1, 2, 3, 4, 5]) + sage: v2 = vector(F, [2, 4, 8, 16, 15]) + sage: v3 = vector(F, [1, 0, 0, 0, 1]) + sage: (F^5).linear_dependence([v1, v2, v3]) == [] True - sage: L = [v1, v2, v3, 2*v1+v2, 3*v2+6*v3] # optional - sage.libs.pari - sage: (F^5).linear_dependence(L) # optional - sage.libs.pari + sage: L = [v1, v2, v3, 2*v1+v2, 3*v2+6*v3] + sage: (F^5).linear_dependence(L) [ (1, 0, 16, 8, 3), (0, 1, 2, 0, 11) ] - sage: v1 + 16*v3 + 8*(2*v1+v2) + 3*(3*v2+6*v3) # optional - sage.libs.pari + sage: v1 + 16*v3 + 8*(2*v1+v2) + 3*(3*v2+6*v3) (0, 0, 0, 0, 0) - sage: v2 + 2*v3 + 11*(3*v2+6*v3) # optional - sage.libs.pari + sage: v2 + 2*v3 + 11*(3*v2+6*v3) (0, 0, 0, 0, 0) - sage: (F^5).linear_dependence(L, zeros='right') # optional - sage.libs.pari + sage: (F^5).linear_dependence(L, zeros='right') [ (15, 16, 0, 1, 0), (0, 14, 11, 0, 1) @@ -5146,7 +5146,7 @@ def __quotient_matrices(self, sub): An example in characteristic 5:: - sage: A = GF(5)^2; B = A.span([[1,3]]); A / B # optional - sage.libs.pari + sage: A = GF(5)^2; B = A.span([[1,3]]); A / B Vector space quotient V/W of dimension 1 over Finite Field of size 5 where V: Vector space of dimension 2 over Finite Field of size 5 W: Vector space of degree 2 and dimension 1 over Finite Field of size 5 @@ -5236,14 +5236,14 @@ def quotient_abstract(self, sub, check=True, **kwds): EXAMPLES:: - sage: V = GF(19)^3 # optional - sage.libs.pari - sage: W = V.span_of_basis([[1,2,3], [1,0,1]]) # optional - sage.libs.pari - sage: U, pi, lift = V.quotient_abstract(W) # optional - sage.libs.pari - sage: pi(V.2) # optional - sage.libs.pari + sage: V = GF(19)^3 + sage: W = V.span_of_basis([[1,2,3], [1,0,1]]) + sage: U, pi, lift = V.quotient_abstract(W) + sage: pi(V.2) (18) - sage: pi(V.0) # optional - sage.libs.pari + sage: pi(V.0) (1) - sage: pi(V.0 + V.2) # optional - sage.libs.pari + sage: pi(V.0 + V.2) (0) Another example involving a quotient of one subspace by another:: @@ -5598,8 +5598,8 @@ def _latex_(self): :: - sage: A = GF(5)^20 # optional - sage.libs.pari - sage: latex(A) # indirect doctest # optional - sage.libs.pari + sage: A = GF(5)^20 + sage: latex(A) \Bold{F}_{5}^{20} :: @@ -5700,12 +5700,12 @@ def change_ring(self, R): sage: A = ZZ^3; A.change_ring(QQ) Vector space of dimension 3 over Rational Field - sage: A = ZZ^3; A.change_ring(GF(5)) # optional - sage.libs.pari + sage: A = ZZ^3; A.change_ring(GF(5)) Vector space of dimension 3 over Finite Field of size 5 For ambient modules any change of rings is defined:: - sage: A = GF(5)**3; A.change_ring(QQ) # optional - sage.libs.pari + sage: A = GF(5)**3; A.change_ring(QQ) Vector space of dimension 3 over Rational Field TESTS: @@ -5993,7 +5993,7 @@ class FreeModule_ambient_domain(FreeModule_generic_domain, FreeModule_ambient): EXAMPLES:: - sage: FreeModule(PolynomialRing(GF(5), 'x'), 3) # optional - sage.libs.pari + sage: FreeModule(PolynomialRing(GF(5), 'x'), 3) Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 5 """ @@ -6004,8 +6004,8 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category TESTS:: - sage: A = FreeModule(PolynomialRing(GF(5),'x'), 3) # optional - sage.libs.pari - sage: TestSuite(A).run() # optional - sage.libs.pari + sage: A = FreeModule(PolynomialRing(GF(5),'x'), 3) + sage: TestSuite(A).run() """ FreeModule_ambient.__init__(self, base_ring, rank, sparse, coordinate_ring, category=category) @@ -6936,15 +6936,15 @@ def relations(self): EXAMPLES:: - sage: V = GF(2)^2 # optional - sage.libs.pari - sage: W = V.subspace([[1, 0]]) # optional - sage.libs.pari - sage: W.relations() == V.zero_submodule() # optional - sage.libs.pari + sage: V = GF(2)^2 + sage: W = V.subspace([[1, 0]]) + sage: W.relations() == V.zero_submodule() True - sage: Q = V / W # optional - sage.libs.pari - sage: Q.relations() == W # optional - sage.libs.pari + sage: Q = V / W + sage: Q.relations() == W True - sage: Q.zero_submodule().relations() == W # optional - sage.libs.pari + sage: Q.zero_submodule().relations() == W True """ return self.__ambient_module.relations() @@ -7345,7 +7345,7 @@ def change_ring(self, R): sage: V = QQ^3 sage: W = V.subspace([[2, 1/2, 1]]) - sage: W.change_ring(GF(7)) # optional - sage.libs.pari + sage: W.change_ring(GF(7)) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 2 4] @@ -8141,8 +8141,8 @@ def element_class(R, is_sparse): EXAMPLES:: - sage: FF = FiniteField(2) # optional - sage.libs.pari - sage: P = PolynomialRing(FF,'x') # optional - sage.libs.pari + sage: FF = FiniteField(2) + sage: P = PolynomialRing(FF,'x') sage: sage.modules.free_module.element_class(QQ, is_sparse=True) sage: sage.modules.free_module.element_class(QQ, is_sparse=False) @@ -8151,15 +8151,15 @@ def element_class(R, is_sparse): sage: sage.modules.free_module.element_class(ZZ, is_sparse=False) - sage: sage.modules.free_module.element_class(FF, is_sparse=True) # optional - sage.libs.pari + sage: sage.modules.free_module.element_class(FF, is_sparse=True) sage: sage.modules.free_module.element_class(FF, is_sparse=False) # optional - sage.libs.pari - sage: sage.modules.free_module.element_class(GF(7), is_sparse=False) # optional - sage.libs.pari + sage: sage.modules.free_module.element_class(GF(7), is_sparse=False) - sage: sage.modules.free_module.element_class(P, is_sparse=True) # optional - sage.libs.pari + sage: sage.modules.free_module.element_class(P, is_sparse=True) - sage: sage.modules.free_module.element_class(P, is_sparse=False) # optional - sage.libs.pari + sage: sage.modules.free_module.element_class(P, is_sparse=False) """ import sage.rings.integer_ring diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index f144706bb30..034d08fbc55 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -43,7 +43,7 @@ field. :: sage: K = ZZ^5 - sage: M = GF(7)^5 # optional - sage.libs.pari + sage: M = GF(7)^5 Arithmetic between the `\QQ` and `\ZZ` modules is defined, and the result is always @@ -60,7 +60,7 @@ to `\QQ`. Since there is no canonical coercion map to the finite field from `\QQ` the following arithmetic is not defined:: - sage: V.0 + M.0 # optional - sage.libs.pari + sage: V.0 + M.0 Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: @@ -73,11 +73,11 @@ field. :: - sage: w = K.0 + M.0; w # optional - sage.libs.pari + sage: w = K.0 + M.0; w (2, 0, 0, 0, 0) - sage: parent(w) # optional - sage.libs.pari + sage: parent(w) Vector space of dimension 5 over Finite Field of size 7 - sage: parent(M.0 + K.0) # optional - sage.libs.pari + sage: parent(M.0 + K.0) Vector space of dimension 5 over Finite Field of size 7 Matrix vector multiply:: @@ -95,7 +95,7 @@ TESTS:: sage: u = 7 sage: R = Integers(D) sage: p = matrix(R,[[84, 97, 55, 58, 51]]) - sage: 2*p.row(0) + sage: 2*p.row(0) # optional - sage.libs.pari (168, 194, 110, 116, 102) This is a test from :trac:`20211`:: @@ -215,20 +215,20 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): All entries must *canonically* coerce to some common ring:: - sage: v = vector([17, GF(11)(5), 19/3]); v # optional - sage.libs.pari + sage: v = vector([17, GF(11)(5), 19/3]); v Traceback (most recent call last): ... TypeError: unable to find a common ring for all elements :: - sage: v = vector([17, GF(11)(5), 19]); v # optional - sage.libs.pari + sage: v = vector([17, GF(11)(5), 19]); v (6, 5, 8) - sage: v.parent() # optional - sage.libs.pari + sage: v.parent() Vector space of dimension 3 over Finite Field of size 11 - sage: v = vector([17, GF(11)(5), 19], QQ); v # optional - sage.libs.pari + sage: v = vector([17, GF(11)(5), 19], QQ); v (17, 5, 19) - sage: v.parent() # optional - sage.libs.pari + sage: v.parent() Vector space of dimension 3 over Rational Field sage: v = vector((1,2,3), QQ); v (1, 2, 3) @@ -251,7 +251,7 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): We make a vector mod 3 out of a vector over `\ZZ`. :: - sage: vector(vector([1,2,3]), GF(3)) # optional - sage.libs.pari + sage: vector(vector([1,2,3]), GF(3)) (1, 2, 0) The degree of a vector may be specified:: @@ -271,9 +271,9 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): you must specify the degree since it is not implied. Here we use a finite field as the base ring. :: - sage: w = vector(FiniteField(7), 4); w # optional - sage.libs.pari + sage: w = vector(FiniteField(7), 4); w (0, 0, 0, 0) - sage: w.parent() # optional - sage.libs.pari + sage: w.parent() Vector space of dimension 4 over Finite Field of size 7 The fastest method to construct a zero vector is to call the @@ -845,11 +845,11 @@ def random_vector(ring, degree=None, *args, **kwds): Any ring with a ``random_element()`` method may be used. :: - sage: F = FiniteField(23) # optional - sage.libs.pari - sage: hasattr(F, 'random_element') # optional - sage.libs.pari + sage: F = FiniteField(23) + sage: hasattr(F, 'random_element') True - sage: v = random_vector(F, 10) # optional - sage.libs.pari - sage: v.parent() # optional - sage.libs.pari + sage: v = random_vector(F, 10) + sage: v.parent() Vector space of dimension 10 over Finite Field of size 23 The default implementation is a dense representation, equivalent to @@ -871,7 +871,7 @@ def random_vector(ring, degree=None, *args, **kwds): sage: v1 = random_vector(ZZ, 20, distribution="1/n") sage: v2 = random_vector(ZZ, 15, x=-1000, y=1000) sage: v3 = random_vector(QQ, 10) - sage: v4 = random_vector(FiniteField(17), 10) # optional - sage.libs.pari + sage: v4 = random_vector(FiniteField(17), 10) sage: v5 = random_vector(RR, 10) sage: set_random_seed(seed) sage: w1 = vector(ZZ.random_element(distribution="1/n") for _ in range(20)) @@ -879,8 +879,8 @@ def random_vector(ring, degree=None, *args, **kwds): sage: w3 = vector(QQ.random_element() for _ in range(10)) sage: [v1, v2, v3] == [w1, w2, w3] True - sage: w4 = vector(FiniteField(17).random_element() for _ in range(10)) # optional - sage.libs.pari - sage: v4 == w4 # optional - sage.libs.pari + sage: w4 = vector(FiniteField(17).random_element() for _ in range(10)) + sage: v4 == w4 True sage: w5 = vector(RR.random_element() for _ in range(10)) sage: v5 == w5 @@ -1154,7 +1154,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v = vector(ZZ, [2, 12, 22]) sage: vector(v) (2, 12, 22) - sage: vector(GF(7), v) # optional - sage.libs.pari + sage: vector(GF(7), v) (2, 5, 1) sage: vector(v, ZZ['x', 'y']) (2, 12, 22) @@ -1177,7 +1177,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: sage_input(vector(RR, [pi, e, 0.5]), verify=True) # Verified vector(RR, [3.1415926535897931, 2.7182818284590451, 0.5]) - sage: sage_input(vector(GF(5), [1, 2, 3, 4, 5]), verify=True) # optional - sage.libs.pari + sage: sage_input(vector(GF(5), [1, 2, 3, 4, 5]), verify=True) # Verified vector(GF(5), [1, 2, 3, 4, 0]) sage: sage_input(vector([0, 0, 0, 1, 0, 0, 0], sparse=True), verify=True) @@ -1328,14 +1328,14 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: v = vector(GF(2), [1,2,3]) # optional - sage.libs.pari - sage: v.n() # optional - sage.libs.pari + sage: v = vector(GF(2), [1,2,3]) + sage: v.n() (1.00000000000000, 0.000000000000000, 1.00000000000000) - sage: _.parent() # optional - sage.libs.pari + sage: _.parent() Vector space of dimension 3 over Real Field with 53 bits of precision - sage: v.n(prec=75) # optional - sage.libs.pari + sage: v.n(prec=75) (1.000000000000000000000, 0.0000000000000000000000, 1.000000000000000000000) - sage: _.parent() # optional - sage.libs.pari + sage: _.parent() Vector space of dimension 3 over Real Field with 75 bits of precision TESTS: @@ -1372,8 +1372,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: w.parent() Full MatrixSpace of 1 by 3 dense matrices over Integer Ring - sage: x = vector(FiniteField(13), [2,4,8,16]) # optional - sage.libs.pari - sage: x.row() # optional - sage.libs.pari + sage: x = vector(FiniteField(13), [2,4,8,16]) + sage: x.row() [2 4 8 3] There is more than one way to get one-row matrix from a vector, @@ -1441,8 +1441,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: w.parent() Full MatrixSpace of 3 by 1 dense matrices over Integer Ring - sage: x = vector(FiniteField(13), [2,4,8,16]) # optional - sage.libs.pari - sage: x.column() # optional - sage.libs.pari + sage: x = vector(FiniteField(13), [2,4,8,16]) + sage: x.column() [2] [4] [8] @@ -1539,7 +1539,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.change_ring(GF(3)) # optional - sage.libs.pari + sage: v = vector(QQ['x,y'], [1..5]); v.change_ring(GF(3)) (1, 2, 0, 1, 2) TESTS: @@ -2196,9 +2196,9 @@ cdef class FreeModuleElement(Vector): # abstract base class The following was fixed in :trac:`8800`:: - sage: M = GF(5)^3 # optional - sage.libs.pari - sage: v = M((4,0,2)) # optional - sage.libs.pari - sage: v.denominator() # optional - sage.libs.pari + sage: M = GF(5)^3 + sage: v = M((4,0,2)) + sage: v.denominator() 1 """ # It may be that the coordinates do not have a denominator @@ -2550,15 +2550,15 @@ cdef class FreeModuleElement(Vector): # abstract base class arguments is reversed.:: sage: v = vector(ZZ, [1,2,3]) - sage: w = vector(FiniteField(3), [0,1,2]) # optional - sage.libs.pari - sage: ip = w.dot_product(v); ip # optional - sage.libs.pari + sage: w = vector(FiniteField(3), [0,1,2]) + sage: ip = w.dot_product(v); ip 2 - sage: ip.parent() # optional - sage.libs.pari + sage: ip.parent() Finite Field of size 3 - sage: ip = v.dot_product(w); ip # optional - sage.libs.pari + sage: ip = v.dot_product(w); ip 2 - sage: ip.parent() # optional - sage.libs.pari + sage: ip.parent() Finite Field of size 3 The dot product of a vector with itself is the 2-norm, squared. :: @@ -2763,24 +2763,24 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: F = GF(previous_prime(2^32)) # optional - sage.libs.pari - sage: v = random_vector(F, 3) # optional - sage.libs.pari - sage: w = random_vector(F, 3) # optional - sage.libs.pari - sage: vh = v.cross_product_matrix() # optional - sage.libs.pari - sage: vh*w == v.cross_product(w) # optional - sage.libs.pari + sage: F = GF(previous_prime(2^32)) # optional - sage.rings.finite_rings + sage: v = random_vector(F, 3) # optional - sage.rings.finite_rings + sage: w = random_vector(F, 3) # optional - sage.rings.finite_rings + sage: vh = v.cross_product_matrix() + sage: vh*w == v.cross_product(w) True - sage: w*vh == w.cross_product(v) # optional - sage.libs.pari + sage: w*vh == w.cross_product(v) True - sage: vh.is_alternating() # optional - sage.libs.pari + sage: vh.is_alternating() True - sage: v = random_vector(F, 7) # optional - sage.libs.pari - sage: w = random_vector(F, 7) # optional - sage.libs.pari - sage: vh = v.cross_product_matrix() # optional - sage.libs.pari - sage: vh*w == v.cross_product(w) # optional - sage.libs.pari + sage: v = random_vector(F, 7) # optional - sage.rings.finite_rings + sage: w = random_vector(F, 7) # optional - sage.rings.finite_rings + sage: vh = v.cross_product_matrix() + sage: vh*w == v.cross_product(w) True - sage: w*vh == w.cross_product(v) # optional - sage.libs.pari + sage: w*vh == w.cross_product(v) True - sage: vh.is_alternating() # optional - sage.libs.pari + sage: vh.is_alternating() True sage: random_vector(F, 5).cross_product_matrix() # optional - sage.libs.pari Traceback (most recent call last): @@ -2837,11 +2837,11 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: W = VectorSpace(GF(3), 3) # optional - sage.libs.pari - sage: w = W([0,1,2]) # optional - sage.libs.pari - sage: w.pairwise_product(v) # optional - sage.libs.pari + sage: W = VectorSpace(GF(3), 3) + sage: w = W([0,1,2]) + sage: w.pairwise_product(v) (0, 2, 0) - sage: w.pairwise_product(v).parent() # optional - sage.libs.pari + sage: w.pairwise_product(v).parent() Vector space of dimension 3 over Finite Field of size 3 Implicit coercion is well defined (regardless of order), so we @@ -2849,7 +2849,7 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: v.pairwise_product(w).parent() # optional - sage.libs.pari + sage: v.pairwise_product(w).parent() Vector space of dimension 3 over Finite Field of size 3 TESTS:: @@ -3408,9 +3408,9 @@ cdef class FreeModuleElement(Vector): # abstract base class But some inputs are not compatible, even if vectors. :: - sage: w = vector(GF(5), [1,2]) # optional - sage.libs.pari - sage: v = vector(GF(7), [1,2,3,4]) # optional - sage.libs.pari - sage: z = w.outer_product(v) # optional - sage.libs.pari + sage: w = vector(GF(5), [1,2]) + sage: v = vector(GF(7), [1,2,3,4]) + sage: z = w.outer_product(v) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 1 dense matrices over Finite Field of size 5' and 'Full MatrixSpace of 1 by 4 dense matrices over Finite Field of size 7' @@ -3840,9 +3840,9 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: s = GF(3) # optional - sage.libs.pari - sage: f = lambda x: s(x) # optional - sage.libs.pari - sage: n = m.apply_map(f, k); n # optional - sage.libs.pari + sage: s = GF(3) + sage: f = lambda x: s(x) + sage: n = m.apply_map(f, k); n # optional - sage.rings.finite_rings (0, 1, 2, 0, 1, 2, 0, 1, 2) sage: n.parent() # optional - sage.libs.pari Vector space of dimension 9 over Finite Field in a of size 3^2 @@ -4716,8 +4716,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): We correctly initialize values which become 0 only after coercion:: - sage: v = FreeModuleElement_generic_sparse(S(GF(3), 6), [1,2,3,4,5,6]) # optional - sage.libs.pari - sage: v.nonzero_positions() # optional - sage.libs.pari + sage: v = FreeModuleElement_generic_sparse(S(GF(3), 6), [1,2,3,4,5,6]) + sage: v.nonzero_positions() [0, 1, 3, 4] """ #WARNING: In creation, we do not check that the indices i satisfy @@ -4925,10 +4925,10 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): Check that the bug in :trac:`13929` has been fixed:: - sage: V = FreeModule(GF(3), 2, sparse=True) # optional - sage.libs.pari - sage: a = V([0,1]) # optional - sage.libs.pari - sage: b = V([1,0]) # optional - sage.libs.pari - sage: a < b # optional - sage.libs.pari + sage: V = FreeModule(GF(3), 2, sparse=True) + sage: a = V([0,1]) + sage: b = V([1,0]) + sage: a < b True """ a = sorted((left)._entries.iteritems()) @@ -5062,14 +5062,14 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: V = VectorSpace(GF(17), 10000000, sparse=True) # optional - sage.libs.pari - sage: w = V(0) # optional - sage.libs.pari - sage: w[39893] = 20 # optional - sage.libs.pari - sage: w[39893] # optional - sage.libs.pari + sage: V = VectorSpace(GF(17), 10000000, sparse=True) + sage: w = V(0) + sage: w[39893] = 20 + sage: w[39893] 3 - sage: w[39000:39003] = [4, 5, 6]; w[39000:39003] # optional - sage.libs.pari + sage: w[39000:39003] = [4, 5, 6]; w[39000:39003] (4, 5, 6) - sage: parent(w[39893]) # optional - sage.libs.pari + sage: parent(w[39893]) Finite Field of size 17 sage: w[39893] = sqrt(2) # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): diff --git a/src/sage/modules/free_module_homspace.py b/src/sage/modules/free_module_homspace.py index bcbe44f0d6b..79c2b226436 100644 --- a/src/sage/modules/free_module_homspace.py +++ b/src/sage/modules/free_module_homspace.py @@ -54,7 +54,7 @@ See :trac:`13321`:: - sage: (GF(7)^2).hom([[20, 0], [0, 21]], ZZ^2) # optional - sage.libs.pari + sage: (GF(7)^2).hom([[20, 0], [0, 21]], ZZ^2) Traceback (most recent call last): ... TypeError: nontrivial morphisms require a coercion map from the base ring diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index ca25ce9ed58..90cf9825dc5 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -124,9 +124,9 @@ def FreeQuadraticModule(base_ring, rank, inner_product_matrix, Check for :trac:`10577`:: - sage: m = matrix.diagonal(GF(2), [1,1]) # optional - sage.libs.pari - sage: V2 = VectorSpace(GF(2), 2, inner_product_matrix=m) # optional - sage.libs.pari - sage: deepcopy(V2) # optional - sage.libs.pari + sage: m = matrix.diagonal(GF(2), [1,1]) + sage: V2 = VectorSpace(GF(2), 2, inner_product_matrix=m) + sage: deepcopy(V2) Ambient quadratic space of dimension 2 over Finite Field of size 2 Inner product matrix: [1 0] @@ -702,7 +702,7 @@ def __init__(self, base_field, dimension, degree, inner_product_matrix, sparse=F Inner product matrix: [2 1] [1 2] - sage: FreeModule(FiniteField(2), 7, inner_product_matrix=1) # optional - sage.libs.pari + sage: FreeModule(FiniteField(2), 7, inner_product_matrix=1) Ambient quadratic space of dimension 7 over Finite Field of size 2 Inner product matrix: [1 0 0 0 0 0 0] @@ -739,12 +739,12 @@ def span(self, gens, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari - sage: W = V.subspace([[2,3,4]]); W # optional - sage.libs.pari + sage: V = VectorSpace(GF(7), 3) + sage: W = V.subspace([[2,3,4]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span([[1,1,1]]) # optional - sage.libs.pari + sage: W.span([[1,1,1]]) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 1] @@ -779,12 +779,12 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): EXAMPLES:: - sage: V = VectorSpace(GF(7), 3) # optional - sage.libs.pari - sage: W = V.subspace([[2,3,4]]); W # optional - sage.libs.pari + sage: V = VectorSpace(GF(7), 3) + sage: W = V.subspace([[2,3,4]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] - sage: W.span_of_basis([[2,2,2], [3,3,0]]) # optional - sage.libs.pari + sage: W.span_of_basis([[2,2,2], [3,3,0]]) Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] @@ -793,7 +793,7 @@ def span_of_basis(self, basis, check=True, already_echelonized=False): The basis vectors must be linearly independent or a ``ValueError`` exception is raised:: - sage: W.span_of_basis([[2,2,2], [3,3,3]]) # optional - sage.libs.pari + sage: W.span_of_basis([[2,2,2], [3,3,3]]) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. @@ -876,7 +876,7 @@ def _latex_(self): sage: latex(QQ^3) # indirect doctest \Bold{Q}^{3} - sage: A = GF(5)^20; latex(A) # optional - sage.libs.pari + sage: A = GF(5)^20; latex(A) \Bold{F}_{5}^{20} sage: A = PolynomialRing(QQ,3,'x')^20; latex(A) @@ -943,7 +943,7 @@ def __init__(self, base_ring, rank, inner_product_matrix, sparse=False): """ EXAMPLES:: - sage: FreeModule(PolynomialRing(GF(5),'x'), 3) # optional - sage.libs.pari + sage: FreeModule(PolynomialRing(GF(5),'x'), 3) Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 5 """ @@ -1356,7 +1356,7 @@ def change_ring(self, R): Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [ 1 1/4 1/2] - sage: W.change_ring(GF(7)) # optional - sage.libs.pari + sage: W.change_ring(GF(7)) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 2 4] @@ -1365,8 +1365,8 @@ def change_ring(self, R): sage: N.inner_product_matrix() [ 1 -1] [ 2 5] - sage: Np = N.change_ring(RDF) # optional - sage.libs.pari - sage: Np.inner_product_matrix() # optional - sage.libs.pari + sage: Np = N.change_ring(RDF) + sage: Np.inner_product_matrix() [ 1.0 -1.0] [ 2.0 5.0] """ diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index c36e1d96f0a..aee4d8ce938 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -45,9 +45,9 @@ We make a large zero vector:: We multiply a vector by a matrix:: - sage: a = (GF(97)^5)(range(5)) # optional - sage.libs.pari - sage: m = matrix(GF(97), 5, range(25)) # optional - sage.libs.pari - sage: a*m # optional - sage.libs.pari + sage: a = (GF(97)^5)(range(5)) + sage: m = matrix(GF(97), 5, range(25)) + sage: a*m (53, 63, 73, 83, 93) TESTS:: @@ -74,21 +74,21 @@ TESTS:: sage: ~v[0] # optional - sage.libs.pari 1482786336 - sage: w = vector(GF(11), [-1,0,0,0]) # optional - sage.libs.pari - sage: w.set_immutable() # optional - sage.libs.pari - sage: isinstance(hash(w), int) # optional - sage.libs.pari + sage: w = vector(GF(11), [-1,0,0,0]) + sage: w.set_immutable() + sage: isinstance(hash(w), int) True Test that :trac:`28042` is fixed:: sage: p = 193379 - sage: K = GF(p) # optional - sage.libs.pari - sage: a = K(1) # optional - sage.libs.pari - sage: b = K(191495) # optional - sage.libs.pari - sage: c = K(109320) # optional - sage.libs.pari - sage: d = K(167667) # optional - sage.libs.pari - sage: e = 103937 # optional - sage.libs.pari - sage: a*c + b*d - e # optional - sage.libs.pari + sage: K = GF(p) # optional - sage.rings.finite_rings + sage: a = K(1) # optional - sage.rings.finite_rings + sage: b = K(191495) # optional - sage.rings.finite_rings + sage: c = K(109320) # optional - sage.rings.finite_rings + sage: d = K(167667) # optional - sage.rings.finite_rings + sage: e = 103937 + sage: a*c + b*d - e # optional - sage.rings.finite_rings 102041 sage: vector([a,b]) * vector([c,d]) - e # optional - sage.libs.pari 102041 @@ -197,15 +197,15 @@ cdef class Vector_modn_dense(free_module_element.FreeModuleElement): """ EXAMPLES:: - sage: v = vector(GF(5), [0,0,0,0]) # optional - sage.libs.pari - sage: v == 0 # optional - sage.libs.pari + sage: v = vector(GF(5), [0,0,0,0]) + sage: v == 0 True - sage: v == 1 # optional - sage.libs.pari + sage: v == 1 False - sage: v == v # optional - sage.libs.pari + sage: v == v True - sage: w = vector(GF(11), [-1,0,0,0]) # optional - sage.libs.pari - sage: w == w # optional - sage.libs.pari + sage: w = vector(GF(11), [-1,0,0,0]) + sage: w == w True """ cdef Py_ssize_t i diff --git a/src/sage/modules/vector_space_homspace.py b/src/sage/modules/vector_space_homspace.py index 8d6dafafa67..c15f0f59285 100644 --- a/src/sage/modules/vector_space_homspace.py +++ b/src/sage/modules/vector_space_homspace.py @@ -38,9 +38,9 @@ a list of matrix representations, where these matrix representatives are relative to the bases of the domain and codomain. :: - sage: K = Hom(GF(3)^2, GF(3)^2) # optional - sage.libs.pari - sage: B = K.basis() # optional - sage.libs.pari - sage: for f in B: # optional - sage.libs.pari + sage: K = Hom(GF(3)^2, GF(3)^2) + sage: B = K.basis() + sage: for f in B: ....: print(f) ....: print("\n") Vector space morphism represented by the matrix: @@ -359,10 +359,10 @@ def __call__(self, A, check=True, **kwds): TESTS:: - sage: V = GF(3)^0 # optional - sage.libs.pari - sage: W = GF(3)^1 # optional - sage.libs.pari - sage: H = V.Hom(W) # optional - sage.libs.pari - sage: H.zero().is_zero() # optional - sage.libs.pari + sage: V = GF(3)^0 + sage: W = GF(3)^1 + sage: H = V.Hom(W) + sage: H.zero().is_zero() True Previously the above code resulted in a TypeError because the From 649a959bd930609017efe8419414a9b122d1ceb4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 27 Jun 2023 18:17:34 -0700 Subject: [PATCH 60/99] sage.matrix: ./sage -fixdoctests --long --distribution 'sagemath-modules' --only-tags --probe=sage.rings.finite_rings --overwrite src/sage/matrix/*.{py,pyx} --- src/sage/matrix/args.pyx | 14 +- src/sage/matrix/berlekamp_massey.py | 2 +- src/sage/matrix/constructor.pyx | 6 +- src/sage/matrix/echelon_matrix.pyx | 16 +- src/sage/matrix/matrix0.pyx | 42 ++-- src/sage/matrix/matrix1.pyx | 12 +- src/sage/matrix/matrix2.pyx | 324 ++++++++++++++-------------- src/sage/matrix/matrix_space.py | 148 ++++++------- src/sage/matrix/special.py | 24 +-- src/sage/matrix/symplectic_basis.py | 28 +-- src/sage/matrix/tests.py | 4 +- 11 files changed, 311 insertions(+), 309 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index 3a44e30d3d1..1b911018f83 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -760,10 +760,10 @@ cdef class MatrixArgs: :: - sage: ma = MatrixArgs(GF(2), 2, 3, L) # optional - sage.libs.pari - sage: ma.dict(convert=False) # optional - sage.libs.pari + sage: ma = MatrixArgs(GF(2), 2, 3, L) + sage: ma.dict(convert=False) {(0, 1): 1, (0, 2): 2, (1, 0): 3, (1, 1): 4, (1, 2): 5} - sage: ma.dict() # optional - sage.libs.pari + sage: ma.dict() {(0, 1): 1, (1, 0): 1, (1, 2): 1} """ self.finalize() @@ -1352,12 +1352,12 @@ cpdef MatrixArgs MatrixArgs_init(space, entries): EXAMPLES:: sage: from sage.matrix.args import MatrixArgs_init - sage: S = MatrixSpace(GF(2), 2, 4) # optional - sage.libs.pari - sage: ma = MatrixArgs_init(S, {(1, 3): 7}) # optional - sage.libs.pari - sage: M = ma.matrix(); M # optional - sage.libs.pari + sage: S = MatrixSpace(GF(2), 2, 4) + sage: ma = MatrixArgs_init(S, {(1, 3): 7}) + sage: M = ma.matrix(); M [0 0 0 0] [0 0 0 1] - sage: parent(M) is S # optional - sage.libs.pari + sage: parent(M) is S True """ cdef MatrixArgs ret diff --git a/src/sage/matrix/berlekamp_massey.py b/src/sage/matrix/berlekamp_massey.py index d101e1bed95..11fff79dbba 100644 --- a/src/sage/matrix/berlekamp_massey.py +++ b/src/sage/matrix/berlekamp_massey.py @@ -55,7 +55,7 @@ def berlekamp_massey(a): sage: from sage.matrix.berlekamp_massey import berlekamp_massey sage: berlekamp_massey([1,2,1,2,1,2]) x^2 - 1 - sage: berlekamp_massey([GF(7)(1), 19, 1, 19]) # optional - sage.libs.pari + sage: berlekamp_massey([GF(7)(1), 19, 1, 19]) x^2 + 6 sage: berlekamp_massey([2,2,1,2,1,191,393,132]) x^4 - 36727/11711*x^3 + 34213/5019*x^2 + 7024942/35133*x - 335813/1673 diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index b33e84086c7..0cdbccbec4a 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -185,10 +185,10 @@ def matrix(*args, **kwds): sage: m = matrix(v); m; m.parent() [ 1 10 100] Full MatrixSpace of 1 by 3 dense matrices over Integer Ring - sage: m = matrix(GF(7), v); m; m.parent() # optional - sage.libs.pari + sage: m = matrix(GF(7), v); m; m.parent() [1 3 2] Full MatrixSpace of 1 by 3 dense matrices over Finite Field of size 7 - sage: m = matrix(GF(7), 3, 1, v); m; m.parent() # optional - sage.libs.pari + sage: m = matrix(GF(7), 3, 1, v); m; m.parent() [1] [3] [2] @@ -546,7 +546,7 @@ def matrix(*args, **kwds): over Univariate Polynomial Ring in x over Integer Ring sage: matrix(ZZ, 10, 10, range(100)).parent() Full MatrixSpace of 10 by 10 dense matrices over Integer Ring - sage: m = matrix(GF(7), [[1/3,2/3,1/2], [3/4,4/5,7]]); m; m.parent() # optional - sage.libs.pari + sage: m = matrix(GF(7), [[1/3,2/3,1/2], [3/4,4/5,7]]); m; m.parent() [5 3 4] [6 5 0] Full MatrixSpace of 2 by 3 dense matrices over Finite Field of size 7 diff --git a/src/sage/matrix/echelon_matrix.pyx b/src/sage/matrix/echelon_matrix.pyx index 59127dfdaef..e46c1381439 100644 --- a/src/sage/matrix/echelon_matrix.pyx +++ b/src/sage/matrix/echelon_matrix.pyx @@ -48,8 +48,8 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, EXAMPLES:: sage: from sage.matrix.echelon_matrix import reduced_echelon_matrix_iterator - sage: it = reduced_echelon_matrix_iterator(GF(2), 2, 3) # optional - sage.libs.pari - sage: for m in it: # optional - sage.libs.pari + sage: it = reduced_echelon_matrix_iterator(GF(2), 2, 3) + sage: for m in it: ....: print(m) ....: print(m.pivots()) ....: print("*******") @@ -87,10 +87,10 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, Testing cardinalities:: sage: q = 71 - sage: F = GF(q) # optional - sage.libs.pari - sage: len(list(reduced_echelon_matrix_iterator(F, 1, 3, copy=False))) == q**2+q+1 # optional - sage.libs.pari + sage: F = GF(q) + sage: len(list(reduced_echelon_matrix_iterator(F, 1, 3, copy=False))) == q**2+q+1 True - sage: len(list(reduced_echelon_matrix_iterator(F, 2, 3, copy=False))) == q**2+q+1 # optional - sage.libs.pari + sage: len(list(reduced_echelon_matrix_iterator(F, 2, 3, copy=False))) == q**2+q+1 True Testing options:: @@ -98,10 +98,10 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, copy=False) # optional - sage.libs.pari sage: next(it) is next(it) # optional - sage.libs.pari True - sage: for a in it: pass # optional - sage.libs.pari + sage: for a in it: pass - sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, set_immutable=True) # optional - sage.libs.pari - sage: all(a.is_immutable() and a.echelon_form() == a for a in it) # optional - sage.libs.pari + sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, set_immutable=True) # optional - sage.rings.finite_rings + sage: all(a.is_immutable() and a.echelon_form() == a for a in it) True """ cdef Matrix m0,m,mm diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index d429a04892f..939c99ca6e1 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -4633,8 +4633,8 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: m = matrix(GF(7), 5, range(25)) # optional - sage.libs.pari - sage: m.rank() # optional - sage.libs.pari + sage: m = matrix(GF(7), 5, range(25)) + sage: m.rank() 2 Rank is not implemented over the integers modulo a composite yet.:: @@ -4650,10 +4650,10 @@ cdef class Matrix(sage.structure.element.Matrix): We should be able to compute the rank of a matrix whose entries are polynomials over a finite field (:trac:`5014`):: - sage: P. = PolynomialRing(GF(17)) # optional - sage.libs.pari - sage: m = matrix(P, [[ 6*x^2 + 8*x + 12, 10*x^2 + 4*x + 11], # optional - sage.libs.pari + sage: P. = PolynomialRing(GF(17)) + sage: m = matrix(P, [[ 6*x^2 + 8*x + 12, 10*x^2 + 4*x + 11], ....: [8*x^2 + 12*x + 15, 8*x^2 + 9*x + 16]]) - sage: m.rank() # optional - sage.libs.pari + sage: m.rank() 2 """ x = self.fetch('rank') @@ -4885,10 +4885,10 @@ cdef class Matrix(sage.structure.element.Matrix): Over finite fields:: - sage: A = matrix(GF(59), 3, [10,56,39,53,56,33,58,24,55]) # optional - sage.libs.pari - sage: A.multiplicative_order() # optional - sage.libs.pari + sage: A = matrix(GF(59), 3, [10,56,39,53,56,33,58,24,55]) + sage: A.multiplicative_order() # optional - sage.rings.finite_rings 580 - sage: (A^580).is_one() # optional - sage.libs.pari + sage: (A^580).is_one() True sage: B = matrix(GF(10007^3, 'b'), 0) # optional - sage.libs.pari @@ -5394,27 +5394,27 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLE of matrix times matrix over different base rings:: sage: a = matrix(ZZ, 2, 2, range(4)) - sage: b = matrix(GF(7), 2, 2, range(4)) # optional - sage.libs.pari + sage: b = matrix(GF(7), 2, 2, range(4)) sage: c = matrix(QQ, 2, 2, range(4)) - sage: d = a * b; d # optional - sage.libs.pari + sage: d = a * b; d [2 3] [6 4] - sage: parent(d) # optional - sage.libs.pari + sage: parent(d) Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 - sage: parent(b * a) # optional - sage.libs.pari + sage: parent(b * a) Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 sage: d = a * c; d [ 2 3] [ 6 11] sage: parent(d) Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: d = b + c # optional - sage.libs.pari + sage: d = b + c Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: 'Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7' and 'Full MatrixSpace of 2 by 2 dense matrices over Rational Field' - sage: d = b + c.change_ring(GF(7)); d # optional - sage.libs.pari + sage: d = b + c.change_ring(GF(7)); d [0 2] [4 6] @@ -5422,16 +5422,16 @@ cdef class Matrix(sage.structure.element.Matrix): other is dense (in such mixed cases, the result is always dense):: sage: a = matrix(ZZ, 2, 2, range(4), sparse=True) - sage: b = matrix(GF(7), 2, 2, range(4), sparse=False) # optional - sage.libs.pari - sage: c = a * b; c # optional - sage.libs.pari + sage: b = matrix(GF(7), 2, 2, range(4), sparse=False) + sage: c = a * b; c [2 3] [6 4] - sage: parent(c) # optional - sage.libs.pari + sage: parent(c) Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 - sage: c = b * a; c # optional - sage.libs.pari + sage: c = b * a; c [2 3] [6 4] - sage: parent(c) # optional - sage.libs.pari + sage: parent(c) Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7 EXAMPLE of matrix multiplication over a noncommutative base ring:: @@ -5640,10 +5640,10 @@ cdef class Matrix(sage.structure.element.Matrix): sage: m = matrix(Zmod(2^100),2,[2,1,3,3]) sage: type(m) - sage: (~m)*m + sage: (~m)*m # optional - sage.libs.pari [1 0] [0 1] - sage: ~m + sage: ~m # optional - sage.libs.pari [ 1 422550200076076467165567735125] [1267650600228229401496703205375 422550200076076467165567735126] diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index a19a3c73ab0..59f40e2d329 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -5,8 +5,8 @@ For design documentation see :mod:`sage.matrix.docs`. TESTS:: - sage: A = Matrix(GF(5), 3, 3, srange(9)) # optional - sage.libs.pari - sage: TestSuite(A).run() # optional - sage.libs.pari + sage: A = Matrix(GF(5), 3, 3, srange(9)) + sage: TestSuite(A).run() """ #***************************************************************************** @@ -626,9 +626,9 @@ cdef class Matrix(Matrix0): sage: sage_input(matrix(QQ, 3, 3, [5..13])/7, verify=True) # Verified matrix(QQ, [[5/7, 6/7, 1], [8/7, 9/7, 10/7], [11/7, 12/7, 13/7]]) - sage: M = MatrixSpace(GF(5), 50, 50, sparse=True).random_element(density=0.002) # optional - sage.libs.pari - sage: input = sage_input(M, verify=True) # optional - sage.libs.pari - sage: sage_eval(input) == M # optional - sage.libs.pari + sage: M = MatrixSpace(GF(5), 50, 50, sparse=True).random_element(density=0.002) + sage: input = sage_input(M, verify=True) + sage: sage_eval(input) == M True sage: from sage.misc.sage_input import SageInputBuilder sage: matrix(RDF, [[3, 1], [4, 1]])._sage_input_(SageInputBuilder(), False) @@ -2456,7 +2456,7 @@ cdef class Matrix(Matrix0): Specify a different base ring for the output:: - sage: M.zero_pattern_matrix(GF(2)).base_ring() # optional - sage.libs.pari + sage: M.zero_pattern_matrix(GF(2)).base_ring() Finite Field of size 2 Examples for different base rings for ``self``:: diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 645e6907be1..17397cf6a85 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -350,7 +350,7 @@ cdef class Matrix(Matrix1): (-1, 2, 0, 0) sage: A = Matrix(Zmod(128), 2, 3, [5, 29, 33, 64, 0, 7]) sage: B = vector(Zmod(128), [31,39,56]) - sage: X = A.solve_left(B); X + sage: X = A.solve_left(B); X # optional - sage.libs.pari (19, 83) sage: X * A == B True @@ -1132,13 +1132,13 @@ cdef class Matrix(Matrix1): :: - sage: G = matrix(GF(3), 2, [0, 1, 2, 2]) # optional - sage.libs.pari + sage: G = matrix(GF(3), 2, [0, 1, 2, 2]) sage: H = matrix(ZZ, 2, [1, 2, 3, 4]) - sage: J = G.elementwise_product(H) # optional - sage.libs.pari - sage: J # optional - sage.libs.pari + sage: J = G.elementwise_product(H) + sage: J [0 2] [0 2] - sage: J.parent() # optional - sage.libs.pari + sage: J.parent() Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 @@ -1181,8 +1181,8 @@ cdef class Matrix(Matrix1): multiplication makes sense. This will raise an error. :: sage: A = matrix(QQ, 3, 2, range(6)) - sage: B = matrix(GF(3), 3, [2]*6) # optional - sage.libs.pari - sage: A.elementwise_product(B) # optional - sage.libs.pari + sage: B = matrix(GF(3), 3, [2]*6) + sage: A.elementwise_product(B) Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -1762,20 +1762,20 @@ cdef class Matrix(Matrix1): An example with an exotic matrix (for which only Butera-Pernici and Ryser algorithms are available):: - sage: R. = PolynomialRing(GF(5)) # optional - sage.libs.pari - sage: A = matrix(R, [[1, x, y], [x*y, x**2+y, 0]]) # optional - sage.libs.pari - sage: A.rook_vector(algorithm="ButeraPernici") # optional - sage.libs.pari + sage: R. = PolynomialRing(GF(5)) + sage: A = matrix(R, [[1, x, y], [x*y, x**2+y, 0]]) + sage: A.rook_vector(algorithm="ButeraPernici") [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: A.rook_vector(algorithm="Ryser") # optional - sage.libs.pari + sage: A.rook_vector(algorithm="Ryser") [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: A.rook_vector(algorithm="Godsil") # optional - sage.libs.pari + sage: A.rook_vector(algorithm="Godsil") Traceback (most recent call last): ... ValueError: coefficients must be zero or one, but we have 'x' in position (0,1). - sage: B = A.transpose() # optional - sage.libs.pari - sage: B.rook_vector(algorithm="ButeraPernici") # optional - sage.libs.pari + sage: B = A.transpose() + sage: B.rook_vector(algorithm="ButeraPernici") [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] - sage: B.rook_vector(algorithm="Ryser") # optional - sage.libs.pari + sage: B.rook_vector(algorithm="Ryser") [1, x^2 + x*y + x + 2*y + 1, 2*x^2*y + x*y^2 + x^2 + y^2 + y] TESTS:: @@ -1920,17 +1920,17 @@ cdef class Matrix(Matrix1): :: - sage: k = GF(37) # optional - sage.libs.pari - sage: P. = PolynomialRing(k) # optional - sage.libs.pari - sage: A = Matrix(P, 2, 3, [x0*x1, x0, x1, x2, x2 + 16, x2 + 5*x1]) # optional - sage.libs.pari - sage: A.minors(2) # optional - sage.libs.pari + sage: k = GF(37) + sage: P. = PolynomialRing(k) + sage: A = Matrix(P, 2, 3, [x0*x1, x0, x1, x2, x2 + 16, x2 + 5*x1]) + sage: A.minors(2) # optional - sage.rings.finite_rings [x0*x1*x2 + 16*x0*x1 - x0*x2, 5*x0*x1^2 + x0*x1*x2 - x1*x2, 5*x0*x1 + x0*x2 - x1*x2 - 16*x1] This test addresses an issue raised at :trac:`20512`:: - sage: A.minors(0)[0].parent() == P # optional - sage.libs.pari + sage: A.minors(0)[0].parent() == P True """ from sage.combinat.combination import Combinations @@ -2041,8 +2041,8 @@ cdef class Matrix(Matrix1): We verify that :trac:`10063` is resolved:: - sage: A = GF(2)['x,y,z'] # optional - sage.libs.pari - sage: A.inject_variables() # optional - sage.libs.pari + sage: A = GF(2)['x,y,z'] + sage: A.inject_variables() Defining x, y, z sage: R = A.quotient(x^2 + 1).quotient(y^2 + 1).quotient(z^2 + 1) # optional - sage.libs.pari sage: R.inject_variables() # optional - sage.libs.pari @@ -2235,11 +2235,11 @@ cdef class Matrix(Matrix1): sage: A.quantum_determinant(q^-2) 7*q^-6 + q^-4 + q^-2 + 5 - sage: S. = PolynomialRing(GF(7)) # optional - sage.libs.pari - sage: R. = LaurentPolynomialRing(S) # optional - sage.libs.pari - sage: MS = MatrixSpace(S, 3, sparse=True) # optional - sage.libs.pari - sage: A = MS([[x, y, 3], [4, 2+y, x^2], [0, 1-x, x+y]]) # optional - sage.libs.pari - sage: A.det() # optional - sage.libs.pari + sage: S. = PolynomialRing(GF(7)) + sage: R. = LaurentPolynomialRing(S) + sage: MS = MatrixSpace(S, 3, sparse=True) + sage: A = MS([[x, y, 3], [4, 2+y, x^2], [0, 1-x, x+y]]) + sage: A.det() # optional - sage.rings.finite_rings x^4 - x^3 + x^2*y + x*y^2 + 2*x^2 - 2*x*y + 3*y^2 + 2*x - 2 sage: A.quantum_determinant() # optional - sage.libs.pari (2*x - 2)*q^2 + (x^4 - x^3 + 3*x*y + 3*y^2)*q + x^2*y + x*y^2 + 2*x^2 + 2*x*y @@ -2413,13 +2413,13 @@ cdef class Matrix(Matrix1): In order to use the Bär-Faddeev-LeVerrier algorithm, the base ring must have characteristic zero:: - sage: A = matrix(GF(5), [(0, 3, 4, 1, 3, 4), # optional - sage.libs.pari + sage: A = matrix(GF(5), [(0, 3, 4, 1, 3, 4), ....: (2, 0, 2, 0, 1, 0), ....: (1, 3, 0, 4, 1, 0), ....: (4, 0, 1, 0, 2, 0), ....: (2, 4, 4, 3, 0, 0), ....: (1, 0, 0, 0, 0, 0)]) - sage: A.pfaffian(algorithm='bfl') # optional - sage.libs.pari + sage: A.pfaffian(algorithm='bfl') Traceback (most recent call last): ... TypeError: Bär-Faddeev-LeVerrier algorithm not applicable, @@ -2615,12 +2615,12 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: m = matrix(ZZ, 3, 3, range(9)) - sage: phi = ZZ.hom(GF(5)) # optional - sage.libs.pari - sage: m.apply_morphism(phi) # optional - sage.libs.pari + sage: phi = ZZ.hom(GF(5)) + sage: m.apply_morphism(phi) [0 1 2] [3 4 0] [1 2 3] - sage: parent(m.apply_morphism(phi)) # optional - sage.libs.pari + sage: parent(m.apply_morphism(phi)) Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 5 @@ -2664,9 +2664,9 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: m = matrix(ZZ, 3, 3, range(9)) - sage: k. = GF(9) # optional - sage.libs.pari - sage: f = lambda x: k(x) # optional - sage.libs.pari - sage: n = m.apply_map(f); n # optional - sage.libs.pari + sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: f = lambda x: k(x) + sage: n = m.apply_map(f); n # optional - sage.rings.finite_rings [0 1 2] [0 1 2] [0 1 2] @@ -2678,9 +2678,9 @@ cdef class Matrix(Matrix1): :: - sage: s = GF(3) # optional - sage.libs.pari - sage: f = lambda x: s(x) # optional - sage.libs.pari - sage: n = m.apply_map(f, k); n # optional - sage.libs.pari + sage: s = GF(3) + sage: f = lambda x: s(x) + sage: n = m.apply_map(f, k); n # optional - sage.rings.finite_rings [0 1 2] [0 1 2] [0 1 2] @@ -2992,8 +2992,8 @@ cdef class Matrix(Matrix1): computation of the characteristic polynomial succeeds as follows:: sage: R. = QQ[] - sage: S. = R.quo((b^3)) - sage: A = matrix(S, [[x*y^2,2*x],[2,x^10*y]]) + sage: S. = R.quo((b^3)) # optional - sage.rings.function_field + sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) sage: A [ x*y^2 2*x] [ 2 x^10*y] @@ -3573,7 +3573,7 @@ cdef class Matrix(Matrix1): Z^3 - 12*Z^2 - 18*Z sage: matrix(ZZ,3,3,range(9))._charpoly_hessenberg('Z') Z^3 - 12*Z^2 - 18*Z - sage: matrix(GF(7), 3, 3,range(9))._charpoly_hessenberg('Z') # optional - sage.libs.pari + sage: matrix(GF(7), 3, 3, range(9))._charpoly_hessenberg('Z') Z^3 + 2*Z^2 + 3*Z sage: matrix(QQ['x'],3,3,range(9))._charpoly_hessenberg('Z') Z^3 - 12*Z^2 - 18*Z @@ -4130,15 +4130,15 @@ cdef class Matrix(Matrix1): :meth:`~sage.matrix.matrix_mod2_dense.Matrix_mod2_dense._right_kernel_matrix` method. There are no options for the algorithm used. :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], # optional - sage.libs.pari + sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], ....: [1, 0, 0, 0, 1, 1,], ....: [1, 0, 0, 0, 1, 1]]) - sage: E = A.right_kernel_matrix(algorithm='default', format='echelon'); E # optional - sage.libs.pari + sage: E = A.right_kernel_matrix(algorithm='default', format='echelon'); E [1 0 0 0 0 1] [0 1 1 0 0 0] [0 0 0 1 0 0] [0 0 0 0 1 1] - sage: A*E.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.libs.pari + sage: A*E.transpose() == zero_matrix(GF(2), 3, 4) True Since GF(2) is a field we can route this computation to the generic @@ -4146,22 +4146,22 @@ cdef class Matrix(Matrix1): keywords, 'pluq', 'default' and unspecified, all have the same effect as there is no optional behavior. :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], # optional - sage.libs.pari - ....: [1, 0, 0, 0, 1, 1,], - ....: [1, 0, 0, 0, 1, 1]]) - sage: P = A.right_kernel_matrix(algorithm='generic', basis='pivot'); P # optional - sage.libs.pari + sage: A = matrix(GF(2), [[0, 1, 1, 0, 0, 0], + ....: [1, 0, 0, 0, 1, 1,], + ....: [1, 0, 0, 0, 1, 1]]) + sage: P = A.right_kernel_matrix(algorithm='generic', basis='pivot'); P [0 1 1 0 0 0] [0 0 0 1 0 0] [1 0 0 0 1 0] [1 0 0 0 0 1] - sage: A*P.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.libs.pari + sage: A*P.transpose() == zero_matrix(GF(2), 3, 4) True - sage: DP = A.right_kernel_matrix(algorithm='default', basis='pivot'); DP # optional - sage.libs.pari + sage: DP = A.right_kernel_matrix(algorithm='default', basis='pivot'); DP [0 1 1 0 0 0] [0 0 0 1 0 0] [1 0 0 0 1 0] [1 0 0 0 0 1] - sage: A*DP.transpose() == zero_matrix(GF(2), 3, 4) # optional - sage.libs.pari + sage: A*DP.transpose() == zero_matrix(GF(2), 3, 4) True sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') # optional - sage.libs.pari [1 0 0 0 0 1] @@ -4171,9 +4171,9 @@ cdef class Matrix(Matrix1): We test that the mod 2 code is called for matrices over GF(2). :: - sage: A = matrix(GF(2),[[0, 1, 1, 0, 0, 0], # optional - sage.libs.pari - ....: [1, 0, 0, 0, 1, 1,], - ....: [1, 0, 0, 0, 1, 1]]) + sage: A = matrix(GF(2), [[0, 1, 1, 0, 0, 0], + ....: [1, 0, 0, 0, 1, 1,], + ....: [1, 0, 0, 0, 1, 1]]) sage: set_verbose(1) sage: A.right_kernel(algorithm='default') # optional - sage.libs.pari verbose ... @@ -4402,8 +4402,8 @@ cdef class Matrix(Matrix1): sage: A.right_kernel_matrix() [1 0] [0 1] - sage: A = matrix(FiniteField(7), 2, 0) # optional - sage.libs.pari - sage: A.right_kernel_matrix().parent() # optional - sage.libs.pari + sage: A = matrix(FiniteField(7), 2, 0) + sage: A.right_kernel_matrix().parent() Full MatrixSpace of 0 by 0 dense matrices over Finite Field of size 7 TESTS: @@ -4425,7 +4425,7 @@ cdef class Matrix(Matrix1): Traceback (most recent call last): ... ValueError: matrix kernel algorithm 'junk' not recognized - sage: matrix(GF(2), 2, 2).right_kernel_matrix(algorithm='padic') # optional - sage.libs.pari + sage: matrix(GF(2), 2, 2).right_kernel_matrix(algorithm='padic') Traceback (most recent call last): ... ValueError: 'padic' matrix kernel algorithm only available over the rationals and the integers, not over Finite Field of size 2 @@ -4737,8 +4737,8 @@ cdef class Matrix(Matrix1): installed. :: sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense - sage: B = Matrix_generic_dense(A.parent(), A.list(), False, False) # optional - sage.libs.pari - sage: P = B.right_kernel(basis='pivot'); P # optional - sage.libs.pari + sage: B = Matrix_generic_dense(A.parent(), A.list(), False, False) + sage: P = B.right_kernel(basis='pivot'); P # optional - sage.rings.finite_rings Vector space of degree 4 and dimension 2 over Finite Field in a of size 5^2 User basis matrix: @@ -4750,7 +4750,7 @@ cdef class Matrix(Matrix1): sage: B.parent()(B.list()) * P.basis_matrix().transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari True - sage: K == P # optional - sage.libs.pari + sage: K == P True Over number fields, PARI is used by default, but general-purpose code @@ -5041,11 +5041,11 @@ cdef class Matrix(Matrix1): Over a finite field, with a basis matrix in "pivot" format. :: - sage: A = matrix(FiniteField(7), [[5, 0, 5, 2, 4], # optional - sage.libs.pari + sage: A = matrix(FiniteField(7), [[5, 0, 5, 2, 4], ....: [1, 3, 2, 3, 6], ....: [1, 1, 6, 5, 3], ....: [2, 5, 6, 0, 0]]) - sage: A.kernel(basis='pivot') # optional - sage.libs.pari + sage: A.kernel(basis='pivot') Vector space of degree 4 and dimension 2 over Finite Field of size 7 User basis matrix: [5 2 1 0] @@ -6042,8 +6042,8 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, 2, range(4)) sage: A._eigenspace_format(None) == 'all' # optional - sage.rings.number_field True - sage: B = matrix(GF(13), 2, range(4)) # optional - sage.libs.pari - sage: B._eigenspace_format(None) # optional - sage.libs.pari + sage: B = matrix(GF(13), 2, range(4)) + sage: B._eigenspace_format(None) # optional - sage.rings.finite_rings 'all' Subrings are promoted to fraction fields and then checked for the @@ -6704,8 +6704,8 @@ cdef class Matrix(Matrix1): The method also works for matrices over finite fields:: - sage: M = matrix(GF(3), [[0,1,1], [1,2,0], [2,0,1]]) # optional - sage.libs.pari - sage: ev = sorted(M.eigenvalues()); ev # optional - sage.libs.pari + sage: M = matrix(GF(3), [[0,1,1], [1,2,0], [2,0,1]]) + sage: ev = sorted(M.eigenvalues()); ev # optional - sage.rings.finite_rings [2*z3, 2*z3 + 1, 2*z3 + 2] Similarly as in the case of ``QQbar``, the eigenvalues belong to some @@ -7658,8 +7658,8 @@ cdef class Matrix(Matrix1): We compute an echelon form both over a domain and fraction field:: sage: R. = QQ[] - sage: a = matrix(R, 2, [x,y,x,y]) - sage: a.echelon_form() # not very useful? -- why two copies of the same row? + sage: a = matrix(R, 2, [x,y, x,y]) + sage: a.echelon_form() # not very useful? -- why two copies of the same row? # optional - sage.rings.function_field [x y] [x y] @@ -7816,13 +7816,13 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: MS = MatrixSpace(GF(19), 2, 3) # optional - sage.libs.pari - sage: C = MS.matrix([1,2,3,4,5,6]) # optional - sage.libs.pari - sage: C.rank() # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(19), 2, 3) + sage: C = MS.matrix([1,2,3,4,5,6]) + sage: C.rank() 2 - sage: C.nullity() # optional - sage.libs.pari + sage: C.nullity() 0 - sage: C.echelon_form() # optional - sage.libs.pari + sage: C.echelon_form() [ 1 0 18] [ 0 1 2] @@ -7830,7 +7830,7 @@ cdef class Matrix(Matrix1): the transformation matrix, so the ``transformation`` option is ignored:: - sage: C.echelon_form(transformation=True) # optional - sage.libs.pari + sage: C.echelon_form(transformation=True) [ 1 0 18] [ 0 1 2] @@ -8256,20 +8256,20 @@ cdef class Matrix(Matrix1): Subdivided, or not, the result is immutable, so make a copy if you want to make changes. :: - sage: A = matrix(FiniteField(7), [[2,0,3], [5,5,3], [5,6,5]]) # optional - sage.libs.pari - sage: E = A.extended_echelon_form() # optional - sage.libs.pari - sage: E.is_mutable() # optional - sage.libs.pari + sage: A = matrix(FiniteField(7), [[2,0,3], [5,5,3], [5,6,5]]) + sage: E = A.extended_echelon_form() + sage: E.is_mutable() False - sage: F = A.extended_echelon_form(subdivide=True) # optional - sage.libs.pari - sage: F # optional - sage.libs.pari + sage: F = A.extended_echelon_form(subdivide=True) + sage: F [1 0 0|0 4 6] [0 1 0|4 2 2] [0 0 1|5 2 3] [-----+-----] - sage: F.is_mutable() # optional - sage.libs.pari + sage: F.is_mutable() False - sage: G = copy(F) # optional - sage.libs.pari - sage: G.subdivide([], []); G # optional - sage.libs.pari + sage: G = copy(F) + sage: G.subdivide([], []); G [1 0 0 0 4 6] [0 1 0 4 2 2] [0 0 1 5 2 3] @@ -9247,10 +9247,10 @@ cdef class Matrix(Matrix1): Different base rings are handled sensibly. :: sage: A = matrix(ZZ, 2, 3, range(6)) - sage: B = matrix(FiniteField(23), 3, 4, range(12)) # optional - sage.libs.pari - sage: C = matrix(FiniteField(29), 4, 5, range(20)) # optional - sage.libs.pari - sage: D = A.tensor_product(B) # optional - sage.libs.pari - sage: D.parent() # optional - sage.libs.pari + sage: B = matrix(FiniteField(23), 3, 4, range(12)) + sage: C = matrix(FiniteField(29), 4, 5, range(20)) + sage: D = A.tensor_product(B) + sage: D.parent() Full MatrixSpace of 6 by 12 dense matrices over Finite Field of size 23 sage: E = C.tensor_product(B) # optional - sage.libs.pari Traceback (most recent call last): @@ -9284,9 +9284,9 @@ cdef class Matrix(Matrix1): sage: m2.tensor_product(m3).dimensions() (0, 6) - sage: m1 = MatrixSpace(GF(5), 3, 2).an_element() # optional - sage.libs.pari - sage: m2 = MatrixSpace(GF(5), 0, 4).an_element() # optional - sage.libs.pari - sage: m1.tensor_product(m2).parent() # optional - sage.libs.pari + sage: m1 = MatrixSpace(GF(5), 3, 2).an_element() + sage: m2 = MatrixSpace(GF(5), 0, 4).an_element() + sage: m1.tensor_product(m2).parent() Full MatrixSpace of 0 by 8 dense matrices over Finite Field of size 5 """ if not isinstance(A, Matrix): @@ -9930,8 +9930,8 @@ cdef class Matrix(Matrix1): :: - sage: A = random_matrix(GF(127), 200, 200, density=0.3) # optional - sage.libs.pari - sage: A.density() <= 0.3 # optional - sage.libs.pari + sage: A = random_matrix(GF(127), 200, 200, density=0.3) + sage: A.density() <= 0.3 True :: @@ -10002,9 +10002,9 @@ cdef class Matrix(Matrix1): Test :trac:`27473`:: - sage: F. = LaurentSeriesRing(GF(2)) # optional - sage.libs.pari - sage: M = Matrix([[t,1], [0,t]]) # optional - sage.libs.pari - sage: ~M # optional - sage.libs.pari + sage: F. = LaurentSeriesRing(GF(2)) + sage: M = Matrix([[t,1], [0,t]]) + sage: ~M [t^-1 t^-2] [ 0 t^-1] @@ -11075,7 +11075,7 @@ cdef class Matrix(Matrix1): stable:: sage: b = matrix(ZZ, 3, 3, range(9)) - sage: jf, p = b.jordan_form(RealField(15), transformation=True) + sage: jf, p = b.jordan_form(RealField(15), transformation=True) # optional - sage.combinat Traceback (most recent call last): ... ValueError: Jordan normal form not implemented over inexact rings. @@ -11109,7 +11109,7 @@ cdef class Matrix(Matrix1): We verify that the bug from :trac:`6942` is fixed:: - sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1], [1,0,0,1,1,1,0], [1,1,0,1,1,1,1], # optional - sage.libs.pari + sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1], [1,0,0,1,1,1,0], [1,1,0,1,1,1,1], ....: [1,1,1,0,1,1,1], [1,1,1,0,0,1,0], [1,1,1,0,1,0,0], ....: [1,1,1,1,1,1,0]]) sage: J, T = M.jordan_form(transformation=True) # optional - sage.combinat sage.libs.pari @@ -11128,7 +11128,7 @@ cdef class Matrix(Matrix1): True sage: T.rank() # optional - sage.combinat sage.libs.pari 7 - sage: M.rank() # optional - sage.combinat sage.libs.pari + sage: M.rank() # optional - sage.combinat 7 We verify that the bug from :trac:`6932` is fixed:: @@ -11524,7 +11524,7 @@ cdef class Matrix(Matrix1): sage: D [0 2] [1 0] - sage: D.diagonalization() + sage: D.diagonalization() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: not diagonalizable over Rational Field @@ -11533,11 +11533,11 @@ cdef class Matrix(Matrix1): sage: E [3 1] [0 3] - sage: E.diagonalization() + sage: E.diagonalization() # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: not diagonalizable - sage: E.jordan_form() + sage: E.jordan_form() # optional - sage.combinat [3 1] [0 3] """ @@ -11875,16 +11875,16 @@ cdef class Matrix(Matrix1): Other exact fields are supported. :: - sage: F. = FiniteField(7^2) # optional - sage.libs.pari - sage: A = matrix(F,[[2*a + 5, 6*a + 6, a + 3], # optional - sage.libs.pari - ....: [ a + 3, 2*a + 2, 4*a + 2], - ....: [2*a + 6, 5*a + 5, 3*a]]) - sage: B = matrix(F,[[5*a + 5, 6*a + 4, a + 1], # optional - sage.libs.pari - ....: [ a + 5, 4*a + 3, 3*a + 3], - ....: [3*a + 5, a + 4, 5*a + 6]]) - sage: A.is_similar(B) # optional - sage.libs.pari + sage: F. = FiniteField(7^2) # optional - sage.rings.finite_rings + sage: A = matrix(F, [[2*a + 5, 6*a + 6, a + 3], # optional - sage.rings.finite_rings + ....: [ a + 3, 2*a + 2, 4*a + 2], + ....: [2*a + 6, 5*a + 5, 3*a]]) + sage: B = matrix(F, [[5*a + 5, 6*a + 4, a + 1], # optional - sage.rings.finite_rings + ....: [ a + 5, 4*a + 3, 3*a + 3], + ....: [3*a + 5, a + 4, 5*a + 6]]) + sage: A.is_similar(B) True - sage: B.is_similar(A) # optional - sage.libs.pari + sage: B.is_similar(A) True sage: _, T = A.is_similar(B, transformation=True) # optional - sage.libs.pari sage: T # optional - sage.libs.pari @@ -12007,9 +12007,9 @@ cdef class Matrix(Matrix1): If the fraction fields of the entries are unequal and do not coerce in a common field, it is an error. :: - sage: A = matrix(GF(3), 2, 2, range(4)) # optional - sage.libs.pari - sage: B = matrix(GF(2), 2, 2, range(4)) # optional - sage.libs.pari - sage: A.is_similar(B, transformation=True) # optional - sage.libs.pari + sage: A = matrix(GF(3), 2, 2, range(4)) + sage: B = matrix(GF(2), 2, 2, range(4)) + sage: A.is_similar(B, transformation=True) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -12438,13 +12438,13 @@ cdef class Matrix(Matrix1): ... TypeError: polynomial variable must be a string or polynomial ring generator, not sin(x) - sage: t = polygen(GF(7), 't') # optional - sage.rings.finite_rings - sage: A.cyclic_subspace(v, var=t) # optional - sage.rings.finite_rings + sage: t = polygen(GF(7), 't') + sage: A.cyclic_subspace(v, var=t) Traceback (most recent call last): ... TypeError: polynomial generator must be over the same ring as the matrix entries - sage: A.cyclic_subspace(v, basis='garbage') # optional - sage.libs.pari + sage: A.cyclic_subspace(v, basis='garbage') Traceback (most recent call last): ... ValueError: basis format must be 'echelon' or 'iterates', not garbage @@ -12473,10 +12473,10 @@ cdef class Matrix(Matrix1): ... TypeError: matrix entries must be from an exact field, not Ring of integers modulo 6 - sage: F. = GF(2^4) # optional - sage.libs.pari - sage: G = matrix(QQ, 4, range(16)) # optional - sage.libs.pari - sage: w = vector(F, 4, [1, a, a^2, a^3]) # optional - sage.libs.pari - sage: G.cyclic_subspace(w) # optional - sage.libs.pari + sage: F. = GF(2^4) # optional - sage.rings.finite_rings + sage: G = matrix(QQ, 4, range(16)) + sage: w = vector(F, 4, [1, a, a^2, a^3]) # optional - sage.rings.finite_rings + sage: G.cyclic_subspace(w) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to make vector entries compatible with matrix entries @@ -13276,8 +13276,8 @@ cdef class Matrix(Matrix1): ....: [3, 2*a + 4, 2*a + 4, 2*a + 1], ....: [3*a + 1, a + 3, 2*a + 4, 4*a + 3], ....: [a, 3, 3*a + 1, a]]) - sage: P, L, U = C.LU(pivot='nonzero') # optional - sage.combinat sage.libs.pari - sage: P # optional - sage.combinat sage.libs.pari + sage: P, L, U = C.LU(pivot='nonzero') # optional - sage.combinat + sage: P # optional - sage.combinat [1 0 0 0] [0 1 0 0] [0 0 1 0] @@ -13294,7 +13294,7 @@ cdef class Matrix(Matrix1): [ 0 0 0 0] sage: L.base_ring() # optional - sage.combinat sage.libs.pari Finite Field in a of size 5^2 - sage: C == P*L*U # optional - sage.combinat sage.libs.pari + sage: C == P*L*U # optional - sage.combinat True With no pivoting strategy given (i.e. ``pivot=None``) @@ -13380,9 +13380,9 @@ cdef class Matrix(Matrix1): Check that :trac:`32736` is solved:: - sage: M = Matrix(FiniteField(11), [[2,3],[4,5]]) # optional - sage.libs.pari - sage: P, L, U = M.LU() # optional - sage.combinat sage.libs.pari - sage: P.base_ring() # optional - sage.combinat sage.libs.pari + sage: M = Matrix(FiniteField(11), [[2,3],[4,5]]) + sage: P, L, U = M.LU() # optional - sage.combinat + sage: P.base_ring() # optional - sage.combinat Finite Field of size 11 """ if pivot not in [None, 'partial', 'nonzero']: @@ -13882,11 +13882,11 @@ cdef class Matrix(Matrix1): ....: [4*a^2 + 3*a + 4, 4*a^2 + 2, 3*a, 2*a^2 + 4*a + 2], ....: [ 3*a^2 + a, 3*a, 3*a^2 + 2, 3*a^2 + 2*a + 3], ....: [2*a^2 + 2*a + 1, 2*a^2 + 4*a + 2, 3*a^2 + 2*a + 3, 3*a^2 + 2*a + 4]]) - sage: A.is_symmetric() # optional - sage.libs.pari + sage: A.is_symmetric() True - sage: L, d = A.indefinite_factorization() # optional - sage.libs.pari - sage: D = diagonal_matrix(d) # optional - sage.libs.pari - sage: L # optional - sage.libs.pari + sage: L, d = A.indefinite_factorization() # optional - sage.rings.finite_rings + sage: D = diagonal_matrix(d) + sage: L # optional - sage.rings.finite_rings [ 1 0 0 0] [4*a^2 + 4*a + 3 1 0 0] [ 3 4*a^2 + a + 2 1 0] @@ -15166,8 +15166,8 @@ cdef class Matrix(Matrix1): Conjugation does not make sense over rings not containing complex numbers or finite fields which are not a quadratic extension:: - sage: N = matrix(GF(5), 2, [0,1,2,3]) # optional - sage.libs.pari - sage: N.conjugate_transpose() # optional - sage.libs.pari + sage: N = matrix(GF(5), 2, [0,1,2,3]) + sage: N.conjugate_transpose() Traceback (most recent call last): ... AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object has no attribute 'conjugate' @@ -15401,8 +15401,8 @@ cdef class Matrix(Matrix1): Another random plot, but over GF(389):: - sage: A = random_matrix(GF(389), 10) # optional - sage.libs.pari - sage: A.plot(cmap='Oranges') # optional - sage.libs.pari sage.plot + sage: A = random_matrix(GF(389), 10) + sage: A.plot(cmap='Oranges') # optional - sage.rings.finite_rings sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.matrix_plot import matrix_plot @@ -15631,13 +15631,13 @@ cdef class Matrix(Matrix1): An example over a field:: - sage: m = matrix(GF(17), 3, 3, [11,5,1, 3,6,8, 1,16,0]) # optional - sage.libs.pari - sage: d,u,v = m.smith_form() # optional - sage.libs.pari - sage: d # optional - sage.libs.pari + sage: m = matrix(GF(17), 3, 3, [11,5,1, 3,6,8, 1,16,0]) + sage: d, u, v = m.smith_form() + sage: d [1 0 0] [0 1 0] [0 0 0] - sage: u*m*v == d # optional - sage.libs.pari + sage: u * m * v == d True When the base ring has a ``ring_of_integers`` method and supports denominators, @@ -15916,32 +15916,32 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = FunctionField(GF(7), 'x').maximal_order() # optional - sage.libs.pari - sage: K. = FunctionField(GF(7)); M = K.maximal_order() # optional - sage.libs.pari - sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) # optional - sage.libs.pari - sage: A.hermite_form() # optional - sage.libs.pari + sage: M = FunctionField(GF(7), 'x').maximal_order() + sage: K. = FunctionField(GF(7)); M = K.maximal_order() + sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1 + x, 2]) + sage: A.hermite_form() [ x 1 2*x] [ 0 x 5*x + 2] - sage: A.hermite_form(transformation=True) # optional - sage.libs.pari + sage: A.hermite_form(transformation=True) ( [ x 1 2*x] [1 0] [ 0 x 5*x + 2], [6 1] ) - sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) # optional - sage.libs.pari - sage: A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.libs.pari + sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) + sage: A.hermite_form(transformation=True, include_zero_rows=False) ([ x 1 2*x], [1 0]) - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True) # optional - sage.rings.finite_rings - sage: H, U # optional - sage.rings.finite_rings + sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True) + sage: H, U ( [ x 1 2*x] [1 0] [ 0 0 0], [5 1] ) - sage: U*A == H # optional - sage.libs.pari + sage: U * A == H True - sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.libs.pari - sage: U*A # optional - sage.libs.pari + sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False) + sage: U * A [ x 1 2*x] - sage: U*A == H # optional - sage.libs.pari + sage: U * A == H True """ left, H, pivots = self._echelon_form_PID() @@ -16015,11 +16015,11 @@ cdef class Matrix(Matrix1): We verify that :trac:`9053` is resolved:: - sage: R. = GF(7)[] # optional - sage.libs.pari - sage: A = R^3 # optional - sage.libs.pari - sage: L = A.span([x*A.0 + (x^3 + 1)*A.1, x*A.2]) # optional - sage.libs.pari - sage: M = A.span([x*L.0]) # optional - sage.libs.pari - sage: M.0 in L # optional - sage.libs.pari + sage: R. = GF(7)[] + sage: A = R^3 + sage: L = A.span([x*A.0 + (x^3 + 1)*A.1, x*A.2]) + sage: M = A.span([x*L.0]) + sage: M.0 in L True """ @@ -16872,12 +16872,12 @@ cdef class Matrix(Matrix1): [ 0| 0 0 0| 0 0 0 1 0 0 a + 6] [ 0| 0 0 0| 0 0 0 0 1 0 2*a + 1] [ 0| 0 0 0| 0 0 0 0 0 1 2*a + 1] - sage: invariants = A.rational_form(format='invariants') # optional - sage.libs.pari - sage: invariants # optional - sage.libs.pari + sage: invariants = A.rational_form(format='invariants') + sage: invariants # optional - sage.rings.finite_rings [[6*a + 5, 1], [6*a + 1, a + 3, a + 3, 1], [5*a, a + 4, a + 6, 6*a + 5, 6*a + 1, 5*a + 6, 5*a + 6, 1]] - sage: R. = F[] # optional - sage.libs.pari - sage: polys = [R(p) for p in invariants] # optional - sage.libs.pari - sage: [p.factor() for p in polys] # optional - sage.libs.pari + sage: R. = F[] + sage: polys = [R(p) for p in invariants] + sage: [p.factor() for p in polys] # optional - sage.rings.finite_rings [x + 6*a + 5, (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a), (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a)^3] sage: polys[-1] == A.minimal_polynomial() # optional - sage.libs.pari True @@ -17790,10 +17790,10 @@ def _smith_diag(d, transformation=True): ) sage: D == U*A*V # optional - sage.rings.number_field True - sage: m = matrix(GF(7), 2, [3,0,0,6]); d,u,v = _smith_diag(m); d # optional - sage.libs.pari + sage: m = matrix(GF(7), 2, [3,0,0,6]); d,u,v = _smith_diag(m); d [1 0] [0 1] - sage: u*m*v == d # optional - sage.libs.pari + sage: u*m*v == d True """ diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 0fe101d612a..17000d28b9c 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -19,7 +19,7 @@ sage: matrix(RR,2,2,sparse=True) [0.000000000000000 0.000000000000000] [0.000000000000000 0.000000000000000] - sage: matrix(GF(11), 2, 2, sparse=True) # optional - sage.libs.pari + sage: matrix(GF(11), 2, 2, sparse=True) [0 0] [0 0] """ @@ -114,7 +114,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(ZZ, 3, 3, False, 'flint') - sage: get_matrix_class(ZZ, 3, 3, False, 'gap') + sage: get_matrix_class(ZZ, 3, 3, False, 'gap') # optional - sage.modules sage: get_matrix_class(ZZ, 3, 3, False, 'generic') @@ -155,7 +155,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): Traceback (most recent call last): ... ValueError: unknown matrix implementation 'crazy_matrix' over Integer Ring - sage: get_matrix_class(GF(3), 2, 2, False, 'm4ri') # optional - sage.libs.pari + sage: get_matrix_class(GF(3), 2, 2, False, 'm4ri') Traceback (most recent call last): ... ValueError: 'm4ri' matrices are only available for fields of characteristic 2 and order <= 65536 @@ -523,8 +523,8 @@ class MatrixSpace(UniqueRepresentation, Parent): [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: m = M2.random_element() # optional - sage.libs.gap sage.rings.finite_rings - sage: M1 = MatrixSpace(GF(2), 5) # optional - sage.rings.finite_rings + sage: m = M2.random_element() # optional - sage.libs.gap + sage: M1 = MatrixSpace(GF(2), 5) sage: M1(m * m) == M1(m) * M1(m) # optional - sage.libs.gap sage.rings.finite_rings True """ @@ -734,7 +734,7 @@ def cardinality(self): EXAMPLES:: - sage: MatrixSpace(GF(3), 2, 3).cardinality() # optional - sage.libs.pari + sage: MatrixSpace(GF(3), 2, 3).cardinality() 729 sage: MatrixSpace(ZZ, 2).cardinality() +Infinity @@ -780,11 +780,11 @@ def transposed(self): EXAMPLES:: - sage: MS = MatrixSpace(GF(3), 7, 10) # optional - sage.libs.pari - sage: MS.transposed # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(3), 7, 10) + sage: MS.transposed Full MatrixSpace of 10 by 7 dense matrices over Finite Field of size 3 - sage: MS = MatrixSpace(GF(3), 7, 7) # optional - sage.libs.pari - sage: MS.transposed is MS # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(3), 7, 7) + sage: MS.transposed is MS True sage: M = MatrixSpace(ZZ, 2, 3) @@ -802,15 +802,15 @@ def _copy_zero(self): EXAMPLES:: - sage: MS = MatrixSpace(GF(2), 20, 20) # optional - sage.libs.pari - sage: MS._copy_zero # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(2), 20, 20) + sage: MS._copy_zero # optional - sage.rings.finite_rings False - sage: MS = MatrixSpace(GF(3), 20, 20) # optional - sage.libs.pari - sage: MS._copy_zero # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(3), 20, 20) + sage: MS._copy_zero # optional - sage.rings.finite_rings True - sage: MS = MatrixSpace(GF(3), 200, 200) # optional - sage.libs.pari - sage: MS._copy_zero # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(3), 200, 200) + sage: MS._copy_zero # optional - sage.rings.finite_rings False sage: MS = MatrixSpace(ZZ,200,200) @@ -845,10 +845,10 @@ def _element_constructor_(self, entries, **kwds): EXAMPLES:: - sage: k = GF(7) # optional - sage.libs.pari - sage: G = MatrixGroup([matrix(k, 2, [1,1,0,1]), matrix(k, 2, [1,0,0,2])]) # optional - sage.libs.pari - sage: g = G.0 # optional - sage.libs.pari - sage: MatrixSpace(k, 2)(g) # optional - sage.libs.pari + sage: k = GF(7) + sage: G = MatrixGroup([matrix(k, 2, [1,1,0,1]), matrix(k, 2, [1,0,0,2])]) + sage: g = G.0 + sage: MatrixSpace(k, 2)(g) [1 1] [0 1] @@ -969,7 +969,7 @@ def change_ring(self, R): EXAMPLES:: - sage: Mat(QQ, 3, 5).change_ring(GF(7)) # optional - sage.libs.pari + sage: Mat(QQ, 3, 5).change_ring(GF(7)) Full MatrixSpace of 3 by 5 dense matrices over Finite Field of size 7 """ @@ -997,7 +997,7 @@ def base_extend(self, R): sage: Mat(ZZ, 3, 5).base_extend(QQ) Full MatrixSpace of 3 by 5 dense matrices over Rational Field - sage: Mat(QQ, 3, 5).base_extend(GF(7)) # optional - sage.libs.pari + sage: Mat(QQ, 3, 5).base_extend(GF(7)) Traceback (most recent call last): ... TypeError: no base extension defined @@ -1151,8 +1151,8 @@ def _coerce_map_from_(self, S): There are also coercions possible from matrix group and arithmetic subgroups:: - sage: MS = MatrixSpace(GF(3), 2, 2) # optional - sage.libs.pari - sage: MS.coerce_map_from(GL(2, 3)) # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(3), 2, 2) + sage: MS.coerce_map_from(GL(2, 3)) Coercion map: From: General Linear Group of degree 2 over Finite Field of size 3 To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 @@ -1346,11 +1346,11 @@ def __len__(self): EXAMPLES:: - sage: len(MatrixSpace(GF(3), 3, 2)) # optional - sage.libs.pari + sage: len(MatrixSpace(GF(3), 3, 2)) 729 - sage: len(MatrixSpace(GF(3), 2, 3)) # optional - sage.libs.pari + sage: len(MatrixSpace(GF(3), 2, 3)) 729 - sage: 3^(2*3) # optional - sage.libs.pari + sage: 3^(2*3) 729 sage: len(MatrixSpace(GF(2003), 3, 2)) # optional - sage.libs.pari @@ -1379,20 +1379,20 @@ def __iter__(self): :: - sage: list(GF(5)) # optional - sage.libs.pari + sage: list(GF(5)) [0, 1, 2, 3, 4] - sage: MS = MatrixSpace(GF(5), 2, 2) # optional - sage.libs.pari - sage: l = list(MS) # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(5), 2, 2) + sage: l = list(MS) Then, consider the following matrices:: - sage: A = MS([2,1,0,1]); A # optional - sage.libs.pari + sage: A = MS([2,1,0,1]); A [2 1] [0 1] - sage: B = MS([1,2,1,0]); B # optional - sage.libs.pari + sage: B = MS([1,2,1,0]); B [1 2] [1 0] - sage: C = MS([1,2,0,0]); C # optional - sage.libs.pari + sage: C = MS([1,2,0,0]); C [1 2] [0 0] @@ -1401,9 +1401,9 @@ def __iter__(self): :: - sage: l.index(A) # optional - sage.libs.pari + sage: l.index(A) 41 - sage: l.index(B) # optional - sage.libs.pari + sage: l.index(B) 46 However, A would come after the matrix C since C has a lower weight @@ -1411,9 +1411,9 @@ def __iter__(self): :: - sage: l.index(A) # optional - sage.libs.pari + sage: l.index(A) 41 - sage: l.index(C) # optional - sage.libs.pari + sage: l.index(C) 19 The weights of matrices over other base rings are not as obvious. @@ -1440,11 +1440,11 @@ def __iter__(self): Some more examples:: - sage: MS = MatrixSpace(GF(2), 2) # optional - sage.libs.pari - sage: a = list(MS) # optional - sage.libs.pari - sage: len(a) # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(2), 2) + sage: a = list(MS) + sage: len(a) 16 - sage: for m in a: # optional - sage.libs.pari + sage: for m in a: ....: print(m) ....: print('-') [0 0] @@ -1498,11 +1498,11 @@ def __iter__(self): :: - sage: MS = MatrixSpace(GF(2), 2, 3) # optional - sage.libs.pari - sage: a = list(MS) # optional - sage.libs.pari - sage: len(a) # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(2), 2, 3) + sage: a = list(MS) + sage: len(a) 64 - sage: a[0] # optional - sage.libs.pari + sage: a[0] [0 0 0] [0 0 0] @@ -1524,11 +1524,11 @@ def __iter__(self): :: - sage: list(MatrixSpace(GF(2), 2, 0)) # optional - sage.libs.pari + sage: list(MatrixSpace(GF(2), 2, 0)) [[]] - sage: list(MatrixSpace(GF(2), 0, 2)) # optional - sage.libs.pari + sage: list(MatrixSpace(GF(2), 0, 2)) [[]] - sage: list(MatrixSpace(GF(2), 0, 0)) # optional - sage.libs.pari + sage: list(MatrixSpace(GF(2), 0, 0)) [[]] If the base ring does not support iteration (for example, with the @@ -1598,15 +1598,15 @@ def __getitem__(self, x): EXAMPLES:: - sage: MS = MatrixSpace(GF(3), 2, 2) # optional - sage.libs.pari - sage: MS['x'] # optional - sage.libs.pari + sage: MS = MatrixSpace(GF(3), 2, 2) + sage: MS['x'] Univariate Polynomial Ring in x over Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 - sage: MS[0] # optional - sage.libs.pari + sage: MS[0] [0 0] [0 0] - sage: MS[9] # optional - sage.libs.pari + sage: MS[9] [0 2] [0 0] @@ -1914,7 +1914,7 @@ def is_finite(self): EXAMPLES:: - sage: MatrixSpace(GF(101), 10000).is_finite() # optional - sage.libs.pari + sage: MatrixSpace(GF(101), 10000).is_finite() True sage: MatrixSpace(QQ, 2).is_finite() False @@ -1930,10 +1930,10 @@ def gen(self, n): EXAMPLES:: - sage: M = Mat(GF(7), 10000, 5); M.ngens() # optional - sage.libs.pari + sage: M = Mat(GF(7), 10000, 5); M.ngens() 50000 - sage: a = M.10 # optional - sage.libs.pari - sage: a[:4] # optional - sage.libs.pari + sage: a = M.10 + sage: a[:4] [0 0 0 0 0] [0 0 0 0 0] [1 0 0 0 0] @@ -1957,10 +1957,10 @@ def zero_matrix(self): EXAMPLES:: - sage: z = MatrixSpace(GF(7), 2, 4).zero_matrix(); z # optional - sage.libs.pari + sage: z = MatrixSpace(GF(7), 2, 4).zero_matrix(); z [0 0 0 0] [0 0 0 0] - sage: z.is_mutable() # optional - sage.libs.pari + sage: z.is_mutable() False TESTS:: @@ -1991,7 +1991,7 @@ def ngens(self): EXAMPLES:: - sage: M = Mat(GF(7), 100, 200); M.ngens() # optional - sage.libs.pari + sage: M = Mat(GF(7), 100, 200); M.ngens() 20000 """ return self.dimension() @@ -2105,10 +2105,10 @@ def matrix(self, x=None, **kwds): Converting sparse to dense matrices used to be too slow (:trac:`20470`). Check that this is fixed:: - sage: m = identity_matrix(GF(2), 2000, sparse=True) # optional - sage.libs.pari - sage: MS = MatrixSpace(GF(2), 2000, sparse=False) # optional - sage.libs.pari - sage: md = MS(m) # used to be slow # optional - sage.libs.pari - sage: md.parent() is MS # optional - sage.libs.pari + sage: m = identity_matrix(GF(2), 2000, sparse=True) + sage: MS = MatrixSpace(GF(2), 2000, sparse=False) + sage: md = MS(m) + sage: md.parent() is MS True """ return self(x, **kwds) @@ -2121,12 +2121,12 @@ def matrix_space(self, nrows=None, ncols=None, sparse=False): EXAMPLES:: - sage: M = Mat(GF(7), 100, 200) # optional - sage.libs.pari - sage: M.matrix_space(5000) # optional - sage.libs.pari + sage: M = Mat(GF(7), 100, 200) + sage: M.matrix_space(5000) Full MatrixSpace of 5000 by 200 dense matrices over Finite Field of size 7 - sage: M.matrix_space(ncols=5000) # optional - sage.libs.pari + sage: M.matrix_space(ncols=5000) Full MatrixSpace of 100 by 5000 dense matrices over Finite Field of size 7 - sage: M.matrix_space(sparse=True) # optional - sage.libs.pari + sage: M.matrix_space(sparse=True) Full MatrixSpace of 100 by 200 sparse matrices over Finite Field of size 7 """ if nrows is None: @@ -2243,7 +2243,7 @@ def random_element(self, density=None, *args, **kwds): sage: TestSuite(M).run() sage: M = Mat(QQ, 3, sparse=True).random_element() - sage: TestSuite(M).run() + sage: TestSuite(M).run() # optional - sage.libs.pari sage: M = Mat(GF(9,'a'), 3, sparse=True).random_element() # optional - sage.libs.pari sage: TestSuite(M).run() # optional - sage.libs.pari @@ -2278,8 +2278,8 @@ def _an_element_(self): Check that this works for large matrices and that it returns a matrix which is not too trivial:: - sage: M = MatrixSpace(GF(2), 100, 100).an_element() # optional - sage.libs.pari - sage: M.rank() >= 2 # optional - sage.libs.pari + sage: M = MatrixSpace(GF(2), 100, 100).an_element() + sage: M.rank() >= 2 True Check that this works for sparse matrices:: @@ -2491,10 +2491,10 @@ def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, check sage: tinv(QQ, sparse=True) sage: tinv(QQ, sparse=False, implementation='flint') # optional - sage.libs.flint sage: tinv(QQ, sparse=False, implementation='generic') - sage: tinv(GF(11), sparse=True) # optional - sage.libs.pari - sage: tinv(GF(11), sparse=False) # optional - sage.libs.pari - sage: tinv(GF(2), sparse=True) # optional - sage.libs.pari - sage: tinv(GF(2), sparse=False) # optional - sage.libs.pari + sage: tinv(GF(11), sparse=True) + sage: tinv(GF(11), sparse=False) + sage: tinv(GF(2), sparse=True) + sage: tinv(GF(2), sparse=False) sage: tinv(SR, sparse=True) # optional - sage.symbolic sage: tinv(SR, sparse=False) # optional - sage.symbolic sage: tinv(RDF, sparse=True) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index fa2a1fd2c4d..71d60ea1198 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -462,7 +462,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation sage: K. = FiniteField(3^2) # optional - sage.rings.finite_rings sage: A = random_matrix(K, 2, 5, implementation='generic') # optional - sage.rings.finite_rings - sage: type(A) # optional - sage.rings.finite_rings + sage: type(A) sage: A.base_ring() is K # optional - sage.rings.finite_rings True @@ -552,7 +552,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation True sage: all(x in ZZ for x in (A - (-1)*identity_matrix(5)).rref().list()) True - sage: A.jordan_form() + sage: A.jordan_form() # optional - sage.combinat [ 2| 0| 0| 0| 0] [--+--+--+--+--] [ 0| 3| 0| 0| 0] @@ -740,11 +740,11 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): Format 4: ring, size and list of entries. :: - sage: A = diagonal_matrix(FiniteField(3), 3, [2, 16]); A # optional - sage.rings.finite_rings + sage: A = diagonal_matrix(FiniteField(3), 3, [2, 16]); A [2 0 0] [0 1 0] [0 0 0] - sage: A.parent() # optional - sage.rings.finite_rings + sage: A.parent() Full MatrixSpace of 3 by 3 sparse matrices over Finite Field of size 3 NumPy arrays may be used as input. :: @@ -1514,17 +1514,17 @@ def circulant(v, sparse=None): [4 8 1 2 3] [3 4 8 1 2] [2 3 4 8 1] - sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=True)); m # optional - sage.rings.finite_rings + sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=True)); m [0 1 2] [2 0 1] [1 2 0] - sage: m.is_sparse() # optional - sage.rings.finite_rings + sage: m.is_sparse() True TESTS:: - sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=False)) # optional - sage.rings.finite_rings - sage: m.is_sparse() # optional - sage.rings.finite_rings + sage: m = matrix.circulant(vector(GF(3),[0,1,-1],sparse=False)) + sage: m.is_sparse() False sage: matrix.circulant([0,1,-1]).is_sparse() False @@ -2447,17 +2447,17 @@ def random_rref_matrix(parent, num_pivots): Matrices can be generated over other exact rings. :: - sage: B = random_matrix(FiniteField(7), 4, 4, # random # optional - sage.rings.finite_rings + sage: B = random_matrix(FiniteField(7), 4, 4, ....: algorithm='echelon_form', num_pivots=3); B [1 0 0 0] [0 1 0 6] [0 0 1 4] [0 0 0 0] - sage: B.rank() == 3 # optional - sage.rings.finite_rings + sage: B.rank() == 3 True - sage: B.base_ring() # optional - sage.rings.finite_rings + sage: B.base_ring() Finite Field of size 7 - sage: B == B.rref() # optional - sage.rings.finite_rings + sage: B == B.rref() True TESTS: diff --git a/src/sage/matrix/symplectic_basis.py b/src/sage/matrix/symplectic_basis.py index d42d76a4543..66dc1883a12 100644 --- a/src/sage/matrix/symplectic_basis.py +++ b/src/sage/matrix/symplectic_basis.py @@ -188,11 +188,12 @@ def symplectic_basis_over_field(M): An example over a finite field:: - sage: E = matrix(GF(7), 8, 8, [0, -1/2, -2, 1/2, 2, 0, -2, 1, 1/2, 0, -1, -3, 0, 2, 5/2, # optional - sage.libs.pari - ....: -3, 2, 1, 0, 3/2, -1, 0, -1, -2, -1/2, 3, -3/2, 0, 1, 3/2, - ....: -1/2, -1/2, -2, 0, 1, -1, 0, 0, 1, -1, 0, -2, 0, -3/2, 0, - ....: 0, 1/2, -2, 2, -5/2, 1, 1/2, -1, -1/2, 0, -1, -1, 3, 2, - ....: 1/2, 1, 2, 1, 0]); E + sage: E = matrix(GF(7), 8, 8, + ....: [0, -1/2, -2, 1/2, 2, 0, -2, 1, 1/2, 0, -1, -3, 0, 2, 5/2, + ....: -3, 2, 1, 0, 3/2, -1, 0, -1, -2, -1/2, 3, -3/2, 0, 1, 3/2, + ....: -1/2, -1/2, -2, 0, 1, -1, 0, 0, 1, -1, 0, -2, 0, -3/2, 0, + ....: 0, 1/2, -2, 2, -5/2, 1, 1/2, -1, -1/2, 0, -1, -1, 3, 2, + ....: 1/2, 1, 2, 1, 0]); E [0 3 5 4 2 0 5 1] [4 0 6 4 0 2 6 4] [2 1 0 5 6 0 6 5] @@ -201,7 +202,7 @@ def symplectic_basis_over_field(M): [0 5 0 2 0 0 4 5] [2 1 1 4 6 3 0 6] [6 3 2 4 1 2 1 0] - sage: F, C = symplectic_basis_over_field(E); F # optional - sage.libs.pari + sage: F, C = symplectic_basis_over_field(E); F [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] @@ -210,15 +211,16 @@ def symplectic_basis_over_field(M): [0 6 0 0 0 0 0 0] [0 0 6 0 0 0 0 0] [0 0 0 6 0 0 0 0] - sage: F == C * E * C.transpose() # optional - sage.libs.pari + sage: F == C * E * C.transpose() True The tricky case of characteristic 2:: - sage: E = matrix(GF(2), 8, 8, [0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, # optional - sage.libs.pari - ....: 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, - ....: 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, - ....: 0, 1, 0, 0]); E + sage: E = matrix(GF(2), 8, 8, + ....: [0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + ....: 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, + ....: 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, + ....: 0, 1, 0, 0]); E [0 0 1 1 0 1 0 1] [0 0 0 0 0 0 0 0] [1 0 0 0 0 0 1 1] @@ -227,7 +229,7 @@ def symplectic_basis_over_field(M): [1 0 0 0 1 0 1 1] [0 0 1 0 1 1 0 0] [1 0 1 1 0 1 0 0] - sage: F, C = symplectic_basis_over_field(E); F # optional - sage.libs.pari + sage: F, C = symplectic_basis_over_field(E); F [0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] @@ -236,7 +238,7 @@ def symplectic_basis_over_field(M): [0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] - sage: F == C * E * C.transpose() # optional - sage.libs.pari + sage: F == C * E * C.transpose() True An inexact example:: diff --git a/src/sage/matrix/tests.py b/src/sage/matrix/tests.py index f4ed51c68b6..c2e2ef74afc 100644 --- a/src/sage/matrix/tests.py +++ b/src/sage/matrix/tests.py @@ -11,7 +11,7 @@ Vector space of degree 1 and dimension 1 over Rational Field Basis matrix: [1] - sage: matrix(GF(7), 1, 0).kernel() # optional - sage.libs.pari + sage: matrix(GF(7), 1, 0).kernel() Vector space of degree 1 and dimension 1 over Finite Field of size 7 Basis matrix: [1] @@ -28,7 +28,7 @@ Vector space of degree 0 and dimension 0 over Rational Field Basis matrix: [] - sage: matrix(GF(7), 0, 1).kernel() # optional - sage.libs.pari + sage: matrix(GF(7), 0, 1).kernel() Vector space of degree 0 and dimension 0 over Finite Field of size 7 Basis matrix: [] From d5f0391f957354655063f98f7b624a65ba4190e3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 1 Jul 2023 15:42:59 -0700 Subject: [PATCH 61/99] Update # optional / # needs --- src/sage/modules/free_module_element.pyx | 727 ++++++++++++----------- 1 file changed, 371 insertions(+), 356 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 034d08fbc55..b9a2cd77295 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -95,7 +95,7 @@ TESTS:: sage: u = 7 sage: R = Integers(D) sage: p = matrix(R,[[84, 97, 55, 58, 51]]) - sage: 2*p.row(0) # optional - sage.libs.pari + sage: 2*p.row(0) # needs sage.libs.pari (168, 194, 110, 116, 102) This is a test from :trac:`20211`:: @@ -347,27 +347,29 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): must be contiguous, so column-wise slices of numpy matrices will raise an exception. :: - sage: import numpy # optional - numpy - sage: x = numpy.random.randn(10) # optional - numpy - sage: y = vector(x) # optional - numpy - sage: parent(y) # optional - numpy + sage: # needs numpy + sage: import numpy + sage: x = numpy.random.randn(10) + sage: y = vector(x) + sage: parent(y) Vector space of dimension 10 over Real Double Field - sage: parent(vector(RDF, x)) # optional - numpy + sage: parent(vector(RDF, x)) Vector space of dimension 10 over Real Double Field - sage: parent(vector(CDF, x)) # optional - numpy + sage: parent(vector(CDF, x)) Vector space of dimension 10 over Complex Double Field - sage: parent(vector(RR, x)) # optional - numpy + sage: parent(vector(RR, x)) Vector space of dimension 10 over Real Field with 53 bits of precision - sage: v = numpy.random.randn(10) * complex(0,1) # optional - numpy - sage: w = vector(v) # optional - numpy - sage: parent(w) # optional - numpy + sage: v = numpy.random.randn(10) * complex(0,1) + sage: w = vector(v) + sage: parent(w) Vector space of dimension 10 over Complex Double Field Multi-dimensional arrays are not supported:: - sage: import numpy as np # optional - numpy - sage: a = np.array([[1, 2, 3], [4, 5, 6]], np.float64) # optional - numpy - sage: vector(a) # optional - numpy + sage: # needs numpy + sage: import numpy as np + sage: a = np.array([[1, 2, 3], [4, 5, 6]], np.float64) + sage: vector(a) Traceback (most recent call last): ... TypeError: cannot convert 2-dimensional array to a vector @@ -384,29 +386,31 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) sage: v[3].parent() Integer Ring - sage: v = vector([float(23.4), int(2), complex(2+7*I), 1]); v + sage: v = vector([float(23.4), int(2), complex(2+7*I), 1]); v # needs sage.symbolic (23.4, 2.0, 2.0 + 7.0*I, 1.0) - sage: v[1].parent() + sage: v[1].parent() # needs sage.symbolic Complex Double Field If the argument is a vector, it doesn't change the base ring. This fixes :trac:`6643`:: - sage: K. = QuadraticField(3) # optional - sage.rings.number_field - sage: u = vector(K, (1/2, sqrt3/2)) # optional - sage.rings.number_field - sage: vector(u).base_ring() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(3) + sage: u = vector(K, (1/2, sqrt3/2)) + sage: vector(u).base_ring() Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - sage: v = vector(K, (0, 1)) # optional - sage.rings.number_field - sage: vector(v).base_ring() # optional - sage.rings.number_field + sage: v = vector(K, (0, 1)) + sage: vector(v).base_ring() Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? Constructing a vector from a numpy array behaves as expected:: - sage: import numpy # optional - numpy - sage: a = numpy.array([1,2,3]) # optional - numpy - sage: v = vector(a); v # optional - numpy + sage: # needs numpy + sage: import numpy + sage: a = numpy.array([1,2,3]) + sage: v = vector(a); v (1, 2, 3) - sage: parent(v) # optional - numpy + sage: parent(v) Ambient free module of rank 3 over the principal ideal domain Integer Ring Complex numbers can be converted naturally to a sequence of length 2. And @@ -452,23 +456,25 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): sage: v = vector(QQ, w, immutable=True) sage: v.is_immutable() True - sage: import numpy as np # optional - numpy - sage: w = np.array([1, 2, pi], float) # optional - numpy sage.symbolic - sage: v = vector(w, immutable=True) # optional - numpy sage.symbolic - sage: v.is_immutable() # optional - numpy sage.symbolic + + sage: # needs numpy + sage: import numpy as np + sage: w = np.array([1, 2, pi], float) # needs sage.symbolic + sage: v = vector(w, immutable=True) # needs sage.symbolic + sage: v.is_immutable() # needs sage.symbolic True - sage: w = np.array([i, 2, 3], complex) # optional - numpy - sage: v = vector(w, immutable=True) # optional - numpy - sage: v.is_immutable() # optional - numpy + sage: w = np.array([i, 2, 3], complex) + sage: v = vector(w, immutable=True) + sage: v.is_immutable() True TESTS: We check that :trac:`31470` is fixed:: - sage: k. = GF(5^3) # optional - sage.libs.pari - sage: S. = k['x', k.frobenius_endomorphism()] # optional - sage.libs.pari - sage: vector(S, 3) # optional - sage.libs.pari + sage: k. = GF(5^3) # needs sage.rings.finite_rings + sage: S. = k['x', k.frobenius_endomorphism()] # needs sage.rings.finite_rings + sage: vector(S, 3) # needs sage.rings.finite_rings ... (0, 0, 0) """ @@ -626,25 +632,27 @@ def prepare(v, R, degree=None): EXAMPLES:: sage: from sage.modules.free_module_element import prepare - sage: prepare([1,2/3,5],None) + sage: prepare([1, 2/3, 5], None) ([1, 2/3, 5], Rational Field) - sage: prepare([1,2/3,5],RR) - ([1.00000000000000, 0.666666666666667, 5.00000000000000], Real Field with 53 bits of precision) + sage: prepare([1, 2/3, 5], RR) + ([1.00000000000000, 0.666666666666667, 5.00000000000000], + Real Field with 53 bits of precision) - sage: prepare({1:4, 3:-2}, ZZ, 6) + sage: prepare({1: 4, 3: -2}, ZZ, 6) ([0, 4, 0, -2, 0, 0], Integer Ring) - sage: prepare({3:1, 5:3}, QQ, 6) + sage: prepare({3: 1, 5: 3}, QQ, 6) ([0, 0, 0, 1, 0, 3], Rational Field) - sage: prepare([1,2/3,'10',5],RR) - ([1.00000000000000, 0.666666666666667, 10.0000000000000, 5.00000000000000], Real Field with 53 bits of precision) + sage: prepare([1, 2/3, '10', 5], RR) + ([1.00000000000000, 0.666666666666667, 10.0000000000000, 5.00000000000000], + Real Field with 53 bits of precision) - sage: prepare({},QQ, 0) + sage: prepare({}, QQ, 0) ([], Rational Field) - sage: prepare([1,2/3,'10',5],None) + sage: prepare([1, 2/3, '10', 5], None) Traceback (most recent call last): ... TypeError: unable to find a common ring for all elements @@ -652,8 +660,8 @@ def prepare(v, R, degree=None): Some objects can be converted to sequences even if they are not always thought of as sequences. :: - sage: c = CDF(2+3*I) - sage: prepare(c, None) + sage: c = CDF(2 + 3*I) # needs sage.symbolic + sage: prepare(c, None) # needs sage.symbolic ([2.0, 3.0], Real Double Field) This checks a bug listed at :trac:`10595`. Without good evidence @@ -746,7 +754,7 @@ def zero_vector(arg0, arg1=None): Garbage instead of a ring will be recognized as such. :: - sage: zero_vector(x^2, 5) # optional - sage.symbolic + sage: zero_vector(x^2, 5) # needs sage.symbolic Traceback (most recent call last): ... TypeError: first argument must be a ring @@ -944,20 +952,20 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(ZZ, 4, range(4)) - sage: giac(v) + v # optional - sage.libs.giac + sage: giac(v) + v # needs sage.libs.giac [0,2,4,6] :: sage: v = vector(QQ, 3, [2/3, 0, 5/4]) - sage: giac(v) # optional - sage.libs.giac + sage: giac(v) # needs sage.libs.giac [2/3,0,5/4] :: sage: P. = ZZ[] sage: v = vector(P, 3, [x^2 + 2, 2*x + 1, -2*x^2 + 4*x]) - sage: giac(v) # optional - sage.libs.giac + sage: giac(v) # needs sage.libs.giac [sageVARx^2+2,2*sageVARx+1,-2*sageVARx^2+4*sageVARx] """ return self.list() @@ -973,15 +981,15 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(range(4)) - sage: v.__pari__() # optional - sage.libs.pari + sage: v.__pari__() # needs sage.libs.pari [0, 1, 2, 3] - sage: v.__pari__().type() # optional - sage.libs.pari + sage: v.__pari__().type() # needs sage.libs.pari 't_VEC' A list of vectors:: sage: L = [vector(i^n for i in range(4)) for n in [1,3,5]] - sage: pari(L) # optional - sage.libs.pari + sage: pari(L) # needs sage.libs.pari [[0, 1, 2, 3], [0, 1, 8, 27], [0, 1, 32, 243]] """ from sage.libs.pari.all import pari @@ -999,16 +1007,16 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(range(4)) - sage: v._pari_init_() # optional - sage.libs.pari + sage: v._pari_init_() # needs sage.libs.pari '[0,1,2,3]' Create the multiplication table of `GF(4)` using GP:: - sage: k. = GF(4, impl="pari_ffelt") # optional - sage.libs.pari - sage: v = gp(vector(list(k))) # optional - sage.libs.pari - sage: v # optional - sage.libs.pari + sage: k. = GF(4, impl="pari_ffelt") # needs sage.libs.pari + sage: v = gp(vector(list(k))) # needs sage.libs.pari + sage: v # needs sage.libs.pari [0, 1, a, a + 1] - sage: v.mattranspose() * v # optional - sage.libs.pari + sage: v.mattranspose() * v # needs sage.libs.pari [0, 0, 0, 0; 0, 1, a, a + 1; 0, a, a + 1, 1; 0, a + 1, 1, a] """ # Elements in vectors are always Sage Elements, so they should @@ -1074,48 +1082,48 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector([1,2,3]) - sage: v.numpy() # optional - numpy + sage: v.numpy() # needs numpy array([1, 2, 3], dtype=object) - sage: v.numpy() * v.numpy() # optional - numpy + sage: v.numpy() * v.numpy() # needs numpy array([1, 4, 9], dtype=object) - sage: vector(QQ, [1, 2, 5/6]).numpy() # optional - numpy + sage: vector(QQ, [1, 2, 5/6]).numpy() # needs numpy array([1, 2, 5/6], dtype=object) By default the ``object`` `dtype `_ is used. Alternatively, the desired dtype can be passed in as a parameter:: sage: v = vector(QQ, [1, 2, 5/6]) - sage: v.numpy() # optional - numpy + sage: v.numpy() # needs numpy array([1, 2, 5/6], dtype=object) - sage: v.numpy(dtype=float) # optional - numpy + sage: v.numpy(dtype=float) # needs numpy array([1. , 2. , 0.83333333]) - sage: v.numpy(dtype=int) # optional - numpy + sage: v.numpy(dtype=int) # needs numpy array([1, 2, 0]) - sage: import numpy # optional - numpy - sage: v.numpy(dtype=numpy.uint8) # optional - numpy + sage: import numpy # needs numpy + sage: v.numpy(dtype=numpy.uint8) # needs numpy array([1, 2, 0], dtype=uint8) Passing a dtype of None will let numpy choose a native type, which can be more efficient but may have unintended consequences:: - sage: v.numpy(dtype=None) # optional - numpy + sage: v.numpy(dtype=None) # needs numpy array([1. , 2. , 0.83333333]) sage: w = vector(ZZ, [0, 1, 2^63 -1]); w (0, 1, 9223372036854775807) - sage: wn = w.numpy(dtype=None); wn # optional - numpy + sage: wn = w.numpy(dtype=None); wn # needs numpy array([ 0, 1, 9223372036854775807]...) - sage: wn.dtype # optional - numpy + sage: wn.dtype # needs numpy dtype('int64') - sage: w.dot_product(w) # optional - numpy + sage: w.dot_product(w) # needs numpy 85070591730234615847396907784232501250 - sage: wn.dot(wn) # overflow # optional - numpy + sage: wn.dot(wn) # overflow # needs numpy 2 Numpy can give rather obscure errors; we wrap these to give a bit of context:: - sage: vector([1, 1/2, QQ['x'].0]).numpy(dtype=float) # optional - numpy + sage: vector([1, 1/2, QQ['x'].0]).numpy(dtype=float) # needs numpy Traceback (most recent call last): ... ValueError: Could not convert vector over Univariate Polynomial Ring in x over Rational Field to numpy array of type <... 'float'>: setting an array element with a sequence. @@ -1133,13 +1141,13 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) # optional - sage.symbolic - sage: v.__hash__() # optional - sage.symbolic + sage: v = vector([1,2/3,pi]) # needs sage.symbolic + sage: v.__hash__() # needs sage.symbolic Traceback (most recent call last): ... TypeError: mutable vectors are unhashable - sage: v.set_immutable() # optional - sage.symbolic - sage: v.__hash__() # random output # optional - sage.symbolic + sage: v.set_immutable() # needs sage.symbolic + sage: v.__hash__() # random output # needs sage.symbolic """ if not self._is_immutable: raise TypeError("mutable vectors are unhashable") @@ -1161,7 +1169,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: vector(vector((1, 6.8))) (1.00000000000000, 6.80000000000000) - sage: vector(vector(SR, (1, sqrt(2)) ) ) + sage: vector(vector(SR, (1, sqrt(2)) ) ) # needs sage.symbolic (1, sqrt(2)) """ if R is None: @@ -1174,7 +1182,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: sage_input(vector(RR, [pi, e, 0.5]), verify=True) + sage: sage_input(vector(RR, [pi, e, 0.5]), verify=True) # needs sage.symbolic # Verified vector(RR, [3.1415926535897931, 2.7182818284590451, 0.5]) sage: sage_input(vector(GF(5), [1, 2, 3, 4, 5]), verify=True) @@ -1192,7 +1200,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: from sage.misc.sage_input import SageInputBuilder sage: vector(ZZ, [42, 389])._sage_input_(SageInputBuilder(), False) {call: {atomic:vector}({atomic:ZZ}, {list: ({atomic:42}, {atomic:389})})} - sage: vector(RDF, {1:pi, 1000:e})._sage_input_(SageInputBuilder(), False) # optional - sage.symbolic + sage: vector(RDF, {1:pi, 1000:e})._sage_input_(SageInputBuilder(), False) # needs sage.symbolic {call: {atomic:vector}({atomic:RDF}, {dict: {{atomic:1}:{atomic:3.1415926535897931}, {atomic:1000}:{atomic:2.718281828459045...}}})} """ # Not a lot of room for prettiness here. @@ -1381,19 +1389,19 @@ cdef class FreeModuleElement(Vector): # abstract base class then taking a transpose. Notice that supplying a vector to the matrix constructor demonstrates Sage's preference for rows. :: - sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # optional - sage.symbolic - sage: x.row() == matrix(x) # optional - sage.symbolic + sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # needs sage.symbolic + sage: x.row() == matrix(x) # needs sage.symbolic True - sage: x.row() == x.column().transpose() # optional - sage.symbolic + sage: x.row() == x.column().transpose() # needs sage.symbolic True Sparse or dense implementations are preserved. :: sage: d = vector(RR, [1.0, 2.0, 3.0]) - sage: s = vector(CDF, {2:5.0+6.0*I}) + sage: s = vector(CDF, {2: 5.0+6.0*I}) # needs sage.symbolic sage: dm = d.row() - sage: sm = s.row() - sage: all([d.is_dense(), dm.is_dense(), s.is_sparse(), sm.is_sparse()]) + sage: sm = s.row() # needs sage.symbolic + sage: all([d.is_dense(), dm.is_dense(), s.is_sparse(), sm.is_sparse()]) # needs sage.symbolic True TESTS: @@ -1453,19 +1461,19 @@ cdef class FreeModuleElement(Vector): # abstract base class then taking a transpose. Notice that supplying a vector to the matrix constructor demonstrates Sage's preference for rows. :: - sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # optional - sage.libs.pari sage.symbolic - sage: x.column() == matrix(x).transpose() # optional - sage.libs.pari sage.symbolic + sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # needs sage.libs.pari sage.symbolic + sage: x.column() == matrix(x).transpose() # needs sage.libs.pari sage.symbolic True - sage: x.column() == x.row().transpose() # optional - sage.libs.pari sage.symbolic + sage: x.column() == x.row().transpose() # needs sage.libs.pari sage.symbolic True Sparse or dense implementations are preserved. :: sage: d = vector(RR, [1.0, 2.0, 3.0]) - sage: s = vector(CDF, {2:5.0+6.0*I}) + sage: s = vector(CDF, {2: 5.0+6.0*I}) # needs sage.symbolic sage: dm = d.column() - sage: sm = s.column() - sage: all([d.is_dense(), dm.is_dense(), s.is_sparse(), sm.is_sparse()]) + sage: sm = s.column() # needs sage.symbolic + sage: all([d.is_dense(), dm.is_dense(), s.is_sparse(), sm.is_sparse()]) # needs sage.symbolic True TESTS: @@ -1523,12 +1531,12 @@ cdef class FreeModuleElement(Vector): # abstract base class """ EXAMPLES:: - sage: var('a,b,d,e') # optional - sage.symbolic + sage: var('a,b,d,e') # needs sage.symbolic (a, b, d, e) - sage: v = vector([a, b, d, e]) # optional - sage.symbolic - sage: v.substitute(a=1) # optional - sage.symbolic + sage: v = vector([a, b, d, e]) # needs sage.symbolic + sage: v.substitute(a=1) # needs sage.symbolic (1, b, d, e) - sage: v.subs(a=b, b=d) # optional - sage.symbolic + sage: v.subs(a=b, b=d) # needs sage.symbolic (b, d, d, e) """ return self.parent()([ a.subs(in_dict, **kwds) for a in self.list() ]) @@ -1547,7 +1555,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Check for :trac:`29630`:: sage: v = vector(QQ, 4, {0:1}, sparse=True) - sage: v.change_ring(AA).is_sparse() # optional - sage.rings.number_field + sage: v.change_ring(AA).is_sparse() # needs sage.rings.number_field True """ if self.base_ring() is R: @@ -1616,17 +1624,17 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) # optional - sage.symbolic - sage: v.items() # optional - sage.symbolic + sage: v = vector([1,2/3,pi]) # needs sage.symbolic + sage: v.items() # needs sage.symbolic - sage: list(v.items()) # optional - sage.symbolic + sage: list(v.items()) # needs sage.symbolic [(0, 1), (1, 2/3), (2, pi)] TESTS: Using iteritems as an alias:: - sage: list(v.iteritems()) # optional - sage.symbolic + sage: list(v.iteritems()) # needs sage.symbolic [(0, 1), (1, 2/3), (2, pi)] """ cdef dict d = self.dict(copy=False) @@ -1641,7 +1649,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1..5]); abs(v) # optional - sage.symbolic + sage: v = vector([1..5]); abs(v) # needs sage.symbolic sqrt(55) sage: v = vector(RDF, [1..5]); abs(v) 7.416198487095663 @@ -1668,14 +1676,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector([1,2,-3]) - sage: v.norm(5) # optional - sage.symbolic + sage: v.norm(5) # needs sage.symbolic 276^(1/5) The default is the usual Euclidean norm. :: - sage: v.norm() # optional - sage.symbolic + sage: v.norm() # needs sage.symbolic sqrt(14) - sage: v.norm(2) # optional - sage.symbolic + sage: v.norm(2) # needs sage.symbolic sqrt(14) The infinity norm is the maximum size (in absolute value) @@ -1691,10 +1699,10 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v=vector(RDF,[1,2,3]) sage: v.norm(5) 3.077384885394063 - sage: v.norm(pi/2) #abs tol 1e-15 # optional - sage.symbolic + sage: v.norm(pi/2) #abs tol 1e-15 # needs sage.symbolic 4.216595864704748 - sage: _=var('a b c d p'); v=vector([a, b, c, d]) # optional - sage.symbolic - sage: v.norm(p) # optional - sage.symbolic + sage: _=var('a b c d p'); v=vector([a, b, c, d]) # needs sage.symbolic + sage: v.norm(p) # needs sage.symbolic (abs(a)^p + abs(b)^p + abs(c)^p + abs(d)^p)^(1/p) Notice that the result may be a symbolic expression, owing to @@ -1708,13 +1716,13 @@ cdef class FreeModuleElement(Vector): # abstract base class Rational Field sage: v = vector(QQ, [3, 5]) - sage: nrm = v.norm(); nrm # optional - sage.symbolic + sage: nrm = v.norm(); nrm # needs sage.symbolic sqrt(34) - sage: nrm.parent() # optional - sage.symbolic + sage: nrm.parent() # needs sage.symbolic Symbolic Ring - sage: numeric = N(nrm); numeric # optional - sage.symbolic + sage: numeric = N(nrm); numeric # needs sage.symbolic 5.83095189484... - sage: numeric.parent() # optional - sage.symbolic + sage: numeric.parent() # needs sage.symbolic Real Field with 53 bits of precision TESTS: @@ -1731,7 +1739,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Norm works with Python integers (see :trac:`13502`). :: sage: v = vector(QQ, [1,2]) - sage: v.norm(int(2)) # optional - sage.symbolic + sage: v.norm(int(2)) # needs sage.symbolic sqrt(5) """ abs_self = [abs(x) for x in self] @@ -1747,17 +1755,17 @@ cdef class FreeModuleElement(Vector): # abstract base class """ EXAMPLES:: - sage: v = vector(SR, [0,0,0,0]) # optional - sage.symbolic - sage: v == 0 # optional - sage.symbolic + sage: v = vector(SR, [0,0,0,0]) # needs sage.symbolic + sage: v == 0 # needs sage.symbolic True - sage: v == 1 # optional - sage.symbolic + sage: v == 1 # needs sage.symbolic False - sage: v == v # optional - sage.symbolic + sage: v == v # needs sage.symbolic True - sage: w = vector(SR, [-1,x,pi,0]) # optional - sage.symbolic - sage: bool(w < v) # optional - sage.symbolic + sage: w = vector(SR, [-1,x,pi,0]) # needs sage.symbolic + sage: bool(w < v) # needs sage.symbolic True - sage: bool(w > v) # optional - sage.symbolic + sage: bool(w > v) # needs sage.symbolic False TESTS:: @@ -1772,14 +1780,14 @@ cdef class FreeModuleElement(Vector): # abstract base class Verify that :trac:`33697` is fixed:: - sage: v = vector(SR, [x]) # optional - sage.symbolic - sage: w = vector(SR, [1]) # optional - sage.symbolic - sage: v == w # optional - sage.symbolic + sage: v = vector(SR, [x]) # needs sage.symbolic + sage: w = vector(SR, [1]) # needs sage.symbolic + sage: v == w # needs sage.symbolic False - sage: assume(x > 0) # optional - sage.symbolic - sage: v == w # optional - sage.symbolic + sage: assume(x > 0) # needs sage.symbolic + sage: v == w # needs sage.symbolic False - sage: forget() # optional - sage.symbolic + sage: forget() # needs sage.symbolic """ cdef Py_ssize_t i for i in range(left._degree): @@ -1836,7 +1844,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector(SR, [1/2,2/5,0]).get(0) # optional - sage.symbolic + sage: vector(SR, [1/2,2/5,0]).get(0) # needs sage.symbolic 1/2 """ return self.get_unsafe(i) @@ -1899,9 +1907,9 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector(SR, [1/2,2/5,0]); v # optional - sage.symbolic + sage: v = vector(SR, [1/2,2/5,0]); v # needs sage.symbolic (1/2, 2/5, 0) - sage: v.set(2, pi); v # optional - sage.symbolic + sage: v.set(2, pi); v # needs sage.symbolic (1/2, 2/5, pi) """ assert value.parent() is self.coordinate_ring() @@ -1914,7 +1922,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector([1,2/3,pi]).__invert__() # optional - sage.symbolic + sage: vector([1,2/3,pi]).__invert__() # needs sage.symbolic Traceback (most recent call last): ... NotImplementedError @@ -1996,8 +2004,8 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) # optional - sage.symbolic - sage: v.list_from_positions([0,0,0,2,1]) # optional - sage.symbolic + sage: v = vector([1, 2/3, pi]) # needs sage.symbolic + sage: v.list_from_positions([0,0,0,2,1]) # needs sage.symbolic [1, 1, 1, pi, 2/3] """ cdef Py_ssize_t i @@ -2111,10 +2119,10 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: x = var('x') # optional - sage.symbolic - sage: v = vector([x/(2*x)+sqrt(2)+var('theta')^3,x/(2*x)]); v # optional - sage.symbolic + sage: x = var('x') # needs sage.symbolic + sage: v = vector([x/(2*x)+sqrt(2)+var('theta')^3,x/(2*x)]); v # needs sage.symbolic (theta^3 + sqrt(2) + 1/2, 1/2) - sage: v._repr_() # optional - sage.symbolic + sage: v._repr_() # needs sage.symbolic '(theta^3 + sqrt(2) + 1/2, 1/2)' """ cdef Py_ssize_t d = self._degree @@ -2288,84 +2296,84 @@ cdef class FreeModuleElement(Vector): # abstract base class The following both plot the given vector:: sage: v = vector(RDF, (1,2)) - sage: A = plot(v) # optional - sage.plot - sage: B = v.plot() # optional - sage.plot - sage: A+B # should just show one vector # optional - sage.plot + sage: A = plot(v) # needs sage.plot + sage: B = v.plot() # needs sage.plot + sage: A+B # should just show one vector # needs sage.plot Graphics object consisting of 2 graphics primitives Examples of the plot types:: - sage: A = plot(v, plot_type='arrow') # optional - sage.plot - sage: B = plot(v, plot_type='point', color='green', size=20) # optional - sage.plot - sage: C = plot(v, plot_type='step') # calls v.plot_step() # optional - sage.plot - sage: A+B+C # optional - sage.plot + sage: A = plot(v, plot_type='arrow') # needs sage.plot + sage: B = plot(v, plot_type='point', color='green', size=20) # needs sage.plot + sage: C = plot(v, plot_type='step') # calls v.plot_step() # needs sage.plot + sage: A+B+C # needs sage.plot Graphics object consisting of 3 graphics primitives You can use the optional arguments for :meth:`plot_step`:: - sage: eps = 0.1 # optional - sage.plot - sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # optional - sage.plot + sage: eps = 0.1 # needs sage.plot + sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # needs sage.plot Graphics object consisting of 1 graphics primitive Three-dimensional examples:: sage: v = vector(RDF, (1,2,1)) - sage: plot(v) # defaults to an arrow plot # optional - sage.plot + sage: plot(v) # defaults to an arrow plot # needs sage.plot Graphics3d Object :: - sage: plot(v, plot_type='arrow') # optional - sage.plot + sage: plot(v, plot_type='arrow') # needs sage.plot Graphics3d Object :: - sage: from sage.plot.plot3d.shapes2 import frame3d # optional - sage.plot - sage: plot(v, plot_type='point')+frame3d((0,0,0), v.list()) # optional - sage.plot + sage: from sage.plot.plot3d.shapes2 import frame3d # needs sage.plot + sage: plot(v, plot_type='point')+frame3d((0,0,0), v.list()) # needs sage.plot Graphics3d Object :: - sage: plot(v, plot_type='step') # calls v.plot_step() # optional - sage.plot + sage: plot(v, plot_type='step') # calls v.plot_step() # needs sage.plot Graphics object consisting of 1 graphics primitive :: - sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # optional - sage.plot + sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # needs sage.plot Graphics object consisting of 1 graphics primitive With greater than three coordinates, it defaults to a step plot:: sage: v = vector(RDF, (1,2,3,4)) - sage: plot(v) # optional - sage.plot + sage: plot(v) # needs sage.plot Graphics object consisting of 1 graphics primitive One dimensional vectors are plotted along the horizontal axis of the coordinate plane:: - sage: plot(vector([1])) # optional - sage.plot + sage: plot(vector([1])) # needs sage.plot Graphics object consisting of 1 graphics primitive An optional start argument may also be specified by a tuple, list, or vector:: sage: u = vector([1,2]); v = vector([2,5]) - sage: plot(u, start=v) # optional - sage.plot + sage: plot(u, start=v) # needs sage.plot Graphics object consisting of 1 graphics primitive TESTS:: - sage: u = vector([1,1]); v = vector([2,2,2]); z=(3,3,3) # optional - sage.plot - sage: plot(u) #test when start=None # optional - sage.plot + sage: u = vector([1,1]); v = vector([2,2,2]); z=(3,3,3) # needs sage.plot + sage: plot(u) #test when start=None # needs sage.plot Graphics object consisting of 1 graphics primitive :: - sage: plot(u, start=v) #test when coordinate dimension mismatch exists # optional - sage.plot + sage: plot(u, start=v) #test when coordinate dimension mismatch exists # needs sage.plot Traceback (most recent call last): ... ValueError: vector coordinates are not of the same dimension - sage: P = plot(v, start=z) # test when start coordinates are passed as a tuple # optional - sage.plot - sage: P = plot(v, start=list(z)) # test when start coordinates are passed as a list # optional - sage.plot + sage: P = plot(v, start=z) # test when start coordinates are passed as a tuple # needs sage.plot + sage: P = plot(v, start=list(z)) # test when start coordinates are passed as a list # needs sage.plot """ # Give sensible defaults based on the vector length if plot_type is None: @@ -2437,8 +2445,8 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: eps = 0.1 - sage: v = vector(RDF, [sin(n*eps) for n in range(100)]) # optional - sage.plot - sage: v.plot_step(eps=eps, xmax=5, hue=0) # optional - sage.plot + sage: v = vector(RDF, [sin(n*eps) for n in range(100)]) # needs sage.plot + sage: v.plot_step(eps=eps, xmax=5, hue=0) # needs sage.plot Graphics object consisting of 1 graphics primitive """ import math @@ -2564,7 +2572,7 @@ cdef class FreeModuleElement(Vector): # abstract base class The dot product of a vector with itself is the 2-norm, squared. :: sage: v = vector(QQ, [3, 4, 7]) - sage: v.dot_product(v) - v.norm()^2 # optional - sage.symbolic + sage: v.dot_product(v) - v.norm()^2 # needs sage.symbolic 0 TESTS: @@ -2602,8 +2610,8 @@ cdef class FreeModuleElement(Vector): # abstract base class Check for :trac:`33814`:: sage: rings = [ZZ, QQ, RDF, ZZ['x']] - sage: rings += [RR] # optional - sage.rings.real_mpfr - sage: rings += [GF(2), GF(3), GF(4)] # optional - sage.rings.finite_rings + sage: rings += [RR] # needs sage.rings.real_mpfr + sage: rings += [GF(2), GF(3), GF(4)] # needs sage.rings.finite_rings sage: for R in rings: ....: _ = (R**0)().dot_product((R**0)()) """ @@ -2763,9 +2771,9 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: F = GF(previous_prime(2^32)) # optional - sage.rings.finite_rings - sage: v = random_vector(F, 3) # optional - sage.rings.finite_rings - sage: w = random_vector(F, 3) # optional - sage.rings.finite_rings + sage: F = GF(previous_prime(2^32)) # needs sage.rings.finite_rings + sage: v = random_vector(F, 3) # needs sage.rings.finite_rings + sage: w = random_vector(F, 3) # needs sage.rings.finite_rings sage: vh = v.cross_product_matrix() sage: vh*w == v.cross_product(w) True @@ -2773,8 +2781,8 @@ cdef class FreeModuleElement(Vector): # abstract base class True sage: vh.is_alternating() True - sage: v = random_vector(F, 7) # optional - sage.rings.finite_rings - sage: w = random_vector(F, 7) # optional - sage.rings.finite_rings + sage: v = random_vector(F, 7) # needs sage.rings.finite_rings + sage: w = random_vector(F, 7) # needs sage.rings.finite_rings sage: vh = v.cross_product_matrix() sage: vh*w == v.cross_product(w) True @@ -2782,7 +2790,7 @@ cdef class FreeModuleElement(Vector): # abstract base class True sage: vh.is_alternating() True - sage: random_vector(F, 5).cross_product_matrix() # optional - sage.libs.pari + sage: random_vector(F, 5).cross_product_matrix() # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Cross product only defined for vectors of length three or seven, not 5 @@ -2933,12 +2941,12 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: R. = QQ[] sage: vector([x, y, 3])._variables() [x, y, z] - sage: vector(SR, [x, y, 3])._variables() # optional - sage.symbolic + sage: vector(SR, [x, y, 3])._variables() # needs sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: v(x, y, z) = (-y, x, 0) # optional - sage.symbolic - sage: v._variables() # optional - sage.symbolic + sage: v(x, y, z) = (-y, x, 0) # needs sage.symbolic + sage: v._variables() # needs sage.symbolic [(x, y, z) |--> x, (x, y, z) |--> y, (x, y, z) |--> z] """ R = self._parent.base_ring() @@ -2971,11 +2979,11 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: vector([x*y, y*z, z*x]).div([x, y, w]) y + z - sage: vector(SR, [x*y, y*z, z*x]).div() # optional - sage.symbolic + sage: vector(SR, [x*y, y*z, z*x]).div() # needs sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: vector(SR, [x*y, y*z, z*x]).div([x, y, z]) # optional - sage.symbolic + sage: vector(SR, [x*y, y*z, z*x]).div([x, y, z]) # needs sage.symbolic x + y + z .. SEEALSO:: @@ -3012,18 +3020,18 @@ cdef class FreeModuleElement(Vector): # abstract base class For rings where the variable order is not well defined, it must be defined explicitly:: - sage: v = vector(SR, [-y, x, 0]) # optional - sage.symbolic - sage: v.curl() # optional - sage.symbolic + sage: v = vector(SR, [-y, x, 0]) # needs sage.symbolic + sage: v.curl() # needs sage.symbolic Traceback (most recent call last): ... ValueError: Unable to determine ordered variable names for Symbolic Ring - sage: v.curl([x, y, z]) # optional - sage.symbolic + sage: v.curl([x, y, z]) # needs sage.symbolic (0, 0, 2) Note that callable vectors have well defined variable orderings:: - sage: v(x, y, z) = (-y, x, 0) # optional - sage.symbolic - sage: v.curl() # optional - sage.symbolic + sage: v(x, y, z) = (-y, x, 0) # needs sage.symbolic + sage: v.curl() # needs sage.symbolic (x, y, z) |--> (0, 0, 2) In two-dimensions, this returns a scalar value:: @@ -3108,14 +3116,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: v = vector(QQ, [4, 1, 3, 2]) - sage: v.normalized() # optional - sage.symbolic + sage: v.normalized() # needs sage.symbolic (2/15*sqrt(30), 1/30*sqrt(30), 1/10*sqrt(30), 1/15*sqrt(30)) sage: sum(v.normalized(1)) 1 Note that normalizing the vector may change the base ring:: - sage: v.base_ring() == v.normalized().base_ring() # optional - sage.symbolic + sage: v.base_ring() == v.normalized().base_ring() # needs sage.symbolic False sage: u = vector(RDF, [-3, 4, 6, 9]) sage: u.base_ring() == u.normalized().base_ring() @@ -3136,10 +3144,10 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector(CDF, [2.3 - 5.4*I, -1.7 + 3.6*I]) - sage: w = v.conjugate(); w + sage: v = vector(CDF, [2.3 - 5.4*I, -1.7 + 3.6*I]) # needs sage.symbolic + sage: w = v.conjugate(); w # needs sage.symbolic (2.3 + 5.4*I, -1.7 - 3.6*I) - sage: w.parent() + sage: w.parent() # needs sage.symbolic Vector space of dimension 2 over Complex Double Field Even if conjugation seems nonsensical over a certain ring, this @@ -3153,15 +3161,16 @@ cdef class FreeModuleElement(Vector): # abstract base class such as the cyclotomic fields. This example uses such a field containing a primitive 7-th root of unity named ``a``. :: - sage: F. = CyclotomicField(7) # optional - sage.rings.number_field - sage: v = vector(F, [a^i for i in range(7)]) # optional - sage.rings.number_field - sage: v # optional - sage.rings.number_field + sage: F. = CyclotomicField(7) # needs sage.rings.number_field + sage: v = vector(F, [a^i for i in range(7)]) # needs sage.rings.number_field + sage: v # needs sage.rings.number_field (1, a, a^2, a^3, a^4, a^5, -a^5 - a^4 - a^3 - a^2 - a - 1) - sage: v.conjugate() # optional - sage.rings.number_field + sage: v.conjugate() # needs sage.rings.number_field (1, -a^5 - a^4 - a^3 - a^2 - a - 1, a^5, a^4, a^3, a^2, a) Sparse vectors are returned as such. :: + sage: # needs sage.symbolic sage: v = vector(CC, {1: 5 - 6*I, 3: -7*I}); v (0.000000000000000, 5.00000000000000 - 6.00000000000000*I, 0.000000000000000, -7.00000000000000*I) sage: v.is_sparse() @@ -3174,10 +3183,10 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: sage: n = 15 - sage: x = vector(CDF, [sin(i*pi/n)+cos(i*pi/n)*I for i in range(n)]) # optional - sage.symbolic - sage: x + x.conjugate() in RDF^n # optional - sage.symbolic + sage: x = vector(CDF, [sin(i*pi/n)+cos(i*pi/n)*I for i in range(n)]) # needs sage.symbolic + sage: x + x.conjugate() in RDF^n # needs sage.symbolic True - sage: I*(x - x.conjugate()) in RDF^n # optional - sage.symbolic + sage: I*(x - x.conjugate()) in RDF^n # needs sage.symbolic True The parent of the conjugate is the same as that of the original vector. @@ -3410,7 +3419,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: w = vector(GF(5), [1,2]) sage: v = vector(GF(7), [1,2,3,4]) - sage: z = w.outer_product(v) # optional - sage.rings.finite_rings + sage: z = w.outer_product(v) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 1 dense matrices over Finite Field of size 5' and 'Full MatrixSpace of 1 by 4 dense matrices over Finite Field of size 7' @@ -3462,6 +3471,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: + sage: # needs sage.symbolic sage: v = vector(CDF, [2+3*I, 5-4*I]) sage: w = vector(CDF, [6-4*I, 2+3*I]) sage: v.hermitian_inner_product(w) @@ -3472,6 +3482,7 @@ cdef class FreeModuleElement(Vector): # abstract base class the base rings have a conjugate method, then the Hermitian inner product will be available. :: + sage: # needs sage.rings.number_field sage: Q. = QuadraticField(-7) sage: a^2 -7 @@ -3485,6 +3496,7 @@ cdef class FreeModuleElement(Vector): # abstract base class in each argument (with conjugation on the first scalar), and anti-commutative. :: + sage: # needs sage.symbolic sage: alpha = CDF(5.0 + 3.0*I) sage: u = vector(CDF, [2+4*I, -3+5*I, 2-7*I]) sage: v = vector(CDF, [-1+3*I, 5+4*I, 9-2*I]) @@ -3524,15 +3536,15 @@ cdef class FreeModuleElement(Vector): # abstract base class def is_dense(self): """ - Return True if this is a dense vector, which is just a + Return ``True`` if this is a dense vector, which is just a statement about the data structure, not the number of nonzero entries. EXAMPLES:: - sage: vector([1/2,2/5,0]).is_dense() + sage: vector([1/2, 2/5, 0]).is_dense() True - sage: vector([1/2,2/5,0],sparse=True).is_dense() + sage: vector([1/2, 2/5, 0], sparse=True).is_dense() False """ return self.is_dense_c() @@ -3542,15 +3554,15 @@ cdef class FreeModuleElement(Vector): # abstract base class def is_sparse(self): """ - Return True if this is a sparse vector, which is just a + Return ``True`` if this is a sparse vector, which is just a statement about the data structure, not the number of nonzero entries. EXAMPLES:: - sage: vector([1/2,2/5,0]).is_sparse() + sage: vector([1/2, 2/5, 0]).is_sparse() False - sage: vector([1/2,2/5,0],sparse=True).is_sparse() + sage: vector([1/2, 2/5, 0], sparse=True).is_sparse() True """ return self.is_sparse_c() @@ -3560,11 +3572,11 @@ cdef class FreeModuleElement(Vector): # abstract base class def is_vector(self): """ - Return True, since this is a vector. + Return ``True``, since this is a vector. EXAMPLES:: - sage: vector([1/2,2/5,0]).is_vector() + sage: vector([1/2, 2/5, 0]).is_vector() True """ return True @@ -3610,13 +3622,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector((1,2,3), QQ)._mathematica_init_() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: vector((1,2,3), QQ)._mathematica_init_() '{1/1, 2/1, 3/1}' - sage: mathematica(vector((1,2,3), QQ)) # optional - mathematica sage.symbolic + sage: mathematica(vector((1,2,3), QQ)) # optional - mathematica {1, 2, 3} - sage: a = vector(SR, 5, [1, x, x^2, sin(x), pi]); a # optional - sage.symbolic + sage: a = vector(SR, 5, [1, x, x^2, sin(x), pi]); a (1, x, x^2, sin(x), pi) - sage: a._mathematica_init_() # optional - mathematica sage.symbolic + sage: a._mathematica_init_() # optional - mathematica '{1, x, (x)^(2), Sin[x], Pi}' """ return '{' + ', '.join(x._mathematica_init_() for x in self.list()) + '}' @@ -3634,16 +3647,16 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v = vector([1, 2, 3]); v (1, 2, 3) - sage: sv = v._sympy_(); sv # optional - sympy + sage: sv = v._sympy_(); sv # needs sympy Matrix([ [1], [2], [3]]) - sage: type(sv) # optional - sympy + sage: type(sv) # needs sympy sage: w = vector({1: 1, 5: -1}, sparse=True) - sage: sw = w._sympy_(); sw # optional - sympy + sage: sw = w._sympy_(); sw # needs sympy Matrix([ [ 0], [ 1], @@ -3651,26 +3664,26 @@ cdef class FreeModuleElement(Vector): # abstract base class [ 0], [ 0], [-1]]) - sage: type(sw) # optional - sympy + sage: type(sw) # needs sympy If ``self`` was immutable, then converting the result to Sage gives back ``self``:: sage: immv = vector([1, 2, 3], immutable=True) - sage: immv._sympy_()._sage_() is immv # optional - sympy + sage: immv._sympy_()._sage_() is immv # needs sympy True If ``self`` was mutable, then converting back to Sage creates a new matrix (column vector):: - sage: sv._sage_() # optional - sympy + sage: sv._sage_() # needs sympy [1] [2] [3] - sage: sv._sage_() is v # optional - sympy + sage: sv._sage_() is v # needs sympy False - sage: sv._sage_() == v # optional - sympy + sage: sv._sage_() == v # needs sympy False """ from sage.interfaces.sympy import sympy_init @@ -3823,17 +3836,17 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: m = vector([1,x,sin(x+1)]) # optional - sage.symbolic - sage: m.apply_map(lambda x: x^2) # optional - sage.symbolic + sage: m = vector([1,x,sin(x+1)]) # needs sage.symbolic + sage: m.apply_map(lambda x: x^2) # needs sage.symbolic (1, x^2, sin(x + 1)^2) - sage: m.apply_map(sin) # optional - sage.symbolic + sage: m.apply_map(sin) # needs sage.symbolic (sin(1), sin(x), sin(sin(x + 1))) :: sage: m = vector(ZZ, 9, range(9)) - sage: k. = GF(9) # optional - sage.libs.pari - sage: m.apply_map(k) # optional - sage.libs.pari + sage: k. = GF(9) # needs sage.rings.finite_rings + sage: m.apply_map(k) # needs sage.rings.finite_rings (0, 1, 2, 0, 1, 2, 0, 1, 2) In this example, we explicitly specify the codomain. @@ -3842,9 +3855,9 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: s = GF(3) sage: f = lambda x: s(x) - sage: n = m.apply_map(f, k); n # optional - sage.rings.finite_rings + sage: n = m.apply_map(f, k); n # needs sage.rings.finite_rings (0, 1, 2, 0, 1, 2, 0, 1, 2) - sage: n.parent() # optional - sage.libs.pari + sage: n.parent() # needs sage.rings.finite_rings Vector space of dimension 9 over Finite Field in a of size 3^2 If your map sends 0 to a non-zero value, then your resulting @@ -3879,8 +3892,8 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: m = vector(SR,[]) # optional - sage.symbolic - sage: m.apply_map(lambda x: x*x) == m # optional - sage.symbolic + sage: m = vector(SR,[]) # needs sage.symbolic + sage: m.apply_map(lambda x: x*x) == m # needs sage.symbolic True Check that we don't unnecessarily apply phi to 0 in the sparse case:: @@ -3900,10 +3913,10 @@ cdef class FreeModuleElement(Vector): # abstract base class Check that the bug in :trac:`14558` has been fixed:: - sage: F. = GF(9) # optional - sage.libs.pari - sage: v = vector([a, 0, 0, 0], sparse=True) # optional - sage.libs.pari - sage: f = F.hom([a**3]) # optional - sage.libs.pari - sage: v.apply_map(f) # optional - sage.libs.pari + sage: F. = GF(9) # needs sage.rings.finite_rings + sage: v = vector([a, 0, 0, 0], sparse=True) # needs sage.rings.finite_rings + sage: f = F.hom([a**3]) # needs sage.rings.finite_rings + sage: v.apply_map(f) # needs sage.rings.finite_rings (2*a + 1, 0, 0, 0) """ if sparse is None: @@ -3957,31 +3970,31 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,x,x^2]) # optional - sage.symbolic - sage: v._derivative(x) # optional - sage.symbolic + sage: v = vector([1,x,x^2]) # needs sage.symbolic + sage: v._derivative(x) # needs sage.symbolic (0, 1, 2*x) - sage: type(v._derivative(x)) == type(v) # optional - sage.symbolic + sage: type(v._derivative(x)) == type(v) # needs sage.symbolic True - sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic - sage: v._derivative(x) # optional - sage.symbolic + sage: v = vector([1,x,x^2], sparse=True) # needs sage.symbolic + sage: v._derivative(x) # needs sage.symbolic (0, 1, 2*x) - sage: type(v._derivative(x)) == type(v) # optional - sage.symbolic + sage: type(v._derivative(x)) == type(v) # needs sage.symbolic True If no variables are specified and the vector contains callable symbolic expressions, then calculate the matrix derivative (i.e., the Jacobian matrix):: - sage: T(r,theta) = [r*cos(theta), r*sin(theta)] # optional - sage.symbolic - sage: T # optional - sage.symbolic + sage: T(r,theta) = [r*cos(theta), r*sin(theta)] # needs sage.symbolic + sage: T # needs sage.symbolic (r, theta) |--> (r*cos(theta), r*sin(theta)) - sage: T.diff() # matrix derivative # optional - sage.symbolic + sage: T.diff() # matrix derivative # needs sage.symbolic [ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)] [ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)] - sage: diff(T) # matrix derivative again # optional - sage.symbolic + sage: diff(T) # matrix derivative again # needs sage.symbolic [ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)] [ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)] - sage: T.diff().det() # Jacobian # optional - sage.symbolic + sage: T.diff().det() # Jacobian # needs sage.symbolic (r, theta) |--> r*cos(theta)^2 + r*sin(theta)^2 """ if var is None: @@ -4005,17 +4018,17 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,x,x^2]) # optional - sage.symbolic - sage: v.derivative(x) # optional - sage.symbolic + sage: v = vector([1,x,x^2]) # needs sage.symbolic + sage: v.derivative(x) # needs sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic + sage: type(v.derivative(x)) == type(v) # needs sage.symbolic True - sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic - sage: v.derivative(x) # optional - sage.symbolic + sage: v = vector([1,x,x^2], sparse=True) # needs sage.symbolic + sage: v.derivative(x) # needs sage.symbolic (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic + sage: type(v.derivative(x)) == type(v) # needs sage.symbolic True - sage: v.derivative(x,x) # optional - sage.symbolic + sage: v.derivative(x,x) # needs sage.symbolic (0, 0, 2) """ from sage.misc.derivative import multi_derivative @@ -4031,13 +4044,13 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: t = var('t') # optional - sage.symbolic - sage: r = vector([t,t^2,sin(t)]) # optional - sage.symbolic - sage: r.integral(t) # optional - sage.symbolic + sage: t = var('t') # needs sage.symbolic + sage: r = vector([t,t^2,sin(t)]) # needs sage.symbolic + sage: r.integral(t) # needs sage.symbolic (1/2*t^2, 1/3*t^3, -cos(t)) - sage: integrate(r, t) # optional - sage.symbolic + sage: integrate(r, t) # needs sage.symbolic (1/2*t^2, 1/3*t^3, -cos(t)) - sage: r.integrate(t, 0, 1) # optional - sage.symbolic + sage: r.integrate(t, 0, 1) # needs sage.symbolic (1/2, 1/3, -cos(1) + 1) """ @@ -4057,20 +4070,20 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: t = var('t') # optional - sage.symbolic - sage: r = vector([t,t^2,sin(t)]) # optional - sage.symbolic - sage: vec, answers = r.nintegral(t,0,1) # optional - sage.symbolic - sage: vec # abs tol 1e-15 # optional - sage.symbolic + sage: t = var('t') # needs sage.symbolic + sage: r = vector([t,t^2,sin(t)]) # needs sage.symbolic + sage: vec, answers = r.nintegral(t,0,1) # needs sage.symbolic + sage: vec # needs sage.symbolic (0.5, 0.3333333333333334, 0.4596976941318602) - sage: type(vec) # optional - sage.symbolic + sage: type(vec) # needs sage.symbolic - sage: answers # optional - sage.symbolic + sage: answers # needs sage.symbolic [(0.5, 5.55111512312578...e-15, 21, 0), (0.3333333333333..., 3.70074341541719...e-15, 21, 0), (0.45969769413186..., 5.10366964392284...e-15, 21, 0)] - sage: r = vector([t,0,1], sparse=True) # optional - sage.symbolic - sage: r.nintegral(t, 0, 1) # optional - sage.symbolic + sage: r = vector([t,0,1], sparse=True) # needs sage.symbolic + sage: r.nintegral(t, 0, 1) # needs sage.symbolic ((0.5, 0.0, 1.0), {0: (0.5, 5.55111512312578...e-15, 21, 0), 2: (1.0, 1.11022302462515...e-14, 21, 0)}) @@ -4161,15 +4174,15 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): :: - sage: v = vector([1,2/3,pi]) # optional - sage.symbolic - sage: v == v # optional - sage.symbolic + sage: v = vector([1,2/3,pi]) # needs sage.symbolic + sage: v == v # needs sage.symbolic True :: - sage: v = vector(RR, [1,2/3,pi]) # optional - sage.symbolic - sage: v.set_immutable() # optional - sage.symbolic - sage: isinstance(hash(v), int) # optional - sage.symbolic + sage: v = vector(RR, [1,2/3,pi]) # needs sage.symbolic + sage: v.set_immutable() # needs sage.symbolic + sage: isinstance(hash(v), int) # needs sage.symbolic True """ cdef _new_c(self, object v): @@ -4202,19 +4215,19 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic - sage: type(v) # optional - sage.symbolic + sage: v = vector([-1,0,3,pi]) # needs sage.symbolic + sage: type(v) # needs sage.symbolic - sage: v.__copy__() # optional - sage.symbolic + sage: v.__copy__() # needs sage.symbolic (-1, 0, 3, pi) - sage: v.__copy__() is v # optional - sage.symbolic + sage: v.__copy__() is v # needs sage.symbolic False - sage: copy(v) # optional - sage.symbolic + sage: copy(v) # needs sage.symbolic (-1, 0, 3, pi) - sage: copy(v) == v # optional - sage.symbolic + sage: copy(v) == v # needs sage.symbolic True - sage: copy(v) is v # optional - sage.symbolic + sage: copy(v) is v # needs sage.symbolic False """ return self._new_c(list(self._entries)) @@ -4223,17 +4236,17 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: type(vector(RR, [-1,0,2/3,pi,oo])) # optional - sage.symbolic + sage: type(vector(RR, [-1,0,2/3,pi,oo])) # needs sage.symbolic We can initialize with lists, tuples and derived types:: sage: from sage.modules.free_module_element import FreeModuleElement_generic_dense - sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo]) # optional - sage.symbolic + sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo]) # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_dense(RR^5, (-1,0,2/3,pi,oo)) # optional - sage.symbolic + sage: FreeModuleElement_generic_dense(RR^5, (-1,0,2/3,pi,oo)) # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_dense(RR^5, Sequence([-1,0,2/3,pi,oo])) # optional - sage.symbolic + sage: FreeModuleElement_generic_dense(RR^5, Sequence([-1,0,2/3,pi,oo])) # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) sage: FreeModuleElement_generic_dense(RR^0, 0) () @@ -4242,26 +4255,26 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): Disabling coercion can lead to illegal objects:: - sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo], coerce=False) # optional - sage.symbolic + sage: FreeModuleElement_generic_dense(RR^5, [-1,0,2/3,pi,oo], coerce=False) # needs sage.symbolic (-1, 0, 2/3, pi, +Infinity) We test the ``copy`` flag:: sage: from sage.modules.free_module_element import FreeModuleElement_generic_dense - sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # optional - sage.symbolic - sage: FreeModuleElement_generic_dense(RR^5, tuple(L), coerce=False, copy=False) # optional - sage.symbolic + sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # needs sage.symbolic + sage: FreeModuleElement_generic_dense(RR^5, tuple(L), coerce=False, copy=False) # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=False) # optional - sage.symbolic - sage: L[4] = 42.0 # optional - sage.symbolic - sage: v # last entry changed since we didn't copy # optional - sage.symbolic + sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=False) # needs sage.symbolic + sage: L[4] = 42.0 # needs sage.symbolic + sage: v # last entry changed since we didn't copy # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, 42.0000000000000) :: - sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # optional - sage.symbolic - sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=True) # optional - sage.symbolic - sage: L[4] = 42.0 # optional - sage.symbolic - sage: v # last entry did not change # optional - sage.symbolic + sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # needs sage.symbolic + sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=True) # needs sage.symbolic + sage: L[4] = 42.0 # needs sage.symbolic + sage: v # last entry did not change # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) Check that :trac:`11751` is fixed:: @@ -4319,8 +4332,8 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi]); w = vector([-2/3,pi^2,1]) # optional - sage.symbolic - sage: v._add_(w) # optional - sage.symbolic + sage: v = vector([1,2/3,pi]); w = vector([-2/3,pi^2,1]) # needs sage.symbolic + sage: v._add_(w) # needs sage.symbolic (1/3, pi^2 + 2/3, pi + 1) """ cdef list a = left._entries @@ -4366,10 +4379,10 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic - sage: v._lmul_(2/3) # optional - sage.symbolic + sage: v = vector([-1,0,3,pi]) # needs sage.symbolic + sage: v._lmul_(2/3) # needs sage.symbolic (-2/3, 0, 2, 2/3*pi) - sage: v * (2/3) # optional - sage.symbolic + sage: v * (2/3) # needs sage.symbolic (-2/3, 0, 2, 2/3*pi) """ if right._parent is self._parent._base: @@ -4402,8 +4415,8 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,3,pi]) # optional - sage.symbolic - sage: v.__reduce__() # optional - sage.symbolic + sage: v = vector([-1,0,3,pi]) # needs sage.symbolic + sage: v.__reduce__() # needs sage.symbolic (, (Vector space of dimension 4 over Symbolic Ring, [-1, 0, 3, pi], 4, True)) """ @@ -4416,8 +4429,8 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector(RR, [-1,0,2/3,pi]) # optional - sage.symbolic - sage: v.get(3) # optional - sage.symbolic + sage: v = vector(RR, [-1,0,2/3,pi]) # needs sage.symbolic + sage: v.get(3) # needs sage.symbolic 3.14159265358979 :: @@ -4453,9 +4466,9 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector(RR, [-1, 0, 2/3, pi]) # optional - sage.symbolic - sage: v.set(3, RR(1)) # optional - sage.symbolic - sage: v # optional - sage.symbolic + sage: v = vector(RR, [-1, 0, 2/3, pi]) # needs sage.symbolic + sage: v.set(3, RR(1)) # needs sage.symbolic + sage: v # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 1.00000000000000) """ self._entries[i] = value @@ -4496,20 +4509,20 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: x, y = var('x,y') # optional - sage.symbolic - sage: f = x^2 + y^2 # optional - sage.symbolic - sage: g = f.gradient() # optional - sage.symbolic - sage: g # optional - sage.symbolic + sage: x, y = var('x,y') # needs sage.symbolic + sage: f = x^2 + y^2 # needs sage.symbolic + sage: g = f.gradient() # needs sage.symbolic + sage: g # needs sage.symbolic (2*x, 2*y) - sage: type(g) # optional - sage.symbolic + sage: type(g) # needs sage.symbolic - sage: g(y=2, x=3) # optional - sage.symbolic + sage: g(y=2, x=3) # needs sage.symbolic (6, 4) - sage: f(x,y) = x^2 + y^2 # optional - sage.symbolic - sage: g = f.gradient() # optional - sage.symbolic - sage: g(3,2) # optional - sage.symbolic + sage: f(x,y) = x^2 + y^2 # needs sage.symbolic + sage: g = f.gradient() # needs sage.symbolic + sage: g(3,2) # needs sage.symbolic (6, 4) - sage: g(x=3, y=2) # optional - sage.symbolic + sage: g(x=3, y=2) # needs sage.symbolic (6, 4) """ return vector([e(*args, **kwargs) for e in self]) @@ -4520,28 +4533,28 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: x, y = var('x,y') # optional - sage.symbolic - sage: v = vector([x,y,x*sin(y)]) # optional - sage.symbolic - sage: w = v.function([x,y]); w # optional - sage.symbolic + sage: x, y = var('x,y') # needs sage.symbolic + sage: v = vector([x, y, x*sin(y)]) # needs sage.symbolic + sage: w = v.function([x,y]); w # needs sage.symbolic (x, y) |--> (x, y, x*sin(y)) - sage: w.coordinate_ring() # optional - sage.symbolic + sage: w.coordinate_ring() # needs sage.symbolic Callable function ring with arguments (x, y) - sage: w(1,2) # optional - sage.symbolic + sage: w(1,2) # needs sage.symbolic (1, 2, sin(2)) - sage: w(2,1) # optional - sage.symbolic + sage: w(2,1) # needs sage.symbolic (2, 1, 2*sin(1)) - sage: w(y=1,x=2) # optional - sage.symbolic + sage: w(y=1,x=2) # needs sage.symbolic (2, 1, 2*sin(1)) :: - sage: x,y = var('x,y') # optional - sage.symbolic - sage: v = vector([x,y,x*sin(y)]) # optional - sage.symbolic - sage: w = v.function([x]); w # optional - sage.symbolic + sage: x,y = var('x,y') # needs sage.symbolic + sage: v = vector([x, y, x*sin(y)]) # needs sage.symbolic + sage: w = v.function([x]); w # needs sage.symbolic x |--> (x, y, x*sin(y)) - sage: w.coordinate_ring() # optional - sage.symbolic + sage: w.coordinate_ring() # needs sage.symbolic Callable function ring with argument x - sage: w(4) # optional - sage.symbolic + sage: w(4) # needs sage.symbolic (4, y, 4*sin(y)) """ from sage.symbolic.callable import CallableSymbolicExpressionRing @@ -4593,9 +4606,9 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): TESTS:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v.set_immutable() # optional - sage.symbolic - sage: isinstance(hash(v), int) # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: v.set_immutable() # needs sage.symbolic + sage: isinstance(hash(v), int) # needs sage.symbolic True Pickling works:: @@ -4645,8 +4658,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v.__copy__() # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: v.__copy__() # needs sage.symbolic (1, 2/3, pi) """ return self._new_c(dict(self._entries)) @@ -4665,13 +4678,13 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): sage: from sage.modules.free_module_element import FreeModuleElement_generic_sparse sage: def S(R,n): ....: return FreeModule(R, n, sparse=True) - sage: FreeModuleElement_generic_sparse(S(RR,5), {0:-1, 2:2/3, 3:pi, 4:oo}) # optional - sage.symbolic + sage: FreeModuleElement_generic_sparse(S(RR,5), {0:-1, 2:2/3, 3:pi, 4:oo}) # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), [-1,0,2/3,pi,oo]) # optional - sage.symbolic + sage: FreeModuleElement_generic_sparse(S(RR,5), [-1,0,2/3,pi,oo]) # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), (-1,0,2/3,pi,oo)) # optional - sage.symbolic + sage: FreeModuleElement_generic_sparse(S(RR,5), (-1,0,2/3,pi,oo)) # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), Sequence([-1,0,2/3,pi,oo])) # optional - sage.symbolic + sage: FreeModuleElement_generic_sparse(S(RR,5), Sequence([-1,0,2/3,pi,oo])) # needs sage.symbolic (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) sage: FreeModuleElement_generic_sparse(S(RR,0), 0) () @@ -4710,6 +4723,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): Test that :trac:`17101` is fixed:: + sage: # needs sage.rings.real_interval_field sage: v = vector([RIF(-1, 1)], sparse=True) sage: v.is_zero() False @@ -4769,8 +4783,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v._add_(v) # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: v._add_(v) # needs sage.symbolic (2, 4/3, 2*pi) """ cdef dict v = dict((right)._entries) @@ -4789,8 +4803,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v._sub_(v) # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: v._sub_(v) # needs sage.symbolic (0, 0, 0) """ cdef dict v = dict(left._entries) # dict to make a copy @@ -4809,8 +4823,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v._lmul_(SR(3)) # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: v._lmul_(SR(3)) # needs sage.symbolic (3, 2, 3*pi) """ cdef dict v = {} @@ -4825,8 +4839,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v._rmul_(SR(3)) # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: v._rmul_(SR(3)) # needs sage.symbolic (3, 2, 3*pi) """ cdef dict v = {} @@ -4893,8 +4907,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True); w = vector([-2/3,pi^2,1],sparse=True) # optional - sage.symbolic - sage: v._pairwise_product_(w) # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True); w = vector([-2/3,pi^2,1],sparse=True) # needs sage.symbolic + sage: v._pairwise_product_(w) # needs sage.symbolic (-2/3, 2/3*pi^2, pi) """ # Component wise vector * vector multiplication. @@ -4918,9 +4932,9 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): TESTS:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: w = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: w == v # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: w = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: w == v # needs sage.symbolic True Check that the bug in :trac:`13929` has been fixed:: @@ -4942,17 +4956,17 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: next(v.items()) # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: next(v.items()) # needs sage.symbolic (0, 1) - sage: list(v.items()) # optional - sage.symbolic + sage: list(v.items()) # needs sage.symbolic [(0, 1), (1, 2/3), (2, pi)] TESTS: Using iteritems as an alias:: - sage: list(v.iteritems()) # optional - sage.symbolic + sage: list(v.iteritems()) # needs sage.symbolic [(0, 1), (1, 2/3), (2, pi)] """ return iter(self._entries.iteritems()) @@ -4963,8 +4977,8 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v.__reduce__() # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: v.__reduce__() # needs sage.symbolic (, (Sparse vector space of dimension 3 over Symbolic Ring, {0: 1, 1: 2/3, 2: pi}, 3, True)) """ @@ -5042,15 +5056,15 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): """ EXAMPLES:: - sage: v = vector([-1,0,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v.get(1) # optional - sage.symbolic + sage: v = vector([-1,0,2/3,pi], sparse=True) # needs sage.symbolic + sage: v.get(1) # needs sage.symbolic 0 - sage: v.get(2) # optional - sage.symbolic + sage: v.get(2) # needs sage.symbolic 2/3 For this class, 0 is returned if the access is out of bounds:: - sage: v.get(10) # optional - sage.symbolic + sage: v.get(10) # needs sage.symbolic 0 """ try: @@ -5071,29 +5085,30 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): (4, 5, 6) sage: parent(w[39893]) Finite Field of size 17 - sage: w[39893] = sqrt(2) # optional - sage.libs.pari sage.symbolic + sage: w[39893] = sqrt(2) # needs sage.rings.finite_rings sage.symbolic Traceback (most recent call last): ... TypeError: self must be a numeric expression :: - sage: v = vector([1,2/3,pi], sparse=True) # optional - sage.symbolic - sage: v.set(1, pi^3) # optional - sage.symbolic - sage: v # optional - sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic + sage: v.set(1, pi^3) # needs sage.symbolic + sage: v # needs sage.symbolic (1, pi^3, pi) - sage: v.set(2, SR(0)) # optional - sage.symbolic - sage: v # optional - sage.symbolic + sage: v.set(2, SR(0)) # needs sage.symbolic + sage: v # needs sage.symbolic (1, pi^3, 0) This assignment is illegal:: - sage: v.set(10, pi) # optional - sage.symbolic + sage: v.set(10, pi) # needs sage.symbolic This lack of bounds checking causes trouble later:: - sage: v # optional - sage.symbolic - ) failed: IndexError: list assignment index out of range> + sage: v # needs sage.symbolic + ) failed: + IndexError: list assignment index out of range> """ if value: self._entries[i] = value From 14e7df055672a62dc3cde3677dddb7bab432a49c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 2 Jul 2023 01:06:19 -0700 Subject: [PATCH 62/99] Update # optional / # needs --- src/sage/matrix/args.pyx | 45 ++++++++++++++++++++++------------- src/sage/matrix/matrix2.pyx | 4 ++++ src/sage/stats/basic_stats.py | 11 +++++---- src/sage/stats/hmm/hmm.pyx | 2 +- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index 1b911018f83..e8dce35a950 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -194,16 +194,22 @@ cdef class MatrixArgs: [1 2] [3 4] - sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized(); ma.matrix() # optional - sage.libs.pari - + sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized() # optional - sage.libs.pari + + sage: ma.matrix() # optional - sage.libs.pari [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized(); ma.matrix() # optional - sage.libs.pari - + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized() # optional - sage.libs.pari + + sage: ma.matrix() # optional - sage.libs.pari [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized(); ma.matrix() # optional - sage.libs.pari - + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized() # optional - sage.libs.pari + + sage: ma.matrix() # optional - sage.libs.pari [3/5 0] [ 0 3/5] sage: ma = MatrixArgs(entries=matrix(2,2)); ma.finalized(); ma.matrix() @@ -219,10 +225,11 @@ cdef class MatrixArgs: > [1 2] [3 4] - sage: from numpy import array # optional - numpy - sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized(); ma.matrix() # optional - numpy - + sage: from numpy import array # optional - numpy + sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized() # optional - numpy + + sage: ma.matrix() # optional - numpy [1 2] [3 4] sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() # optional - numpy @@ -230,15 +237,19 @@ cdef class MatrixArgs: [3.0 4.0]> [1.0 2.0] [3.0 4.0] - sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() # optional - numpy - + sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized() # optional - numpy + + sage: ma.matrix() # optional - numpy [1.0000 2.0000] [3.0000 4.0000] - sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized(); ma.matrix() # optional - sage.graphs - + sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized() # optional - sage.graphs + + sage: ma.matrix() # optional - sage.graphs [0 1 1] [1 0 1] [1 1 0] diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 17397cf6a85..2b2d1f038d5 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -9686,6 +9686,7 @@ cdef class Matrix(Matrix1): Hermitian matrices are normal. :: + sage: # needs sage.symbolic sage: A = matrix(QQ, 5, 5, range(25)) + I*matrix(QQ, 5, 5, range(0, 50, 2)) sage: B = A*A.conjugate_transpose() sage: B.is_hermitian() @@ -9695,6 +9696,7 @@ cdef class Matrix(Matrix1): Circulant matrices are normal. :: + sage: # needs sage.graphs sage: G = graphs.CirculantGraph(20, [3, 7]) sage: D = digraphs.Circuit(20) sage: A = 3*D.adjacency_matrix() - 5*G.adjacency_matrix() @@ -9859,6 +9861,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage: M = random_matrix(CC, 5, 7) sage: for i in range(5): M[i,i] = 0 sage: M[4, 0] = M[0, 6] = M[4, 6] = 0 @@ -9868,6 +9871,7 @@ cdef class Matrix(Matrix1): You can use :meth:`~sage.repl.image.Image.save` to save the resulting image:: + sage: # needs - pillow sage.rings.real_mpfr sage: filename = tmp_filename(ext='.png') sage: img.save(filename) sage: with open(filename, 'rb') as fobj: diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index b004477d87e..4919a406297 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -198,6 +198,7 @@ def std(v, bias=False): EXAMPLES:: + sage: # optional - sage.symbolic sage: std([1..6], bias=True) # optional - sage.symbolic doctest:warning... DeprecationWarning: sage.stats.basic_stats.std is deprecated; @@ -212,7 +213,7 @@ def std(v, bias=False): use numpy.mean or numpy.nanmean instead See https://github.com/sagemath/sage/issues/29662 for details. 1/2*sqrt(35/3) - sage: std([1..6], bias=False) + sage: std([1..6], bias=False) # optional - sage.symbolic sqrt(7/2) sage: std([e, pi]) # optional - sage.symbolic sqrt(1/2)*abs(pi - e) @@ -223,9 +224,11 @@ def std(v, bias=False): + (5*sqrt(2) - 10*I + 3)^2 + (5*sqrt(2) + 5*I - 6)^2) sage: std([RIF(1.0103, 1.0103), RIF(2)]) 0.6998235813403261? - sage: import numpy # optional - numpy - sage: x = numpy.array([1,2,3,4,5]) # optional - numpy - sage: std(x, bias=False) # optional - numpy + + sage: # optional - numpy + sage: import numpy # optional - numpy + sage: x = numpy.array([1,2,3,4,5]) # optional - numpy + sage: std(x, bias=False) # optional - numpy 1.5811388300841898 sage: x = stats.TimeSeries([1..100]) # optional - numpy sage: std(x) # optional - numpy diff --git a/src/sage/stats/hmm/hmm.pyx b/src/sage/stats/hmm/hmm.pyx index 13ee3682615..0f2d10074ff 100644 --- a/src/sage/stats/hmm/hmm.pyx +++ b/src/sage/stats/hmm/hmm.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.modules +# sage.doctest: needs numpy sage.modules """ Hidden Markov Models From 51c0e0a65bb1ef59bfcd871e7cf648341258376d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 2 Jul 2023 21:59:51 -0700 Subject: [PATCH 63/99] Update # optional / # needs --- src/sage/stats/time_series.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 1d8dde6899c..fd1c193c52b 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -1447,7 +1447,7 @@ cdef class TimeSeries: sage: v.autocovariance(1) -2.7 sage: mu = v.mean() - sage: sum((v[i]-mu)*(v[i+1]-mu) for i in range(len(v)-1)])/len(v) + sage: sum((v[i]-mu)*(v[i+1]-mu) for i in range(len(v)-1))/len(v) -2.7 sage: v.autocovariance(1) -2.7 From e016c46fdb3f650a26c59e714bb3abba85ef4118 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Jul 2023 22:36:44 -0700 Subject: [PATCH 64/99] Update # needs --- src/sage/modules/module.pyx | 53 ++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/sage/modules/module.pyx b/src/sage/modules/module.pyx index 8400252adf9..818d139c3ba 100644 --- a/src/sage/modules/module.pyx +++ b/src/sage/modules/module.pyx @@ -107,10 +107,11 @@ cdef class Module(Parent): We check that :trac:`8119` has been resolved:: - sage: M = ZZ^3 # optional - sage.modules - sage: h = M.__hash__() # optional - sage.modules - sage: M.rename('toto') # optional - sage.modules - sage: h == M.__hash__() # optional - sage.modules + sage: # needs sage.modules + sage: M = ZZ^3 + sage: h = M.__hash__() + sage: M.rename('toto') + sage: h == M.__hash__() True """ @@ -162,7 +163,7 @@ cdef class Module(Parent): Make sure :trac:`3638` is fixed:: - sage: vector(ZZ,[1,2,11]) == vector(Zmod(8),[1,2,3]) # optional - sage.modules + sage: vector(ZZ,[1,2,11]) == vector(Zmod(8),[1,2,3]) # needs sage.modules True AUTHORS: @@ -187,8 +188,8 @@ cdef class Module(Parent): EXAMPLES:: - sage: from sage.modular.modform.space import ModularFormsSpace # optional - sage.modular - sage: ModularFormsSpace(Gamma0(11), 2, # optional - sage.modular sage.rings.finite_rings + sage: from sage.modular.modform.space import ModularFormsSpace # needs sage.modular + sage: ModularFormsSpace(Gamma0(11), 2, # needs sage.modular sage.rings.finite_rings ....: DirichletGroup(1)[0], QQ).change_ring(GF(7)) Traceback (most recent call last): ... @@ -213,33 +214,34 @@ cdef class Module(Parent): EXAMPLES:: - sage: V = ZZ^7 # optional - sage.modules - sage: V.base_extend(QQ) # optional - sage.modules + sage: V = ZZ^7 # needs sage.modules + sage: V.base_extend(QQ) # needs sage.modules Vector space of dimension 7 over Rational Field TESTS:: - sage: N = ModularForms(6, 4) # optional - sage.modular - sage: N.base_extend(CyclotomicField(7)) # optional - sage.modular sage.rings.number_field + sage: N = ModularForms(6, 4) # needs sage.modular + sage: N.base_extend(CyclotomicField(7)) # needs sage.modular sage.rings.number_field Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Cyclotomic Field of order 7 and degree 6 - sage: m = ModularForms(DirichletGroup(13).0^2,2); m # optional - sage.modular sage.rings.number_field + sage: m = ModularForms(DirichletGroup(13).0^2,2); m # needs sage.modular sage.rings.number_field Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 - sage: m.base_extend(CyclotomicField(12)) # optional - sage.modular sage.rings.number_field + sage: m.base_extend(CyclotomicField(12)) # needs sage.modular sage.rings.number_field Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 12 and degree 4 - sage: chi = DirichletGroup(109, CyclotomicField(3)).0 # optional - sage.modular sage.rings.number_field - sage: S3 = CuspForms(chi, 2) # optional - sage.modular sage.rings.number_field - sage: S9 = S3.base_extend(CyclotomicField(9)); S9 # optional - sage.modular sage.rings.number_field + sage: # needs sage.modular sage.rings.number_field + sage: chi = DirichletGroup(109, CyclotomicField(3)).0 + sage: S3 = CuspForms(chi, 2) + sage: S9 = S3.base_extend(CyclotomicField(9)); S9 Cuspidal subspace of dimension 8 of Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 over Cyclotomic Field of order 9 and degree 6 - sage: S9.has_coerce_map_from(S3) # not implemented # optional - sage.modular sage.rings.number_field + sage: S9.has_coerce_map_from(S3) # not implemented True - sage: S9.base_extend(CyclotomicField(3)) # optional - sage.modular sage.rings.number_field + sage: S9.base_extend(CyclotomicField(3)) Traceback (most recent call last): ... TypeError: Base extension of self (over 'Cyclotomic Field of order 9 and degree 6') @@ -279,8 +281,8 @@ def is_Module(x): EXAMPLES:: sage: from sage.modules.module import is_Module - sage: M = FreeModule(RationalField(),30) # optional - sage.modules - sage: is_Module(M) # optional - sage.modules + sage: M = FreeModule(RationalField(),30) # needs sage.modules + sage: is_Module(M) # needs sage.modules True sage: is_Module(10) False @@ -298,14 +300,15 @@ def is_VectorSpace(x): EXAMPLES:: + sage: # needs sage.modules sage: from sage.modules.module import is_Module, is_VectorSpace - sage: M = FreeModule(RationalField(),30) # optional - sage.modules - sage: is_VectorSpace(M) # optional - sage.modules + sage: M = FreeModule(RationalField(),30) + sage: is_VectorSpace(M) True - sage: M = FreeModule(IntegerRing(),30) # optional - sage.modules - sage: is_Module(M) # optional - sage.modules + sage: M = FreeModule(IntegerRing(),30) + sage: is_Module(M) True - sage: is_VectorSpace(M) # optional - sage.modules + sage: is_VectorSpace(M) False """ From fdc9b2557266208518c10fa26806fa7a1b2d023f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 13 Jul 2023 23:58:33 -0700 Subject: [PATCH 65/99] sage.matrix: Update # needs --- src/sage/matrix/action.pyx | 10 +- src/sage/matrix/args.pyx | 61 +- src/sage/matrix/berlekamp_massey.py | 2 +- src/sage/matrix/constructor.pyx | 63 +- src/sage/matrix/echelon_matrix.pyx | 6 +- src/sage/matrix/matrix0.pyx | 365 +-- src/sage/matrix/matrix1.pyx | 196 +- src/sage/matrix/matrix2.pyx | 2280 +++++++++-------- src/sage/matrix/matrix_cdv.pyx | 21 +- src/sage/matrix/matrix_complex_ball_dense.pyx | 2 +- src/sage/matrix/matrix_dense.pyx | 13 +- src/sage/matrix/matrix_generic_dense.pyx | 26 +- src/sage/matrix/matrix_generic_sparse.pyx | 2 +- .../matrix/matrix_modn_dense_template.pxi | 143 +- src/sage/matrix/matrix_polynomial_dense.pyx | 929 +++---- src/sage/matrix/matrix_space.py | 154 +- src/sage/matrix/matrix_sparse.pyx | 37 +- src/sage/matrix/operation_table.py | 242 +- src/sage/matrix/special.py | 146 +- src/sage/matrix/tests.py | 2 +- 20 files changed, 2445 insertions(+), 2255 deletions(-) diff --git a/src/sage/matrix/action.pyx b/src/sage/matrix/action.pyx index af0c92786d0..5c6296a1c35 100644 --- a/src/sage/matrix/action.pyx +++ b/src/sage/matrix/action.pyx @@ -209,8 +209,8 @@ cdef class MatrixMatrixAction(MatrixMulAction): Respects compatible subdivisions:: - sage: M = matrix(5, 5, prime_range(100)) # optional - sage.libs.pari - sage: M.subdivide(2, 3); M # optional - sage.libs.pari + sage: M = matrix(5, 5, prime_range(100)) # needs sage.libs.pari + sage: M.subdivide(2, 3); M # needs sage.libs.pari [ 2 3 5| 7 11] [13 17 19|23 29] [--------+-----] @@ -225,7 +225,7 @@ cdef class MatrixMatrixAction(MatrixMulAction): [--+--] [36|49] [64|81] - sage: M*N # optional - sage.libs.pari + sage: M*N # needs sage.libs.pari [ 1048| 1388] [ 3056| 4117] [-----+-----] @@ -235,7 +235,7 @@ cdef class MatrixMatrixAction(MatrixMulAction): Note that this is just like block matrix multiplication:: - sage: M.subdivision(0,0) * N.subdivision(0,0) + M.subdivision(0,1) * N.subdivision(1,0) # optional - sage.libs.pari + sage: M.subdivision(0,0) * N.subdivision(0,0) + M.subdivision(0,1) * N.subdivision(1,0) # needs sage.libs.pari [1048] [3056] @@ -249,7 +249,7 @@ cdef class MatrixMatrixAction(MatrixMulAction): [16|25] [36|49] [64|81] - sage: M*N # optional - sage.libs.pari + sage: M*N # needs sage.libs.pari [ 1048 1388] [ 3056 4117] [ 5360 7303] diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index e8dce35a950..8b0378dec6b 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -83,7 +83,7 @@ cdef class SparseEntry: sage: from sage.matrix.args import SparseEntry sage: SparseEntry(123, 456, "abc") SparseEntry(123, 456, 'abc') - sage: SparseEntry(1/3, 2/3, x) # optional - sage.symbolic + sage: SparseEntry(1/3, 2/3, x) # needs sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert rational 1/3 to an integer @@ -176,10 +176,10 @@ cdef class MatrixArgs: [3.141592653589793 0.0] [ 0.0 3.141592653589793] - sage: ma = MatrixArgs(2, 2, entries=pi); ma.finalized() # optional - sage.symbolic + sage: ma = MatrixArgs(2, 2, entries=pi); ma.finalized() # needs sage.symbolic - sage: ma.matrix() # optional - sage.symbolic + sage: ma.matrix() # needs sage.symbolic [pi 0] [ 0 pi] sage: ma = MatrixArgs(ZZ, 2, 2, entries={(0,0):7}); ma.finalized(); ma.matrix() @@ -194,22 +194,22 @@ cdef class MatrixArgs: [1 2] [3 4] - sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized() # optional - sage.libs.pari + sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized() # needs sage.libs.pari - sage: ma.matrix() # optional - sage.libs.pari + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized() # optional - sage.libs.pari + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized() # needs sage.libs.pari - sage: ma.matrix() # optional - sage.libs.pari + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized() # optional - sage.libs.pari + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized() # needs sage.libs.pari - sage: ma.matrix() # optional - sage.libs.pari + sage: ma.matrix() # needs sage.libs.pari [3/5 0] [ 0 3/5] sage: ma = MatrixArgs(entries=matrix(2,2)); ma.finalized(); ma.matrix() @@ -225,31 +225,33 @@ cdef class MatrixArgs: > [1 2] [3 4] - sage: from numpy import array # optional - numpy - sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized() # optional - numpy + sage: from numpy import array # needs numpy + sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized() # needs numpy - sage: ma.matrix() # optional - numpy + sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized(); ma.matrix() # optional - numpy - + sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized() # needs numpy + + sage: ma.matrix() [1.0 2.0] [3.0 4.0] - sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized() # optional - numpy + sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized() # needs numpy - sage: ma.matrix() # optional - numpy + sage: ma.matrix() # needs numpy [1.0000 2.0000] [3.0000 4.0000] - sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized() # optional - sage.graphs + sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized() # needs sage.graphs - sage: ma.matrix() # optional - sage.graphs + sage: ma.matrix() # needs sage.graphs [0 1 1] [1 0 1] [1 1 0] @@ -471,8 +473,8 @@ cdef class MatrixArgs: Sparse examples:: - sage: ma = MatrixArgs(3, 3, pi) # optional - sage.symbolic - sage: list(ma.iter(sparse=True)) # optional - sage.symbolic + sage: ma = MatrixArgs(3, 3, pi) # needs sage.symbolic + sage: list(ma.iter(sparse=True)) # needs sage.symbolic [SparseEntry(0, 0, pi), SparseEntry(1, 1, pi), SparseEntry(2, 2, pi)] sage: ma = MatrixArgs(2, 3) sage: list(ma.iter(sparse=True)) @@ -832,11 +834,11 @@ cdef class MatrixArgs: EXAMPLES:: sage: from sage.matrix.args import MatrixArgs - sage: MatrixArgs(pi).finalized() # optional - sage.symbolic + sage: MatrixArgs(pi).finalized() # needs sage.symbolic Traceback (most recent call last): ... TypeError: the dimensions of the matrix must be specified - sage: MatrixArgs(RR, pi).finalized() # optional - sage.symbolic + sage: MatrixArgs(RR, pi).finalized() # needs sage.symbolic Traceback (most recent call last): ... TypeError: the dimensions of the matrix must be specified @@ -1235,21 +1237,22 @@ cdef class MatrixArgs: Check that :trac:`26655` is fixed:: - sage: F. = GF(9) # optional - sage.libs.pari - sage: M = MatrixSpace(F, 2, 2) # optional - sage.libs.pari - sage: A = M([[1, a], [0, 1]]) # optional - sage.libs.pari - sage: M(pari(A)) # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = GF(9) + sage: M = MatrixSpace(F, 2, 2) + sage: A = M([[1, a], [0, 1]]) + sage: M(pari(A)) [1 a] [0 1] Constructing a matrix from a PARI ``t_VEC`` or ``t_COL`` with ``t_VEC`` or ``t_COL`` elements is currently not supported:: - sage: M(pari([1, a, 0, 1])) # optional - sage.libs.pari sage.rings.finite_rings + sage: M(pari([1, a, 0, 1])) # needs sage.libs.pari sage.rings.finite_rings Traceback (most recent call last): ... NameError: name 'a' is not defined - sage: M(pari([[1, a], [0, 1]])) # optional - sage.libs.pari sage.rings.finite_rings + sage: M(pari([[1, a], [0, 1]])) # needs sage.libs.pari sage.rings.finite_rings Traceback (most recent call last): ... NameError: name 'a' is not defined diff --git a/src/sage/matrix/berlekamp_massey.py b/src/sage/matrix/berlekamp_massey.py index 11fff79dbba..199991e93cd 100644 --- a/src/sage/matrix/berlekamp_massey.py +++ b/src/sage/matrix/berlekamp_massey.py @@ -59,7 +59,7 @@ def berlekamp_massey(a): x^2 + 6 sage: berlekamp_massey([2,2,1,2,1,191,393,132]) x^4 - 36727/11711*x^3 + 34213/5019*x^2 + 7024942/35133*x - 335813/1673 - sage: berlekamp_massey(prime_range(2, 38)) # optional - sage.libs.pari + sage: berlekamp_massey(prime_range(2, 38)) # needs sage.libs.pari x^6 - 14/9*x^5 - 7/9*x^4 + 157/54*x^3 - 25/27*x^2 - 73/18*x + 37/9 TESTS:: diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index 0cdbccbec4a..3617c9ae96a 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -172,9 +172,9 @@ def matrix(*args, **kwds): :: - sage: import numpy # optional - numpy - sage: n = numpy.array([[1,2], [3,4]], float) # optional - numpy - sage: m = matrix(n); m; m.parent() # optional - numpy + sage: import numpy # needs numpy + sage: n = numpy.array([[1,2], [3,4]], float) # needs numpy + sage: m = matrix(n); m; m.parent() # needs numpy [1.0 2.0] [3.0 4.0] Full MatrixSpace of 2 by 2 dense matrices over Real Double Field @@ -196,15 +196,15 @@ def matrix(*args, **kwds): :: - sage: matrix(pari.mathilbert(3)) # optional - sage.libs.pari + sage: matrix(pari.mathilbert(3)) # needs sage.libs.pari [ 1 1/2 1/3] [1/2 1/3 1/4] [1/3 1/4 1/5] :: - sage: g = graphs.PetersenGraph() # optional - sage.graphs - sage: m = matrix(g); m; m.parent() # optional - sage.graphs + sage: g = graphs.PetersenGraph() # needs sage.graphs + sage: m = matrix(g); m; m.parent() # needs sage.graphs [0 1 0 0 1 1 0 0 0 0] [1 0 1 0 0 0 1 0 0 0] [0 1 0 1 0 0 0 1 0 0] @@ -456,77 +456,78 @@ def matrix(*args, **kwds): Check conversion from numpy:: - sage: import numpy # optional - numpy - sage: n = numpy.array([[complex(0,1),complex(0,2)], [3,4]], complex) # optional - numpy - sage: m = matrix(n); m; m.parent() # optional - numpy + sage: import numpy # needs numpy + sage: n = numpy.array([[complex(0,1),complex(0,2)], [3,4]], complex) # needs numpy + sage: m = matrix(n); m; m.parent() # needs numpy [1.0*I 2.0*I] [ 3.0 4.0] Full MatrixSpace of 2 by 2 dense matrices over Complex Double Field - sage: n = numpy.array([[1,2], [3,4]], 'int32') # optional - numpy - sage: m = matrix(n); m; m.parent() # optional - numpy + sage: n = numpy.array([[1,2], [3,4]], 'int32') # needs numpy + sage: m = matrix(n); m; m.parent() # needs numpy [1 2] [3 4] Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'float32') # optional - numpy - sage: m = matrix(n); m; m.parent() # optional - numpy + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'float32') # needs numpy + sage: m = matrix(n); m; m.parent() # needs numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Real Double Field - sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'float64') # optional - numpy - sage: m = matrix(n); m; m.parent() # optional - numpy + sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'float64') # needs numpy + sage: m = matrix(n); m; m.parent() # needs numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Real Double Field - sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'complex64') # optional - numpy - sage: m = matrix(n); m; m.parent() # optional - numpy + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'complex64') # needs numpy + sage: m = matrix(n); m; m.parent() # needs numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Complex Double Field - sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'complex128') # optional - numpy - sage: m = matrix(n); m; m.parent() # optional - numpy + sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'complex128') # needs numpy + sage: m = matrix(n); m; m.parent() # needs numpy [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Complex Double Field sage: a = matrix([[1,2], [3,4]]) - sage: b = matrix(a.numpy()); b # optional - numpy + sage: b = matrix(a.numpy()); b # needs numpy [1 2] [3 4] - sage: a == b # optional - numpy + sage: a == b # needs numpy True - sage: c = matrix(a.numpy('float32')); c # optional - numpy + sage: c = matrix(a.numpy('float32')); c # needs numpy [1.0 2.0] [3.0 4.0] - sage: matrix(numpy.array([[5]])) # optional - numpy + sage: matrix(numpy.array([[5]])) # needs numpy [5] - sage: matrix(numpy.matrix([[5]])) # optional - numpy + sage: matrix(numpy.matrix([[5]])) # needs numpy [5] A ring and a numpy array:: - sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]],'float32') # optional - numpy - sage: m = matrix(ZZ, n); m; m.parent() # optional - numpy + sage: # needs numpy + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]],'float32') + sage: m = matrix(ZZ, n); m; m.parent() [1 2 3] [4 5 6] [7 8 9] Full MatrixSpace of 3 by 3 dense matrices over Integer Ring - sage: n = matrix(QQ, 2, 2, [1, 1/2, 1/3, 1/4]).numpy(); n # optional - numpy + sage: n = matrix(QQ, 2, 2, [1, 1/2, 1/3, 1/4]).numpy(); n array([[1. , 0.5 ], [0.33333333, 0.25 ]]) - sage: matrix(QQ, n) # optional - numpy + sage: matrix(QQ, n) [ 1 1/2] [1/3 1/4] The dimensions of a matrix may be given as numpy types:: - sage: matrix(numpy.int32(2), numpy.int32(3)) # optional - numpy + sage: matrix(numpy.int32(2), numpy.int32(3)) # needs numpy [0 0 0] [0 0 0] - sage: matrix(nrows=numpy.int32(2), ncols=numpy.int32(3)) # optional - numpy + sage: matrix(nrows=numpy.int32(2), ncols=numpy.int32(3)) # needs numpy [0 0 0] [0 0 0] @@ -577,7 +578,7 @@ def matrix(*args, **kwds): Check :trac:`24459`:: - sage: Matrix(ZZ, sys.maxsize, sys.maxsize) # optional - sage.libs.flint + sage: Matrix(ZZ, sys.maxsize, sys.maxsize) # needs sage.libs.flint Traceback (most recent call last): ... RuntimeError... diff --git a/src/sage/matrix/echelon_matrix.pyx b/src/sage/matrix/echelon_matrix.pyx index e46c1381439..7f5457a7f7b 100644 --- a/src/sage/matrix/echelon_matrix.pyx +++ b/src/sage/matrix/echelon_matrix.pyx @@ -95,12 +95,12 @@ def reduced_echelon_matrix_iterator(K, k, n, bint sparse=False, bint copy=True, Testing options:: - sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, copy=False) # optional - sage.libs.pari - sage: next(it) is next(it) # optional - sage.libs.pari + sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, copy=False) # needs sage.rings.finite_rings + sage: next(it) is next(it) # needs sage.rings.finite_rings True sage: for a in it: pass - sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, set_immutable=True) # optional - sage.rings.finite_rings + sage: it = reduced_echelon_matrix_iterator(GF(4, 'z'), 2, 4, set_immutable=True) # needs sage.rings.finite_rings sage: all(a.is_immutable() and a.echelon_form() == a for a in it) True """ diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 939c99ca6e1..4657008f6c5 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -543,11 +543,11 @@ cdef class Matrix(sage.structure.element.Matrix): TESTS:: - sage: class MyAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): # optional - sage.rings.number_fields + sage: class MyAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): # needs sage.rings.number_fields ....: def __bool__(self): ....: raise ValueError - sage: mat = matrix(1, 1, MyAlgebraicNumber(1)) # optional - sage.rings.number_fields - sage: bool(mat) # optional - sage.rings.number_fields + sage: mat = matrix(1, 1, MyAlgebraicNumber(1)) # needs sage.rings.number_fields + sage: bool(mat) # needs sage.rings.number_fields Traceback (most recent call last): ... ValueError @@ -907,16 +907,17 @@ cdef class Matrix(sage.structure.element.Matrix): Check that submatrices with a specified implementation have the same implementation:: - sage: M = MatrixSpace(GF(2), 3, 3, implementation='generic') # optional - sage.libs.pari - sage: m = M(range(9)) # optional - sage.libs.pari - sage: type(m) # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: M = MatrixSpace(GF(2), 3, 3, implementation='generic') + sage: m = M(range(9)) + sage: type(m) - sage: parent(m) # optional - sage.libs.pari + sage: parent(m) Full MatrixSpace of 3 by 3 dense matrices over Finite Field of size 2 (using Matrix_generic_dense) - sage: type(m[:2,:2]) # optional - sage.libs.pari + sage: type(m[:2,:2]) - sage: parent(m[:2,:2]) # optional - sage.libs.pari + sage: parent(m[:2,:2]) Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 2 (using Matrix_generic_dense) """ @@ -1638,14 +1639,14 @@ cdef class Matrix(sage.structure.element.Matrix): sage: A = Matrix(QQ, 2, 2, [1/2, 1/3, 1/3, 1/4]) sage: A.parent() - Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: A.change_ring(GF(25,'a')) # optional - sage.libs.pari + Full MatrixSpace of 2 by 2 dense matrices over Rational Field + sage: A.change_ring(GF(25,'a')) # needs sage.rings.finite_rings [3 2] [2 4] - sage: A.change_ring(GF(25,'a')).parent() # optional - sage.libs.pari + sage: A.change_ring(GF(25,'a')).parent() # needs sage.rings.finite_rings Full MatrixSpace of 2 by 2 dense matrices over Finite Field in a of size 5^2 - sage: A.change_ring(ZZ) # optional - sage.libs.pari + sage: A.change_ring(ZZ) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: matrix has denominators so can...t change to ZZ @@ -1656,7 +1657,7 @@ cdef class Matrix(sage.structure.element.Matrix): [1/2 1/3] [-------] [1/3 1/4] - sage: A.change_ring(GF(25,'a')) # optional - sage.libs.pari + sage: A.change_ring(GF(25,'a')) # needs sage.rings.finite_rings [3 2] [---] [2 4] @@ -1926,10 +1927,10 @@ cdef class Matrix(sage.structure.element.Matrix): Prior to :trac:`11544` this could take a full minute to run (2011). :: sage: A = matrix(QQ, 4, 4, [1, 2, -2, 2, 1, 0, -1, -1, 0, -1, 1, 1, -1, 2, 1/2, 0]) - sage: e = A.eigenvalues()[3] # optional - sage.rings.number_field - sage: K = (A - e).kernel() # optional - sage.rings.number_field - sage: P = K.basis_matrix() # optional - sage.rings.number_field - sage: P.str() # optional - sage.rings.number_field + sage: e = A.eigenvalues()[3] # needs sage.rings.number_field + sage: K = (A - e).kernel() # needs sage.rings.number_field + sage: P = K.basis_matrix() # needs sage.rings.number_field + sage: P.str() # needs sage.rings.number_field '[ 1.000000000000000? + 0.?e-17*I -2.116651487479748? + 0.0255565807096352?*I -0.2585224251020429? + 0.2886023409047535?*I -0.4847545623533090? - 1.871890760086142?*I]' Use single-row delimiters where appropriate:: @@ -2364,17 +2365,18 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: f(x,y) = x^2 + y # optional - sage.symbolic - sage: m = matrix([[f, f*f], [f^3, f^4]]); m # optional - sage.symbolic + sage: # needs sage.symbolic + sage: f(x,y) = x^2 + y + sage: m = matrix([[f, f*f], [f^3, f^4]]); m [ (x, y) |--> x^2 + y (x, y) |--> (x^2 + y)^2] [(x, y) |--> (x^2 + y)^3 (x, y) |--> (x^2 + y)^4] - sage: m(1, 2) # optional - sage.symbolic + sage: m(1, 2) [ 3 9] [27 81] - sage: m(y=2, x=1) # optional - sage.symbolic + sage: m(y=2, x=1) [ 3 9] [27 81] - sage: m(2, 1) # optional - sage.symbolic + sage: m(2, 1) [ 5 25] [125 625] """ @@ -2562,12 +2564,13 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M`` with it:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups - sage: sigma, tau = G.gens() # optional - sage.groups - sage: sigma # optional - sage.groups + sage: # needs sage.groups + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) + sage: sigma, tau = G.gens() + sage: sigma (1,2,3)(4,5) - sage: M.permute_columns(sigma) # optional - sage.groups - sage: M # optional - sage.groups + sage: M.permute_columns(sigma) + sage: M [0 0 1 0 0] [2 0 0 0 0] [0 3 0 0 0] @@ -2613,11 +2616,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups - sage: sigma, tau = G.gens() # optional - sage.groups - sage: sigma # optional - sage.groups + sage: # needs sage.groups + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) + sage: sigma, tau = G.gens() + sage: sigma (1,2,3)(4,5) - sage: M.with_permuted_columns(sigma) # optional - sage.groups + sage: M.with_permuted_columns(sigma) [0 0 1 0 0] [2 0 0 0 0] [0 3 0 0 0] @@ -2744,12 +2748,13 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups - sage: sigma, tau = G.gens() # optional - sage.groups - sage: sigma # optional - sage.groups + sage: # needs sage.groups + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) + sage: sigma, tau = G.gens() + sage: sigma (1,2,3)(4,5) - sage: M.permute_rows(sigma) # optional - sage.groups - sage: M # optional - sage.groups + sage: M.permute_rows(sigma) + sage: M [0 2 0 0 0] [0 0 3 0 0] [1 0 0 0 0] @@ -2793,11 +2798,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups - sage: sigma, tau = G.gens() # optional - sage.groups - sage: sigma # optional - sage.groups + sage: # needs sage.groups + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) + sage: sigma, tau = G.gens() + sage: sigma (1,2,3)(4,5) - sage: M.with_permuted_rows(sigma) # optional - sage.groups + sage: M.with_permuted_rows(sigma) [0 2 0 0 0] [0 0 3 0 0] [1 0 0 0 0] @@ -2851,12 +2857,13 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups - sage: sigma, tau = G.gens() # optional - sage.groups - sage: sigma # optional - sage.groups + sage: # needs sage.groups + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) + sage: sigma, tau = G.gens() + sage: sigma (1,2,3)(4,5) - sage: M.permute_rows_and_columns(sigma,tau) # optional - sage.groups - sage: M # optional - sage.groups + sage: M.permute_rows_and_columns(sigma,tau) + sage: M [2 0 0 0 0] [0 3 0 0 0] [0 0 0 0 1] @@ -2896,11 +2903,12 @@ cdef class Matrix(sage.structure.element.Matrix): Next of all, create a permutation group element and act on ``M``:: - sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) # optional - sage.groups - sage: sigma, tau = G.gens() # optional - sage.groups - sage: sigma # optional - sage.groups + sage: # needs sage.groups + sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)']) + sage: sigma, tau = G.gens() + sage: sigma (1,2,3)(4,5) - sage: M.with_permuted_rows_and_columns(sigma,tau) # optional - sage.groups + sage: M.with_permuted_rows_and_columns(sigma,tau) [2 0 0 0 0] [0 3 0 0 0] [0 0 0 0 1] @@ -2934,7 +2942,7 @@ cdef class Matrix(sage.structure.element.Matrix): If not, we get an error message:: - sage: a.add_multiple_of_row(1, 0, SR.I()) # optional - sage.symbolic + sage: a.add_multiple_of_row(1, 0, SR.I()) # needs sage.symbolic Traceback (most recent call last): ... TypeError: Multiplying row by Symbolic Ring element cannot be done over @@ -3019,7 +3027,7 @@ cdef class Matrix(sage.structure.element.Matrix): If not, we get an error message:: - sage: a.add_multiple_of_column(1, 0, SR.I()) # optional - sage.symbolic + sage: a.add_multiple_of_column(1, 0, SR.I()) # needs sage.symbolic Traceback (most recent call last): ... TypeError: Multiplying column by Symbolic Ring element cannot be done over @@ -3992,44 +4000,47 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) - sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) False - sage: B = A*A.conjugate_transpose() # optional - sage.rings.number_field - sage: B._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field + sage: B = A*A.conjugate_transpose() + sage: B._is_hermitian(skew=False, tolerance=0) True Sage has several fields besides the entire complex numbers where conjugation is non-trivial:: - sage: F. = QuadraticField(-7) # optional - sage.rings.number_field - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: F. = QuadraticField(-7) + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field + sage: C._is_hermitian(skew=False, tolerance=0) False - sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field - sage: C._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field + sage: C = C*C.conjugate_transpose() + sage: C._is_hermitian(skew=False, tolerance=0) True A matrix that is nearly Hermitian, but for a non-real diagonal entry:: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) False - sage: A[1, 1] = 132 # optional - sage.rings.number_field - sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field + sage: A[1, 1] = 132 + sage: A._is_hermitian(skew=False, tolerance=0) True Rectangular matrices are never Hermitian:: - sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field - sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field + sage: A = matrix(QQbar, 3, 4) # needs sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) # needs sage.rings.number_field False A square, empty matrix is trivially Hermitian:: @@ -4040,10 +4051,10 @@ cdef class Matrix(sage.structure.element.Matrix): A matrix that is skew-Hermitian:: - sage: A = matrix(QQbar, [[-I, 2+I], [-2+I, 0]]) # optional - sage.rings.number_field - sage: A._is_hermitian(skew=False, tolerance=0) # optional - sage.rings.number_field + sage: A = matrix(QQbar, [[-I, 2+I], [-2+I, 0]]) # needs sage.rings.number_field + sage: A._is_hermitian(skew=False, tolerance=0) # needs sage.rings.number_field False - sage: A._is_hermitian(skew=True, tolerance=0) # optional - sage.rings.number_field + sage: A._is_hermitian(skew=True, tolerance=0) True """ key = ("_is_hermitian", skew, tolerance) @@ -4135,44 +4146,47 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[ 1 + I, 1 - 6*I, -1 - I], ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) - sage: A.is_hermitian() # optional - sage.rings.number_field + sage: A.is_hermitian() False - sage: B = A*A.conjugate_transpose() # optional - sage.rings.number_field - sage: B.is_hermitian() # optional - sage.rings.number_field + sage: B = A * A.conjugate_transpose() + sage: B.is_hermitian() True Sage has several fields besides the entire complex numbers where conjugation is non-trivial. :: - sage: F. = QuadraticField(-7) # optional - sage.rings.number_field - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: F. = QuadraticField(-7) + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C.is_hermitian() # optional - sage.rings.number_field + sage: C.is_hermitian() False - sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field - sage: C.is_hermitian() # optional - sage.rings.number_field + sage: C = C*C.conjugate_transpose() + sage: C.is_hermitian() True A matrix that is nearly Hermitian, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A.is_hermitian() # optional - sage.rings.number_field + sage: A.is_hermitian() False - sage: A[1, 1] = 132 # optional - sage.rings.number_field - sage: A.is_hermitian() # optional - sage.rings.number_field + sage: A[1, 1] = 132 + sage: A.is_hermitian() True Rectangular matrices are never Hermitian. :: - sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field - sage: A.is_hermitian() # optional - sage.rings.number_field + sage: A = matrix(QQbar, 3, 4) # needs sage.rings.number_field + sage: A.is_hermitian() # needs sage.rings.number_field False A square, empty matrix is trivially Hermitian. :: @@ -4210,27 +4224,28 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: A = matrix(QQbar, [[0, -1], # optional - sage.rings.number_field + sage: A = matrix(QQbar, [[0, -1], # needs sage.rings.number_field ....: [1, 0]]) - sage: A.is_skew_hermitian() # optional - sage.rings.number_field + sage: A.is_skew_hermitian() # needs sage.rings.number_field True A matrix that is nearly skew-Hermitian, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ -I, -1, 1-I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[ -I, -1, 1-I], ....: [ 1, 1, -1], ....: [-1-I, 1, -I]]) - sage: A.is_skew_hermitian() # optional - sage.rings.number_field + sage: A.is_skew_hermitian() False - sage: A[1, 1] = -I # optional - sage.rings.number_field - sage: A.is_skew_hermitian() # optional - sage.rings.number_field + sage: A[1, 1] = -I + sage: A.is_skew_hermitian() True Rectangular matrices are never skew-Hermitian. :: - sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field - sage: A.is_skew_hermitian() # optional - sage.rings.number_field + sage: A = matrix(QQbar, 3, 4) # needs sage.rings.number_field + sage: A.is_skew_hermitian() # needs sage.rings.number_field False A square, empty matrix is trivially Hermitian. :: @@ -4886,41 +4901,42 @@ cdef class Matrix(sage.structure.element.Matrix): Over finite fields:: sage: A = matrix(GF(59), 3, [10,56,39,53,56,33,58,24,55]) - sage: A.multiplicative_order() # optional - sage.rings.finite_rings + sage: A.multiplicative_order() # needs sage.rings.finite_rings 580 sage: (A^580).is_one() True - sage: B = matrix(GF(10007^3, 'b'), 0) # optional - sage.libs.pari - sage: B.multiplicative_order() # optional - sage.libs.pari + sage: B = matrix(GF(10007^3, 'b'), 0) # needs sage.rings.finite_rings + sage: B.multiplicative_order() # needs sage.rings.finite_rings 1 - sage: M = MatrixSpace(GF(11^2, 'e'), 5) # optional - sage.libs.pari - sage: E = M.random_element() # optional - sage.libs.pari - sage: while E.det() == 0: # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: M = MatrixSpace(GF(11^2, 'e'), 5) + sage: E = M.random_element() + sage: while E.det() == 0: ....: E = M.random_element() - sage: (E^E.multiplicative_order()).is_one() # optional - sage.libs.pari + sage: (E^E.multiplicative_order()).is_one() True Over `\ZZ`:: - sage: m = matrix(ZZ,2,2,[-1,1,-1,0]) - sage: m.multiplicative_order() # optional - sage.groups + sage: m = matrix(ZZ, 2, 2, [-1,1,-1,0]) + sage: m.multiplicative_order() # needs sage.groups 3 - sage: m = posets.ChainPoset(6).coxeter_transformation() # optional - sage.combinat sage.graphs - sage: m.multiplicative_order() # optional - sage.combinat sage.graphs sage.groups + sage: m = posets.ChainPoset(6).coxeter_transformation() # needs sage.combinat sage.graphs + sage: m.multiplicative_order() # needs sage.combinat sage.graphs sage.groups 7 - sage: P = posets.TamariLattice(4).coxeter_transformation() # optional - sage.combinat sage.graphs - sage: P.multiplicative_order() # optional - sage.combinat sage.graphs sage.groups + sage: P = posets.TamariLattice(4).coxeter_transformation() # needs sage.combinat sage.graphs + sage: P.multiplicative_order() # needs sage.combinat sage.graphs sage.groups 10 sage: M = matrix(ZZ, 2, 2, [1, 1, 0, 1]) - sage: M.multiplicative_order() # optional - sage.groups + sage: M.multiplicative_order() # needs sage.groups +Infinity - sage: for k in range(600): # optional - sage.groups + sage: for k in range(600): # needs sage.groups ....: m = SL2Z.random_element() ....: o = m.multiplicative_order() ....: if o != Infinity and m**o != SL2Z.one(): @@ -4935,19 +4951,19 @@ cdef class Matrix(sage.structure.element.Matrix): ....: else: ....: return ZZ.random_element(-100,100) sage: rnd = matrix(ZZ, 8, 8, val) - sage: (rnd * m24 * rnd.inverse_of_unit()).multiplicative_order() # optional - sage.groups + sage: (rnd * m24 * rnd.inverse_of_unit()).multiplicative_order() # needs sage.groups 24 TESTS:: - sage: C = matrix(GF(2^10, 'c'), 2, 3, [1]*6) # optional - sage.libs.pari - sage: C.multiplicative_order() # optional - sage.libs.pari + sage: C = matrix(GF(2^10, 'c'), 2, 3, [1]*6) # needs sage.rings.finite_rings + sage: C.multiplicative_order() # needs sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: self must be invertible ... - sage: D = matrix(IntegerModRing(6),3,[5,5,3,0,2,5,5,4,0]) - sage: D.multiplicative_order() # optional - sage.groups + sage: D = matrix(IntegerModRing(6), 3, [5,5,3,0,2,5,5,4,0]) + sage: D.multiplicative_order() Traceback (most recent call last): ... NotImplementedError: ... only ... over finite fields or ZZ @@ -5066,11 +5082,12 @@ cdef class Matrix(sage.structure.element.Matrix): Check that :trac:`8198` is fixed:: - sage: R = Qp(5, 5) # optional - sage.rings.padics - sage: x = R(5).add_bigoh(1) # optional - sage.rings.padics - sage: I = matrix(R, [[1, 0], [0, 1]]) # optional - sage.rings.padics - sage: v = vector(R, [1, x]) # optional - sage.rings.padics - sage: v*I # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: R = Qp(5, 5) + sage: x = R(5).add_bigoh(1) + sage: I = matrix(R, [[1, 0], [0, 1]]) + sage: v = vector(R, [1, x]) + sage: v*I (1 + O(5^5), O(5)) """ @@ -5100,11 +5117,12 @@ cdef class Matrix(sage.structure.element.Matrix): Check that :trac:`8198` is fixed:: - sage: R = Qp(5, 5) # optional - sage.rings.padics - sage: x = R(5).add_bigoh(1) # optional - sage.rings.padics - sage: I = matrix(R, [[1, 0], [0, 1]]) # optional - sage.rings.padics - sage: v = vector(R, [1, x]) # optional - sage.rings.padics - sage: I*v # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: R = Qp(5, 5) + sage: x = R(5).add_bigoh(1) + sage: I = matrix(R, [[1, 0], [0, 1]]) + sage: v = vector(R, [1, x]) + sage: I*v (1 + O(5^5), O(5)) """ @@ -5197,10 +5215,11 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat - sage: a = matrix(2, 2, [1,2,x*y,y*x]) # optional - sage.combinat - sage: b = matrix(2, 2, [1,2,y*x,y*x]) # optional - sage.combinat - sage: a + b # indirect doctest # optional - sage.combinat + sage: # needs sage.combinat + sage: R. = FreeAlgebra(QQ, 2) + sage: a = matrix(2, 2, [1,2,x*y,y*x]) + sage: b = matrix(2, 2, [1,2,y*x,y*x]) + sage: a + b # indirect doctest [ 2 4] [x*y + y*x 2*y*x] @@ -5220,10 +5239,11 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: - sage: R. = FreeAlgebra(QQ,2) # optional - sage.combinat - sage: a = matrix(2, 2, [1,2,x*y,y*x]) # optional - sage.combinat - sage: b = matrix(2, 2, [1,2,y*x,y*x]) # optional - sage.combinat - sage: a-b # indirect doctest # optional - sage.combinat + sage: # needs sage.combinat + sage: R. = FreeAlgebra(QQ,2) + sage: a = matrix(2, 2, [1,2,x*y,y*x]) + sage: b = matrix(2, 2, [1,2,y*x,y*x]) + sage: a - b # indirect doctest [ 0 0] [x*y - y*x 0] @@ -5296,11 +5316,11 @@ cdef class Matrix(sage.structure.element.Matrix): [ x*y x^2*y x*y^2] [ -x^2*y^2 x^2*y + x*y^2 x^2*y - x*y^2] - sage: R. = FreeAlgebra(ZZ,2) # optional - sage.combinat - sage: a = matrix(R, 2, 3,[1,x,y, -x*y,x+y,x-y]); a # optional - sage.combinat + sage: R. = FreeAlgebra(ZZ,2) # needs sage.combinat + sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a [ 1 x y] [ -x*y x + y x - y] - sage: (x*y) * a # indirect doctest # optional - sage.combinat + sage: (x*y) * a # indirect doctest # needs sage.combinat [ x*y x*y*x x*y^2] [ -x*y*x*y x*y*x + x*y^2 x*y*x - x*y^2] """ @@ -5329,22 +5349,23 @@ cdef class Matrix(sage.structure.element.Matrix): An example in which the base ring is not commutative:: - sage: F. = FreeAlgebra(QQ,2) # optional - sage.combinat - sage: a = matrix(2, [x,y, x^2,y^2]); a # optional - sage.combinat + sage: # needs sage.combinat + sage: F. = FreeAlgebra(QQ,2) + sage: a = matrix(2, [x,y, x^2,y^2]); a [ x y] [x^2 y^2] - sage: x * a # indirect doctest # optional - sage.combinat + sage: x * a # indirect doctest [ x^2 x*y] [ x^3 x*y^2] - sage: a * y # optional - sage.combinat + sage: a * y [ x*y y^2] [x^2*y y^3] - sage: R. = FreeAlgebra(ZZ,2) # optional - sage.combinat - sage: a = matrix(R, 2, 3,[1,x,y, -x*y,x+y,x-y]); a # optional - sage.combinat + sage: R. = FreeAlgebra(ZZ,2) # needs sage.combinat + sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a # needs sage.combinat [ 1 x y] [ -x*y x + y x - y] - sage: a * (x*y) # optional - sage.combinat + sage: a * (x*y) # needs sage.combinat [ x*y x^2*y y*x*y] [ -x*y*x*y x^2*y + y*x*y x^2*y - y*x*y] """ @@ -5386,9 +5407,9 @@ cdef class Matrix(sage.structure.element.Matrix): We verify that the matrix multiplies are correct by comparing them with what PARI gets:: - sage: gp(a)*gp(b) - gp(a*b) # optional - sage.libs.pari + sage: gp(a)*gp(b) - gp(a*b) # needs sage.libs.pari [0, 0; 0, 0] - sage: gp(b)*gp(a) - gp(b*a) # optional - sage.libs.pari + sage: gp(b)*gp(a) - gp(b*a) # needs sage.libs.pari [0, 0, 0; 0, 0, 0; 0, 0, 0] EXAMPLE of matrix times matrix over different base rings:: @@ -5436,15 +5457,16 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLE of matrix multiplication over a noncommutative base ring:: - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat - sage: x*y - y*x # optional - sage.combinat + sage: # needs sage.combinat + sage: R. = FreeAlgebra(QQ, 2) + sage: x*y - y*x x*y - y*x - sage: a = matrix(2, 2, [1,2, x,y]) # optional - sage.combinat - sage: b = matrix(2, 2, [x,y, x^2,y^2]) # optional - sage.combinat - sage: a*b # optional - sage.combinat + sage: a = matrix(2, 2, [1,2, x,y]) + sage: b = matrix(2, 2, [x,y, x^2,y^2]) + sage: a*b [ x + 2*x^2 y + 2*y^2] [x^2 + y*x^2 x*y + y^3] - sage: b*a # optional - sage.combinat + sage: b*a [ x + y*x 2*x + y^2] [x^2 + y^2*x 2*x^2 + y^3] @@ -5512,15 +5534,16 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLE of scalar multiplication in the noncommutative case:: - sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat - sage: a = matrix(2, [x,y, x^2,y^2]) # optional - sage.combinat - sage: a * x # optional - sage.combinat + sage: # needs sage.combinat + sage: R. = FreeAlgebra(ZZ, 2) + sage: a = matrix(2, [x,y, x^2,y^2]) + sage: a * x [ x^2 y*x] [ x^3 y^2*x] - sage: x * a # optional - sage.combinat + sage: x * a [ x^2 x*y] [ x^3 x*y^2] - sage: a*x - x*a # optional - sage.combinat + sage: a*x - x*a [ 0 -x*y + y*x] [ 0 -x*y^2 + y^2*x] """ @@ -5640,17 +5663,17 @@ cdef class Matrix(sage.structure.element.Matrix): sage: m = matrix(Zmod(2^100),2,[2,1,3,3]) sage: type(m) - sage: (~m)*m # optional - sage.libs.pari + sage: (~m)*m # needs sage.libs.pari [1 0] [0 1] - sage: ~m # optional - sage.libs.pari + sage: ~m # needs sage.libs.pari [ 1 422550200076076467165567735125] [1267650600228229401496703205375 422550200076076467165567735126] Matrices over p-adics. See :trac:`17272` :: - sage: R = ZpCA(5,5,print_mode='val-unit') - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) + sage: R = ZpCA(5, 5, print_mode='val-unit') # needs sage.rings.padics + sage: A = matrix(R, 3, 3, [250,2369,1147,106,927,362,90,398,2483]) # needs sage.rings.padics sage: A [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] @@ -5776,19 +5799,19 @@ cdef class Matrix(sage.structure.element.Matrix): EXAMPLES:: sage: R. = ZZ[] - sage: RR = R.quotient(a*d - b*c - 1) # optional - sage.libs.singular - sage: a,b,c,d = RR.gens() # optional - sage.libs.singular - sage: m = matrix(2, [a,b, c,d]) # optional - sage.libs.singular - sage: n = m.inverse_of_unit() # optional - sage.libs.singular - sage: m * n # optional - sage.libs.singular + sage: RR = R.quotient(a*d - b*c - 1) + sage: a,b,c,d = RR.gens() # needs sage.libs.singular + sage: m = matrix(2, [a,b, c,d]) + sage: n = m.inverse_of_unit() # needs sage.libs.singular + sage: m * n # needs sage.libs.singular [1 0] [0 1] - sage: matrix(RR, 2, 1, [a,b]).inverse_of_unit() # optional - sage.libs.singular + sage: matrix(RR, 2, 1, [a,b]).inverse_of_unit() # needs sage.libs.singular Traceback (most recent call last): ... ArithmeticError: self must be a square matrix - sage: matrix(RR, 1, 1, [2]).inverse_of_unit() # optional - sage.libs.singular + sage: matrix(RR, 1, 1, [2]).inverse_of_unit() # needs sage.libs.singular Traceback (most recent call last): ... NotImplementedError: Lifting of multivariate polynomials over non-fields is not implemented. @@ -5801,9 +5824,9 @@ cdef class Matrix(sage.structure.element.Matrix): Tests for :trac:`28570`:: - sage: P = posets.TamariLattice(7) # optional - sage.combinat sage.graphs - sage: M = P._hasse_diagram._leq_matrix # optional - sage.combinat sage.graphs - sage: M.inverse_of_unit() # this was very slow, now 1s # optional - sage.combinat sage.graphs + sage: P = posets.TamariLattice(7) # needs sage.combinat sage.graphs + sage: M = P._hasse_diagram._leq_matrix # needs sage.combinat sage.graphs + sage: M.inverse_of_unit() # this was very slow, now 1s # needs sage.combinat sage.graphs 429 x 429 sparse matrix over Integer Ring... sage: m = matrix(Zmod(2**2), 1, 1, [1], sparse=True) @@ -5896,9 +5919,9 @@ cdef class Matrix(sage.structure.element.Matrix): Non-integer (symbolic) exponents are also supported:: - sage: k = var('k') # optional - sage.symbolic - sage: A = matrix([[2, -1], [1, 0]]) # optional - sage.symbolic - sage: A^(2*k+1) # optional - sage.symbolic + sage: k = var('k') # needs sage.symbolic + sage: A = matrix([[2, -1], [1, 0]]) + sage: A^(2*k+1) # needs sage.symbolic [ 2*k + 2 -2*k - 1] [ 2*k + 1 -2*k] """ diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 59f40e2d329..0c74c820166 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -40,11 +40,11 @@ cdef class Matrix(Matrix0): sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a [ x + 1 2/3] [1/2*x^2 x^3 + 1] - sage: b = gp(a); b # indirect doctest # optional - sage.libs.pari + sage: b = gp(a); b # indirect doctest # needs sage.libs.pari [x + 1, 2/3; 1/2*x^2, x^3 + 1] sage: a.determinant() x^4 + x^3 - 1/3*x^2 + x + 1 - sage: b.matdet() # optional - sage.libs.pari + sage: b.matdet() # needs sage.libs.pari x^4 + x^3 - 1/3*x^2 + x + 1 """ w = self.list() @@ -69,11 +69,11 @@ cdef class Matrix(Matrix0): sage: a = matrix(R,2,[x+1,2/3, x^2/2, 1+x^3]); a [ x + 1 2/3] [1/2*x^2 x^3 + 1] - sage: b = pari(a); b # indirect doctest # optional - sage.libs.pari + sage: b = pari(a); b # indirect doctest # needs sage.libs.pari [x + 1, 2/3; 1/2*x^2, x^3 + 1] sage: a.determinant() x^4 + x^3 - 1/3*x^2 + x + 1 - sage: b.matdet() # optional - sage.libs.pari + sage: b.matdet() # needs sage.libs.pari x^4 + x^3 - 1/3*x^2 + x + 1 This function preserves precision for entries of inexact type (e.g. @@ -83,7 +83,7 @@ cdef class Matrix(Matrix0): sage: a = matrix(R, 2, [1, 2, 3, 1]); a [1.0 2.0] [3.0 1.0] - sage: b = pari(a); b # optional - sage.libs.pari + sage: b = pari(a); b # needs sage.libs.pari [1.000000000, 2.000000000; 3.000000000, 1.000000000] # 32-bit [1.00000000000000, 2.00000000000000; 3.00000000000000, 1.00000000000000] # 64-bit """ @@ -97,34 +97,36 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: A = MatrixSpace(QQ,3,3)([0,1,2,3,4,5,6,7,8]) - sage: g = gap(A) # indirect doctest # optional - sage.libs.gap - sage: g # optional - sage.libs.gap + sage: g = gap(A) # indirect doctest # needs sage.libs.gap + sage: g # needs sage.libs.gap [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ] - sage: g.CharacteristicPolynomial() # optional - sage.libs.gap + sage: g.CharacteristicPolynomial() # needs sage.libs.gap x_1^3-12*x_1^2-18*x_1 - sage: A.characteristic_polynomial() # optional - sage.libs.gap + sage: A.characteristic_polynomial() # needs sage.libs.gap x^3 - 12*x^2 - 18*x - sage: matrix(QQ, g) == A # optional - sage.libs.gap + sage: matrix(QQ, g) == A # needs sage.libs.gap True Particularly difficult is the case of matrices over cyclotomic fields and general number fields. See :trac:`5618` and :trac:`8909`:: - sage: K. = CyclotomicField(8) # optional - sage.rings.number_field - sage: A = MatrixSpace(K, 2, 2)([0, 1+zeta, 2*zeta, 3]) # optional - sage.rings.number_field - sage: g = gap(A); g # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(8) + sage: A = MatrixSpace(K, 2, 2)([0, 1+zeta, 2*zeta, 3]) + sage: g = gap(A); g [ [ 0, 1+E(8) ], [ 2*E(8), 3 ] ] - sage: matrix(K, g) == A # optional - sage.rings.number_field + sage: matrix(K, g) == A True - sage: g.IsMatrix() # optional - sage.rings.number_field + sage: g.IsMatrix() true + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: L. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: A = MatrixSpace(L, 2, 2)([0, 1+tau, 2*tau, 3]) # optional - sage.rings.number_field - sage: g = gap(A); g # optional - sage.rings.number_field + sage: L. = NumberField(x^3 - 2) + sage: A = MatrixSpace(L, 2, 2)([0, 1+tau, 2*tau, 3]) + sage: g = gap(A); g [ [ !0, tau+1 ], [ 2*tau, !3 ] ] - sage: matrix(L, g) == A # optional - sage.rings.number_field + sage: matrix(L, g) == A True """ cdef Py_ssize_t i, j @@ -153,9 +155,9 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: libgap(identity_matrix(ZZ, 2)) # optional - sage.libs.gap + sage: libgap(identity_matrix(ZZ, 2)) # needs sage.libs.gap [ [ 1, 0 ], [ 0, 1 ] ] - sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # optional - sage.libs.gap sage.libs.pari + sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # needs sage.libs.gap sage.rings.finite_rings [ [ Z(3)^0, Z(3) ], [ 0*Z(3), Z(3)^0 ] ] """ from sage.libs.gap.libgap import libgap @@ -192,9 +194,9 @@ cdef class Matrix(Matrix0): :: - sage: y = var('y') # optional - sage.symbolic - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic - sage: M == fricas(M).sage() # optional - fricas # optional - sage.symbolic + sage: y = var('y') # needs sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # needs sage.symbolic + sage: M == fricas(M).sage() # optional - fricas # needs sage.symbolic True """ s = ','.join('[' + ','.join(cf._fricas_init_() for cf in row) + ']' @@ -213,21 +215,21 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: M = matrix(ZZ, 2, range(4)) - sage: giac(M) # optional - sage.libs.giac + sage: giac(M) # needs sage.libs.giac [[0,1],[2,3]] sage: M = matrix(QQ, 3, [1,2,3, 4/3,5/3,6/4, 7,8,9]) - sage: giac(M) # optional - sage.libs.giac + sage: giac(M) # needs sage.libs.giac [[1,2,3],[4/3,5/3,3/2],[7,8,9]] sage: P. = ZZ[] sage: M = matrix(P, 2, [-9*x^2-2*x+2, x-1, x^2+8*x, -3*x^2+5]) - sage: giac(M) # optional - sage.libs.giac + sage: giac(M) # needs sage.libs.giac [[-9*sageVARx^2-2*sageVARx+2,sageVARx-1],[sageVARx^2+8*sageVARx,-3*sageVARx^2+5]] - sage: y = var('y') # optional - sage.symbolic - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic - sage: giac(M).det().sage() # optional - sage.libs.giac sage.symbolic + sage: y = var('y') # needs sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # needs sage.symbolic + sage: giac(M).det().sage() # needs sage.libs.giac sage.symbolic (y^2*dilog(y) + y*dilog(y)*sin(y) - y + 4)/y """ s = ','.join('[' + ','.join(cf._giac_init_() for cf in row) + ']' @@ -244,11 +246,11 @@ cdef class Matrix(Matrix0): [0 1 2] [3 4 5] [6 7 8] - sage: m._maxima_init_() # optional - sage.symbolic + sage: m._maxima_init_() # needs sage.symbolic 'matrix([0,1,2],[3,4,5],[6,7,8])' - sage: a = maxima(m); a # optional - sage.symbolic + sage: a = maxima(m); a # needs sage.symbolic matrix([0,1,2],[3,4,5],[6,7,8]) - sage: a.charpoly('x').expand() # optional - sage.symbolic + sage: a.charpoly('x').expand() # needs sage.symbolic ...-x^3...+12*x^2+18*x sage: m.charpoly() x^3 - 12*x^2 - 18*x @@ -271,7 +273,7 @@ cdef class Matrix(Matrix0): sage: A = MatrixSpace(QQ,3)([1,2,3,4/3,5/3,6/4,7,8,9]) sage: g = mathematica(A); g # optional - mathematica {{1, 2, 3}, {4/3, 5/3, 3/2}, {7, 8, 9}} - sage: A._mathematica_init_() # optional - sage.symbolic + sage: A._mathematica_init_() # needs sage.symbolic '{{1/1, 2/1, 3/1}, {4/3, 5/3, 3/2}, {7/1, 8/1, 9/1}}' :: @@ -282,10 +284,10 @@ cdef class Matrix(Matrix0): :: - sage: a = matrix([[pi, sin(x)], [cos(x), 1/e]]); a # optional - sage.symbolic + sage: a = matrix([[pi, sin(x)], [cos(x), 1/e]]); a # needs sage.symbolic [ pi sin(x)] [cos(x) e^(-1)] - sage: a._mathematica_init_() # optional - sage.symbolic + sage: a._mathematica_init_() # needs sage.symbolic '{{Pi, Sin[x]}, {Cos[x], Exp[-1]}}' """ return '{' + ', '.join([v._mathematica_init_() for v in self.rows()]) + '}' @@ -336,9 +338,9 @@ cdef class Matrix(Matrix0): We coerce a matrix over a cyclotomic field, where the generator must be named during the coercion. :: - sage: K = CyclotomicField(9); z = K.0 # optional - sage.rings.number_field - sage: M = matrix(K, 3, 3, [0,1,3,z,z**4,z-1,z**17,1,0]) # optional - sage.rings.number_field - sage: M # optional - sage.rings.number_field + sage: K = CyclotomicField(9); z = K.0 # needs sage.rings.number_field + sage: M = matrix(K, 3, 3, [0,1,3,z,z**4,z-1,z**17,1,0]) # needs sage.rings.number_field + sage: M # needs sage.rings.number_field [ 0 1 3] [ zeta9 zeta9^4 zeta9 - 1] [-zeta9^5 - zeta9^2 1 0] @@ -389,9 +391,9 @@ cdef class Matrix(Matrix0): sage: maple(M) # optional - maple Matrix(2, 2, [[-9*x^2-2*x+2,x-1],[x^2+8*x,-3*x^2+5]]) - sage: y = var('y') # optional - sage.symbolic - sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # optional - sage.symbolic - sage: M == maple(M).sage() # optional - maple # optional - sage.symbolic + sage: y = var('y') # needs sage.symbolic + sage: M = matrix(SR, 2, [y+sin(y), y - 4, 1/y, dilog(y)]) # needs sage.symbolic + sage: M == maple(M).sage() # optional - maple # needs sage.symbolic True """ s = ','.join('[' + ','.join(cf._maple_init_() for cf in row) + ']' @@ -408,9 +410,9 @@ cdef class Matrix(Matrix0): sage: polymake(M) # optional - jupymake 0 1 2 3 - sage: K. = QuadraticField(5) # optional - sage.rings.number_field - sage: M = matrix(K, [[1, 2], [sqrt5, 3]]) # optional - sage.rings.number_field - sage: polymake(M) # optional - jupymake # optional - sage.rings.number_field + sage: K. = QuadraticField(5) # needs sage.rings.number_field + sage: M = matrix(K, [[1, 2], [sqrt5, 3]]) # needs sage.rings.number_field + sage: polymake(M) # optional - jupymake # needs sage.rings.number_field 1 2 0+1r5 3 """ @@ -485,7 +487,7 @@ cdef class Matrix(Matrix0): [1 2 3] [4 5 6] [7 8 9] - sage: a._scilab_init_() # optional - sage.libs.pari + sage: a._scilab_init_() # needs sage.libs.pari '[1,2,3;4,5,6;7,8,9]' AUTHORS: @@ -540,49 +542,49 @@ cdef class Matrix(Matrix0): [1 2 3] [4 5 6] [7 8 9] - sage: sA = A._sympy_(); sA # optional - sympy + sage: sA = A._sympy_(); sA # needs sympy Matrix([ [1, 2, 3], [4, 5, 6], [7, 8, 9]]) - sage: type(sA) # optional - sympy + sage: type(sA) # needs sympy sage: I = MatrixSpace(QQ, 5, 5, sparse=True).identity_matrix() - sage: sI = I._sympy_(); sI # optional - sympy + sage: sI = I._sympy_(); sI # needs sympy Matrix([ [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]) - sage: type(sI) # optional - sympy + sage: type(sI) # needs sympy If ``self`` was immutable, then converting the result to Sage gives back ``self``:: sage: immA = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]], immutable=True) - sage: immA._sympy_()._sage_() is immA # optional - sympy + sage: immA._sympy_()._sage_() is immA # needs sympy True If ``self`` was mutable, then converting back to Sage creates a new matrix:: - sage: sA._sage_() is A # optional - sage.symbolic sympy + sage: sA._sage_() is A # needs sympy sage.symbolic False - sage: sA._sage_() == A # optional - sage.symbolic sympy + sage: sA._sage_() == A # needs sympy sage.symbolic True Symbolic matrices are supported:: - sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M # optional - sage.symbolic + sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M # needs sage.symbolic [ sin(x) cos(x)] [-cos(x) sin(x)] - sage: sM = M._sympy_(); sM # optional - sage.symbolic sympy + sage: sM = M._sympy_(); sM # needs sympy sage.symbolic Matrix([ [ sin(x), cos(x)], [-cos(x), sin(x)]]) - sage: sM.subs(x, pi/4) # optional - sage.symbolic sympy + sage: sM.subs(x, pi/4) # needs sympy sage.symbolic Matrix([ [ sqrt(2)/2, sqrt(2)/2], [-sqrt(2)/2, sqrt(2)/2]]) @@ -593,12 +595,12 @@ cdef class Matrix(Matrix0): sage: ZeroCol = matrix(QQ, 3, 0, sparse=False); ZeroCol [] - sage: sZeroCol = ZeroCol._sympy_(); sZeroCol # optional - sympy + sage: sZeroCol = ZeroCol._sympy_(); sZeroCol # needs sympy Matrix(3, 0, []) sage: ZeroRow = matrix(QQ, 0, 2, sparse=False); ZeroRow [] - sage: sZeroRow = ZeroRow._sympy_(); sZeroRow # optional - sympy + sage: sZeroRow = ZeroRow._sympy_(); sZeroRow # needs sympy Matrix(0, 2, []) """ @@ -679,19 +681,19 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: a = matrix(3, range(12)) - sage: a.numpy() # optional - numpy + sage: a.numpy() # needs numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) - sage: a.numpy('f') # optional - numpy + sage: a.numpy('f') # needs numpy array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]], dtype=float32) - sage: a.numpy('d') # optional - numpy + sage: a.numpy('d') # needs numpy array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]]) - sage: a.numpy('B') # optional - numpy + sage: a.numpy('B') # needs numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], dtype=uint8) @@ -699,8 +701,8 @@ cdef class Matrix(Matrix0): Type ``numpy.typecodes`` for a list of the possible typecodes:: - sage: import numpy # optional - numpy - sage: sorted(numpy.typecodes.items()) # optional - numpy + sage: import numpy # needs numpy + sage: sorted(numpy.typecodes.items()) # needs numpy [('All', '?bhilqpBHILQPefdgFDGSUVOMm'), ('AllFloat', 'efdgFDG'), ('AllInteger', 'bBhHiIlLqQpP'), ('Character', 'c'), ('Complex', 'FDG'), ('Datetime', 'Mm'), ('Float', 'efdg'), ('Integer', 'bhilqp'), @@ -710,15 +712,15 @@ cdef class Matrix(Matrix0): the magic :meth:`__array__` method) to convert Sage matrices to numpy arrays:: - sage: import numpy # optional - numpy - sage: b = numpy.array(a); b # optional - numpy + sage: import numpy # needs numpy + sage: b = numpy.array(a); b # needs numpy array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) - sage: b.dtype # optional - numpy + sage: b.dtype # needs numpy dtype('int32') # 32-bit dtype('int64') # 64-bit - sage: b.shape # optional - numpy + sage: b.shape # needs numpy (3, 4) """ import numpy @@ -976,14 +978,14 @@ cdef class Matrix(Matrix0): sage: matrix(3, [1..9]).columns() [(1, 4, 7), (2, 5, 8), (3, 6, 9)] - sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).columns() # optional - sage.symbolic + sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).columns() # needs sage.symbolic [(1.41421356237310, 2.71828182845905), (3.14159265358979, 0.000000000000000)] sage: matrix(RR, 0, 2, []).columns() [(), ()] sage: matrix(RR, 2, 0, []).columns() [] - sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) # optional - sage.symbolic - sage: parent(m.columns()[0]) + sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) # needs sage.symbolic + sage: parent(m.columns()[0]) # needs sage.symbolic Sparse vector space of dimension 3 over Real Field with 53 bits of precision Sparse matrices produce sparse columns. :: @@ -1032,14 +1034,14 @@ cdef class Matrix(Matrix0): sage: matrix(3, [1..9]).rows() [(1, 2, 3), (4, 5, 6), (7, 8, 9)] - sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).rows() # optional - sage.symbolic + sage: matrix(RR, 2, [sqrt(2), pi, exp(1), 0]).rows() # needs sage.symbolic [(1.41421356237310, 3.14159265358979), (2.71828182845905, 0.000000000000000)] sage: matrix(RR, 0, 2, []).rows() [] sage: matrix(RR, 2, 0, []).rows() [(), ()] - sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) - sage: parent(m.rows()[0]) + sage: m = matrix(RR, 3, 3, {(1,2): pi, (2, 2): -1, (0,1): sqrt(2)}) # needs sage.symbolic + sage: parent(m.rows()[0]) # needs sage.symbolic Sparse vector space of dimension 3 over Real Field with 53 bits of precision Sparse matrices produce sparse rows. :: @@ -1613,18 +1615,18 @@ cdef class Matrix(Matrix0): ``A.stack(B)`` and ``B.stack(A)`` should be equal:: sage: A = matrix(QQ, 1, 2, [1,2]) - sage: B = matrix(RR, 1, 2, [sin(1.1), sin(2.2)]) # optional - sage.symbolic - sage: C = A.stack(B); C # optional - sage.symbolic + sage: B = matrix(RR, 1, 2, [sin(1.1), sin(2.2)]) + sage: C = A.stack(B); C [ 1.00000000000000 2.00000000000000] [0.891207360061435 0.808496403819590] - sage: C.parent() # optional - sage.symbolic + sage: C.parent() Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision - sage: D = B.stack(A); D # optional - sage.symbolic + sage: D = B.stack(A); D [0.891207360061435 0.808496403819590] [ 1.00000000000000 2.00000000000000] - sage: D.parent() # optional - sage.symbolic + sage: D.parent() Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision @@ -1883,17 +1885,17 @@ cdef class Matrix(Matrix0): elements of ``right`` into the base ring of ``self``. :: sage: A = matrix(QQ, 2, [1,2]) - sage: B = matrix(RR, 2, [sin(1.1), sin(2.2)]) # optional - sage.symbolic - sage: C = A.augment(B); C # optional - sage.symbolic + sage: B = matrix(RR, 2, [sin(1.1), sin(2.2)]) + sage: C = A.augment(B); C # needs sage.symbolic [ 1 183017397/205358938] [ 2 106580492/131825561] - sage: C.parent() # optional - sage.symbolic + sage: C.parent() # needs sage.symbolic Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: D = B.augment(A); D # optional - sage.symbolic + sage: D = B.augment(A); D [0.89120736006... 1.00000000000000] [0.80849640381... 2.00000000000000] - sage: D.parent() # optional - sage.symbolic + sage: D.parent() Full MatrixSpace of 2 by 2 dense matrices over Real Field with 53 bits of precision @@ -2472,36 +2474,38 @@ cdef class Matrix(Matrix0): :: - sage: W. = CyclotomicField(100) # optional - sage.rings.number_field - sage: M = Matrix(2, 3, [a, a/2, 0, a^2, a^100-1, a^2 - a]); M # optional - sage.rings.number_field + sage: W. = CyclotomicField(100) # needs sage.rings.number_field + sage: M = Matrix(2, 3, [a, a/2, 0, a^2, a^100-1, a^2 - a]); M # needs sage.rings.number_field [ a 1/2*a 0] [ a^2 0 a^2 - a] - sage: M.zero_pattern_matrix() # optional - sage.rings.number_field + sage: M.zero_pattern_matrix() # needs sage.rings.number_field [0 0 1] [0 1 0] :: - sage: K. = GF(2^4) # optional - sage.libs.pari - sage: l = [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: K. = GF(2^4) + sage: l = [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1, ....: a + 1, a^2, a^3 + a + 1, a^3 + a, a^3 + a] - sage: M = Matrix(K, 3, 4, l); M # optional - sage.libs.pari + sage: M = Matrix(K, 3, 4, l); M [ a^2 + 1 a^3 + 1 0 0] [ a a^3 + a + 1 a + 1 a + 1] [ a^2 a^3 + a + 1 a^3 + a a^3 + a] - sage: M.zero_pattern_matrix() # optional - sage.libs.pari + sage: M.zero_pattern_matrix() [0 0 1 1] [0 0 0 0] [0 0 0 0] :: - sage: K. = GF(25) # optional - sage.libs.pari - sage: M = Matrix(K, 2, 3, [0, 2, 3, 5, a, a^2]) # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: K. = GF(25) + sage: M = Matrix(K, 2, 3, [0, 2, 3, 5, a, a^2]) + sage: M [ 0 2 3] [ 0 a a + 3] - sage: M.zero_pattern_matrix() # optional - sage.libs.pari + sage: M.zero_pattern_matrix() [1 0 0] [1 0 0] @@ -2588,7 +2592,7 @@ cdef class Matrix(Matrix0): dict items are ETuples (see :trac:`17658`):: sage: from sage.rings.polynomial.polydict import ETuple - sage: matrix(GF(5^2, "z"), {ETuple((1, 1)): 2}).dense_matrix() # optional - sage.libs.pari + sage: matrix(GF(5^2, "z"), {ETuple((1, 1)): 2}).dense_matrix() # needs sage.rings.finite_rings [0 0] [0 2] """ diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 2b2d1f038d5..7fadf4fdc46 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -168,16 +168,17 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: var('a,b,d,e') # optional - sage.symbolic + sage: # needs sage.symbolic + sage: var('a,b,d,e') (a, b, d, e) - sage: m = matrix([[a,b], [d,e]]) # optional - sage.symbolic - sage: m.substitute(a=1) # optional - sage.symbolic + sage: m = matrix([[a,b], [d,e]]) + sage: m.substitute(a=1) [1 b] [d e] - sage: m.subs(a=b, b=d) # optional - sage.symbolic + sage: m.subs(a=b, b=d) [b d] [d e] - sage: m.subs({a: 3, b:2, d:1, e:-1}) # optional - sage.symbolic + sage: m.subs({a: 3, b: 2, d: 1, e: -1}) [ 3 2] [ 1 -1] @@ -350,7 +351,7 @@ cdef class Matrix(Matrix1): (-1, 2, 0, 0) sage: A = Matrix(Zmod(128), 2, 3, [5, 29, 33, 64, 0, 7]) sage: B = vector(Zmod(128), [31,39,56]) - sage: X = A.solve_left(B); X # optional - sage.libs.pari + sage: X = A.solve_left(B); X # needs sage.libs.pari (19, 83) sage: X * A == B True @@ -392,9 +393,9 @@ cdef class Matrix(Matrix1): The vector of constants needs to be compatible with the base ring of the coefficient matrix:: - sage: F. = FiniteField(27) # optional - sage.libs.pari - sage: b = vector(F, [a,a,a,a,a]) # optional - sage.libs.pari - sage: A.solve_left(b) # optional - sage.libs.pari + sage: F. = FiniteField(27) # needs sage.rings.finite_rings + sage: b = vector(F, [a,a,a,a,a]) # needs sage.rings.finite_rings + sage: A.solve_left(b) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: ... @@ -413,9 +414,9 @@ cdef class Matrix(Matrix1): any are inexact, however, the ``check`` is still skipped (:trac:`29729` and :trac:`33159`):: - sage: A = matrix(SR, [[1, 1]]) # optional - sage.symbolic - sage: b = vector(SR, [2, 3]) # optional - sage.symbolic - sage: A.solve_left(b) # optional - sage.symbolic + sage: A = matrix(SR, [[1, 1]]) # needs sage.symbolic + sage: b = vector(SR, [2, 3]) # needs sage.symbolic + sage: A.solve_left(b) # needs sage.symbolic Traceback (most recent call last): ... ValueError: matrix equation has no solutions @@ -423,7 +424,7 @@ cdef class Matrix(Matrix1): In this case, turning off the ``check`` leads to a wrong result:: - sage: A.solve_left(b, check=False) # optional - sage.symbolic + sage: A.solve_left(b, check=False) # needs sage.symbolic (2) """ @@ -595,58 +596,60 @@ cdef class Matrix(Matrix1): sage: A = Matrix(Zmod(6), 3, 2, [1,2,3,4,5,6]) sage: B = vector(Zmod(6), [1,1,1]) - sage: A.solve_right(B) # optional - sage.libs.pari + sage: A.solve_right(B) # needs sage.libs.pari (5, 1) sage: B = vector(Zmod(6), [5,1,1]) - sage: A.solve_right(B) # optional - sage.libs.pari + sage: A.solve_right(B) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: matrix equation has no solutions sage: A = Matrix(Zmod(128), 2, 3, [23,11,22,4,1,0]) sage: B = Matrix(Zmod(128), 2, 1, [1,0]) - sage: A.solve_right(B) # optional - sage.libs.pari + sage: A.solve_right(B) # needs sage.libs.pari [ 5] [108] [127] sage: B = B.column(0) - sage: A.solve_right(B) # optional - sage.libs.pari + sage: A.solve_right(B) # needs sage.libs.pari (5, 108, 127) sage: A = Matrix(Zmod(15), 3,4, range(12)) sage: B = Matrix(Zmod(15), 3,3, range(3,12)) - sage: X = A.solve_right(B) # optional - sage.libs.pari - sage: A*X == B # optional - sage.libs.pari + sage: X = A.solve_right(B) # needs sage.libs.pari + sage: A*X == B # needs sage.libs.pari True Solving a system over the p-adics:: - sage: k = Qp(5, 4) # optional - sage.rings.padics - sage: a = matrix(k, 3, [1,7,3, 2,5,4, 1,1,2]); a # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: k = Qp(5, 4) + sage: a = matrix(k, 3, [1,7,3, 2,5,4, 1,1,2]); a [ 1 + O(5^4) 2 + 5 + O(5^4) 3 + O(5^4)] [ 2 + O(5^4) 5 + O(5^5) 4 + O(5^4)] [ 1 + O(5^4) 1 + O(5^4) 2 + O(5^4)] - sage: v = vector(k, 3, [1,2,3]) # optional - sage.rings.padics - sage: x = a \ v; x # optional - sage.rings.padics + sage: v = vector(k, 3, [1,2,3]) + sage: x = a \ v; x (4 + 5 + 5^2 + 3*5^3 + O(5^4), 2 + 5 + 3*5^2 + 5^3 + O(5^4), 1 + 5 + O(5^4)) - sage: a * x == v # optional - sage.rings.padics + sage: a * x == v True Solving a system of linear equations symbolically using symbolic matrices:: - sage: var('a,b,c,d,x,y') # optional - sage.symbolic + sage: # needs sage.symbolic + sage: var('a,b,c,d,x,y') (a, b, c, d, x, y) - sage: A = matrix(SR, 2, [a,b,c,d]); A # optional - sage.symbolic + sage: A = matrix(SR, 2, [a,b,c,d]); A [a b] [c d] - sage: result = vector(SR, [3,5]); result # optional - sage.symbolic + sage: result = vector(SR, [3,5]); result (3, 5) - sage: soln = A.solve_right(result); soln # optional - sage.symbolic + sage: soln = A.solve_right(result); soln (-b*(3*c/a - 5)/(a*(b*c/a - d)) + 3/a, (3*c/a - 5)/(b*c/a - d)) - sage: (a*x+b*y).subs(x=soln[0], y=soln[1]).simplify_full() # optional - sage.symbolic + sage: (a*x + b*y).subs(x=soln[0], y=soln[1]).simplify_full() 3 - sage: (c*x+d*y).subs(x=soln[0], y=soln[1]).simplify_full() # optional - sage.symbolic + sage: (c*x + d*y).subs(x=soln[0], y=soln[1]).simplify_full() 5 - sage: (A*soln).apply_map(lambda x: x.simplify_full()) # optional - sage.symbolic + sage: (A*soln).apply_map(lambda x: x.simplify_full()) (3, 5) Over inexact rings, the output of this function may not be an exact @@ -721,8 +724,8 @@ cdef class Matrix(Matrix1): (:trac:`12406`):: sage: A = matrix(QQ, 2, [1, 2, 3, 4]) - sage: b = vector(RDF, [pi, e]) # optional - sage.symbolic - sage: A.solve_right(b) # tol 1e-15 # optional - sage.symbolic + sage: b = vector(RDF, [pi, e]) # needs sage.symbolic + sage: A.solve_right(b) # tol 1e-15 # needs sage.symbolic (-3.564903478720541, 3.353248066155167) sage: R. = ZZ[] sage: b = vector(R, [1, t]) @@ -737,7 +740,7 @@ cdef class Matrix(Matrix1): sage: A = Matrix(Zmod(6), 3, 2, [1,2,3,4,5,6]) sage: b = vector(ZZ, [1,1,1]) - sage: A.solve_right(b).base_ring() is Zmod(6) # optional - sage.libs.pari + sage: A.solve_right(b).base_ring() is Zmod(6) # needs sage.libs.pari True Check that the coercion mechanism gives consistent results @@ -778,9 +781,9 @@ cdef class Matrix(Matrix1): The vector of constants needs to be compatible with the base ring of the coefficient matrix. :: - sage: F. = FiniteField(27) # optional - sage.libs.pari - sage: b = vector(F, [a,a,a,a,a]) # optional - sage.libs.pari - sage: A.solve_right(b) # optional - sage.libs.pari + sage: F. = FiniteField(27) # needs sage.rings.finite_rings + sage: b = vector(F, [a,a,a,a,a]) # needs sage.rings.finite_rings + sage: A.solve_right(b) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: ... @@ -816,31 +819,32 @@ cdef class Matrix(Matrix1): any are inexact, however, the ``check`` is still skipped (:trac:`29729` and :trac:`33159`):: - sage: m = matrix(SR, [0]) # optional - sage.symbolic - sage: b = vector(SR, [1]) # optional - sage.symbolic - sage: m.solve_right(b, check=True) # optional - sage.symbolic + sage: m = matrix(SR, [0]) # needs sage.symbolic + sage: b = vector(SR, [1]) # needs sage.symbolic + sage: m.solve_right(b, check=True) # needs sage.symbolic Traceback (most recent call last): ... ValueError: matrix equation has no solutions In this case, turning off the ``check`` leads to a wrong result:: - sage: m.solve_right(b, check=False) # optional - sage.symbolic + sage: m.solve_right(b, check=False) # needs sage.symbolic (0) In the following, we have an inexact entry in the matrix, so the ``check`` is still skipped leading to a wrong result:: - sage: m = matrix(SR, [0.0]) # optional - sage.symbolic - sage: m.solve_right(b, check=True) # optional - sage.symbolic + sage: m = matrix(SR, [0.0]) # needs sage.symbolic + sage: m.solve_right(b, check=True) # needs sage.symbolic (0) :: - sage: SC = SR.subring(no_variables=True) # optional - sage.symbolic - sage: m = matrix(SC, [0]) # optional - sage.symbolic - sage: b = vector(SC, [1]) # optional - sage.symbolic - sage: m.solve_right(b) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: SC = SR.subring(no_variables=True) + sage: m = matrix(SC, [0]) + sage: b = vector(SC, [1]) + sage: m.solve_right(b) Traceback (most recent call last): ... ValueError: matrix equation has no solutions @@ -1144,13 +1148,14 @@ cdef class Matrix(Matrix1): Non-commutative rings behave as expected. These are the usual quaternions. :: - sage: R. = QuaternionAlgebra(-1, -1) # optional - sage.combinat - sage: A = matrix(R, 2, [1,i,j,k]) # optional - sage.combinat - sage: B = matrix(R, 2, [i,i,i,i]) # optional - sage.combinat - sage: A.elementwise_product(B) # optional - sage.combinat + sage: # needs sage.combinat + sage: R. = QuaternionAlgebra(-1, -1) + sage: A = matrix(R, 2, [1,i,j,k]) + sage: B = matrix(R, 2, [i,i,i,i]) + sage: A.elementwise_product(B) [ i -1] [-k j] - sage: B.elementwise_product(A) # optional - sage.combinat + sage: B.elementwise_product(A) [ i -1] [ k -j] @@ -1555,14 +1560,15 @@ cdef class Matrix(Matrix1): sage: Mx = M.pseudoinverse(algorithm="exact") sage: (Mx*M).norm() # huge error 11.5... - sage: Mx = M.pseudoinverse(algorithm="numpy") - sage: (Mx*M).norm() # still OK + sage: Mx = M.pseudoinverse(algorithm="numpy") # needs numpy + sage: (Mx * M).norm() # still OK 1.00... When multiplying the given matrix with the pseudoinverse, the result is symmetric for the ``exact`` algorithm or hermitian for the ``exactconj`` algorithm:: + sage: # needs sage.rings.number_field sage.symbolic sage: M = matrix(QQbar, 2, 2, [1, sqrt(-3), -sqrt(-3), 3]) sage: M * M.pseudoinverse() [ 0.2500000000000000? 0.4330127018922193?*I] @@ -1587,13 +1593,13 @@ cdef class Matrix(Matrix1): Numpy gives a strange answer due to rounding errors:: - sage: M.pseudoinverse(algorithm="numpy") # random + sage: M.pseudoinverse(algorithm="numpy") # random # needs numpy [-1286742750677287/643371375338643 1000799917193445/1000799917193444] [ 519646110850445/346430740566963 -300239975158034/600479950316067] Although it is not too far off:: - sage: (~M-M.pseudoinverse(algorithm="numpy")).norm() < 1e-14 + sage: (~M - M.pseudoinverse(algorithm="numpy")).norm() < 1e-14 # needs numpy True TESTS:: @@ -1709,7 +1715,7 @@ cdef class Matrix(Matrix1): These numbers are the coefficients of a modified Laguerre polynomial:: sage: x = polygen(QQ) - sage: factorial(8) * laguerre(8,-x) # optional - sage.symbolic + sage: factorial(8) * laguerre(8,-x) # needs sage.symbolic x^8 + 64*x^7 + 1568*x^6 + 18816*x^5 + 117600*x^4 + 376320*x^3 + 564480*x^2 + 322560*x + 40320 @@ -1720,7 +1726,7 @@ cdef class Matrix(Matrix1): sage: A = identity_matrix(21) sage: A.rook_vector(complement=True)[-1] 18795307255050944540 - sage: Derangements(21).cardinality() # optional - sage.combinat + sage: Derangements(21).cardinality() # needs sage.combinat 18795307255050944540 An other example that we convert into a rook polynomial:: @@ -1744,7 +1750,7 @@ cdef class Matrix(Matrix1): [1, 8, 20, 16, 4] sage: A.rook_vector(algorithm="Ryser") [1, 8, 20, 16, 4] - sage: A.rook_vector(algorithm="Godsil") # optional - sage.graphs + sage: A.rook_vector(algorithm="Godsil") # needs sage.graphs [1, 8, 20, 16, 4] When the matrix `A` has more ones then zeroes it is usually faster @@ -1784,17 +1790,17 @@ cdef class Matrix(Matrix1): [1, 0, 0] sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Ryser") [1, 0, 0] - sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Godsil") # optional - sage.graphs + sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Godsil") # needs sage.graphs [1, 0, 0] sage: matrix.ones(4, 2).rook_vector("Ryser") [1, 8, 12] - sage: matrix.ones(4, 2).rook_vector("Godsil") # optional - sage.graphs + sage: matrix.ones(4, 2).rook_vector("Godsil") # needs sage.graphs [1, 8, 12] sage: m = matrix(ZZ,4,5) sage: m[:4,:4] = identity_matrix(4) sage: algos = ["Ryser", "ButeraPernici"] - sage: algos += ["Godsil"] # optional - sage.graphs - sage: for algorithm in algos: + sage: algos += ["Godsil"] + sage: for algorithm in algos: # needs sage.graphs ....: v = m.rook_vector(complement=True, use_complement=True, algorithm=algorithm) ....: if v != [1, 16, 78, 128, 53]: ....: print("ERROR with algorithm={} use_complement=True".format(algorithm)) @@ -1923,7 +1929,7 @@ cdef class Matrix(Matrix1): sage: k = GF(37) sage: P. = PolynomialRing(k) sage: A = Matrix(P, 2, 3, [x0*x1, x0, x1, x2, x2 + 16, x2 + 5*x1]) - sage: A.minors(2) # optional - sage.rings.finite_rings + sage: A.minors(2) # needs sage.rings.finite_rings [x0*x1*x2 + 16*x0*x1 - x0*x2, 5*x0*x1^2 + x0*x1*x2 - x1*x2, 5*x0*x1 + x0*x2 - x1*x2 - 16*x1] @@ -2021,16 +2027,16 @@ cdef class Matrix(Matrix1): TESTS:: - sage: A = matrix(5, 5, [next_prime(i^2) for i in range(25)]) # optional - sage.libs.pari - sage: B = MatrixSpace(ZZ['x'], 5, 5)(A) # optional - sage.libs.pari - sage: A.det() - B.det() # optional - sage.libs.pari + sage: A = matrix(5, 5, [next_prime(i^2) for i in range(25)]) # needs sage.libs.pari + sage: B = MatrixSpace(ZZ['x'], 5, 5)(A) # needs sage.libs.pari + sage: A.det() - B.det() # needs sage.libs.pari 0 We verify that :trac:`5569` is resolved (otherwise the following would hang for hours):: - sage: d = random_matrix(GF(next_prime(10^20)), 50).det() # optional - sage.libs.pari - sage: d = random_matrix(Integers(10^50), 50).det() # optional - sage.libs.pari + sage: d = random_matrix(GF(next_prime(10^20)), 50).det() # needs sage.rings.finite_rings + sage: d = random_matrix(Integers(10^50), 50).det() # needs sage.rings.finite_rings We verify that :trac:`7704` is resolved:: @@ -2044,14 +2050,14 @@ cdef class Matrix(Matrix1): sage: A = GF(2)['x,y,z'] sage: A.inject_variables() Defining x, y, z - sage: R = A.quotient(x^2 + 1).quotient(y^2 + 1).quotient(z^2 + 1) # optional - sage.libs.pari - sage: R.inject_variables() # optional - sage.libs.pari + sage: R = A.quotient(x^2 + 1).quotient(y^2 + 1).quotient(z^2 + 1) # needs sage.rings.finite_rings + sage: R.inject_variables() # needs sage.rings.finite_rings Defining xbarbarbar, ybarbarbar, zbarbarbar - sage: M = matrix([[1, 1, 1, 1], # optional - sage.libs.pari + sage: M = matrix([[1, 1, 1, 1], # needs sage.rings.finite_rings ....: [xbarbarbar, ybarbarbar, 1, 1], ....: [0, 1, zbarbarbar, 1], ....: [xbarbarbar, zbarbarbar, 1, 1]]) - sage: M.determinant() # optional - sage.libs.pari + sage: M.determinant() # needs sage.rings.finite_rings xbarbarbar*ybarbarbar*zbarbarbar + xbarbarbar*ybarbarbar + xbarbarbar*zbarbarbar + ybarbarbar*zbarbarbar + xbarbarbar + ybarbarbar + zbarbarbar + 1 @@ -2216,14 +2222,14 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(SR, 2, lambda i, j: f'a{i}{j}'); A # optional - sage.symbolic + sage: A = matrix(SR, 2, lambda i, j: f'a{i}{j}'); A # needs sage.symbolic [a00 a01] [a10 a11] - sage: A.quantum_determinant() # optional - sage.symbolic + sage: A.quantum_determinant() # needs sage.symbolic -a01*a10*q + a00*a11 - sage: A = matrix(SR, 3, lambda i, j: f'a{i}{j}') # optional - sage.symbolic - sage: A.quantum_determinant() # optional - sage.symbolic + sage: A = matrix(SR, 3, lambda i, j: f'a{i}{j}') # needs sage.symbolic + sage: A.quantum_determinant() # needs sage.symbolic -a02*a11*a20*q^3 + (a01*a12*a20 + a02*a10*a21)*q^2 + (-a00*a12*a21 - a01*a10*a22)*q + a00*a11*a22 @@ -2239,13 +2245,13 @@ cdef class Matrix(Matrix1): sage: R. = LaurentPolynomialRing(S) sage: MS = MatrixSpace(S, 3, sparse=True) sage: A = MS([[x, y, 3], [4, 2+y, x^2], [0, 1-x, x+y]]) - sage: A.det() # optional - sage.rings.finite_rings + sage: A.det() # needs sage.rings.finite_rings x^4 - x^3 + x^2*y + x*y^2 + 2*x^2 - 2*x*y + 3*y^2 + 2*x - 2 - sage: A.quantum_determinant() # optional - sage.libs.pari + sage: A.quantum_determinant() # needs sage.rings.finite_rings (2*x - 2)*q^2 + (x^4 - x^3 + 3*x*y + 3*y^2)*q + x^2*y + x*y^2 + 2*x^2 + 2*x*y - sage: A.quantum_determinant(int(2)) # optional - sage.libs.pari + sage: A.quantum_determinant(int(2)) # needs sage.rings.finite_rings 2*x^4 - 2*x^3 + x^2*y + x*y^2 + 2*x^2 + x*y - y^2 + x - 1 - sage: A.quantum_determinant(q*x + q^-1*y) # optional - sage.libs.pari + sage: A.quantum_determinant(q*x + q^-1*y) # needs sage.rings.finite_rings (2*x*y^2 - 2*y^2)*q^-2 + (x^4*y - x^3*y + 3*x*y^2 + 3*y^3)*q^-1 + (-2*x^2*y + x*y^2 + 2*x^2 - 2*x*y) + (x^5 - x^4 + 3*x^2*y + 3*x*y^2)*q + (2*x^3 - 2*x^2)*q^2 @@ -2427,7 +2433,7 @@ cdef class Matrix(Matrix1): In that case, the definition by perfect matchings is used instead:: - sage: A.pfaffian() # optional - sage.combinat sage.libs.pari + sage: A.pfaffian() # needs sage.combinat sage.rings.finite_rings 2 """ @@ -2512,7 +2518,7 @@ cdef class Matrix(Matrix1): ....: (2, -1, 0, 0, 1, 5/2), ....: (-2, 1, -3/2, -1, 0, 1/2), ....: (1/2, -3/2, -1, -5/2, -1/2, 0)]) - sage: A._pf_perfect_matchings() # optional - sage.combinat + sage: A._pf_perfect_matchings() # needs sage.combinat -1/2 """ @@ -2570,7 +2576,7 @@ cdef class Matrix(Matrix1): sage: A = random_matrix(ZZ['x'], 6) sage: A = A - A.transpose() - sage: A.pfaffian(algorithm='bfl') == A._pf_perfect_matchings() # optional - sage.combinat + sage: A.pfaffian(algorithm='bfl') == A._pf_perfect_matchings() # needs sage.combinat True """ @@ -2664,13 +2670,13 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: m = matrix(ZZ, 3, 3, range(9)) - sage: k. = GF(9) # optional - sage.rings.finite_rings + sage: k. = GF(9) # needs sage.rings.finite_rings sage: f = lambda x: k(x) - sage: n = m.apply_map(f); n # optional - sage.rings.finite_rings + sage: n = m.apply_map(f); n # needs sage.rings.finite_rings [0 1 2] [0 1 2] [0 1 2] - sage: n.parent() # optional - sage.libs.pari + sage: n.parent() # needs sage.rings.finite_rings Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 @@ -2680,11 +2686,11 @@ cdef class Matrix(Matrix1): sage: s = GF(3) sage: f = lambda x: s(x) - sage: n = m.apply_map(f, k); n # optional - sage.rings.finite_rings + sage: n = m.apply_map(f, k); n # needs sage.rings.finite_rings [0 1 2] [0 1 2] [0 1 2] - sage: n.parent() # optional - sage.libs.pari + sage: n.parent() # needs sage.rings.finite_rings Full MatrixSpace of 3 by 3 dense matrices over Finite Field in a of size 3^2 @@ -2779,7 +2785,7 @@ cdef class Matrix(Matrix1): sage: a = matrix(QQ, 2,2, [1,2,3,4]); a [1 2] [3 4] - sage: a.characteristic_polynomial('T') # optional - sage.libs.pari + sage: a.characteristic_polynomial('T') # needs sage.libs.pari T^2 - 5*T - 2 """ return self.charpoly(*args, **kwds) @@ -2791,9 +2797,9 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: a = matrix(QQ, 4, 4, range(16)) - sage: a.minimal_polynomial('z') # optional - sage.libs.pari + sage: a.minimal_polynomial('z') # needs sage.libs.pari z^3 - 30*z^2 - 80*z - sage: a.minpoly() # optional - sage.libs.pari + sage: a.minpoly() # needs sage.libs.pari x^3 - 30*x^2 - 80*x """ return self.minpoly(var, **kwds) @@ -2808,18 +2814,19 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(GF(9, 'c'), 4, [1,1,0,0, 0,1,0,0, 0,0,5,0, 0,0,0,5]) # optional - sage.libs.pari - sage: factor(A.minpoly()) # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = matrix(GF(9, 'c'), 4, [1,1,0,0, 0,1,0,0, 0,0,5,0, 0,0,0,5]) + sage: factor(A.minpoly()) (x + 1) * (x + 2)^2 - sage: A.minpoly()(A) == 0 # optional - sage.libs.pari + sage: A.minpoly()(A) == 0 True - sage: factor(A.charpoly()) # optional - sage.libs.pari + sage: factor(A.charpoly()) (x + 1)^2 * (x + 2)^2 The default variable name is `x`, but you can specify another name:: - sage: factor(A.minpoly('y')) # optional - sage.libs.pari + sage: factor(A.minpoly('y')) # needs sage.rings.finite_rings (y + 1) * (y + 2)^2 """ f = self.fetch('minpoly') @@ -2866,8 +2873,8 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: a = matrix([[1,2], [3,4]]) # optional - sage.libs.pari - sage: a._test_minpoly() # optional - sage.libs.pari + sage: a = matrix([[1,2], [3,4]]) + sage: a._test_minpoly() # needs sage.libs.pari """ if self.nrows() == self.ncols() and self.base_ring().is_exact(): tester = self._tester(**options) @@ -2928,7 +2935,7 @@ cdef class Matrix(Matrix1): An example over `\QQ`:: sage: A = MatrixSpace(QQ, 3)(range(9)) - sage: A.charpoly('x') # optional - sage.libs.pari + sage: A.charpoly('x') # needs sage.libs.pari x^3 - 12*x^2 - 18*x sage: A.trace() 12 @@ -2973,11 +2980,11 @@ cdef class Matrix(Matrix1): Here is an example over a number field:: sage: x = QQ['x'].gen() - sage: K. = NumberField(x^2 - 2) - sage: m = matrix(K, [[a-1, 2], [a, a+1]]) - sage: m.charpoly('Z') + sage: K. = NumberField(x^2 - 2) # needs sage.rings.number_field + sage: m = matrix(K, [[a-1, 2], [a, a+1]]) # needs sage.rings.number_field + sage: m.charpoly('Z') # needs sage.rings.number_field Z^2 - 2*a*Z - 2*a + 1 - sage: m.charpoly('a')(m) == 0 + sage: m.charpoly('a')(m) == 0 # needs sage.rings.number_field True Over integers modulo `n` with composite `n`:: @@ -2992,8 +2999,8 @@ cdef class Matrix(Matrix1): computation of the characteristic polynomial succeeds as follows:: sage: R. = QQ[] - sage: S. = R.quo((b^3)) # optional - sage.rings.function_field - sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) + sage: S. = R.quo((b^3)) # needs sage.rings.function_field + sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) # needs sage.rings.function_field sage: A [ x*y^2 2*x] [ 2 x^10*y] @@ -3013,6 +3020,7 @@ cdef class Matrix(Matrix1): and crash if an empty dictionary was cached. We don't cache dictionaries anymore, but this test should still pass:: + sage: # needs sage.rings.padics sage: z = Zp(p=5) sage: A = matrix(z, [ [3 + O(5^1), 4 + O(5^1), 4 + O(5^1)], ....: [2*5^2 + O(5^3), 2 + O(5^1), 1 + O(5^1)], @@ -3130,8 +3138,8 @@ cdef class Matrix(Matrix1): Test that :trac:`27937` is fixed:: - sage: R = FreeAbelianMonoid('u,v').algebra(QQ) # optional - sage.groups - sage: matrix(4, 4, lambda i, j: R.an_element())._charpoly_df() # optional - sage.groups + sage: R = FreeAbelianMonoid('u,v').algebra(QQ) # needs sage.groups + sage: matrix(4, 4, lambda i, j: R.an_element())._charpoly_df() # needs sage.groups B[1]*x^4 - 4*B[u]*x^3 .. NOTE:: @@ -3240,12 +3248,12 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = MatrixSpace(QQ,3,3) - sage: A = M([1,9,-7,4/5,4,3,6,4,3]) - sage: A.fcp() # optional - sage.libs.pari + sage: M = MatrixSpace(QQ, 3, 3) + sage: A = M([1,9,-7, 4/5,4,3, 6,4,3]) + sage: A.fcp() # needs sage.libs.pari x^3 - 8*x^2 + 209/5*x - 286 sage: A = M([3, 0, -2, 0, -2, 0, 0, 0, 0]) - sage: A.fcp('T') # optional - sage.libs.pari + sage: A.fcp('T') # needs sage.libs.pari (T - 3) * T * (T + 2) """ return self.charpoly(var).factor() @@ -3290,14 +3298,15 @@ cdef class Matrix(Matrix1): Here's an example involving a cyclotomic field:: - sage: K. = CyclotomicField(3) # optional - sage.rings.number_field - sage: M = MatrixSpace(K, 3, sparse=True) # optional - sage.rings.number_field - sage: A = M([(1+z)/3, (2+z)/3, z/3, 1, 1+z, -2, 1, 5, -1+z]) # optional - sage.rings.number_field - sage: print(A) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(3) + sage: M = MatrixSpace(K, 3, sparse=True) + sage: A = M([(1+z)/3, (2+z)/3, z/3, 1, 1+z, -2, 1, 5, -1+z]) + sage: print(A) [1/3*z + 1/3 1/3*z + 2/3 1/3*z] [ 1 z + 1 -2] [ 1 5 z - 1] - sage: print(A.denominator()) # optional - sage.rings.number_field + sage: print(A.denominator()) 3 """ if self.nrows() == 0 or self.ncols() == 0: @@ -3708,34 +3717,36 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: Q = QuadraticField(-7) # optional - sage.rings.number_field - sage: a = Q.gen(0) # optional - sage.rings.number_field - sage: A = matrix(Q, [[ 2, 5-a, 15-a], # optional - sage.rings.number_field - ....: [2+a, a, -7 + 5*a]]) - sage: result = A._right_kernel_matrix_over_number_field() # optional - sage.rings.number_field sage.libs.pari - sage: result[0] # optional - sage.rings.number_field sage.libs.pari + sage: # needs sage.rings.number_field + sage: Q = QuadraticField(-7) + sage: a = Q.gen(0) + sage: A = matrix(Q, [[ 2, 5 - a, 15 - a], + ....: [2 + a, a, -7 + 5*a]]) + sage: result = A._right_kernel_matrix_over_number_field() # needs sage.libs.pari + sage: result[0] # needs sage.libs.pari 'pivot-pari-numberfield' - sage: P = result[1]; P # optional - sage.rings.number_field sage.libs.pari + sage: P = result[1]; P # needs sage.libs.pari [-a -3 1] - sage: A*P.transpose() == zero_matrix(Q, 2, 1) # optional - sage.rings.number_field sage.libs.pari + sage: A * P.transpose() == zero_matrix(Q, 2, 1) # needs sage.libs.pari True TESTS: We test some trivial cases. :: - sage: Q = QuadraticField(-7) # optional - sage.rings.number_field - sage: A = matrix(Q, 0, 2) # optional - sage.rings.number_field - sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field sage.libs.pari + sage: # needs sage.rings.number_field + sage: Q = QuadraticField(-7) + sage: A = matrix(Q, 0, 2) + sage: A._right_kernel_matrix_over_number_field()[1] # needs sage.libs.pari [1 0] [0 1] - sage: A = matrix(Q, 2, 0) # optional - sage.rings.number_field sage.libs.pari - sage: A._right_kernel_matrix_over_number_field()[1].parent() # optional - sage.rings.number_field sage.libs.pari + sage: A = matrix(Q, 2, 0) # needs sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1].parent() # needs sage.libs.pari Full MatrixSpace of 0 by 0 dense matrices over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I - sage: A = zero_matrix(Q, 4, 3) # optional - sage.rings.number_field sage.libs.pari - sage: A._right_kernel_matrix_over_number_field()[1] # optional - sage.rings.number_field sage.libs.pari + sage: A = zero_matrix(Q, 4, 3) # needs sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1] # needs sage.libs.pari [1 0 0] [0 1 0] [0 0 1] @@ -3764,35 +3775,37 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: C = CyclotomicField(14) # optional - sage.rings.number_field - sage: a = C.gen(0) # optional - sage.rings.number_field - sage: A = matrix(C, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: C = CyclotomicField(14) + sage: a = C.gen(0) + sage: A = matrix(C, 3, 4, [[ 1, a, 1+a, a^3+a^5], ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: result = A._right_kernel_matrix_over_field() # optional - sage.rings.number_field - sage: result[0] # optional - sage.rings.number_field + sage: result = A._right_kernel_matrix_over_field() + sage: result[0] 'pivot-generic' - sage: P = result[1]; P # optional - sage.rings.number_field + sage: P = result[1]; P [ -1 -1 1 0] [-zeta14^3 -zeta14^4 0 1] - sage: A*P.transpose() == zero_matrix(C, 3, 2) # optional - sage.rings.number_field + sage: A * P.transpose() == zero_matrix(C, 3, 2) True TESTS: We test some trivial cases. :: - sage: C = CyclotomicField(14) # optional - sage.rings.number_field - sage: A = matrix(C, 0, 2) # optional - sage.rings.number_field - sage: A._right_kernel_matrix_over_field()[1] # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: C = CyclotomicField(14) + sage: A = matrix(C, 0, 2) + sage: A._right_kernel_matrix_over_field()[1] [1 0] [0 1] - sage: A = matrix(C, 2, 0) # optional - sage.rings.number_field - sage: A._right_kernel_matrix_over_field()[1].parent() # optional - sage.rings.number_field + sage: A = matrix(C, 2, 0) + sage: A._right_kernel_matrix_over_field()[1].parent() Full MatrixSpace of 0 by 0 dense matrices over Cyclotomic Field of order 14 and degree 6 - sage: A = zero_matrix(C, 4, 3) # optional - sage.rings.number_field - sage: A._right_kernel_matrix_over_field()[1] # optional - sage.rings.number_field + sage: A = zero_matrix(C, 4, 3) + sage: A._right_kernel_matrix_over_field()[1] [1 0 0] [0 1 0] [0 0 1] @@ -3911,15 +3924,15 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(Zmod(24480), [[1,2,3,4,5],[7,7,7,7,7]]) - sage: result = A._right_kernel_matrix_over_integer_mod_ring() # optional - sage.libs.pari - sage: result[0] # optional - sage.libs.pari + sage: A = matrix(Zmod(24480), [[1,2,3,4,5], [7,7,7,7,7]]) + sage: result = A._right_kernel_matrix_over_integer_mod_ring() # needs sage.libs.pari + sage: result[0] # needs sage.libs.pari 'computed-pari-matkermod' - sage: P = result[1]; P # optional - sage.libs.pari + sage: P = result[1]; P # needs sage.libs.pari [ 1 24478 1 0 0] [ 2 24477 0 1 0] [ 3 24476 0 0 1] - sage: A*P.transpose() == 0 # optional - sage.libs.pari + sage: A * P.transpose() == 0 # needs sage.libs.pari True """ R = self.base_ring() @@ -4072,47 +4085,49 @@ cdef class Matrix(Matrix1): basis, so the `basis` keywords 'computed' and 'pivot' will return the same results. :: - sage: Q = QuadraticField(-7) # optional - sage.rings.number_field - sage: a = Q.gen(0) # optional - sage.rings.number_field - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: Q = QuadraticField(-7) + sage: a = Q.gen(0) + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], ....: [2+a, a, -7 + 5*a, -3+3*a]]) - sage: C = A.right_kernel_matrix(algorithm='default', basis='computed'); C # optional - sage.rings.number_field + sage: C = A.right_kernel_matrix(algorithm='default', basis='computed'); C [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*C.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field + sage: A*C.transpose() == zero_matrix(Q, 2, 2) True - sage: P = A.right_kernel_matrix(algorithm='pari', basis='pivot'); P # optional - sage.rings.number_field sage.libs.pari + sage: P = A.right_kernel_matrix(algorithm='pari', basis='pivot'); P # needs sage.libs.pari [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*P.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field sage.libs.pari + sage: A*P.transpose() == zero_matrix(Q, 2, 2) # needs sage.libs.pari True - sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E # optional - sage.rings.number_field + sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: A*E.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field + sage: A*E.transpose() == zero_matrix(Q, 2, 2) True We can bypass using PARI for number fields and use Sage's general code for matrices over any field. The basis vectors as computed are in pivot format. :: - sage: Q = QuadraticField(-7) # optional - sage.rings.number_field - sage: a = Q.gen(0) # optional - sage.rings.number_field - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a],[2+a, a, -7 + 5*a, -3+3*a]]) # optional - sage.rings.number_field - sage: G = A.right_kernel_matrix(algorithm='generic', basis='computed'); G # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: Q = QuadraticField(-7) + sage: a = Q.gen(0) + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], [2+a, a, -7 + 5*a, -3+3*a]]) + sage: G = A.right_kernel_matrix(algorithm='generic', basis='computed'); G [ -a -3 1 0] [ -2 -a - 1 0 1] - sage: A*G.transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field + sage: A*G.transpose() == zero_matrix(Q, 2, 2) True We check that number fields are handled by the right routine as part of typical right kernel computation. :: - sage: Q = QuadraticField(-7) # optional - sage.rings.number_field - sage: a = Q.gen(0) # optional - sage.rings.number_field - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a],[2+a, a, -7 + 5*a, -3+3*a]]) # optional - sage.rings.number_field + sage: Q = QuadraticField(-7) # needs sage.rings.number_field + sage: a = Q.gen(0) # needs sage.rings.number_field + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], [2+a, a, -7 + 5*a, -3+3*a]]) # needs sage.rings.number_field sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') # optional - sage.rings.number_field + sage: A.right_kernel(algorithm='default') # needs sage.rings.number_field verbose ... verbose 1 () computing right kernel matrix over a number field for 2x4 matrix verbose 1 () done computing right kernel matrix over a number field for 2x4 matrix @@ -4163,7 +4178,7 @@ cdef class Matrix(Matrix1): [1 0 0 0 0 1] sage: A*DP.transpose() == zero_matrix(GF(2), 3, 4) True - sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') # optional - sage.libs.pari + sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') # needs sage.rings.finite_rings [1 0 0 0 0 1] [0 1 1 0 0 0] [0 0 0 1 0 0] @@ -4175,7 +4190,7 @@ cdef class Matrix(Matrix1): ....: [1, 0, 0, 0, 1, 1,], ....: [1, 0, 0, 0, 1, 1]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') # optional - sage.libs.pari + sage: A.right_kernel(algorithm='default') # needs sage.rings.finite_rings verbose ... verbose 1 () computing right kernel matrix over integers mod 2 for 3x6 matrix verbose 1 () done computing right kernel matrix over integers mod 2 for 3x6 matrix @@ -4194,19 +4209,20 @@ cdef class Matrix(Matrix1): will compute a set of basis vectors in the pivot format. These could be returned as a basis in echelon form. :: - sage: F. = FiniteField(5^2) # optional - sage.libs.pari - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(5^2) + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: P = A.right_kernel_matrix(algorithm='default', basis='pivot'); P # optional - sage.libs.pari + sage: P = A.right_kernel_matrix(algorithm='default', basis='pivot'); P [ 4 4 1 0] [ a + 2 3*a + 3 0 1] - sage: A*P.transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari + sage: A*P.transpose() == zero_matrix(F, 3, 2) True - sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E # optional - sage.libs.pari + sage: E = A.right_kernel_matrix(algorithm='default', basis='echelon'); E [ 1 0 3*a + 4 2*a + 2] [ 0 1 2*a 3*a + 3] - sage: A*E.transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari + sage: A*E.transpose() == zero_matrix(F, 3, 2) True This general code can be requested for matrices over any field @@ -4233,12 +4249,12 @@ cdef class Matrix(Matrix1): We test that the generic code is called for matrices over fields, lacking any more specific routine. :: - sage: F. = FiniteField(5^2) # optional - sage.libs.pari - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.libs.pari + sage: F. = FiniteField(5^2) # needs sage.rings.finite_rings + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # needs sage.rings.finite_rings ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') # optional - sage.libs.pari + sage: A.right_kernel(algorithm='default') # needs sage.rings.finite_rings verbose ... verbose 1 () computing right kernel matrix over an arbitrary field for 3x4 matrix ... @@ -4717,17 +4733,18 @@ cdef class Matrix(Matrix1): Over an arbitrary field, with two basis formats. Same vector space, different bases. :: - sage: F. = FiniteField(5^2) # optional - sage.libs.pari - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(5^2) + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) - sage: K = A.right_kernel(); K # optional - sage.libs.pari + sage: K = A.right_kernel(); K Vector space of degree 4 and dimension 2 over Finite Field in a of size 5^2 Basis matrix: [ 1 0 3*a + 4 2*a + 2] [ 0 1 2*a 3*a + 3] - sage: A*K.basis_matrix().transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari + sage: A * K.basis_matrix().transpose() == zero_matrix(F, 3, 2) True In the following test, we have to force usage of @@ -4738,7 +4755,7 @@ cdef class Matrix(Matrix1): sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense sage: B = Matrix_generic_dense(A.parent(), A.list(), False, False) - sage: P = B.right_kernel(basis='pivot'); P # optional - sage.rings.finite_rings + sage: P = B.right_kernel(basis='pivot'); P # needs sage.rings.finite_rings Vector space of degree 4 and dimension 2 over Finite Field in a of size 5^2 User basis matrix: @@ -4748,36 +4765,38 @@ cdef class Matrix(Matrix1): If the optional meataxe package is installed, we again have to make sure to work with a copy of B that has the same type as ``P.basis_matrix()``:: - sage: B.parent()(B.list()) * P.basis_matrix().transpose() == zero_matrix(F, 3, 2) # optional - sage.libs.pari + sage: (B.parent()(B.list()) * P.basis_matrix().transpose() # needs sage.rings.finite_rings + ....: == zero_matrix(F, 3, 2)) True - sage: K == P + sage: K == P # needs sage.rings.finite_rings True Over number fields, PARI is used by default, but general-purpose code can be requested. Same vector space, same bases, different code.:: - sage: Q = QuadraticField(-7) # optional - sage.rings.number_field - sage: a = Q.gen(0) # optional - sage.rings.number_field - sage: A = matrix(Q, [[ 2, 5-a, 15-a, 16+4*a], # optional - sage.rings.number_field - ....: [2+a, a, -7 + 5*a, -3+3*a]]) - sage: K = A.right_kernel(algorithm='default'); K # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: Q = QuadraticField(-7) + sage: a = Q.gen(0) + sage: A = matrix(Q, [[ 2, 5 - a, 15 - a, 16 + 4*a], + ....: [2 + a, a, -7 + 5*a, -3 + 3*a]]) + sage: K = A.right_kernel(algorithm='default'); K Vector space of degree 4 and dimension 2 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I Basis matrix: [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: A*K.basis_matrix().transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field + sage: A * K.basis_matrix().transpose() == zero_matrix(Q, 2, 2) True - sage: B = copy(A) # optional - sage.rings.number_field - sage: G = A.right_kernel(algorithm='generic'); G # optional - sage.rings.number_field + sage: B = copy(A) + sage: G = A.right_kernel(algorithm='generic'); G Vector space of degree 4 and dimension 2 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I Basis matrix: [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] - sage: B*G.basis_matrix().transpose() == zero_matrix(Q, 2, 2) # optional - sage.rings.number_field + sage: B * G.basis_matrix().transpose() == zero_matrix(Q, 2, 2) True - sage: K == G # optional - sage.rings.number_field + sage: K == G True For matrices over the integers, several options are possible. @@ -5154,7 +5173,7 @@ cdef class Matrix(Matrix1): [ 0 2 0 -1] [ 0 1 -2 0] [ 0 2 0 -2] - sage: t.fcp() # optional - sage.libs.pari + sage: t.fcp() # needs sage.libs.pari (x - 39) * (x + 2) * (x^2 - 2) sage: s = (t-39)*(t^2-2) sage: V = s.kernel(); V @@ -5250,11 +5269,12 @@ cdef class Matrix(Matrix1): An example over a bigger ring:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: L. = NumberField(x^2 - x + 2) # optional - sage.rings.number_field - sage: OL = L.ring_of_integers() # optional - sage.rings.number_field - sage: A = matrix(L, 2, [1, w/2]) # optional - sage.rings.number_field - sage: A.integer_kernel(OL) # optional - sage.rings.number_field + sage: L. = NumberField(x^2 - x + 2) + sage: OL = L.ring_of_integers() + sage: A = matrix(L, 2, [1, w/2]) + sage: A.integer_kernel(OL) Free module of degree 2 and rank 1 over Maximal Order in Number Field in w with defining polynomial x^2 - x + 2 Echelon basis matrix: @@ -5468,23 +5488,23 @@ cdef class Matrix(Matrix1): [198 209 220 231 242 253] [264 275 286 297 308 319] [330 341 352 363 374 385] - sage: A.decomposition() # optional - sage.libs.pari - [ - (Ambient free module of rank 4 over the principal ideal domain Integer Ring, True) - ] - sage: B.decomposition() # optional - sage.libs.pari - [ - (Vector space of degree 6 and dimension 2 over Rational Field - Basis matrix: - [ 1 0 -1 -2 -3 -4] - [ 0 1 2 3 4 5], True), - (Vector space of degree 6 and dimension 4 over Rational Field - Basis matrix: - [ 1 0 0 0 -5 4] - [ 0 1 0 0 -4 3] - [ 0 0 1 0 -3 2] - [ 0 0 0 1 -2 1], False) - ] + sage: A.decomposition() # needs sage.libs.pari + [ (Ambient free module of rank 4 + over the principal ideal domain Integer Ring, + True) ] + sage: B.decomposition() # needs sage.libs.pari + [ (Vector space of degree 6 and dimension 2 over Rational Field + Basis matrix: + [ 1 0 -1 -2 -3 -4] + [ 0 1 2 3 4 5], + True), + (Vector space of degree 6 and dimension 4 over Rational Field + Basis matrix: + [ 1 0 0 0 -5 4] + [ 0 1 0 0 -4 3] + [ 0 0 1 0 -3 2] + [ 0 0 0 1 -2 1], + False) ] """ if algorithm == 'kernel' or self.base_ring() not in _Fields: return self._decomposition_using_kernels(is_diagonalizable = is_diagonalizable, dual=dual) @@ -5661,48 +5681,46 @@ cdef class Matrix(Matrix1): [ 3 0 -2] [ 0 -2 0] [ 0 0 0] - sage: t.fcp('X') # factored charpoly # optional - sage.libs.pari + sage: t.fcp('X') # factored charpoly # needs sage.libs.pari (X - 3) * X * (X + 2) sage: v = kernel(t*(t+2)); v # an invariant subspace Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [0 1 0] [0 0 1] - sage: D = t.decomposition_of_subspace(v); D # optional - sage.libs.pari - [ - (Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 0 1], True), - (Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 1 0], True) - ] - sage: t.restrict(D[0][0]) # optional - sage.libs.pari + sage: D = t.decomposition_of_subspace(v); D # needs sage.libs.pari + [ (Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: [0 0 1], + True), + (Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: [0 1 0], + True) ] + sage: t.restrict(D[0][0]) # needs sage.libs.pari [0] - sage: t.restrict(D[1][0]) # optional - sage.libs.pari + sage: t.restrict(D[1][0]) # needs sage.libs.pari [-2] We do a decomposition over ZZ:: - sage: a = matrix(ZZ,6,[0, 0, -2, 0, 2, 0, 2, -4, -2, 0, 2, 0, 0, 0, -2, -2, 0, 0, 2, 0, -2, -4, 2, -2, 0, 2, 0, -2, -2, 0, 0, 2, 0, -2, 0, 0]) - sage: a.decomposition_of_subspace(ZZ^6) # optional - sage.libs.pari - [ - (Free module of degree 6 and rank 2 over Integer Ring - Echelon basis matrix: - [ 1 0 1 -1 1 -1] - [ 0 1 0 -1 2 -1], False), - (Free module of degree 6 and rank 4 over Integer Ring - Echelon basis matrix: - [ 1 0 -1 0 1 0] - [ 0 1 0 0 0 0] - [ 0 0 0 1 0 0] - [ 0 0 0 0 0 1], False) - ] + sage: a = matrix(ZZ, 6, [0, 0, -2, 0, 2, 0, 2, -4, -2, 0, 2, 0, 0, 0, -2, -2, 0, 0, 2, 0, -2, -4, 2, -2, 0, 2, 0, -2, -2, 0, 0, 2, 0, -2, 0, 0]) + sage: a.decomposition_of_subspace(ZZ^6) # needs sage.libs.pari + [ (Free module of degree 6 and rank 2 over Integer Ring + Echelon basis matrix: + [ 1 0 1 -1 1 -1] + [ 0 1 0 -1 2 -1], + False), + (Free module of degree 6 and rank 4 over Integer Ring + Echelon basis matrix: + [ 1 0 -1 0 1 0] + [ 0 1 0 0 0 0] + [ 0 0 0 1 0 0] + [ 0 0 0 0 0 1], + False) ] TESTS:: sage: t = matrix(QQ, 3, [3, 0, -2, 0, -2, 0, 0, 0, 0]) - sage: t.decomposition_of_subspace(v, check_restrict = False) == t.decomposition_of_subspace(v) # optional - sage.libs.pari + sage: t.decomposition_of_subspace(v, check_restrict = False) == t.decomposition_of_subspace(v) # needs sage.libs.pari True """ if not sage.modules.free_module.is_FreeModule(M): @@ -5976,7 +5994,7 @@ cdef class Matrix(Matrix1): [6 7 8] sage: t.wiedemann(0) x^2 - 12*x - 18 - sage: t.charpoly() # optional - sage.libs.pari + sage: t.charpoly() # needs sage.libs.pari x^3 - 12*x^2 - 18*x """ i = int(i); t=int(t) @@ -6040,17 +6058,17 @@ cdef class Matrix(Matrix1): of finite fields:: sage: A = matrix(QQ, 2, range(4)) - sage: A._eigenspace_format(None) == 'all' # optional - sage.rings.number_field + sage: A._eigenspace_format(None) == 'all' # needs sage.rings.number_field True sage: B = matrix(GF(13), 2, range(4)) - sage: B._eigenspace_format(None) # optional - sage.rings.finite_rings + sage: B._eigenspace_format(None) # needs sage.rings.finite_rings 'all' Subrings are promoted to fraction fields and then checked for the existence of algebraic closures. :: sage: A = matrix(ZZ, 2, range(4)) - sage: A._eigenspace_format(None) == 'all' # optional - sage.rings.number_field + sage: A._eigenspace_format(None) == 'all' # needs sage.rings.number_field True """ if format not in [None, 'all', 'galois']: @@ -6134,40 +6152,47 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenspaces_left(format='all'); es # optional - sage.rings.number_field - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (-1.348469228349535?, Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 0.3101020514433644? -0.3797958971132713?]), - (13.34846922834954?, Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 1.289897948556636? 1.579795897113272?]) - ] + sage: es = A.eigenspaces_left(format='all'); es # needs sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (-1.348469228349535?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 0.3101020514433644? -0.3797958971132713?]), + (13.34846922834954?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 1.289897948556636? 1.579795897113272?]) ] - sage: es = A.eigenspaces_left(format='galois'); es # optional - sage.rings.number_field - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) - ] - sage: es = A.eigenspaces_left(format='galois', algebraic_multiplicity=True); es # optional - sage.rings.number_field - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1], 1), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5], 1) - ] - sage: e, v, n = es[0]; v = v.basis()[0] # optional - sage.rings.number_field - sage: delta = e*v - v*A # optional - sage.rings.number_field - sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: es = A.eigenspaces_left(format='galois'); es + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) ] + sage: es = A.eigenspaces_left(format='galois', + ....: algebraic_multiplicity=True); es + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1], + 1), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5], + 1) ] + sage: e, v, n = es[0]; v = v.basis()[0] + sage: delta = e*v - v*A + sage: abs(abs(delta)) < 1e-10 True The same computation, but with implicit base change to a field. :: @@ -6176,21 +6201,23 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_left(format='galois') # optional - sage.rings.number_field - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) - ] + sage: A.eigenspaces_left(format='galois') # needs sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/15*a1 + 2/5 2/15*a1 - 1/5]) ] We compute the left eigenspaces of the matrix of the Hecke operator `T_2` on level 43 modular symbols, both with all eigenvalues (the default) and with one subspace per factor. :: - sage: A = ModularSymbols(43).T(2).matrix(); A # optional - sage.modular + sage: # needs sage.modular + sage: A = ModularSymbols(43).T(2).matrix(); A [ 3 0 0 0 0 0 -1] [ 0 -2 1 0 0 0 0] [ 0 -1 1 1 0 -1 0] @@ -6198,13 +6225,13 @@ cdef class Matrix(Matrix1): [ 0 -1 0 1 1 -1 1] [ 0 0 -2 0 2 -2 1] [ 0 0 -1 0 1 0 -1] - sage: A.base_ring() # optional - sage.modular + sage: A.base_ring() Rational Field - sage: f = A.charpoly(); f # optional - sage.modular + sage: f = A.charpoly(); f x^7 + x^6 - 12*x^5 - 16*x^4 + 36*x^3 + 52*x^2 - 32*x - 48 - sage: factor(f) # optional - sage.modular + sage: factor(f) (x - 3) * (x + 2)^2 * (x^2 - 2)^2 - sage: A.eigenspaces_left(algebraic_multiplicity=True) # optional - sage.modular + sage: A.eigenspaces_left(algebraic_multiplicity=True) [ (3, Vector space of degree 7 and dimension 1 over Rational Field User basis matrix: @@ -6228,7 +6255,7 @@ cdef class Matrix(Matrix1): [ 0 1 0 -1 -2.414213562373095? 1 -1] [ 0 0 1 0 -1 0 -0.4142135623730951?], 2) ] - sage: A.eigenspaces_left(format='galois', algebraic_multiplicity=True) # optional - sage.modular + sage: A.eigenspaces_left(format='galois', algebraic_multiplicity=True) [ (3, Vector space of degree 7 and dimension 1 over Rational Field User basis matrix: @@ -6250,16 +6277,17 @@ cdef class Matrix(Matrix1): Next we compute the left eigenspaces over the finite field of order 11. :: - sage: A = ModularSymbols(43, base_ring=GF(11), sign=1).T(2).matrix(); A # optional - sage.modular sage.rings.finite_rings + sage: # needs sage.modular sage.rings.finite_rings + sage: A = ModularSymbols(43, base_ring=GF(11), sign=1).T(2).matrix(); A [ 3 0 9 0] [ 0 9 0 10] [ 0 0 10 1] [ 0 0 1 1] - sage: A.base_ring() # optional - sage.modular sage.rings.finite_rings + sage: A.base_ring() Finite Field of size 11 - sage: A.charpoly() # optional - sage.modular sage.rings.finite_rings + sage: A.charpoly() x^4 + 10*x^3 + 3*x^2 + 2*x + 1 - sage: A.eigenspaces_left(format='galois', var='beta') # optional - sage.modular sage.rings.finite_rings + sage: A.eigenspaces_left(format='galois', var='beta') [ (9, Vector space of degree 4 and dimension 1 over Finite Field of size 11 User basis matrix: [0 1 5 6]), @@ -6296,13 +6324,14 @@ cdef class Matrix(Matrix1): [ 0.897878732... 0.278434036... -0.341010658...] [ 0.408248290... -0.816496580... 0.408248290...] - sage: x, y = var('x y') # optional - sage.symbolic - sage: S = matrix([[x, y], [y, 3*x^2]]) # optional - sage.symbolic - sage: em = S.eigenmatrix_left() # optional - sage.symbolic - sage: eigenvalues = em[0]; eigenvalues # optional - sage.symbolic + sage: # needs sage.symbolic + sage: x, y = var('x y') + sage: S = matrix([[x, y], [y, 3*x^2]]) + sage: em = S.eigenmatrix_left() + sage: eigenvalues = em[0]; eigenvalues [3/2*x^2 + 1/2*x - 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2) 0] [ 0 3/2*x^2 + 1/2*x + 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2)] - sage: eigenvectors = em[1]; eigenvectors # optional - sage.symbolic + sage: eigenvectors = em[1]; eigenvectors [ 1 1/2*(3*x^2 - x - sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] [ 1 1/2*(3*x^2 - x + sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] @@ -6310,28 +6339,30 @@ cdef class Matrix(Matrix1): possible, will raise an error. Using the ``'galois'`` format option is more likely to be successful. :: - sage: F. = FiniteField(11^2) # optional - sage.libs.pari - sage: A = matrix(F, [[b + 1, b + 1], [10*b + 4, 5*b + 4]]) # optional - sage.libs.pari - sage: A.eigenspaces_left(format='all') # optional - sage.libs.pari + sage: F. = FiniteField(11^2) # needs sage.rings.finite_rings + sage: A = matrix(F, [[b + 1, b + 1], [10*b + 4, 5*b + 4]]) # needs sage.rings.finite_rings + sage: A.eigenspaces_left(format='all') # needs sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: unable to construct eigenspaces for eigenvalues outside the base field, try the keyword option: format='galois' - sage: A.eigenspaces_left(format='galois') # optional - sage.libs.pari - [ - (a0, Vector space of degree 2 and dimension 1 over Univariate Quotient Polynomial Ring in a0 over Finite Field in b of size 11^2 with modulus x^2 + (5*b + 6)*x + 8*b + 10 - User basis matrix: - [ 1 6*b*a0 + 3*b + 1]) - ] + sage: A.eigenspaces_left(format='galois') # needs sage.rings.finite_rings + [ (a0, + Vector space of degree 2 and dimension 1 over + Univariate Quotient Polynomial Ring in a0 over + Finite Field in b of size 11^2 + with modulus x^2 + (5*b + 6)*x + 8*b + 10 + User basis matrix: + [ 1 6*b*a0 + 3*b + 1]) ] TESTS: We make sure that :trac:`13308` is fixed. :: - sage: M = ModularSymbols(Gamma1(23), sign=1) # optional - sage.modular - sage: m = M.cuspidal_subspace().hecke_matrix(2) # optional - sage.modular - sage: [j*m == i[0]*j # long time (4s) # optional - sage.modular + sage: M = ModularSymbols(Gamma1(23), sign=1) # needs sage.modular + sage: m = M.cuspidal_subspace().hecke_matrix(2) # needs sage.modular + sage: [j*m == i[0]*j # long time (4s) # needs sage.modular ....: for i in m.eigenspaces_left(format='all') for j in i[1].basis()] [True, True, True, True, True, True, True, True, True, True, True, True] @@ -6489,39 +6520,45 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_right() # optional - sage.rings.number_field - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (-1.348469228349535?, Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 0.1303061543300932? -0.7393876913398137?]), - (13.34846922834954?, Vector space of degree 3 and dimension 1 over Algebraic Field - User basis matrix: - [ 1 3.069693845669907? 5.139387691339814?]) - ] - sage: es = A.eigenspaces_right(format='galois'); es # optional - sage.rings.number_field - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) - ] - sage: es = A.eigenspaces_right(format='galois', algebraic_multiplicity=True); es # optional - sage.rings.number_field - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1], 1), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5], 1) - ] - sage: e, v, n = es[0]; v = v.basis()[0] # optional - sage.rings.number_field - sage: delta = v*e - A*v # optional - sage.rings.number_field - sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field + sage: A.eigenspaces_right() # needs sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (-1.348469228349535?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 0.1303061543300932? -0.7393876913398137?]), + (13.34846922834954?, + Vector space of degree 3 and dimension 1 over Algebraic Field + User basis matrix: + [ 1 3.069693845669907? 5.139387691339814?]) ] + sage: es = A.eigenspaces_right(format='galois'); es # needs sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) ] + sage: es = A.eigenspaces_right(format='galois', # needs sage.rings.number_field + ....: algebraic_multiplicity=True); es + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1], + 1), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5], + 1) ] + sage: e, v, n = es[0]; v = v.basis()[0] # needs sage.rings.number_field + sage: delta = v*e - A*v # needs sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # needs sage.rings.number_field True The same computation, but with implicit base change to a field:: @@ -6530,15 +6567,16 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_right(format='galois') # optional - sage.rings.number_field - [ - (0, Vector space of degree 3 and dimension 1 over Rational Field - User basis matrix: - [ 1 -2 1]), - (a1, Vector space of degree 3 and dimension 1 over Number Field in a1 with defining polynomial x^2 - 12*x - 18 - User basis matrix: - [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) - ] + sage: A.eigenspaces_right(format='galois') # needs sage.rings.number_field + [ (0, + Vector space of degree 3 and dimension 1 over Rational Field + User basis matrix: + [ 1 -2 1]), + (a1, + Vector space of degree 3 and dimension 1 over + Number Field in a1 with defining polynomial x^2 - 12*x - 18 + User basis matrix: + [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) ] This method is only applicable to exact matrices. The "eigenmatrix" routines for matrices with double-precision @@ -6565,13 +6603,14 @@ cdef class Matrix(Matrix1): [ 0.505774475... 0.104205787... -0.816496580...] [ 0.846785134... -0.591288087... 0.408248290...] - sage: x, y = var('x y') # optional - sage.symbolic - sage: S = matrix([[x, y], [y, 3*x^2]]) # optional - sage.symbolic - sage: em = S.eigenmatrix_right() # optional - sage.symbolic - sage: eigenvalues = em[0]; eigenvalues # optional - sage.symbolic + sage: # needs sage.symbolic + sage: x, y = var('x y') + sage: S = matrix([[x, y], [y, 3*x^2]]) + sage: em = S.eigenmatrix_right() + sage: eigenvalues = em[0]; eigenvalues [3/2*x^2 + 1/2*x - 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2) 0] [ 0 3/2*x^2 + 1/2*x + 1/2*sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2)] - sage: eigenvectors = em[1]; eigenvectors # optional - sage.symbolic + sage: eigenvectors = em[1]; eigenvectors [ 1 1] [1/2*(3*x^2 - x - sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y 1/2*(3*x^2 - x + sqrt(9*x^4 - 6*x^3 + x^2 + 4*y^2))/y] @@ -6642,7 +6681,7 @@ cdef class Matrix(Matrix1): [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15] - sage: sorted(a.eigenvalues(), reverse=True) # optional - sage.rings.number_field + sage: sorted(a.eigenvalues(), reverse=True) # needs sage.rings.number_field [32.46424919657298?, 0, 0, -2.464249196572981?] :: @@ -6651,7 +6690,7 @@ cdef class Matrix(Matrix1): ....: (-2, 0, -10, 2), ....: (-1, 0, 15, -2), ....: (0, 1, 0, -1)]) - sage: a.eigenvalues() # optional - sage.rings.number_field + sage: a.eigenvalues() # needs sage.rings.number_field [-0.9386318578049146?, 15.50655435353258?, 0.2160387521361705? - 4.713151979747493?*I, @@ -6662,7 +6701,7 @@ cdef class Matrix(Matrix1): :: sage: b = a + a.transpose() - sage: ev = b.eigenvalues(); ev # optional - sage.rings.number_field + sage: ev = b.eigenvalues(); ev # needs sage.rings.number_field [-8.35066086057957?, -1.107247901349379?, 5.718651326708515?, 33.73925743522043?] @@ -6671,11 +6710,11 @@ cdef class Matrix(Matrix1): :: - sage: e = ev[0]; e # optional - sage.rings.number_field + sage: e = ev[0]; e # needs sage.rings.number_field -8.35066086057957? - sage: p = e.minpoly(); p # optional - sage.rings.number_field + sage: p = e.minpoly(); p # needs sage.rings.number_field x^4 - 30*x^3 - 171*x^2 + 1460*x + 1784 - sage: p(e) == 0 # optional - sage.rings.number_field + sage: p(e) == 0 # needs sage.rings.number_field True To perform computations on the eigenvalue as an element of a number @@ -6683,7 +6722,7 @@ cdef class Matrix(Matrix1): :: - sage: e.as_number_field_element() # optional - sage.rings.number_field + sage: e.as_number_field_element() # needs sage.rings.number_field (Number Field in a with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264, a + 7, @@ -6697,29 +6736,31 @@ cdef class Matrix(Matrix1): :: sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) - sage: M.eigenvalues() # optional - sage.rings.number_field + sage: M.eigenvalues() # needs sage.rings.number_field [2, -1*I, 1*I] - sage: M.eigenvalues(extend=False) # optional - sage.rings.number_field + sage: M.eigenvalues(extend=False) # needs sage.rings.number_field [2] The method also works for matrices over finite fields:: sage: M = matrix(GF(3), [[0,1,1], [1,2,0], [2,0,1]]) - sage: ev = sorted(M.eigenvalues()); ev # optional - sage.rings.finite_rings + sage: ev = sorted(M.eigenvalues()); ev # needs sage.rings.finite_rings [2*z3, 2*z3 + 1, 2*z3 + 2] Similarly as in the case of ``QQbar``, the eigenvalues belong to some algebraic closure but they can be converted to elements of a finite field:: - sage: e = ev[0] # optional - sage.libs.pari - sage: e.parent() # optional - sage.libs.pari + sage: e = ev[0] # needs sage.rings.finite_rings + sage: e.parent() # needs sage.rings.finite_rings Algebraic closure of Finite Field of size 3 - sage: e.as_finite_field_element() # optional - sage.libs.pari - (Finite Field in z3 of size 3^3, 2*z3, Ring morphism: - From: Finite Field in z3 of size 3^3 - To: Algebraic closure of Finite Field of size 3 - Defn: z3 |--> z3) + sage: e.as_finite_field_element() # needs sage.rings.finite_rings + (Finite Field in z3 of size 3^3, + 2*z3, + Ring morphism: + From: Finite Field in z3 of size 3^3 + To: Algebraic closure of Finite Field of size 3 + Defn: z3 |--> z3) """ x = self.fetch('eigenvalues') if x is not None: @@ -6792,15 +6833,13 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenvectors_left(); es # optional - sage.rings.number_field - [(0, [ - (1, -2, 1) - ], 1), - (-1.348469228349535?, [(1, 0.3101020514433644?, -0.3797958971132713?)], 1), - (13.34846922834954?, [(1, 1.289897948556636?, 1.579795897113272?)], 1)] - sage: eval, [evec], mult = es[0] # optional - sage.rings.number_field - sage: delta = eval*evec - evec*A # optional - sage.rings.number_field - sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field + sage: es = A.eigenvectors_left(); es # needs sage.rings.number_field + [(0, [ (1, -2, 1) ], 1), + (-1.348469228349535?, [(1, 0.3101020514433644?, -0.3797958971132713?)], 1), + (13.34846922834954?, [(1, 1.289897948556636?, 1.579795897113272?)], 1)] + sage: eval, [evec], mult = es[0] # needs sage.rings.number_field + sage: delta = eval*evec - evec*A # needs sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # needs sage.rings.number_field True Notice the difference between considering ring extensions or not. @@ -6808,11 +6847,11 @@ cdef class Matrix(Matrix1): :: sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) - sage: M.eigenvectors_left() # optional - sage.rings.number_field - [(2, [ - (0, 0, 1) - ], 1), (-1*I, [(1, -1*I, 0)], 1), (1*I, [(1, 1*I, 0)], 1)] - sage: M.eigenvectors_left(extend=False) # optional - sage.rings.number_field + sage: M.eigenvectors_left() # needs sage.rings.number_field + [(2, [ (0, 0, 1) ], 1), + (-1*I, [(1, -1*I, 0)], 1), + (1*I, [(1, 1*I, 0)], 1)] + sage: M.eigenvectors_left(extend=False) # needs sage.rings.number_field [(2, [ (0, 0, 1) ], 1)] @@ -6829,16 +6868,16 @@ cdef class Matrix(Matrix1): Check the deprecation:: - sage: matrix(QQ, [[1, 2], [3, 4]]).eigenvectors_left(False) # optional - sage.rings.number_field + sage: matrix(QQ, [[1, 2], [3, 4]]).eigenvectors_left(False) # needs sage.rings.number_field doctest:...: DeprecationWarning: "extend" should be used as keyword argument See https://github.com/sagemath/sage/issues/29243 for details. [] Check :trac:`30518`:: - sage: K. = QuadraticField(-1) # optional - sage.rings.number_field - sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4, 4*i-4,1-i,-2]) # optional - sage.rings.number_field - sage: assert all(m*v == e*v for e, vs, _ in m.eigenvectors_right() for v in vs) # optional - sage.rings.number_field + sage: K. = QuadraticField(-1) # needs sage.rings.number_field + sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4, 4*i-4,1-i,-2]) # needs sage.rings.number_field + sage: assert all(m*v == e*v for e, vs, _ in m.eigenvectors_right() for v in vs) # needs sage.rings.number_field """ if other is not None: if isinstance(other, bool): @@ -6926,19 +6965,17 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenvectors_right(); es # optional - sage.rings.number_field - [(0, [ - (1, -2, 1) - ], 1), - (-1.348469228349535?, [(1, 0.1303061543300932?, -0.7393876913398137?)], 1), - (13.34846922834954?, [(1, 3.069693845669907?, 5.139387691339814?)], 1)] - sage: A.eigenvectors_right(extend=False) # optional - sage.rings.number_field + sage: es = A.eigenvectors_right(); es # needs sage.rings.number_field + [(0, [ (1, -2, 1) ], 1), + (-1.348469228349535?, [(1, 0.1303061543300932?, -0.7393876913398137?)], 1), + (13.34846922834954?, [(1, 3.069693845669907?, 5.139387691339814?)], 1)] + sage: A.eigenvectors_right(extend=False) # needs sage.rings.number_field [(0, [ (1, -2, 1) ], 1)] - sage: eval, [evec], mult = es[0] # optional - sage.rings.number_field - sage: delta = eval*evec - A*evec # optional - sage.rings.number_field - sage: abs(abs(delta)) < 1e-10 # optional - sage.rings.number_field + sage: eval, [evec], mult = es[0] # needs sage.rings.number_field + sage: delta = eval*evec - A*evec # needs sage.rings.number_field + sage: abs(abs(delta)) < 1e-10 # needs sage.rings.number_field True TESTS:: @@ -6998,23 +7035,23 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: D, P = A.eigenmatrix_left() # optional - sage.rings.number_field - sage: D # optional - sage.rings.number_field + sage: D, P = A.eigenmatrix_left() # needs sage.rings.number_field + sage: D # needs sage.rings.number_field [ 0 0 0] [ 0 -1.348469228349535? 0] [ 0 0 13.34846922834954?] - sage: P # optional - sage.rings.number_field + sage: P # needs sage.rings.number_field [ 1 -2 1] [ 1 0.3101020514433644? -0.3797958971132713?] [ 1 1.289897948556636? 1.579795897113272?] - sage: P*A == D*P # optional - sage.rings.number_field + sage: P*A == D*P # needs sage.rings.number_field True Because `P` is invertible, `A` is diagonalizable. :: - sage: A == (~P)*D*P # optional - sage.rings.number_field + sage: A == (~P)*D*P # needs sage.rings.number_field True The matrix `P` may contain zero rows corresponding to eigenvalues for @@ -7027,16 +7064,16 @@ cdef class Matrix(Matrix1): [2 1 0] [0 2 1] [0 0 2] - sage: D, P = A.eigenmatrix_left() # optional - sage.rings.number_field - sage: D # optional - sage.rings.number_field + sage: D, P = A.eigenmatrix_left() # needs sage.rings.number_field + sage: D # needs sage.rings.number_field [2 0 0] [0 2 0] [0 0 2] - sage: P # optional - sage.rings.number_field + sage: P # needs sage.rings.number_field [0 0 1] [0 0 0] [0 0 0] - sage: P*A == D*P # optional - sage.rings.number_field + sage: P*A == D*P # needs sage.rings.number_field True A generalized eigenvector decomposition:: @@ -7052,15 +7089,15 @@ cdef class Matrix(Matrix1): sage: A = matrix.identity(CDF, 2) sage: B = matrix(CDF, [[2, 1+I], [4, 2+2*I]]) sage: D, P = A.eigenmatrix_left(B) - sage: D.diagonal() # tol 1e-14 + sage: D.diagonal() # tol 1e-14 # needs sage.symbolic [0.2 - 0.1*I, +infinity] In this case, we can still verify the eigenvector equation for the first eigenvalue and first eigenvector:: - sage: l = D[0, 0] + sage: l = D[0, 0] # needs sage.symbolic sage: v = P[0, :] - sage: (v * A - l * v * B).norm() < 1e-14 + sage: (v * A - l * v * B).norm() < 1e-14 # needs sage.symbolic True The second eigenvector is contained in the left kernel of `B`:: @@ -7121,19 +7158,20 @@ cdef class Matrix(Matrix1): the algebraic multiplicity. The following examples show that these cases are detected (:trac:`27842`):: - sage: A = matrix(SR, [(225/548, 0, -175/274*sqrt(193/1446)), # optional - sage.symbolic + sage: # needs sage.symbolic + sage: A = matrix(SR, [(225/548, 0, -175/274*sqrt(193/1446)), ....: (0, 1/2, 0), ....: (-63/548*sqrt(723/386), 0, 49/548)]) - sage: A.eigenmatrix_left() # optional - sage.symbolic + sage: A.eigenmatrix_left() Traceback (most recent call last): ... RuntimeError: failed to compute eigenvectors for eigenvalue ..., check eigenvectors_left() for partial results - sage: B = matrix(SR, [(1/2, -7/2*sqrt(1/386), 0, 49/2*sqrt(1/279078)), # optional - sage.symbolic + sage: B = matrix(SR, [(1/2, -7/2*sqrt(1/386), 0, 49/2*sqrt(1/279078)), ....: (-7/2*sqrt(1/386), 211/772, 0, -8425/772*sqrt(1/723)), ....: (0, 0, 1/2, 0), ....: (49/2*sqrt(1/279078), -8425/772*sqrt(1/723), 0, 561/772)]) - sage: B.eigenmatrix_left() # long time (1.2 seconds) # optional - sage.symbolic + sage: B.eigenmatrix_left() # long time (1.2 seconds) Traceback (most recent call last): ... RuntimeError: failed to compute eigenvectors for eigenvalue ..., @@ -7216,23 +7254,23 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: D, P = A.eigenmatrix_right() # optional - sage.rings.number_field - sage: D # optional - sage.rings.number_field + sage: D, P = A.eigenmatrix_right() # needs sage.rings.number_field + sage: D # needs sage.rings.number_field [ 0 0 0] [ 0 -1.348469228349535? 0] [ 0 0 13.34846922834954?] - sage: P # optional - sage.rings.number_field + sage: P # needs sage.rings.number_field [ 1 1 1] [ -2 0.1303061543300932? 3.069693845669907?] [ 1 -0.7393876913398137? 5.139387691339814?] - sage: A*P == P*D # optional - sage.rings.number_field + sage: A*P == P*D # needs sage.rings.number_field True Because `P` is invertible, `A` is diagonalizable. :: - sage: A == P*D*(~P) # optional - sage.rings.number_field + sage: A == P*D*(~P) # needs sage.rings.number_field True The matrix `P` may contain zero columns corresponding to eigenvalues @@ -7245,16 +7283,16 @@ cdef class Matrix(Matrix1): [2 1 0] [0 2 1] [0 0 2] - sage: D, P = A.eigenmatrix_right() # optional - sage.rings.number_field - sage: D # optional - sage.rings.number_field + sage: D, P = A.eigenmatrix_right() # needs sage.rings.number_field + sage: D # needs sage.rings.number_field [2 0 0] [0 2 0] [0 0 2] - sage: P # optional - sage.rings.number_field + sage: P # needs sage.rings.number_field [1 0 0] [0 0 0] [0 0 0] - sage: A*P == P*D # optional - sage.rings.number_field + sage: A*P == P*D # needs sage.rings.number_field True A generalized eigenvector decomposition:: @@ -7276,9 +7314,9 @@ cdef class Matrix(Matrix1): In this case, we can still verify the eigenvector equation for the first eigenvalue and first eigenvector:: - sage: l = D[0, 0] + sage: l = D[0, 0] # needs sage.symbolic sage: v = P[:, 0] - sage: (A * v - B * v * l).norm() < 1e-14 + sage: (A * v - B * v * l).norm() < 1e-14 # needs sage.symbolic True The second eigenvector is contained in the right kernel of `B`:: @@ -7354,8 +7392,8 @@ cdef class Matrix(Matrix1): sage: M.eigenvalue_multiplicity(1) 0 - sage: M = posets.DiamondPoset(5).coxeter_transformation() # optional - sage.combinat, sage.graphs - sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] # optional - sage.combinat, sage.graphs + sage: M = posets.DiamondPoset(5).coxeter_transformation() # needs sage.combinat + sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] # needs sage.combinat [3, 2] TESTS:: @@ -7508,14 +7546,15 @@ cdef class Matrix(Matrix1): [ 0 4 8 12] [ 0 0 0 0] + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: L. = NumberField(x^2 - x + 2) # optional - sage.rings.number_field - sage: OL = L.ring_of_integers() # optional - sage.rings.number_field - sage: m = matrix(OL, 2, 2, [1,2,3,4+w]) # optional - sage.rings.number_field - sage: m.echelon_form() # optional - sage.rings.number_field + sage: L. = NumberField(x^2 - x + 2) + sage: OL = L.ring_of_integers() + sage: m = matrix(OL, 2, 2, [1,2,3,4+w]) + sage: m.echelon_form() [ 1 2] [ 0 w - 2] - sage: E, T = m.echelon_form(transformation=True); E,T + sage: E, T = m.echelon_form(transformation=True); E, T ( [ 1 2] [ 1 0] [ 0 w - 2], [-3 1] @@ -7659,7 +7698,7 @@ cdef class Matrix(Matrix1): sage: R. = QQ[] sage: a = matrix(R, 2, [x,y, x,y]) - sage: a.echelon_form() # not very useful? -- why two copies of the same row? # optional - sage.rings.function_field + sage: a.echelon_form() # not very useful? -- why two copies of the same row? # needs sage.rings.function_field [x y] [x y] @@ -7673,8 +7712,9 @@ cdef class Matrix(Matrix1): We check that the echelon form works for matrices over p-adics. See :trac:`17272`:: + sage: # needs sage.rings.padics sage: R = ZpCA(5,5,print_mode='val-unit') - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) + sage: A = matrix(R, 3,3, [250,2369,1147, 106,927,362, 90,398,2483]) sage: A [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] @@ -7886,13 +7926,13 @@ cdef class Matrix(Matrix1): sage: a._echelon('classical') [ 1 0 -1] [ 0 1 2] - sage: R = ZpCA(5, 5, print_mode='val-unit') # optional - sage.rings.padics - sage: A = matrix(R, 3, 3, [250,2369,1147, 106,927,362, 90,398,2483]) # optional - sage.rings.padics - sage: A # optional - sage.rings.padics + sage: R = ZpCA(5, 5, print_mode='val-unit') # needs sage.rings.padics + sage: A = matrix(R, 3, 3, [250,2369,1147, 106,927,362, 90,398,2483]) # needs sage.rings.padics + sage: A # needs sage.rings.padics [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: A._echelon('partial_pivoting') # optional - sage.rings.padics + sage: A._echelon('partial_pivoting') # needs sage.rings.padics [1 + O(5^5) O(5^5) O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5)] @@ -7965,13 +8005,13 @@ cdef class Matrix(Matrix1): sage: P = a._echelon_in_place('classical'); a [ 1 0 -1] [ 0 1 2] - sage: R = ZpCA(5, 5, print_mode='val-unit') # optional - sage.rings.padics - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) # optional - sage.rings.padics - sage: A # optional - sage.rings.padics + sage: R = ZpCA(5, 5, print_mode='val-unit') # needs sage.rings.padics + sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) # needs sage.rings.padics + sage: A # needs sage.rings.padics [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: P = A._echelon_in_place('partial_pivoting'); A # optional - sage.rings.padics + sage: P = A._echelon_in_place('partial_pivoting'); A # needs sage.rings.padics [1 + O(5^5) O(5^5) O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5)] @@ -8343,14 +8383,15 @@ cdef class Matrix(Matrix1): [ 6 1/4] [ 8 -5] - sage: B = M.as_bipartite_graph() # optional - sage.graphs - sage: B # optional - sage.graphs + sage: # needs sage.graphs + sage: B = M.as_bipartite_graph() + sage: B Bipartite graph on 5 vertices - sage: B.edges(sort=True) # optional - sage.graphs + sage: B.edges(sort=True) [(1, 4, 1/3), (1, 5, 7), (2, 4, 6), (2, 5, 1/4), (3, 4, 8), (3, 5, -5)] - sage: len(B.left) == M.nrows() # optional - sage.graphs + sage: len(B.left) == M.nrows() True - sage: len(B.right) == M.ncols() # optional - sage.graphs + sage: len(B.right) == M.ncols() True """ from sage.graphs.bipartite_graph import BipartiteGraph @@ -8377,18 +8418,18 @@ cdef class Matrix(Matrix1): [1 0] [1 0] [0 1] - sage: A = M.automorphisms_of_rows_and_columns() # optional - sage.groups - sage: A # optional - sage.groups + sage: A = M.automorphisms_of_rows_and_columns() # needs sage.groups + sage: A # needs sage.groups [((), ()), ((1,2), ())] - sage: M = matrix(ZZ,[[1,1,1,1],[1,1,1,1]]) # optional - sage.groups - sage: A = M.automorphisms_of_rows_and_columns() # optional - sage.groups - sage: len(A) # optional - sage.groups + sage: M = matrix(ZZ, [[1,1,1,1],[1,1,1,1]]) + sage: A = M.automorphisms_of_rows_and_columns() # needs sage.groups + sage: len(A) # needs sage.groups 48 One can now apply these automorphisms to ``M`` to show that it leaves it invariant:: - sage: all(M.with_permuted_rows_and_columns(*i) == M for i in A) # optional - sage.groups + sage: all(M.with_permuted_rows_and_columns(*i) == M for i in A) # needs sage.groups True Check that :trac:`25426` is fixed:: @@ -8398,7 +8439,7 @@ cdef class Matrix(Matrix1): ....: (1, 0, 3, 0, 2), ....: (0, 1, 0, 2, 1), ....: (0, 0, 2, 1, 2)]) - sage: j.automorphisms_of_rows_and_columns() # optional - sage.groups + sage: j.automorphisms_of_rows_and_columns() # needs sage.groups [((), ()), ((1,3)(2,5), (1,3)(2,5))] """ from sage.groups.perm_gps.constructor import \ @@ -8456,7 +8497,7 @@ cdef class Matrix(Matrix1): [-1 5] [ 2 4] - sage: M.permutation_normal_form(check=True) # optional - sage.graphs sage.groups + sage: M.permutation_normal_form(check=True) # needs sage.graphs sage.groups ( [ 5 -1] [ 4 2] @@ -8467,7 +8508,7 @@ cdef class Matrix(Matrix1): TESTS:: sage: M = matrix(ZZ, [[3, 4, 5], [3, 4, 5], [3, 5, 4], [2, 0,1]]) - sage: M.permutation_normal_form() # optional - sage.graphs + sage: M.permutation_normal_form() # needs sage.graphs [5 4 3] [5 4 3] [4 5 3] @@ -8618,7 +8659,7 @@ cdef class Matrix(Matrix1): [1 2 3] [2 6 4] [3 5 3] - sage: M.is_permutation_of(N) # optional - sage.graphs + sage: M.is_permutation_of(N) # needs sage.graphs True Some examples that are not permutations of each other:: @@ -8628,13 +8669,13 @@ cdef class Matrix(Matrix1): [1 2 3] [4 5 6] [7 8 9] - sage: M.is_permutation_of(N) # optional - sage.graphs + sage: M.is_permutation_of(N) # needs sage.graphs False sage: N = matrix(ZZ, [[1,2], [3,4]]) sage: N [1 2] [3 4] - sage: M.is_permutation_of(N) # optional - sage.graphs + sage: M.is_permutation_of(N) False And for when ``check`` is True:: @@ -8644,11 +8685,11 @@ cdef class Matrix(Matrix1): [3 5 3] [2 6 4] [1 2 3] - sage: r = M.is_permutation_of(N, check=True) # optional - sage.graphs - sage: r # optional - sage.graphs + sage: r = M.is_permutation_of(N, check=True) # needs sage.graphs + sage: r # needs sage.graphs (True, ((1,2,3), ())) - sage: p = r[1] # optional - sage.graphs - sage: M.with_permuted_rows_and_columns(*p) == N # optional - sage.graphs + sage: p = r[1] # needs sage.graphs + sage: M.with_permuted_rows_and_columns(*p) == N # needs sage.graphs True """ ncols = self.ncols() @@ -8866,26 +8907,27 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(5, 5, prime_range(100)) # optional - sage.libs.pari - sage: M.subdivide(2,3); M # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: M = matrix(5, 5, prime_range(100)) + sage: M.subdivide(2,3); M [ 2 3 5| 7 11] [13 17 19|23 29] [--------+-----] [31 37 41|43 47] [53 59 61|67 71] [73 79 83|89 97] - sage: M.subdivision(0,0) # optional - sage.libs.pari + sage: M.subdivision(0,0) [ 2 3 5] [13 17 19] - sage: M.subdivision(1,0) # optional - sage.libs.pari + sage: M.subdivision(1,0) [31 37 41] [53 59 61] [73 79 83] - sage: M.subdivision_entry(1,0,0,0) # optional - sage.libs.pari + sage: M.subdivision_entry(1,0,0,0) 31 - sage: M.subdivisions() # optional - sage.libs.pari + sage: M.subdivisions() ([2], [3]) - sage: M.subdivide(None, [1,3]); M # optional - sage.libs.pari + sage: M.subdivide(None, [1,3]); M [ 2| 3 5| 7 11] [13|17 19|23 29] [31|37 41|43 47] @@ -8894,7 +8936,8 @@ cdef class Matrix(Matrix1): Degenerate cases work too:: - sage: M.subdivide([2,5], [0,1,3]); M # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: M.subdivide([2,5], [0,1,3]); M [| 2| 3 5| 7 11] [|13|17 19|23 29] [+--+-----+-----] @@ -8902,12 +8945,12 @@ cdef class Matrix(Matrix1): [|53|59 61|67 71] [|73|79 83|89 97] [+--+-----+-----] - sage: M.subdivision(0,0) # optional - sage.libs.pari + sage: M.subdivision(0,0) [] - sage: M.subdivision(0,1) # optional - sage.libs.pari + sage: M.subdivision(0,1) [ 2] [13] - sage: M.subdivide([2,2,3], [0,0,1,1]); M # optional - sage.libs.pari + sage: M.subdivide([2,2,3], [0,0,1,1]); M [|| 2|| 3 5 7 11] [||13||17 19 23 29] [++--++-----------] @@ -8916,14 +8959,14 @@ cdef class Matrix(Matrix1): [++--++-----------] [||53||59 61 67 71] [||73||79 83 89 97] - sage: M.subdivision(0,0) # optional - sage.libs.pari + sage: M.subdivision(0,0) [] - sage: M.subdivision(2,4) # optional - sage.libs.pari + sage: M.subdivision(2,4) [37 41 43 47] Indices do not need to be in the right order (:trac:`14064`):: - sage: M.subdivide([4, 2], [3, 1]); M # optional - sage.libs.pari + sage: M.subdivide([4, 2], [3, 1]); M # needs sage.libs.pari [ 2| 3 5| 7 11] [13|17 19|23 29] [--+-----+-----] @@ -9252,7 +9295,7 @@ cdef class Matrix(Matrix1): sage: D = A.tensor_product(B) sage: D.parent() Full MatrixSpace of 6 by 12 dense matrices over Finite Field of size 23 - sage: E = C.tensor_product(B) # optional - sage.libs.pari + sage: E = C.tensor_product(B) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: @@ -9569,26 +9612,28 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQbar, [[(1/sqrt(5))*(1+i), (1/sqrt(55))*(3+2*I), (1/sqrt(22))*(2+2*I)], # optional - sage.symbolic sage.rings.number_field - ....: [(1/sqrt(5))*(1-i), (1/sqrt(55))*(2+2*I), (1/sqrt(22))*(-3+I)], - ....: [ (1/sqrt(5))*I, (1/sqrt(55))*(3-5*I), (1/sqrt(22))*(-2)]]) - sage: A.is_unitary() # optional - sage.symbolic sage.rings.number_field + sage: A = matrix(QQbar, # needs sage.rings.number_field sage.symbolic + ....: [[(1/sqrt(5))*(1+i), (1/sqrt(55))*(3+2*I), (1/sqrt(22))*(2+2*I)], + ....: [(1/sqrt(5))*(1-i), (1/sqrt(55))*(2+2*I), (1/sqrt(22))*(-3+I)], + ....: [ (1/sqrt(5))*I, (1/sqrt(55))*(3-5*I), (1/sqrt(22))*(-2)]]) + sage: A.is_unitary() # needs sage.rings.number_field sage.symbolic True A permutation matrix is always orthogonal. :: - sage: sigma = Permutation([1,3,4,5,2]) # optional - sage.combinat - sage: P = sigma.to_matrix(); P # optional - sage.combinat + sage: # needs sage.combinat + sage: sigma = Permutation([1,3,4,5,2]) + sage: P = sigma.to_matrix(); P [1 0 0 0 0] [0 0 0 0 1] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] - sage: P.is_unitary() # optional - sage.combinat + sage: P.is_unitary() True - sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat sage.libs.pari + sage: P.change_ring(GF(3)).is_unitary() # needs sage.rings.finite_rings True - sage: P.change_ring(GF(3)).is_unitary() # optional - sage.combinat sage.libs.pari + sage: P.change_ring(GF(3)).is_unitary() # needs sage.rings.finite_rings True A square matrix far from unitary. :: @@ -9599,7 +9644,7 @@ cdef class Matrix(Matrix1): Rectangular matrices are never unitary. :: - sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field + sage: A = matrix(QQbar, 3, 4) # needs sage.rings.number_field sage: A.is_unitary() False """ @@ -9725,30 +9770,32 @@ cdef class Matrix(Matrix1): Sage has several fields besides the entire complex numbers where conjugation is non-trivial. :: - sage: F. = QuadraticField(-7) # optional - sage.rings.number_field - sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: F. = QuadraticField(-7) + sage: C = matrix(F, [[-2*b - 3, 7*b - 6, -b + 3], ....: [-2*b - 3, -3*b + 2, -2*b], ....: [ b + 1, 0, -2]]) - sage: C = C*C.conjugate_transpose() # optional - sage.rings.number_field - sage: C.is_normal() # optional - sage.rings.number_field + sage: C = C*C.conjugate_transpose() + sage: C.is_normal() True A matrix that is nearly normal, but for a non-real diagonal entry. :: - sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[ 2, 2-I, 1+4*I], ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) - sage: A.is_normal() # optional - sage.rings.number_field + sage: A.is_normal() False - sage: A[1,1] = 132 # optional - sage.rings.number_field - sage: A.is_normal() # optional - sage.rings.number_field + sage: A[1,1] = 132 + sage: A.is_normal() True Rectangular matrices are never normal. :: - sage: A = matrix(QQbar, 3, 4) # optional - sage.rings.number_field - sage: A.is_normal() # optional - sage.rings.number_field + sage: A = matrix(QQbar, 3, 4) # needs sage.rings.number_field + sage: A.is_normal() # needs sage.rings.number_field False A square, empty matrix is trivially normal. :: @@ -9813,19 +9860,20 @@ cdef class Matrix(Matrix1): try to deduce the decomposition from the matrix :: sage: L = [] - sage: L.append((9, Permutation([4, 1, 3, 5, 2]))) # optional - sage.combinat - sage: L.append((6, Permutation([5, 3, 4, 1, 2]))) # optional - sage.combinat - sage: L.append((3, Permutation([3, 1, 4, 2, 5]))) # optional - sage.combinat - sage: L.append((2, Permutation([1, 4, 2, 3, 5]))) # optional - sage.combinat - sage: M = sum([c * p.to_matrix() for (c,p) in L]) # optional - sage.combinat - sage: decomp = sage.combinat.permutation.bistochastic_as_sum_of_permutations(M) # optional - sage.combinat - sage: print(decomp) # optional - sage.combinat + sage: L.append((9, Permutation([4, 1, 3, 5, 2]))) + sage: L.append((6, Permutation([5, 3, 4, 1, 2]))) + sage: L.append((3, Permutation([3, 1, 4, 2, 5]))) + sage: L.append((2, Permutation([1, 4, 2, 3, 5]))) + sage: M = sum([c * p.to_matrix() for c, p in L]) + sage: from sage.combinat.permutation import bistochastic_as_sum_of_permutations + sage: decomp = bistochastic_as_sum_of_permutations(M) # needs sage.combinat + sage: print(decomp) # needs sage.combinat 2*B[[1, 4, 2, 3, 5]] + 3*B[[3, 1, 4, 2, 5]] + 9*B[[4, 1, 3, 5, 2]] + 6*B[[5, 3, 4, 1, 2]] An exception is raised when the matrix is not bistochastic:: sage: M = Matrix([[2,3],[2,2]]) - sage: decomp = sage.combinat.permutation.bistochastic_as_sum_of_permutations(M) # optional - sage.combinat + sage: decomp = bistochastic_as_sum_of_permutations(M) # needs sage.combinat Traceback (most recent call last): ... ValueError: The matrix is not bistochastic @@ -9865,13 +9913,13 @@ cdef class Matrix(Matrix1): sage: M = random_matrix(CC, 5, 7) sage: for i in range(5): M[i,i] = 0 sage: M[4, 0] = M[0, 6] = M[4, 6] = 0 - sage: img = M.visualize_structure(); img # optional - pillow + sage: img = M.visualize_structure(); img # needs pillow 7x5px 24-bit RGB image You can use :meth:`~sage.repl.image.Image.save` to save the resulting image:: - sage: # needs - pillow sage.rings.real_mpfr + sage: # needs pillow sage.rings.real_mpfr sage: filename = tmp_filename(ext='.png') sage: img.save(filename) sage: with open(filename, 'rb') as fobj: @@ -9882,7 +9930,7 @@ cdef class Matrix(Matrix1): Test :trac:`17341`:: - sage: random_matrix(GF(2), 8, 586, sparse=True).visualize_structure() # optional - sage.libs.pari + sage: random_matrix(GF(2), 8, 586, sparse=True).visualize_structure() # needs sage.rings.finite_rings 512x6px 24-bit RGB image """ cdef Py_ssize_t x, y, _x, _y, v, bi, bisq @@ -10042,22 +10090,22 @@ cdef class Matrix(Matrix1): sage: M = Matrix(QQ, 2, 2, [5/3,2/56, 33/13,41/10]); M [ 5/3 1/28] [33/13 41/10] - sage: N = M.adjugate(); N # optional - sage.libs.pari + sage: N = M.adjugate(); N # needs sage.libs.pari [ 41/10 -1/28] [-33/13 5/3] - sage: M * N # optional - sage.libs.pari + sage: M * N # needs sage.libs.pari [7363/1092 0] [ 0 7363/1092] An alias is :meth:`adjoint_classical`, which replaces the deprecated :meth:`adjoint` method:: - sage: M.adjoint() # optional - sage.libs.pari + sage: M.adjoint() # needs sage.libs.pari ...: DeprecationWarning: adjoint is deprecated. Please use adjugate instead. See https://github.com/sagemath/sage/issues/10501 for details. [ 41/10 -1/28] [-33/13 5/3] - sage: M.adjoint_classical() # optional - sage.libs.pari + sage: M.adjoint_classical() # needs sage.libs.pari [ 41/10 -1/28] [-33/13 5/3] @@ -10126,19 +10174,19 @@ cdef class Matrix(Matrix1): not an integral domain:: sage: R. = QQ[] - sage: S. = R.quo((b^3)) # optional - sage.libs.singular - sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) # optional - sage.libs.singular - sage: A # optional - sage.libs.singular + sage: S. = R.quo((b^3)) # needs sage.libs.singular + sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) # needs sage.libs.singular + sage: A # needs sage.libs.singular [ x*y^2 2*x] [ 2 x^10*y] - sage: A.det() # optional - sage.libs.singular + sage: A.det() # needs sage.libs.singular -4*x - sage: A.charpoly('T') # optional - sage.libs.singular + sage: A.charpoly('T') # needs sage.libs.singular T^2 + (-x^10*y - x*y^2)*T - 4*x - sage: A.adjugate() # optional - sage.libs.singular + sage: A.adjugate() # needs sage.libs.singular [x^10*y -2*x] [ -2 x*y^2] - sage: A.adjugate() * A # optional - sage.libs.singular + sage: A.adjugate() * A # needs sage.libs.singular [-4*x 0] [ 0 -4*x] @@ -10161,8 +10209,8 @@ cdef class Matrix(Matrix1): presence of non-integral powers of the variable `x` (:trac:`14403`):: - sage: x = var('x') # optional - sage.symbolic - sage: Matrix([[sqrt(x),x], [1,0]]).adjugate() # optional - sage.symbolic + sage: x = var('x') # needs sage.symbolic + sage: Matrix([[sqrt(x),x], [1,0]]).adjugate() # needs sage.symbolic [ 0 -x] [ -1 sqrt(x)] @@ -10237,58 +10285,60 @@ cdef class Matrix(Matrix1): For a nonsingular matrix, the QR decomposition is unique. :: - sage: A = matrix(QQbar, [[-2, 0, -4, -1, -1], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[-2, 0, -4, -1, -1], ....: [-2, 1, -6, -3, -1], ....: [1, 1, 7, 4, 5], ....: [3, 0, 8, 3, 3], ....: [-1, 1, -6, -6, 5]]) - sage: Q, R = A.QR() # optional - sage.rings.number_field - sage: Q # optional - sage.rings.number_field + sage: Q, R = A.QR() + sage: Q [ -0.4588314677411235? -0.1260506983326509? 0.3812120831224489? -0.394573711338418? -0.6874400625964?] [ -0.4588314677411235? 0.4726901187474409? -0.05198346588033394? 0.7172941251646595? -0.2209628772631?] [ 0.2294157338705618? 0.6617661662464172? 0.6619227988762521? -0.1808720937375480? 0.1964114464561?] [ 0.6882472016116853? 0.1890760474989764? -0.2044682991293135? 0.0966302966543065? -0.6628886317894?] [ -0.2294157338705618? 0.5357154679137663? -0.609939332995919? -0.536422031427112? 0.0245514308070?] - sage: R # optional - sage.rings.number_field + sage: R [ 4.358898943540674? -0.4588314677411235? 13.07669683062202? 6.194224814505168? 2.982404540317303?] [ 0 1.670171752907625? 0.5987408170800917? -1.292019657909672? 6.207996892883057?] [ 0 0 5.444401659866974? 5.468660610611130? -0.6827161852283857?] [ 0 0 0 1.027626039419836? -3.619300149686620?] [ 0 0 0 0 0.024551430807012?] - sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field + sage: Q.conjugate_transpose()*Q [1.000000000000000? 0.?e-18 0.?e-17 0.?e-16 0.?e-13] [ 0.?e-18 1.000000000000000? 0.?e-17 0.?e-16 0.?e-13] [ 0.?e-17 0.?e-17 1.000000000000000? 0.?e-16 0.?e-13] [ 0.?e-16 0.?e-16 0.?e-16 1.000000000000000? 0.?e-13] [ 0.?e-13 0.?e-13 0.?e-13 0.?e-13 1.0000000000000?] - sage: Q*R == A # optional - sage.rings.number_field + sage: Q * R == A True An example with complex numbers in ``QQbar``, the field of algebraic numbers. :: - sage: A = matrix(QQbar, [[-8, 4*I + 1, -I + 2, 2*I + 1], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[-8, 4*I + 1, -I + 2, 2*I + 1], ....: [1, -2*I - 1, -I + 3, -I + 1], ....: [I + 7, 2*I + 1, -2*I + 7, -I + 1], ....: [I + 2, 0, I + 12, -1]]) - sage: Q, R = A.QR() # optional - sage.rings.number_field - sage: Q # optional - sage.rings.number_field + sage: Q, R = A.QR() + sage: Q [ -0.7302967433402215? 0.2070566455055649? + 0.5383472783144687?*I 0.2463049809998642? - 0.0764456358723292?*I 0.2381617683194332? - 0.1036596032779695?*I] [ 0.0912870929175277? -0.2070566455055649? - 0.3778783780476559?*I 0.3786559533863033? - 0.1952221495524667?*I 0.701244450214469? - 0.3643711650986595?*I] [ 0.6390096504226938? + 0.0912870929175277?*I 0.1708217325420910? + 0.6677576817554466?*I -0.03411475806452072? + 0.04090198741767143?*I 0.3140171085506764? - 0.0825191718705412?*I] [ 0.1825741858350554? + 0.0912870929175277?*I -0.03623491296347385? + 0.0724698259269477?*I 0.8632284069415110? + 0.06322839976356195?*I -0.4499694867611521? - 0.0116119181208918?*I] - sage: R # optional - sage.rings.number_field + sage: R [ 10.95445115010333? 0.?e-18 - 1.917028951268082?*I 5.385938482134133? - 2.190890230020665?*I -0.2738612787525831? - 2.190890230020665?*I] [ 0 4.829596256417300? + 0.?e-18*I -0.869637911123373? - 5.864879483945125?*I 0.993871898426712? - 0.3054085521207082?*I] [ 0 0 12.00160760935814? + 0.?e-16*I -0.2709533402297273? + 0.4420629644486323?*I] [ 0 0 0 1.942963944258992? + 0.?e-16*I] - sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field + sage: Q.conjugate_transpose()*Q [1.000000000000000? + 0.?e-19*I 0.?e-18 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-18 + 0.?e-17*I 1.000000000000000? + 0.?e-17*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-17 + 0.?e-17*I 0.?e-17 + 0.?e-17*I 1.000000000000000? + 0.?e-17*I 0.?e-16 + 0.?e-16*I] [ 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I 1.000000000000000? + 0.?e-16*I] - sage: Q*R - A # optional - sage.rings.number_field + sage: Q*R - A [ 0.?e-17 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] [ 0.?e-18 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] [0.?e-17 + 0.?e-18*I 0.?e-17 + 0.?e-17*I 0.?e-16 + 0.?e-16*I 0.?e-16 + 0.?e-16*I] @@ -10296,58 +10346,61 @@ cdef class Matrix(Matrix1): A rank-deficient rectangular matrix, with both values of the ``full`` keyword. :: - sage: A = matrix(QQbar, [[2, -3, 3], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[2, -3, 3], ....: [-1, 1, -1], ....: [-1, 3, -3], ....: [-5, 1, -1]]) - sage: Q, R = A.QR() # optional - sage.rings.number_field - sage: Q # optional - sage.rings.number_field + sage: Q, R = A.QR() + sage: Q [ 0.3592106040535498? -0.5693261797050169? 0.7239227659930268? 0.1509015305256380?] [ -0.1796053020267749? 0.1445907757980996? 0 0.9730546968377341?] [ -0.1796053020267749? 0.7048800320157352? 0.672213996993525? -0.1378927778941174?] [ -0.8980265101338745? -0.3976246334447737? 0.1551263069985058? -0.10667177157846818?] - sage: R # optional - sage.rings.number_field + sage: R [ 5.567764362830022? -2.694079530401624? 2.694079530401624?] [ 0 3.569584777515583? -3.569584777515583?] [ 0 0 0] [ 0 0 0] - sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field + sage: Q.conjugate_transpose() * Q [ 1 0.?e-18 0.?e-18 0.?e-18] [ 0.?e-18 1 0.?e-18 0.?e-18] [ 0.?e-18 0.?e-18 1.000000000000000? 0.?e-18] [ 0.?e-18 0.?e-18 0.?e-18 1.000000000000000?] - sage: Q, R = A.QR(full=False) # optional - sage.rings.number_field - sage: Q # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: Q, R = A.QR(full=False) + sage: Q [ 0.3592106040535498? -0.5693261797050169?] [-0.1796053020267749? 0.1445907757980996?] [-0.1796053020267749? 0.7048800320157352?] [-0.8980265101338745? -0.3976246334447737?] - sage: R # optional - sage.rings.number_field + sage: R [ 5.567764362830022? -2.694079530401624? 2.694079530401624?] [ 0 3.569584777515583? -3.569584777515583?] - sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field + sage: Q.conjugate_transpose()*Q [ 1 0.?e-18] [0.?e-18 1] Another rank-deficient rectangular matrix, with complex entries, as a reduced decomposition. :: - sage: A = matrix(QQbar, [[-3*I - 3, I - 3, -12*I + 1, -2], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[-3*I - 3, I - 3, -12*I + 1, -2], ....: [-I - 1, -2, 5*I - 1, -I - 2], ....: [-4*I - 4, I - 5, -7*I, -I - 4]]) - sage: Q, R = A.QR(full=False) # optional - sage.rings.number_field - sage: Q # optional - sage.rings.number_field + sage: Q, R = A.QR(full=False) + sage: Q [ -0.4160251471689219? - 0.4160251471689219?*I 0.5370861555295747? + 0.1790287185098583?*I] [ -0.1386750490563073? - 0.1386750490563073?*I -0.7519206177414046? - 0.2506402059138015?*I] [ -0.5547001962252291? - 0.5547001962252291?*I -0.2148344622118299? - 0.07161148740394329?*I] - sage: R # optional - sage.rings.number_field + sage: R [ 7.211102550927979? 3.328201177351375? - 5.269651864139676?*I 7.904477796209515? + 8.45917799243475?*I 4.021576422632911? - 2.634825932069838?*I] [ 0 1.074172311059150? -1.611258466588724? - 9.13046464400277?*I 1.611258466588724? + 0.5370861555295747?*I] - sage: Q.conjugate_transpose()*Q # optional - sage.rings.number_field + sage: Q.conjugate_transpose()*Q [1 0] [0 1] - sage: Q*R - A # optional - sage.rings.number_field + sage: Q*R - A [0 0 0 0] [0 0 0 0] [0 0 0 0] @@ -10355,29 +10408,31 @@ cdef class Matrix(Matrix1): Results of full decompositions are cached and thus returned immutable. :: - sage: A = random_matrix(QQbar, 2, 2) # optional - sage.rings.number_field - sage: Q, R = A.QR() # optional - sage.rings.number_field - sage: Q.is_mutable() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = random_matrix(QQbar, 2, 2) + sage: Q, R = A.QR() + sage: Q.is_mutable() False - sage: R.is_mutable() # optional - sage.rings.number_field + sage: R.is_mutable() False Trivial cases return trivial results of the correct size, and we check `Q` itself in one case. :: - sage: A = zero_matrix(QQbar, 0, 10) # optional - sage.rings.number_field - sage: Q, R = A.QR() # optional - sage.rings.number_field - sage: Q.nrows(), Q.ncols() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = zero_matrix(QQbar, 0, 10) + sage: Q, R = A.QR() + sage: Q.nrows(), Q.ncols() (0, 0) - sage: R.nrows(), R.ncols() # optional - sage.rings.number_field + sage: R.nrows(), R.ncols() (0, 10) - sage: A = zero_matrix(QQbar, 3, 0) # optional - sage.rings.number_field - sage: Q, R = A.QR() # optional - sage.rings.number_field - sage: Q.nrows(), Q.ncols() # optional - sage.rings.number_field + sage: A = zero_matrix(QQbar, 3, 0) + sage: Q, R = A.QR() + sage: Q.nrows(), Q.ncols() (3, 3) - sage: R.nrows(), R.ncols() # optional - sage.rings.number_field + sage: R.nrows(), R.ncols() (3, 0) - sage: Q # optional - sage.rings.number_field + sage: Q [1 0 0] [0 1 0] [0 0 1] @@ -10404,7 +10459,7 @@ cdef class Matrix(Matrix1): roots, though some small cases pass through. :: sage: A = matrix(ZZ, 3, 3, range(9)) - sage: A.QR() # optional - sage.symbolic + sage: A.QR() # needs sage.symbolic Traceback (most recent call last): ... TypeError: QR decomposition unable to compute square roots in Rational Field @@ -10534,32 +10589,33 @@ cdef class Matrix(Matrix1): so we need to check with the conjugate-transpose. This example verifies that the bug on :trac:`10791` is fixed. :: - sage: F. = QuadraticField(-5) # optional - sage.rings.number_field - sage: A = matrix(F, [[ 1, a - 3, a - 2, a + 1], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: F. = QuadraticField(-5) + sage: A = matrix(F, [[ 1, a - 3, a - 2, a + 1], ....: [ a, 2*a + 1, 3*a + 1, 1], ....: [a + 1, a - 6, 2*a - 5, 1], ....: [ 2*a, a, 3*a, -3], ....: [ 1, a - 1, a, a - 1]]) - sage: A.rank() # optional - sage.rings.number_field + sage: A.rank() 3 - sage: Q, R = A._gram_schmidt_noscale() # optional - sage.rings.number_field - sage: Q # optional - sage.rings.number_field + sage: Q, R = A._gram_schmidt_noscale() + sage: Q [ 1 25/33*a - 38/11 641/1163*a + 453/1163] [ a 17/11*a + 73/33 322/1163*a + 1566/1163] [ a + 1 10/33*a - 173/33 -784/1163*a + 1614/1163] [ 2*a 1/11*a + 80/33 196/1163*a - 1234/1163] [ 1 25/33*a - 16/11 855/1163*a - 1717/1163] - sage: R # optional - sage.rings.number_field + sage: R [ 1 8/33*a + 5/11 8/33*a + 16/11 2/11*a + 1/33] [ 0 1 1 -107/1163*a - 78/1163] [ 0 0 0 1] - sage: Q*R == A # optional - sage.rings.number_field + sage: Q*R == A True - sage: Q.transpose().conjugate()*Q # optional - sage.rings.number_field + sage: Q.transpose().conjugate()*Q [ 33 0 0] [ 0 2326/33 0] [ 0 0 16532/1163] - sage: Q.column_space() == A.column_space() # optional - sage.rings.number_field + sage: Q.column_space() == A.column_space() True Some trivial cases. :: @@ -10751,6 +10807,7 @@ cdef class Matrix(Matrix1): for small cases or instruction. Now we need to use the ``orthonormal`` keyword. :: + sage: # needs sage.rings.number_field sage: A = matrix(QQbar, [[6, -8, 1], ....: [4, 1, 3], ....: [6, 3, 3], @@ -10767,13 +10824,13 @@ cdef class Matrix(Matrix1): [ 1.492555785314984? 7.006153332071100? 1.638930357041381?] [ 2.885607851608969? 1.804330147889395? 7.963520581008761?] [ 7.064764050490923? 5.626248468100069? -1.197679876299471?] - sage: M*G-A + sage: M*G - A [0 0 0] [0 0 0] [0 0 0] [0 0 0] [0 0 0] - sage: (G*G.transpose()-identity_matrix(3)).norm() < 10^-10 + sage: (G*G.transpose() - identity_matrix(3)).norm() < 10^-10 True sage: G.row_space() == A.row_space() True @@ -10781,6 +10838,7 @@ cdef class Matrix(Matrix1): After :trac:`14047`, the matrix can also be over the algebraic reals ``AA``:: + sage: # needs sage.rings.number_field sage: A = matrix(AA, [[6, -8, 1], ....: [4, 1, 3], ....: [6, 3, 3], @@ -10802,22 +10860,24 @@ cdef class Matrix(Matrix1): Note the use of the conjugate-transpose when checking the orthonormality. :: + sage: # needs sage.rings.number_field sage: A = matrix(QQbar, [[ -2, -I - 1, 4*I + 2, -1], ....: [-4*I, -2*I + 17, 0, 9*I + 1], ....: [ 1, -2*I - 6, -I + 11, -5*I + 1]]) sage: G, M = A.gram_schmidt(orthonormal=True) - sage: (M*G-A).norm() < 10^-10 + sage: (M*G - A).norm() < 10^-10 True sage: id3 = G*G.conjugate().transpose() sage: (id3 - identity_matrix(3)).norm() < 10^-10 True - sage: G.row_space() == A.row_space() # long time + sage: G.row_space() == A.row_space() # long time True A square matrix with small rank. The zero vectors produced as a result of linear dependence get eliminated, so the rows of ``G`` are a basis for the row space of ``A``. :: + sage: # needs sage.rings.number_field sage: A = matrix(QQbar, [[2, -6, 3, 8], ....: [1, -3, 2, 5], ....: [0, 0, 2, 4], @@ -10833,12 +10893,12 @@ cdef class Matrix(Matrix1): [ 6.208757731331742? 0.6718090752798139?] [ 3.574739299857670? 2.687236301119256?] [10.630145812734649? 0] - sage: M*G-A + sage: M*G - A [0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0] - sage: (G*G.transpose()-identity_matrix(2)).norm() < 10^-10 + sage: (G*G.transpose() - identity_matrix(2)).norm() < 10^-10 True sage: G.row_space() == A.row_space() True @@ -10884,13 +10944,14 @@ cdef class Matrix(Matrix1): A complex subfield of the complex numbers. :: - sage: C. = CyclotomicField(5) # optional - sage.rings.number_field - sage: A = matrix(C, # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: C. = CyclotomicField(5) + sage: A = matrix(C, ....: [[ -z^3 - 2*z, -z^3 - 1, 2*z^3 - 2*z^2 + 2*z, 1], ....: [ z^3 - 2*z^2 + 1, -z^3 + 2*z^2 - z - 1, -1, z^2 + z], ....: [-1/2*z^3 - 2*z^2 + z + 1, -z^3 + z - 2, -2*z^3 + 1/2*z^2, 2*z^2 - z + 2]]) - sage: G, M = A.gram_schmidt(orthonormal=False) # optional - sage.rings.number_field - sage: G # optional - sage.rings.number_field + sage: G, M = A.gram_schmidt(orthonormal=False) + sage: G [ -z^3 - 2*z -z^3 - 1 2*z^3 - 2*z^2 + 2*z 1] [ 155/139*z^3 - 161/139*z^2 + 31/139*z + 13/139 -175/139*z^3 + 180/139*z^2 - 125/139*z - 142/139 230/139*z^3 + 124/139*z^2 + 6/139*z + 19/139 -14/139*z^3 + 92/139*z^2 - 6/139*z - 95/139] [-10359/19841*z^3 - 36739/39682*z^2 + 24961/39682*z - 11879/39682 -28209/39682*z^3 - 3671/19841*z^2 + 51549/39682*z - 38613/39682 -42769/39682*z^3 - 615/39682*z^2 - 1252/19841*z - 14392/19841 4895/19841*z^3 + 57885/39682*z^2 - 46094/19841*z + 65747/39682] @@ -11016,27 +11077,27 @@ cdef class Matrix(Matrix1): [ 0 1 0 0] [ 1 -1 1 0] [ 1 -1 1 2] - sage: a.jordan_form() # optional - sage.combinat + sage: a.jordan_form() # needs sage.combinat [2|0 0|0] [-+---+-] [0|1 1|0] [0|0 1|0] [-+---+-] [0|0 0|1] - sage: a.jordan_form(subdivide=False) # optional - sage.combinat + sage: a.jordan_form(subdivide=False) # needs sage.combinat [2 0 0 0] [0 1 1 0] [0 0 1 0] [0 0 0 1] - sage: b = matrix(ZZ,3,3,range(9)); b # optional - sage.combinat + sage: b = matrix(ZZ,3,3,range(9)); b [0 1 2] [3 4 5] [6 7 8] - sage: b.jordan_form() # optional - sage.combinat + sage: b.jordan_form() # needs sage.combinat Traceback (most recent call last): ... RuntimeError: Some eigenvalue does not exist in Rational Field. - sage: b.jordan_form(RealField(15)) # optional - sage.combinat + sage: b.jordan_form(RealField(15)) # needs sage.combinat Traceback (most recent call last): ... ValueError: Jordan normal form not implemented over inexact rings. @@ -11045,7 +11106,7 @@ cdef class Matrix(Matrix1): in the smallest ring containing the matrix entries (:trac:`14508`):: sage: c = matrix([[0,1,0], [0,0,1], [1,0,0]]) - sage: c.jordan_form(CyclotomicField(3)) # optional - sage.combinat sage.rings.number_field + sage: c.jordan_form(CyclotomicField(3)) # needs sage.combinat sage.rings.number_field [ 1| 0| 0] [----------+----------+----------] [ 0| zeta3| 0] @@ -11060,15 +11121,15 @@ cdef class Matrix(Matrix1): [ 0 1 -1 -1] [-1 -1 3 0] [ 1 1 -1 2] - sage: jf, p = m.jordan_form(transformation=True) # optional - sage.combinat - sage: jf # optional - sage.combinat + sage: jf, p = m.jordan_form(transformation=True) # needs sage.combinat + sage: jf # needs sage.combinat [2|0|0 0] [-+-+---] [0|1|0 0] [-+-+---] [0|0|4 1] [0|0|0 4] - sage: ~p * m * p # optional - sage.combinat + sage: ~p * m * p # needs sage.combinat [2 0 0 0] [0 1 0 0] [0 0 4 1] @@ -11079,7 +11140,7 @@ cdef class Matrix(Matrix1): stable:: sage: b = matrix(ZZ, 3, 3, range(9)) - sage: jf, p = b.jordan_form(RealField(15), transformation=True) # optional - sage.combinat + sage: jf, p = b.jordan_form(RealField(15), transformation=True) # needs sage.combinat Traceback (most recent call last): ... ValueError: Jordan normal form not implemented over inexact rings. @@ -11090,7 +11151,7 @@ cdef class Matrix(Matrix1): [1 1 1] [1 1 1] [1 1 1] - sage: c.jordan_form(subdivide=False) # optional - sage.combinat + sage: c.jordan_form(subdivide=False) # needs sage.combinat [3 0 0] [0 0 0] [0 0 0] @@ -11103,12 +11164,12 @@ cdef class Matrix(Matrix1): sage: p = random_matrix(ZZ,n,n) sage: while p.rank() != n: p = random_matrix(ZZ,n,n) sage: m = p * jf * ~p - sage: mjf, mp = m.jordan_form(transformation=True) # optional - sage.combinat - sage: mjf == jf # optional - sage.combinat + sage: mjf, mp = m.jordan_form(transformation=True) # needs sage.combinat + sage: mjf == jf # needs sage.combinat True sage: m = diagonal_matrix([1,1,0,0]) - sage: jf, P = m.jordan_form(transformation=True) # optional - sage.combinat - sage: jf == ~P*m*P # optional - sage.combinat + sage: jf, P = m.jordan_form(transformation=True) # needs sage.combinat + sage: jf == ~P*m*P # needs sage.combinat True We verify that the bug from :trac:`6942` is fixed:: @@ -11116,8 +11177,8 @@ cdef class Matrix(Matrix1): sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1], [1,0,0,1,1,1,0], [1,1,0,1,1,1,1], ....: [1,1,1,0,1,1,1], [1,1,1,0,0,1,0], [1,1,1,0,1,0,0], ....: [1,1,1,1,1,1,0]]) - sage: J, T = M.jordan_form(transformation=True) # optional - sage.combinat sage.libs.pari - sage: J # optional - sage.combinat sage.libs.pari + sage: J, T = M.jordan_form(transformation=True) # needs sage.combinat sage.rings.finite_rings + sage: J # needs sage.combinat sage.rings.finite_rings [1 1|0 0|0 0|0] [0 1|0 0|0 0|0] [---+---+---+-] @@ -11128,17 +11189,17 @@ cdef class Matrix(Matrix1): [0 0|0 0|0 1|0] [---+---+---+-] [0 0|0 0|0 0|1] - sage: M * T == T * J # optional - sage.combinat sage.libs.pari + sage: M * T == T * J # needs sage.combinat sage.rings.finite_rings True - sage: T.rank() # optional - sage.combinat sage.libs.pari + sage: T.rank() # needs sage.combinat sage.rings.finite_rings 7 - sage: M.rank() # optional - sage.combinat + sage: M.rank() 7 We verify that the bug from :trac:`6932` is fixed:: - sage: M = Matrix(1, 1, [1]) # optional - sage.combinat - sage: M.jordan_form(transformation=True) # optional - sage.combinat + sage: M = Matrix(1, 1, [1]) + sage: M.jordan_form(transformation=True) # needs sage.combinat ([1], [1]) We now go through three `10 \times 10` matrices to exhibit cases where @@ -11155,7 +11216,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -66 -199/3 -42 -41/3 0 13/3 -55/3 -2/3] [ 18 57 -9 -54 -57 0 0 0 -15 0] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat + sage: J, T = A.jordan_form(transformation=True); J # needs sage.combinat [3 1 0|0 0 0|0 0 0|0] [0 3 1|0 0 0|0 0 0|0] [0 0 3|0 0 0|0 0 0|0] @@ -11169,9 +11230,9 @@ cdef class Matrix(Matrix1): [0 0 0|0 0 0|0 0 3|0] [-----+-----+-----+-] [0 0 0|0 0 0|0 0 0|3] - sage: T * J * T**(-1) == A # optional - sage.combinat + sage: T * J * T**(-1) == A # needs sage.combinat True - sage: T.rank() # optional - sage.combinat + sage: T.rank() # needs sage.combinat 10 :: @@ -11187,7 +11248,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -66 -28/3 -42 -41/3 0 13/3 2/3 82/3] [ 18 57 -9 0 -57 0 0 0 3 28] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat + sage: J, T = A.jordan_form(transformation=True); J # needs sage.combinat [3 1 0|0 0 0|0 0|0 0] [0 3 1|0 0 0|0 0|0 0] [0 0 3|0 0 0|0 0|0 0] @@ -11201,9 +11262,9 @@ cdef class Matrix(Matrix1): [-----+-----+---+---] [0 0 0|0 0 0|0 0|3 1] [0 0 0|0 0 0|0 0|0 3] - sage: T * J * T**(-1) == A # optional - sage.combinat + sage: T * J * T**(-1) == A # needs sage.combinat True - sage: T.rank() # optional - sage.combinat + sage: T.rank() # needs sage.combinat 10 :: @@ -11219,7 +11280,7 @@ cdef class Matrix(Matrix1): [ 20 26/3 -30 -199/3 -42 -14/3 70 13/3 -55/3 -2/3] [ 18 57 -9 -54 -57 0 63 0 -15 0] [ 0 0 0 0 0 0 0 0 0 3] - sage: J, T = A.jordan_form(transformation=True); J # optional - sage.combinat + sage: J, T = A.jordan_form(transformation=True); J # needs sage.combinat [3 1 0|0 0|0 0|0 0|0] [0 3 1|0 0|0 0|0 0|0] [0 0 3|0 0|0 0|0 0|0] @@ -11234,17 +11295,17 @@ cdef class Matrix(Matrix1): [0 0 0|0 0|0 0|0 3|0] [-----+---+---+---+-] [0 0 0|0 0|0 0|0 0|3] - sage: T * J * T**(-1) == A # optional - sage.combinat + sage: T * J * T**(-1) == A # needs sage.combinat True - sage: T.rank() # optional - sage.combinat + sage: T.rank() # needs sage.combinat 10 Verify that we smoothly move to QQ from ZZ (:trac:`12693`), i.e. we work in the vector space over the field:: sage: M = matrix(((2,2,2), (0,0,0), (-2,-2,-2))) - sage: J, P = M.jordan_form(transformation=True) # optional - sage.combinat - sage: J; P # optional - sage.combinat + sage: J, P = M.jordan_form(transformation=True) # needs sage.combinat + sage: J; P # needs sage.combinat [0 1|0] [0 0|0] [---+-] @@ -11252,15 +11313,15 @@ cdef class Matrix(Matrix1): [ 2 1 0] [ 0 0 1] [-2 0 -1] - sage: J - ~P * M * P # optional - sage.combinat + sage: J - ~P * M * P # needs sage.combinat [0 0 0] [0 0 0] [0 0 0] - sage: parent(M) # optional - sage.combinat + sage: parent(M) Full MatrixSpace of 3 by 3 dense matrices over Integer Ring - sage: parent(J) == parent(P) == MatrixSpace(QQ, 3) # optional - sage.combinat + sage: parent(J) == parent(P) == MatrixSpace(QQ, 3) # needs sage.combinat True - sage: M.jordan_form(transformation=True) == (M/1).jordan_form(transformation=True) # optional - sage.combinat + sage: M.jordan_form(transformation=True) == (M/1).jordan_form(transformation=True) # needs sage.combinat True By providing eigenvalues ourselves, we can compute the Jordan form even @@ -11269,16 +11330,16 @@ cdef class Matrix(Matrix1): sage: Qx = PolynomialRing(QQ, 'x11, x12, x13, x21, x22, x23, x31, x32, x33') sage: x11, x12, x13, x21, x22, x23, x31, x32, x33 = Qx.gens() sage: M = matrix(Qx, [[0, 0, x31], [0, 0, x21], [0, 0, 0]]) # This is a nilpotent matrix. - sage: M.jordan_form(eigenvalues=[(0, 3)]) # optional - sage.combinat + sage: M.jordan_form(eigenvalues=[(0, 3)]) # needs sage.combinat [0 1|0] [0 0|0] [---+-] [0 0|0] - sage: M.jordan_form(eigenvalues=[(0, 2)]) # optional - sage.combinat + sage: M.jordan_form(eigenvalues=[(0, 2)]) # needs sage.combinat Traceback (most recent call last): ... ValueError: The provided list of eigenvalues is not correct. - sage: M.jordan_form(transformation=True, eigenvalues=[(0, 3)]) # optional - sage.combinat + sage: M.jordan_form(transformation=True, eigenvalues=[(0, 3)]) # needs sage.combinat ( [0 1|0] [0 0|0] [x31 0 1] @@ -11290,7 +11351,7 @@ cdef class Matrix(Matrix1): and it needs to be implemented. :: sage: A = matrix(Integers(6), 2, 2, range(4)) - sage: A.jordan_form() # optional - sage.combinat + sage: A.jordan_form() # needs sage.combinat Traceback (most recent call last): ... ValueError: Matrix entries must be from a field, not Ring of integers modulo 6 @@ -11299,8 +11360,8 @@ cdef class Matrix(Matrix1): sage: R = FractionField(PolynomialRing(RationalField(), 'a')) sage: a = R.gen() - sage: A = matrix(R, [[1,a], [a,1]]) # optional - sage.combinat - sage: A.jordan_form() # optional - sage.combinat + sage: A = matrix(R, [[1,a], [a,1]]) + sage: A.jordan_form() # needs sage.combinat [ a + 1| 0] [------+------] [ 0|-a + 1] @@ -11473,26 +11534,26 @@ cdef class Matrix(Matrix1): [-3 5 3 3] [ 3 -6 -4 -3] [-3 6 3 2] - sage: A.is_diagonalizable() # optional - sage.libs.pari + sage: A.is_diagonalizable() # needs sage.libs.pari True - sage: A.diagonalization() # optional - sage.libs.pari + sage: A.diagonalization() # needs sage.libs.pari ( [ 2 0 0 0] [ 1 1 0 0] [ 0 -1 0 0] [ 1 0 1 0] [ 0 0 -1 0] [-1 0 0 1] [ 0 0 0 -1], [ 1 1 -2 -1] ) - sage: D, P = A.diagonalization() # optional - sage.libs.pari - sage: P^-1*A*P == D # optional - sage.libs.pari + sage: D, P = A.diagonalization() # needs sage.libs.pari + sage: P^-1*A*P == D # needs sage.libs.pari True sage: A = matrix(QQ, 2, [0, 2, 1, 0]) - sage: A.is_diagonalizable() # optional - sage.libs.pari + sage: A.is_diagonalizable() # needs sage.libs.pari False - sage: A.is_diagonalizable(QQbar) # optional - sage.libs.pari sage.rings.number_field + sage: A.is_diagonalizable(QQbar) # needs sage.libs.pari sage.rings.number_field True - sage: D, P = A.diagonalization(QQbar) # optional - sage.libs.pari sage.rings.number_field - sage: P^-1*A*P == D # optional - sage.libs.pari sage.rings.number_field + sage: D, P = A.diagonalization(QQbar) # needs sage.libs.pari sage.rings.number_field + sage: P^-1*A*P == D # needs sage.libs.pari sage.rings.number_field True Matrices may fail to be diagonalizable for various reasons:: @@ -11528,7 +11589,7 @@ cdef class Matrix(Matrix1): sage: D [0 2] [1 0] - sage: D.diagonalization() # optional - sage.libs.pari + sage: D.diagonalization() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: not diagonalizable over Rational Field @@ -11537,11 +11598,11 @@ cdef class Matrix(Matrix1): sage: E [3 1] [0 3] - sage: E.diagonalization() # optional - sage.libs.pari + sage: E.diagonalization() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: not diagonalizable - sage: E.jordan_form() # optional - sage.combinat + sage: E.jordan_form() # needs sage.combinat [3 1] [0 3] """ @@ -11624,9 +11685,9 @@ cdef class Matrix(Matrix1): ....: [ 9, -8, 11, -12, 51], ....: [ 3, -4, 0, -1, 9], ....: [-1, 0, -4, 4, -12]]) - sage: A.is_diagonalizable() # optional - sage.libs.pari + sage: A.is_diagonalizable() # needs sage.libs.pari True - sage: A.diagonalization() # optional - sage.libs.pari + sage: A.diagonalization() # needs sage.libs.pari ( [ 2 0 0 0 0] [ 1 1 0 1 0] [ 0 3 0 0 0] [ 1/2 0 1 0 1] @@ -11643,9 +11704,9 @@ cdef class Matrix(Matrix1): ....: [-2, -14, 0, 0, 10], ....: [3, 13, -2, 0, -11], ....: [-1, 6, 1, -3, 1]]) - sage: A.is_diagonalizable() # optional - sage.libs.pari + sage: A.is_diagonalizable() # needs sage.libs.pari False - sage: A.jordan_form(subdivide=False) # optional - sage.libs.pari + sage: A.jordan_form(subdivide=False) # needs sage.libs.pari [-1 1 0 0 0] [ 0 -1 0 0 0] [ 0 0 2 1 0] @@ -11662,46 +11723,48 @@ cdef class Matrix(Matrix1): ....: [2, -1, 1, 0, -2], ....: [0, -1, -1, -5, -8]]) - sage: [e in QQ for e in A.eigenvalues()] # optional - sage.rings.number_field + sage: [e in QQ for e in A.eigenvalues()] # needs sage.rings.number_field [False, False, False, False, False] - sage: A.is_diagonalizable() # optional - sage.libs.pari + sage: A.is_diagonalizable() # needs sage.libs.pari False - sage: A.diagonalization() # optional - sage.libs.pari + sage: A.diagonalization() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: not diagonalizable over Rational Field - sage: [e in QQbar for e in A.eigenvalues()] # optional - sage.rings.number_field + sage: [e in QQbar for e in A.eigenvalues()] # needs sage.rings.number_field [True, True, True, True, True] - sage: A.is_diagonalizable(base_field=QQbar) # optional - sage.rings.number_field + sage: A.is_diagonalizable(base_field=QQbar) # needs sage.rings.number_field True Other exact fields may be employed, though it will not always be possible to extend their base fields to contain all the eigenvalues. :: - sage: F. = FiniteField(5^2) # optional - sage.libs.pari - sage: A = matrix(F, [[ 4, 3*b + 2, 3*b + 1, 3*b + 4], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(5^2) + sage: A = matrix(F, [[ 4, 3*b + 2, 3*b + 1, 3*b + 4], ....: [2*b + 1, 4*b, 0, 2], ....: [ 4*b, b + 2, 2*b + 3, 3], ....: [ 2*b, 3*b, 4*b + 4, 3*b + 3]]) - sage: A.is_diagonalizable() # optional - sage.libs.pari + sage: A.is_diagonalizable() False - sage: A.jordan_form() # optional - sage.libs.pari + sage: A.jordan_form() [ 4 1| 0 0] [ 0 4| 0 0] [---------------+---------------] [ 0 0|2*b + 1 1] [ 0 0| 0 2*b + 1] - sage: F. = QuadraticField(-7) # optional - sage.rings.number_field - sage: A = matrix(F, [[ c + 3, 2*c - 2, -2*c + 2, c - 1], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: F. = QuadraticField(-7) + sage: A = matrix(F, [[ c + 3, 2*c - 2, -2*c + 2, c - 1], ....: [2*c + 10, 13*c + 15, -13*c - 17, 11*c + 31], ....: [2*c + 10, 14*c + 10, -14*c - 12, 12*c + 30], ....: [ 0, 2*c - 2, -2*c + 2, 2*c + 2]]) - sage: A.is_diagonalizable() # optional - sage.rings.number_field + sage: A.is_diagonalizable() True - sage: A.diagonalization() # optional - sage.rings.number_field + sage: A.diagonalization() ( [ 4 0 0 0] [ 1 0 1 0] [ 0 -2 0 0] [ 4 1 0 1] @@ -11712,7 +11775,7 @@ cdef class Matrix(Matrix1): A trivial matrix is diagonalizable, trivially. :: sage: A = matrix(QQ, 0, 0) - sage: A.is_diagonalizable() # optional - sage.libs.pari + sage: A.is_diagonalizable() # needs sage.libs.pari True A matrix must be square to be diagonalizable. :: @@ -11863,39 +11926,39 @@ cdef class Matrix(Matrix1): sage: B = matrix(ZZ, [[ 1, 12, 3], ....: [-1, -6, -1], ....: [ 0, 6, 1]]) - sage: A.is_similar(B) # optional - sage.libs.pari + sage: A.is_similar(B) True - sage: _, T = A.is_similar(B, transformation=True) # optional - sage.libs.pari - sage: T # optional - sage.libs.pari + sage: _, T = A.is_similar(B, transformation=True) # needs sage.libs.pari + sage: T # needs sage.libs.pari [ 1.00000000000000? + 0.?e-14*I 0.?e-14 + 0.?e-14*I 0.?e-14 + 0.?e-14*I] [-0.66666666666667? + 0.?e-15*I 0.166666666666667? + 0.?e-15*I -0.83333333333334? + 0.?e-14*I] [ 0.66666666666667? + 0.?e-14*I 0.?e-14 + 0.?e-14*I -0.33333333333333? + 0.?e-14*I] - sage: T.change_ring(QQ) # optional - sage.libs.pari + sage: T.change_ring(QQ) # needs sage.libs.pari [ 1 0 0] [-2/3 1/6 -5/6] [ 2/3 0 -1/3] - sage: A == T.inverse()*B*T # optional - sage.libs.pari + sage: A == T.inverse()*B*T # needs sage.libs.pari True Other exact fields are supported. :: - sage: F. = FiniteField(7^2) # optional - sage.rings.finite_rings - sage: A = matrix(F, [[2*a + 5, 6*a + 6, a + 3], # optional - sage.rings.finite_rings + sage: F. = FiniteField(7^2) # needs sage.rings.finite_rings + sage: A = matrix(F, [[2*a + 5, 6*a + 6, a + 3], # needs sage.rings.finite_rings ....: [ a + 3, 2*a + 2, 4*a + 2], ....: [2*a + 6, 5*a + 5, 3*a]]) - sage: B = matrix(F, [[5*a + 5, 6*a + 4, a + 1], # optional - sage.rings.finite_rings + sage: B = matrix(F, [[5*a + 5, 6*a + 4, a + 1], # needs sage.rings.finite_rings ....: [ a + 5, 4*a + 3, 3*a + 3], ....: [3*a + 5, a + 4, 5*a + 6]]) sage: A.is_similar(B) True sage: B.is_similar(A) True - sage: _, T = A.is_similar(B, transformation=True) # optional - sage.libs.pari - sage: T # optional - sage.libs.pari + sage: _, T = A.is_similar(B, transformation=True) # needs sage.rings.finite_rings + sage: T # needs sage.rings.finite_rings [ 1 0 0] [6*a + 1 4*a + 3 4*a + 2] [6*a + 3 3*a + 5 3*a + 6] - sage: A == T.inverse()*B*T # optional - sage.libs.pari + sage: A == T.inverse() * B * T # needs sage.rings.finite_rings True Two matrices with different sets of eigenvalues, so they @@ -11909,9 +11972,9 @@ cdef class Matrix(Matrix1): ....: [-1, 2, -3, -7], ....: [-2, 3, -4, -7], ....: [ 0, -1, 0, 0]]) - sage: A.eigenvalues() == B.eigenvalues() # optional - sage.rings.number_field + sage: A.eigenvalues() == B.eigenvalues() # needs sage.rings.number_field False - sage: A.is_similar(B, transformation=True) # optional - sage.libs.pari + sage: A.is_similar(B, transformation=True) (False, None) Similarity is an equivalence relation, so this routine computes @@ -11927,7 +11990,7 @@ cdef class Matrix(Matrix1): sage: B = matrix(QQ, [[-38, -63, 42], ....: [ 14, 25, -14], ....: [-14, -21, 18]]) - sage: A.charpoly() == B.charpoly() # optional - sage.libs.pari + sage: A.charpoly() == B.charpoly() # needs sage.libs.pari True sage: A.rational_form() [ 0 0 -48] @@ -11954,19 +12017,20 @@ cdef class Matrix(Matrix1): design, but we are not able to resurrect a similarity transformation. :: - sage: F. = FiniteField(7^2) # optional - sage.libs.pari - sage: C = matrix(F, [[ a + 2, 5*a + 4], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(7^2) + sage: C = matrix(F, [[ a + 2, 5*a + 4], ....: [6*a + 6, 6*a + 4]]) - sage: S = matrix(F, [[0, 1], # optional - sage.libs.pari + sage: S = matrix(F, [[0, 1], ....: [1, 0]]) - sage: D = S.inverse()*C*S # optional - sage.libs.pari - sage: C.is_similar(D) # optional - sage.libs.pari + sage: D = S.inverse()*C*S + sage: C.is_similar(D) True - sage: C.is_similar(D, transformation=True) # optional - sage.libs.pari + sage: C.is_similar(D, transformation=True) Traceback (most recent call last): ... RuntimeError: unable to compute transformation for similar matrices - sage: C.jordan_form() # optional - sage.libs.pari + sage: C.jordan_form() Traceback (most recent call last): ... RuntimeError: Some eigenvalue does not exist in @@ -11976,9 +12040,9 @@ cdef class Matrix(Matrix1): algebraic closure of this field to find the change-of-basis matrix:: - sage: cox = posets.TamariLattice(3).coxeter_transformation() # optional - sage.graphs sage.combinat sage.libs.pari - sage: M = cox.change_ring(GF(3)) # optional - sage.graphs sage.combinat sage.libs.pari - sage: M.is_similar(M**3, True) # long time # optional - sage.graphs sage.combinat sage.libs.pari + sage: cox = posets.TamariLattice(3).coxeter_transformation() # needs sage.combinat sage.graphs sage.rings.finite_rings + sage: M = cox.change_ring(GF(3)) # needs sage.combinat sage.graphs sage.rings.finite_rings + sage: M.is_similar(M**3, True) # long time # needs sage.combinat sage.graphs sage.rings.finite_rings ( [1 0 0 0 0] [0 1 1 0 2] @@ -12013,7 +12077,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(GF(3), 2, 2, range(4)) sage: B = matrix(GF(2), 2, 2, range(4)) - sage: A.is_similar(B, transformation=True) # optional - sage.rings.finite_rings + sage: A.is_similar(B, transformation=True) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -12027,8 +12091,8 @@ cdef class Matrix(Matrix1): of ``QQ`` in ``QQbar``). :: sage: A = matrix(ZZ, 2, 2, range(4)) - sage: B = matrix(QQbar, 2, 2, range(4)) # optional - sage.rings.number_field - sage: A.is_similar(B) # optional - sage.rings.number_field + sage: B = matrix(QQbar, 2, 2, range(4)) # needs sage.rings.number_field + sage: A.is_similar(B) # needs sage.rings.number_field True TESTS: @@ -12437,7 +12501,7 @@ cdef class Matrix(Matrix1): ... TypeError: first input should be a vector, not junk - sage: A.cyclic_subspace(v, var=sin(x)) # optional - sage.symbolic + sage: A.cyclic_subspace(v, var=sin(x)) # needs sage.symbolic Traceback (most recent call last): ... TypeError: polynomial variable must be a string or polynomial ring generator, not sin(x) @@ -12477,10 +12541,10 @@ cdef class Matrix(Matrix1): ... TypeError: matrix entries must be from an exact field, not Ring of integers modulo 6 - sage: F. = GF(2^4) # optional - sage.rings.finite_rings + sage: F. = GF(2^4) # needs sage.rings.finite_rings sage: G = matrix(QQ, 4, range(16)) - sage: w = vector(F, 4, [1, a, a^2, a^3]) # optional - sage.rings.finite_rings - sage: G.cyclic_subspace(w) # optional - sage.rings.finite_rings + sage: w = vector(F, 4, [1, a, a^2, a^3]) # needs sage.rings.finite_rings + sage: G.cyclic_subspace(w) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to make vector entries compatible with matrix entries @@ -12623,53 +12687,55 @@ cdef class Matrix(Matrix1): ....: [ -2, -18, -38, 15]]) sage: A.is_symmetric() True - sage: L = A.cholesky(); L # optional - sage.rings.number_field + sage: L = A.cholesky(); L # needs sage.rings.number_field [ 8.83176086632785? 0 0 0] [ -3.396831102433787? 9.51112708681461? 0 0] [ -4.189425026335004? 17.32383862241232? 2.886751345948129? 0] [-0.2264554068289192? -1.973397116652010? -1.649572197684645? 2.886751345948129?] - sage: L.parent() # optional - sage.rings.number_field + sage: L.parent() # needs sage.rings.number_field Full MatrixSpace of 4 by 4 dense matrices over Algebraic Real Field - sage: L*L.transpose() == A # optional - sage.rings.number_field + sage: L*L.transpose() == A # needs sage.rings.number_field True Some subfields of the complex numbers, such as this number field of complex numbers with rational real and imaginary parts, allow for this computation:: - sage: C. = QuadraticField(-1) # optional - sage.rings.number_field - sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: C. = QuadraticField(-1) + sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], ....: [ -17*I + 3, 38, -69*I + 89, 7*I + 15], ....: [-24*I + 25, 69*I + 89, 976, 24*I + 6], ....: [ -21*I, -7*I + 15, -24*I + 6, 28]]) - sage: A.is_hermitian() # optional - sage.rings.number_field + sage: A.is_hermitian() True - sage: L = A.cholesky(); L # optional - sage.rings.number_field + sage: L = A.cholesky(); L [ 4.79...? 0 0 0] [ 0.62...? - 3.54...?*I 5.00...? 0 0] [ 5.21...? - 5.00...?*I 13.58...? + 10.72...?*I 24.98...? 0] [ -4.37...?*I -0.10...? - 0.85...?*I -0.21...? + 0.37...?*I 2.81...?] - sage: L.parent() # optional - sage.rings.number_field + sage: L.parent() Full MatrixSpace of 4 by 4 dense matrices over Algebraic Field - sage: (L*L.conjugate_transpose() - A.change_ring(QQbar)).norm() < 10^-10 # optional - sage.rings.number_field + sage: (L*L.conjugate_transpose() - A.change_ring(QQbar)).norm() < 10^-10 True The field of algebraic numbers is an ideal setting for this computation:: - sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], ....: [ -2*I + 4, 11, 10 - 12*I], ....: [ 4*I + 6, 10 + 12*I, 37]]) - sage: A.is_hermitian() # optional - sage.rings.number_field + sage: A.is_hermitian() True - sage: L = A.cholesky() # optional - sage.rings.number_field - sage: L # optional - sage.rings.number_field + sage: L = A.cholesky() + sage: L [ 1.414213562373095? 0 0] [2.828427124746190? - 1.414213562373095?*I 1 0] [4.242640687119285? + 2.828427124746190?*I -2*I + 2 1.732050807568878?] - sage: L.parent() # optional - sage.rings.number_field + sage: L.parent() Full MatrixSpace of 3 by 3 dense matrices over Algebraic Field - sage: L*L.conjugate_transpose() == A # optional - sage.rings.number_field + sage: L*L.conjugate_transpose() == A True Results are cached, hence immutable. Use the ``copy`` function @@ -12705,8 +12771,8 @@ cdef class Matrix(Matrix1): Even symbolic matrices can sometimes be factored:: - sage: A = matrix(SR, [[pi,0], [0,pi]]) # optional - sage.symbolic - sage: A.cholesky() # optional - sage.symbolic + sage: A = matrix(SR, [[pi,0], [0,pi]]) # needs sage.symbolic + sage: A.cholesky() # needs sage.symbolic [sqrt(pi) 0] [ 0 sqrt(pi)] @@ -12725,22 +12791,23 @@ cdef class Matrix(Matrix1): The matrix may not be Hermitian:: - sage: F. = FiniteField(5^4) # optional - sage.libs.pari - sage: A = matrix(F, [[2+a^3, 3], [3, 3]]) # optional - sage.libs.pari - sage: A.cholesky() # optional - sage.libs.pari + sage: F. = FiniteField(5^4) # needs sage.rings.finite_rings + sage: A = matrix(F, [[2+a^3, 3], [3, 3]]) # needs sage.rings.finite_rings + sage: A.cholesky() # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix is not Hermitian The matrix may not be positive-definite:: - sage: C. = QuadraticField(-1) # optional - sage.rings.number_field - sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: C. = QuadraticField(-1) + sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: B.is_positive_definite() # optional - sage.rings.number_field + sage: B.is_positive_definite() False - sage: B.cholesky() # optional - sage.rings.number_field + sage: B.cholesky() Traceback (most recent call last): ... ValueError: matrix is not positive definite @@ -12765,11 +12832,11 @@ cdef class Matrix(Matrix1): sage: E = matrix(QQ, [[2, 1], [1, 1]]) sage: E.is_symmetric() True - sage: E.eigenvalues() + sage: E.eigenvalues() # needs sage.rings.number_field [0.38...?, 2.61...?] sage: E.det() 1 - sage: E.cholesky() + sage: E.cholesky() # needs sage.rings.number_field [ 1.414213562373095? 0] [0.7071067811865475? 0.7071067811865475?] @@ -12781,7 +12848,7 @@ cdef class Matrix(Matrix1): Rational Field sage: E = matrix(QQ, [[2, 1], [1, 1]]) - sage: E.cholesky().base_ring() + sage: E.cholesky().base_ring() # needs sage.rings.number_field Algebraic Real Field Check that sparse floating-point matrices can be factored @@ -12791,17 +12858,17 @@ cdef class Matrix(Matrix1): sage: A.cholesky() [1.0 0.0] [1.0 1.0] - sage: A = matrix(CDF, [[1, I], [-I, 2]], sparse=True) + sage: A = matrix(CDF, [[1, I], [-I, 2]], sparse=True) # needs sage.rings.number_field sage: A.cholesky() [ 1.0 0.0] [-1.0*I 1.0] Try the trivial case (:trac:`33107`):: - sage: all( matrix(R,[]).cholesky() == matrix(R,[]) + sage: all( matrix(R,[]).cholesky() == matrix(R,[]) # needs sage.rings.number_field ....: for R in (RR,CC,RDF,CDF,ZZ,QQ,AA,QQbar) ) True - sage: all( matrix(R,[]).cholesky().is_immutable() + sage: all( matrix(R,[]).cholesky().is_immutable() # needs sage.rings.number_field ....: for R in (RR,CC,RDF,CDF,ZZ,QQ,AA,QQbar) ) True @@ -12931,32 +12998,34 @@ cdef class Matrix(Matrix1): A matrix containing real roots:: - sage: A = matrix(AA, [ [1, 0, sqrt(2)], # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: A = matrix(AA, [ [1, 0, sqrt(2)], ....: [0, sqrt(3), 0 ], ....: [sqrt(2), 0, sqrt(5)] ]) - sage: A.is_positive_definite() # optional - sage.rings.number_field sage.symbolic + sage: A.is_positive_definite() True - sage: B = matrix(AA, [ [2*sqrt(5) + 5, 0, -sqrt(8*sqrt(5) + 18)], # optional - sage.rings.number_field sage.symbolic + sage: B = matrix(AA, [ [2*sqrt(5) + 5, 0, -sqrt(8*sqrt(5) + 18)], ....: [0, sqrt(1/3), 0], ....: [-sqrt(8*sqrt(5) + 18), 0, sqrt(5) + 2] ]) - sage: A.inverse_positive_definite() == B # optional - sage.rings.number_field sage.symbolic + sage: A.inverse_positive_definite() == B True - sage: A*B == A.matrix_space().identity_matrix() # optional - sage.rings.number_field sage.symbolic + sage: A*B == A.matrix_space().identity_matrix() True A Hermitian (but not symmetric) matrix with complex entries:: - sage: A = matrix(QQbar, [ [ 1, 0, I ], # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: A = matrix(QQbar, [ [ 1, 0, I ], ....: [ 0, sqrt(5), 0 ], ....: [-I, 0, 3 ] ]) - sage: A.is_positive_definite() # optional - sage.rings.number_field sage.symbolic + sage: A.is_positive_definite() True - sage: B = matrix(QQbar, [ [ 3/2, 0, -I/2 ], # optional - sage.rings.number_field sage.symbolic + sage: B = matrix(QQbar, [ [ 3/2, 0, -I/2 ], ....: [ 0, sqrt(1/5), 0 ], ....: [ I/2, 0, 1/2 ] ]) - sage: A.inverse_positive_definite() == B # optional - sage.rings.number_field sage.symbolic + sage: A.inverse_positive_definite() == B True - sage: A*B == A.matrix_space().identity_matrix() # optional - sage.rings.number_field sage.symbolic + sage: A*B == A.matrix_space().identity_matrix() True TESTS: @@ -12986,11 +13055,11 @@ cdef class Matrix(Matrix1): sage: from sage.misc.prandom import choice sage: n = ZZ.random_element(2) - sage: ring = choice([AA, QQbar]) + sage: ring = choice([AA, QQbar]) # needs sage.rings.number_field sage: A = matrix.random(ring, n) sage: I = matrix.identity(ring, n) sage: A = A*A.conjugate_transpose() + I - sage: A.is_positive_definite() + sage: A.is_positive_definite() # needs sage.rings.number_field True sage: actual = A.inverse_positive_definite() sage: expected = A.inverse() @@ -13119,47 +13188,47 @@ cdef class Matrix(Matrix1): ....: [2, 0, 1, 4, 2, 6, 0], ....: [1, 0, -1, 8, -1, -1, -3], ....: [1, 1, 2, -2, -1, 1, 3]]) - sage: P, L, U = A.LU(pivot='partial') # optional - sage.combinat - sage: P # optional - sage.combinat + sage: P, L, U = A.LU(pivot='partial') + sage: P [0 0 0 0 1] [1 0 0 0 0] [0 0 0 1 0] [0 0 1 0 0] [0 1 0 0 0] - sage: L # optional - sage.combinat + sage: L [ 1 0 0 0 0] [ 1/2 1 0 0 0] [ 1/2 1/3 1 0 0] [ 1 2/3 1/5 1 0] [ 1/2 -1/3 -2/5 0 1] - sage: U # optional - sage.combinat + sage: U [ 2 -1 0 6 4 8 -2] [ 0 3/2 2 -5 -3 -3 4] [ 0 0 -5/3 20/3 -2 -4 -10/3] [ 0 0 0 0 2/5 4/5 0] [ 0 0 0 0 1/5 2/5 0] - sage: A == P*L*U # optional - sage.combinat + sage: A == P*L*U True - sage: P, L, U = A.LU(pivot='nonzero') # optional - sage.combinat - sage: P # optional - sage.combinat + sage: P, L, U = A.LU(pivot='nonzero') + sage: P [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: L # optional - sage.combinat + sage: L [ 1 0 0 0 0] [ 2 1 0 0 0] [ 2 2 1 0 0] [ 1 1 -1 1 0] [ 1 2 2 0 1] - sage: U # optional - sage.combinat + sage: U [ 1 -1 0 2 4 7 -1] [ 0 1 0 2 -4 -6 0] [ 0 0 1 -4 2 4 2] [ 0 0 0 0 1 2 0] [ 0 0 0 0 -1 -2 0] - sage: A == P*L*U # optional - sage.combinat + sage: A == P*L*U True An example of the compact format. :: @@ -13169,10 +13238,10 @@ cdef class Matrix(Matrix1): ....: [-1, -4, -6, -6], ....: [ 0, -2, -5, -8], ....: [-2, -6, -6, -2]]) - sage: perm, M = B.LU(format='compact') # optional - sage.combinat - sage: perm # optional - sage.combinat + sage: perm, M = B.LU(format='compact') + sage: perm (4, 3, 0, 1, 2) - sage: M # optional - sage.combinat + sage: M [ -2 -6 -6 -2] [ 0 -2 -5 -8] [-1/2 0 2 4] @@ -13186,13 +13255,13 @@ cdef class Matrix(Matrix1): ....: [ 1, -2, 1, 3], ....: [-4, 7, -3, -8], ....: [-3, 8, -1, -5]]) - sage: P, L, U = C.LU(format='plu') # optional - sage.combinat - sage: perm, M = C.LU(format='compact') # optional - sage.combinat - sage: (L - identity_matrix(4)) + U == M # optional - sage.combinat + sage: P, L, U = C.LU(format='plu') + sage: perm, M = C.LU(format='compact') + sage: (L - identity_matrix(4)) + U == M True - sage: p = [perm[i]+1 for i in range(len(perm))] # optional - sage.combinat - sage: PP = Permutation(p).to_matrix() # optional - sage.combinat - sage: PP == P # optional - sage.combinat + sage: p = [perm[i]+1 for i in range(len(perm))] + sage: PP = Permutation(p).to_matrix() + sage: PP == P True For a nonsingular matrix, and the 'nonzero' pivot @@ -13208,29 +13277,29 @@ cdef class Matrix(Matrix1): ....: [-2, 2, -3, 2, 1, 0], ....: [ 0, -1, -1, 0, 2, 5], ....: [-1, 2, -4, -1, 5, -3]]) - sage: P, L, U = D.LU(pivot='nonzero') # optional - sage.combinat - sage: P # optional - sage.combinat + sage: P, L, U = D.LU(pivot='nonzero') + sage: P [1 0 0 0 0 0] [0 1 0 0 0 0] [0 0 1 0 0 0] [0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] - sage: L # optional - sage.combinat + sage: L [ 1 0 0 0 0 0] [ 3 1 0 0 0 0] [ -4 -1 1 0 0 0] [ -2 -1 -1 1 0 0] [ 0 1/2 1/4 1/2 1 0] [ -1 -1 -5/2 -2 -6 1] - sage: U # optional - sage.combinat + sage: U [ 1 0 2 0 -2 -1] [ 0 -2 -3 -1 6 9] [ 0 0 2 0 -3 -3] [ 0 0 0 1 0 4] [ 0 0 0 0 -1/4 -3/4] [ 0 0 0 0 0 1] - sage: D == L*U # optional - sage.combinat + sage: D == L*U True The base ring of the matrix may be any field, or a ring @@ -13260,45 +13329,45 @@ cdef class Matrix(Matrix1): Traceback (most recent call last): ... TypeError: cannot take absolute value of matrix entries, try 'pivot=nonzero' - sage: P, L, U = B.LU(pivot='nonzero') # optional - sage.combinat - sage: P # optional - sage.combinat + sage: P, L, U = B.LU(pivot='nonzero') + sage: P [1 0] [0 1] - sage: L # optional - sage.combinat + sage: L [ 1 0] [y^2/(y + 1) 1] - sage: U # optional - sage.combinat + sage: U [ y + 1 y^2 + y] [ 0 0] - sage: L.base_ring() # optional - sage.combinat + sage: L.base_ring() Fraction Field of Univariate Polynomial Ring in y over Rational Field - sage: B == P*L*U # optional - sage.combinat + sage: B == P*L*U True - sage: F. = FiniteField(5^2) # optional - sage.libs.pari - sage: C = matrix(F, [[a + 3, 4*a + 4, 2, 4*a + 2], # optional - sage.libs.pari + sage: F. = FiniteField(5^2) # needs sage.rings.finite_rings + sage: C = matrix(F, [[a + 3, 4*a + 4, 2, 4*a + 2], # needs sage.rings.finite_rings ....: [3, 2*a + 4, 2*a + 4, 2*a + 1], ....: [3*a + 1, a + 3, 2*a + 4, 4*a + 3], ....: [a, 3, 3*a + 1, a]]) - sage: P, L, U = C.LU(pivot='nonzero') # optional - sage.combinat - sage: P # optional - sage.combinat + sage: P, L, U = C.LU(pivot='nonzero') + sage: P [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] - sage: L # optional - sage.combinat sage.libs.pari + sage: L # needs sage.combinat sage.rings.finite_rings [ 1 0 0 0] [3*a + 3 1 0 0] [ 2*a 4*a + 2 1 0] [2*a + 3 2 2*a + 4 1] - sage: U # optional - sage.combinat sage.libs.pari + sage: U # needs sage.combinat sage.rings.finite_rings [ a + 3 4*a + 4 2 4*a + 2] [ 0 a + 1 a + 3 2*a + 4] [ 0 0 1 4*a + 2] [ 0 0 0 0] - sage: L.base_ring() # optional - sage.combinat sage.libs.pari + sage: L.base_ring() # needs sage.combinat sage.rings.finite_rings Finite Field in a of size 5^2 - sage: C == P*L*U # optional - sage.combinat + sage: C == P*L*U True With no pivoting strategy given (i.e. ``pivot=None``) @@ -13310,10 +13379,10 @@ cdef class Matrix(Matrix1): sage: entries = [3, 20, 11, 7, 16, 28, 5, 15, 21, 23, 22, 18, 8, 23, 15, 2] sage: A = matrix(Integers(29), 4, 4, entries) - sage: perm, _ = A.LU(format='compact'); perm # optional - sage.combinat + sage: perm, _ = A.LU(format='compact'); perm (0, 1, 2, 3) sage: B = matrix(QQ, 4, 4, entries) - sage: perm, _ = B.LU(format='compact'); perm # optional - sage.combinat + sage: perm, _ = B.LU(format='compact'); perm (2, 0, 1, 3) The `U` matrix is only guaranteed to be upper-triangular. @@ -13325,8 +13394,8 @@ cdef class Matrix(Matrix1): ....: [ 0, 0, 1, -4, -1, -3, 6, -5, -6], ....: [-2, 8, -1, -4, 2, -4, 1, -8, -7], ....: [ 1, -4, 2, -4, -3, 2, 5, 6, 4]]) - sage: P, L, U = A.LU() # optional - sage.combinat - sage: U # optional - sage.combinat + sage: P, L, U = A.LU() + sage: U [ -2 8 -1 -4 2 -4 1 -8 -7] [ 0 0 1/2 -2 -1 -2 9/2 -3 -7/2] [ 0 0 3/2 -6 -2 0 11/2 2 1/2] @@ -13359,15 +13428,15 @@ cdef class Matrix(Matrix1): components of the 'plu' format are not. :: sage: A = matrix(ZZ, 2, range(4)) - sage: perm, M = A.LU(format='compact') # optional - sage.combinat - sage: perm[0] = 25 # optional - sage.combinat + sage: perm, M = A.LU(format='compact') + sage: perm[0] = 25 Traceback (most recent call last): ... TypeError: 'tuple' object does not support item assignment - sage: M.is_immutable() # optional - sage.combinat + sage: M.is_immutable() True - sage: P, L, U = A.LU(format='plu') # optional - sage.combinat - sage: all(A.is_mutable() for A in [P, L, U]) # optional - sage.combinat + sage: P, L, U = A.LU(format='plu') + sage: all(A.is_mutable() for A in [P, L, U]) True Partial pivoting is based on the absolute values of entries @@ -13375,18 +13444,19 @@ cdef class Matrix(Matrix1): absolute value must be handled carefully. This tests that situation in the case of cyclotomic fields. :: - sage: C = SymmetricGroup(5).character_table() # optional - sage.groups sage.rings.number_field - sage: C.base_ring() # optional - sage.groups sage.rings.number_field + sage: # needs sage.groups sage.rings.number_field + sage: C = SymmetricGroup(5).character_table() + sage: C.base_ring() Cyclotomic Field of order 1 and degree 1 - sage: P, L, U = C.LU(pivot='partial') # optional - sage.combinat sage.groups sage.rings.number_field - sage: C == P*L*U # optional - sage.combinat sage.groups sage.rings.number_field + sage: P, L, U = C.LU(pivot='partial') + sage: C == P*L*U True Check that :trac:`32736` is solved:: sage: M = Matrix(FiniteField(11), [[2,3],[4,5]]) - sage: P, L, U = M.LU() # optional - sage.combinat - sage: P.base_ring() # optional - sage.combinat + sage: P, L, U = M.LU() + sage: P.base_ring() Finite Field of size 11 """ if pivot not in [None, 'partial', 'nonzero']: @@ -13555,9 +13625,10 @@ cdef class Matrix(Matrix1): A Hermitian matrix. :: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ) - sage: C. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], # optional - sage.rings.number_field + sage: C. = NumberField(x^2 + 1) + sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], ....: [ -17*I + 3, 38, -69*I + 89, 7*I + 15], ....: [-24*I + 25, 69*I + 89, 976, 24*I + 6], ....: [ -21*I, -7*I + 15, -24*I + 6, 28]]) @@ -13636,7 +13707,7 @@ cdef class Matrix(Matrix1): ... ValueError: matrix is not symmetric (maybe try the 'hermitian' keyword) - sage: A = matrix([[3, 2+3*I], [5+6*I, 12]]) + sage: A = matrix([[3, 2+3*I], [5+6*I, 12]]) # needs sage.rings.number_field sage: A._indefinite_factorization('hermitian', check=True) Traceback (most recent call last): ... @@ -13838,23 +13909,24 @@ cdef class Matrix(Matrix1): with rational real and imaginary parts. As theory predicts, the diagonal entries will be real numbers. :: - sage: C. = QuadraticField(-1) # optional - sage.rings.number_field - sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: C. = QuadraticField(-1) + sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: B.is_hermitian() # optional - sage.rings.number_field + sage: B.is_hermitian() True - sage: L, d = B.indefinite_factorization(algorithm='hermitian') # optional - sage.rings.number_field - sage: D = diagonal_matrix(d) # optional - sage.rings.number_field - sage: L # optional - sage.rings.number_field + sage: L, d = B.indefinite_factorization(algorithm='hermitian') + sage: D = diagonal_matrix(d) + sage: L [ 1 0 0] [ I + 2 1 0] [ -I + 1 2*I + 1 1] - sage: D # optional - sage.rings.number_field + sage: D [ 2 0 0] [ 0 -2 0] [ 0 0 3] - sage: B == L*D*L.conjugate_transpose() # optional - sage.rings.number_field + sage: B == L*D*L.conjugate_transpose() True If a leading principal submatrix has zero determinant, this @@ -13880,27 +13952,27 @@ cdef class Matrix(Matrix1): may be factored. This provides a reasonable alternative to the Cholesky decomposition. :: - sage: F. = FiniteField(5^3) # optional - sage.libs.pari - sage: A = matrix(F, # optional - sage.libs.pari + sage: F. = FiniteField(5^3) # needs sage.rings.finite_rings + sage: A = matrix(F, # needs sage.rings.finite_rings ....: [[ a^2 + 2*a, 4*a^2 + 3*a + 4, 3*a^2 + a, 2*a^2 + 2*a + 1], ....: [4*a^2 + 3*a + 4, 4*a^2 + 2, 3*a, 2*a^2 + 4*a + 2], ....: [ 3*a^2 + a, 3*a, 3*a^2 + 2, 3*a^2 + 2*a + 3], ....: [2*a^2 + 2*a + 1, 2*a^2 + 4*a + 2, 3*a^2 + 2*a + 3, 3*a^2 + 2*a + 4]]) sage: A.is_symmetric() True - sage: L, d = A.indefinite_factorization() # optional - sage.rings.finite_rings + sage: L, d = A.indefinite_factorization() # needs sage.rings.finite_rings sage: D = diagonal_matrix(d) - sage: L # optional - sage.rings.finite_rings + sage: L # needs sage.rings.finite_rings [ 1 0 0 0] [4*a^2 + 4*a + 3 1 0 0] [ 3 4*a^2 + a + 2 1 0] [ 4*a^2 + 4 2*a^2 + 3*a + 3 2*a^2 + 3*a + 1 1] - sage: D # optional - sage.libs.pari + sage: D # needs sage.rings.finite_rings [ a^2 + 2*a 0 0 0] [ 0 2*a^2 + 2*a + 4 0 0] [ 0 0 3*a^2 + 4*a + 3 0] [ 0 0 0 a^2 + 3*a] - sage: A == L*D*L.transpose() # optional - sage.libs.pari + sage: A == L*D*L.transpose() # needs sage.rings.finite_rings True This works correctly for the 0x0 matrix:: @@ -14306,13 +14378,13 @@ cdef class Matrix(Matrix1): The same is true of the following complex Hermitian matrix:: - sage: A = matrix(QQbar, [ [ 0,I], + sage: A = matrix(QQbar, [ [ 0,I], # needs sage.rings.number_field ....: [-I,0] ]) sage: A.block_ldlt(classical=True) Traceback (most recent call last): ... ValueError: matrix has no classical LDL^T factorization - sage: A.block_ldlt() + sage: A.block_ldlt() # needs sage.rings.number_field ( [1 0] [1 0] [ 0 I] [0 1], [0 1], [-I 0] @@ -14400,11 +14472,11 @@ cdef class Matrix(Matrix1): An indefinite Hermitian matrix that happens to have a classical factorization:: - sage: F. = QuadraticField(-1) # optional - sage.rings.number_field - sage: A = matrix(F, [[ 2, 4 - 2*I, 2 + 2*I], # optional - sage.rings.number_field + sage: F. = QuadraticField(-1) # needs sage.rings.number_field + sage: A = matrix(F, [[ 2, 4 - 2*I, 2 + 2*I], # needs sage.rings.number_field ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) - sage: A.block_ldlt(classical=True)[1:] # optional - sage.rings.number_field + sage: A.block_ldlt(classical=True)[1:] # needs sage.rings.number_field ( [ 2| 0| 0] [--+--+--] @@ -14436,11 +14508,11 @@ cdef class Matrix(Matrix1): correctly:: sage: n = ZZ.random_element(6) - sage: F = QuadraticField(-1, 'I') # optional - sage.rings.number_field - sage: A = matrix.random(F, n) # optional - sage.rings.number_field - sage: A = A + A.conjugate_transpose() # optional - sage.rings.number_field - sage: P,L,D = A.block_ldlt() # optional - sage.rings.number_field - sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() # optional - sage.rings.number_field + sage: F = QuadraticField(-1, 'I') # needs sage.rings.number_field + sage: A = matrix.random(F, n) # needs sage.rings.number_field + sage: A = A + A.conjugate_transpose() + sage: P,L,D = A.block_ldlt() + sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() True Ensure that a "random" complex positive-semidefinite matrix is @@ -14448,13 +14520,13 @@ cdef class Matrix(Matrix1): is in fact diagonal:: sage: n = ZZ.random_element(6) - sage: F = QuadraticField(-1, 'I') # optional - sage.rings.number_field - sage: A = matrix.random(F, n) # optional - sage.rings.number_field - sage: A = A*A.conjugate_transpose() # optional - sage.rings.number_field - sage: P,L,D = A.block_ldlt() # optional - sage.rings.number_field - sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() # optional - sage.rings.number_field + sage: F = QuadraticField(-1, 'I') # needs sage.rings.number_field + sage: A = matrix.random(F, n) # needs sage.rings.number_field + sage: A = A * A.conjugate_transpose() + sage: P,L,D = A.block_ldlt() + sage: A == P * L * D * L.conjugate_transpose() * P.conjugate_transpose() True - sage: diagonal_matrix(D.diagonal()) == D # optional - sage.rings.number_field + sage: diagonal_matrix(D.diagonal()) == D True The factorization should be a no-op on diagonal matrices:: @@ -14588,7 +14660,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, [ [2,1], ....: [1,2] ] ) - sage: A.eigenvalues() # optional - sage.rings.number_field + sage: A.eigenvalues() # needs sage.rings.number_field [3, 1] sage: A.is_positive_semidefinite() True @@ -14597,7 +14669,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, [ [1,1], ....: [1,1] ] ) - sage: A.eigenvalues() + sage: A.eigenvalues() # needs sage.rings.number_field [2, 0] sage: A.is_positive_semidefinite() True @@ -14606,7 +14678,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, [ [0,1], ....: [1,0] ] ) - sage: A.eigenvalues() + sage: A.eigenvalues() # needs sage.rings.number_field [1, -1] sage: A.is_positive_semidefinite() False @@ -14616,7 +14688,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, [ [2,1], ....: [0,0] ]) - sage: A.eigenvalues() + sage: A.eigenvalues() # needs sage.rings.number_field [2, 0] sage: A.is_positive_semidefinite() False @@ -14658,7 +14730,7 @@ cdef class Matrix(Matrix1): return ``False``):: sage: rings = [ZZ, QQ, RDF, CDF] - sage: rings.append(QuadraticField(-1, 'I')) # optional - sage.rings.number_field + sage: rings.append(QuadraticField(-1, 'I')) # needs sage.rings.number_field sage: from sage.misc.prandom import choice sage: ring = choice(rings) sage: A = matrix.random(ring, 10); A = A + A.conjugate_transpose() @@ -14667,18 +14739,18 @@ cdef class Matrix(Matrix1): ....: return True ....: return ( A.is_hermitian() and ....: all(v >= 0 for v in A.eigenvalues()) ) - sage: expected = is_positive_semidefinite_naive(A) + sage: expected = is_positive_semidefinite_naive(A) # needs numpy sage: actual = A.is_positive_semidefinite() - sage: actual == expected + sage: actual == expected # needs numpy True We reject matrices whose base fields cannot be coerced to either real numbers, complex numbers, or symbolics; otherwise we risk returning nonsensical results:: - sage: F = FiniteField(5^2) # optional - sage.libs.pari - sage: A = matrix.identity(F, 1) # optional - sage.libs.pari - sage: A.is_positive_semidefinite() # optional - sage.libs.pari + sage: F = FiniteField(5^2) # needs sage.rings.finite_rings + sage: A = matrix.identity(F, 1) # needs sage.rings.finite_rings + sage: A.is_positive_semidefinite() # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: Could not see Finite Field in z2 of size 5^2 @@ -14786,9 +14858,10 @@ cdef class Matrix(Matrix1): confirmed by the positive determinants of its leading principal submatrices:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: C. = NumberField(x^2 + 1, embedding=CC(0,1)) # optional - sage.rings.number_field - sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], # optional - sage.rings.number_field + sage: C. = NumberField(x^2 + 1, embedding=CC(0,1)) + sage: A = matrix(C, [[ 23, 17*I + 3, 24*I + 25, 21*I], ....: [ -17*I + 3, 38, -69*I + 89, 7*I + 15], ....: [-24*I + 25, 69*I + 89, 976, 24*I + 6], ....: [ -21*I, -7*I + 15, -24*I + 6, 28]]) @@ -14800,6 +14873,7 @@ cdef class Matrix(Matrix1): An Hermitian matrix that is not positive-definite and a vector ``u`` that makes the corresponding quadratic form negative:: + sage: # needs sage.rings.number_field sage: C. = QuadraticField(-1) sage: B = matrix(C, [[ 2, 4 - 2*I, 2 + 2*I], ....: [4 + 2*I, 8, 10*I], @@ -14814,12 +14888,12 @@ cdef class Matrix(Matrix1): confirmed by the positive determinants of its leading principal submatrices:: - sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], + sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], # needs sage.rings.number_field ....: [ -2*I + 4, 11, 10 - 12*I], ....: [ 4*I + 6, 10 + 12*I, 37]]) - sage: A.is_positive_definite() + sage: A.is_positive_definite() # needs sage.rings.number_field True - sage: [A[:i,:i].determinant() for i in range(1,A.nrows()+1)] + sage: [A[:i,:i].determinant() for i in range(1, A.nrows() + 1)] # needs sage.rings.number_field [2, 2, 6] TESTS: @@ -14828,17 +14902,18 @@ cdef class Matrix(Matrix1): numbers, complex numbers, or symbolic ring, then this routine will fail since comparison to zero is meaningless:: - sage: F. = FiniteField(5^3) # optional - sage.libs.pari - sage: a.conjugate() # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(5^3) + sage: a.conjugate() Traceback (most recent call last): ... TypeError: cardinality of the field must be a square number - sage: A = matrix(F, # optional - sage.libs.pari + sage: A = matrix(F, ....: [[ a^2 + 2*a, 4*a^2 + 3*a + 4, 3*a^2 + a, 2*a^2 + 2*a + 1], ....: [4*a^2 + 3*a + 4, 4*a^2 + 2, 3*a, 2*a^2 + 4*a + 2], ....: [ 3*a^2 + a, 3*a, 3*a^2 + 2, 3*a^2 + 2*a + 3], ....: [2*a^2 + 2*a + 1, 2*a^2 + 4*a + 2, 3*a^2 + 2*a + 3, 3*a^2 + 2*a + 4]]) - sage: A.is_positive_definite() # optional - sage.libs.pari + sage: A.is_positive_definite() Traceback (most recent call last): ... ValueError: Could not see Finite Field in a of size 5^3 as a subring @@ -14856,7 +14931,7 @@ cdef class Matrix(Matrix1): True sage: matrix.identity(CC,4).is_positive_definite() True - sage: matrix.identity(SR,4).is_positive_definite() # optional - sage.symbolic + sage: matrix.identity(SR,4).is_positive_definite() # needs sage.symbolic True """ result = self._is_positive_definite_or_semidefinite(False) @@ -15058,21 +15133,21 @@ cdef class Matrix(Matrix1): A matrix over a not-totally-real number field:: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^2 + 5) # optional - sage.rings.number_field - sage: M = matrix(K, [[1+j,1], [0,2*j]]) # optional - sage.rings.number_field - sage: M.conjugate() # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 5) # needs sage.rings.number_field + sage: M = matrix(K, [[1+j,1], [0,2*j]]) # needs sage.rings.number_field + sage: M.conjugate() # needs sage.rings.number_field [-j + 1 1] [ 0 -2*j] There is a shortcut for the conjugate:: - sage: M.C + sage: M.C # needs sage.rings.number_field [-j + 1 1] [ 0 -2*j] There is also a shortcut for the conjugate transpose, or "Hermitian transpose":: - sage: M.H + sage: M.H # needs sage.rings.number_field [-j + 1 0] [ 1 -2*j] @@ -15113,10 +15188,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(SR, 2, 2, [[2-I, 3+4*I], [9-6*I, 5*I]]) # optional - sage.symbolic - sage: M.base_ring() # optional - sage.symbolic + sage: M = matrix(SR, 2, 2, [[2-I, 3+4*I], [9-6*I, 5*I]]) # needs sage.symbolic + sage: M.base_ring() # needs sage.symbolic Symbolic Ring - sage: M.conjugate_transpose() # optional - sage.symbolic + sage: M.conjugate_transpose() # needs sage.symbolic [ I + 2 6*I + 9] [-4*I + 3 -5*I] @@ -15129,7 +15204,7 @@ cdef class Matrix(Matrix1): There is also a shortcut for the conjugate transpose, or "Hermitian transpose":: - sage: M.H # optional - sage.symbolic + sage: M.H # needs sage.symbolic [ I + 2 6*I + 9] [-4*I + 3 -5*I] @@ -15146,24 +15221,25 @@ cdef class Matrix(Matrix1): (Matrices over quadratic number fields are another class of examples.) :: - sage: C = CyclotomicField(5) # optional - sage.rings.number_field - sage: a = C.gen(); a # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: C = CyclotomicField(5) + sage: a = C.gen(); a zeta5 - sage: CC(a) # optional - sage.rings.number_field + sage: CC(a) 0.309016994374947 + 0.951056516295154*I - sage: M = matrix(C, 1, 2, [a^2, a+a^3]) # optional - sage.rings.number_field - sage: M.conjugate_transpose() # optional - sage.rings.number_field + sage: M = matrix(C, 1, 2, [a^2, a+a^3]) + sage: M.conjugate_transpose() [ zeta5^3] [-zeta5^3 - zeta5 - 1] Furthermore, this method can be applied to matrices over quadratic extensions of finite fields:: - sage: F. = GF(9,'a') # optional - sage.libs.pari - sage: N = matrix(F, 2, [0,a,-a,1]); N # optional - sage.libs.pari + sage: F. = GF(9,'a') # needs sage.rings.finite_rings + sage: N = matrix(F, 2, [0,a,-a,1]); N # needs sage.rings.finite_rings [ 0 a] [2*a 1] - sage: N.conjugate_transpose() # optional - sage.libs.pari + sage: N.conjugate_transpose() # needs sage.rings.finite_rings [ 0 a + 2] [2*a + 1 1] @@ -15300,26 +15376,26 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: d = matrix([[3, 0], [0,sqrt(2)]]) # optional - sage.symbolic - sage: b = matrix([[1, -1], [2, 2]]); e = b * d * b.inverse(); e # optional - sage.symbolic + sage: d = matrix([[3, 0], [0, sqrt(2)]]) # needs sage.symbolic + sage: b = matrix([[1, -1], [2, 2]]); e = b * d * b.inverse(); e # needs sage.symbolic [ 1/2*sqrt(2) + 3/2 -1/4*sqrt(2) + 3/4] [ -sqrt(2) + 3 1/2*sqrt(2) + 3/2] :: - sage: e.numerical_approx(53) # optional - sage.symbolic + sage: e.numerical_approx(53) # needs sage.symbolic [ 2.20710678118655 0.396446609406726] [ 1.58578643762690 2.20710678118655] :: - sage: e.numerical_approx(20) # optional - sage.symbolic + sage: e.numerical_approx(20) # needs sage.symbolic [ 2.2071 0.39645] [ 1.5858 2.2071] :: - sage: (e - I).numerical_approx(20) # optional - sage.symbolic + sage: (e - I).numerical_approx(20) # needs sage.symbolic [2.2071 - 1.0000*I 0.39645] [ 1.5858 2.2071 - 1.0000*I] @@ -15341,7 +15417,7 @@ cdef class Matrix(Matrix1): :: - sage: matrix(SR, 2, 2, range(4)).n() # optional - sage.symbolic + sage: matrix(SR, 2, 2, range(4)).n() # needs sage.symbolic [0.000000000000000 1.00000000000000] [ 2.00000000000000 3.00000000000000] @@ -15356,8 +15432,8 @@ cdef class Matrix(Matrix1): We check that :trac:`29700` is fixed:: sage: M = matrix(3, [1,1,1,1,0,0,0,1,0]) - sage: A, B = M.diagonalization(QQbar) # optional - sage.rings.number_field - sage: _ = A.n() # optional - sage.rings.number_field + sage: A, B = M.diagonalization(QQbar) # needs sage.rings.number_field + sage: _ = A.n() # needs sage.rings.number_field """ from sage.rings.real_mpfr import RealField @@ -15392,7 +15468,7 @@ cdef class Matrix(Matrix1): A matrix over ZZ colored with different grey levels:: sage: A = matrix([[1,3,5,1],[2,4,5,6],[1,3,5,7]]) - sage: A.plot() # optional - sage.plot + sage: A.plot() # needs sage.plot Graphics object consisting of 1 graphics primitive Here we make a random matrix over ``RR`` and use ``cmap='hsv'`` to color @@ -15400,13 +15476,13 @@ cdef class Matrix(Matrix1): ``matrix_plot`` for more information on cmaps):: sage: A = random_matrix(RDF, 50) - sage: plot(A, cmap='hsv') # optional - sage.plot + sage: plot(A, cmap='hsv') # needs sage.plot Graphics object consisting of 1 graphics primitive Another random plot, but over GF(389):: sage: A = random_matrix(GF(389), 10) - sage: A.plot(cmap='Oranges') # optional - sage.rings.finite_rings sage.plot + sage: A.plot(cmap='Oranges') # needs sage.plot sage.rings.finite_rings Graphics object consisting of 1 graphics primitive """ from sage.plot.matrix_plot import matrix_plot @@ -15422,17 +15498,18 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: v = vector([1,x,x^2]) # optional - sage.symbolic - sage: v.derivative(x) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: v = vector([1,x,x^2]) + sage: v.derivative(x) (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic + sage: type(v.derivative(x)) == type(v) True - sage: v = vector([1,x,x^2], sparse=True) # optional - sage.symbolic - sage: v.derivative(x) # optional - sage.symbolic + sage: v = vector([1,x,x^2], sparse=True) + sage: v.derivative(x) (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) # optional - sage.symbolic + sage: type(v.derivative(x)) == type(v) True - sage: v.derivative(x,x) # optional - sage.symbolic + sage: v.derivative(x,x) (0, 0, 2) """ from sage.misc.derivative import multi_derivative @@ -15458,23 +15535,23 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: a = matrix([[1,2], [3,4]]) - sage: a.exp() # optional - sage.symbolic + sage: a.exp() # needs sage.symbolic [-1/22*((sqrt(33) - 11)*e^sqrt(33) - sqrt(33) - 11)*e^(-1/2*sqrt(33) + 5/2) 2/33*(sqrt(33)*e^sqrt(33) - sqrt(33))*e^(-1/2*sqrt(33) + 5/2)] [ 1/11*(sqrt(33)*e^sqrt(33) - sqrt(33))*e^(-1/2*sqrt(33) + 5/2) 1/22*((sqrt(33) + 11)*e^sqrt(33) - sqrt(33) + 11)*e^(-1/2*sqrt(33) + 5/2)] - sage: type(a.exp()) # optional - sage.symbolic + sage: type(a.exp()) # needs sage.symbolic sage: a = matrix([[1/2,2/3], [3/4,4/5]]) - sage: a.exp() # optional - sage.symbolic + sage: a.exp() # needs sage.symbolic [-1/418*((3*sqrt(209) - 209)*e^(1/10*sqrt(209)) - 3*sqrt(209) - 209)*e^(-1/20*sqrt(209) + 13/20) 20/627*(sqrt(209)*e^(1/10*sqrt(209)) - sqrt(209))*e^(-1/20*sqrt(209) + 13/20)] [ 15/418*(sqrt(209)*e^(1/10*sqrt(209)) - sqrt(209))*e^(-1/20*sqrt(209) + 13/20) 1/418*((3*sqrt(209) + 209)*e^(1/10*sqrt(209)) - 3*sqrt(209) + 209)*e^(-1/20*sqrt(209) + 13/20)] - sage: a = matrix(RR, [[1,pi.n()], [1e2,1e-2]]) - sage: a.exp() # optional - sage.symbolic + sage: a = matrix(RR, [[1,pi.n()], [1e2,1e-2]]) # needs sage.symbolic + sage: a.exp() # needs sage.symbolic [ 1/11882424341266*((11*sqrt(227345670387496707609) + 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) + 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) 445243650/75781890129165569203*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] [ 10000/53470909535697*(sqrt(227345670387496707609)*e^(3/1275529100*sqrt(227345670387496707609)) - sqrt(227345670387496707609))*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200) -1/11882424341266*((11*sqrt(227345670387496707609) - 5941212170633)*e^(3/1275529100*sqrt(227345670387496707609)) - 11*sqrt(227345670387496707609) - 5941212170633)*e^(-3/2551058200*sqrt(227345670387496707609) + 101/200)] - sage: a.change_ring(RDF).exp() # rel tol 1e-14 # optional - sage.symbolic + sage: a.change_ring(RDF).exp() # rel tol 1e-14 # needs sage.symbolic [42748127.31532951 7368259.244159399] [234538976.1381042 40426191.45156228] @@ -15483,9 +15560,9 @@ cdef class Matrix(Matrix1): Sparse matrices are handled correctly (:trac:`28935`), but may require a patched version of maxima (:trac:`32898`) for now:: - sage: matrix.diagonal([0], sparse=True).exp() # not tested, requires patched maxima + sage: matrix.diagonal([0], sparse=True).exp() # not tested # needs sage.symbolic [1] - sage: matrix.zero(CBF, 2, sparse=True).exp() # optional - sage.symbolic + sage: matrix.zero(CBF, 2, sparse=True).exp() # needs sage.symbolic [1.000000000000000 0] [ 0 1.000000000000000] """ @@ -15517,9 +15594,9 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: x = polygen(ZZ, 'x') - sage: OE. = EquationOrder(x^2 - x + 2) # optional - sage.rings.number_field - sage: m = Matrix([[1, w], [w, 7]]) # optional - sage.rings.number_field - sage: m.elementary_divisors() # optional - sage.rings.number_field + sage: OE. = EquationOrder(x^2 - x + 2) # needs sage.rings.number_field + sage: m = Matrix([[1, w], [w, 7]]) # needs sage.rings.number_field + sage: m.elementary_divisors() # needs sage.rings.number_field [1, -w + 9] .. SEEALSO:: @@ -15608,20 +15685,21 @@ cdef class Matrix(Matrix1): An example over the ring of integers of a number field (of class number 1):: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: OE. = EquationOrder(x^2 - x + 2) # optional - sage.rings.number_field - sage: m = Matrix([[1, w], [w, 7]]) # optional - sage.rings.number_field - sage: d, u, v = m.smith_form() # optional - sage.rings.number_field - sage: (d, u, v) # optional - sage.rings.number_field + sage: OE. = EquationOrder(x^2 - x + 2) + sage: m = Matrix([[1, w], [w, 7]]) + sage: d, u, v = m.smith_form() + sage: (d, u, v) ( [ 1 0] [ 1 0] [ 1 -w] [ 0 -w + 9], [-w 1], [ 0 1] ) - sage: u * m * v == d # optional - sage.rings.number_field + sage: u * m * v == d True - sage: u.base_ring() == v.base_ring() == d.base_ring() == OE # optional - sage.rings.number_field + sage: u.base_ring() == v.base_ring() == d.base_ring() == OE True - sage: u.det().is_unit() and v.det().is_unit() # optional - sage.rings.number_field + sage: u.det().is_unit() and v.det().is_unit() True An example over the polynomial ring QQ[x]:: @@ -15661,52 +15739,57 @@ cdef class Matrix(Matrix1): Some examples over non-PID's work anyway:: - sage: R. = EquationOrder(x^2 + 5) # class number 2 # optional - sage.rings.number_field - sage: A = matrix(R, 2, 2, [s-1, -s, -s, 2*s+1]) # optional - sage.rings.number_field - sage: D, U, V = A.smith_form() # optional - sage.rings.number_field - sage: D, U, V # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: R. = EquationOrder(x^2 + 5) # class number 2 + sage: A = matrix(R, 2, 2, [s - 1, -s, -s, 2*s + 1]) + sage: D, U, V = A.smith_form() + sage: D, U, V ( [ 1 0] [ 4 s + 4] [ 1 -5*s + 6] [ 0 -s - 6], [ s s - 1], [ 0 1] ) - sage: D == U*A*V # optional - sage.rings.number_field + sage: D == U * A * V True Others don't, but they fail quite constructively:: - sage: matrix(R, 2, 2, [s-1, -s-2, -2*s, -s-2]).smith_form() # optional - sage.rings.number_field + sage: matrix(R, 2, 2, [s - 1, -s - 2, -2*s, -s - 2]).smith_form() # needs sage.rings.number_field Traceback (most recent call last): ... ArithmeticError: Ideal Fractional ideal (2, s + 1) not principal Empty matrices are handled safely:: - sage: m = MatrixSpace(OE, 2,0)(0) # optional - sage.rings.number_field - sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: m = MatrixSpace(OE, 2,0)(0) + sage: d, u, v = m.smith_form(); u * m * v == d True - sage: m = MatrixSpace(OE, 0,2)(0) # optional - sage.rings.number_field - sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field + sage: m = MatrixSpace(OE, 0,2)(0) + sage: d, u, v = m.smith_form(); u * m * v == d True - sage: m = MatrixSpace(OE, 0,0)(0) # optional - sage.rings.number_field - sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field + sage: m = MatrixSpace(OE, 0,0)(0) + sage: d, u, v = m.smith_form(); u * m * v == d True Some pathological cases that crashed earlier versions:: - sage: m = Matrix(OE, [[2*w, 2*w-1, -w+1], # optional - sage.rings.number_field - ....: [2*w+2, -2*w-1, w-1], - ....: [-2*w-1, -2*w-2, 2*w-1]]) - sage: d, u, v = m.smith_form(); u * m * v == d # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: m = Matrix(OE, [[ 2*w, 2*w - 1, -w + 1], + ....: [ 2*w + 2, -2*w - 1, w - 1], + ....: [-2*w - 1, -2*w - 2, 2*w - 1]]) + sage: d, u, v = m.smith_form(); u * m * v == d True - sage: m = matrix(OE, 3, 3, [-5*w-1,-2*w-2,4*w-10, 8*w,-w,w-1, -1,1,-8]) # optional - sage.rings.number_field - sage: d, u, v = m.smith_form(); u*m*v == d # optional - sage.rings.number_field + sage: m = matrix(OE, [[-5*w - 1, -2*w - 2, 4*w - 10], + ....: [ 8*w, -w, w - 1], + ....: [ -1, 1, -8]]) + sage: d, u, v = m.smith_form(); u * m * v == d True Over local fields, we can request the transformation matrices to be integral:; - sage: K = Qp(2, 5, print_mode='terse') # optional - sage.rings.padics - sage: M = matrix(K, 2, 3, [1/2, 1, 2, 1/3, 1, 3]) # optional - sage.rings.padics - sage: M.smith_form(integral=True) # optional - sage.rings.padics + sage: K = Qp(2, 5, print_mode='terse') # needs sage.rings.padics + sage: M = matrix(K, 2, 3, [1/2, 1, 2, 1/3, 1, 3]) # needs sage.rings.padics + sage: M.smith_form(integral=True) # needs sage.rings.padics ( [1/2 + O(2^4) 0 0] [ 1 + O(2^5) 0] [ 0 1 + O(2^5) 0], [42 + O(2^6) 1 + O(2^5)], @@ -15973,11 +16056,12 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: x = polygen(ZZ, 'x') - sage: L. = NumberField(x^3 - 2) # optional - sage.rings.number_field - sage: OL = L.ring_of_integers() # optional - sage.rings.number_field + sage: L. = NumberField(x^3 - 2) # needs sage.rings.number_field + sage: OL = L.ring_of_integers() # needs sage.rings.number_field We check some degenerate cases:: + sage: # needs sage.rings.number_field sage: m = matrix(OL, 0, 0, []); r,s,p = m._echelon_form_PID() sage: (r,s,p) ([], [], []) @@ -15996,17 +16080,18 @@ cdef class Matrix(Matrix1): A 2x2 matrix:: - sage: m = matrix(OL, 2, 2, [1,0, a, 2]) - sage: r,s,p = m._echelon_form_PID(); (r,s,p) + sage: m = matrix(OL, 2, 2, [1, 0, a, 2]) # needs sage.rings.number_field + sage: r,s,p = m._echelon_form_PID(); (r,s,p) # needs sage.rings.number_field ( [ 1 0] [1 0] [-a 1], [0 2], [0, 1] ) - sage: r * m == s and r.det() == 1 + sage: r * m == s and r.det() == 1 # needs sage.rings.number_field True A larger example:: + sage: # needs sage.rings.number_field sage: m = matrix(OL, 3, 5, [a^2 - 3*a - 1, a^2 - 3*a + 1, a^2 + 1, ....: -a^2 + 2, -3*a^2 - a - 1, -6*a - 1, a^2 - 3*a - 1, ....: 2*a^2 + a + 5, -2*a^2 + 5*a + 1, -a^2 + 13*a - 3, @@ -16446,7 +16531,7 @@ cdef class Matrix(Matrix1): sage: U.inverse()*B*U == Z True - sage: A.jordan_form() == B.jordan_form() # optional - sage.combinat + sage: A.jordan_form() == B.jordan_form() # needs sage.combinat True Two more examples, illustrating the two extremes of the zig-zag @@ -16507,38 +16592,39 @@ cdef class Matrix(Matrix1): sage: U.inverse()*D*U == Z True - sage: C.jordan_form() == D.jordan_form() # optional - sage.combinat + sage: C.jordan_form() == D.jordan_form() # needs sage.combinat True ZigZag form is achieved entirely with the operations of the field, so while the eigenvalues may lie outside the field, this does not impede the computation of the form. :: - sage: F. = GF(5^4) # optional - sage.libs.pari - sage: A = matrix(F, [[ a, 0, 0, a + 3], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = GF(5^4) + sage: A = matrix(F, [[ a, 0, 0, a + 3], ....: [ 0,a^2 + 1, 0, 0], ....: [ 0, 0,a^3, 0], ....: [a^2 +4 , 0, 0,a + 2]]) - sage: A.zigzag_form() # optional - sage.libs.pari + sage: A.zigzag_form() [ 0 a^3 + 2*a^2 + 2*a + 2| 0| 0] [ 1 2*a + 2| 0| 0] [-------------------------------------------+---------------------+---------------------] [ 0 0| a^3| 0] [-------------------------------------------+---------------------+---------------------] [ 0 0| 0| a^2 + 1] - sage: A.eigenvalues() # optional - sage.libs.pari + sage: A.eigenvalues() Traceback (most recent call last): ... NotImplementedError: algebraic closures of finite fields are only implemented for prime fields Subdivisions are optional. :: - sage: F. = GF(5^4) # optional - sage.libs.pari - sage: A = matrix(F, [[ a, 0, 0, a + 3], # optional - sage.libs.pari + sage: F. = GF(5^4) # needs sage.rings.finite_rings + sage: A = matrix(F, [[ a, 0, 0, a + 3], # needs sage.rings.finite_rings ....: [ 0,a^2 + 1, 0, 0], ....: [ 0, 0,a^3, 0], ....: [a^2 +4 , 0, 0,a + 2]]) - sage: A.zigzag_form(subdivide=False) # optional - sage.libs.pari + sage: A.zigzag_form(subdivide=False) # needs sage.rings.finite_rings [ 0 a^3 + 2*a^2 + 2*a + 2 0 0] [ 1 2*a + 2 0 0] [ 0 0 a^3 0] @@ -16709,13 +16795,13 @@ cdef class Matrix(Matrix1): sage: invariants [[4, -4, 1], [-12, 4, 9, -6, 1], [216, -108, -306, 271, 41, -134, 64, -13, 1]] sage: polys = [R(p) for p in invariants] - sage: [p.factor() for p in polys] # optional - sage.libs.pari + sage: [p.factor() for p in polys] # needs sage.rings.finite_rings [(x - 2)^2, (x - 3) * (x + 1) * (x - 2)^2, (x + 1)^2 * (x - 3)^3 * (x - 2)^3] sage: all(polys[i].divides(polys[i+1]) for i in range(len(polys)-1)) True - sage: polys[-1] == A.minimal_polynomial(var='x') # optional - sage.libs.pari + sage: polys[-1] == A.minimal_polynomial(var='x') # needs sage.libs.pari True - sage: prod(polys) == A.characteristic_polynomial(var='x') # optional - sage.libs.pari + sage: prod(polys) == A.characteristic_polynomial(var='x') # needs sage.libs.pari True Rational form is a canonical form. Any two matrices are similar @@ -16733,9 +16819,9 @@ cdef class Matrix(Matrix1): ....: [0, -42, 14, 8, 167, -17, -84, 13], ....: [0, -50, 17, 10, 199, -23, -98, 14], ....: [0, 15, -5, -2, -59, 7, 30, -2]]) - sage: C.minimal_polynomial().factor() # optional - sage.libs.pari + sage: C.minimal_polynomial().factor() # needs sage.libs.pari (x - 2)^2 - sage: C.characteristic_polynomial().factor() # optional - sage.libs.pari + sage: C.characteristic_polynomial().factor() # needs sage.libs.pari (x - 2)^8 sage: C.rational_form() [ 0 -4| 0 0| 0 0| 0 0] @@ -16758,9 +16844,9 @@ cdef class Matrix(Matrix1): ....: [ 31, -18, 135, 38, 12, 47, 155, -147], ....: [-33, 19, -138, -39, -13, -45, -156, 151], ....: [ -7, 4, -29, -8, -3, -10, -34, 34]]) - sage: D.minimal_polynomial().factor() # optional - sage.libs.pari + sage: D.minimal_polynomial().factor() # needs sage.libs.pari (x - 2)^2 - sage: D.characteristic_polynomial().factor() # optional - sage.libs.pari + sage: D.characteristic_polynomial().factor() # needs sage.libs.pari (x - 2)^8 sage: D.rational_form() [ 0 -4| 0 0| 0 0| 0 0] @@ -16783,9 +16869,9 @@ cdef class Matrix(Matrix1): ....: [-3, -7, 5, -6, -1, 5, -4, 14], ....: [ 6, 18, -10, 14, 4, -10, 10, -28], ....: [-2, -6, 4, -5, -1, 3, -3, 13]]) - sage: E.minimal_polynomial().factor() # optional - sage.libs.pari + sage: E.minimal_polynomial().factor() # needs sage.libs.pari (x - 2)^3 - sage: E.characteristic_polynomial().factor() # optional - sage.libs.pari + sage: E.characteristic_polynomial().factor() # needs sage.libs.pari (x - 2)^8 sage: E.rational_form() [ 2| 0 0| 0 0| 0 0 0] @@ -16822,9 +16908,9 @@ cdef class Matrix(Matrix1): ....: [ 139, -35, 99, -49, -18, 236, -41, -70, 370, -118, -377, -619], ....: [ 243, 9, 81, -72, -81, 386, 43, -105, 508, -124, -564, -911], ....: [-155, -3, -55, 45, 50, -245, -27, 65, -328, 77, 365, 583]]) - sage: A.characteristic_polynomial().factor() # optional - sage.libs.pari + sage: A.characteristic_polynomial().factor() # needs sage.libs.pari (x^2 - 2)^2 * (x^2 + 2*x + 5)^4 - sage: A.eigenvalues(extend=False) # optional - sage.rings.number_field + sage: A.eigenvalues(extend=False) # needs sage.rings.number_field [] sage: A.rational_form() [ 0 -5| 0 0 0 0| 0 0 0 0 0 0] @@ -16843,14 +16929,14 @@ cdef class Matrix(Matrix1): [ 0 0| 0 0 0 0| 0 0 0 0 1 -4] sage: F. = QQ[] sage: polys = A.rational_form(format='invariants') - sage: [F(p).factor() for p in polys] # optional - sage.libs.pari + sage: [F(p).factor() for p in polys] # needs sage.libs.pari [x^2 + 2*x + 5, (x^2 - 2) * (x^2 + 2*x + 5), (x^2 - 2) * (x^2 + 2*x + 5)^2] Rational form may be computed over any field. The matrix below is an example where the eigenvalues lie outside the field. :: - sage: F. = FiniteField(7^2) # optional - sage.libs.pari - sage: A = matrix(F, # optional - sage.libs.pari + sage: F. = FiniteField(7^2) # needs sage.rings.finite_rings + sage: A = matrix(F, # needs sage.rings.finite_rings ....: [[5*a + 3, 4*a + 1, 6*a + 2, 2*a + 5, 6, 4*a + 5, 4*a + 5, 5, a + 6, 5, 4*a + 4], ....: [6*a + 3, 2*a + 4, 0, 6, 5*a + 5, 2*a, 5*a + 1, 1, 5*a + 2, 4*a, 5*a + 6], ....: [3*a + 1, 6*a + 6, a + 6, 2, 0, 3*a + 6, 5*a + 4, 5*a + 6, 5*a + 2, 3, 4*a + 2], @@ -16862,7 +16948,7 @@ cdef class Matrix(Matrix1): ....: [3*a + 5, 6*a + 2, 4*a, a + 5, 0, 5*a, 6*a + 5, 2*a + 1, 3*a + 1, 3*a + 5, 4*a + 2], ....: [3*a + 2, a + 3, 3*a + 6, a, 3*a + 5, 5*a + 1, 3*a + 2, a + 3, a + 2, 6*a + 1, 3*a + 3], ....: [6*a + 6, 5*a + 1, 4*a, 2, 5*a + 5, 3*a + 5, 3*a + 1, 2*a, 2*a, 2*a + 4, 4*a + 2]]) - sage: A.rational_form() # optional - sage.libs.pari + sage: A.rational_form() # needs sage.rings.finite_rings [ a + 2| 0 0 0| 0 0 0 0 0 0 0] [-------+-----------------------+-------------------------------------------------------] [ 0| 0 0 a + 6| 0 0 0 0 0 0 0] @@ -16877,17 +16963,17 @@ cdef class Matrix(Matrix1): [ 0| 0 0 0| 0 0 0 0 1 0 2*a + 1] [ 0| 0 0 0| 0 0 0 0 0 1 2*a + 1] sage: invariants = A.rational_form(format='invariants') - sage: invariants # optional - sage.rings.finite_rings + sage: invariants # needs sage.rings.finite_rings [[6*a + 5, 1], [6*a + 1, a + 3, a + 3, 1], [5*a, a + 4, a + 6, 6*a + 5, 6*a + 1, 5*a + 6, 5*a + 6, 1]] sage: R. = F[] sage: polys = [R(p) for p in invariants] - sage: [p.factor() for p in polys] # optional - sage.rings.finite_rings + sage: [p.factor() for p in polys] # needs sage.rings.finite_rings [x + 6*a + 5, (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a), (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a)^3] - sage: polys[-1] == A.minimal_polynomial() # optional - sage.libs.pari + sage: polys[-1] == A.minimal_polynomial() # needs sage.rings.finite_rings True - sage: prod(polys) == A.characteristic_polynomial() # optional - sage.libs.pari + sage: prod(polys) == A.characteristic_polynomial() # needs sage.rings.finite_rings True - sage: A.eigenvalues() # optional - sage.libs.pari + sage: A.eigenvalues() # needs sage.rings.finite_rings Traceback (most recent call last): ... NotImplementedError: algebraic closures of finite fields are only implemented for prime fields @@ -17084,47 +17170,49 @@ cdef class Matrix(Matrix1): Nonnegative matrices are positive operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # needs sage.geometry.polyhedron sage: L = random_matrix(QQ, 3).apply_map(abs) - sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron + sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron - sage: L = matrix(SR, [ [0, e, 0 ], # optional - sage.symbolic + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # needs sage.geometry.polyhedron + sage: L = matrix(SR, [ [0, e, 0 ], # needs sage.symbolic ....: [0, 2, pi], ....: [sqrt(2), 0, 0 ] ]) - sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron sage.symbolic True Your matrix can be over any exact ring, for example the ring of univariate polynomials with rational coefficients:: - sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) # optional - sage.geometry.polyhedron - sage: K.is_full_space() # optional - sage.geometry.polyhedron + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) # needs sage.geometry.polyhedron + sage: K.is_full_space() # needs sage.geometry.polyhedron True sage: x = polygen(ZZ, 'x') sage: L = matrix(QQ[x], [[x,0],[0,1]]) - sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron + sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron True TESTS: The identity matrix is always a positive operator:: - sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=8) + sage: R = K.lattice().vector_space().base_ring() + sage: L = identity_matrix(R, K.lattice_dim()) + sage: L.is_positive_operator_on(K) True The zero matrix is always a positive operator:: - sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=8) + sage: R = K.lattice().vector_space().base_ring() + sage: L = zero_matrix(R, K.lattice_dim()) + sage: L.is_positive_operator_on(K) True Everything in ``K1.positive_operators_gens(K2)`` should be @@ -17132,10 +17220,12 @@ cdef class Matrix(Matrix1): the underlying ring symbolic (the usual case is tested by the ``positive_operators_gens`` method):: - sage: K1 = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron - sage: K2 = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron - sage: all(L.change_ring(SR).is_positive_operator_on(K1, K2) # long time # optional - sage.geometry.polyhedron sage.symbolic - ....: for L in K1.positive_operators_gens(K2)) + sage: # needs sage.geometry.polyhedron + sage: K1 = random_cone(max_ambient_dim=5) + sage: K2 = random_cone(max_ambient_dim=5) + sage: results = ( L.change_ring(SR).is_positive_operator_on(K1, K2) # needs sage.symbolic + ....: for L in K1.positive_operators_gens(K2) ) + sage: all(results) # long time # needs sage.symbolic True Technically we could test this, but for now only closed convex cones @@ -17150,9 +17240,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron sage: L = identity_matrix(RR, 3) - sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron + sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17160,11 +17250,11 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic + sage: SCR = SR.subring(no_variables=True); SCR # needs sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron - sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic - sage: L.is_positive_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # needs sage.symbolic + sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron sage.symbolic True """ import sage.geometry.abc @@ -17242,38 +17332,40 @@ cdef class Matrix(Matrix1): Negative Z-matrices are cross-positive operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron - sage: L = matrix(SR, [ [-1, 2, 0], # optional - sage.symbolic + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # needs sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, 2, 0], # needs sage.symbolic ....: [ 0, 2, 7], ....: [ 3, 0, 3] ]) - sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: L.is_cross_positive_on(K) # needs sage.geometry.polyhedron sage.symbolic True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) # optional - sage.geometry.polyhedron - sage: L = matrix(SR, [ [-1, e, 0 ], # optional - sage.symbolic + sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) # needs sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, e, 0 ], # needs sage.symbolic ....: [ 0, 2, pi], ....: [ sqrt(2), 0, 3 ] ]) - sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: L.is_cross_positive_on(K) # needs sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always cross-positive:: - sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=8) + sage: R = K.lattice().vector_space().base_ring() + sage: L = identity_matrix(R, K.lattice_dim()) + sage: L.is_cross_positive_on(K) True The zero matrix is always cross-positive:: - sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=8) + sage: R = K.lattice().vector_space().base_ring() + sage: L = zero_matrix(R, K.lattice_dim()) + sage: L.is_cross_positive_on(K) True Everything in ``K.cross_positive_operators_gens()`` should be @@ -17281,9 +17373,10 @@ cdef class Matrix(Matrix1): symbolic (the usual case is tested by the ``cross_positive_operators_gens`` method):: - sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron - sage: all(L.change_ring(SR).is_cross_positive_on(K) # long time # optional - sage.geometry.polyhedron sage.symbolic - ....: for L in K.cross_positive_operators_gens()) + sage: K = random_cone(max_ambient_dim=5) # needs sage.geometry.polyhedron + sage: results = ( L.change_ring(SR).is_cross_positive_on(K) # needs sage.geometry.polyhedron sage.symbolic + ....: for L in K.cross_positive_operators_gens() ) + sage: all(results) # long time # needs sage.geometry.polyhedron sage.symbolic True Technically we could test this, but for now only closed convex cones @@ -17298,9 +17391,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron sage: L = identity_matrix(RR, 3) - sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron + sage: L.is_cross_positive_on(K) # needs sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17308,11 +17401,11 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic + sage: SCR = SR.subring(no_variables=True); SCR # needs sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron - sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic - sage: L.is_cross_positive_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # needs sage.symbolic + sage: L.is_cross_positive_on(K) # needs sage.geometry.polyhedron sage.symbolic True """ import sage.geometry.abc @@ -17379,46 +17472,48 @@ cdef class Matrix(Matrix1): Z-matrices are Z-operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron - sage: L = matrix(SR, [ [-1, -2, 0], # optional - sage.symbolic + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # needs sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, -2, 0], # needs sage.symbolic ....: [ 0, 2, -7], ....: [-3, 0, 3] ]) - sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: L.is_Z_operator_on(K) # needs sage.geometry.polyhedron sage.symbolic True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron - sage: L = matrix(SR, [ [-1, -e, 0 ], # optional - sage.symbolic + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # needs sage.geometry.polyhedron + sage: L = matrix(SR, [ [-1, -e, 0 ], # needs sage.symbolic ....: [ 0, 2, -pi], ....: [-sqrt(2), 0, 3 ] ]) - sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: L.is_Z_operator_on(K) # needs sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always a Z-operator:: - sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=8) + sage: R = K.lattice().vector_space().base_ring() + sage: L = identity_matrix(R, K.lattice_dim()) + sage: L.is_Z_operator_on(K) True The zero matrix is always a Z-operator:: - sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=8) + sage: R = K.lattice().vector_space().base_ring() + sage: L = zero_matrix(R, K.lattice_dim()) + sage: L.is_Z_operator_on(K) True Everything in ``K.Z_operators_gens()`` should be a Z-operator on ``K``, , even if we make the underlying ring symbolic (the usual case is tested by the ``Z_operators_gens`` method):: - sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron - sage: all(L.change_ring(SR).is_Z_operator_on(K) # long time # optional - sage.geometry.polyhedron sage.symbolic + sage: K = random_cone(max_ambient_dim=5) # needs sage.geometry.polyhedron + sage: all(L.change_ring(SR).is_Z_operator_on(K) # long time # needs sage.geometry.polyhedron sage.symbolic ....: for L in K.Z_operators_gens()) True @@ -17434,9 +17529,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron sage: L = identity_matrix(RR, 3) - sage: L.is_Z_operator_on(K) # optional - sage.geometry.polyhedron + sage: L.is_Z_operator_on(K) # needs sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17498,36 +17593,38 @@ cdef class Matrix(Matrix1): Diagonal matrices are Lyapunov-like operators on the nonnegative orthant:: - sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # optional - sage.geometry.polyhedron + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # needs sage.geometry.polyhedron sage: L = diagonal_matrix(random_vector(QQ, 3)) - sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron + sage: L.is_lyapunov_like_on(K) # needs sage.geometry.polyhedron True Symbolic entries also work in some easy cases:: - sage: K = Cone([(1,0,0),(0,1,0),(0,0,1)]) # optional - sage.geometry.polyhedron - sage: L = matrix(SR, [ [e, 0, 0 ], # optional - sage.symbolic + sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)]) # needs sage.geometry.polyhedron + sage: L = matrix(SR, [ [e, 0, 0 ], # needs sage.symbolic ....: [0, pi, 0 ], ....: [0, 0, sqrt(2)] ]) - sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: L.is_lyapunov_like_on(K) # needs sage.geometry.polyhedron sage.symbolic True TESTS: The identity matrix is always Lyapunov-like:: - sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = identity_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=8) + sage: R = K.lattice().vector_space().base_ring() + sage: L = identity_matrix(R, K.lattice_dim()) + sage: L.is_lyapunov_like_on(K) True The zero matrix is always Lyapunov-like:: - sage: K = random_cone(max_ambient_dim=8) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = zero_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=8) + sage: R = K.lattice().vector_space().base_ring() + sage: L = zero_matrix(R, K.lattice_dim()) + sage: L.is_lyapunov_like_on(K) True Everything in ``K.lyapunov_like_basis()`` should be @@ -17535,8 +17632,8 @@ cdef class Matrix(Matrix1): symbolic (the usual case is tested by the ``lyapunov_like_basis`` method):: - sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron - sage: all(L.change_ring(SR).is_lyapunov_like_on(K) # long time # optional - sage.geometry.polyhedron sage.symbolic + sage: K = random_cone(max_ambient_dim=5) # needs sage.geometry.polyhedron + sage: all(L.change_ring(SR).is_lyapunov_like_on(K) # long time # needs sage.geometry.polyhedron sage.symbolic ....: for L in K.lyapunov_like_basis()) True @@ -17552,9 +17649,9 @@ cdef class Matrix(Matrix1): We can't give reliable answers over inexact rings:: - sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron + sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron sage: L = identity_matrix(RR, 3) - sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron + sage: L.is_lyapunov_like_on(K) # needs sage.geometry.polyhedron Traceback (most recent call last): ... ValueError: The base ring of the matrix is neither symbolic nor @@ -17562,23 +17659,24 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR # optional - sage.symbolic + sage: SCR = SR.subring(no_variables=True); SCR # needs sage.symbolic Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) # optional - sage.geometry.polyhedron - sage: L = identity_matrix(SCR, 3) # optional - sage.symbolic - sage: L.is_lyapunov_like_on(K) # optional - sage.geometry.polyhedron sage.symbolic + sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron + sage: L = identity_matrix(SCR, 3) # needs sage.symbolic + sage: L.is_lyapunov_like_on(K) # needs sage.geometry.polyhedron sage.symbolic True A matrix is Lyapunov-like on a cone if and only if both the matrix and its negation are cross-positive on the cone:: - sage: K = random_cone(max_ambient_dim=5) # optional - sage.geometry.polyhedron - sage: R = K.lattice().vector_space().base_ring() # optional - sage.geometry.polyhedron - sage: L = random_matrix(R, K.lattice_dim()) # optional - sage.geometry.polyhedron - sage: actual = L.is_lyapunov_like_on(K) # long time # optional - sage.geometry.polyhedron - sage: expected = (L.is_cross_positive_on(K) and # long time # optional - sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = random_cone(max_ambient_dim=5) + sage: R = K.lattice().vector_space().base_ring() + sage: L = random_matrix(R, K.lattice_dim()) + sage: actual = L.is_lyapunov_like_on(K) # long time + sage: expected = (L.is_cross_positive_on(K) and # long time ....: (-L).is_cross_positive_on(K)) - sage: actual == expected # long time # optional - sage.geometry.polyhedron + sage: actual == expected # long time True """ import sage.geometry.abc @@ -17639,9 +17737,9 @@ cdef class Matrix(Matrix1): Create a Gram matrix and LLL-reduce it:: sage: M = Matrix(ZZ, 2, 2, [5, 3, 3, 2]) - sage: U = M.LLL_gram() # optional - sage.libs.pari - sage: MM = U.transpose() * M * U # optional - sage.libs.pari - sage: M, U, MM # optional - sage.libs.pari + sage: U = M.LLL_gram() # needs sage.libs.pari + sage: MM = U.transpose() * M * U # needs sage.libs.pari + sage: M, U, MM # needs sage.libs.pari ( [5 3] [-1 1] [1 0] [3 2], [ 1 -2], [0 1] @@ -17653,28 +17751,28 @@ cdef class Matrix(Matrix1): preserve orientation). :: sage: M = Matrix(RDF, 2, 2, [1, 0, 0, 1e-5]) - sage: M.LLL_gram() # optional - sage.libs.pari + sage: M.LLL_gram() # needs sage.libs.pari [ 0 -1] [ 1 0] The algorithm might work for some semidefinite and indefinite forms:: - sage: Matrix(ZZ, 2, 2, [2, 6, 6, 3]).LLL_gram() # optional - sage.libs.pari + sage: Matrix(ZZ, 2, 2, [2, 6, 6, 3]).LLL_gram() # needs sage.libs.pari [-3 -1] [ 1 0] - sage: Matrix(ZZ, 2, 2, [1, 0, 0, -1]).LLL_gram() # optional - sage.libs.pari + sage: Matrix(ZZ, 2, 2, [1, 0, 0, -1]).LLL_gram() # needs sage.libs.pari [ 0 -1] [ 1 0] However, it might fail for others, either raising a ``ValueError``:: - sage: Matrix(ZZ, 1, 1, [0]).LLL_gram() # optional - sage.libs.pari + sage: Matrix(ZZ, 1, 1, [0]).LLL_gram() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram did not return a square matrix, perhaps the matrix is not positive definite - sage: Matrix(ZZ, 2, 2, [0, 1, 1, 0]).LLL_gram() # optional - sage.libs.pari + sage: Matrix(ZZ, 2, 2, [0, 1, 1, 0]).LLL_gram() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram did not return a square matrix, @@ -17682,14 +17780,14 @@ cdef class Matrix(Matrix1): or running forever:: - sage: Matrix(ZZ, 2, 2, [-5, -1, -1, -5]).LLL_gram() # not tested # optional - sage.libs.pari + sage: Matrix(ZZ, 2, 2, [-5, -1, -1, -5]).LLL_gram() # not tested, needs sage.libs.pari Traceback (most recent call last): ... RuntimeError: infinite loop while calling qflllgram Nonreal input leads to a value error:: - sage: Matrix(2, 2, [CDF(1, 1), 0, 0, 1]).LLL_gram() # optional - sage.libs.pari + sage: Matrix(2, 2, [CDF(1, 1), 0, 0, 1]).LLL_gram() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: qflllgram failed, perhaps the matrix is not positive definite @@ -17743,10 +17841,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQbar, [[ -3, 5 - 3*I, 7 - 4*I], + sage: A = matrix(QQbar, [[ -3, 5 - 3*I, 7 - 4*I], # needs sage.rings.number_field ....: [7 + 3*I, -1 + 6*I, 3 + 5*I], ....: [3 + 3*I, -3 + 6*I, 5 + I]]) - sage: A.C + sage: A.C # needs sage.rings.number_field [ -3 5 + 3*I 7 + 4*I] [ 7 - 3*I -1 - 6*I 3 - 5*I] [ 3 - 3*I -3 - 6*I 5 - 1*I] @@ -17761,10 +17859,10 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A = matrix(QQbar, [[ -3, 5 - 3*I, 7 - 4*I], + sage: A = matrix(QQbar, [[ -3, 5 - 3*I, 7 - 4*I], # needs sage.rings.number_field ....: [7 + 3*I, -1 + 6*I, 3 + 5*I], ....: [3 + 3*I, -3 + 6*I, 5 + I]]) - sage: A.H + sage: A.H # needs sage.rings.number_field [ -3 7 - 3*I 3 - 3*I] [ 5 + 3*I -1 - 6*I -3 - 6*I] [ 7 + 4*I 3 - 5*I 5 - 1*I] @@ -17785,14 +17883,14 @@ def _smith_diag(d, transformation=True): sage: from sage.matrix.matrix2 import _smith_diag sage: x = polygen(ZZ, 'x') - sage: OE = EquationOrder(x^2 - x + 2, 'w') # optional - sage.rings.number_field - sage: A = matrix(OE, 2, [2, 0, 0, 3]) # optional - sage.rings.number_field - sage: D,U,V = _smith_diag(A); D,U,V # optional - sage.rings.number_field + sage: OE = EquationOrder(x^2 - x + 2, 'w') # needs sage.rings.number_field + sage: A = matrix(OE, 2, [2, 0, 0, 3]) # needs sage.rings.number_field + sage: D,U,V = _smith_diag(A); D,U,V # needs sage.rings.number_field ( [1 0] [2 1] [ 1 -3] [0 6], [3 2], [-1 4] ) - sage: D == U*A*V # optional - sage.rings.number_field + sage: D == U*A*V # needs sage.rings.number_field True sage: m = matrix(GF(7), 2, [3,0,0,6]); d,u,v = _smith_diag(m); d [1 0] @@ -17861,12 +17959,13 @@ def _generic_clear_column(m): EXAMPLES:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: L. = NumberField(x^2 - x + 2) # optional - sage.rings.number_field - sage: OL = L.ring_of_integers(); w = OL(w) # optional - sage.rings.number_field - sage: m = matrix(OL, 8, 4, [2*w - 2, 2*w + 1, -2, w, 2, -2, -2*w - 2, -2*w + 2, -w + 2, 2*w + 1, -w + 2, -w - 2, -2*w, # optional - sage.rings.number_field + sage: L. = NumberField(x^2 - x + 2) + sage: OL = L.ring_of_integers(); w = OL(w) + sage: m = matrix(OL, 8, 4, [2*w - 2, 2*w + 1, -2, w, 2, -2, -2*w - 2, -2*w + 2, -w + 2, 2*w + 1, -w + 2, -w - 2, -2*w, ....: 2*w, -w+ 2, w - 1, -2*w + 2, 2*w + 2, 2*w - 1, -w, 2*w + 2, -w + 2, 2, 2*w -1, w - 4, -2*w - 2, 2*w - 1, 0, 6, 7, 2*w + 1, 14]) - sage: s,t = m.echelon_form(transformation=True); t*m == s # indirect doctest # optional - sage.rings.number_field + sage: s,t = m.echelon_form(transformation=True); t*m == s # indirect doctest True sage: s[0] (w, 0, 0, 0) @@ -17969,15 +18068,16 @@ def _smith_onestep(m): EXAMPLES:: + sage: # needs sage.rings.number_field sage: from sage.matrix.matrix2 import _smith_onestep sage: x = polygen(ZZ, 'x') - sage: OE. = EquationOrder(x^2 - x + 2) # optional - sage.rings.number_field - sage: m = matrix(OE, 3, 3, [1, 0, 7, 2, w, w+17, 13+8*w, 0, 6]) # optional - sage.rings.number_field - sage: a,b,c = _smith_onestep(m); b # optional - sage.rings.number_field + sage: OE. = EquationOrder(x^2 - x + 2) + sage: m = matrix(OE, 3, 3, [1, 0, 7, 2, w, w+17, 13+8*w, 0, 6]) + sage: a,b,c = _smith_onestep(m); b [ 1 0 0] [ 0 w w + 3] [ 0 0 -56*w - 85] - sage: a * m * c == b # optional - sage.rings.number_field + sage: a * m * c == b True """ @@ -18177,27 +18277,27 @@ def _matrix_power_symbolic(A, n): General power of a two by two matrix:: - sage: n = SR.var('n') # optional - sage.symbolic + sage: n = SR.var('n') # needs sage.symbolic sage: A = matrix(QQ, [[2, -1], [1, 0]]) - sage: B = A^n; B # optional - sage.symbolic + sage: B = A^n; B # needs sage.symbolic [ n + 1 -n] [ n -n + 1] - sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic + sage: all(A^k == B.subs({n: k}) for k in range(8)) # needs sage.symbolic True General power of a three by three matrix in Jordan form:: - sage: n = SR.var('n') # optional - sage.symbolic + sage: n = SR.var('n') # needs sage.symbolic sage: A = matrix(QQ, 3, [[2, 1, 0], [0, 2, 0], [0, 0, 3]]) sage: A [2 1 0] [0 2 0] [0 0 3] - sage: B = A^n; B # optional - sage.symbolic + sage: B = A^n; B # needs sage.symbolic [ 2^n 2^(n - 1)*n 0] [ 0 2^n 0] [ 0 0 3^n] - sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic + sage: all(A^k == B.subs({n: k}) for k in range(8)) # needs sage.symbolic True General power of a three by three matrix not in Jordan form:: @@ -18207,26 +18307,26 @@ def _matrix_power_symbolic(A, n): [ 4 1 2] [ 0 2 -4] [ 0 1 6] - sage: B = A^n; B # optional - sage.symbolic + sage: B = A^n; B # needs sage.symbolic [ 4^n 4^(n - 1)*n 2*4^(n - 1)*n] [ 0 -2*4^(n - 1)*n + 4^n -4*4^(n - 1)*n] [ 0 4^(n - 1)*n 2*4^(n - 1)*n + 4^n] - sage: [B.subs({n: k}) for k in range(4)] # optional - sage.symbolic + sage: [B.subs({n: k}) for k in range(4)] # needs sage.symbolic [ [1 0 0] [ 4 1 2] [ 16 8 16] [ 64 48 96] [0 1 0] [ 0 2 -4] [ 0 0 -32] [ 0 -32 -192] [0 0 1], [ 0 1 6], [ 0 8 32], [ 0 48 160] ] - sage: all(A^k == B.subs({n: k}) for k in range(8)) # optional - sage.symbolic + sage: all(A^k == B.subs({n: k}) for k in range(8)) # needs sage.symbolic True TESTS: Testing exponentiation in the symbolic ring:: - sage: n = var('n') # optional - sage.symbolic - sage: A = matrix([[pi, e],[0, -2*I]]) # optional - sage.symbolic - sage: (A^n).list() # optional - sage.symbolic + sage: n = var('n') # needs sage.symbolic + sage: A = matrix([[pi, e],[0, -2*I]]) # needs sage.symbolic + sage: (A^n).list() # needs sage.symbolic [pi^n, -(-2*I)^n/(pi*e^(-1) + 2*I*e^(-1)) + pi^n/(pi*e^(-1) + 2*I*e^(-1)), 0, @@ -18235,7 +18335,7 @@ def _matrix_power_symbolic(A, n): If the base ring is inexact, the Jordan normal form is not available:: sage: A = matrix(RDF, [[2, -1], [1, 0]]) - sage: A^n # optional - sage.symbolic + sage: A^n # needs sage.symbolic Traceback (most recent call last): ... ValueError: Jordan normal form not implemented over inexact rings. @@ -18243,14 +18343,14 @@ def _matrix_power_symbolic(A, n): Testing exponentiation in the integer ring:: sage: A = matrix(ZZ, [[1,-1], [-1,1]]) - sage: A^(2*n+1) # optional - sage.symbolic + sage: A^(2*n+1) # needs sage.symbolic [ 1/2*2^(2*n + 1) -1/2*2^(2*n + 1)] [-1/2*2^(2*n + 1) 1/2*2^(2*n + 1)] Check if :trac:`23215` is fixed:: - sage: a, b, k = var('a, b, k') # optional - sage.symbolic - sage: (matrix(2, [a, b, -b, a])^k).list() # optional - sage.symbolic + sage: a, b, k = var('a, b, k') # needs sage.symbolic + sage: (matrix(2, [a, b, -b, a])^k).list() # needs sage.symbolic [1/2*(a + I*b)^k + 1/2*(a - I*b)^k, -1/2*I*(a + I*b)^k + 1/2*I*(a - I*b)^k, 1/2*I*(a + I*b)^k - 1/2*I*(a - I*b)^k, diff --git a/src/sage/matrix/matrix_cdv.pyx b/src/sage/matrix/matrix_cdv.pyx index c67936f6e4c..dfbdb053328 100644 --- a/src/sage/matrix/matrix_cdv.pyx +++ b/src/sage/matrix/matrix_cdv.pyx @@ -35,31 +35,32 @@ cpdef hessenbergize_cdvf(Matrix_generic_dense H): TESTS:: - sage: K = Qp(5, print_mode="digits", prec=5) # optional - sage.rings.padics - sage: H = matrix(K, 3, 3, range(9)) # optional - sage.rings.padics - sage: H # optional - sage.rings.padics + sage: # needs sage.rings.padics + sage: K = Qp(5, print_mode="digits", prec=5) + sage: H = matrix(K, 3, 3, range(9)) + sage: H [ 0 ...00001 ...00002] [ ...00003 ...00004 ...000010] [ ...00011 ...00012 ...00013] - sage: H.hessenbergize() # optional - sage.rings.padics - sage: H # optional - sage.rings.padics + sage: H.hessenbergize() + sage: H [ 0 ...00010 ...00002] [ ...00003 ...00024 ...000010] [ ...00000 ...44440 ...44443] :: - sage: M = random_matrix(K, 6, 6) # optional - sage.rings.padics - sage: M.charpoly()[0] == M.determinant() # optional - sage.rings.padics + sage: M = random_matrix(K, 6, 6) # needs sage.rings.padics + sage: M.charpoly()[0] == M.determinant() # needs sage.rings.padics True We check that :trac:`31753` is resolved:: - sage: R. = GF(5)[[]] # optional - sage.libs.pari - sage: M = matrix(3, 3, [ 1, t + O(t^3), t^2, # optional - sage.libs.pari + sage: R. = GF(5)[[]] + sage: M = matrix(3, 3, [ 1, t + O(t^3), t^2, ....: 1 + t + O(t^3), 2 + t^2, 3 + 2*t + O(t^3), ....: t - t^2, 2*t, 1 + t ]) - sage: M.charpoly() # optional - sage.libs.pari + sage: M.charpoly() x^3 + (1 + 4*t + 4*t^2 + O(t^3))*x^2 + (t + 2*t^2 + O(t^3))*x + 3 + 2*t^2 + O(t^3) """ cdef Py_ssize_t n, i, j, k diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index 17ec254070b..9e14079c6d4 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -945,7 +945,7 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): EXAMPLES:: - sage: matrix(CBF, [[i*pi, 1], [0, i*pi]]).exp() # optional - sage.symbolic + sage: matrix(CBF, [[i*pi, 1], [0, i*pi]]).exp() # needs sage.symbolic [[-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I [-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I] [ 0 [-1.00000000000000 +/- ...e-16] + [+/- ...e-16]*I] sage: matrix(CBF, [[1/2, 1/3]]).exp() diff --git a/src/sage/matrix/matrix_dense.pyx b/src/sage/matrix/matrix_dense.pyx index e76047c2f0a..0f5089b5122 100644 --- a/src/sage/matrix/matrix_dense.pyx +++ b/src/sage/matrix/matrix_dense.pyx @@ -74,11 +74,12 @@ cdef class Matrix_dense(matrix.Matrix): Check :trac:`27629`:: - sage: var('x') # optional - sage.symbolic + sage: # needs sage.symbolic + sage: var('x') x - sage: assume(x, 'real') # optional - sage.symbolic - sage: M = matrix([[0, -x], [x, 0]]) # optional - sage.symbolic - sage: M.transpose() == M # optional - sage.symbolic + sage: assume(x, 'real') + sage: M = matrix([[0, -x], [x, 0]]) + sage: M.transpose() == M False """ other = right @@ -270,8 +271,8 @@ cdef class Matrix_dense(matrix.Matrix): EXAMPLES:: - sage: m = matrix(2, [x^i for i in range(4)]) # optional - sage.symbolic - sage: m._derivative(x) # optional - sage.symbolic + sage: m = matrix(2, [x^i for i in range(4)]) # needs sage.symbolic + sage: m._derivative(x) # needs sage.symbolic [ 0 1] [ 2*x 3*x^2] """ diff --git a/src/sage/matrix/matrix_generic_dense.pyx b/src/sage/matrix/matrix_generic_dense.pyx index 2057b6b1460..cdf77388e25 100644 --- a/src/sage/matrix/matrix_generic_dense.pyx +++ b/src/sage/matrix/matrix_generic_dense.pyx @@ -70,11 +70,11 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): more:: sage: S. = PolynomialRing(QQ) - sage: F. = QQ.extension(t^4 + 1) # optional - sage.rings.number_field - sage: R. = PolynomialRing(F) # optional - sage.rings.number_field - sage: M = MatrixSpace(R, 1, 2) # optional - sage.rings.number_field + sage: F. = QQ.extension(t^4 + 1) # needs sage.rings.number_field + sage: R. = PolynomialRing(F) # needs sage.rings.number_field + sage: M = MatrixSpace(R, 1, 2) # needs sage.rings.number_field sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense - sage: Matrix_generic_dense(M, (x, y), True, True) # optional - sage.rings.number_field + sage: Matrix_generic_dense(M, (x, y), True, True) # needs sage.rings.number_field [x y] """ ma = MatrixArgs_init(parent, entries) @@ -214,10 +214,11 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): EXAMPLES:: - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat - sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) # optional - sage.combinat - sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) # optional - sage.combinat - sage: a._add_(b) # optional - sage.combinat + sage: # needs sage.combinat + sage: R. = FreeAlgebra(QQ, 2) + sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) + sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) + sage: a._add_(b) [ 2 4] [x*y + y*x 2*y*x] """ @@ -237,10 +238,11 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): EXAMPLES:: - sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat - sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) # optional - sage.combinat - sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) # optional - sage.combinat - sage: a._sub_(b) # optional - sage.combinat + sage: # needs sage.combinat + sage: R. = FreeAlgebra(QQ, 2) + sage: a = matrix(R, 2, 2, [1,2,x*y,y*x]) + sage: b = matrix(R, 2, 2, [1,2,y*x,y*x]) + sage: a._sub_(b) [ 0 0] [x*y - y*x 0] """ diff --git a/src/sage/matrix/matrix_generic_sparse.pyx b/src/sage/matrix/matrix_generic_sparse.pyx index 0a2f8f52cc9..4cd7cecc7e8 100644 --- a/src/sage/matrix/matrix_generic_sparse.pyx +++ b/src/sage/matrix/matrix_generic_sparse.pyx @@ -16,7 +16,7 @@ EXAMPLES:: sage: a * b.transpose() [ 2*x^2 + x 2*x^5 + x^4] [ 5*x^2 + 4*x + 3 5*x^5 + 4*x^4 + 3*x^3] - sage: pari(a)*pari(b.transpose()) # optional - sage.libs.pari + sage: pari(a)*pari(b.transpose()) # needs sage.libs.pari [2*x^2 + x, 2*x^5 + x^4; 5*x^2 + 4*x + 3, 5*x^5 + 4*x^4 + 3*x^3] sage: c = copy(b); c [ 1 x x^2] diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index ca3382859f5..6db1a5a0411 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -462,7 +462,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): TESTS:: sage: import gc - sage: for i in range(10): + sage: for i in range(10): # needs sage.libs.pari ....: A = random_matrix(GF(7),1000,1000) ....: B = random_matrix(Integers(10),1000,1000) ....: C = random_matrix(GF(16007),1000,1000) @@ -508,11 +508,11 @@ cdef class Matrix_modn_dense_template(Matrix_dense): [6 5] [4 2] - sage: Matrix(GF(6434383), 2, 2, [-1, int(-2), GF(7)(-3), 1/4]) + sage: Matrix(GF(6434383), 2, 2, [-1, int(-2), GF(7)(-3), 1/4]) # needs sage.libs.pari [6434382 6434381] [ 4 1608596] - sage: Matrix(Integers(4618990), 2, 2, [-1, int(-2), GF(7)(-3), 1/7]) + sage: Matrix(Integers(4618990), 2, 2, [-1, int(-2), GF(7)(-3), 1/7]) # needs sage.rings.finite_rings [4618989 4618988] [ 4 2639423] """ @@ -668,7 +668,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): And for larger modulus:: - sage: A = random_matrix(GF(1009), 51, 5) + sage: A = random_matrix(GF(1009), 51, 5) # needs sage.libs.pari sage: data, version = A._pickle() sage: B = A.parent()(0) sage: B._unpickle(data, version) @@ -963,11 +963,11 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: A = matrix(ZZ, 10, 10, range(1000, 1100)) sage: A.change_ring(GF(17)) == A.change_ring(GF(17)) True - sage: A.change_ring(GF(17)) == A.change_ring(GF(19)) + sage: A.change_ring(GF(17)) == A.change_ring(GF(19)) # needs sage.rings.finite_rings False - sage: A.change_ring(GF(17)) == A.change_ring(Integers(2000)) + sage: A.change_ring(GF(17)) == A.change_ring(Integers(2000)) # needs sage.rings.finite_rings False - sage: A.change_ring(GF(17)) == A.change_ring(Integers(2000)) + sage: A.change_ring(GF(17)) == A.change_ring(Integers(2000)) # needs sage.rings.finite_rings False """ cdef Py_ssize_t i @@ -1061,8 +1061,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(16007),2,2) - sage: B = random_matrix(GF(16007),2,2) + sage: A = random_matrix(GF(16007),2,2) # needs sage.libs.pari + sage: B = random_matrix(GF(16007),2,2) # needs sage.libs.pari sage: C = A*B sage: all(C[i, j] == sum(A[i, k]*B[k, j] for k in range(2)) for i in range(2) for j in range(2)) True @@ -1073,6 +1073,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: + sage: # needs sage.libs.pari sage: A = random_matrix(GF(15991), 201, 117) sage: B = random_matrix(GF(15991), 117, 195) sage: C = random_matrix(GF(15991), 201, 117) @@ -1087,7 +1088,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(16007), 200, 200) + sage: A = random_matrix(GF(16007), 200, 200) # needs sage.libs.pari sage: MS = parent(A) sage: (MS(0) * A) == 0 True @@ -1160,13 +1161,13 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: matrix(v*A) == matrix(v)*A True - sage: A = random_matrix(GF(4796509), 10, 20) - sage: v = random_vector(GF(4796509), 10) + sage: A = random_matrix(GF(4796509), 10, 20) # needs sage.libs.pari + sage: v = random_vector(GF(4796509), 10) # needs sage.libs.pari sage: matrix(v*A) == matrix(v)*A True sage: A = random_matrix(Integers(16337), 10, 20) - sage: v = random_vector(Integers(16337), 10) + sage: v = random_vector(Integers(16337), 10) # needs sage.libs.pari sage: matrix(v*A) == matrix(v)*A True @@ -1213,13 +1214,13 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: matrix(A*v).transpose() == A*matrix(v).transpose() True - sage: A = random_matrix(GF(4796509), 10, 20) - sage: v = random_vector(GF(4796509), 20) + sage: A = random_matrix(GF(4796509), 10, 20) # needs sage.libs.pari + sage: v = random_vector(GF(4796509), 20) # needs sage.libs.pari sage: matrix(A*v).transpose() == A*matrix(v).transpose() True sage: A = random_matrix(Integers(16337), 10, 20) - sage: v = random_vector(Integers(16337), 20) + sage: v = random_vector(Integers(16337), 20) # needs sage.libs.pari sage: matrix(A*v).transpose() == A*matrix(v).transpose() True """ @@ -1289,7 +1290,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(2916337), 7, 7) + sage: A = random_matrix(GF(2916337), 7, 7) # needs sage.libs.pari sage: B = copy(A) sage: char_p = A.characteristic_polynomial() sage: char_p(A) == 0 @@ -1328,27 +1329,27 @@ cdef class Matrix_modn_dense_template(Matrix_dense): ValueError: matrix must be square sage: A = matrix(GF(19), 10, 10) - sage: A.minimal_polynomial() + sage: A.minimal_polynomial() # needs sage.libs.pari x - sage: A = random_matrix(GF(4198973), 0, 0) - sage: A.minimal_polynomial() + sage: A = random_matrix(GF(4198973), 0, 0) # needs sage.libs.pari + sage: A.minimal_polynomial() # needs sage.libs.pari 1 - sage: A = random_matrix(GF(4198973), 0, 1) - sage: A.minimal_polynomial() + sage: A = random_matrix(GF(4198973), 0, 1) # needs sage.libs.pari + sage: A.minimal_polynomial() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: matrix must be square - sage: A = random_matrix(GF(4198973), 1, 0) - sage: A.minimal_polynomial() + sage: A = random_matrix(GF(4198973), 1, 0) # needs sage.libs.pari + sage: A.minimal_polynomial() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: matrix must be square - sage: A = matrix(GF(4198973), 10, 10) - sage: A.minimal_polynomial() + sage: A = matrix(GF(4198973), 10, 10) # needs sage.libs.pari + sage: A.minimal_polynomial() # needs sage.libs.pari x sage: A = Mat(GF(7),3,3)([0, 1, 2] * 3) @@ -1443,7 +1444,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(1214471), 10, 10) + sage: A = random_matrix(GF(1214471), 10, 10) # needs sage.libs.pari sage: B = copy(A) sage: min_p = A.minimal_polynomial(proof=True) sage: min_p(A) == 0 @@ -1474,29 +1475,29 @@ cdef class Matrix_modn_dense_template(Matrix_dense): ValueError: matrix must be square sage: A = matrix(GF(17), 10, 10) - sage: A.minimal_polynomial() + sage: A.minimal_polynomial() # needs sage.libs.pari x :: - sage: A = random_matrix(GF(2535919), 0, 0) - sage: A.minimal_polynomial() + sage: A = random_matrix(GF(2535919), 0, 0) # needs sage.libs.pari + sage: A.minimal_polynomial() # needs sage.libs.pari 1 - sage: A = random_matrix(GF(2535919), 0, 1) - sage: A.minimal_polynomial() + sage: A = random_matrix(GF(2535919), 0, 1) # needs sage.libs.pari + sage: A.minimal_polynomial() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: matrix must be square - sage: A = random_matrix(GF(2535919), 1, 0) - sage: A.minimal_polynomial() + sage: A = random_matrix(GF(2535919), 1, 0) # needs sage.libs.pari + sage: A.minimal_polynomial() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: matrix must be square - sage: A = matrix(GF(2535919), 10, 10) - sage: A.minimal_polynomial() + sage: A = matrix(GF(2535919), 10, 10) # needs sage.libs.pari + sage: A.minimal_polynomial() # needs sage.libs.pari x EXAMPLES:: @@ -1639,7 +1640,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(16007), 10, 20) + sage: A = random_matrix(GF(16007), 10, 20) # needs sage.libs.pari sage: E = A.echelon_form() sage: A.row_space() == E.row_space() True @@ -1656,7 +1657,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): Parallel computation:: - sage: A = random_matrix(GF(65521),100,200) + sage: A = random_matrix(GF(65521),100,200) # needs sage.libs.pari sage: Parallelism().set('linbox', nproc=2) sage: E = A.echelon_form() sage: Parallelism().set('linbox', nproc=1) # switch off parallelization @@ -1687,16 +1688,16 @@ cdef class Matrix_modn_dense_template(Matrix_dense): [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] - sage: A = random_matrix(GF(16007), 0, 10) + sage: A = random_matrix(GF(16007), 0, 10) # needs sage.libs.pari sage: A.echelon_form() [] - sage: A = random_matrix(GF(16007), 10, 0) + sage: A = random_matrix(GF(16007), 10, 0) # needs sage.libs.pari sage: A.echelon_form() [] - sage: A = random_matrix(GF(16007), 0, 0) + sage: A = random_matrix(GF(16007), 0, 0) # needs sage.libs.pari sage: A.echelon_form() [] - sage: A = matrix(GF(16007), 10, 10) + sage: A = matrix(GF(16007), 10, 10) # needs sage.libs.pari sage: A.echelon_form() [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] @@ -2126,7 +2127,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(16007), 100, 100) + sage: A = random_matrix(GF(16007), 100, 100) # needs sage.libs.pari sage: B = copy(A) sage: A.rank() 100 @@ -2147,13 +2148,13 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: A = random_matrix(GF(7), 0, 1) sage: A.rank() 0 - sage: A = random_matrix(GF(16007), 0, 0) + sage: A = random_matrix(GF(16007), 0, 0) # needs sage.libs.pari sage: A.rank() 0 - sage: A = random_matrix(GF(16007), 1, 0) + sage: A = random_matrix(GF(16007), 1, 0) # needs sage.libs.pari sage: A.rank() 0 - sage: A = random_matrix(GF(16007), 0, 1) + sage: A = random_matrix(GF(16007), 0, 1) # needs sage.libs.pari sage: A.rank() 0 """ @@ -2177,49 +2178,49 @@ cdef class Matrix_modn_dense_template(Matrix_dense): EXAMPLES:: sage: s = set() - sage: while s != set(GF(7)): + sage: while s != set(GF(7)): # needs sage.libs.pari ....: A = random_matrix(GF(7), 10, 10) ....: s.add(A.determinant()) :: sage: A = random_matrix(GF(7), 100, 100) - sage: A.determinant() == A.transpose().determinant() + sage: A.determinant() == A.transpose().determinant() # needs sage.libs.pari True sage: B = random_matrix(GF(7), 100, 100) - sage: (A*B).determinant() == A.determinant() * B.determinant() + sage: (A*B).determinant() == A.determinant() * B.determinant() # needs sage.libs.pari True :: - sage: A = random_matrix(GF(16007), 10, 10) - sage: A.determinant().parent() is GF(16007) + sage: A = random_matrix(GF(16007), 10, 10) # needs sage.libs.pari + sage: A.determinant().parent() is GF(16007) # needs sage.libs.pari True :: - sage: A = random_matrix(GF(16007), 100, 100) - sage: A.determinant().parent() is GF(16007) + sage: A = random_matrix(GF(16007), 100, 100) # needs sage.libs.pari + sage: A.determinant().parent() is GF(16007) # needs sage.libs.pari True - sage: A.determinant() == A.transpose().determinant() + sage: A.determinant() == A.transpose().determinant() # needs sage.libs.pari True - sage: B = random_matrix(GF(16007), 100, 100) - sage: (A*B).determinant() == A.determinant() * B.determinant() + sage: B = random_matrix(GF(16007), 100, 100) # needs sage.libs.pari + sage: (A*B).determinant() == A.determinant() * B.determinant() # needs sage.libs.pari True Parallel computation:: - sage: A = random_matrix(GF(65521),200) + sage: A = random_matrix(GF(65521),200) # needs sage.libs.pari sage: B = copy(A) sage: Parallelism().set('linbox', nproc=2) - sage: d = A.determinant() + sage: d = A.determinant() # needs sage.libs.pari sage: Parallelism().set('linbox', nproc=1) # switch off parallelization - sage: e = B.determinant() - sage: d==e + sage: e = B.determinant() # needs sage.libs.pari + sage: d==e # needs sage.libs.pari True TESTS:: @@ -2237,23 +2238,23 @@ cdef class Matrix_modn_dense_template(Matrix_dense): ... ValueError: self must be a square matrix - sage: A = matrix(GF(7), 5, 5); A.det() + sage: A = matrix(GF(7), 5, 5); A.det() # needs sage.libs.pari 0 - sage: A = random_matrix(GF(16007), 0, 0); A.det() + sage: A = random_matrix(GF(16007), 0, 0); A.det() # needs sage.libs.pari 1 - sage: A = random_matrix(GF(16007), 0, 1); A.det() + sage: A = random_matrix(GF(16007), 0, 1); A.det() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: self must be a square matrix - sage: A = random_matrix(GF(16007), 1, 0); A.det() + sage: A = random_matrix(GF(16007), 1, 0); A.det() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: self must be a square matrix - sage: A = matrix(GF(16007), 5, 5); A.det() + sage: A = matrix(GF(16007), 5, 5); A.det() # needs sage.libs.pari 0 """ if self._nrows != self._ncols: @@ -2738,7 +2739,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: A.lift().parent() Full MatrixSpace of 2 by 3 dense matrices over Integer Ring - sage: A = matrix(GF(16007),2,3,[1..6]) + sage: A = matrix(GF(16007),2,3,[1..6]) # needs sage.libs.pari sage: A.lift() [1 2 3] [4 5 6] @@ -3081,15 +3082,15 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: bool(A) False - sage: A = matrix(GF(16007), 0, 0) + sage: A = matrix(GF(16007), 0, 0) # needs sage.libs.pari sage: A.is_zero() True - sage: A = matrix(GF(16007), 1, 0) + sage: A = matrix(GF(16007), 1, 0) # needs sage.libs.pari sage: A.is_zero() True - sage: A = matrix(GF(16007), 0, 1) + sage: A = matrix(GF(16007), 0, 1) # needs sage.libs.pari sage: A.is_zero() True """ @@ -3109,8 +3110,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): EXAMPLES:: - sage: M = Matrix(GF(49), 2, [1,2,-2,0]) - sage: M.zero_pattern_matrix() # indirect doctest + sage: M = Matrix(GF(49), 2, [1,2,-2,0]) # needs sage.libs.pari + sage: M.zero_pattern_matrix() # indirect doctest # needs sage.libs.pari [0 0] [0 1] diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 3c672f0be13..22bde66b787 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -113,11 +113,11 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari - sage: M._check_shift_dimension(shifts=[1,3,2]) # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) + sage: M._check_shift_dimension(shifts=[1,3,2]) - sage: M._check_shift_dimension(shifts=[1,3,2], row_wise=False) # optional - sage.libs.pari + sage: M._check_shift_dimension(shifts=[1,3,2], row_wise=False) Traceback (most recent call last): ... ValueError: shifts length should be the row dimension @@ -139,21 +139,21 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari - sage: M.degree() # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) + sage: M.degree() 3 The zero matrix has degree ``-1``:: - sage: M = Matrix(pR, 2, 3) # optional - sage.libs.pari - sage: M.degree() # optional - sage.libs.pari + sage: M = Matrix(pR, 2, 3) + sage: M.degree() -1 For an empty matrix, the degree is not defined:: - sage: M = Matrix(pR, 3, 0) # optional - sage.libs.pari - sage: M.degree() # optional - sage.libs.pari + sage: M = Matrix(pR, 3, 0) + sage: M.degree() Traceback (most recent call last): ... ValueError: empty matrix does not have a degree @@ -193,20 +193,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari - sage: M.degree_matrix() # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) + sage: M.degree_matrix() [ 1 -1 0] [ 3 -1 -1] - sage: M.degree_matrix(shifts=[0,1,2]) # optional - sage.libs.pari + sage: M.degree_matrix(shifts=[0,1,2]) [ 1 -1 2] [ 3 -1 -1] The zero entries in the polynomial matrix can be identified in the (shifted) degree matrix as the entries equal to ``min(shifts)-1``:: - sage: M.degree_matrix(shifts=[-2,1,2]) # optional - sage.libs.pari + sage: M.degree_matrix(shifts=[-2,1,2]) [-1 -3 2] [ 1 -3 -3] @@ -214,7 +214,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): rows of the matrix (which, in terms of modules, means that we are working column-wise, see the class documentation):: - sage: M.degree_matrix(shifts=[-1,2], row_wise=False) # optional - sage.libs.pari + sage: M.degree_matrix(shifts=[-1,2], row_wise=False) [ 0 -2 -1] [ 5 -2 -2] """ @@ -241,14 +241,14 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pR. = GF(7)[] - sage: M = Matrix([ # optional - sage.libs.pari + sage: M = Matrix([ ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.constant_matrix() # optional - sage.libs.pari + sage: M.constant_matrix() [1 5 4 0] [1 1 2 0] [4 1 5 6] @@ -266,18 +266,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pR. = GF(7)[] - sage: M = Matrix([ # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: M = Matrix([ ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.is_constant() # optional - sage.libs.pari + sage: M.is_constant() False - sage: M = Matrix(pR, [[1,5,2], [3,1,5]]); M.is_constant() # optional - sage.libs.pari + sage: M = Matrix(pR, [[1,5,2], [3,1,5]]); M.is_constant() True - sage: M = Matrix.zero(pR, 3, 5); M.is_constant() # optional - sage.libs.pari + sage: M = Matrix.zero(pR, 3, 5); M.is_constant() True .. SEEALSO:: @@ -313,48 +314,48 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pR. = GF(7)[] - sage: M = Matrix([ # optional - sage.libs.pari + sage: M = Matrix([ ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.coefficient_matrix(2) # optional - sage.libs.pari + sage: M.coefficient_matrix(2) [5 0 0 0] [6 0 0 0] [4 0 2 1] - sage: M.coefficient_matrix(0) == M.constant_matrix() # optional - sage.libs.pari + sage: M.coefficient_matrix(0) == M.constant_matrix() True Row-wise and column-wise coefficient extraction are available:: - sage: M.coefficient_matrix([3,2,1]) # optional - sage.libs.pari + sage: M.coefficient_matrix([3,2,1]) [1 0 0 0] [6 0 0 0] [6 5 5 5] - sage: M.coefficient_matrix([2,0,1,3], row_wise=False) # optional - sage.libs.pari + sage: M.coefficient_matrix([2,0,1,3], row_wise=False) [5 5 6 0] [6 1 0 0] [4 1 5 0] Negative degrees give zero coefficients:: - sage: M.coefficient_matrix([-1,0,1,3], row_wise=False) # optional - sage.libs.pari + sage: M.coefficient_matrix([-1,0,1,3], row_wise=False) [0 5 6 0] [0 1 0 0] [0 1 5 0] Length of list of degrees is checked:: - sage: M.coefficient_matrix([2,1,1,2]) # optional - sage.libs.pari + sage: M.coefficient_matrix([2,1,1,2]) Traceback (most recent call last): ... ValueError: length of input degree list should be the row dimension of the input matrix - sage: M.coefficient_matrix([3,2,1], row_wise=False) # optional - sage.libs.pari + sage: M.coefficient_matrix([3,2,1], row_wise=False) Traceback (most recent call last): ... ValueError: length of input degree list should be the column @@ -409,41 +410,41 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pR. = GF(7)[] - sage: M = Matrix([ # optional - sage.libs.pari + sage: M = Matrix([ ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.truncate(2) # optional - sage.libs.pari + sage: M.truncate(2) [5*x + 1 5 6*x + 4 0] [3*x + 1 1 2 0] [6*x + 4 5*x + 1 5*x + 5 5*x + 6] - sage: M.truncate(1) == M.constant_matrix() # optional - sage.libs.pari + sage: M.truncate(1) == M.constant_matrix() True Row-wise and column-wise truncation are available:: - sage: M.truncate([3,2,1]) # optional - sage.libs.pari + sage: M.truncate([3,2,1]) [5*x^2 + 5*x + 1 5 6*x + 4 0] [ 3*x + 1 1 2 0] [ 4 1 5 6] - sage: M.truncate([2,1,1,2], row_wise=False) # optional - sage.libs.pari + sage: M.truncate([2,1,1,2], row_wise=False) [5*x + 1 5 4 0] [3*x + 1 1 2 0] [6*x + 4 1 5 5*x + 6] Length of list of truncation orders is checked:: - sage: M.truncate([2,1,1,2]) # optional - sage.libs.pari + sage: M.truncate([2,1,1,2]) Traceback (most recent call last): ... ValueError: length of input precision list should be the row dimension of the input matrix - sage: M.truncate([3,2,1], row_wise=False) # optional - sage.libs.pari + sage: M.truncate([3,2,1], row_wise=False) Traceback (most recent call last): ... ValueError: length of input precision list should be the column @@ -500,42 +501,42 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pR. = GF(7)[] - sage: M = Matrix([ # optional - sage.libs.pari + sage: M = Matrix([ ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.shift(-2) # optional - sage.libs.pari + sage: M.shift(-2) [ x + 5 0 0 0] [ 6 0 0 0] [2*x + 4 0 2 1] Row-wise and column-wise shifting are available:: - sage: M.shift([-1,2,-2]) # optional - sage.libs.pari + sage: M.shift([-1,2,-2]) [ x^2 + 5*x + 5 0 6 0] [6*x^4 + 3*x^3 + x^2 x^2 2*x^2 0] [ 2*x + 4 0 2 1] - sage: M.shift([-1,1,0,0], row_wise=False) # optional - sage.libs.pari + sage: M.shift([-1,1,0,0], row_wise=False) [ x^2 + 5*x + 5 5*x 6*x + 4 0] [ 6*x + 3 x 2 0] [2*x^2 + 4*x + 6 5*x^2 + x 2*x^2 + 5*x + 5 x^2 + 5*x + 6] - sage: M.shift([-d for d in M.row_degrees()]) == M.leading_matrix() # optional - sage.libs.pari + sage: M.shift([-d for d in M.row_degrees()]) == M.leading_matrix() True Length of input shift degree list is checked:: - sage: M.shift([1,3,1,4]) # optional - sage.libs.pari + sage: M.shift([1,3,1,4]) Traceback (most recent call last): ... ValueError: length of input shift list should be the row dimension of the input matrix - sage: M.shift([5,2,-1], row_wise=False) # optional - sage.libs.pari + sage: M.shift([5,2,-1], row_wise=False) Traceback (most recent call last): ... ValueError: length of input shift list should be the column @@ -608,14 +609,14 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pR. = GF(7)[] - sage: M = Matrix([ # optional - sage.libs.pari + sage: M = Matrix([ ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.reverse() # optional - sage.libs.pari + sage: M.reverse() [ x^3 + 5*x^2 + 5*x + 1 5*x^3 4*x^3 + 6*x^2 0] [ x^3 + 3*x^2 + 6*x x^3 @@ -623,17 +624,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [4*x^3 + 6*x^2 + 4*x + 2 x^3 + 5*x^2 5*x^3 + 5*x^2 + 2*x 6*x^3 + 5*x^2 + x] - sage: M.reverse(1) # optional - sage.libs.pari + sage: M.reverse(1) [ x + 5 5*x 4*x + 6 0] [ x + 3 x 2*x 0] [4*x + 6 x + 5 5*x + 5 6*x + 5] - sage: M.reverse(0) == M.constant_matrix() # optional - sage.libs.pari + sage: M.reverse(0) == M.constant_matrix() True Entry-wise reversing with respect to each entry's degree:: - sage: M.reverse(entry_wise=True) # optional - sage.libs.pari + sage: M.reverse(entry_wise=True) [ x^3 + 5*x^2 + 5*x + 1 5 4*x + 6 0] [ x^2 + 3*x + 6 1 @@ -643,7 +644,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Row-wise and column-wise degree reversing are available:: - sage: M.reverse([2,3,1]) # optional - sage.libs.pari + sage: M.reverse([2,3,1]) [ x^2 + 5*x + 5 5*x^2 4*x^2 + 6*x 0] [x^3 + 3*x^2 + 6*x x^3 2*x^3 @@ -651,7 +652,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 6 x + 5 5*x + 5 6*x + 5] - sage: M.reverse(M.column_degrees(), row_wise=False) # optional - sage.libs.pari + sage: M.reverse(M.column_degrees(), row_wise=False) [ x^3 + 5*x^2 + 5*x + 1 5*x 4*x^2 + 6*x 0] [ x^3 + 3*x^2 + 6*x x @@ -661,19 +662,19 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Wrong length or negativity of input degree raise errors: - sage: M.reverse([1,3,1,4]) # optional - sage.libs.pari + sage: M.reverse([1,3,1,4]) Traceback (most recent call last): ... ValueError: length of input degree list should be the row dimension of the input matrix - sage: M.reverse([5,2,1], row_wise=False) # optional - sage.libs.pari + sage: M.reverse([5,2,1], row_wise=False) Traceback (most recent call last): ... ValueError: length of input degree list should be the column dimension of the input matrix - sage: M.reverse([2,3,-1]) # optional - sage.libs.pari + sage: M.reverse([2,3,-1]) Traceback (most recent call last): ... OverflowError: can't convert negative value to unsigned long @@ -742,30 +743,31 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: A = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: pR. = GF(7)[] + sage: A = Matrix(pR, 3, 3, ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: B = A.inverse_series_trunc(4); B # optional - sage.libs.pari + sage: B = A.inverse_series_trunc(4); B [ x^3 + 5*x^2 + x + 4 x^3 + 5*x^2 + 6*x + 4 6*x^2 + 5*x + 3] [ 4*x^2 + 5*x + 6 6*x^3 + x^2 + x + 6 3*x^3 + 2*x^2 + 2] [5*x^3 + 5*x^2 + 6*x + 6 4*x^3 + 2*x^2 + 6*x + 4 6*x^3 + x^2 + 6*x + 1] - sage: (B*A).truncate(4) == 1 # optional - sage.libs.pari + sage: (B*A).truncate(4) == 1 True - sage: A.inverse_series_trunc(0) # optional - sage.libs.pari + sage: A.inverse_series_trunc(0) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: the precision must be positive - sage: A[:2,:].inverse_series_trunc(4) # optional - sage.libs.pari + sage: A[:2,:].inverse_series_trunc(4) # needs sage.rings.finite_rings Traceback (most recent call last): ... ArithmeticError: the input matrix must be square - sage: A[0,:] = A[0,:] - A[0,:](0) + A[1,:](0) + A[2,:](0) # optional - sage.libs.pari - sage: A.inverse_series_trunc(4) # optional - sage.libs.pari + sage: A[0,:] = A[0,:] - A[0,:](0) + A[1,:](0) + A[2,:](0) # needs sage.rings.finite_rings + sage: A.inverse_series_trunc(4) # needs sage.rings.finite_rings Traceback (most recent call last): ... ZeroDivisionError: the constant matrix term self(0) must be invertible @@ -839,61 +841,62 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: A = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: pR. = GF(7)[] + sage: A = Matrix(pR, 3, 3, ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: A.is_square() and A.constant_matrix().is_invertible() # optional - sage.libs.pari + sage: A.is_square() and A.constant_matrix().is_invertible() True - sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) # optional - sage.libs.pari - sage: X = A.solve_left_series_trunc(B, 4); X # optional - sage.libs.pari + sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) + sage: X = A.solve_left_series_trunc(B, 4); X (3*x^3 + 3*x^2 + 2*x + 4, 4*x^3 + x^2 + 2*x + 6, 6*x^3 + x + 3) - sage: B == X*A % x**4 # optional - sage.libs.pari + sage: B == X*A % x**4 True - sage: B = Matrix(pR, 2, 3, # optional - sage.libs.pari + sage: B = Matrix(pR, 2, 3, # needs sage.rings.finite_rings ....: [[3*x, x^2 + x + 2, x^2 + 2*x + 3], ....: [ 0, 6*x^2 + 1, 1]]) - sage: A.solve_left_series_trunc(B, 3) # optional - sage.libs.pari + sage: A.solve_left_series_trunc(B, 3) # needs sage.rings.finite_rings [6*x^2 + 2*x + 2 4*x + 3 2*x^2 + 3*x] [3*x^2 + 4*x + 5 4*x^2 + 3 x^2 + 6*x + 3] - sage: X = A.solve_left_series_trunc(B, 37); B == X*A % x**37 # optional - sage.libs.pari + sage: X = A.solve_left_series_trunc(B, 37); B == X*A % x**37 # needs sage.rings.finite_rings True Dimensions of input are checked:: - sage: A.solve_left_series_trunc(B[:,:2], 3) # optional - sage.libs.pari + sage: A.solve_left_series_trunc(B[:,:2], 3) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: number of columns of self must equal number of columns of right-hand side Raises an exception when no solution:: - sage: A[2:,:].solve_left_series_trunc(B, 4) # optional - sage.libs.pari + sage: A[2:,:].solve_left_series_trunc(B, 4) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix equation has no solutions - sage: Ax = x*A; C = vector(pR, [1,1,1]) # optional - sage.libs.pari - sage: Ax.solve_left_series_trunc(C, 5) # optional - sage.libs.pari + sage: Ax = x*A; C = vector(pR, [1,1,1]) # needs sage.rings.finite_rings + sage: Ax.solve_left_series_trunc(C, 5) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix equation has no solutions Supports rectangular and rank-deficient cases:: - sage: A[:,:2].solve_left_series_trunc(B[:,:2], 4) # optional - sage.libs.pari + sage: A[:,:2].solve_left_series_trunc(B[:,:2], 4) # needs sage.rings.finite_rings [5*x^2 + 2*x + 5 5*x + 5 2*x + 4] [5*x^3 + 2*x + 1 2*x^2 + 2*x + 5 4*x^2] - sage: V = Matrix([[3*x^2 + 4*x + 1, 4*x]]) # optional - sage.libs.pari - sage: A[:2,:].solve_left_series_trunc(V*A[:2,:], 4) == V # optional - sage.libs.pari + sage: V = Matrix([[3*x^2 + 4*x + 1, 4*x]]) # needs sage.rings.finite_rings + sage: A[:2,:].solve_left_series_trunc(V*A[:2,:], 4) == V # needs sage.rings.finite_rings True - sage: A[1,:] = (x+1) * A[0,:]; A[2,:] = (x+5) * A[0,:] # optional - sage.libs.pari - sage: B = (3*x^3+x^2+2)*A[0,:] # optional - sage.libs.pari - sage: A.solve_left_series_trunc(B, 6) # optional - sage.libs.pari + sage: A[1,:] = (x+1) * A[0,:]; A[2,:] = (x+5) * A[0,:] # needs sage.rings.finite_rings + sage: B = (3*x^3+x^2+2)*A[0,:] # needs sage.rings.finite_rings + sage: A.solve_left_series_trunc(B, 6) # needs sage.rings.finite_rings [4*x^2 + 6*x + 2 3*x^2 + x 0] .. SEEALSO:: @@ -986,64 +989,65 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: A = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: pR. = GF(7)[] + sage: A = Matrix(pR, 3, 3, ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], ....: [6*x^2 + 6*x + 6, 4*x^2 + 5*x, 4*x^2 + x + 3], ....: [3*x^2 + 2, 4*x + 1, x^2 + 3*x]]) - sage: A.is_square() and A.constant_matrix().is_invertible() # optional - sage.libs.pari + sage: A.is_square() and A.constant_matrix().is_invertible() True - sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) # optional - sage.libs.pari - sage: X = A.solve_right_series_trunc(B, 4); X # optional - sage.libs.pari + sage: B = vector([2*x^2 + 6*x + 6, 0, x + 6]) + sage: X = A.solve_right_series_trunc(B, 4); X (2*x^3 + x^2, 5*x^3 + x^2 + 5*x + 6, 4*x^3 + 6*x^2 + 4*x) - sage: B == A*X % x**4 # optional - sage.libs.pari + sage: B == A*X % x**4 True - sage: B = Matrix(pR, 3, 2, # optional - sage.libs.pari + sage: B = Matrix(pR, 3, 2, # needs sage.rings.finite_rings ....: [[5*x^2 + 6*x + 3, 4*x^2 + 6*x + 4], ....: [ x^2 + 4*x + 2, 5*x + 2], ....: [ 5*x + 3, 0]]) - sage: A.solve_right_series_trunc(B, 3) # optional - sage.libs.pari + sage: A.solve_right_series_trunc(B, 3) # needs sage.rings.finite_rings [ 3*x^2 + x + 1 5*x^2 + 4*x + 3] [6*x^2 + 3*x + 1 4*x + 1] [ 6*x^2 + 1 2*x^2 + x + 4] - sage: X = A.solve_right_series_trunc(B, 37); B == A*X % x**37 # optional - sage.libs.pari + sage: X = A.solve_right_series_trunc(B, 37); B == A*X % x**37 # needs sage.rings.finite_rings True Dimensions of input are checked:: - sage: A.solve_right_series_trunc(B[:2,:], 3) # optional - sage.libs.pari + sage: A.solve_right_series_trunc(B[:2,:], 3) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: number of rows of self must equal number of rows of right-hand side Raises an exception when no solution:: - sage: A[:,2:].solve_right_series_trunc(B, 4) # optional - sage.libs.pari + sage: A[:,2:].solve_right_series_trunc(B, 4) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix equation has no solutions - sage: Ax = x*A; C = vector(pR, [1,1,1]) # optional - sage.libs.pari - sage: Ax.solve_right_series_trunc(C, 5) # optional - sage.libs.pari + sage: Ax = x*A; C = vector(pR, [1,1,1]) # needs sage.rings.finite_rings + sage: Ax.solve_right_series_trunc(C, 5) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix equation has no solutions Supports rectangular and rank-deficient cases:: - sage: A[:2,:].solve_right_series_trunc(B[:2,:],4) # optional - sage.libs.pari + sage: A[:2,:].solve_right_series_trunc(B[:2,:],4) # needs sage.rings.finite_rings [ 5*x^2 + 4*x x + 4] [ x^2 + 3*x + 5 3*x^2 + 4*x + 4] [ 5*x + 3 3*x + 2] - sage: V = Matrix([[2*x^2 + 5*x + 1], [3*x^2+4]]) # optional - sage.libs.pari - sage: A[:,:2].solve_right_series_trunc(A[:,:2]*V, 4) == V # optional - sage.libs.pari + sage: V = Matrix([[2*x^2 + 5*x + 1], [3*x^2+4]]) # needs sage.rings.finite_rings + sage: A[:,:2].solve_right_series_trunc(A[:,:2]*V, 4) == V # needs sage.rings.finite_rings True - sage: A[:,1] = (x+1) * A[:,0]; A[:,2] = (x+5) * A[:,0] # optional - sage.libs.pari - sage: B = (3*x^3+x^2+2)*A[:,0] # optional - sage.libs.pari - sage: A.solve_right_series_trunc(B, 6) # optional - sage.libs.pari + sage: A[:,1] = (x+1) * A[:,0]; A[:,2] = (x+5) * A[:,0] # needs sage.rings.finite_rings + sage: B = (3*x^3+x^2+2)*A[:,0] # needs sage.rings.finite_rings + sage: A.solve_right_series_trunc(B, 6) # needs sage.rings.finite_rings [4*x^2 + 6*x + 2] [ 3*x^2 + x] [ 0] @@ -1095,35 +1099,35 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari - sage: M.row_degrees() # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) + sage: M.row_degrees() [1, 3] - sage: M.row_degrees(shifts=[0,1,2]) # optional - sage.libs.pari + sage: M.row_degrees(shifts=[0,1,2]) [2, 3] A zero row in a polynomial matrix can be identified in the (shifted) row degrees as the entries equal to ``min(shifts)-1``:: - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 0, 0]]) # optional - sage.libs.pari - sage: M.row_degrees() # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 0, 0]]) + sage: M.row_degrees() [1, 3, -1] - sage: M.row_degrees(shifts=[-2,1,2]) # optional - sage.libs.pari + sage: M.row_degrees(shifts=[-2,1,2]) [2, 1, -3] The row degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix(pR, 0, 3) # optional - sage.libs.pari - sage: M.row_degrees() # optional - sage.libs.pari + sage: M = Matrix(pR, 0, 3) + sage: M.row_degrees() Traceback (most recent call last): ... ValueError: empty matrix does not have row degrees - sage: M = Matrix(pR, 3, 0) # optional - sage.libs.pari - sage: M.row_degrees() # optional - sage.libs.pari + sage: M = Matrix(pR, 3, 0) + sage: M.row_degrees() Traceback (most recent call last): ... ValueError: empty matrix does not have row degrees @@ -1162,31 +1166,31 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari - sage: M.column_degrees() # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) + sage: M.column_degrees() [3, -1, 0] - sage: M.column_degrees(shifts=[0,2]) # optional - sage.libs.pari + sage: M.column_degrees(shifts=[0,2]) [5, -1, 0] A zero column in a polynomial matrix can be identified in the (shifted) column degrees as the entries equal to ``min(shifts)-1``:: - sage: M.column_degrees(shifts=[-2,1]) # optional - sage.libs.pari + sage: M.column_degrees(shifts=[-2,1]) [4, -3, -2] The column degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix(pR, 0, 3) # optional - sage.libs.pari - sage: M.column_degrees() # optional - sage.libs.pari + sage: M = Matrix(pR, 0, 3) + sage: M.column_degrees() Traceback (most recent call last): ... ValueError: empty matrix does not have column degrees - sage: M = Matrix(pR, 3, 0) # optional - sage.libs.pari - sage: M.column_degrees() # optional - sage.libs.pari + sage: M = Matrix(pR, 3, 0) + sage: M.column_degrees() Traceback (most recent call last): ... ValueError: empty matrix does not have column degrees @@ -1243,28 +1247,28 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari - sage: M.leading_matrix() # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) + sage: M.leading_matrix() [3 0 0] [1 0 0] - sage: M.leading_matrix().base_ring() # optional - sage.libs.pari + sage: M.leading_matrix().base_ring() Finite Field of size 7 - sage: M.leading_matrix(shifts=[0,1,2]) # optional - sage.libs.pari + sage: M.leading_matrix(shifts=[0,1,2]) [0 0 1] [1 0 0] - sage: M.leading_matrix(row_wise=False) # optional - sage.libs.pari + sage: M.leading_matrix(row_wise=False) [0 0 1] [1 0 0] - sage: M.leading_matrix(shifts=[-2,1], row_wise=False) # optional - sage.libs.pari + sage: M.leading_matrix(shifts=[-2,1], row_wise=False) [0 0 1] [1 0 0] - sage: M.leading_matrix(shifts=[2,0], row_wise=False) # optional - sage.libs.pari + sage: M.leading_matrix(shifts=[2,0], row_wise=False) [3 0 1] [1 0 0] """ @@ -1318,19 +1322,21 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, 0, 0) # optional - sage.libs.pari - sage: M._is_empty_popov() # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: pR. = GF(7)[] + sage: M = Matrix(pR, 0, 0) + sage: M._is_empty_popov() True - sage: M._is_empty_popov(include_zero_vectors=False) # optional - sage.libs.pari + sage: M._is_empty_popov(include_zero_vectors=False) True - sage: M = Matrix(pR, 0, 3) # optional - sage.libs.pari - sage: M._is_empty_popov(include_zero_vectors=False) # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: M = Matrix(pR, 0, 3) + sage: M._is_empty_popov(include_zero_vectors=False) True - sage: M._is_empty_popov(row_wise=False) # optional - sage.libs.pari + sage: M._is_empty_popov(row_wise=False) True - sage: M._is_empty_popov(row_wise=False,include_zero_vectors=False) # optional - sage.libs.pari + sage: M._is_empty_popov(row_wise=False,include_zero_vectors=False) False .. SEEALSO:: @@ -1389,23 +1395,23 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari - sage: M.is_reduced() # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) + sage: M.is_reduced() False - sage: M.is_reduced(shifts=[0,1,2]) # optional - sage.libs.pari + sage: M.is_reduced(shifts=[0,1,2]) True - sage: M.is_reduced(shifts=[2,0], row_wise=False) # optional - sage.libs.pari + sage: M.is_reduced(shifts=[2,0], row_wise=False) True - sage: M.is_reduced(shifts=[2,0], row_wise=False, # optional - sage.libs.pari + sage: M.is_reduced(shifts=[2,0], row_wise=False, ....: include_zero_vectors=False) False - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 1, 0]]) # optional - sage.libs.pari - sage: M.is_reduced(shifts=[2,0,0], row_wise=False) # optional - sage.libs.pari + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0], [0, 1, 0]]) + sage: M.is_reduced(shifts=[2,0,0], row_wise=False) True .. SEEALSO:: @@ -1469,21 +1475,21 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) # optional - sage.libs.pari - sage: M.leading_positions() # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[3*x+1, 0, 1], [x^3+3, 0, 0]]) + sage: M.leading_positions() [0, 0] - sage: M.leading_positions(return_degree=True) # optional - sage.libs.pari + sage: M.leading_positions(return_degree=True) ([0, 0], [1, 3]) - sage: M.leading_positions(shifts=[0,5,2], return_degree=True) # optional - sage.libs.pari + sage: M.leading_positions(shifts=[0,5,2], return_degree=True) ([2, 0], [0, 3]) - sage: M.leading_positions(row_wise=False, return_degree=True) # optional - sage.libs.pari + sage: M.leading_positions(row_wise=False, return_degree=True) ([1, -1, 0], [3, -1, 0]) - sage: M.leading_positions(shifts=[1,2], row_wise=False, # optional - sage.libs.pari + sage: M.leading_positions(shifts=[1,2], row_wise=False, ....: return_degree=True) ([1, -1, 0], [3, -1, 0]) @@ -1491,29 +1497,29 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): (resp. column) degree, the leading position is chosen as the rightmost (resp. bottommost) such entry:: - sage: M.leading_positions(shifts=[0,5,1], return_degree=True) # optional - sage.libs.pari + sage: M.leading_positions(shifts=[0,5,1], return_degree=True) ([2, 0], [0, 3]) - sage: M.leading_positions(shifts=[2,0], row_wise=False, # optional - sage.libs.pari + sage: M.leading_positions(shifts=[2,0], row_wise=False, ....: return_degree=True) ([1, -1, 0], [3, -1, 0]) The leading positions and pivot degrees of an empty matrix (`0\times n` or `m\times 0`) is not defined:: - sage: M = Matrix(pR, 0, 3) # optional - sage.libs.pari - sage: M.leading_positions() # optional - sage.libs.pari + sage: M = Matrix(pR, 0, 3) + sage: M.leading_positions() Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions - sage: M.leading_positions(row_wise=False) # optional - sage.libs.pari + sage: M.leading_positions(row_wise=False) Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions - sage: M = Matrix(pR, 3, 0) # optional - sage.libs.pari - sage: M.leading_positions(row_wise=False) # optional - sage.libs.pari + sage: M = Matrix(pR, 3, 0) + sage: M.leading_positions(row_wise=False) Traceback (most recent call last): ... ValueError: empty matrix does not have leading positions @@ -1601,59 +1607,59 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix([ [x^3+3*x^2+6*x+6, 3*x^2+3*x+6, 4*x^2+x+3], # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix([ [x^3+3*x^2+6*x+6, 3*x^2+3*x+6, 4*x^2+x+3], ....: [5, 1, 0 ], ....: [2*x^2+2, 2*x+5, x^2+4*x+6] ]) - sage: M.is_weak_popov() # optional - sage.libs.pari + sage: M.is_weak_popov() True One can check whether the leading positions, in addition to being pairwise distinct, are actually in increasing order:: - sage: M.is_weak_popov(ordered=True) # optional - sage.libs.pari + sage: M.is_weak_popov(ordered=True) True - sage: N = M.with_swapped_rows(1, 2) # optional - sage.libs.pari - sage: N.is_weak_popov() # optional - sage.libs.pari + sage: N = M.with_swapped_rows(1, 2) + sage: N.is_weak_popov() True - sage: N.is_weak_popov(ordered=True) # optional - sage.libs.pari + sage: N.is_weak_popov(ordered=True) False Shifts and orientation (row-wise or column-wise) are supported:: - sage: M.is_weak_popov(shifts=[2,3,1]) # optional - sage.libs.pari + sage: M.is_weak_popov(shifts=[2,3,1]) False - sage: M.is_weak_popov(shifts=[0,2,0], row_wise=False, # optional - sage.libs.pari + sage: M.is_weak_popov(shifts=[0,2,0], row_wise=False, ....: ordered=True) True Rectangular matrices are supported:: - sage: M = Matrix([ # optional - sage.libs.pari + sage: M = Matrix([ ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], ....: [2*x^3+4*x^2+6*x+4, 5*x + 1, 2*x^2+5*x+5, x^2+5*x+6] ....: ]) - sage: M.is_weak_popov(shifts=[0,2,1,3]) # optional - sage.libs.pari + sage: M.is_weak_popov(shifts=[0,2,1,3]) True - sage: M.is_weak_popov(shifts=[0,2,1,3], ordered=True) # optional - sage.libs.pari + sage: M.is_weak_popov(shifts=[0,2,1,3], ordered=True) True Zero rows (resp. columns) can be forbidden:: - sage: M = Matrix([ # optional - sage.libs.pari + sage: M = Matrix([ ....: [ 6*x+4, 0, 5*x+1, 0], ....: [ 2, 5*x + 1, 6*x^2+3*x+1, 0], ....: [2*x^2+5*x+5, 1, 2*x^3+4*x^2+6*x+4, 0] ....: ]) - sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, # optional - sage.libs.pari + sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, ....: ordered=True) True - sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, # optional - sage.libs.pari + sage: M.is_weak_popov(shifts=[2,1,0], row_wise=False, ....: include_zero_vectors=False) False @@ -1741,60 +1747,60 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[x^4+6*x^3+4*x+4, 3*x+6, 3 ], # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[x^4+6*x^3+4*x+4, 3*x+6, 3 ], ....: [x^2+6*x+6, x^2+5*x+5, 2 ], ....: [3*x, 6*x+5, x+5]]) - sage: M.is_popov() # optional - sage.libs.pari + sage: M.is_popov() True - sage: M.is_popov(shifts=[0,1,2]) # optional - sage.libs.pari + sage: M.is_popov(shifts=[0,1,2]) True - sage: M[:,:2].is_popov() # optional - sage.libs.pari + sage: M[:,:2].is_popov() False - sage: M[:2,:].is_popov(shifts=[0,1,2]) # optional - sage.libs.pari + sage: M[:2,:].is_popov(shifts=[0,1,2]) True - sage: M = Matrix(pR, [[x^4+3*x^3+x^2+2*x+6, x^3+5*x^2+5*x+1], # optional - sage.libs.pari + sage: M = Matrix(pR, [[x^4+3*x^3+x^2+2*x+6, x^3+5*x^2+5*x+1], ....: [6*x+1, x^2+4*x+1 ], ....: [6, 6 ]]) - sage: M.is_popov(row_wise=False) # optional - sage.libs.pari + sage: M.is_popov(row_wise=False) False - sage: M.is_popov(shifts=[0,2,3], row_wise=False) # optional - sage.libs.pari + sage: M.is_popov(shifts=[0,2,3], row_wise=False) True One can forbid zero rows (or columns if not working row-wise):: - sage: N = Matrix(pR, [[x^4+3*x^3+x^2+2*x+6, 6*x+1 ], # optional - sage.libs.pari + sage: N = Matrix(pR, [[x^4+3*x^3+x^2+2*x+6, 6*x+1 ], ....: [5*x^2+5*x+1, x^2+4*x+1 ], ....: [0, 0 ]]) - sage: N.is_popov() # optional - sage.libs.pari + sage: N.is_popov() True - sage: N.is_popov(include_zero_vectors=False) # optional - sage.libs.pari + sage: N.is_popov(include_zero_vectors=False) False One can verify Popov form up to row permutation (or column permutation if not working row-wise):: - sage: M.swap_columns(0, 1) # optional - sage.libs.pari - sage: M.is_popov(shifts=[0,2,3], row_wise=False) # optional - sage.libs.pari + sage: M.swap_columns(0, 1) + sage: M.is_popov(shifts=[0,2,3], row_wise=False) False - sage: M.is_popov(shifts=[0,2,3], row_wise=False, # optional - sage.libs.pari - ....: up_to_permutation=True) # optional - sage.libs.pari + sage: M.is_popov(shifts=[0,2,3], row_wise=False, + ....: up_to_permutation=True) True - sage: N.swap_rows(0, 2) # optional - sage.libs.pari + sage: N.swap_rows(0, 2) - sage: N.is_popov() # optional - sage.libs.pari + sage: N.is_popov() False - sage: N.is_popov(up_to_permutation=True) # optional - sage.libs.pari + sage: N.is_popov(up_to_permutation=True) True """ # the matrix should be in weak Popov form (ordered except if @@ -1879,41 +1885,43 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [[x^4+6*x^3+4*x+4, 3*x+6, 3 ], # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [[x^4+6*x^3+4*x+4, 3*x+6, 3 ], ....: [0, x^2+5*x+5, 2 ], ....: [0, 0, x+5]]) - sage: M.is_hermite() # optional - sage.libs.pari + sage: M.is_hermite() True - sage: M.is_hermite(row_wise=False) # optional - sage.libs.pari + sage: M.is_hermite(row_wise=False) True - sage: M.is_hermite(row_wise=False, lower_echelon=True) # optional - sage.libs.pari + sage: M.is_hermite(row_wise=False, lower_echelon=True) False - sage: N = Matrix(pR, [[x+5, 0, 0 ], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: N = Matrix(pR, [[x+5, 0, 0 ], ....: [2, x^4+6*x^3+4*x+4, 0 ], ....: [3, 3*x^3+6, x^2+5*x+5]]) - sage: N.is_hermite() # optional - sage.libs.pari + sage: N.is_hermite() False - sage: N.is_hermite(lower_echelon=True) # optional - sage.libs.pari + sage: N.is_hermite(lower_echelon=True) True - sage: N.is_hermite(row_wise=False) # optional - sage.libs.pari + sage: N.is_hermite(row_wise=False) False - sage: N.is_hermite(row_wise=False, lower_echelon=True) # optional - sage.libs.pari + sage: N.is_hermite(row_wise=False, lower_echelon=True) False Rectangular matrices with zero rows are supported. Zero rows (resp. columns) can be forbidden, and otherwise they should be at the bottom (resp. the right-hand side) of the matrix:: - sage: N[:,1:].is_hermite(lower_echelon=True) # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: N[:,1:].is_hermite(lower_echelon=True) False - sage: N[[1,2,0],1:].is_hermite(lower_echelon=True) # optional - sage.libs.pari + sage: N[[1,2,0],1:].is_hermite(lower_echelon=True) True - sage: N[:2,:].is_hermite(row_wise=False, lower_echelon=True) # optional - sage.libs.pari + sage: N[:2,:].is_hermite(row_wise=False, lower_echelon=True) True - sage: N[:2,:].is_hermite(row_wise=False, # optional - sage.libs.pari + sage: N[:2,:].is_hermite(row_wise=False, ....: lower_echelon=True, ....: include_zero_vectors=False) False @@ -1994,61 +2002,63 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [ # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [ ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: P, U = M.weak_popov_form(transformation=True) # optional - sage.combinat sage.libs.pari - sage: P # optional - sage.combinat sage.libs.pari + sage: # needs sage.combinat sage.rings.finite_rings + sage: P, U = M.weak_popov_form(transformation=True) + sage: P [ 4 x^2 6*x^2 + x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: U # optional - sage.combinat sage.libs.pari + sage: U [2*x^2 + 1 4*x] [ 4*x 1] - sage: P.is_weak_popov() and U.is_invertible() and U*M == P # optional - sage.combinat sage.libs.pari + sage: P.is_weak_popov() and U.is_invertible() and U*M == P True Demonstrating the ``ordered`` option:: - sage: P.leading_positions() # optional - sage.combinat sage.libs.pari + sage: P.leading_positions() # needs sage.combinat sage.rings.finite_rings [2, 1] - sage: PP = M.weak_popov_form(ordered=True); PP # optional - sage.combinat sage.libs.pari + sage: PP = M.weak_popov_form(ordered=True); PP [ 2 4*x^2 + 2*x + 4 5] [ 4 x^2 6*x^2 + x + 2] - sage: PP.leading_positions() # optional - sage.combinat sage.libs.pari + sage: PP.leading_positions() [1, 2] Demonstrating shifts:: - sage: P = M.weak_popov_form(shifts=[0,2,4]); P # optional - sage.combinat sage.libs.pari + sage: P = M.weak_popov_form(shifts=[0,2,4]); P [ 6*x^2 + 6*x + 4 5*x^4 + 4*x^3 + 5*x^2 + 5*x 2*x + 2] [ 2 4*x^2 + 2*x + 4 5] - sage: P == M.weak_popov_form(shifts=[-10,-8,-6]) # optional - sage.combinat sage.libs.pari + sage: P == M.weak_popov_form(shifts=[-10,-8,-6]) True Column-wise form is the row-wise form of the transpose:: - sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T # optional - sage.combinat sage.libs.pari + sage: M.weak_popov_form() == M.T.weak_popov_form(row_wise=False).T True Zero vectors can be discarded:: - sage: M.weak_popov_form(row_wise=False) # optional - sage.combinat sage.libs.pari + sage: M.weak_popov_form(row_wise=False) [x + 4 6 0] [ 5 1 0] - sage: P, U = M.weak_popov_form(transformation=True, # optional - sage.combinat sage.libs.pari + sage: # needs sage.combinat sage.rings.finite_rings + sage: P, U = M.weak_popov_form(transformation=True, ....: row_wise=False, ....: include_zero_vectors=False) - sage: P # optional - sage.combinat sage.libs.pari + sage: P [x + 4 6] [ 5 1] - sage: U # optional - sage.combinat sage.libs.pari + sage: U [ 5*x + 2 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 1 1 2*x + 1] [ 5*x + 5 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.combinat sage.libs.pari + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() True .. SEEALSO:: @@ -2123,34 +2133,35 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: F. = GF(2^4, 'a') # optional - sage.libs.pari - sage: PF. = F[] # optional - sage.libs.pari - sage: A = matrix(PF,[[1, a*x^17 + 1 ], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = GF(2^4, 'a') + sage: PF. = F[] + sage: A = matrix(PF,[[1, a*x^17 + 1 ], ....: [0, a*x^11 + a^2*x^7 + 1 ]]) - sage: M = A.__copy__() # optional - sage.libs.pari - sage: U = M._weak_popov_form(transformation=True) # optional - sage.combinat sage.libs.pari - sage: U * A == M # optional - sage.combinat sage.libs.pari + sage: M = A.__copy__() + sage: U = M._weak_popov_form(transformation=True) # needs sage.combinat + sage: U * A == M # needs sage.combinat True - sage: M.is_weak_popov() # optional - sage.combinat sage.libs.pari + sage: M.is_weak_popov() # needs sage.combinat True - sage: U.is_invertible() # optional - sage.combinat sage.libs.pari + sage: U.is_invertible() # needs sage.combinat True sage: PF. = QQ[] sage: A = matrix(PF,3,[x, x^2, x^3, ....: x^2, x^1, 0, ....: x^3, x^3, x^3]) - sage: A.weak_popov_form() # optional - sage.combinat + sage: A.weak_popov_form() [ x x^2 x^3] [ x^2 x 0] [ x^3 - x x^3 - x^2 0] - sage: M = A.__copy__() # optional - sage.combinat - sage: U = M._weak_popov_form(transformation=True, shifts=[16,8,0]) # optional - sage.combinat - sage: M # optional - sage.combinat + sage: M = A.__copy__() + sage: U = M._weak_popov_form(transformation=True, shifts=[16,8,0]) + sage: M [ x x^2 x^3] [ 0 -x^2 + x -x^4 + x^3] [ 0 0 -x^5 + x^4 + x^3] - sage: U * A == M # optional - sage.combinat + sage: U * A == M True """ cdef Py_ssize_t i, j @@ -2278,56 +2289,59 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: M = Matrix(pR, [ # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: M = Matrix(pR, [ ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: P, U = M.popov_form(transformation=True) # optional - sage.combinat sage.libs.pari - sage: P # optional - sage.combinat sage.libs.pari + sage: # needs sage.combinat sage.rings.finite_rings + sage: P, U = M.popov_form(transformation=True) + sage: P [ 4 x^2 + 4*x + 1 3] [ 0 4*x + 1 x^2 + 6*x + 1] - sage: U # optional - sage.combinat sage.libs.pari + sage: U [ x 2] [5*x^2 + x + 6 3*x + 2] - sage: P.is_popov() and U.is_invertible() and U*M == P # optional - sage.combinat sage.libs.pari + sage: P.is_popov() and U.is_invertible() and U*M == P True Demonstrating shifts and specific case of Hermite form:: - sage: P = M.popov_form(shifts=[0,2,4]); P # optional - sage.combinat sage.libs.pari + sage: # needs sage.combinat sage.rings.finite_rings + sage: P = M.popov_form(shifts=[0,2,4]); P [ 4*x^2 + 3*x + 4 x^4 + 3*x^3 + 5*x^2 + 5*x + 5 0] [ 6 5*x^2 + 6*x + 5 1] - sage: P.is_popov(shifts=[0,2,4]) # optional - sage.combinat sage.libs.pari + sage: P.is_popov(shifts=[0,2,4]) True - sage: P == M.popov_form(shifts=[-6,-4,-2]) # optional - sage.combinat sage.libs.pari + sage: P == M.popov_form(shifts=[-6,-4,-2]) True - sage: dd = sum(M.row_degrees()) + 1 # optional - sage.combinat sage.libs.pari - sage: M.popov_form(shifts=[2*dd,dd,0]) == M.hermite_form() # optional - sage.combinat sage.libs.pari + sage: dd = sum(M.row_degrees()) + 1 + sage: M.popov_form(shifts=[2*dd,dd,0]) == M.hermite_form() True Column-wise form is the row-wise form of the transpose:: - sage: M.popov_form() == M.T.popov_form(row_wise=False).T # optional - sage.combinat sage.libs.pari + sage: M.popov_form() == M.T.popov_form(row_wise=False).T True Zero vectors can be discarded:: - sage: M.popov_form(row_wise=False) # optional - sage.combinat sage.libs.pari + sage: M.popov_form(row_wise=False) [x + 2 6 0] [ 0 1 0] - sage: P, U = M.popov_form(transformation=True, # optional - sage.combinat sage.libs.pari + sage: # needs sage.combinat sage.rings.finite_rings + sage: P, U = M.popov_form(transformation=True, ....: row_wise=False, ....: include_zero_vectors=False) - sage: P # optional - sage.combinat sage.libs.pari + sage: P [x + 2 6] [ 0 1] - sage: U # optional - sage.combinat sage.libs.pari + sage: U [ 3*x^2 + 6*x + 3 5*x^2 + 4*x + 4 3*x^3 + 3*x^2 + 2*x + 4] [ 3 1 2*x + 1] [ 5*x + 2 2 6] - sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() # optional - sage.combinat sage.libs.pari + sage: M*U[:,:2] == P and (M*U[:,2]).is_zero() True .. SEEALSO:: @@ -2469,40 +2483,41 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(3)[] # optional - sage.libs.pari - sage: A = matrix(pR, 3, [x, x^2, x^3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: pR. = GF(3)[] + sage: A = matrix(pR, 3, [x, x^2, x^3, ....: x^2, x^1, 0, ....: x^3, x^3, x^3]) - sage: R = A.reduced_form(); R # optional - sage.libs.pari + sage: R = A.reduced_form(); R [ x x^2 x^3] [ x^2 x 0] [ x^3 + 2*x x^3 + 2*x^2 0] - sage: R.is_reduced() # optional - sage.libs.pari + sage: R.is_reduced() True - sage: R2 = A.reduced_form(shifts=[6,3,0]); R2 # optional - sage.libs.pari + sage: R2 = A.reduced_form(shifts=[6,3,0]); R2 [ x x^2 x^3] [ 0 2*x^2 + x 2*x^4 + x^3] [ 0 0 2*x^5 + x^4 + x^3] - sage: R2.is_reduced(shifts=[6,3,0]) # optional - sage.libs.pari + sage: R2.is_reduced(shifts=[6,3,0]) True - sage: R2.is_reduced() # optional - sage.libs.pari + sage: R2.is_reduced() False If the matrix is an `n \times 1` matrix with at least one non-zero entry, `R` has a single non-zero entry and that entry is a scalar multiple of the greatest-common-divisor of the entries of the matrix:: - sage: A = matrix([[x*(x-1)*(x+1)], [x*(x-2)*(x+2)], [x]]) # optional - sage.libs.pari - sage: R = A.reduced_form() # optional - sage.libs.pari - sage: R # optional - sage.libs.pari + sage: A = matrix([[x*(x-1)*(x+1)], [x*(x-2)*(x+2)], [x]]) # needs sage.rings.finite_rings + sage: R = A.reduced_form() # needs sage.rings.finite_rings + sage: R # needs sage.rings.finite_rings [x] [0] [0] A zero matrix is already reduced:: - sage: A = matrix(pR, 2, [0,0,0,0]) # optional - sage.libs.pari - sage: A.reduced_form() # optional - sage.libs.pari + sage: A = matrix(pR, 2, [0,0,0,0]) # needs sage.rings.finite_rings + sage: A.reduced_form() # needs sage.rings.finite_rings [0 0] [0 0] @@ -2516,29 +2531,30 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [0 0 x] sage: A.is_reduced() True - sage: W = A.reduced_form(); W # optional - sage.combinat + sage: W = A.reduced_form(); W [ x x x] [-x -x 0] - sage: W.is_weak_popov() # optional - sage.combinat + sage: W.is_weak_popov() True The last example shows the usage of the transformation parameter:: - sage: Fq. = GF(2^3) # optional - sage.libs.pari - sage: pR. = Fq[] # optional - sage.libs.pari - sage: A = matrix(pR, [[x^2+a, x^4+a], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: Fq. = GF(2^3) + sage: pR. = Fq[] + sage: A = matrix(pR, [[x^2+a, x^4+a], ....: [ x^3, a*x^4]]) - sage: W, U = A.reduced_form(transformation=True) # optional - sage.libs.pari - sage: W, U # optional - sage.libs.pari + sage: W, U = A.reduced_form(transformation=True) + sage: W, U ( [ x^2 + a x^4 + a] [1 0] [x^3 + a*x^2 + a^2 a^2], [a 1] ) - sage: W.is_reduced() # optional - sage.libs.pari + sage: W.is_reduced() True - sage: U*W == A # optional - sage.libs.pari + sage: U*W == A True - sage: U.is_invertible() # optional - sage.libs.pari + sage: U.is_invertible() True .. SEEALSO:: @@ -2578,32 +2594,33 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: M. = GF(7)[] # optional - sage.libs.pari - sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) # optional - sage.libs.pari - sage: A.hermite_form() # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: M. = GF(7)[] + sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) + sage: A.hermite_form() [ x 1 2*x] [ 0 x 5*x + 2] - sage: A.hermite_form(transformation=True) # optional - sage.libs.pari + sage: A.hermite_form(transformation=True) ( [ x 1 2*x] [1 0] [ 0 x 5*x + 2], [6 1] ) - sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) # optional - sage.libs.pari - sage: A.hermite_form(transformation=True, include_zero_rows=False) # optional - sage.libs.pari + sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x]) + sage: A.hermite_form(transformation=True, include_zero_rows=False) ([ x 1 2*x], [0 4]) - sage: H, U = A.hermite_form(transformation=True, # optional - sage.libs.pari + sage: H, U = A.hermite_form(transformation=True, ....: include_zero_rows=True); H, U ( [ x 1 2*x] [0 4] [ 0 0 0], [5 1] ) - sage: U * A == H # optional - sage.libs.pari + sage: U * A == H True - sage: H, U = A.hermite_form(transformation=True, # optional - sage.libs.pari + sage: H, U = A.hermite_form(transformation=True, ....: include_zero_rows=False) - sage: U * A # optional - sage.libs.pari + sage: U * A [ x 1 2*x] - sage: U * A == H # optional - sage.libs.pari + sage: U * A == H True .. SEEALSO:: @@ -2640,26 +2657,27 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: A = Matrix(pR, 3, 2, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: pR. = GF(7)[] + sage: A = Matrix(pR, 3, 2, ....: [[ 3*x^3 + 3*x, 2*x^3 + 4], ....: [ 3*x^3 + 6*x + 5, 6*x^3 + 5*x^2 + 1], ....: [ 2*x^3 + 2*x + 6, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: B = Matrix(pR, 3, 3, ....: [[ 3, x + 3, 6], ....: [3*x^3 + 3*x + 1, 4*x^2 + 3*x, 6*x^3 + x + 4], ....: [ 4*x^2 + x + 4, 3*x^2 + 4*x, 3*x^2 + 3*x + 2]]) - sage: Q, R = A.left_quo_rem(B); Q, R # optional - sage.libs.pari + sage: Q, R = A.left_quo_rem(B); Q, R ( [2*x^2 + 4*x + 6 6*x^2 + 4*x + 1] [ 3 1] [ 3*x^2 + 5*x 2*x^2 + x + 5] [ 6 5*x^2 + 2*x + 3] [ 6*x^2 + 3*x 4*x^2 + 6*x + 1], [ 2*x + 3 6*x + 3] ) - sage: rdegR = R.row_degrees(); rdegB = B.row_degrees() # optional - sage.libs.pari - sage: A == B*Q+R and all(rdegR[i] < rdegB[i] for i in range(3)) # optional - sage.libs.pari + sage: rdegR = R.row_degrees(); rdegB = B.row_degrees() + sage: A == B*Q+R and all(rdegR[i] < rdegB[i] for i in range(3)) True - sage: A[:2,:].left_quo_rem(B) # optional - sage.libs.pari + sage: A[:2,:].left_quo_rem(B) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: row dimension of self should be the row dimension of @@ -2669,19 +2687,20 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): no quotient and remainder (unless the matrix has full row rank, see :meth:`right_quo_rem`):: - sage: Q, R = A[:2,:].left_quo_rem(B[:2,:]); Q, R # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: Q, R = A[:2,:].left_quo_rem(B[:2,:]); Q, R ( [ 3*x + 3 2*x + 1] [ 3*x^2 + 5*x 2*x^2 + x + 5] [ 5 0] [ 0 0], [4*x^2 + x + 2 4*x^2 + x] ) - sage: rdegR = R.row_degrees(); rdegB = B[:2,:].row_degrees() # optional - sage.libs.pari - sage: A[:2,:] == B[:2,:]*Q+R # optional - sage.libs.pari + sage: rdegR = R.row_degrees(); rdegB = B[:2,:].row_degrees() + sage: A[:2,:] == B[:2,:]*Q+R True - sage: all([rdegR[i] < rdegB[i] for i in range(len(rdegR))]) # optional - sage.libs.pari + sage: all([rdegR[i] < rdegB[i] for i in range(len(rdegR))]) True - sage: A.left_quo_rem(B[:,:2]) # optional - sage.libs.pari + sage: A.left_quo_rem(B[:,:2]) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder @@ -2735,37 +2754,39 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Case where `B` is a square, column reduced matrix:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: A = Matrix(pR, 2, 3, # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: A = Matrix(pR, 2, 3, ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 3, 3, ....: [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], ....: [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], ....: [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari + sage: B.is_reduced(row_wise=False) True - sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.libs.pari + sage: Q, R = A.right_quo_rem(B); Q, R ( [ 4*x x + 2 6*x + 1] [ x + 2 6*x + 1 5*x + 4] [4*x + 3 x + 6 3*x + 4], [4*x + 2 2*x + 3 4*x + 3] ) - sage: A == Q*B+R and R.degree() < 2 # optional - sage.libs.pari + sage: A == Q*B+R and R.degree() < 2 True - sage: A[:,:2].right_quo_rem(B) # optional - sage.libs.pari + sage: A[:,:2].right_quo_rem(B) Traceback (most recent call last): ... ValueError: column dimension of self should be the column dimension of the input matrix - sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 3, 3, ....: [[3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], ....: [x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari + sage: B.is_reduced(row_wise=False) True - sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.libs.pari + sage: Q, R = A.right_quo_rem(B); Q, R ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2773,20 +2794,21 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) # optional - sage.libs.pari + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() + sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) True With a nonsingular but also non-reduced matrix, there exists a solution, but it might not be unique:: - sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 3, 3, ....: [[ 5, 0, 2*x + 6], ....: [ 4*x, 3*x^2 + 4*x + 5, x + 1], ....: [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) - sage: B.det() != 0 and (not B.is_reduced(row_wise=False)) # optional - sage.libs.pari + sage: B.det() != 0 and (not B.is_reduced(row_wise=False)) True - sage: Q, R = A.right_quo_rem(B); Q, R # optional - sage.libs.pari + sage: Q, R = A.right_quo_rem(B); Q, R ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2], @@ -2794,17 +2816,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 5 x^2 + 2*x + 1 2] [ 6*x + 3 5*x^2 + 6 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari - sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.libs.pari + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) True - sage: Q2 = Matrix(pR, 2, 3, # optional - sage.libs.pari + sage: Q2 = Matrix(pR, 2, 3, ....: [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], ....: [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) - sage: R2 = Matrix(pR, 2, 3, # optional - sage.libs.pari + sage: R2 = Matrix(pR, 2, 3, ....: [[ 5*x, 3*x + 4, 5], ....: [4*x + 6, 5*x, 4]]) - sage: A == Q2*B + R2 # optional - sage.libs.pari + sage: A == Q2*B + R2 # needs sage.rings.finite_rings True The same remark holds more generally for full column rank matrices: @@ -2812,8 +2834,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): other cases (rank-deficient matrix `B` or matrix `B` having strictly fewer rows than columns) there may be no solution:: - sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # optional - sage.libs.pari - sage: Q, R = A.right_quo_rem(C); Q, R # optional - sage.libs.pari + sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # needs sage.rings.finite_rings + sage: Q, R = A.right_quo_rem(C); Q, R # needs sage.rings.finite_rings ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1 0] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2 0], @@ -2822,13 +2844,13 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 6*x + 3 5*x^2 + 6 3] ) - sage: A.right_quo_rem(B[:2,:]) # matrix 2 x 3, full row rank # optional - sage.libs.pari + sage: A.right_quo_rem(B[:2,:]) # matrix 2 x 3, full row rank # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder with the required degree property - sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # optional - sage.libs.pari - sage: A.right_quo_rem(D) # optional - sage.libs.pari + sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # needs sage.rings.finite_rings + sage: A.right_quo_rem(D) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder @@ -2839,11 +2861,12 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): remainder, in which case this method will find it via normal form computation:: - sage: B = Matrix(pR, 1, 2, [[x, x]]) # optional - sage.libs.pari - sage: A = Matrix(pR, 1, 2, [[x, x+2]]) # optional - sage.libs.pari - sage: A.right_quo_rem(B) # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 1, 2, [[x, x]]) + sage: A = Matrix(pR, 1, 2, [[x, x+2]]) + sage: A.right_quo_rem(B) ([1], [0 2]) - sage: A == 1*B + Matrix([[0,2]]) # optional - sage.libs.pari + sage: A == 1*B + Matrix([[0,2]]) True .. SEEALSO:: @@ -2891,32 +2914,34 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: A = Matrix(pR, 2, 3, # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: A = Matrix(pR, 2, 3, ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 3, 3, ....: [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], ....: [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], ....: [5*x^2 + 3*x + 6, 6*x^2 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari + sage: B.is_reduced(row_wise=False) True - sage: Q, R = A._right_quo_rem_reduced(B); Q, R # optional - sage.libs.pari + sage: Q, R = A._right_quo_rem_reduced(B); Q, R ( [ 4*x x + 2 6*x + 1] [ x + 2 6*x + 1 5*x + 4] [4*x + 3 x + 6 3*x + 4], [4*x + 2 2*x + 3 4*x + 3] ) - sage: A == Q*B+R and R.degree() < 2 # optional - sage.libs.pari + sage: A == Q*B+R and R.degree() < 2 True - sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 3, 3, ....: [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], ....: [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari + sage: B.is_reduced(row_wise=False) True - sage: Q, R = A._right_quo_rem_reduced(B); Q, R # optional - sage.libs.pari + sage: Q, R = A._right_quo_rem_reduced(B); Q, R ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2924,8 +2949,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari - sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.libs.pari + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) True """ # Step 0: find parameter d (delta in above reference) @@ -2970,16 +2995,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: A = Matrix(pR, 2, 3, # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: A = Matrix(pR, 2, 3, ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 3, 3, ....: [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], ....: [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], ....: [6, 6*x^3 + x + 4, 3*x^2 + 3*x + 2]]) - sage: Q, R = A._right_quo_rem_solve(B); Q, R # optional - sage.libs.pari + sage: Q, R = A._right_quo_rem_solve(B); Q, R ( [2*x^2 + 4*x + 6 3*x^2 + 5*x 6*x^2 + 3*x] [6*x^2 + 4*x + 1 2*x^2 + x + 5 4*x^2 + 6*x + 1], @@ -2987,22 +3013,23 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 3 6 2*x + 3] [ 1 5*x^2 + 2*x + 3 6*x + 3] ) - sage: B.is_reduced(row_wise=False) # optional - sage.libs.pari + sage: B.is_reduced(row_wise=False) True - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari - sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) # optional - sage.libs.pari + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() + sage: A == Q*B+R and all([cdegR[i] < cdegB[i] for i in range(3)]) True With a nonsingular but also non-reduced matrix, there exists a solution and one is found by this method, but it might not be unique:: - sage: B = Matrix(pR, 3, 3, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 3, 3, ....: [[ 5, 0, 2*x + 6], ....: [ 4*x, 3*x^2 + 4*x + 5, x + 1], ....: [3*x^2 + 5*x + 2, 6*x^3 + 4*x + 6, 3]]) - sage: B.det() != 0 and not B.is_reduced(row_wise=False) # optional - sage.libs.pari + sage: B.det() != 0 and not B.is_reduced(row_wise=False) True - sage: Q, R = A._right_quo_rem_solve(B); Q, R # optional - sage.libs.pari + sage: Q, R = A._right_quo_rem_solve(B); Q, R ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2], @@ -3010,17 +3037,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 4*x + 5 x^2 + 2*x + 1 2] [ 6*x + 3 5*x^2 + 6 3] ) - sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() # optional - sage.libs.pari - sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) # optional - sage.libs.pari + sage: cdegR = R.column_degrees(); cdegB = B.column_degrees() + sage: A == Q*B+R and all(cdegR[i] < cdegB[i] for i in range(3)) True - sage: Q2 = Matrix(pR, 2, 3, # optional - sage.libs.pari + sage: Q2 = Matrix(pR, 2, 3, ....: [[6*x^2 + 3*x + 1, 4*x^2 + 3*x + 6, 5*x + 1], ....: [ x^2 + 5*x + 3, 5*x^2 + 3*x + 2, x + 2]]) - sage: R2 = Matrix(pR, 2, 3, # optional - sage.libs.pari + sage: R2 = Matrix(pR, 2, 3, ....: [[ 5*x, 3*x + 4, 5], ....: [4*x + 6, 5*x, 4]]) - sage: A == Q2*B + R2 # optional - sage.libs.pari + sage: A == Q2*B + R2 # needs sage.rings.finite_rings True The same remark holds more generally for full column rank matrices: @@ -3028,8 +3055,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): other cases (rank-deficient or strictly fewer rows than columns) there might be no solution:: - sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # optional - sage.libs.pari - sage: Q, R = A._right_quo_rem_solve(C); Q, R # optional - sage.libs.pari + sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # needs sage.rings.finite_rings + sage: Q, R = A._right_quo_rem_solve(C); Q, R # needs sage.rings.finite_rings ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1 0] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2 0], @@ -3038,12 +3065,12 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 6*x + 3 5*x^2 + 6 3] ) - sage: A._right_quo_rem_solve(B[:2,:]) # 2 x 3, full row rank # optional - sage.libs.pari + sage: A._right_quo_rem_solve(B[:2,:]) # 2 x 3, full row rank # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution - sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # optional - sage.libs.pari - sage: A._right_quo_rem_solve(D) # optional - sage.libs.pari + sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # needs sage.rings.finite_rings + sage: A._right_quo_rem_solve(D) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution @@ -3052,11 +3079,12 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): columns), even when there is a solution, this method might not find it:: - sage: B = Matrix(pR, 1, 2, [[x, x]]) # optional - sage.libs.pari - sage: A = Matrix(pR, 1, 2, [[x, x+2]]) # optional - sage.libs.pari - sage: A == 1*B + Matrix([[0,2]]) # a valid quo_rem # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: B = Matrix(pR, 1, 2, [[x, x]]) + sage: A = Matrix(pR, 1, 2, [[x, x+2]]) + sage: A == 1*B + Matrix([[0,2]]) # a valid quo_rem True - sage: A._right_quo_rem_solve(B) # optional - sage.libs.pari + sage: A._right_quo_rem_solve(B) Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution @@ -3137,24 +3165,25 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: B = Matrix(pR, [ # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: B = Matrix(pR, [ ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: A = Matrix(pR, 1, 3, [ # optional - sage.libs.pari + sage: A = Matrix(pR, 1, 3, [ ....: [3*x^4+3*x^3+4*x^2+5*x+1, x^4+x^3+5*x^2+4*x+4, 4*x^4+2*x^3+x]]) - sage: Q, R = A.reduce(B,return_quotient=True); R # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: Q, R = A.reduce(B,return_quotient=True); R [3*x^4 + 3*x^3 + 4*x + 3 2*x + 2 2*x + 6] - sage: A == Q*B + R # optional - sage.libs.pari + sage: A == Q*B + R True - sage: P = B.popov_form(); P.leading_positions(return_degree=True) # optional - sage.libs.pari + sage: P = B.popov_form(); P.leading_positions(return_degree=True) ([1, 2], [2, 2]) - sage: R.degree_matrix() # optional - sage.libs.pari + sage: R.degree_matrix() [4 1 1] - sage: A.reduce(P) == R # optional - sage.libs.pari + sage: A.reduce(P) == R True - sage: A.reduce(P[:,:2]) # optional - sage.libs.pari + sage: A.reduce(P[:,:2]) Traceback (most recent call last): ... ValueError: column dimension of self should be the column @@ -3162,41 +3191,43 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Demonstrating shifts:: - sage: Qs, Rs = A.reduce(B, shifts=[0,2,4], return_quotient=True); Rs # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: Qs, Rs = A.reduce(B, shifts=[0,2,4], return_quotient=True); Rs [3*x^4 + 3*x^3 + 6*x + 2 4*x^3 + 5*x 0] - sage: A == Qs*B + Rs # optional - sage.libs.pari + sage: A == Qs*B + Rs True - sage: Ps = B.popov_form(shifts=[0,2,4]) # optional - sage.libs.pari - sage: Ps.leading_positions(shifts=[0,2,4], return_degree=True) # optional - sage.libs.pari + sage: Ps = B.popov_form(shifts=[0,2,4]) + sage: Ps.leading_positions(shifts=[0,2,4], return_degree=True) ([1, 2], [4, 0]) - sage: Rs.degree_matrix() # optional - sage.libs.pari + sage: Rs.degree_matrix() [ 4 3 -1] - sage: A.reduce(Ps, shifts=[0,2,4]) == Rs # optional - sage.libs.pari + sage: A.reduce(Ps, shifts=[0,2,4]) == Rs True If ``return_quotient`` is ``False``, only the normal form is returned:: - sage: R == A.reduce(B) and Rs == A.reduce(B, shifts=[0,2,4]) # optional - sage.libs.pari + sage: R == A.reduce(B) and Rs == A.reduce(B, shifts=[0,2,4]) # needs sage.rings.finite_rings True Demonstrating column-wise normal forms, with a matrix `A` which has several columns, and a matrix `B` which does not have full column rank (its column-wise Popov form has a zero column):: - sage: A = Matrix(pR, 2, 2, # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = Matrix(pR, 2, 2, ....: [[5*x^3 + 2*x^2 + 4*x + 1, x^3 + 4*x + 4], ....: [2*x^3 + 5*x^2 + 2*x + 4, 2*x^3 + 3*x + 2]]) - sage: (Q,R) = A.reduce(B,row_wise=False, return_quotient=True); R # optional - sage.libs.pari + sage: (Q,R) = A.reduce(B,row_wise=False, return_quotient=True); R [0 3] [0 0] - sage: A == B*Q + R # optional - sage.libs.pari + sage: A == B*Q + R True - sage: P = B.popov_form(row_wise=False); P # optional - sage.libs.pari + sage: P = B.popov_form(row_wise=False); P [x + 2 6 0] [ 0 1 0] - sage: P.leading_positions(row_wise=False, return_degree=True) # optional - sage.libs.pari + sage: P.leading_positions(row_wise=False, return_degree=True) ([0, 1, -1], [1, 0, -1]) - sage: R.degree_matrix() # optional - sage.libs.pari + sage: R.degree_matrix() [-1 0] [-1 -1] @@ -3296,25 +3327,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(97)[] # optional - sage.libs.pari + sage: pR. = GF(97)[] We consider the following example from [Arne Storjohann, Notes on computing minimal approximant bases, 2006]:: - sage: order = 8; shifts = [1,1,0,0,0] # optional - sage.libs.pari - sage: pmat = Matrix(pR, 5, 1, [ # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: order = 8; shifts = [1,1,0,0,0] + sage: pmat = Matrix(pR, 5, 1, [ ....: pR([35, 0, 41, 87, 3, 42, 22, 90]), ....: pR([80, 15, 62, 87, 14, 93, 24, 0]), ....: pR([42, 57, 90, 87, 22, 80, 71, 53]), ....: pR([37, 72, 74, 6, 5, 75, 23, 47]), ....: pR([36, 10, 74, 1, 29, 44, 87, 74])]) - sage: appbas = Matrix(pR, [ # optional - sage.libs.pari + sage: appbas = Matrix(pR, [ ....: [x+47, 57, 58*x+44, 9*x+23, 93*x+76], ....: [ 15, x+18, 52*x+23, 15*x+58, 93*x+88], ....: [ 17, 86, x^2+77*x+16, 76*x+29, 90*x+78], ....: [ 44, 36, 3*x+42, x^2+50*x+26, 85*x+44], ....: [ 2, 22, 54*x+94, 73*x+24, x^2+2*x+25]]) - sage: appbas.is_minimal_approximant_basis( # optional - sage.libs.pari + sage: appbas.is_minimal_approximant_basis( ....: pmat, order, shifts, row_wise=True, normal_form=True) True @@ -3323,35 +3355,35 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): not an approximant basis since its rows generate a module strictly contained in the set of approximants for ``pmat`` at order 8:: - sage: M = x^8 * Matrix.identity(pR, 5) # optional - sage.libs.pari - sage: M.is_minimal_approximant_basis(pmat, 8) # optional - sage.libs.pari + sage: M = x^8 * Matrix.identity(pR, 5) + sage: M.is_minimal_approximant_basis(pmat, 8) # needs sage.rings.finite_rings False Since ``pmat`` is a single column, with nonzero constant coefficient, its column-wise approximant bases at order 8 are all `1\times 1` matrices `[c x^8]` for some nonzero field element `c`:: - sage: M = Matrix(pR, [x^8]) # optional - sage.libs.pari - sage: M.is_minimal_approximant_basis( # optional - sage.libs.pari + sage: M = Matrix(pR, [x^8]) + sage: M.is_minimal_approximant_basis( # needs sage.rings.finite_rings ....: pmat, 8, row_wise=False, normal_form=True) True Exceptions are raised if input dimensions are not sound:: - sage: appbas.is_minimal_approximant_basis(pmat, [8,8], shifts) # optional - sage.libs.pari + sage: appbas.is_minimal_approximant_basis(pmat, [8,8], shifts) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: order length should be the column dimension of the input matrix - sage: appbas.is_minimal_approximant_basis( # optional - sage.libs.pari + sage: appbas.is_minimal_approximant_basis( # needs sage.rings.finite_rings ....: pmat, order, shifts, row_wise=False) Traceback (most recent call last): ... ValueError: shifts length should be the column dimension of the input matrix - sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, 8) # optional - sage.libs.pari + sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, 8) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: column dimension should be the row dimension of the @@ -3507,25 +3539,25 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pR. = GF(7)[] sage: order = [4, 3]; shifts = [-1, 2, 0] - sage: F = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5*x^2 + 4*x + 1], # optional - sage.libs.pari + sage: F = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5*x^2 + 4*x + 1], ....: [ 2*x^2 + 2*x + 3, 6*x^2 + 6*x + 3], ....: [4*x^3 + x + 1, 4*x^2 + 2*x + 3]]) - sage: P = F.minimal_approximant_basis(order, shifts) # optional - sage.libs.pari - sage: P.is_minimal_approximant_basis(F, order, shifts) # optional - sage.libs.pari + sage: P = F.minimal_approximant_basis(order, shifts) + sage: P.is_minimal_approximant_basis(F, order, shifts) True By default, the computed basis is not required to be in normal form (and will not be except in rare special cases):: - sage: P.is_minimal_approximant_basis(F, order, shifts, # optional - sage.libs.pari + sage: P.is_minimal_approximant_basis(F, order, shifts, ....: normal_form=True) False - sage: P = F.minimal_approximant_basis(order, shifts, # optional - sage.libs.pari + sage: P = F.minimal_approximant_basis(order, shifts, ....: normal_form=True) - sage: P.is_minimal_approximant_basis(F, order, shifts, # optional - sage.libs.pari + sage: P.is_minimal_approximant_basis(F, order, shifts, ....: normal_form=True) True @@ -3533,37 +3565,37 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): by default. Besides, if the orders are all the same, one can rather give a single integer:: - sage: (F.minimal_approximant_basis(3) == # optional - sage.libs.pari + sage: (F.minimal_approximant_basis(3) == ....: F.minimal_approximant_basis([3,3], shifts=None)) True One can work column-wise by specifying ``row_wise=False``:: - sage: P = F.minimal_approximant_basis([5,2,2], [0,1], # optional - sage.libs.pari + sage: P = F.minimal_approximant_basis([5,2,2], [0,1], ....: row_wise=False) - sage: P.is_minimal_approximant_basis(F, [5,2,2], shifts=[0,1], # optional - sage.libs.pari + sage: P.is_minimal_approximant_basis(F, [5,2,2], shifts=[0,1], ....: row_wise=False) True - sage: (F.minimal_approximant_basis(3, row_wise=True) == # optional - sage.libs.pari + sage: (F.minimal_approximant_basis(3, row_wise=True) == ....: F.transpose().minimal_approximant_basis( ....: 3, row_wise=False).transpose()) True Errors are raised if the input dimensions are not sound:: - sage: P = F.minimal_approximant_basis([4], shifts) # optional - sage.libs.pari + sage: P = F.minimal_approximant_basis([4], shifts) Traceback (most recent call last): ... ValueError: order length should be the column dimension - sage: P = F.minimal_approximant_basis(order, [0,0,0,0]) # optional - sage.libs.pari + sage: P = F.minimal_approximant_basis(order, [0,0,0,0]) Traceback (most recent call last): ... ValueError: shifts length should be the row dimension An error is raised if order does not contain only positive integers:: - sage: P = F.minimal_approximant_basis([1,0], shifts) # optional - sage.libs.pari + sage: P = F.minimal_approximant_basis([1,0], shifts) Traceback (most recent call last): ... ValueError: order should consist of positive integers @@ -3660,31 +3692,32 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari + sage: pR. = GF(7)[] This method supports any number of columns or rows, as well as arbitrary shifts and orders:: - sage: order = [4, 1, 2]; shifts = [-3, 4] # optional - sage.libs.pari - sage: pmat = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5, 4], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: order = [4, 1, 2]; shifts = [-3, 4] + sage: pmat = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5, 4], ....: [2*x^3 + 2*x^2 + 2*x + 3, 6, 6*x + 3]]) - sage: appbas, rdeg = pmat._approximant_basis_iterative(order, # optional - sage.libs.pari + sage: appbas, rdeg = pmat._approximant_basis_iterative(order, ....: shifts) - sage: appbas.is_minimal_approximant_basis(pmat, order, shifts) # optional - sage.libs.pari + sage: appbas.is_minimal_approximant_basis(pmat, order, shifts) True The returned list is the shifted row degrees of ``appbas``:: - sage: rdeg == appbas.row_degrees(shifts) # optional - sage.libs.pari + sage: rdeg == appbas.row_degrees(shifts) # needs sage.rings.finite_rings True Approximant bases for the zero matrix are all constant unimodular matrices; in fact, this algorithm returns the identity:: - sage: pmat = Matrix(pR, 3, 2) # optional - sage.libs.pari - sage: appbas,rdeg = pmat._approximant_basis_iterative([2,5], # optional - sage.libs.pari + sage: pmat = Matrix(pR, 3, 2) + sage: appbas,rdeg = pmat._approximant_basis_iterative([2,5], ....: [5,0,-4]) - sage: rdeg == [5,0,-4] and appbas == Matrix.identity(pR, 3) # optional - sage.libs.pari + sage: rdeg == [5,0,-4] and appbas == Matrix.identity(pR, 3) True """ # Define parameters and perform some sanity checks @@ -3813,24 +3846,24 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(97)[] # optional - sage.libs.pari - sage: pmat = Matrix(pR, [[1], [x], [x**2]]) # optional - sage.libs.pari + sage: pR. = GF(97)[] + sage: pmat = Matrix(pR, [[1], [x], [x**2]]) - sage: kerbas = Matrix(pR, [[x,-1,0], [0,x,-1]]) # optional - sage.libs.pari - sage: kerbas.is_minimal_kernel_basis(pmat) # optional - sage.libs.pari + sage: kerbas = Matrix(pR, [[x,-1,0], [0,x,-1]]) + sage: kerbas.is_minimal_kernel_basis(pmat) True A matrix in Popov form which has the right rank, all rows in the kernel, but does not generate the kernel:: - sage: kerbas = Matrix(pR, [[x**2,0,-1], [0,x,-1]]) # optional - sage.libs.pari - sage: kerbas.is_minimal_kernel_basis(pmat) # optional - sage.libs.pari + sage: kerbas = Matrix(pR, [[x**2,0,-1], [0,x,-1]]) + sage: kerbas.is_minimal_kernel_basis(pmat) False Shifts and right kernel bases are supported (with ``row_wise``), and one can test whether the kernel basis is normalized in shifted-Popov form (with ``normal_form``):: - sage: kerbas = Matrix(pR, [[-x,-x**2], [1,0], [0,1]]) # optional - sage.libs.pari - sage: kerbas.is_minimal_kernel_basis( # optional - sage.libs.pari + sage: kerbas = Matrix(pR, [[-x,-x**2], [1,0], [0,1]]) + sage: kerbas.is_minimal_kernel_basis( ....: pmat.transpose(), row_wise=False, ....: normal_form=True, shifts=[0,1,2]) True @@ -3935,25 +3968,25 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: pR. = GF(7)[] # optional - sage.libs.pari - sage: pmat = Matrix([[(x+1)*(x+3)], [(x+1)*(x+3)+1]]) # optional - sage.libs.pari - sage: pmat.minimal_kernel_basis() # optional - sage.libs.pari + sage: pR. = GF(7)[] + sage: pmat = Matrix([[(x+1)*(x+3)], [(x+1)*(x+3)+1]]) + sage: pmat.minimal_kernel_basis() [6*x^2 + 3*x + 3 x^2 + 4*x + 3] - sage: pmat = Matrix([[(x+1)*(x+3)], [(x+1)*(x+4)]]) # optional - sage.libs.pari - sage: pmat.minimal_kernel_basis() # optional - sage.libs.pari + sage: pmat = Matrix([[(x+1)*(x+3)], [(x+1)*(x+4)]]) + sage: pmat.minimal_kernel_basis() [6*x + 3 x + 3] - sage: pmat.minimal_kernel_basis(row_wise=False) # optional - sage.libs.pari + sage: pmat.minimal_kernel_basis(row_wise=False) [] - sage: pmat = Matrix(pR, [[1, x, x**2]]) # optional - sage.libs.pari - sage: pmat.minimal_kernel_basis(row_wise=False, normal_form=True) # optional - sage.libs.pari + sage: pmat = Matrix(pR, [[1, x, x**2]]) + sage: pmat.minimal_kernel_basis(row_wise=False, normal_form=True) [x 0] [6 x] [0 6] - sage: pmat.minimal_kernel_basis(row_wise=False, normal_form=True, # optional - sage.libs.pari + sage: pmat.minimal_kernel_basis(row_wise=False, normal_form=True, ....: shifts=[0,1,2]) [ 6*x 6*x^2] [ 1 0] @@ -3961,22 +3994,22 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Some particular cases (matrix is zero, dimension is zero, column is zero):: - sage: Matrix(pR, 2, 1).minimal_kernel_basis() # optional - sage.rings.finite_rings + sage: Matrix(pR, 2, 1).minimal_kernel_basis() [1 0] [0 1] - sage: Matrix(pR, 2, 0).minimal_kernel_basis() # optional - sage.rings.finite_rings + sage: Matrix(pR, 2, 0).minimal_kernel_basis() [1 0] [0 1] - sage: Matrix(pR, 0, 2).minimal_kernel_basis() # optional - sage.rings.finite_rings + sage: Matrix(pR, 0, 2).minimal_kernel_basis() [] - sage: Matrix(pR, 3, 2, [[1,0],[1,0],[1,0]]).minimal_kernel_basis() # optional - sage.rings.finite_rings + sage: Matrix(pR, 3, 2, [[1,0],[1,0],[1,0]]).minimal_kernel_basis() [6 1 0] [6 0 1] - sage: Matrix(pR, 3, 2, [[x,0],[1,0],[x+1,0]]).minimal_kernel_basis() # optional - sage.rings.finite_rings + sage: Matrix(pR, 3, 2, [[x,0],[1,0],[x+1,0]]).minimal_kernel_basis() [6 x 0] [6 6 1] """ diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 17000d28b9c..c4c902a09c6 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -114,31 +114,32 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(ZZ, 3, 3, False, 'flint') - sage: get_matrix_class(ZZ, 3, 3, False, 'gap') # optional - sage.modules + sage: get_matrix_class(ZZ, 3, 3, False, 'gap') # needs sage.modules sage: get_matrix_class(ZZ, 3, 3, False, 'generic') - sage: get_matrix_class(GF(2^15), 3, 3, False, None) # optional - sage.libs.pari + sage: get_matrix_class(GF(2^15), 3, 3, False, None) # needs sage.rings.finite_rings - sage: get_matrix_class(GF(2^17), 3, 3, False, None) # optional - sage.libs.pari + sage: get_matrix_class(GF(2^17), 3, 3, False, None) # needs sage.rings.finite_rings - sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri') # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri') - sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri') # optional - sage.libs.pari + sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri') - sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float') # optional - sage.libs.pari + sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float') - sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double') # optional - sage.libs.pari + sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double') - sage: get_matrix_class(RDF, 2, 2, False, 'numpy') + sage: get_matrix_class(RDF, 2, 2, False, 'numpy') # needs numpy - sage: get_matrix_class(CDF, 2, 3, False, 'numpy') + sage: get_matrix_class(CDF, 2, 3, False, 'numpy') # needs numpy - sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe # optional - sage.libs.pari + sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe, needs sage.rings.finite_rings sage: get_matrix_class(IntegerModRing(3), 4, 4, False, 'meataxe') # optional - meataxe @@ -146,7 +147,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): Traceback (most recent call last): ... ValueError: 'meataxe' matrix can only deal with finite fields of order < 256 - sage: get_matrix_class(GF(next_prime(255)), 4, 4, False, 'meataxe') # optional - sage.libs.pari + sage: get_matrix_class(GF(next_prime(255)), 4, 4, False, 'meataxe') # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: 'meataxe' matrix can only deal with finite fields of order < 256 @@ -168,21 +169,21 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): ... ValueError: 'linbox-double' matrices can only deal with order < 94906266 - sage: type(matrix(SR, 2, 2, 0)) + sage: type(matrix(SR, 2, 2, 0)) # needs sage.symbolic - sage: type(matrix(SR, 2, 2, 0, sparse=True)) + sage: type(matrix(SR, 2, 2, 0, sparse=True)) # needs sage.symbolic - sage: type(matrix(GF(7), 2, range(4))) + sage: type(matrix(GF(7), 2, range(4))) # needs sage.rings.finite_rings - sage: type(matrix(GF(16007), 2, range(4))) # optional - sage.libs.pari + sage: type(matrix(GF(16007), 2, range(4))) # needs sage.rings.finite_rings - sage: type(matrix(CBF, 2, range(4))) + sage: type(matrix(CBF, 2, range(4))) # needs sage.libs.flint - sage: type(matrix(GF(2), 2, range(4))) # optional - sage.libs.pari + sage: type(matrix(GF(2), 2, range(4))) # needs sage.rings.finite_rings - sage: type(matrix(GF(64, 'z'), 2, range(4))) # optional - sage.libs.pari + sage: type(matrix(GF(64, 'z'), 2, range(4))) # needs sage.rings.finite_rings - sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe # optional - sage.libs.pari + sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe # needs sage.rings.finite_rings """ @@ -495,37 +496,37 @@ class MatrixSpace(UniqueRepresentation, Parent): Check that different implementations play together as expected:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1(range(4))) # optional - sage.libs.flint + sage: type(M1(range(4))) # needs sage.libs.flint sage: type(M2(range(4))) - sage: M1(M2.an_element()) # optional - sage.libs.flint + sage: M1(M2.an_element()) # needs sage.libs.flint [ 0 1] [-1 2] - sage: M2(M1.an_element()) # optional - sage.libs.flint + sage: M2(M1.an_element()) # needs sage.libs.flint [ 0 1] [-1 2] - sage: all((A.get_action(B) is not None) == (A is B) # optional - sage.libs.flint + sage: all((A.get_action(B) is not None) == (A is B) # needs sage.libs.flint ....: for A in [M1, M2] for B in [M1, M2]) True Check that libgap matrices over finite fields are working properly:: - sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') # optional - sage.libs.gap sage.libs.pari - sage: M2.one() # optional - sage.libs.gap sage.libs.pari + sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') # needs sage.libs.gap sage.rings.finite_rings + sage: M2.one() # needs sage.libs.gap sage.rings.finite_rings [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] - sage: m = M2.random_element() # optional - sage.libs.gap + sage: m = M2.random_element() sage: M1 = MatrixSpace(GF(2), 5) - sage: M1(m * m) == M1(m) * M1(m) # optional - sage.libs.gap sage.rings.finite_rings + sage: M1(m * m) == M1(m) * M1(m) # needs sage.libs.gap sage.rings.finite_rings True """ @@ -542,16 +543,16 @@ def __classcall__(cls, base_ring, nrows, ncols=None, sparse=False, implementatio sage: M2 = MatrixSpace(QQ, 2) sage: M1 is M2 True - sage: M3 = MatrixSpace(QQ, 2, implementation='flint') # optional - sage.libs.flint - sage: M1 is M3 # optional - sage.libs.flint + sage: M3 = MatrixSpace(QQ, 2, implementation='flint') # needs sage.libs.flint + sage: M1 is M3 # needs sage.libs.flint True :: - sage: M = MatrixSpace(ZZ, 10, implementation="flint") # optional - sage.libs.flint - sage: M # optional - sage.libs.flint + sage: M = MatrixSpace(ZZ, 10, implementation="flint") # needs sage.libs.flint + sage: M # needs sage.libs.flint Full MatrixSpace of 10 by 10 dense matrices over Integer Ring - sage: loads(M.dumps()) is M # optional - sage.libs.flint + sage: loads(M.dumps()) is M # needs sage.libs.flint True sage: MatrixSpace(ZZ, 10, implementation="foobar") @@ -682,7 +683,7 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): 200 x 1 dense matrix over Rational Field (use the '.str()' method to see the entries) sage: A = MatrixSpace(RDF,1000,1000).random_element() sage: B = MatrixSpace(RDF,1000,1000).random_element() - sage: C = A * B # optional - sage.libs.flint + sage: C = A * B We check that :trac:`18186` is fixed:: @@ -755,7 +756,7 @@ def characteristic(self): sage: MatrixSpace(ZZ, 2).characteristic() 0 - sage: MatrixSpace(GF(9), 0).characteristic() # optional - sage.libs.pari + sage: MatrixSpace(GF(9), 0).characteristic() # needs sage.rings.finite_rings 3 """ return self.base_ring().characteristic() @@ -803,14 +804,14 @@ def _copy_zero(self): EXAMPLES:: sage: MS = MatrixSpace(GF(2), 20, 20) - sage: MS._copy_zero # optional - sage.rings.finite_rings + sage: MS._copy_zero # needs sage.rings.finite_rings False sage: MS = MatrixSpace(GF(3), 20, 20) - sage: MS._copy_zero # optional - sage.rings.finite_rings + sage: MS._copy_zero # needs sage.rings.finite_rings True sage: MS = MatrixSpace(GF(3), 200, 200) - sage: MS._copy_zero # optional - sage.rings.finite_rings + sage: MS._copy_zero # needs sage.rings.finite_rings False sage: MS = MatrixSpace(ZZ,200,200) @@ -878,8 +879,8 @@ def _element_constructor_(self, entries, **kwds): [3 4] sage: MS = MatrixSpace(ZZ, 2) - sage: g = Gamma0(5)([1,1,0,1]) # optional - sage.modular - sage: MS(g) # optional - sage.modular + sage: g = Gamma0(5)([1,1,0,1]) # needs sage.modular + sage: MS(g) [1 1] [0 1] @@ -901,10 +902,10 @@ def _element_constructor_(self, entries, **kwds): sage: rings = [ZZ, QQ, RealField(100), ComplexField(100), RDF, CDF] sage: rings.append(PolynomialRing(QQ, 'x')) sage: rings.append(PolynomialRing(CC, 2, 'x')) - sage: rings.append(SR) # optional - sage.symbolic - sage: rings.extend([GF(2), GF(11), GF(2^8,'a'), GF(3^19,'a')]) # optional - sage.libs.pari + sage: rings.append(SR) # needs sage.symbolic + sage: rings.extend([GF(2), GF(11), GF(2^8,'a'), GF(3^19,'a')]) # needs sage.rings.finite_rings sage: x = polygen(QQ) - sage: rings.extend([NumberField(x^3 + 2, 'a'), CyclotomicField(4)]) # optional - sage.rings.number_field + sage: rings.extend([NumberField(x^3 + 2, 'a'), CyclotomicField(4)]) # needs sage.rings.number_field sage: for R in rings: ....: A = MatrixSpace(R, 60, 30, sparse=False)(0) ....: B = A.augment(A) @@ -1156,8 +1157,8 @@ def _coerce_map_from_(self, S): Coercion map: From: General Linear Group of degree 2 over Finite Field of size 3 To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 - sage: MS.coerce_map_from(GL(2, 2)) # optional - sage.libs.pari - sage: MS.coerce_map_from(Gamma1(5)) # optional - sage.libs.pari + sage: MS.coerce_map_from(GL(2, 2)) # needs sage.rings.finite_rings + sage: MS.coerce_map_from(Gamma1(5)) # needs sage.rings.finite_rings Coercion map: From: Congruence Subgroup Gamma1(5) To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 @@ -1181,7 +1182,7 @@ def _coerce_map_from_(self, S): sage: m = R([[1, 0], [0, 1]]) sage: m in G True - sage: m in list(G) # optional - sage.libs.gap + sage: m in list(G) # needs sage.libs.gap True sage: m == G(m) True @@ -1199,9 +1200,9 @@ def _coerce_map_from_(self, S): poset):: sage: S = [] - sage: S += [MatrixSpace(ZZ, 3, implementation='flint')] # optional - sage.libs.flint + sage: S += [MatrixSpace(ZZ, 3, implementation='flint')] # needs sage.libs.flint sage: S += [MatrixSpace(ZZ, 3, implementation='generic')] - sage: S += [MatrixSpace(ZZ, 3, implementation='gap')] # optional - sage.libs.gap + sage: S += [MatrixSpace(ZZ, 3, implementation='gap')] # needs sage.libs.gap sage: S += [MatrixSpace(ZZ, 3, sparse=True)] sage: mult = '' sage: for A in S: @@ -1211,7 +1212,7 @@ def _coerce_map_from_(self, S): ....: else: ....: mult += ' ' ....: mult += '\n' - sage: print(mult) # optional - sage.libs.flint sage.libs.gap + sage: print(mult) # needs sage.libs.flint sage.libs.gap XXXX X X XX @@ -1291,7 +1292,7 @@ def _repr_(self): sage: MS Full MatrixSpace of 2 by 4 sparse matrices over Integer Ring - sage: MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint + sage: MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.flint Full MatrixSpace of 2 by 2 dense matrices over Integer Ring sage: MatrixSpace(ZZ, 2, implementation='generic') Full MatrixSpace of 2 by 2 dense matrices over Integer Ring (using Matrix_generic_dense) @@ -1353,7 +1354,7 @@ def __len__(self): sage: 3^(2*3) 729 - sage: len(MatrixSpace(GF(2003), 3, 2)) # optional - sage.libs.pari + sage: len(MatrixSpace(GF(2003), 3, 2)) # needs sage.rings.finite_rings Traceback (most recent call last): ... OverflowError: cannot fit 'int' into an index-sized integer @@ -1807,10 +1808,10 @@ def identity_matrix(self): Check different implementations:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1.identity_matrix()) # optional - sage.libs.flint + sage: type(M1.identity_matrix()) # needs sage.libs.flint sage: type(M2.identity_matrix()) @@ -1865,10 +1866,10 @@ def diagonal_matrix(self, entries): Check different implementations:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # optional - sage.libs.flint + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.flint sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1.diagonal_matrix([1, 2])) # optional - sage.libs.flint + sage: type(M1.diagonal_matrix([1, 2])) # needs sage.libs.flint sage: type(M2.diagonal_matrix([1, 2])) @@ -1901,9 +1902,9 @@ def is_sparse(self): EXAMPLES:: - sage: Mat(GF(2011), 10000).is_sparse() # optional - sage.libs.pari + sage: Mat(GF(2011), 10000).is_sparse() # needs sage.rings.finite_rings False - sage: Mat(GF(2011), 10000, sparse=True).is_sparse() # optional - sage.libs.pari + sage: Mat(GF(2011), 10000, sparse=True).is_sparse() # needs sage.rings.finite_rings True """ return self.__is_sparse @@ -2062,8 +2063,8 @@ def matrix(self, x=None, **kwds): [2] sage: MS = MatrixSpace(CC, 2, 1) sage: x = polygen(ZZ, 'x') - sage: F = NumberField(x^2 + 1, name='x') # optional - sage.rings.number_field - sage: MS([F(1), F(0)]) # optional - sage.rings.number_field + sage: F = NumberField(x^2 + 1, name='x') # needs sage.rings.number_field + sage: MS([F(1), F(0)]) # needs sage.rings.number_field [ 1.00000000000000] [0.000000000000000] @@ -2086,19 +2087,20 @@ def matrix(self, x=None, **kwds): Check that :trac:`13302` is fixed:: - sage: MatrixSpace(Qp(3),1,1)([Qp(3).zero()]) + sage: MatrixSpace(Qp(3), 1,1)([Qp(3).zero()]) # needs sage.rings.padics [0] - sage: MatrixSpace(Qp(3),1,1)([Qp(3)(4/3)]) + sage: MatrixSpace(Qp(3), 1,1)([Qp(3)(4/3)]) # needs sage.rings.padics [3^-1 + 1 + O(3^19)] One-rowed matrices over combinatorial free modules used to break the constructor (:trac:`17124`). Check that this is fixed:: + sage: # needs sage.combinat sage: Sym = SymmetricFunctions(ZZ) sage: h = Sym.h() - sage: MatrixSpace(h,1,1)([h[1]]) + sage: MatrixSpace(h, 1,1)([h[1]]) [h[1]] - sage: MatrixSpace(h,2,1)([h[1], h[2]]) + sage: MatrixSpace(h, 2,1)([h[1], h[2]]) [h[1]] [h[2]] @@ -2186,7 +2188,7 @@ def column_space(self): EXAMPLES:: - sage: M = Mat(GF(9,'a'), 20, 5, sparse=True); M.column_space() # optional - sage.libs.pari + sage: M = Mat(GF(9,'a'), 20, 5, sparse=True); M.column_space() # needs sage.rings.finite_rings Sparse vector space of dimension 20 over Finite Field in a of size 3^2 """ try: @@ -2243,10 +2245,10 @@ def random_element(self, density=None, *args, **kwds): sage: TestSuite(M).run() sage: M = Mat(QQ, 3, sparse=True).random_element() - sage: TestSuite(M).run() # optional - sage.libs.pari + sage: TestSuite(M).run() # needs sage.libs.pari - sage: M = Mat(GF(9,'a'), 3, sparse=True).random_element() # optional - sage.libs.pari - sage: TestSuite(M).run() # optional - sage.libs.pari + sage: M = Mat(GF(9,'a'), 3, sparse=True).random_element() # needs sage.rings.finite_rings + sage: TestSuite(M).run() # needs sage.rings.finite_rings """ Z = self.zero_matrix().__copy__() if density is None: @@ -2343,8 +2345,8 @@ def some_elements(self): [ 1/2 -1/2 2] [1 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0] [0 0 0] [ -2 0 1], [0 0 0], [0 0 0], [0 0 0], [1 0 0], [0 1 0], [0 0 1] ) - sage: M = MatrixSpace(SR, 2, 2) # optional - sage.symbolic - sage: tuple(M.some_elements()) # optional - sage.symbolic + sage: M = MatrixSpace(SR, 2, 2) # needs sage.symbolic + sage: tuple(M.some_elements()) # needs sage.symbolic ( [some_variable some_variable] [1 0] [0 1] [0 0] [0 0] [some_variable some_variable], [0 0], [0 0], [1 0], [0 1] @@ -2381,7 +2383,7 @@ def _polymake_init_(self): sage: polymake(MatrixSpace(QQ, 3)) # optional - jupymake Matrix - sage: polymake(MatrixSpace(QuadraticField(5), 3)) # optional - jupymake # optional - sage.rings.number_field + sage: polymake(MatrixSpace(QuadraticField(5), 3)) # optional - jupymake, needs sage.rings.number_field Matrix """ from sage.interfaces.polymake import polymake @@ -2486,23 +2488,23 @@ def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, check sage: from sage.matrix.matrix_space import _test_trivial_matrices_inverse as tinv sage: tinv(ZZ, sparse=True) - sage: tinv(ZZ, sparse=False, implementation='flint') # optional - sage.libs.flint + sage: tinv(ZZ, sparse=False, implementation='flint') sage: tinv(ZZ, sparse=False, implementation='generic') sage: tinv(QQ, sparse=True) - sage: tinv(QQ, sparse=False, implementation='flint') # optional - sage.libs.flint + sage: tinv(QQ, sparse=False, implementation='flint') sage: tinv(QQ, sparse=False, implementation='generic') sage: tinv(GF(11), sparse=True) sage: tinv(GF(11), sparse=False) sage: tinv(GF(2), sparse=True) sage: tinv(GF(2), sparse=False) - sage: tinv(SR, sparse=True) # optional - sage.symbolic - sage: tinv(SR, sparse=False) # optional - sage.symbolic + sage: tinv(SR, sparse=True) # needs sage.symbolic + sage: tinv(SR, sparse=False) # needs sage.symbolic sage: tinv(RDF, sparse=True) sage: tinv(RDF, sparse=False) sage: tinv(CDF, sparse=True) sage: tinv(CDF, sparse=False) - sage: tinv(CyclotomicField(7), sparse=True) # optional - sage.rings.number_field - sage: tinv(CyclotomicField(7), sparse=False) # optional - sage.rings.number_field + sage: tinv(CyclotomicField(7), sparse=True) # needs sage.rings.number_field + sage: tinv(CyclotomicField(7), sparse=False) # needs sage.rings.number_field sage: tinv(QQ['x,y'], sparse=True) sage: tinv(QQ['x,y'], sparse=False) diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index de62df71f60..ada66d6a2ce 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -636,12 +636,12 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: sage: m = matrix(ZZ, 3, range(9), sparse=True) - sage: phi = ZZ.hom(GF(5)) # optional - sage.libs.pari - sage: m.apply_morphism(phi) # optional - sage.libs.pari + sage: phi = ZZ.hom(GF(5)) + sage: m.apply_morphism(phi) [0 1 2] [3 4 0] [1 2 3] - sage: m.apply_morphism(phi).parent() # optional - sage.libs.pari + sage: m.apply_morphism(phi).parent() Full MatrixSpace of 3 by 3 sparse matrices over Finite Field of size 5 """ @@ -672,24 +672,24 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: sage: m = matrix(ZZ, 10000, {(1,2): 17}, sparse=True) - sage: k. = GF(9) # optional - sage.libs.pari - sage: f = lambda x: k(x) # optional - sage.libs.pari - sage: n = m.apply_map(f) # optional - sage.libs.pari - sage: n.parent() # optional - sage.libs.pari + sage: k. = GF(9) # needs sage.rings.finite_rings + sage: f = lambda x: k(x) + sage: n = m.apply_map(f) # needs sage.rings.finite_rings + sage: n.parent() # needs sage.rings.finite_rings Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field in a of size 3^2 - sage: n[1, 2] # optional - sage.libs.pari + sage: n[1, 2] # needs sage.rings.finite_rings 2 An example where the codomain is explicitly specified. :: - sage: n = m.apply_map(lambda x:x%3, GF(3)) # optional - sage.libs.pari - sage: n.parent() # optional - sage.libs.pari + sage: n = m.apply_map(lambda x: x%3, GF(3)) + sage: n.parent() Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field of size 3 - sage: n[1, 2] # optional - sage.libs.pari + sage: n[1, 2] 2 If we did not specify the codomain, the resulting matrix in the @@ -809,8 +809,8 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: - sage: m = matrix(2, [x^i for i in range(4)], sparse=True) # optional - sage.symbolic - sage: m._derivative(x) # optional - sage.symbolic + sage: m = matrix(2, [x^i for i in range(4)], sparse=True) # needs sage.symbolic + sage: m._derivative(x) # needs sage.symbolic [ 0 1] [ 2*x 3*x^2] """ @@ -1178,10 +1178,11 @@ cdef class Matrix_sparse(matrix.Matrix): Check that the bug in :trac:`13854` has been fixed:: - sage: A. = FreeAlgebra(QQ, 2) # optional - sage.combinat - sage: P. = A.g_algebra(relations={y*x: -x*y}, order='lex') # optional - sage.combinat - sage: M = Matrix([[x]], sparse=True) # optional - sage.combinat - sage: w = vector([y]) # optional - sage.combinat + sage: # needs sage.combinat + sage: A. = FreeAlgebra(QQ, 2) + sage: P. = A.g_algebra(relations={y*x: -x*y}, order='lex') + sage: M = Matrix([[x]], sparse=True) + sage: w = vector([y]) doctest:...: UserWarning: You are constructing a free module over a noncommutative ring. Sage does not have a concept of left/right and both sided modules, so be careful. @@ -1192,7 +1193,7 @@ cdef class Matrix_sparse(matrix.Matrix): of left/right and both sided modules, so be careful. It's also not guaranteed that all multiplications are done from the right side. - sage: M*w # optional - sage.combinat + sage: M*w (x*y) """ cdef int i, j diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index 0d19218849d..69cc34d221e 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -81,8 +81,8 @@ class OperationTable(SageObject): In its most basic use, the table needs a structure and an operation:: sage: from sage.matrix.operation_table import OperationTable - sage: G = SymmetricGroup(3) # optional - sage.groups - sage: OperationTable(G, operation=operator.mul) # optional - sage.groups + sage: G = SymmetricGroup(3) # needs sage.groups + sage: OperationTable(G, operation=operator.mul) # needs sage.groups * a b c d e f +------------ a| a b c d e f @@ -112,8 +112,8 @@ class OperationTable(SageObject): 26 elements. :: sage: from sage.matrix.operation_table import OperationTable - sage: G = DihedralGroup(14) # optional - sage.groups - sage: OperationTable(G, operator.mul, names='letters') # optional - sage.groups + sage: G = DihedralGroup(14) # needs sage.groups + sage: OperationTable(G, operator.mul, names='letters') # needs sage.groups * aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb +------------------------------------------------------------------------------------ aa| aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb @@ -149,8 +149,8 @@ class OperationTable(SageObject): zeros to make a common width. :: sage: from sage.matrix.operation_table import OperationTable - sage: G = AlternatingGroup(4) # optional - sage.groups - sage: OperationTable(G, operator.mul, names='digits') # optional - sage.groups + sage: G = AlternatingGroup(4) # needs sage.groups + sage: OperationTable(G, operator.mul, names='digits') # needs sage.groups * 00 01 02 03 04 05 06 07 08 09 10 11 +------------------------------------ 00| 00 01 02 03 04 05 06 07 08 09 10 11 @@ -171,8 +171,8 @@ class OperationTable(SageObject): of the elements can be used. :: sage: from sage.matrix.operation_table import OperationTable - sage: G = AlternatingGroup(3) # optional - sage.groups - sage: OperationTable(G, operator.mul, names='elements') # optional - sage.groups + sage: G = AlternatingGroup(3) # needs sage.groups + sage: OperationTable(G, operator.mul, names='elements') # needs sage.groups * () (1,2,3) (1,3,2) +------------------------ ()| () (1,2,3) (1,3,2) @@ -184,16 +184,17 @@ class OperationTable(SageObject): :meth:`~sage.matrix.operation_table.OperationTable.column_keys` method. :: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = QuaternionGroup() # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: T.column_keys() # optional - sage.groups + sage: G = QuaternionGroup() + sage: T = OperationTable(G, operator.mul) + sage: T.column_keys() ((), (1,2,3,4)(5,6,7,8), ..., (1,8,3,6)(2,7,4,5)) - sage: names=['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] # optional - sage.groups - sage: T.change_names(names=names) # optional - sage.groups - sage: sorted(T.translation().items()) # optional - sage.groups + sage: names=['1', 'I', '-1', '-I', 'J', '-K', '-J', 'K'] + sage: T.change_names(names=names) + sage: sorted(T.translation().items()) [('-1', (1,3)(2,4)(5,7)(6,8)), ..., ('K', (1,8,3,6)(2,7,4,5))] - sage: T # optional - sage.groups + sage: T * 1 I -1 -I J -K -J K +------------------------ 1| 1 I -1 -I J -K -J K @@ -301,12 +302,13 @@ class OperationTable(SageObject): structure, in forms that can be coerced into the structure. Here we demonstrate the proper use first:: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: H = CyclicPermutationGroup(4) # optional - sage.groups - sage: H.list() # optional - sage.groups + sage: H = CyclicPermutationGroup(4) + sage: H.list() [(), (1,2,3,4), (1,3)(2,4), (1,4,3,2)] - sage: elts = ['()', '(1,3)(2,4)'] # optional - sage.groups - sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups + sage: elts = ['()', '(1,3)(2,4)'] + sage: OperationTable(H, operator.mul, elements=elts) * a b +---- a| a b @@ -315,11 +317,12 @@ class OperationTable(SageObject): This can be rewritten so as to pass the actual elements of the group ``H``, using a simple ``for`` loop:: - sage: L = H.list() #list of elements of the group H # optional - sage.groups - sage: elts = [L[i] for i in {0, 2}] # optional - sage.groups - sage: elts # optional - sage.groups + sage: # needs sage.groups + sage: L = H.list() #list of elements of the group H + sage: elts = [L[i] for i in {0, 2}] + sage: elts [(), (1,3)(2,4)] - sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups + sage: OperationTable(H, operator.mul, elements=elts) * a b +---- a| a b @@ -327,31 +330,32 @@ class OperationTable(SageObject): Here are a couple of improper uses:: - sage: elts.append(5) # optional - sage.groups - sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups + sage: # needs sage.groups + sage: elts.append(5) + sage: OperationTable(H, operator.mul, elements=elts) Traceback (most recent call last): ... TypeError: unable to coerce 5 into Cyclic group of order 4 as a permutation group - sage: elts[2] = '(1,3,2,4)' # optional - sage.groups - sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups + sage: elts[2] = '(1,3,2,4)' + sage: OperationTable(H, operator.mul, elements=elts) Traceback (most recent call last): ... TypeError: unable to coerce (1,3,2,4) into Cyclic group of order 4 as a permutation group - sage: elts[2] = '(1,2,3,4)' # optional - sage.groups - sage: OperationTable(H, operator.mul, elements=elts) # optional - sage.groups + sage: elts[2] = '(1,2,3,4)' + sage: OperationTable(H, operator.mul, elements=elts) Traceback (most recent call last): ... ValueError: (1,3)(2,4)*(1,2,3,4)=(1,4,3,2), and so the set is not closed Unusable functions should be recognized as such:: - sage: H = CyclicPermutationGroup(4) # optional - sage.groups - sage: OperationTable(H, operator.add) # optional - sage.groups + sage: H = CyclicPermutationGroup(4) # needs sage.groups + sage: OperationTable(H, operator.add) # needs sage.groups Traceback (most recent call last): ... TypeError: elements () and () of Cyclic group of order 4 as a permutation group are incompatible with operation: - sage: from operator import xor # optional - sage.groups - sage: OperationTable(H, xor) # optional - sage.groups + sage: from operator import xor + sage: OperationTable(H, xor) # needs sage.groups Traceback (most recent call last): ... TypeError: elements () and () of Cyclic group of order 4 as a permutation group are incompatible with operation: @@ -359,9 +363,9 @@ class OperationTable(SageObject): We construct the multiplication table for a finite finitely presented group, where there is no normalization done when computing the hash:: - sage: GU. = FreeGroup() # optional - sage.groups - sage: gr0 = GU / (s^(-2)*t*s*t, t^(-2)*s*t*s, s*t*s*t) # optional - sage.groups - sage: gr0.multiplication_table() # optional - sage.groups + sage: GU. = FreeGroup() # needs sage.groups + sage: gr0 = GU / (s^(-2)*t*s*t, t^(-2)*s*t*s, s*t*s*t) # needs sage.groups + sage: gr0.multiplication_table() # needs sage.groups * a b c d e f g h i j k l +------------------------ a| a b c d e f g h i j k l @@ -388,9 +392,9 @@ def __init__(self, S, operation, names='letters', elements=None): TESTS:: sage: from sage.matrix.operation_table import OperationTable - sage: G = SymmetricGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: TestSuite(T).run() # optional - sage.groups + sage: G = SymmetricGroup(3) # needs sage.groups + sage: T = OperationTable(G, operator.mul) # needs sage.groups + sage: TestSuite(T).run() # needs sage.groups """ # Determine the elements of S, specified or not # If elements are given, we check if they are all in S @@ -509,15 +513,16 @@ def _name_maker(self, names): and :meth:`change_names` methods. So we just demonstrate the nature of the output here. :: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = SymmetricGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: w, l, d = T._name_maker('letters') # optional - sage.groups - sage: w # optional - sage.groups + sage: G = SymmetricGroup(3) + sage: T = OperationTable(G, operator.mul) + sage: w, l, d = T._name_maker('letters') + sage: w 1 - sage: l[0] # optional - sage.groups + sage: l[0] 'a' - sage: d['a'] # optional - sage.groups + sage: d['a'] () TESTS: @@ -526,18 +531,19 @@ def _name_maker(self, names): doctests for the :class:`OperationTable` and :meth:`change_names` methods that rely on this one. :: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = AlternatingGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: T._name_maker(['x']) # optional - sage.groups + sage: G = AlternatingGroup(3) + sage: T = OperationTable(G, operator.mul) + sage: T._name_maker(['x']) Traceback (most recent call last): ... ValueError: list of element names must be the same size as the set, 1 != 3 - sage: T._name_maker(['x', 'y', 4]) # optional - sage.groups + sage: T._name_maker(['x', 'y', 4]) Traceback (most recent call last): ... ValueError: list of element names must only contain strings, not 4 - sage: T._name_maker('blatzo') # optional - sage.groups + sage: T._name_maker('blatzo') Traceback (most recent call last): ... ValueError: element names must be a list, or one of the keywords: 'letters', 'digits', 'elements' @@ -607,32 +613,34 @@ def __getitem__(self, pair): EXAMPLES:: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = DiCyclicGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: T.column_keys() # optional - sage.groups + sage: G = DiCyclicGroup(3) + sage: T = OperationTable(G, operator.mul) + sage: T.column_keys() ((), (5,6,7), ..., (1,4,2,3)(5,7)) - sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)')] # optional - sage.groups + sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)')] (1,4,2,3)(5,6) TESTS:: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = DiCyclicGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: T[G('(1,2)(3,4)(5,6,7)')] # optional - sage.groups + sage: G = DiCyclicGroup(3) + sage: T = OperationTable(G, operator.mul) + sage: T[G('(1,2)(3,4)(5,6,7)')] Traceback (most recent call last): ... TypeError: indexing into an operation table requires exactly two elements - sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)'), G('(1,3,2,4)(5,7)')] # optional - sage.groups + sage: T[G('(1,2)(3,4)(5,6,7)'), G('(1,3,2,4)(5,7)'), G('(1,3,2,4)(5,7)')] Traceback (most recent call last): ... TypeError: indexing into an operation table requires exactly two elements - sage: T[2, 3] # optional - sage.groups + sage: T[2, 3] Traceback (most recent call last): ... IndexError: invalid indices of operation table: (2, 3) - sage: T['(1,512)', '(1,3,2,4)(5,7)'] # optional - sage.groups + sage: T['(1,512)', '(1,3,2,4)(5,7)'] Traceback (most recent call last): ... IndexError: invalid indices of operation table: ((1,512), (1,3,2,4)(5,7)) @@ -662,14 +670,15 @@ def __eq__(self, other): EXAMPLES:: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = CyclicPermutationGroup(6) # optional - sage.groups - sage: H = CyclicPermutationGroup(3) # optional - sage.groups - sage: P = OperationTable(G, operator.mul) # optional - sage.groups - sage: Q = OperationTable(G, operator.mul) # optional - sage.groups - sage: R = OperationTable(H, operator.mul) # optional - sage.groups - sage: S = OperationTable(G, operator.truediv) # optional - sage.groups - sage: P == P, P == Q, P == R, P == S # optional - sage.groups + sage: G = CyclicPermutationGroup(6) + sage: H = CyclicPermutationGroup(3) + sage: P = OperationTable(G, operator.mul) + sage: Q = OperationTable(G, operator.mul) + sage: R = OperationTable(H, operator.mul) + sage: S = OperationTable(G, operator.truediv) + sage: P == P, P == Q, P == R, P == S (True, True, False, False) """ return (self._elts == other._elts) and (self._operation == other._operation) @@ -680,14 +689,15 @@ def __ne__(self, other): EXAMPLES:: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = CyclicPermutationGroup(6) # optional - sage.groups - sage: H = CyclicPermutationGroup(3) # optional - sage.groups - sage: P = OperationTable(G, operator.mul) # optional - sage.groups - sage: Q = OperationTable(G, operator.mul) # optional - sage.groups - sage: R = OperationTable(H, operator.mul) # optional - sage.groups - sage: S = OperationTable(G, operator.truediv) # optional - sage.groups - sage: P != P, P != Q, P != R, P != S # optional - sage.groups + sage: G = CyclicPermutationGroup(6) + sage: H = CyclicPermutationGroup(3) + sage: P = OperationTable(G, operator.mul) + sage: Q = OperationTable(G, operator.mul) + sage: R = OperationTable(H, operator.mul) + sage: S = OperationTable(G, operator.truediv) + sage: P != P, P != Q, P != R, P != S (False, False, True, True) """ return not self == other @@ -724,33 +734,35 @@ def set_print_symbols(self, ascii, latex): EXAMPLES:: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = AlternatingGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: T.set_print_symbols('@', '\\times') # optional - sage.groups - sage: T # optional - sage.groups + sage: G = AlternatingGroup(3) + sage: T = OperationTable(G, operator.mul) + sage: T.set_print_symbols('@', '\\times') + sage: T @ a b c +------ a| a b c b| b c a c| c a b - sage: T._latex_() # optional - sage.groups + sage: T._latex_() '{\\setlength{\\arraycolsep}{2ex}\n\\begin{array}{r|*{3}{r}}\n\\multicolumn{1}{c|}{\\times}&a&b&c\\\\\\hline\n{}a&a&b&c\\\\\n{}b&b&c&a\\\\\n{}c&c&a&b\\\\\n\\end{array}}' TESTS:: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = AlternatingGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: T.set_print_symbols('@', 5) # optional - sage.groups + sage: G = AlternatingGroup(3) + sage: T = OperationTable(G, operator.mul) + sage: T.set_print_symbols('@', 5) Traceback (most recent call last): ... ValueError: LaTeX symbol must be a string, not 5 - sage: T.set_print_symbols('@x@', '\\times') # optional - sage.groups + sage: T.set_print_symbols('@x@', '\\times') Traceback (most recent call last): ... ValueError: ASCII symbol should be a single character, not @x@ - sage: T.set_print_symbols(5, '\\times') # optional - sage.groups + sage: T.set_print_symbols(5, '\\times') Traceback (most recent call last): ... ValueError: ASCII symbol should be a single character, not 5 @@ -781,9 +793,9 @@ def column_keys(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G = AlternatingGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: T.column_keys() # optional - sage.groups + sage: G = AlternatingGroup(3) # needs sage.groups + sage: T = OperationTable(G, operator.mul) # needs sage.groups + sage: T.column_keys() # needs sage.groups ((), (1,2,3), (1,3,2)) """ return self._elts @@ -807,9 +819,9 @@ def translation(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: G = AlternatingGroup(3) # optional - sage.groups - sage: T = OperationTable(G, operator.mul, names=['p','q','r']) # optional - sage.groups - sage: T.translation() # optional - sage.groups + sage: G = AlternatingGroup(3) # needs sage.groups + sage: T = OperationTable(G, operator.mul, names=['p','q','r']) # needs sage.groups + sage: T.translation() # needs sage.groups {'p': (), 'q': (1,2,3), 'r': (1,3,2)} """ return self._name_dict @@ -828,9 +840,9 @@ def table(self): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: C = CyclicPermutationGroup(3) # optional - sage.groups - sage: T=OperationTable(C, operator.mul) # optional - sage.groups - sage: T.table() # optional - sage.groups + sage: C = CyclicPermutationGroup(3) # needs sage.groups + sage: T=OperationTable(C, operator.mul) # needs sage.groups + sage: T.table() # needs sage.groups [[0, 1, 2], [1, 2, 0], [2, 0, 1]] """ return self._table @@ -869,47 +881,48 @@ def change_names(self, names): :class:`OperationTable` since creating a new operation table uses the same routine. :: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: D = DihedralGroup(2) # optional - sage.groups - sage: T = OperationTable(D, operator.mul) # optional - sage.groups - sage: T # optional - sage.groups + sage: D = DihedralGroup(2) + sage: T = OperationTable(D, operator.mul) + sage: T * a b c d +-------- a| a b c d b| b a d c c| c d a b d| d c b a - sage: T.translation()['c'] # optional - sage.groups + sage: T.translation()['c'] (1,2) - sage: T.change_names('digits') # optional - sage.groups - sage: T # optional - sage.groups + sage: T.change_names('digits') + sage: T * 0 1 2 3 +-------- 0| 0 1 2 3 1| 1 0 3 2 2| 2 3 0 1 3| 3 2 1 0 - sage: T.translation()['2'] # optional - sage.groups + sage: T.translation()['2'] (1,2) - sage: T.change_names('elements') # optional - sage.groups - sage: T # optional - sage.groups + sage: T.change_names('elements') + sage: T * () (3,4) (1,2) (1,2)(3,4) +-------------------------------------------- ()| () (3,4) (1,2) (1,2)(3,4) (3,4)| (3,4) () (1,2)(3,4) (1,2) (1,2)| (1,2) (1,2)(3,4) () (3,4) (1,2)(3,4)| (1,2)(3,4) (1,2) (3,4) () - sage: T.translation()['(1,2)'] # optional - sage.groups + sage: T.translation()['(1,2)'] (1,2) - sage: T.change_names(['w', 'x', 'y', 'z']) # optional - sage.groups - sage: T # optional - sage.groups + sage: T.change_names(['w', 'x', 'y', 'z']) + sage: T * w x y z +-------- w| w x y z x| x w z y y| y z w x z| z y x w - sage: T.translation()['y'] # optional - sage.groups + sage: T.translation()['y'] (1,2) """ self._width, self._names, self._name_dict = self._name_maker(names) @@ -926,17 +939,18 @@ def matrix_of_variables(self): The output here is from the doctests for the old ``cayley_table()`` method for permutation groups. :: + sage: # needs sage.groups sage: from sage.matrix.operation_table import OperationTable - sage: G = PermutationGroup(['(1,2,3)', '(2,3)']) # optional - sage.groups - sage: T = OperationTable(G, operator.mul) # optional - sage.groups - sage: T.matrix_of_variables() # optional - sage.groups + sage: G = PermutationGroup(['(1,2,3)', '(2,3)']) + sage: T = OperationTable(G, operator.mul) + sage: T.matrix_of_variables() [x0 x1 x2 x3 x4 x5] [x1 x0 x3 x2 x5 x4] [x2 x4 x0 x5 x1 x3] [x3 x5 x1 x4 x0 x2] [x4 x2 x5 x0 x3 x1] [x5 x3 x4 x1 x2 x0] - sage: T.column_keys()[2]*T.column_keys()[2] == T.column_keys()[0] # optional - sage.groups + sage: T.column_keys()[2]*T.column_keys()[2] == T.column_keys()[0] True """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -963,8 +977,8 @@ def color_table(self, element_names=True, cmap=None, **options): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # optional - sage.plot sage.groups - sage: OTa.color_table() # optional - sage.plot sage.groups + sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # needs sage.groups sage.plot + sage: OTa.color_table() # needs sage.groups sage.plot Graphics object consisting of 37 graphics primitives .. PLOT:: @@ -1023,8 +1037,8 @@ def gray_table(self, **options): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # optional - sage.plot sage.groups - sage: OTa.gray_table() # optional - sage.plot sage.groups + sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # needs sage.groups sage.plot + sage: OTa.gray_table() # needs sage.groups sage.plot Graphics object consisting of 37 graphics primitives .. PLOT:: diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 71d60ea1198..2570b95a316 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -7,7 +7,7 @@ For example, here is a circulant matrix of order five:: - sage: matrix.circulant(SR.var('a b c d e')) # optional - sage.symbolic + sage: matrix.circulant(SR.var('a b c d e')) # needs sage.symbolic [a b c d e] [e a b c d] [d e a b c] @@ -362,22 +362,22 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation sage: expected_density = (1 - (4/5)^3) sage: float(expected_density) 0.488 - sage: while abs(density_sum/total_count - expected_density) > 0.001: # optional - sage.libs.flint (o/w timeout) + sage: while abs(density_sum/total_count - expected_density) > 0.001: ....: add_sample(ZZ, 5, x=-10, y=10, density=0.75) sage: density_sum = 0.0 sage: total_count = 0.0 sage: add_sample(ZZ, 5, x=20, y=30, density=0.75) - sage: while abs(density_sum/total_count - expected_density) > 0.001: # optional - sage.libs.flint + sage: while abs(density_sum/total_count - expected_density) > 0.001: # needs sage.libs.flint ....: add_sample(ZZ, 5, x=20, y=30, density=0.75) sage: density_sum = 0.0 sage: total_count = 0.0 - sage: add_sample(ZZ, 100, x=20, y=30, density=0.75) # optional - sage.libs.flint + sage: add_sample(ZZ, 100, x=20, y=30, density=0.75) # needs sage.libs.flint sage: expected_density = (1 - (99/100)^75) sage: float(expected_density) 0.529... - sage: while abs(density_sum/total_count - expected_density) > 0.001: # optional - sage.libs.flint + sage: while abs(density_sum/total_count - expected_density) > 0.001: # needs sage.libs.flint ....: add_sample(ZZ, 100, x=20, y=30, density=0.75) For a matrix with low density it may be advisable to insist on a sparse @@ -393,15 +393,15 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation For algorithm testing you might want to control the number of bits, say 10,000 entries, each limited to 16 bits. :: - sage: A = random_matrix(ZZ, 100, 100, x=2^16); A # optional - sage.libs.flint + sage: A = random_matrix(ZZ, 100, 100, x=2^16); A # needs sage.libs.flint 100 x 100 dense matrix over Integer Ring (use the '.str()' method to see the entries) One can prescribe a specific matrix implementation:: - sage: K. = FiniteField(2^8) # optional - sage.rings.finite_rings - sage: type(random_matrix(K, 2, 5)) # optional - sage.rings.finite_rings + sage: K. = FiniteField(2^8) # needs sage.rings.finite_rings + sage: type(random_matrix(K, 2, 5)) # needs sage.rings.finite_rings - sage: type(random_matrix(K, 2, 5, implementation="generic")) # optional - sage.rings.finite_rings + sage: type(random_matrix(K, 2, 5, implementation="generic")) # needs sage.rings.finite_rings Random rational matrices. Now ``num_bound`` and ``den_bound`` control the @@ -460,11 +460,11 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation randomisation when using the optional meataxe package, we have to make sure that we use the default implementation in this test:: - sage: K. = FiniteField(3^2) # optional - sage.rings.finite_rings - sage: A = random_matrix(K, 2, 5, implementation='generic') # optional - sage.rings.finite_rings + sage: K. = FiniteField(3^2) # needs sage.rings.finite_rings + sage: A = random_matrix(K, 2, 5, implementation='generic') # needs sage.rings.finite_rings sage: type(A) - sage: A.base_ring() is K # optional - sage.rings.finite_rings + sage: A.base_ring() is K # needs sage.rings.finite_rings True sage: TestSuite(A).run() @@ -552,7 +552,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation True sage: all(x in ZZ for x in (A - (-1)*identity_matrix(5)).rref().list()) True - sage: A.jordan_form() # optional - sage.combinat + sage: A.jordan_form() # needs sage.combinat [ 2| 0| 0| 0| 0] [--+--+--+--+--] [ 0| 3| 0| 0| 0] @@ -749,36 +749,36 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): NumPy arrays may be used as input. :: - sage: import numpy # optional - numpy - sage: entries = numpy.array([1.2, 5.6]); entries # optional - numpy + sage: import numpy # needs numpy + sage: entries = numpy.array([1.2, 5.6]); entries # needs numpy array([1.2, 5.6]) - sage: A = diagonal_matrix(3, entries); A # optional - numpy + sage: A = diagonal_matrix(3, entries); A # needs numpy [1.2 0.0 0.0] [0.0 5.6 0.0] [0.0 0.0 0.0] - sage: A.parent() # optional - numpy + sage: A.parent() # needs numpy Full MatrixSpace of 3 by 3 sparse matrices over Real Double Field sage: j = complex(0,1) - sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries # optional - numpy + sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries # needs numpy array([2. +1.j , 8.1+0.j , 3.4+2.6j]) - sage: A = diagonal_matrix(entries); A # optional - numpy + sage: A = diagonal_matrix(entries); A # needs numpy [2.0 + 1.0*I 0.0 0.0] [ 0.0 8.1 0.0] [ 0.0 0.0 3.4 + 2.6*I] - sage: A.parent() # optional - numpy + sage: A.parent() # needs numpy Full MatrixSpace of 3 by 3 sparse matrices over Complex Double Field - sage: entries = numpy.array([4, 5, 6]) # optional - numpy - sage: A = diagonal_matrix(entries); A # optional - numpy + sage: entries = numpy.array([4, 5, 6]) # needs numpy + sage: A = diagonal_matrix(entries); A # needs numpy [4 0 0] [0 5 0] [0 0 6] - sage: A.parent() # optional - numpy + sage: A.parent() # needs numpy Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring - sage: entries = numpy.array([4.1, 5.2, 6.3]) # optional - numpy - sage: A = diagonal_matrix(ZZ, entries); A # optional - numpy + sage: entries = numpy.array([4.1, 5.2, 6.3]) # needs numpy + sage: A = diagonal_matrix(ZZ, entries); A # needs numpy Traceback (most recent call last): ... TypeError: unable to convert 4.1 to an element of Integer Ring @@ -820,7 +820,7 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): Types for the entries need to be iterable (tuple, list, vector, NumPy array, etc):: - sage: diagonal_matrix(x^2) # optional - sage.symbolic + sage: diagonal_matrix(x^2) # needs sage.symbolic Traceback (most recent call last): ... TypeError: 'sage.symbolic.expression.Expression' object is not iterable @@ -2274,19 +2274,19 @@ def companion_matrix(poly, format='right'): [ 1 0 -8] [ 0 1 4] - sage: y = var('y') # optional - sage.symbolic - sage: q = y^3 - 2*y + 1 # optional - sage.symbolic - sage: companion_matrix(q) # optional - sage.symbolic + sage: y = var('y') # needs sage.symbolic + sage: q = y^3 - 2*y + 1 # needs sage.symbolic + sage: companion_matrix(q) # needs sage.symbolic Traceback (most recent call last): ... TypeError: input must be a polynomial (not a symbolic expression, see docstring), or other iterable, not y^3 - 2*y + 1 - sage: coeff_list = [q(y=0)] + [q.coefficient(y^k) # optional - sage.symbolic + sage: coeff_list = [q(y=0)] + [q.coefficient(y^k) # needs sage.symbolic ....: for k in range(1, q.degree(y)+1)] - sage: coeff_list # optional - sage.symbolic + sage: coeff_list # needs sage.symbolic [1, -2, 0, 1] - sage: companion_matrix(coeff_list) # optional - sage.symbolic + sage: companion_matrix(coeff_list) # needs sage.symbolic [ 0 0 -1] [ 1 0 2] [ 0 1 0] @@ -2299,9 +2299,9 @@ def companion_matrix(poly, format='right'): sage: t = polygen(QQ, 't') sage: p = t^12 - 7*t^4 + 28*t^2 - 456 sage: C = companion_matrix(p, format='top') - sage: q = C.minpoly(var='t'); q # optional - sage.libs.pari + sage: q = C.minpoly(var='t'); q # needs sage.libs.pari t^12 - 7*t^4 + 28*t^2 - 456 - sage: p == q # optional - sage.libs.pari + sage: p == q # needs sage.libs.pari True sage: p = t^3 + 3*t - 8 @@ -2310,9 +2310,9 @@ def companion_matrix(poly, format='right'): ....: companion_matrix(p^2), ....: companion_matrix(q), ....: companion_matrix(q) ) - sage: A.charpoly(var='t').factor() # optional - sage.libs.pari + sage: A.charpoly(var='t').factor() # needs sage.libs.pari (t^3 + 3*t - 8)^3 * (t^5 + t - 17)^2 - sage: A.minpoly(var='t').factor() # optional - sage.libs.pari + sage: A.minpoly(var='t').factor() # needs sage.libs.pari (t^3 + 3*t - 8)^2 * (t^5 + t - 17) TESTS:: @@ -2322,7 +2322,7 @@ def companion_matrix(poly, format='right'): ... ValueError: format must be 'right', 'left', 'top' or 'bottom', not junk - sage: companion_matrix(sin(x)) # optional - sage.symbolic + sage: companion_matrix(sin(x)) # needs sage.symbolic Traceback (most recent call last): ... TypeError: input must be a polynomial (not a symbolic expression, see docstring), @@ -2334,8 +2334,8 @@ def companion_matrix(poly, format='right'): ValueError: polynomial (or the polynomial implied by coefficients) must be monic, not a leading coefficient of 896 - sage: F. = GF(2^2) # optional - sage.rings.finite_rings - sage: companion_matrix([4/3, a+1, 1]) # optional - sage.rings.finite_rings + sage: F. = GF(2^2) # needs sage.rings.finite_rings + sage: companion_matrix([4/3, a+1, 1]) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: unable to find common ring for coefficients from polynomial @@ -2640,12 +2640,13 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): Matrices can be generated over any exact ring. :: - sage: F. = GF(2^3) # optional - sage.rings.finite_rings - sage: B = random_matrix(F, 4, 5, algorithm='echelonizable', rank=4, # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = GF(2^3) + sage: B = random_matrix(F, 4, 5, algorithm='echelonizable', rank=4, ....: upper_bound=None) - sage: B.rank() # optional - sage.rings.finite_rings + sage: B.rank() 4 - sage: B.base_ring() is F # optional - sage.rings.finite_rings + sage: B.base_ring() is F True Square matrices over ZZ or QQ with full rank are always unimodular. :: @@ -2985,12 +2986,13 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): A matrix over the number Field in `y` with defining polynomial `y^2-2y-2`. :: + sage: # needs sage.rings.number_field sage: y = polygen(ZZ, 'y') - sage: K = NumberField(y^2 - 2*y - 2, 'y') # optional - sage.rings.number_field - sage: C = random_matrix(K, 3, algorithm='unimodular') # optional - sage.rings.number_field - sage: det(C) # optional - sage.rings.number_field + sage: K = NumberField(y^2 - 2*y - 2, 'y') + sage: C = random_matrix(K, 3, algorithm='unimodular') + sage: det(C) 1 - sage: C.base_ring() is K # optional - sage.rings.number_field + sage: C.base_ring() is K True TESTS: @@ -3004,8 +3006,8 @@ def random_unimodular_matrix(parent, upper_bound=None, max_tries=100): Only matrices over ZZ and QQ can have size control. :: - sage: F. = GF(5^7) # optional - sage.rings.finite_rings - sage: random_matrix(F, 5, algorithm='unimodular', upper_bound=20) # optional - sage.rings.finite_rings + sage: F. = GF(5^7) # needs sage.rings.finite_rings + sage: random_matrix(F, 5, algorithm='unimodular', upper_bound=20) # needs sage.rings.finite_rings Traceback (most recent call last): ... TypeError: only matrices over ZZ or QQ can have size control. @@ -3069,10 +3071,10 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): sage: from sage.matrix.constructor import random_diagonalizable_matrix sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5) sage: A = random_diagonalizable_matrix(matrix_space) - sage: eigenvalues = A.eigenvalues() # optional - sage.rings.number_field - sage: S = A.right_eigenmatrix()[1] # optional - sage.rings.number_field - sage: eigenvalues2 = (S.inverse()*A*S).diagonal() # optional - sage.rings.number_field - sage: sorted(eigenvalues) == sorted(eigenvalues2) # optional - sage.rings.number_field + sage: eigenvalues = A.eigenvalues() # needs sage.rings.number_field + sage: S = A.right_eigenmatrix()[1] # needs sage.rings.number_field + sage: eigenvalues2 = (S.inverse()*A*S).diagonal() # needs sage.rings.number_field + sage: sorted(eigenvalues) == sorted(eigenvalues2) # needs sage.rings.number_field True A diagonalizable matrix with eigenvalues and dimensions designated, @@ -3088,9 +3090,9 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): True sage: all(x in ZZ for x in (B-(6*identity_matrix(6))).rref().list()) True - sage: S = B.right_eigenmatrix()[1] # optional - sage.rings.number_field - sage: eigenvalues2 = (S.inverse()*B*S).diagonal() # optional - sage.rings.number_field - sage: all(e in eigenvalues for e in eigenvalues2) # optional - sage.rings.number_field + sage: S = B.right_eigenmatrix()[1] # needs sage.rings.number_field + sage: eigenvalues2 = (S.inverse()*B*S).diagonal() # needs sage.rings.number_field + sage: all(e in eigenvalues for e in eigenvalues2) # needs sage.rings.number_field True TESTS: @@ -3273,15 +3275,16 @@ def vector_on_axis_rotation_matrix(v, i, ring=None): sage: from sage.matrix.constructor import vector_on_axis_rotation_matrix sage: v = vector((1,2,3)) - sage: vector_on_axis_rotation_matrix(v, 2) * v + sage: vector_on_axis_rotation_matrix(v, 2) * v # needs sage.symbolic (0, 0, sqrt(14)) - sage: vector_on_axis_rotation_matrix(v, 1) * v + sage: vector_on_axis_rotation_matrix(v, 1) * v # needs sage.symbolic (0, sqrt(14), 0) - sage: vector_on_axis_rotation_matrix(v, 0) * v + sage: vector_on_axis_rotation_matrix(v, 0) * v # needs sage.symbolic (sqrt(14), 0, 0) :: + sage: # needs sage.symbolic sage: x,y = var('x,y') sage: v = vector((x,y)) sage: vector_on_axis_rotation_matrix(v, 1) @@ -3298,7 +3301,7 @@ def vector_on_axis_rotation_matrix(v, i, ring=None): :: sage: v = vector((1,2,3,4)) - sage: vector_on_axis_rotation_matrix(v, 0) * v + sage: vector_on_axis_rotation_matrix(v, 0) * v # needs sage.symbolic (sqrt(30), 0, 0, 0) sage: vector_on_axis_rotation_matrix(v, 0, ring=RealField(10)) [ 0.18 0.37 0.55 0.73] @@ -3343,35 +3346,35 @@ def ith_to_zero_rotation_matrix(v, i, ring=None): sage: from sage.matrix.constructor import ith_to_zero_rotation_matrix sage: v = vector((1,2,3)) - sage: ith_to_zero_rotation_matrix(v, 2) + sage: ith_to_zero_rotation_matrix(v, 2) # needs sage.symbolic [ 1 0 0] [ 0 2/13*sqrt(13) 3/13*sqrt(13)] [ 0 -3/13*sqrt(13) 2/13*sqrt(13)] - sage: ith_to_zero_rotation_matrix(v, 2) * v + sage: ith_to_zero_rotation_matrix(v, 2) * v # needs sage.symbolic (1, sqrt(13), 0) :: - sage: ith_to_zero_rotation_matrix(v, 0) + sage: ith_to_zero_rotation_matrix(v, 0) # needs sage.symbolic [ 3/10*sqrt(10) 0 -1/10*sqrt(10)] [ 0 1 0] [ 1/10*sqrt(10) 0 3/10*sqrt(10)] - sage: ith_to_zero_rotation_matrix(v, 1) + sage: ith_to_zero_rotation_matrix(v, 1) # needs sage.symbolic [ 1/5*sqrt(5) 2/5*sqrt(5) 0] [-2/5*sqrt(5) 1/5*sqrt(5) 0] [ 0 0 1] - sage: ith_to_zero_rotation_matrix(v, 2) + sage: ith_to_zero_rotation_matrix(v, 2) # needs sage.symbolic [ 1 0 0] [ 0 2/13*sqrt(13) 3/13*sqrt(13)] [ 0 -3/13*sqrt(13) 2/13*sqrt(13)] :: - sage: ith_to_zero_rotation_matrix(v, 0) * v + sage: ith_to_zero_rotation_matrix(v, 0) * v # needs sage.symbolic (0, 2, sqrt(10)) - sage: ith_to_zero_rotation_matrix(v, 1) * v + sage: ith_to_zero_rotation_matrix(v, 1) * v # needs sage.symbolic (sqrt(5), 0, 3) - sage: ith_to_zero_rotation_matrix(v, 2) * v + sage: ith_to_zero_rotation_matrix(v, 2) * v # needs sage.symbolic (1, sqrt(13), 0) Other ring:: @@ -3387,6 +3390,7 @@ def ith_to_zero_rotation_matrix(v, i, ring=None): On the symbolic ring:: + sage: # needs sage.symbolic sage: x,y,z = var('x,y,z') sage: v = vector((x,y,z)) sage: ith_to_zero_rotation_matrix(v, 2) @@ -3492,7 +3496,7 @@ def vandermonde(v, ring=None): A Vandermonde matrix of order three over the symbolic ring:: - sage: matrix.vandermonde(SR.var(['x0', 'x1', 'x2'])) # optional - sage.symbolic + sage: matrix.vandermonde(SR.var(['x0', 'x1', 'x2'])) # needs sage.symbolic [ 1 x0 x0^2] [ 1 x1 x1^2] [ 1 x2 x2^2] @@ -3579,7 +3583,7 @@ def hankel(c, r=None, ring=None): A Hankel matrix with symbolic entries:: - sage: matrix.hankel(SR.var('a, b, c, d, e')) # optional - sage.symbolic + sage: matrix.hankel(SR.var('a, b, c, d, e')) # needs sage.symbolic [a b c d e] [b c d e 0] [c d e 0 0] @@ -3588,7 +3592,7 @@ def hankel(c, r=None, ring=None): We can also pass the elements of the last row, starting at the second column:: - sage: matrix.hankel(SR.var('a, b, c, d, e'), SR.var('f, g, h, i')) # optional - sage.symbolic + sage: matrix.hankel(SR.var('a, b, c, d, e'), SR.var('f, g, h, i')) # needs sage.symbolic [a b c d e] [b c d e f] [c d e f g] diff --git a/src/sage/matrix/tests.py b/src/sage/matrix/tests.py index c2e2ef74afc..9208a5d4d72 100644 --- a/src/sage/matrix/tests.py +++ b/src/sage/matrix/tests.py @@ -45,7 +45,7 @@ sage: matrix(QQ, 2, 2, [1, 1, 1, 1]) / (1/2) [2 2] [2 2] - sage: matrix(QQ['x,y'], 2, 2, [1, 1, 1, 1]) / x # optional - sage.symbolic + sage: matrix(QQ['x,y'], 2, 2, [1, 1, 1, 1]) / x # needs sage.symbolic [1/x 1/x] [1/x 1/x] sage: A = matrix(CC, 2, 2, [1, 1, 1, 1]) / I; A From f3dd891131f1bef48fbff1b70e29aafb6a9d4b06 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 14 Jul 2023 00:08:42 -0700 Subject: [PATCH 66/99] sage.modules: Update # needs --- src/sage/modules/complex_double_vector.py | 5 +- src/sage/modules/fg_pid/fgp_module.py | 34 +-- src/sage/modules/filtered_vector_space.py | 45 +-- src/sage/modules/free_module.py | 138 ++++----- src/sage/modules/free_module_element.pyx | 265 +++++++++-------- src/sage/modules/free_module_integer.py | 47 +-- src/sage/modules/free_module_morphism.py | 148 ++++------ src/sage/modules/free_quadratic_module.py | 4 +- ...free_quadratic_module_integer_symmetric.py | 273 +++++++++--------- src/sage/modules/matrix_morphism.py | 37 +-- src/sage/modules/quotient_module.py | 51 ++-- src/sage/modules/tensor_operations.py | 32 +- src/sage/modules/torsion_quadratic_module.py | 95 +++--- src/sage/modules/tutorial_free_modules.py | 2 +- .../modules/vector_complex_double_dense.pyx | 17 +- src/sage/modules/vector_double_dense.pyx | 12 +- src/sage/modules/vector_integer_dense.pyx | 6 +- src/sage/modules/vector_modn_dense.pyx | 32 +- src/sage/modules/vector_real_double_dense.pyx | 13 +- src/sage/modules/vector_space_morphism.py | 143 ++++----- .../modules/with_basis/indexed_element.pyx | 161 ++++++----- 21 files changed, 796 insertions(+), 764 deletions(-) diff --git a/src/sage/modules/complex_double_vector.py b/src/sage/modules/complex_double_vector.py index faf935694a6..88ad6bb6d67 100644 --- a/src/sage/modules/complex_double_vector.py +++ b/src/sage/modules/complex_double_vector.py @@ -7,10 +7,9 @@ TESTS:: - sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]) - sage: v + sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]); v # needs sage.symbolic (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: loads(dumps(v)) == v + sage: loads(dumps(v)) == v # needs sage.symbolic True """ diff --git a/src/sage/modules/fg_pid/fgp_module.py b/src/sage/modules/fg_pid/fgp_module.py index 02b50c82203..dfc74231fe9 100644 --- a/src/sage/modules/fg_pid/fgp_module.py +++ b/src/sage/modules/fg_pid/fgp_module.py @@ -1084,7 +1084,7 @@ def gens_to_smith(self): EXAMPLES:: sage: L2 = IntegralLattice(3 * matrix([[-2,0,0], [0,1,0], [0,0,-4]])) - sage: D = L2.discriminant_group().normal_form(); D # optional - sage.libs.pari sage.rings.padics + sage: D = L2.discriminant_group().normal_form(); D # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (3, 6, 12) Gram matrix of the quadratic form with values in Q/Z: [1/2 0 0 0 0] @@ -1092,13 +1092,13 @@ def gens_to_smith(self): [ 0 0 1/3 0 0] [ 0 0 0 1/3 0] [ 0 0 0 0 2/3] - sage: D.gens_to_smith() # optional - sage.libs.pari sage.rings.padics + sage: D.gens_to_smith() # needs sage.libs.pari sage.rings.padics [0 3 0] [0 0 3] [0 4 0] [1 2 0] [0 0 4] - sage: T = D.gens_to_smith() * D.smith_to_gens(); T # optional - sage.libs.pari sage.rings.padics + sage: T = D.gens_to_smith() * D.smith_to_gens(); T # needs sage.libs.pari sage.rings.padics [ 3 0 3 0 0] [ 0 33 0 0 3] [ 4 0 4 0 0] @@ -1107,9 +1107,9 @@ def gens_to_smith(self): The matrix `T` now satisfies a certain congruence:: - sage: for i in range(T.nrows()): # optional - sage.libs.pari sage.rings.padics + sage: for i in range(T.nrows()): # needs sage.libs.pari sage.rings.padics ....: T[:,i] = T[:,i] % D.gens()[i].order() - sage: T # optional - sage.libs.pari sage.rings.padics + sage: T # needs sage.libs.pari sage.rings.padics [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] @@ -1135,7 +1135,7 @@ def smith_to_gens(self): EXAMPLES:: sage: L2 = IntegralLattice(3 * matrix([[-2,0,0], [0,1,0], [0,0,-4]])) - sage: D = L2.discriminant_group().normal_form(); D # optional - sage.libs.pari sage.rings.padics + sage: D = L2.discriminant_group().normal_form(); D # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (3, 6, 12) Gram matrix of the quadratic form with values in Q/Z: [1/2 0 0 0 0] @@ -1143,33 +1143,33 @@ def smith_to_gens(self): [ 0 0 1/3 0 0] [ 0 0 0 1/3 0] [ 0 0 0 0 2/3] - sage: D.smith_to_gens() # optional - sage.libs.pari sage.rings.padics + sage: D.smith_to_gens() # needs sage.libs.pari sage.rings.padics [ 0 0 1 1 0] [ 1 0 1 0 0] [ 0 11 0 0 1] - sage: T = D.smith_to_gens() * D.gens_to_smith(); T # optional - sage.libs.pari sage.rings.padics + sage: T = D.smith_to_gens() * D.gens_to_smith(); T # needs sage.libs.pari sage.rings.padics [ 1 6 0] [ 0 7 0] [ 0 0 37] This matrix satisfies the congruence:: - sage: for i in range(T.ncols()): # optional - sage.libs.pari sage.rings.padics + sage: for i in range(T.ncols()): # needs sage.libs.pari sage.rings.padics ....: T[:, i] = T[:, i] % D.smith_form_gens()[i].order() - sage: T # optional - sage.libs.pari sage.rings.padics + sage: T # needs sage.libs.pari sage.rings.padics [1 0 0] [0 1 0] [0 0 1] We create some element of our FGP module:: - sage: x = D.linear_combination_of_smith_form_gens((1,2,3)); x # optional - sage.libs.pari sage.rings.padics + sage: x = D.linear_combination_of_smith_form_gens((1,2,3)); x # needs sage.libs.pari sage.rings.padics (1, 2, 3) and want to know some (it is not unique) linear combination of the user defined generators that is ``x``:: - sage: x.vector() * D.smith_to_gens() # optional - sage.libs.pari sage.rings.padics + sage: x.vector() * D.smith_to_gens() # needs sage.libs.pari sage.rings.padics (2, 33, 3, 1, 3) """ if self.base_ring() != ZZ: @@ -1228,12 +1228,12 @@ def gens_vector(self, x, reduce=False): In our generators:: - sage: v = D.gens_vector(x); v + sage: v = D.gens_vector(x); v # needs sage.libs.pari (2, 9, 3, 1, 33) The output can be further reduced:: - sage: D.gens_vector(x, reduce=True) + sage: D.gens_vector(x, reduce=True) # needs sage.libs.pari (0, 1, 0, 1, 0) Let us check:: @@ -1867,7 +1867,7 @@ def construction(self): sage: T2 = A2 / B2 sage: t1 = T1.an_element() sage: t2 = T2.an_element() - sage: t1 + t2 # optional - sage.libs.flint (o/w infinite recursion) + sage: t1 + t2 # needs sage.libs.flint (o/w infinite recursion) (1, 1) """ from sage.modules.module_functors import QuotientModuleFunctor @@ -2068,8 +2068,8 @@ def _test_morphism_0(*args, **kwds): sage: set_random_seed(s); v = [fgp._test_morphism_0(1) for _ in range(30)] sage: set_random_seed(s); v = [fgp._test_morphism_0(2) for _ in range(30)] sage: set_random_seed(s); v = [fgp._test_morphism_0(3) for _ in range(10)] - sage: set_random_seed(s); v = [fgp._test_morphism_0(i) for i in range(1,20)] # optional - sage.libs.flint (o/w timeout) - sage: set_random_seed(s); v = [fgp._test_morphism_0(4) for _ in range(50)] # long time, optional - sage.libs.flint + sage: set_random_seed(s); v = [fgp._test_morphism_0(i) for i in range(1,20)] # needs sage.libs.flint (o/w timeout) + sage: set_random_seed(s); v = [fgp._test_morphism_0(4) for _ in range(50)] # long time, needs sage.libs.flint """ phi = random_fgp_morphism_0(*args, **kwds) K = phi.kernel() diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index b81e228111d..4ddaee182c7 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -83,17 +83,17 @@ Any field can be used as the vector space base. For example a finite field:: - sage: F. = GF(5^3) # optional - sage.libs.pari - sage: r1 = (a, 0, F(5)); r1 # optional - sage.libs.pari + sage: F. = GF(5^3) # needs sage.rings.finite_rings + sage: r1 = (a, 0, F(5)); r1 # needs sage.rings.finite_rings (a, 0, 0) - sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=F) # optional - sage.libs.pari + sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=F) # needs sage.rings.finite_rings GF(125)^2 >= GF(125)^1 in GF(125)^3 Or the algebraic field:: - sage: r1 = (1, 0, 1+QQbar(I)); r1 # optional - sage.rings.number_field + sage: r1 = (1, 0, 1+QQbar(I)); r1 # needs sage.rings.number_field (1, 0, I + 1) - sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=QQbar) # optional - sage.rings.number_field + sage: FilteredVectorSpace([r1, r2, r3], {0:[0,1], oo:[1]}, base_ring=QQbar) # needs sage.rings.number_field Vector space of dimension 2 over Algebraic Field >= Vector space of dimension 1 over Algebraic Field in Vector space of dimension 3 over Algebraic Field @@ -788,11 +788,11 @@ def _repr_field_name(self): sage: FilteredVectorSpace(2, base_ring=QQ)._repr_field_name() 'QQ' - sage: F. = GF(9) # optional - sage.libs.pari - sage: FilteredVectorSpace(2, base_ring=F)._repr_field_name() # optional - sage.libs.pari + sage: F. = GF(9) # needs sage.rings.finite_rings + sage: FilteredVectorSpace(2, base_ring=F)._repr_field_name() # needs sage.rings.finite_rings 'GF(9)' - sage: FilteredVectorSpace(2, base_ring=AA)._repr_field_name() # optional - sage.rings.number_field + sage: FilteredVectorSpace(2, base_ring=AA)._repr_field_name() # needs sage.rings.number_field Traceback (most recent call last): ... NotImplementedError @@ -829,8 +829,8 @@ def _repr_vector_space(self, dim): sage: F3 = FilteredVectorSpace(3, base_ring=GF(3)) sage: F3._repr_vector_space(1234) 'GF(3)^1234' - sage: F3 = FilteredVectorSpace(3, base_ring=AA) # optional - sage.rings.number_field - sage: F3._repr_vector_space(1234) # optional - sage.rings.number_field + sage: F3 = FilteredVectorSpace(3, base_ring=AA) # needs sage.rings.number_field + sage: F3._repr_vector_space(1234) # needs sage.rings.number_field 'Vector space of dimension 1234 over Algebraic Real Field' """ if dim == 0: @@ -886,7 +886,7 @@ def _repr_(self): QQ^1 >= 0 in QQ^2 sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=GF(3)) GF(3)^2 >= GF(3)^1 >= GF(3)^1 >= 0 - sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=AA) # optional - sage.rings.number_field + sage: FilteredVectorSpace({1:[(1,0), (-1,1)], 3:[(1,0)]}, base_ring=AA) # needs sage.rings.number_field Vector space of dimension 2 over Algebraic Real Field >= Vector space of dimension 1 over Algebraic Real Field >= Vector space of dimension 1 over Algebraic Real Field >= 0 @@ -922,12 +922,13 @@ def __eq__(self, other): TESTS:: - sage: P = toric_varieties.P2() # optional - sage.geometry.polyhedron sage.schemes - sage: T_P = P.sheaves.tangent_bundle() # optional - sage.geometry.polyhedron sage.schemes - sage: O_P = P.sheaves.trivial_bundle(1) # optional - sage.geometry.polyhedron sage.schemes - sage: S1 = T_P + O_P # optional - sage.geometry.polyhedron sage.schemes - sage: S2 = O_P + T_P # optional - sage.geometry.polyhedron sage.schemes - sage: S1._filt[0].is_isomorphic(S2._filt[0]) # known bug # optional - sage.geometry.polyhedron sage.schemes + sage: # needs sage.geometry.polyhedron sage.schemes + sage: P = toric_varieties.P2() + sage: T_P = P.sheaves.tangent_bundle() + sage: O_P = P.sheaves.trivial_bundle(1) + sage: S1 = T_P + O_P + sage: S2 = O_P + T_P + sage: S1._filt[0].is_isomorphic(S2._filt[0]) # known bug True sage: FilteredVectorSpace(2, base_ring=QQ) == FilteredVectorSpace(2, base_ring=GF(5)) @@ -1111,7 +1112,7 @@ def _power_operation(self, n, operation): QQ^2 >= QQ^1 >= 0 sage: F._power_operation(2, 'symmetric') QQ^3 >= QQ^2 >= QQ^1 >= 0 - sage: F._power_operation(2, 'antisymmetric') # optional - sage.groups + sage: F._power_operation(2, 'antisymmetric') # needs sage.groups QQ^1 >= 0 """ from sage.modules.tensor_operations import VectorCollection, TensorOperation @@ -1151,13 +1152,13 @@ def exterior_power(self, n): sage: F = FilteredVectorSpace(1, 1) + FilteredVectorSpace(1, 2); F QQ^2 >= QQ^1 >= 0 - sage: F.exterior_power(1) # optional - sage.groups + sage: F.exterior_power(1) # needs sage.groups QQ^2 >= QQ^1 >= 0 - sage: F.exterior_power(2) # optional - sage.groups + sage: F.exterior_power(2) # needs sage.groups QQ^1 >= 0 - sage: F.exterior_power(3) # optional - sage.groups + sage: F.exterior_power(3) # needs sage.groups 0 - sage: F.wedge(2) # optional - sage.groups + sage: F.wedge(2) # needs sage.groups QQ^1 >= 0 """ return self._power_operation(n, 'antisymmetric') diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 2e671b6658f..3ba7073a381 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -243,11 +243,11 @@ def create_object(self, version, key): sage: R. = QQ[] sage: Q = R.quo(R.ideal([x^2 - y^2 - 1])) - sage: Q.is_integral_domain() # optional - sage.libs.singular + sage: Q.is_integral_domain() # needs sage.libs.singular True - sage: Q2 = FreeModule(Q, 2) # optional - sage.libs.singular - sage: from sage.modules.free_module import FreeModule_ambient_domain # optional - sage.libs.singular - sage: isinstance(Q2, FreeModule_ambient_domain) # optional - sage.libs.singular + sage: Q2 = FreeModule(Q, 2) # needs sage.libs.singular + sage: from sage.modules.free_module import FreeModule_ambient_domain + sage: isinstance(Q2, FreeModule_ambient_domain) # needs sage.libs.singular True """ base_ring, rank, sparse, inner_product_matrix = key @@ -613,7 +613,7 @@ def span(gens, base_ring=None, check=True, already_echelonized=False): [ 1 0 -3] [ 0 1 4] - sage: span([V.gen(0)], QuadraticField(-7,'a')) # optional - sage.rings.number_field + sage: span([V.gen(0)], QuadraticField(-7,'a')) # needs sage.rings.number_field Vector space of degree 3 and dimension 1 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I Basis matrix: @@ -1014,8 +1014,8 @@ def some_elements(self): ... (46/103823, -46/103823, 103823/46)) - sage: F = FreeModule(SR, 2) # optional - sage.symbolic - sage: tuple(F.some_elements()) # optional - sage.symbolic + sage: F = FreeModule(SR, 2) # needs sage.symbolic + sage: tuple(F.some_elements()) # needs sage.symbolic ((1, 0), (some_variable, some_variable)) """ yield self.an_element() @@ -1188,14 +1188,14 @@ def __richcmp__(self, other, op): More exotic comparisons:: - sage: R1 = ZZ[sqrt(2)] - sage: F1 = R1^3 - sage: V1 = F1.span([[sqrt(2),sqrt(2),0]]) + sage: R1 = ZZ[sqrt(2)] # needs sage.symbolic + sage: F1 = R1^3 # needs sage.symbolic + sage: V1 = F1.span([[sqrt(2), sqrt(2), 0]]) # needs sage.symbolic sage: F2 = ZZ^3 sage: V2 = F2.span([[2,2,0]]) - sage: V2 <= V1 # Different ambient vector spaces + sage: V2 <= V1 # Different ambient vector spaces # needs sage.symbolic False - sage: V1 <= V2 + sage: V1 <= V2 # needs sage.symbolic False sage: R2. = GF(5)[] sage: F3 = R2^3 @@ -1643,14 +1643,14 @@ def span(self, gens, base_ring=None, check=True, already_echelonized=False): Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 1 0] - sage: v = V((1, pi, log(2))); v # optional - sage.symbolic + sage: v = V((1, pi, log(2))); v # needs sage.symbolic (1.0, 3.141592653589793, 0.6931471805599453) - sage: W.span([v], base_ring=GF(7)) # optional - sage.rings.finite_rings sage.symbolic + sage: W.span([v], base_ring=GF(7)) # needs sage.rings.finite_rings sage.symbolic Traceback (most recent call last): ... ValueError: argument gens (= [(1.0, 3.141592653589793, 0.6931471805599453)]) is not compatible with base_ring (= Finite Field of size 7) - sage: W = V.submodule([v]) # optional - sage.symbolic - sage: W.span([V.gen(2)], base_ring=GF(7)) # optional - sage.rings.finite_rings sage.symbolic + sage: W = V.submodule([v]) # needs sage.symbolic + sage: W.span([V.gen(2)], base_ring=GF(7)) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [0 0 1] @@ -1811,10 +1811,10 @@ def free_resolution(self, *args, **kwds): sage: S. = PolynomialRing(QQ) sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) - sage: res = N.free_resolution() # optional - sage.libs.singular - sage: res # optional - sage.libs.singular + sage: res = N.free_resolution() # needs sage.libs.singular + sage: res # needs sage.libs.singular S^2 <-- S^2 <-- 0 - sage: ascii_art(res.chain_complex()) # optional - sage.libs.singular + sage: ascii_art(res.chain_complex()) # needs sage.libs.singular [x - y y*z] [ z x*z] 0 <-- C_0 <-------------- C_1 <-- 0 @@ -1843,13 +1843,13 @@ def graded_free_resolution(self, *args, **kwds): sage: S. = PolynomialRing(QQ) sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) - sage: N.graded_free_resolution(shifts=[1, -1]) # optional - sage.libs.singular + sage: N.graded_free_resolution(shifts=[1, -1]) # needs sage.libs.singular S(-1)⊕S(1) <-- S(-2)⊕S(-3) <-- 0 - sage: N.graded_free_resolution(shifts=[2, 3]) # optional - sage.libs.singular + sage: N.graded_free_resolution(shifts=[2, 3]) # needs sage.libs.singular S(-2)⊕S(-3) <-- S(-3)⊕S(-4) <-- 0 sage: N = M.submodule([vector([x^3 - y^6, z^2]), vector([y * z, x])]) - sage: N.graded_free_resolution(degrees=[2, 1, 3], shifts=[2, 3]) # optional - sage.libs.singular + sage: N.graded_free_resolution(degrees=[2, 1, 3], shifts=[2, 3]) # needs sage.libs.singular S(-2)⊕S(-3) <-- S(-6)⊕S(-8) <-- 0 """ from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular @@ -2357,16 +2357,16 @@ def __iter__(self): EXAMPLES:: - sage: V = VectorSpace(GF(4, 'a'), 2) # optional - sage.libs.pari - sage: [x for x in V] # optional - sage.libs.pari + sage: V = VectorSpace(GF(4, 'a'), 2) # needs sage.rings.finite_rings + sage: [x for x in V] # needs sage.rings.finite_rings [(0, 0), (a, 0), (a + 1, 0), (1, 0), (0, a), (a, a), (a + 1, a), (1, a), (0, a + 1), (a, a + 1), (a + 1, a + 1), (1, a + 1), (0, 1), (a, 1), (a + 1, 1), (1, 1)] :: - sage: W = V.subspace([V([1, 1])]) # optional - sage.libs.pari - sage: [x for x in W] # optional - sage.libs.pari + sage: W = V.subspace([V([1, 1])]) # needs sage.rings.finite_rings + sage: [x for x in W] # needs sage.rings.finite_rings [(0, 0), (a, a), (a + 1, a + 1), (1, 1)] Free modules over enumerated infinite rings (i.e., those in the @@ -2466,12 +2466,12 @@ def cardinality(self): EXAMPLES:: - sage: k. = FiniteField(9) # optional - sage.libs.pari - sage: V = VectorSpace(k, 3) # optional - sage.libs.pari - sage: V.cardinality() # optional - sage.libs.pari + sage: k. = FiniteField(9) # needs sage.rings.finite_rings + sage: V = VectorSpace(k, 3) # needs sage.rings.finite_rings + sage: V.cardinality() # needs sage.rings.finite_rings 729 - sage: W = V.span([[1,2,1], [0,1,1]]) # optional - sage.libs.pari - sage: W.cardinality() # optional - sage.libs.pari + sage: W = V.span([[1,2,1], [0,1,1]]) # needs sage.rings.finite_rings + sage: W.cardinality() # needs sage.rings.finite_rings 81 sage: R = IntegerModRing(12) sage: M = FreeModule(R, 2) @@ -2774,7 +2774,7 @@ def coordinate_module(self, V): function to write a submodule in terms of integral cuspidal modular symbols:: - sage: M = ModularSymbols(54) + sage: M = ModularSymbols(54) # needs sage.modular sage: S = M.cuspidal_subspace() sage: K = S.integral_structure(); K Free module of degree 19 and rank 8 over Integer Ring @@ -3398,29 +3398,31 @@ def _magma_init_(self, magma): How about some inexact fields:: - sage: v = vector(RR, [1, pi, 5/6]) # optional - sage.symbolic - sage: F = v.parent() # optional - sage.symbolic - sage: M = magma(F); M # optional - magma # optional - sage.symbolic + sage: # needs sage.symbolic + sage: v = vector(RR, [1, pi, 5/6]) + sage: F = v.parent() + sage: M = magma(F); M # optional - magma Full Vector space of degree 3 over Real field of precision 15 - sage: M.Type() # optional - magma # optional - sage.symbolic + sage: M.Type() # optional - magma ModTupFld - sage: m = M.sage(); m # optional - magma # optional - sage.symbolic + sage: m = M.sage(); m # optional - magma Vector space of dimension 3 over Real Field with 53 bits of precision - sage: m is F # optional - magma # optional - sage.symbolic + sage: m is F # optional - magma True For interval fields, we can convert to Magma but there is no interval field in Magma so we cannot convert back:: - sage: v = vector(RealIntervalField(100), [1, pi, 0.125]) # optional - sage.symbolic - sage: F = v.parent() # optional - sage.symbolic - sage: M = magma(v.parent()); M # optional - magma # optional - sage.symbolic + sage: # needs sage.symbolic + sage: v = vector(RealIntervalField(100), [1, pi, 0.125]) + sage: F = v.parent() + sage: M = magma(v.parent()); M # optional - magma Full Vector space of degree 3 over Real field of precision 30 - sage: M.Type() # optional - magma # optional - sage.symbolic + sage: M.Type() # optional - magma ModTupFld - sage: m = M.sage(); m # optional - magma # optional - sage.symbolic + sage: m = M.sage(); m # optional - magma Vector space of dimension 3 over Real Field with 100 bits of precision - sage: m is F # optional - magma # optional - sage.symbolic + sage: m is F # optional - magma False """ K = magma(self.base_ring()) @@ -3809,7 +3811,7 @@ def intersection(self, other): We intersect two modules over the ring of integers of a number field:: sage: x = polygen(ZZ, 'x') - sage: L. = NumberField(x^2 - x + 2) + sage: L. = NumberField(x^2 - x + 2) # needs sage.rings.number_field sage: OL = L.ring_of_integers() sage: V = L**3 sage: W1 = V.span([[0,w/5,0], [1,0,-1/17]], OL) @@ -4206,10 +4208,11 @@ def vector_space_span(self, gens, check=True): :: sage: R. = QQ[] - sage: K = NumberField(x^2 + 1, 'a'); a = K.gen() # optional - sage.rings.number_field - sage: V = VectorSpace(K, 3) # optional - sage.rings.number_field - sage: V.vector_space_span([2*V.gen(0) + 3*V.gen(2)]) # optional - sage.rings.number_field - Vector space of degree 3 and dimension 1 over Number Field in a with defining polynomial x^2 + 1 + sage: K = NumberField(x^2 + 1, 'a'); a = K.gen() # needs sage.rings.number_field + sage: V = VectorSpace(K, 3) # needs sage.rings.number_field + sage: V.vector_space_span([2*V.gen(0) + 3*V.gen(2)]) # needs sage.rings.number_field + Vector space of degree 3 and dimension 1 + over Number Field in a with defining polynomial x^2 + 1 Basis matrix: [ 1 0 3/2] @@ -5308,14 +5311,15 @@ def __init__(self, base_ring, rank, sparse=False, coordinate_ring=None, category We check that the creation of a submodule does not trigger the construction of a basis of the ambient space. See :trac:`15953`:: - sage: F. = GF(4) # optional - sage.libs.pari - sage: V = VectorSpace(F, 1) # optional - sage.libs.pari - sage: v = V.random_element() # optional - sage.libs.pari - sage: _ = V.subspace([v]) # optional - sage.libs.pari - sage: hasattr(V, '_FreeModule_ambient__basis') # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = GF(4) + sage: V = VectorSpace(F, 1) + sage: v = V.random_element() + sage: _ = V.subspace([v]) + sage: hasattr(V, '_FreeModule_ambient__basis') False - sage: _ = V.basis() # optional - sage.libs.pari - sage: hasattr(V, '_FreeModule_ambient__basis') # optional - sage.libs.pari + sage: _ = V.basis() + sage: hasattr(V, '_FreeModule_ambient__basis') True """ FreeModule_generic.__init__(self, base_ring, rank=rank, @@ -5970,9 +5974,9 @@ def _sympy_(self): EXAMPLES:: - sage: sZZ3 = (ZZ^3)._sympy_(); sZZ3 # optional - sympy + sage: sZZ3 = (ZZ^3)._sympy_(); sZZ3 # needs sympy ProductSet(Integers, Integers, Integers) - sage: (1, 2, 3) in sZZ3 # optional - sympy + sage: (1, 2, 3) in sZZ3 # needs sympy True """ from sympy import ProductSet @@ -6352,9 +6356,9 @@ def _element_constructor_(self, e, *args, **kwds): EXAMPLES:: - sage: k. = GF(3^4) # optional - sage.libs.pari - sage: VS = k.vector_space(map=False) # optional - sage.libs.pari - sage: VS(a) # optional - sage.libs.pari + sage: k. = GF(3^4) # needs sage.rings.finite_rings + sage: VS = k.vector_space(map=False) # needs sage.rings.finite_rings + sage: VS(a) # needs sage.rings.finite_rings (0, 1, 0, 0) """ try: @@ -6465,8 +6469,8 @@ def __init__(self, ambient, basis, check=True, :trac:`10250` is solved as well:: sage: V = (QQ^2).span_of_basis([[1,1]]) - sage: w = sqrt(2) * V([1,1]) # optional - sage.symbolic - sage: 3 * w # optional - sage.symbolic + sage: w = sqrt(2) * V([1,1]) # needs sage.symbolic + sage: 3 * w # needs sage.symbolic (3*sqrt(2), 3*sqrt(2)) TESTS: @@ -6686,9 +6690,9 @@ def _echelonized_basis(self, ambient, basis): sage: W = V.submodule_with_basis([[1,1,0],[0,2,1]]) sage: W._echelonized_basis(V,W.basis()) [(1, 0, -1/2), (0, 1, 1/2)] - sage: V = SR^3 # optional - sage.symbolic - sage: W = V.submodule_with_basis([[1,0,1]]) # optional - sage.symbolic - sage: W._echelonized_basis(V, W.basis()) # optional - sage.symbolic + sage: V = SR^3 # needs sage.symbolic + sage: W = V.submodule_with_basis([[1,0,1]]) + sage: W._echelonized_basis(V, W.basis()) [(1, 0, 1)] """ # Return the first rank rows (i.e., the nonzero rows). @@ -8153,7 +8157,7 @@ def element_class(R, is_sparse): sage: sage.modules.free_module.element_class(FF, is_sparse=True) - sage: sage.modules.free_module.element_class(FF, is_sparse=False) # optional - sage.libs.pari + sage: sage.modules.free_module.element_class(FF, is_sparse=False) # needs sage.rings.finite_rings sage: sage.modules.free_module.element_class(GF(7), is_sparse=False) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index b9a2cd77295..e6e81aa6cc9 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -460,8 +460,8 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): sage: # needs numpy sage: import numpy as np sage: w = np.array([1, 2, pi], float) # needs sage.symbolic - sage: v = vector(w, immutable=True) # needs sage.symbolic - sage: v.is_immutable() # needs sage.symbolic + sage: v = vector(w, immutable=True) + sage: v.is_immutable() True sage: w = np.array([i, 2, 3], complex) sage: v = vector(w, immutable=True) @@ -1012,11 +1012,12 @@ cdef class FreeModuleElement(Vector): # abstract base class Create the multiplication table of `GF(4)` using GP:: - sage: k. = GF(4, impl="pari_ffelt") # needs sage.libs.pari - sage: v = gp(vector(list(k))) # needs sage.libs.pari - sage: v # needs sage.libs.pari + sage: # needs sage.libs.pari + sage: k. = GF(4, impl="pari_ffelt") + sage: v = gp(vector(list(k))) + sage: v [0, 1, a, a + 1] - sage: v.mattranspose() * v # needs sage.libs.pari + sage: v.mattranspose() * v [0, 0, 0, 0; 0, 1, a, a + 1; 0, a, a + 1, 1; 0, a + 1, 1, a] """ # Elements in vectors are always Sage Elements, so they should @@ -1116,7 +1117,7 @@ cdef class FreeModuleElement(Vector): # abstract base class array([ 0, 1, 9223372036854775807]...) sage: wn.dtype # needs numpy dtype('int64') - sage: w.dot_product(w) # needs numpy + sage: w.dot_product(w) 85070591730234615847396907784232501250 sage: wn.dot(wn) # overflow # needs numpy 2 @@ -1141,13 +1142,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,2/3,pi]) # needs sage.symbolic - sage: v.__hash__() # needs sage.symbolic + sage: # needs sage.symbolic + sage: v = vector([1,2/3,pi]) + sage: v.__hash__() Traceback (most recent call last): ... TypeError: mutable vectors are unhashable - sage: v.set_immutable() # needs sage.symbolic - sage: v.__hash__() # random output # needs sage.symbolic + sage: v.set_immutable() + sage: v.__hash__() # random output """ if not self._is_immutable: raise TypeError("mutable vectors are unhashable") @@ -1390,9 +1392,9 @@ cdef class FreeModuleElement(Vector): # abstract base class matrix constructor demonstrates Sage's preference for rows. :: sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # needs sage.symbolic - sage: x.row() == matrix(x) # needs sage.symbolic + sage: x.row() == matrix(x) True - sage: x.row() == x.column().transpose() # needs sage.symbolic + sage: x.row() == x.column().transpose() True Sparse or dense implementations are preserved. :: @@ -1462,9 +1464,9 @@ cdef class FreeModuleElement(Vector): # abstract base class matrix constructor demonstrates Sage's preference for rows. :: sage: x = vector(RDF, [sin(i*pi/20) for i in range(10)]) # needs sage.libs.pari sage.symbolic - sage: x.column() == matrix(x).transpose() # needs sage.libs.pari sage.symbolic + sage: x.column() == matrix(x).transpose() True - sage: x.column() == x.row().transpose() # needs sage.libs.pari sage.symbolic + sage: x.column() == x.row().transpose() True Sparse or dense implementations are preserved. :: @@ -1531,12 +1533,13 @@ cdef class FreeModuleElement(Vector): # abstract base class """ EXAMPLES:: - sage: var('a,b,d,e') # needs sage.symbolic + sage: # needs sage.symbolic + sage: var('a,b,d,e') (a, b, d, e) - sage: v = vector([a, b, d, e]) # needs sage.symbolic - sage: v.substitute(a=1) # needs sage.symbolic + sage: v = vector([a, b, d, e]) + sage: v.substitute(a=1) (1, b, d, e) - sage: v.subs(a=b, b=d) # needs sage.symbolic + sage: v.subs(a=b, b=d) (b, d, d, e) """ return self.parent()([ a.subs(in_dict, **kwds) for a in self.list() ]) @@ -1722,7 +1725,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Symbolic Ring sage: numeric = N(nrm); numeric # needs sage.symbolic 5.83095189484... - sage: numeric.parent() # needs sage.symbolic + sage: numeric.parent() Real Field with 53 bits of precision TESTS: @@ -1755,17 +1758,18 @@ cdef class FreeModuleElement(Vector): # abstract base class """ EXAMPLES:: - sage: v = vector(SR, [0,0,0,0]) # needs sage.symbolic - sage: v == 0 # needs sage.symbolic + sage: # needs sage.symbolic + sage: v = vector(SR, [0,0,0,0]) + sage: v == 0 True - sage: v == 1 # needs sage.symbolic + sage: v == 1 False - sage: v == v # needs sage.symbolic + sage: v == v True - sage: w = vector(SR, [-1,x,pi,0]) # needs sage.symbolic - sage: bool(w < v) # needs sage.symbolic + sage: w = vector(SR, [-1,x,pi,0]) + sage: bool(w < v) True - sage: bool(w > v) # needs sage.symbolic + sage: bool(w > v) False TESTS:: @@ -1780,14 +1784,15 @@ cdef class FreeModuleElement(Vector): # abstract base class Verify that :trac:`33697` is fixed:: - sage: v = vector(SR, [x]) # needs sage.symbolic - sage: w = vector(SR, [1]) # needs sage.symbolic - sage: v == w # needs sage.symbolic + sage: # needs sage.symbolic + sage: v = vector(SR, [x]) + sage: w = vector(SR, [1]) + sage: v == w False - sage: assume(x > 0) # needs sage.symbolic - sage: v == w # needs sage.symbolic + sage: assume(x > 0) + sage: v == w False - sage: forget() # needs sage.symbolic + sage: forget() """ cdef Py_ssize_t i for i in range(left._degree): @@ -2303,15 +2308,16 @@ cdef class FreeModuleElement(Vector): # abstract base class Examples of the plot types:: - sage: A = plot(v, plot_type='arrow') # needs sage.plot - sage: B = plot(v, plot_type='point', color='green', size=20) # needs sage.plot - sage: C = plot(v, plot_type='step') # calls v.plot_step() # needs sage.plot - sage: A+B+C # needs sage.plot + sage: # needs sage.plot + sage: A = plot(v, plot_type='arrow') + sage: B = plot(v, plot_type='point', color='green', size=20) + sage: C = plot(v, plot_type='step') # calls v.plot_step() + sage: A+B+C Graphics object consisting of 3 graphics primitives You can use the optional arguments for :meth:`plot_step`:: - sage: eps = 0.1 # needs sage.plot + sage: eps = 0.1 sage: plot(v, plot_type='step', eps=eps, xmax=5, hue=0) # needs sage.plot Graphics object consisting of 1 graphics primitive @@ -2362,7 +2368,7 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: u = vector([1,1]); v = vector([2,2,2]); z=(3,3,3) # needs sage.plot + sage: u = vector([1,1]); v = vector([2,2,2]); z=(3,3,3) sage: plot(u) #test when start=None # needs sage.plot Graphics object consisting of 1 graphics primitive @@ -2445,7 +2451,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: eps = 0.1 - sage: v = vector(RDF, [sin(n*eps) for n in range(100)]) # needs sage.plot + sage: v = vector(RDF, [sin(n*eps) for n in range(100)]) sage: v.plot_step(eps=eps, xmax=5, hue=0) # needs sage.plot Graphics object consisting of 1 graphics primitive """ @@ -3161,11 +3167,12 @@ cdef class FreeModuleElement(Vector): # abstract base class such as the cyclotomic fields. This example uses such a field containing a primitive 7-th root of unity named ``a``. :: - sage: F. = CyclotomicField(7) # needs sage.rings.number_field - sage: v = vector(F, [a^i for i in range(7)]) # needs sage.rings.number_field - sage: v # needs sage.rings.number_field + sage: # needs sage.rings.number_field + sage: F. = CyclotomicField(7) + sage: v = vector(F, [a^i for i in range(7)]) + sage: v (1, a, a^2, a^3, a^4, a^5, -a^5 - a^4 - a^3 - a^2 - a - 1) - sage: v.conjugate() # needs sage.rings.number_field + sage: v.conjugate() (1, -a^5 - a^4 - a^3 - a^2 - a - 1, a^5, a^4, a^3, a^2, a) Sparse vectors are returned as such. :: @@ -3913,10 +3920,11 @@ cdef class FreeModuleElement(Vector): # abstract base class Check that the bug in :trac:`14558` has been fixed:: - sage: F. = GF(9) # needs sage.rings.finite_rings - sage: v = vector([a, 0, 0, 0], sparse=True) # needs sage.rings.finite_rings - sage: f = F.hom([a**3]) # needs sage.rings.finite_rings - sage: v.apply_map(f) # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = GF(9) + sage: v = vector([a, 0, 0, 0], sparse=True) + sage: f = F.hom([a**3]) + sage: v.apply_map(f) (2*a + 1, 0, 0, 0) """ if sparse is None: @@ -3970,31 +3978,33 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,x,x^2]) # needs sage.symbolic - sage: v._derivative(x) # needs sage.symbolic + sage: # needs sage.symbolic + sage: v = vector([1,x,x^2]) + sage: v._derivative(x) (0, 1, 2*x) - sage: type(v._derivative(x)) == type(v) # needs sage.symbolic + sage: type(v._derivative(x)) == type(v) True - sage: v = vector([1,x,x^2], sparse=True) # needs sage.symbolic - sage: v._derivative(x) # needs sage.symbolic + sage: v = vector([1,x,x^2], sparse=True) + sage: v._derivative(x) (0, 1, 2*x) - sage: type(v._derivative(x)) == type(v) # needs sage.symbolic + sage: type(v._derivative(x)) == type(v) True If no variables are specified and the vector contains callable symbolic expressions, then calculate the matrix derivative (i.e., the Jacobian matrix):: - sage: T(r,theta) = [r*cos(theta), r*sin(theta)] # needs sage.symbolic - sage: T # needs sage.symbolic + sage: # needs sage.symbolic + sage: T(r,theta) = [r*cos(theta), r*sin(theta)] + sage: T (r, theta) |--> (r*cos(theta), r*sin(theta)) - sage: T.diff() # matrix derivative # needs sage.symbolic + sage: T.diff() # matrix derivative [ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)] [ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)] - sage: diff(T) # matrix derivative again # needs sage.symbolic + sage: diff(T) # matrix derivative again [ (r, theta) |--> cos(theta) (r, theta) |--> -r*sin(theta)] [ (r, theta) |--> sin(theta) (r, theta) |--> r*cos(theta)] - sage: T.diff().det() # Jacobian # needs sage.symbolic + sage: T.diff().det() # Jacobian (r, theta) |--> r*cos(theta)^2 + r*sin(theta)^2 """ if var is None: @@ -4018,17 +4028,18 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: v = vector([1,x,x^2]) # needs sage.symbolic - sage: v.derivative(x) # needs sage.symbolic + sage: # needs sage.symbolic + sage: v = vector([1,x,x^2]) + sage: v.derivative(x) (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) # needs sage.symbolic + sage: type(v.derivative(x)) == type(v) True - sage: v = vector([1,x,x^2], sparse=True) # needs sage.symbolic - sage: v.derivative(x) # needs sage.symbolic + sage: v = vector([1,x,x^2], sparse=True) + sage: v.derivative(x) (0, 1, 2*x) - sage: type(v.derivative(x)) == type(v) # needs sage.symbolic + sage: type(v.derivative(x)) == type(v) True - sage: v.derivative(x,x) # needs sage.symbolic + sage: v.derivative(x,x) (0, 0, 2) """ from sage.misc.derivative import multi_derivative @@ -4044,13 +4055,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: t = var('t') # needs sage.symbolic - sage: r = vector([t,t^2,sin(t)]) # needs sage.symbolic - sage: r.integral(t) # needs sage.symbolic + sage: # needs sage.symbolic + sage: t = var('t') + sage: r = vector([t,t^2,sin(t)]) + sage: r.integral(t) (1/2*t^2, 1/3*t^3, -cos(t)) - sage: integrate(r, t) # needs sage.symbolic + sage: integrate(r, t) (1/2*t^2, 1/3*t^3, -cos(t)) - sage: r.integrate(t, 0, 1) # needs sage.symbolic + sage: r.integrate(t, 0, 1) (1/2, 1/3, -cos(1) + 1) """ @@ -4070,20 +4082,22 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: t = var('t') # needs sage.symbolic - sage: r = vector([t,t^2,sin(t)]) # needs sage.symbolic - sage: vec, answers = r.nintegral(t,0,1) # needs sage.symbolic - sage: vec # needs sage.symbolic + sage: # needs sage.symbolic + sage: t = var('t') + sage: r = vector([t,t^2,sin(t)]) + sage: vec, answers = r.nintegral(t,0,1) + sage: vec # abs tol 1e-15 (0.5, 0.3333333333333334, 0.4596976941318602) - sage: type(vec) # needs sage.symbolic + sage: type(vec) - sage: answers # needs sage.symbolic + sage: answers [(0.5, 5.55111512312578...e-15, 21, 0), (0.3333333333333..., 3.70074341541719...e-15, 21, 0), (0.45969769413186..., 5.10366964392284...e-15, 21, 0)] - sage: r = vector([t,0,1], sparse=True) # needs sage.symbolic - sage: r.nintegral(t, 0, 1) # needs sage.symbolic + sage: # needs sage.symbolic + sage: r = vector([t,0,1], sparse=True) + sage: r.nintegral(t, 0, 1) ((0.5, 0.0, 1.0), {0: (0.5, 5.55111512312578...e-15, 21, 0), 2: (1.0, 1.11022302462515...e-14, 21, 0)}) @@ -4175,14 +4189,14 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): :: sage: v = vector([1,2/3,pi]) # needs sage.symbolic - sage: v == v # needs sage.symbolic + sage: v == v True :: sage: v = vector(RR, [1,2/3,pi]) # needs sage.symbolic - sage: v.set_immutable() # needs sage.symbolic - sage: isinstance(hash(v), int) # needs sage.symbolic + sage: v.set_immutable() + sage: isinstance(hash(v), int) True """ cdef _new_c(self, object v): @@ -4215,12 +4229,13 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: v = vector([-1,0,3,pi]) # needs sage.symbolic - sage: type(v) # needs sage.symbolic + sage: # needs sage.symbolic + sage: v = vector([-1,0,3,pi]) + sage: type(v) - sage: v.__copy__() # needs sage.symbolic + sage: v.__copy__() (-1, 0, 3, pi) - sage: v.__copy__() is v # needs sage.symbolic + sage: v.__copy__() is v False sage: copy(v) # needs sage.symbolic @@ -4260,21 +4275,23 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): We test the ``copy`` flag:: + sage: # needs sage.symbolic sage: from sage.modules.free_module_element import FreeModuleElement_generic_dense - sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # needs sage.symbolic - sage: FreeModuleElement_generic_dense(RR^5, tuple(L), coerce=False, copy=False) # needs sage.symbolic + sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] + sage: FreeModuleElement_generic_dense(RR^5, tuple(L), coerce=False, copy=False) (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=False) # needs sage.symbolic - sage: L[4] = 42.0 # needs sage.symbolic - sage: v # last entry changed since we didn't copy # needs sage.symbolic + sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=False) + sage: L[4] = 42.0 + sage: v # last entry changed since we didn't copy (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, 42.0000000000000) :: - sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] # needs sage.symbolic - sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=True) # needs sage.symbolic - sage: L[4] = 42.0 # needs sage.symbolic - sage: v # last entry did not change # needs sage.symbolic + sage: # needs sage.symbolic + sage: L = [RR(x) for x in (-1,0,2/3,pi,oo)] + sage: v = FreeModuleElement_generic_dense(RR^5, L, coerce=False, copy=True) + sage: L[4] = 42.0 + sage: v # last entry did not change (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) Check that :trac:`11751` is fixed:: @@ -4509,20 +4526,21 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: x, y = var('x,y') # needs sage.symbolic - sage: f = x^2 + y^2 # needs sage.symbolic - sage: g = f.gradient() # needs sage.symbolic - sage: g # needs sage.symbolic + sage: # needs sage.symbolic + sage: x, y = var('x,y') + sage: f = x^2 + y^2 + sage: g = f.gradient() + sage: g (2*x, 2*y) - sage: type(g) # needs sage.symbolic + sage: type(g) - sage: g(y=2, x=3) # needs sage.symbolic + sage: g(y=2, x=3) (6, 4) - sage: f(x,y) = x^2 + y^2 # needs sage.symbolic - sage: g = f.gradient() # needs sage.symbolic - sage: g(3,2) # needs sage.symbolic + sage: f(x,y) = x^2 + y^2 + sage: g = f.gradient() + sage: g(3,2) (6, 4) - sage: g(x=3, y=2) # needs sage.symbolic + sage: g(x=3, y=2) (6, 4) """ return vector([e(*args, **kwargs) for e in self]) @@ -4533,28 +4551,30 @@ cdef class FreeModuleElement_generic_dense(FreeModuleElement): EXAMPLES:: - sage: x, y = var('x,y') # needs sage.symbolic - sage: v = vector([x, y, x*sin(y)]) # needs sage.symbolic - sage: w = v.function([x,y]); w # needs sage.symbolic + sage: # needs sage.symbolic + sage: x, y = var('x,y') + sage: v = vector([x, y, x*sin(y)]) + sage: w = v.function([x,y]); w (x, y) |--> (x, y, x*sin(y)) - sage: w.coordinate_ring() # needs sage.symbolic + sage: w.coordinate_ring() Callable function ring with arguments (x, y) - sage: w(1,2) # needs sage.symbolic + sage: w(1,2) (1, 2, sin(2)) - sage: w(2,1) # needs sage.symbolic + sage: w(2,1) (2, 1, 2*sin(1)) - sage: w(y=1,x=2) # needs sage.symbolic + sage: w(y=1,x=2) (2, 1, 2*sin(1)) :: - sage: x,y = var('x,y') # needs sage.symbolic - sage: v = vector([x, y, x*sin(y)]) # needs sage.symbolic - sage: w = v.function([x]); w # needs sage.symbolic + sage: # needs sage.symbolic + sage: x,y = var('x,y') + sage: v = vector([x, y, x*sin(y)]) + sage: w = v.function([x]); w x |--> (x, y, x*sin(y)) - sage: w.coordinate_ring() # needs sage.symbolic + sage: w.coordinate_ring() Callable function ring with argument x - sage: w(4) # needs sage.symbolic + sage: w(4) (4, y, 4*sin(y)) """ from sage.symbolic.callable import CallableSymbolicExpressionRing @@ -5092,12 +5112,13 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): :: - sage: v = vector([1,2/3,pi], sparse=True) # needs sage.symbolic - sage: v.set(1, pi^3) # needs sage.symbolic - sage: v # needs sage.symbolic + sage: # needs sage.symbolic + sage: v = vector([1,2/3,pi], sparse=True) + sage: v.set(1, pi^3) + sage: v (1, pi^3, pi) - sage: v.set(2, SR(0)) # needs sage.symbolic - sage: v # needs sage.symbolic + sage: v.set(2, SR(0)) + sage: v (1, pi^3, 0) This assignment is illegal:: diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index d9a96197d23..c97438ba210 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -111,7 +111,7 @@ def IntegerLattice(basis, lll_reduce=True): We construct an ideal lattice from an element of an absolute order:: - sage: K. = CyclotomicField(17) + sage: K. = CyclotomicField(17) # needs sage.rings.number_field sage: O = K.ring_of_integers() sage: f = O(-a^15 + a^13 + 4*a^12 - 12*a^11 - 256*a^10 + a^9 - a^7 - 4*a^6 + a^5 + 210*a^4 + 2*a^3 - 2*a^2 + 2*a - 2) sage: from sage.modules.free_module_integer import IntegerLattice @@ -156,10 +156,10 @@ def IntegerLattice(basis, lll_reduce=True): Sage also interfaces with fpylll's lattice generator:: sage: from sage.modules.free_module_integer import IntegerLattice - sage: from fpylll import IntegerMatrix # optional - fpylll - sage: A = IntegerMatrix.random(8, "simdioph", bits=20, bits2=10) # optional - fpylll - sage: A = A.to_matrix(matrix(ZZ, 8, 8)) # optional - fpylll - sage: IntegerLattice(A, lll_reduce=False) # optional - fpylll + sage: from fpylll import IntegerMatrix # needs fpylll + sage: A = IntegerMatrix.random(8, "simdioph", bits=20, bits2=10) # needs fpylll + sage: A = A.to_matrix(matrix(ZZ, 8, 8)) # needs fpylll + sage: IntegerLattice(A, lll_reduce=False) # needs fpylll Free module of degree 8 and rank 8 over Integer Ring User basis matrix: [ 1024 829556 161099 11567 521155 769480 639201 689979] @@ -263,11 +263,12 @@ def __init__(self, ambient, basis, check=True, echelonize=False, sage: M.row_space() == L.matrix().row_space() True + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^8 + 1) # optional - sage.rings.number_field - sage: O = K.ring_of_integers() # optional - sage.rings.number_field - sage: f = O(a^7 - a^6 + 4*a^5 - a^4 + a^3 + 1) # optional - sage.rings.number_field - sage: IntegerLattice(f) # optional - sage.rings.number_field + sage: K. = NumberField(x^8 + 1) + sage: O = K.ring_of_integers() + sage: f = O(a^7 - a^6 + 4*a^5 - a^4 + a^3 + 1) + sage: IntegerLattice(f) Free module of degree 8 and rank 8 over Integer Ring User basis matrix: [ 0 1 0 1 0 3 3 0] @@ -369,10 +370,10 @@ def LLL(self, *args, **kwds): ... sage: L.reduced_basis == A True - sage: old = L.reduced_basis[0].norm().n() # optional - sage.symbolic + sage: old = L.reduced_basis[0].norm().n() # needs sage.symbolic sage: _ = L.LLL() - sage: new = L.reduced_basis[0].norm().n() # optional - sage.symbolic - sage: new <= old # optional - sage.symbolic + sage: new = L.reduced_basis[0].norm().n() # needs sage.symbolic + sage: new <= old # needs sage.symbolic True """ basis = self.reduced_basis @@ -404,20 +405,20 @@ def BKZ(self, *args, **kwds): sage: from sage.modules.free_module_integer import IntegerLattice sage: A = sage.crypto.gen_lattice(type='random', n=1, m=60, q=2^60, seed=42) - sage: L = IntegerLattice(A, lll_reduce=False) # optional - sage.libs.flint - sage: min(v.norm().n() for v in L.reduced_basis) # optional - sage.libs.flint + sage: L = IntegerLattice(A, lll_reduce=False) # needs sage.libs.flint + sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.libs.flint 4.17330740711759e15 - sage: L.LLL() # optional - sage.libs.flint + sage: L.LLL() # needs sage.libs.flint 60 x 60 dense matrix over Integer Ring (use the '.str()' method to see the entries) - sage: min(v.norm().n() for v in L.reduced_basis) # optional - sage.libs.flint + sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.libs.flint 5.19615242270663 - sage: L.BKZ(block_size=10) # optional - sage.libs.flint + sage: L.BKZ(block_size=10) # needs sage.libs.flint 60 x 60 dense matrix over Integer Ring (use the '.str()' method to see the entries) - sage: min(v.norm().n() for v in L.reduced_basis) # optional - sage.libs.flint + sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.libs.flint 4.12310562561766 .. NOTE:: @@ -562,21 +563,21 @@ def shortest_vector(self, update_reduced_basis=True, algorithm="fplll", *args, * sage: from sage.modules.free_module_integer import IntegerLattice sage: A = sage.crypto.gen_lattice(type='random', n=1, m=30, q=2^40, seed=42) sage: L = IntegerLattice(A, lll_reduce=False) - sage: min(v.norm().n() for v in L.reduced_basis) + sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.symbolic 6.03890756700000e10 - sage: L.shortest_vector().norm().n() + sage: L.shortest_vector().norm().n() # needs sage.symbolic 3.74165738677394 sage: L = IntegerLattice(A, lll_reduce=False) - sage: min(v.norm().n() for v in L.reduced_basis) + sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.symbolic 6.03890756700000e10 - sage: L.shortest_vector(algorithm="pari").norm().n() + sage: L.shortest_vector(algorithm="pari").norm().n() # needs sage.symbolic 3.74165738677394 sage: L = IntegerLattice(A, lll_reduce=True) - sage: L.shortest_vector(algorithm="pari").norm().n() + sage: L.shortest_vector(algorithm="pari").norm().n() # needs sage.symbolic 3.74165738677394 """ if algorithm == "pari": diff --git a/src/sage/modules/free_module_morphism.py b/src/sage/modules/free_module_morphism.py index aa1925415f3..dd7b0ab4803 100644 --- a/src/sage/modules/free_module_morphism.py +++ b/src/sage/modules/free_module_morphism.py @@ -211,10 +211,10 @@ def change_ring(self, R): [0 1 0] [0 0 1] Codomain: Vector space of degree 2 and dimension 2 over Rational Field - Basis matrix: - [1 0] - [0 1] - sage: f = h.change_ring(GF(7)); f # optional - sage.libs.pari + Basis matrix: + [1 0] + [0 1] + sage: f = h.change_ring(GF(7)); f Vector space morphism represented by the matrix: [4 4] [4 4] @@ -414,17 +414,18 @@ def lift(self, x): This works for vector spaces, too:: - sage: V = VectorSpace(GF(3), 2) # optional - sage.libs.pari - sage: W = VectorSpace(GF(3), 3) # optional - sage.libs.pari - sage: f = V.hom([W.1, W.1 - W.0]) # optional - sage.libs.pari - sage: f.lift(W.1) # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: V = VectorSpace(GF(3), 2) + sage: W = VectorSpace(GF(3), 3) + sage: f = V.hom([W.1, W.1 - W.0]) + sage: f.lift(W.1) (1, 0) - sage: f.lift(W.2) # optional - sage.libs.pari + sage: f.lift(W.2) Traceback (most recent call last): ... ValueError: element is not in the image - sage: w = W((17, -2, 0)) # optional - sage.libs.pari - sage: f(f.lift(w)) == w # optional - sage.libs.pari + sage: w = W((17, -2, 0)) + sage: f(f.lift(w)) == w True This example illustrates the use of the ``preimage_representative`` @@ -488,16 +489,16 @@ def eigenvalues(self, extend=True): sage: V = QQ^3 sage: H = V.endomorphism_ring()([[1,-1,0], [-1,1,1], [0,3,1]]) - sage: H.eigenvalues() # optional - sage.rings.number_field + sage: H.eigenvalues() # needs sage.rings.number_field [3, 1, -1] Note the effect of the ``extend`` option:: sage: V = QQ^2 sage: H = V.endomorphism_ring()([[0,-1], [1,0]]) - sage: H.eigenvalues() # optional - sage.rings.number_field + sage: H.eigenvalues() # needs sage.rings.number_field [-1*I, 1*I] - sage: H.eigenvalues(extend=False) # optional - sage.libs.pari + sage: H.eigenvalues(extend=False) # needs sage.libs.pari [] """ if self.base_ring().is_field(): @@ -525,50 +526,30 @@ def eigenvectors(self, extend=True): EXAMPLES:: - sage: V=(QQ^4).subspace([[0,2,1,4],[1,2,5,0],[1,1,1,1]]) - sage: H=(V.Hom(V))(matrix(QQ, [[0,1,0],[-1,0,0],[0,0,3]])) - sage: H.eigenvectors() # optional - sage.rings.number_field - [(3, [ - (0, 0, 1, -6/7) - ], 1), (-1*I, [ - (1, 1*I, 0, -0.571428571428572? + 2.428571428571429?*I) - ], 1), (1*I, [ - (1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I) - ], 1)] - sage: H.eigenvectors(extend=False) # optional - sage.rings.number_field - [(3, [ - (0, 0, 1, -6/7) - ], 1)] - sage: H1=(V.Hom(V))(matrix(QQ, [[2,1,0],[0,2,0],[0,0,3]])) - sage: H1.eigenvectors() # optional - sage.rings.number_field - [(3, [ - (0, 0, 1, -6/7) - ], 1), (2, [ - (0, 1, 0, 17/7) - ], 2)] - sage: H1.eigenvectors(extend=False) # optional - sage.rings.number_field - [(3, [ - (0, 0, 1, -6/7) - ], 1), (2, [ - (0, 1, 0, 17/7) - ], 2)] + sage: V = (QQ^4).subspace([[0,2,1,4], [1,2,5,0], [1,1,1,1]]) + sage: H = (V.Hom(V))(matrix(QQ, [[0,1,0], [-1,0,0], [0,0,3]])) + sage: H.eigenvectors() # needs sage.rings.number_field + [(3, [ (0, 0, 1, -6/7) ], 1), + (-1*I, [ (1, 1*I, 0, -0.571428571428572? + 2.428571428571429?*I) ], 1), + (1*I, [ (1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I) ], 1)] + sage: H.eigenvectors(extend=False) # needs sage.rings.number_field + [(3, [ (0, 0, 1, -6/7) ], 1)] + sage: H1 = (V.Hom(V))(matrix(QQ, [[2,1,0],[0,2,0],[0,0,3]])) + sage: H1.eigenvectors() # needs sage.rings.number_field + [(3, [ (0, 0, 1, -6/7) ], 1), + (2, [ (0, 1, 0, 17/7) ], 2)] + sage: H1.eigenvectors(extend=False) # needs sage.rings.number_field + [(3, [ (0, 0, 1, -6/7) ], 1), + (2, [ (0, 1, 0, 17/7) ], 2)] :: sage: V = QQ^2 sage: m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").eigenvectors() # optional - sage.rings.number_field - [(1, - [ - (1, 0) - ], - 2)] - sage: V.hom(m).eigenvectors() # optional - sage.rings.number_field - [(1, - [ - (0, 1) - ], - 2)] + sage: V.hom(m, side="right").eigenvectors() # needs sage.rings.number_field + [(1, [ (1, 0) ], 2)] + sage: V.hom(m).eigenvectors() # needs sage.rings.number_field + [(1, [ (0, 1) ], 2)] """ if self.base_ring().is_field(): if self.is_endomorphism(): @@ -604,28 +585,25 @@ def eigenspaces(self, extend=True): sage: V = QQ^3 sage: h = V.hom([[1,0,0], [0,0,1], [0,-1,0]], V) - sage: h.eigenspaces() # optional - sage.rings.number_field - [(1, - Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [1 0 0]), - (-1*I, - Vector space of degree 3 and dimension 1 over Algebraic Field - Basis matrix: - [ 0 1 1*I]), - (1*I, - Vector space of degree 3 and dimension 1 over Algebraic Field - Basis matrix: - [ 0 1 -1*I])] - - sage: h.eigenspaces(extend=False) # optional - sage.rings.number_field + sage: h.eigenspaces() # needs sage.rings.number_field + [(1, Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [1 0 0]), + (-1*I, Vector space of degree 3 and dimension 1 over Algebraic Field + Basis matrix: + [ 0 1 1*I]), + (1*I, Vector space of degree 3 and dimension 1 over Algebraic Field + Basis matrix: + [ 0 1 -1*I])] + + sage: h.eigenspaces(extend=False) # needs sage.rings.number_field [(1, Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [1 0 0])] sage: h = V.hom([[2,1,0], [0,2,0], [0,0,-1]], V) - sage: h.eigenspaces() # optional - sage.rings.number_field + sage: h.eigenspaces() # needs sage.rings.number_field [(-1, Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [0 0 1]), @@ -634,7 +612,7 @@ def eigenspaces(self, extend=True): [0 1 0])] sage: h = V.hom([[2,1,0], [0,2,0], [0,0,2]], V) - sage: h.eigenspaces() # optional - sage.rings.number_field + sage: h.eigenspaces() # needs sage.rings.number_field [(2, Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [0 1 0] @@ -643,16 +621,14 @@ def eigenspaces(self, extend=True): :: sage: V = QQ^2; m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").eigenspaces() # optional - sage.rings.number_field - [(1, - Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 0])] - sage: V.hom(m).eigenspaces() # optional - sage.rings.number_field - [(1, - Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [0 1])] + sage: V.hom(m, side="right").eigenspaces() # needs sage.rings.number_field + [(1, Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [1 0])] + sage: V.hom(m).eigenspaces() # needs sage.rings.number_field + [(1, Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [0 1])] """ ev = self.eigenvectors(extend) return [(vec[0], Sequence(vec[1]).universe().subspace(vec[1])) @@ -676,9 +652,9 @@ def minimal_polynomial(self,var='x'): Compute the minimal polynomial, and check it. :: - sage: V=GF(7)^3 # optional - sage.libs.pari - sage: H=V.Hom(V)([[0,1,2],[-1,0,3],[2,4,1]]) # optional - sage.libs.pari - sage: H # optional - sage.libs.pari + sage: V = GF(7)^3 + sage: H = V.Hom(V)([[0,1,2], [-1,0,3], [2,4,1]]) + sage: H Vector space morphism represented by the matrix: [0 1 2] [6 0 3] @@ -686,13 +662,13 @@ def minimal_polynomial(self,var='x'): Domain: Vector space of dimension 3 over Finite Field of size 7 Codomain: Vector space of dimension 3 over Finite Field of size 7 - sage: H.minpoly() # optional - sage.libs.pari + sage: H.minpoly() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 - sage: H.minimal_polynomial() # optional - sage.libs.pari + sage: H.minimal_polynomial() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 - sage: H^3 + (H^2)*6 + H*6 + 1 # optional - sage.libs.pari + sage: H^3 + (H^2)*6 + H*6 + 1 Vector space morphism represented by the matrix: [0 0 0] [0 0 0] diff --git a/src/sage/modules/free_quadratic_module.py b/src/sage/modules/free_quadratic_module.py index 90cf9825dc5..ff112b9a5c2 100644 --- a/src/sage/modules/free_quadratic_module.py +++ b/src/sage/modules/free_quadratic_module.py @@ -1141,8 +1141,8 @@ def __init__(self, base_field, dimension, inner_product_matrix, sparse=False): Check for :trac:`10606`:: sage: D = matrix.diagonal(ZZ, [1,1]) - sage: V = VectorSpace(GF(46349), 2, inner_product_matrix=D) # optional - sage.libs.pari - sage: deepcopy(V) # optional - sage.libs.pari + sage: V = VectorSpace(GF(46349), 2, inner_product_matrix=D) # needs sage.rings.finite_rings + sage: deepcopy(V) # needs sage.rings.finite_rings Ambient quadratic space of dimension 2 over Finite Field of size 46349 Inner product matrix: diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index fd53a367b54..d722a2d9195 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -155,7 +155,8 @@ def IntegralLattice(data, basis=None): (see :mod:`Cartan types ` and :class:`CartanMatrix`):: - sage: IntegralLattice(["E", 7]) # optional - sage.graphs + sage: # needs sage.graphs + sage: IntegralLattice(["E", 7]) Lattice of degree 7 and rank 7 over Integer Ring Standard basis Inner product matrix: @@ -166,20 +167,20 @@ def IntegralLattice(data, basis=None): [ 0 0 0 -1 2 -1 0] [ 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 -1 2] - sage: IntegralLattice(["A", 2]) # optional - sage.graphs + sage: IntegralLattice(["A", 2]) Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: [ 2 -1] [-1 2] - sage: IntegralLattice("D3") # optional - sage.graphs + sage: IntegralLattice("D3") Lattice of degree 3 and rank 3 over Integer Ring Standard basis Inner product matrix: [ 2 -1 -1] [-1 2 0] [-1 0 2] - sage: IntegralLattice(["D", 4]) # optional - sage.graphs + sage: IntegralLattice(["D", 4]) Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -199,7 +200,7 @@ def IntegralLattice(data, basis=None): Inner product matrix: [0 1] [1 0] - sage: IntegralLattice(["A", 3], [[1,1,1]]) # optional - sage.graphs + sage: IntegralLattice(["A", 3], [[1,1,1]]) # needs sage.graphs Lattice of degree 3 and rank 1 over Integer Ring Basis matrix: [1 1 1] @@ -212,7 +213,7 @@ def IntegralLattice(data, basis=None): Basis matrix: [1 1 1 1] Standard scalar product - sage: IntegralLattice("A2", [[1,1]]) # optional - sage.graphs + sage: IntegralLattice("A2", [[1,1]]) # needs sage.graphs Lattice of degree 2 and rank 1 over Integer Ring Basis matrix: [1 1] @@ -222,11 +223,11 @@ def IntegralLattice(data, basis=None): TESTS:: - sage: IntegralLattice(["A", 1, 1]) # optional - sage.graphs + sage: IntegralLattice(["A", 1, 1]) # needs sage.graphs Traceback (most recent call last): ... ValueError: lattices must be nondegenerate; use FreeQuadraticModule instead - sage: IntegralLattice(["D", 3, 1]) # optional - sage.graphs + sage: IntegralLattice(["D", 3, 1]) # needs sage.graphs Traceback (most recent call last): ... ValueError: lattices must be nondegenerate; use FreeQuadraticModule instead @@ -271,12 +272,13 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): EXAMPLES:: + sage: # needs sage.graphs sage: from sage.modules.free_quadratic_module_integer_symmetric import IntegralLatticeDirectSum - sage: L1 = IntegralLattice("D4") # optional - sage.graphs - sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.graphs - sage: L3 = IntegralLattice("A4", [[0, 1, 1, 2], [1, 2, 3, 1]]) # optional - sage.graphs - sage: Lattices = [L1, L2, L3] # optional - sage.graphs - sage: IntegralLatticeDirectSum([L1, L2, L3]) # optional - sage.graphs + sage: L1 = IntegralLattice("D4") + sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) + sage: L3 = IntegralLattice("A4", [[0, 1, 1, 2], [1, 2, 3, 1]]) + sage: Lattices = [L1, L2, L3] + sage: IntegralLatticeDirectSum([L1, L2, L3]) Lattice of degree 11 and rank 7 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0 0 0 0] @@ -298,17 +300,17 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): [ 0 0 0 0 0 0 0 -1 2 -1 0] [ 0 0 0 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 0 0 0 -1 2] - sage: [L, phi] = IntegralLatticeDirectSum([L1, L2, L3], True) # optional - sage.graphs - sage: LL3 = L.sublattice(phi[2].image().basis_matrix()) # optional - sage.graphs - sage: L3.discriminant() == LL3.discriminant() # optional - sage.graphs + sage: [L, phi] = IntegralLatticeDirectSum([L1, L2, L3], True) + sage: LL3 = L.sublattice(phi[2].image().basis_matrix()) + sage: L3.discriminant() == LL3.discriminant() True - sage: x = L3([1, 2, 3, 1]) # optional - sage.graphs - sage: phi[2](x).inner_product(phi[2](x)) == x.inner_product(x) # optional - sage.graphs + sage: x = L3([1, 2, 3, 1]) + sage: phi[2](x).inner_product(phi[2](x)) == x.inner_product(x) True TESTS:: - sage: IntegralLatticeDirectSum([IntegralLattice("D4")]) # optional - sage.graphs + sage: IntegralLatticeDirectSum([IntegralLattice("D4")]) # needs sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -318,9 +320,9 @@ def IntegralLatticeDirectSum(Lattices, return_embeddings=False): [ 0 -1 0 2] sage: L1 = IntegralLattice(2 * matrix.identity(2), [[1/2, 1/2]]) - sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # optional - sage.graphs - sage: [L, phi] = IntegralLatticeDirectSum([L1, L2], True) # optional - sage.graphs - sage: L # optional - sage.graphs + sage: L2 = IntegralLattice("A3", [[1, 1, 2]]) # needs sage.graphs + sage: [L, phi] = IntegralLatticeDirectSum([L1, L2], True) # needs sage.graphs + sage: L # needs sage.graphs Lattice of degree 5 and rank 2 over Integer Ring Basis matrix: [1/2 1/2 0 0 0] @@ -416,18 +418,19 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Inner product matrix: [4]]] - sage: L1 = IntegralLattice([[2]]) # optional - sage.graphs - sage: L2 = IntegralLattice([[2]]) # optional - sage.graphs - sage: AL1 = L1.discriminant_group() # optional - sage.graphs - sage: AL2 = L2.discriminant_group() # optional - sage.graphs - sage: AL1 # optional - sage.graphs + sage: # needs sage.graphs + sage: L1 = IntegralLattice([[2]]) + sage: L2 = IntegralLattice([[2]]) + sage: AL1 = L1.discriminant_group() + sage: AL2 = L2.discriminant_group() + sage: AL1 Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1/2] - sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.graphs - sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.graphs - sage: glue = [[g1, g2]] # optional - sage.graphs - sage: IntegralLatticeGluing([L1, L2], glue) # optional - sage.graphs + sage: g1 = L1.discriminant_group().gens()[0] + sage: g2 = L2.discriminant_group().gens()[0] + sage: glue = [[g1, g2]] + sage: IntegralLatticeGluing([L1, L2], glue) Lattice of degree 2 and rank 2 over Integer Ring Basis matrix: [1/2 1/2] @@ -436,13 +439,14 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [2 0] [0 2] - sage: L1 = IntegralLattice("A4") # optional - sage.graphs - sage: L2 = IntegralLattice("A4") # optional - sage.graphs - sage: g1 = L1.discriminant_group().gens()[0] # optional - sage.graphs - sage: g2 = L2.discriminant_group().gens()[0] # optional - sage.graphs - sage: glue = [[g1, 2 * g2]] # optional - sage.graphs - sage: [V, phi] = IntegralLatticeGluing([L1, L2], glue, True) # optional - sage.graphs - sage: V # optional - sage.graphs + sage: # needs sage.graphs + sage: L1 = IntegralLattice("A4") + sage: L2 = IntegralLattice("A4") + sage: g1 = L1.discriminant_group().gens()[0] + sage: g2 = L2.discriminant_group().gens()[0] + sage: glue = [[g1, 2 * g2]] + sage: [V, phi] = IntegralLatticeGluing([L1, L2], glue, True) + sage: V Lattice of degree 8 and rank 8 over Integer Ring Basis matrix: [1/5 2/5 3/5 4/5 2/5 4/5 1/5 3/5] @@ -462,7 +466,7 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [ 0 0 0 0 -1 2 -1 0] [ 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 -1 2] - sage: V.sublattice(phi[0].image().basis_matrix()) # optional - sage.graphs + sage: V.sublattice(phi[0].image().basis_matrix()) Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -481,8 +485,8 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Different gluings can be composed:: - sage: D4 = IntegralLattice("D4") # optional - sage.graphs - sage: D4.discriminant_group() # optional - sage.graphs + sage: D4 = IntegralLattice("D4") # needs sage.graphs + sage: D4.discriminant_group() # needs sage.graphs Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] @@ -493,23 +497,23 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Gram matrix of the quadratic form with values in Q/2Z: [1/2 0] [ 0 1/2] - sage: g1 = D4.discriminant_group().gens()[0] # optional - sage.graphs + sage: g1 = D4.discriminant_group().gens()[0] # needs sage.graphs sage: g2 = L2.discriminant_group().gens()[0] + L2.discriminant_group().gens()[1] - sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) # optional - sage.graphs - sage: AD6 = D6.discriminant_group() # optional - sage.graphs - sage: AD6.normal_form() # optional - sage.graphs + sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) # needs sage.graphs + sage: AD6 = D6.discriminant_group() # needs sage.graphs + sage: AD6.normal_form() # needs sage.graphs Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [3/2 0] [ 0 3/2] - sage: f1, g1 = AD6.normal_form().gens() # optional - sage.graphs + sage: f1, g1 = AD6.normal_form().gens() # needs sage.graphs sage: f2, g2 = L2.discriminant_group().gens() - sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) # optional - sage.graphs - sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) # optional - sage.graphs - sage: x = D4([1, 0, 0, 0]) # optional - sage.graphs - sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x))) == x.inner_product(x) # optional - sage.graphs + sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) # needs sage.graphs + sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) # needs sage.graphs + sage: x = D4([1, 0, 0, 0]) # needs sage.graphs + sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x))) == x.inner_product(x) # needs sage.graphs True - sage: D4embed # optional - sage.graphs + sage: D4embed # needs sage.graphs Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -528,28 +532,30 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): The input may be a list of three or more lattices:: - sage: A7 = IntegralLattice("A7") # optional - sage.graphs - sage: D5 = IntegralLattice("D5") # optional - sage.graphs - sage: gA7 = A7.discriminant_group().gens()[0] # optional - sage.graphs - sage: gD5 = D5.discriminant_group().gens()[0] # optional - sage.graphs - sage: [L, phi] = IntegralLatticeGluing([A7, A7, D5, D5], # optional - sage.graphs + sage: # needs sage.graphs + sage: A7 = IntegralLattice("A7") + sage: D5 = IntegralLattice("D5") + sage: gA7 = A7.discriminant_group().gens()[0] + sage: gD5 = D5.discriminant_group().gens()[0] + sage: [L, phi] = IntegralLatticeGluing([A7, A7, D5, D5], ....: [[gA7, gA7, gD5, 2 * gD5], ....: [gA7, 7 * gA7, 2 * gD5, gD5]], True) - sage: L.determinant() # optional - sage.graphs + sage: L.determinant() 1 - sage: B = phi[0].matrix() # optional - sage.graphs - sage: B*L.gram_matrix()*B.transpose() == A7.gram_matrix() # optional - sage.graphs + sage: B = phi[0].matrix() + sage: B*L.gram_matrix()*B.transpose() == A7.gram_matrix() True The gluing takes place in the direct sum of the respective ambient spaces:: - sage: L1 = IntegralLattice("D4", [[1, 1, 0, 0], [0, 1, 1, 0]]) # optional - sage.graphs - sage: L2 = IntegralLattice("E6", [[0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1]]) # optional - sage.graphs - sage: [f1, f2] = L1.discriminant_group().gens() # optional - sage.graphs - sage: [g1, g2] = L2.discriminant_group().gens() # optional - sage.graphs - sage: [L, phi] = IntegralLatticeGluing([L1, L2], # optional - sage.graphs + sage: # needs sage.graphs + sage: L1 = IntegralLattice("D4", [[1, 1, 0, 0], [0, 1, 1, 0]]) + sage: L2 = IntegralLattice("E6", [[0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1]]) + sage: [f1, f2] = L1.discriminant_group().gens() + sage: [g1, g2] = L2.discriminant_group().gens() + sage: [L, phi] = IntegralLatticeGluing([L1, L2], ....: [[f1, g1], [f2, 2 * g2]], True) - sage: phi[0] # optional - sage.graphs + sage: phi[0] Free module morphism defined by the matrix [ 2 2 -2 -1] [ 0 2 -1 0] @@ -579,8 +585,8 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): [ 0 0 0 0 0 -1 -1 2 -1 0] [ 0 0 0 0 0 0 0 -1 2 -1] [ 0 0 0 0 0 0 0 0 -1 2] - sage: B = phi[0].matrix() # optional - sage.graphs - sage: B * L.gram_matrix() * B.transpose() == L1.gram_matrix() # optional - sage.graphs + sage: B = phi[0].matrix() + sage: B * L.gram_matrix() * B.transpose() == L1.gram_matrix() True """ [direct_sum, phi] = IntegralLatticeDirectSum(Lattices, return_embeddings=True) @@ -696,8 +702,8 @@ def _repr_(self): EXAMPLES:: - sage: A2 = IntegralLattice("A2") # optional - sage.graphs - sage: A2 # optional - sage.graphs + sage: A2 = IntegralLattice("A2") # needs sage.graphs + sage: A2 # needs sage.graphs Lattice of degree 2 and rank 2 over Integer Ring Standard basis Inner product matrix: @@ -732,8 +738,8 @@ def is_even(self): sage: L = IntegralLattice(G) sage: L.is_even() False - sage: L = IntegralLattice("A2") # optional - sage.graphs - sage: L.is_even() # optional - sage.graphs + sage: L = IntegralLattice("A2") # needs sage.graphs + sage: L.is_even() # needs sage.graphs True """ return all(d % 2 == 0 for d in self.gram_matrix().diagonal()) @@ -751,8 +757,8 @@ def dual_lattice(self): EXAMPLES:: - sage: L = IntegralLattice("A2") # optional - sage.graphs - sage: Ldual = L.dual_lattice(); Ldual # optional - sage.graphs + sage: L = IntegralLattice("A2") # needs sage.graphs + sage: Ldual = L.dual_lattice(); Ldual # needs sage.graphs Free module of degree 2 and rank 2 over Integer Ring Echelon basis matrix: [1/3 2/3] @@ -760,7 +766,7 @@ def dual_lattice(self): Since our lattices are always integral, a lattice is contained in its dual:: - sage: L.is_submodule(Ldual) # optional - sage.graphs + sage: L.is_submodule(Ldual) # needs sage.graphs True """ return self.span(self.gram_matrix().inverse()*self.basis_matrix()) @@ -808,13 +814,13 @@ def discriminant_group(self, s=0): sage: import gc sage: gc.freeze() - sage: L = IntegralLattice("A2") # optional - sage.graphs - sage: for k in range(1,500): # long time # optional - sage.graphs + sage: L = IntegralLattice("A2") # needs sage.graphs + sage: for k in range(1,500): # long time ....: G = L.twist(k) ....: D = G.discriminant_group() - sage: tmp = gc.collect() # optional - sage.graphs - sage: tmp = gc.collect() # optional - sage.graphs - sage: len([a for a in gc.get_objects() if type(a) == type(L)]) <= 300 # optional - sage.graphs + sage: tmp = gc.collect() + sage: tmp = gc.collect() + sage: len([a for a in gc.get_objects() if type(a) == type(L)]) <= 300 True sage: gc.unfreeze() """ @@ -850,8 +856,8 @@ def signature_pair(self): EXAMPLES:: - sage: A2 = IntegralLattice("A2") # optional - sage.graphs - sage: A2.signature_pair() # optional - sage.graphs + sage: A2 = IntegralLattice("A2") # needs sage.graphs + sage: A2.signature_pair() # needs sage.graphs (2, 0) """ from sage.quadratic_forms.quadratic_form import QuadraticForm @@ -1030,18 +1036,19 @@ def maximal_overlattice(self, p=None): EXAMPLES:: - sage: L = IntegralLattice("A4").twist(25*89) # optional - sage.graphs - sage: L.maximal_overlattice().determinant() # optional - sage.graphs + sage: # needs sage.graphs + sage: L = IntegralLattice("A4").twist(25*89) + sage: L.maximal_overlattice().determinant() 5 - sage: L.maximal_overlattice(89).determinant().factor() # optional - sage.graphs + sage: L.maximal_overlattice(89).determinant().factor() 5^9 - sage: L.maximal_overlattice(5).determinant().factor() # optional - sage.graphs + sage: L.maximal_overlattice(5).determinant().factor() 5 * 89^4 TESTS:: sage: L = IntegralLattice(matrix.diagonal([2,4,4,8])) - sage: L.maximal_overlattice().is_even() # optional - sage.libs.flint + sage: L.maximal_overlattice().is_even() # needs sage.libs.flint True """ @@ -1165,8 +1172,8 @@ def orthogonal_group(self, gens=None, is_finite=None): EXAMPLES:: - sage: A4 = IntegralLattice("A4") # optional - sage.graphs - sage: Aut = A4.orthogonal_group(); Aut # optional - sage.graphs sage.libs.gap + sage: A4 = IntegralLattice("A4") # needs sage.graphs + sage: Aut = A4.orthogonal_group(); Aut # needs sage.graphs sage.libs.gap Group of isometries with 4 generators ( [0 0 0 1] [-1 -1 -1 0] [ 1 0 0 0] [ 1 0 0 0] [0 0 1 0] [ 0 0 0 -1] [-1 -1 -1 -1] [ 0 1 0 0] @@ -1176,37 +1183,37 @@ def orthogonal_group(self, gens=None, is_finite=None): The group acts from the right on the lattice and its discriminant group:: - sage: x = A4.an_element() # optional - sage.graphs - sage: g = Aut.an_element(); g # optional - sage.graphs sage.libs.gap + sage: x = A4.an_element() # needs sage.graphs + sage: g = Aut.an_element(); g # needs sage.graphs sage.libs.gap [-1 -1 -1 0] [ 0 0 1 0] [ 0 0 -1 -1] [ 0 1 1 1] - sage: x*g # optional - sage.graphs sage.libs.gap + sage: x*g # needs sage.graphs sage.libs.gap (-1, -1, -1, 0) - sage: (x*g).parent() == A4 # optional - sage.graphs sage.libs.gap + sage: (x*g).parent() == A4 # needs sage.graphs sage.libs.gap True - sage: (g*x).parent() # optional - sage.graphs sage.libs.gap + sage: (g*x).parent() # needs sage.graphs sage.libs.gap Vector space of dimension 4 over Rational Field - sage: y = A4.discriminant_group().an_element() # optional - sage.graphs sage.libs.gap - sage: y*g # optional - sage.graphs sage.libs.gap + sage: y = A4.discriminant_group().an_element() # needs sage.graphs sage.libs.gap + sage: y*g # needs sage.graphs sage.libs.gap (4) If the group is finite we can compute the usual things:: - sage: Aut.order() # optional - sage.graphs sage.libs.gap + sage: Aut.order() # needs sage.graphs sage.libs.gap 240 - sage: conj = Aut.conjugacy_classes_representatives() # optional - sage.graphs sage.libs.gap - sage: len(conj) # optional - sage.graphs sage.libs.gap + sage: conj = Aut.conjugacy_classes_representatives() # needs sage.graphs sage.libs.gap + sage: len(conj) # needs sage.graphs sage.libs.gap 14 - sage: Aut.structure_description() # optional - sage.graphs sage.libs.gap + sage: Aut.structure_description() # needs sage.graphs sage.libs.gap 'C2 x S5' The lattice can live in a larger ambient space:: sage: A2 = IntegralLattice(matrix.identity(3), ....: Matrix(ZZ, 2, 3, [1,-1,0,0,1,-1])) - sage: A2.orthogonal_group() # optional - sage.libs.gap + sage: A2.orthogonal_group() # needs sage.libs.gap Group of isometries with 2 generators ( [ 2/3 2/3 -1/3] [1 0 0] [ 2/3 -1/3 2/3] [0 0 1] @@ -1216,15 +1223,15 @@ def orthogonal_group(self, gens=None, is_finite=None): It can be negative definite as well:: sage: A2m = IntegralLattice(-Matrix(ZZ, 2, [2,1,1,2])) - sage: G = A2m.orthogonal_group() # optional - sage.libs.gap - sage: G.order() # optional - sage.libs.gap + sage: G = A2m.orthogonal_group() # needs sage.libs.gap + sage: G.order() # needs sage.libs.gap 12 If the lattice is indefinite, sage does not know how to compute generators. Can you teach it?:: sage: U = IntegralLattice(Matrix(ZZ, 2, [0,1,1,0])) - sage: U.orthogonal_group() # optional - sage.libs.gap + sage: U.orthogonal_group() # needs sage.libs.gap Traceback (most recent call last): ... NotImplementedError: currently, we can only compute generators @@ -1234,7 +1241,7 @@ def orthogonal_group(self, gens=None, is_finite=None): sage: S = IntegralLattice(Matrix(ZZ, 2, [2, 3, 3, 2])) sage: f = Matrix(ZZ, 2, [0,1,-1,3]) - sage: S.orthogonal_group([f]) # optional - sage.libs.gap + sage: S.orthogonal_group([f]) # needs sage.libs.gap Group of isometries with 1 generator ( [ 0 1] [-1 3] @@ -1245,7 +1252,7 @@ def orthogonal_group(self, gens=None, is_finite=None): We can handle the trivial group:: sage: S = IntegralLattice(Matrix(ZZ, 2, [2, 3, 3, 2])) - sage: S.orthogonal_group([]) # optional - sage.libs.gap + sage: S.orthogonal_group([]) # needs sage.libs.gap Group of isometries with 1 generator ( [1 0] [0 1] @@ -1304,7 +1311,7 @@ def genus(self): EXAMPLES:: sage: L = IntegralLattice("U") - sage: L.genus() # optional - sage.padics + sage: L.genus() # needs sage.padics Genus of [0 1] [1 0] @@ -1326,8 +1333,8 @@ def tensor_product(self, other, discard_basis=False): EXAMPLES:: - sage: L = IntegralLattice("D3", [[1,-1,0], [0,1,-1]]) # optional - sage.graphs - sage: L1 = L.tensor_product(L); L1 # optional - sage.graphs + sage: L = IntegralLattice("D3", [[1,-1,0], [0,1,-1]]) # needs sage.graphs + sage: L1 = L.tensor_product(L); L1 # needs sage.graphs Lattice of degree 9 and rank 4 over Integer Ring Basis matrix: [ 1 -1 0 -1 1 0 0 0 0] @@ -1344,12 +1351,12 @@ def tensor_product(self, other, discard_basis=False): [-2 1 1 0 0 0 4 -2 -2] [ 1 -2 0 0 0 0 -2 4 0] [ 1 0 -2 0 0 0 -2 0 4] - sage: L1.gram_matrix() # optional - sage.graphs + sage: L1.gram_matrix() # needs sage.graphs [ 36 -12 -12 4] [-12 24 4 -8] [-12 4 24 -8] [ 4 -8 -8 16] - sage: L2 = L.tensor_product(L, True); L2 # optional - sage.graphs + sage: L2 = L.tensor_product(L, True); L2 # needs sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -1380,8 +1387,8 @@ def quadratic_form(self): EXAMPLES:: - sage: L = IntegralLattice("A2") # optional - sage.graphs - sage: q = L.quadratic_form(); q # optional - sage.graphs + sage: L = IntegralLattice("A2") # needs sage.graphs + sage: q = L.quadratic_form(); q # needs sage.graphs Quadratic form in 2 variables over Integer Ring with coefficients: [ 2 -2 ] [ * 2 ] @@ -1400,10 +1407,10 @@ def minimum(self): EXAMPLES:: - sage: L = IntegralLattice('A2') # optional - sage.graphs - sage: L.minimum() # optional - sage.graphs + sage: L = IntegralLattice('A2') # needs sage.graphs + sage: L.minimum() # needs sage.graphs 2 - sage: L.twist(-1).minimum() # optional - sage.graphs + sage: L.twist(-1).minimum() # needs sage.graphs -Infinity """ p, n = self.signature_pair() @@ -1426,10 +1433,10 @@ def maximum(self): EXAMPLES:: - sage: L = IntegralLattice('A2') # optional - sage.graphs - sage: L.maximum() # optional - sage.graphs + sage: L = IntegralLattice('A2') # needs sage.graphs + sage: L.maximum() # needs sage.graphs +Infinity - sage: L.twist(-1).maximum() # optional - sage.graphs + sage: L.twist(-1).maximum() # needs sage.graphs -2 """ if self.rank() == 0: @@ -1450,13 +1457,13 @@ def LLL(self): EXAMPLES:: - sage: L = IntegralLattice('A2') # optional - sage.graphs - sage: L.lll() == L # optional - sage.graphs + sage: L = IntegralLattice('A2') # needs sage.graphs + sage: L.lll() == L # needs sage.graphs True sage: G = matrix(ZZ, 3, [0,1,0, 1,0,0, 0,0,7]) sage: V = matrix(ZZ, 3, [-14,-15,-15, -4,1,16, -5,-5,-4]) sage: L = IntegralLattice(V * G * V.T) - sage: L.lll().gram_matrix() # optional - sage.libs.gap + sage: L.lll().gram_matrix() # needs sage.libs.gap [0 0 1] [0 7 0] [1 0 0] @@ -1497,10 +1504,10 @@ def short_vectors(self, n, **kwargs): EXAMPLES:: - sage: A2 = IntegralLattice('A2') # optional - sage.graphs - sage: A2.short_vectors(3) # optional - sage.graphs + sage: A2 = IntegralLattice('A2') # needs sage.graphs + sage: A2.short_vectors(3) # needs sage.graphs [[(0, 0)], [], [(1, 1), (-1, -1), (0, 1), (0, -1), (1, 0), (-1, 0)]] - sage: A2.short_vectors(3,up_to_sign_flag=True) # optional - sage.graphs + sage: A2.short_vectors(3,up_to_sign_flag=True) # needs sage.graphs [[(0, 0)], [], [(1, 1), (0, 1), (1, 0)]] """ p, m = self.signature_pair() @@ -1527,8 +1534,8 @@ def twist(self, s, discard_basis=False): EXAMPLES:: - sage: L = IntegralLattice("A4") # optional - sage.graphs - sage: L.twist(3) # optional - sage.graphs + sage: L = IntegralLattice("A4") # needs sage.graphs + sage: L.twist(3) # needs sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -1590,15 +1597,15 @@ def local_modification(M, G, p, check=True): EXAMPLES:: sage: from sage.modules.free_quadratic_module_integer_symmetric import local_modification - sage: L = IntegralLattice("A3").twist(15) # optional - sage.graphs - sage: M = L.maximal_overlattice() # optional - sage.graphs - sage: for p in prime_divisors(L.determinant()): # optional - sage.graphs + sage: L = IntegralLattice("A3").twist(15) # needs sage.graphs + sage: M = L.maximal_overlattice() # needs sage.graphs + sage: for p in prime_divisors(L.determinant()): # needs sage.graphs ....: M = local_modification(M, L.gram_matrix(), p) - sage: M.genus() == L.genus() # optional - sage.graphs + sage: M.genus() == L.genus() # needs sage.graphs True - sage: L = IntegralLattice("D4").twist(3*4) # optional - sage.graphs - sage: M = L.maximal_overlattice() # optional - sage.graphs - sage: local_modification(M, L.gram_matrix(), 2) # optional - sage.graphs + sage: L = IntegralLattice("D4").twist(3*4) # needs sage.graphs + sage: M = L.maximal_overlattice() # needs sage.graphs + sage: local_modification(M, L.gram_matrix(), 2) # needs sage.graphs Lattice of degree 4 and rank 4 over Integer Ring Basis matrix: [1/3 0 2/3 2/3] diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index fd52d96d3c1..2ad91a155ae 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -21,13 +21,13 @@ [0 0 1] sage: is_MatrixMorphism(m) True - sage: m.charpoly('x') # optional - sage.libs.pari + sage: m.charpoly('x') # needs sage.libs.pari x^3 - 3*x^2 + 3*x - 1 sage: m.base_ring() Rational Field sage: m.det() 1 - sage: m.fcp('x') # optional - sage.libs.pari + sage: m.fcp('x') # needs sage.libs.pari (x - 1)^3 sage: m.matrix() [1 0 0] @@ -523,10 +523,11 @@ def __mul__(self, right): Composite maps can be formed with matrix morphisms:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^2 + 23) # optional - sage.rings.number_field - sage: V, VtoK, KtoV = K.vector_space() # optional - sage.rings.number_field - sage: f = V.hom([V.0 - V.1, V.0 + V.1])*KtoV; f # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 23) + sage: V, VtoK, KtoV = K.vector_space() + sage: f = V.hom([V.0 - V.1, V.0 + V.1])*KtoV; f Composite map: From: Number Field in a with defining polynomial x^2 + 23 To: Vector space of dimension 2 over Rational Field @@ -539,9 +540,9 @@ def __mul__(self, right): [ 1 1] Domain: Vector space of dimension 2 over Rational Field Codomain: Vector space of dimension 2 over Rational Field - sage: f(a) # optional - sage.rings.number_field + sage: f(a) (1, 1) - sage: V.hom([V.0 - V.1, V.0 + V.1], side="right")*KtoV # optional - sage.rings.number_field + sage: V.hom([V.0 - V.1, V.0 + V.1], side="right")*KtoV Composite map: From: Number Field in a with defining polynomial x^2 + 23 To: Vector space of dimension 2 over Rational Field @@ -836,7 +837,7 @@ def decomposition(self, *args, **kwds): EXAMPLES:: sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) - sage: phi.decomposition() # optional - sage.libs.pari + sage: phi.decomposition() # needs sage.libs.pari [ Free module of degree 2 and rank 1 over Integer Ring Echelon basis matrix: @@ -846,7 +847,7 @@ def decomposition(self, *args, **kwds): [ 1 -1] ] sage: phi2 = V.hom(phi.matrix(), side="right") - sage: phi2.decomposition() # optional - sage.libs.pari + sage: phi2.decomposition() # needs sage.libs.pari [ Free module of degree 2 and rank 1 over Integer Ring Echelon basis matrix: @@ -905,10 +906,10 @@ def fcp(self, var='x'): EXAMPLES:: - sage: V = ZZ^2; phi = V.hom([V.0+V.1, 2*V.1]) - sage: phi.fcp() # optional - sage.libs.pari + sage: V = ZZ^2; phi = V.hom([V.0 + V.1, 2*V.1]) + sage: phi.fcp() # needs sage.libs.pari (x - 2) * (x - 1) - sage: phi.fcp('T') # optional - sage.libs.pari + sage: phi.fcp('T') # needs sage.libs.pari (T - 2) * (T - 1) """ return self.charpoly(var).factor() @@ -976,22 +977,22 @@ def image(self): Basis matrix: [ 1 0 -1] [ 0 1 2] - sage: hom(GF(7)^3, GF(7)^2, zero_matrix(GF(7), 3, 2)).image() # optional - sage.libs.pari + sage: hom(GF(7)^3, GF(7)^2, zero_matrix(GF(7), 3, 2)).image() Vector space of degree 2 and dimension 0 over Finite Field of size 7 Basis matrix: [] - sage: m = matrix(3, [1, 0, 0, 1, 0, 0, 0, 0, 1]); m # optional - sage.libs.pari + sage: m = matrix(3, [1, 0, 0, 1, 0, 0, 0, 0, 1]); m [1 0 0] [1 0 0] [0 0 1] - sage: f1 = V.hom(m) # optional - sage.libs.pari - sage: f2 = V.hom(m, side="right") # optional - sage.libs.pari - sage: f1.image() # optional - sage.libs.pari + sage: f1 = V.hom(m) + sage: f2 = V.hom(m, side="right") + sage: f1.image() Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [1 0 0] [0 0 1] - sage: f2.image() # optional - sage.libs.pari + sage: f2.image() Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [1 1 0] diff --git a/src/sage/modules/quotient_module.py b/src/sage/modules/quotient_module.py index b5af2323b3e..462e44c4165 100644 --- a/src/sage/modules/quotient_module.py +++ b/src/sage/modules/quotient_module.py @@ -307,10 +307,11 @@ class FreeModule_ambient_field_quotient(FreeModule_ambient_field): EXAMPLES:: - sage: k. = QuadraticField(-1) # optional - sage.rings.number_field - sage: A = k^3; V = A.span([[1,0,i], [2,i,0]]) # optional - sage.rings.number_field - sage: W = A.span([[3,i,i]]) # optional - sage.rings.number_field - sage: U = V/W; U # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: k. = QuadraticField(-1) + sage: A = k^3; V = A.span([[1,0,i], [2,i,0]]) + sage: W = A.span([[3,i,i]]) + sage: U = V/W; U Vector space quotient V/W of dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I where V: Vector space of degree 3 and dimension 2 over Number Field in i @@ -320,20 +321,20 @@ class FreeModule_ambient_field_quotient(FreeModule_ambient_field): [ 0 1 -2] W: Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 1/3*i 1/3*i] - sage: U.V() # optional - sage.rings.number_field + Basis matrix: + [ 1 1/3*i 1/3*i] + sage: U.V() Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 0 i] [ 0 1 -2] - sage: U.W() # optional - sage.rings.number_field + sage: U.W() Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 1/3*i 1/3*i] - sage: U.quotient_map() # optional - sage.rings.number_field + sage: U.quotient_map() Vector space morphism represented by the matrix: [ 1] [3*i] @@ -343,18 +344,18 @@ class FreeModule_ambient_field_quotient(FreeModule_ambient_field): [ 1 0 i] [ 0 1 -2] Codomain: Vector space quotient V/W of dimension 1 over Number Field in i - with defining polynomial x^2 + 1 with i = 1*I where - V: Vector space of degree 3 and dimension 2 over Number Field in i - with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 0 i] - [ 0 1 -2] - W: Vector space of degree 3 and dimension 1 over Number Field in i - with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 1/3*i 1/3*i] - sage: Z = V.quotient(W) # optional - sage.rings.number_field - sage: Z == U # optional - sage.rings.number_field + with defining polynomial x^2 + 1 with i = 1*I where + V: Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + Basis matrix: + [ 1 0 i] + [ 0 1 -2] + W: Vector space of degree 3 and dimension 1 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + Basis matrix: + [ 1 1/3*i 1/3*i] + sage: Z = V.quotient(W) + sage: Z == U True We create three quotient spaces and compare them:: @@ -441,19 +442,19 @@ def _repr_(self): We create a quotient vector space over a finite field:: - sage: k. = GF(9); A = k^3; V = A.span_of_basis([[1,0,a], [a,a,1]]); W = V.span([V.1]) # optional - sage.libs.pari - sage: Q = V/W # optional - sage.libs.pari + sage: k. = GF(9); A = k^3; V = A.span_of_basis([[1,0,a], [a,a,1]]); W = V.span([V.1]) # needs sage.libs.pari + sage: Q = V/W # needs sage.libs.pari Note the type:: - sage: type(Q) # optional - sage.libs.pari + sage: type(Q) # needs sage.libs.pari The string representation mentions that this is a quotient `V/W`, that the quotient has dimension 1 and is over a finite field, and also describes `V` and `W`:: - sage: Q._repr_() # optional - sage.libs.pari + sage: Q._repr_() # needs sage.libs.pari 'Vector space quotient V/W of dimension 1 over Finite Field in a of size 3^2 where\nV: Vector space of degree 3 and dimension 2 over Finite Field in a of size 3^2\nUser basis matrix:\n[1 0 a]\n[a a 1]\nW: Vector space of degree 3 and dimension 1 over Finite Field in a of size 3^2\nBasis matrix:\n[ 1 1 a + 2]' """ return "%s space quotient V/W of dimension %s over %s where\nV: %s\nW: %s" % ( diff --git a/src/sage/modules/tensor_operations.py b/src/sage/modules/tensor_operations.py index e82c5a4341a..41743870ca7 100644 --- a/src/sage/modules/tensor_operations.py +++ b/src/sage/modules/tensor_operations.py @@ -119,7 +119,7 @@ def antisymmetrized_coordinate_sums(dim, n): EXAMPLES:: sage: from sage.modules.tensor_operations import antisymmetrized_coordinate_sums - sage: antisymmetrized_coordinate_sums(3, 2) # optional - sage.groups + sage: antisymmetrized_coordinate_sums(3, 2) # needs sage.groups ((0, 1) - (1, 0), (0, 2) - (2, 0), (1, 2) - (2, 1)) """ from sage.structure.formal_sum import FormalSum @@ -379,8 +379,8 @@ def _init_power_operation_vectors(self, i, linear_combinations): sage: Sym2_R = TensorOperation([R,R], operation='symmetric') sage: Sym2_R.vectors() # indirect doctest ((1, 0, 0), (1, 2, 0), (-1, -2, 0), (1, 4, 4), (-1, -4, -4)) - sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # optional - sage.groups - sage: Alt2_R.vectors() # indirect doctest # optional - sage.groups + sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # needs sage.groups + sage: Alt2_R.vectors() # indirect doctest # needs sage.groups ((2), (-2)) """ rays = [self._V[j].vectors()[k] for j, k in enumerate(i)] @@ -453,8 +453,8 @@ def _init_antisymmetric(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (1,2), (-1,-2)], QQ, 2) - sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # indirect doctest # optional - sage.groups - sage: sorted(Alt2_R._index_map.items()) # optional - sage.groups + sage: Alt2_R = TensorOperation([R, R], operation='antisymmetric') # indirect doctest # needs sage.groups + sage: sorted(Alt2_R._index_map.items()) # needs sage.groups [((0, 1), 0), ((0, 2), 1)] """ n = len(self._V) @@ -517,17 +517,17 @@ def index_map(self, *i): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups - sage: detR.index_map(1, 0) # optional - sage.groups + sage: detR = TensorOperation([R]*2, 'antisymmetric') # needs sage.groups + sage: detR.index_map(1, 0) # needs sage.groups 0 - sage: detR.index_map(0, 1) # optional - sage.groups + sage: detR.index_map(0, 1) # needs sage.groups 0 TESTS:: - sage: sorted(detR._index_map.items()) # optional - sage.groups + sage: sorted(detR._index_map.items()) # needs sage.groups [((0, 1), 0), ((0, 2), 1), ((1, 2), 2)] - sage: detR.vectors() # optional - sage.groups + sage: detR.vectors() # needs sage.groups ((1), (-3), (2)) """ if len(i) == 1 and isinstance(i[0], (list, tuple)): @@ -553,10 +553,10 @@ def preimage(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups - sage: sorted(detR.preimage()) # optional - sage.groups + sage: detR = TensorOperation([R]*2, 'antisymmetric') # needs sage.groups + sage: sorted(detR.preimage()) # needs sage.groups [(0, 1), (0, 2), (1, 2)] - sage: sorted(detR.codomain()) # optional - sage.groups + sage: sorted(detR.codomain()) # needs sage.groups [0, 1, 2] """ return self._index_map.keys() @@ -574,10 +574,10 @@ def codomain(self): sage: from sage.modules.tensor_operations import \ ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) - sage: detR = TensorOperation([R]*2, 'antisymmetric') # optional - sage.groups - sage: sorted(detR.preimage()) # optional - sage.groups + sage: detR = TensorOperation([R]*2, 'antisymmetric') # needs sage.groups + sage: sorted(detR.preimage()) # needs sage.groups [(0, 1), (0, 2), (1, 2)] - sage: sorted(detR.codomain()) # optional - sage.groups + sage: sorted(detR.codomain()) # needs sage.groups [0, 1, 2] """ return self._index_map.values() diff --git a/src/sage/modules/torsion_quadratic_module.py b/src/sage/modules/torsion_quadratic_module.py index 21e8a49b82c..19f4a6104da 100644 --- a/src/sage/modules/torsion_quadratic_module.py +++ b/src/sage/modules/torsion_quadratic_module.py @@ -374,8 +374,8 @@ def all_submodules(self): EXAMPLES:: - sage: D = IntegralLattice("D4").discriminant_group() # optional - sage.combinat - sage: D.all_submodules() # optional - sage.combinat + sage: D = IntegralLattice("D4").discriminant_group() # needs sage.combinat + sage: D.all_submodules() # needs sage.combinat [Finite quadratic module over Integer Ring with invariants () Gram matrix of the quadratic form with values in Q/2Z: [], @@ -428,9 +428,9 @@ def brown_invariant(self): EXAMPLES:: - sage: L = IntegralLattice("D4") # optional - sage.combinat - sage: D = L.discriminant_group() # optional - sage.combinat - sage: D.brown_invariant() # optional - sage.combinat + sage: L = IntegralLattice("D4") # needs sage.combinat + sage: D = L.discriminant_group() # needs sage.combinat + sage: D.brown_invariant() # needs sage.combinat 4 We require the quadratic form to be defined modulo `2 \ZZ`:: @@ -551,24 +551,25 @@ def genus(self, signature_pair): EXAMPLES:: - sage: L = IntegralLattice("D4").direct_sum(IntegralLattice("A2")) # optional - sage.combinat - sage: D = L.discriminant_group() # optional - sage.combinat - sage: genus = D.genus(L.signature_pair()) # optional - sage.combinat sage.libs.pari - sage: genus # optional - sage.combinat sage.libs.pari + sage: # needs sage.combinat + sage: L = IntegralLattice("D4").direct_sum(IntegralLattice("A2")) + sage: D = L.discriminant_group() + sage: genus = D.genus(L.signature_pair()) # needs sage.libs.pari + sage: genus # needs sage.libs.pari Genus of None Signature: (6, 0) Genus symbol at 2: 1^4:2^-2 Genus symbol at 3: 1^-5 3^-1 - sage: genus == L.genus() # optional - sage.combinat sage.libs.pari + sage: genus == L.genus() # needs sage.libs.pari True Let `H` be an even unimodular lattice of signature `(9, 1)`. Then `L = D_4 + A_2` is primitively embedded in `H`. We compute the discriminant form of the orthogonal complement of `L` in `H`:: - sage: DK = D.twist(-1) # optional - sage.combinat sage.libs.pari - sage: DK # optional - sage.combinat sage.libs.pari + sage: DK = D.twist(-1) # needs sage.combinat sage.libs.pari + sage: DK # needs sage.combinat sage.libs.pari Finite quadratic module over Integer Ring with invariants (2, 6) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] @@ -577,7 +578,7 @@ def genus(self, signature_pair): We know that `K` has signature `(5, 1)` and thus we can compute the genus of `K` as:: - sage: DK.genus((3,1)) # optional - sage.combinat sage.libs.pari + sage: DK.genus((3,1)) # needs sage.combinat sage.libs.pari Genus of None Signature: (3, 1) @@ -589,7 +590,7 @@ def genus(self, signature_pair): sage: L = IntegralLattice(matrix.diagonal(range(1, 5))) sage: D = L.discriminant_group() - sage: D.genus((4,0)) # optional - sage.libs.pari + sage: D.genus((4,0)) # needs sage.libs.pari Genus of None Signature: (4, 0) @@ -598,20 +599,21 @@ def genus(self, signature_pair): TESTS:: - sage: L.genus() == D.genus((4,0)) # optional - sage.libs.pari + sage: L.genus() == D.genus((4,0)) # needs sage.libs.pari True - sage: D.genus((1,0)) # optional - sage.libs.pari + sage: D.genus((1,0)) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: this discriminant form and signature do not define a genus A systematic test of lattices of small ranks and determinants:: - sage: from sage.quadratic_forms.genera.genus import genera # optional - sage.libs.pari - sage: signatures = [(1,0), (1,1), (1,2), (3,0), (0,4)] # optional - sage.libs.pari - sage: dets = range(1, 33) # optional - sage.libs.pari - sage: genera = flatten([genera(s, d, even=False) for d in dets for s in signatures]) # long time # optional - sage.libs.pari - sage: all(g == g.discriminant_form().genus(g.signature_pair()) for g in genera) # long time # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: from sage.quadratic_forms.genera.genus import genera + sage: signatures = [(1,0), (1,1), (1,2), (3,0), (0,4)] + sage: dets = range(1, 33) + sage: genera = flatten([genera(s, d, even=False) for d in dets for s in signatures]) # long time + sage: all(g == g.discriminant_form().genus(g.signature_pair()) for g in genera) # long time True """ from sage.quadratic_forms.genera.genus import (Genus_Symbol_p_adic_ring, @@ -754,18 +756,18 @@ def is_genus(self, signature_pair, even=True): EXAMPLES:: - sage: L3 = IntegralLattice(3 * Matrix(ZZ, 2, [2,1,1,2])) # optional - sage.combinat - sage: L = IntegralLattice("D4").direct_sum(L3) # optional - sage.combinat - sage: D = L.discriminant_group() # optional - sage.combinat - sage: D.is_genus((6,0)) # optional - sage.combinat + sage: L3 = IntegralLattice(3 * Matrix(ZZ, 2, [2,1,1,2])) + sage: L = IntegralLattice("D4").direct_sum(L3) # needs sage.combinat + sage: D = L.discriminant_group() # needs sage.combinat + sage: D.is_genus((6,0)) # needs sage.combinat True Let us see if there is a lattice in the genus defined by the same discriminant form but with a different signature:: - sage: D.is_genus((4,2)) # optional - sage.combinat + sage: D.is_genus((4,2)) # needs sage.combinat False - sage: D.is_genus((16,2)) # optional - sage.combinat + sage: D.is_genus((16,2)) # needs sage.combinat True """ s_plus = ZZ(signature_pair[0]) @@ -835,33 +837,34 @@ def orthogonal_group(self, gens=None, check=False): sage: D = TorsionQuadraticForm(matrix.identity(2)/2) sage: f = matrix(2, [0,1,1,0]) - sage: D.orthogonal_group(gens=[f]).order() # optional - sage.groups + sage: D.orthogonal_group(gens=[f]).order() # needs sage.groups 2 If no generators are given a slow brute force approach is used to calculate the full orthogonal group:: sage: D = TorsionQuadraticForm(matrix.identity(3)/2) - sage: OD = D.orthogonal_group() # optional - sage.groups - sage: OD.order() # optional - sage.groups + sage: OD = D.orthogonal_group() # needs sage.groups + sage: OD.order() # needs sage.groups 6 - sage: fd = D.hom([D.1, D.0, D.2]) - sage: OD(fd) # optional - sage.groups + sage: fd = D.hom([D.1, D.0, D.2]) # needs sage.symbolic + sage: OD(fd) # needs sage.groups [0 1 0] [1 0 0] [0 0 1] We compute the kernel of the action of the orthogonal group of `L` on the discriminant group:: - sage: L = IntegralLattice('A4') # optional - sage.combinat - sage: O = L.orthogonal_group() # optional - sage.combinat sage.groups - sage: D = L.discriminant_group() # optional - sage.combinat sage.groups - sage: Obar = D.orthogonal_group(O.gens()) # optional - sage.combinat sage.groups - sage: O.order() # optional - sage.combinat sage.groups + sage: # needs sage.combinat + sage: L = IntegralLattice('A4') + sage: O = L.orthogonal_group() # needs sage.groups + sage: D = L.discriminant_group() # needs sage.groups + sage: Obar = D.orthogonal_group(O.gens()) # needs sage.groups + sage: O.order() # needs sage.groups 240 - sage: Obar.order() # optional - sage.combinat sage.groups + sage: Obar.order() # needs sage.groups 2 - sage: phi = O.hom(Obar.gens()) # optional - sage.combinat sage.groups - sage: phi.kernel().order() # optional - sage.combinat sage.groups + sage: phi = O.hom(Obar.gens()) # needs sage.groups + sage: phi.kernel().order() # needs sage.groups 120 """ from sage.groups.fqf_orthogonal import FqfOrthogonalGroup, _isom_fqf @@ -989,13 +992,13 @@ def normal_form(self, partial=False): EXAMPLES:: sage: L1 = IntegralLattice(matrix([[-2,0,0], [0,1,0], [0,0,4]])) - sage: L1.discriminant_group().normal_form() # optional - sage.libs.pari sage.rings.padics + sage: L1.discriminant_group().normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4) Gram matrix of the quadratic form with values in Q/Z: [1/2 0] [ 0 1/4] sage: L2 = IntegralLattice(matrix([[-2,0,0], [0,1,0], [0,0,-4]])) - sage: L2.discriminant_group().normal_form() # optional - sage.libs.pari sage.rings.padics + sage: L2.discriminant_group().normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4) Gram matrix of the quadratic form with values in Q/Z: [1/2 0] @@ -1007,13 +1010,13 @@ def normal_form(self, partial=False): sage: AL1 = L1.discriminant_group() sage: L2 = IntegralLattice(matrix([[-4,0,0], [0,-4,0], [0,0,2]])) sage: AL2 = L2.discriminant_group() - sage: AL1.normal_form() # optional - sage.libs.pari sage.rings.padics + sage: AL1.normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] [ 0 1/4 0] [ 0 0 5/4] - sage: AL2.normal_form() # optional - sage.libs.pari sage.rings.padics + sage: AL2.normal_form() # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] @@ -1033,7 +1036,7 @@ def normal_form(self, partial=False): [ 1/12 1/6 1/36 1/9] [ 5/36 1/36 1/36 11/72] [ 1/36 1/9 11/72 1/36] - sage: T.normal_form() # optional - sage.libs.pari sage.rings.padics + sage: T.normal_form() # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/3)Z: [ 1/6 1/12 0 0 0 0 0 0] @@ -1050,7 +1053,7 @@ def normal_form(self, partial=False): A degenerate case:: sage: T = TorsionQuadraticModule((1/6)*D4dual, D4, modulus=1/36) - sage: T.normal_form() # optional - sage.libs.pari sage.rings.padics + sage: T.normal_form() # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/18)Z: [1/36 1/72 0 0 0 0 0 0] diff --git a/src/sage/modules/tutorial_free_modules.py b/src/sage/modules/tutorial_free_modules.py index d5dd60d00bf..8fe8cd8c7df 100644 --- a/src/sage/modules/tutorial_free_modules.py +++ b/src/sage/modules/tutorial_free_modules.py @@ -40,7 +40,7 @@ sage: F = CombinatorialFreeModule(ZZ, CC); F.an_element() B[1.00000000000000*I] - sage: F = CombinatorialFreeModule(ZZ, Partitions(NonNegativeIntegers(), # optional - sage.combinat + sage: F = CombinatorialFreeModule(ZZ, Partitions(NonNegativeIntegers(), # needs sage.combinat ....: max_part=3)); F.an_element() 2*B[[]] + 2*B[[1]] + 3*B[[2]] sage: F = CombinatorialFreeModule(ZZ, ['spam', 'eggs', '42']); F.an_element() diff --git a/src/sage/modules/vector_complex_double_dense.pyx b/src/sage/modules/vector_complex_double_dense.pyx index 3f7b31bc787..d9715fbdc82 100644 --- a/src/sage/modules/vector_complex_double_dense.pyx +++ b/src/sage/modules/vector_complex_double_dense.pyx @@ -4,16 +4,17 @@ Dense complex double vectors using a NumPy backend EXAMPLES:: - sage: v = vector(CDF, [(1,-1), (2,pi), (3,5)]); v # optional - sage.symbolic + sage: # needs sage.symbolic + sage: v = vector(CDF, [(1,-1), (2,pi), (3,5)]); v (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: type(v) # optional - sage.symbolic + sage: type(v) - sage: parent(v) # optional - sage.symbolic + sage: parent(v) Vector space of dimension 3 over Complex Double Field - sage: v[0] = 5 # optional - sage.symbolic - sage: v # optional - sage.symbolic + sage: v[0] = 5 + sage: v (5.0, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: loads(dumps(v)) == v # optional - sage.symbolic + sage: loads(dumps(v)) == v True TESTS:: @@ -54,9 +55,9 @@ cdef class Vector_complex_double_dense(Vector_double_dense): EXAMPLES:: - sage: v = vector(CDF, [(1,-1), (2,pi), (3,5)]); v # optional - sage.symbolic + sage: v = vector(CDF, [(1,-1), (2,pi), (3,5)]); v # needs sage.symbolic (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: v*v # rel tol 1e-15 # optional - sage.symbolic + sage: v*v # rel tol 1e-15 # needs sage.symbolic -21.86960440108936 + 40.56637061435917*I """ def __cinit__(self, parent, entries, coerce=True, copy=True): diff --git a/src/sage/modules/vector_double_dense.pyx b/src/sage/modules/vector_double_dense.pyx index 557ebc3ed8a..eaab8f6c098 100644 --- a/src/sage/modules/vector_double_dense.pyx +++ b/src/sage/modules/vector_double_dense.pyx @@ -7,16 +7,16 @@ Complex Double Field EXAMPLES:: - sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]); v # optional - sage.symbolic + sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]); v # needs sage.symbolic (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: type(v) # optional - sage.symbolic + sage: type(v) # needs sage.symbolic - sage: parent(v) # optional - sage.symbolic + sage: parent(v) # needs sage.symbolic Vector space of dimension 3 over Complex Double Field - sage: v[0] = 5 # optional - sage.symbolic - sage: v # optional - sage.symbolic + sage: v[0] = 5 # needs sage.symbolic + sage: v # needs sage.symbolic (5.0, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: loads(dumps(v)) == v # optional - sage.symbolic + sage: loads(dumps(v)) == v # needs sage.symbolic True sage: v = vector(RDF, [1,2,3,4]); v (1.0, 2.0, 3.0, 4.0) diff --git a/src/sage/modules/vector_integer_dense.pyx b/src/sage/modules/vector_integer_dense.pyx index 593de691422..177ada5dea1 100644 --- a/src/sage/modules/vector_integer_dense.pyx +++ b/src/sage/modules/vector_integer_dense.pyx @@ -314,10 +314,10 @@ cdef class Vector_integer_dense(free_module_element.FreeModuleElement): sage: A = random_matrix(ZZ,1,3) sage: v = A.row(0) - sage: vs = singular(v) # optional - sage.libs.singular - sage: vs._repr_() == '{},\n{},\n{}'.format(*v) # optional - sage.libs.singular + sage: vs = singular(v) # needs sage.libs.singular + sage: vs._repr_() == '{},\n{},\n{}'.format(*v) # needs sage.libs.singular True - sage: vs.type() # optional - sage.libs.singular + sage: vs.type() # needs sage.libs.singular 'intvec' """ if singular is None: diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index aee4d8ce938..322a3a00f6f 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -58,20 +58,20 @@ TESTS:: sage: v = vector(Integers(389), [1,2,3,4,5]) sage: loads(dumps(v)) == v True - sage: v = vector(Integers(next_prime(10^20)), [1,2,3,4,5]) # optional - sage.libs.pari - sage: loads(dumps(v)) == v # optional - sage.libs.pari + sage: v = vector(Integers(next_prime(10^20)), [1,2,3,4,5]) # needs sage.libs.pari + sage: loads(dumps(v)) == v True - sage: K = GF(previous_prime(2^31)) # optional - sage.libs.pari - sage: v = vector(K, [42]); type(v[0]) # optional - sage.libs.pari + sage: K = GF(previous_prime(2^31)) # needs sage.rings.finite_rings + sage: v = vector(K, [42]); type(v[0]) # needs sage.rings.finite_rings - sage: ~v[0] # optional - sage.libs.pari + sage: ~v[0] # needs sage.rings.finite_rings 2096353084 - sage: K = GF(next_prime(2^31)) # optional - sage.libs.pari - sage: v = vector(K, [42]); type(v[0]) # optional - sage.libs.pari + sage: K = GF(next_prime(2^31)) # needs sage.rings.finite_rings + sage: v = vector(K, [42]); type(v[0]) # needs sage.rings.finite_rings - sage: ~v[0] # optional - sage.libs.pari + sage: ~v[0] # needs sage.rings.finite_rings 1482786336 sage: w = vector(GF(11), [-1,0,0,0]) @@ -82,17 +82,17 @@ TESTS:: Test that :trac:`28042` is fixed:: sage: p = 193379 - sage: K = GF(p) # optional - sage.rings.finite_rings - sage: a = K(1) # optional - sage.rings.finite_rings - sage: b = K(191495) # optional - sage.rings.finite_rings - sage: c = K(109320) # optional - sage.rings.finite_rings - sage: d = K(167667) # optional - sage.rings.finite_rings + sage: K = GF(p) # needs sage.rings.finite_rings + sage: a = K(1) # needs sage.rings.finite_rings + sage: b = K(191495) # needs sage.rings.finite_rings + sage: c = K(109320) # needs sage.rings.finite_rings + sage: d = K(167667) # needs sage.rings.finite_rings sage: e = 103937 - sage: a*c + b*d - e # optional - sage.rings.finite_rings + sage: a*c + b*d - e # needs sage.rings.finite_rings 102041 - sage: vector([a,b]) * vector([c,d]) - e # optional - sage.libs.pari + sage: vector([a,b]) * vector([c,d]) - e # needs sage.rings.finite_rings 102041 - sage: type(vector([a,b]) * vector([c,d])) # optional - sage.libs.pari + sage: type(vector([a,b]) * vector([c,d])) # needs sage.rings.finite_rings AUTHOR: diff --git a/src/sage/modules/vector_real_double_dense.pyx b/src/sage/modules/vector_real_double_dense.pyx index 55b04c08834..bf7c75f1605 100644 --- a/src/sage/modules/vector_real_double_dense.pyx +++ b/src/sage/modules/vector_real_double_dense.pyx @@ -4,16 +4,17 @@ Dense real double vectors using a NumPy backend EXAMPLES:: - sage: v = vector(RDF, [1, pi, sqrt(2)]); v # optional - sage.symbolic + sage: # needs sage.symbolic + sage: v = vector(RDF, [1, pi, sqrt(2)]); v (1.0, 3.141592653589793, 1.414213562373095) - sage: type(v) # optional - sage.symbolic + sage: type(v) - sage: parent(v) # optional - sage.symbolic + sage: parent(v) Vector space of dimension 3 over Real Double Field - sage: v[0] = 5 # optional - sage.symbolic - sage: v # optional - sage.symbolic + sage: v[0] = 5 + sage: v (5.0, 3.141592653589793, 1.414213562373095) - sage: loads(dumps(v)) == v # optional - sage.symbolic + sage: loads(dumps(v)) == v True AUTHORS: diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 81200afbb1d..9b86bd457a3 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -41,12 +41,12 @@ sage: F = Integers(13) sage: D = F^3 sage: C = F^2 - sage: x, y, z = var('x y z') # optional - sage.symbolic - sage: f(x, y, z) = [2*x + 3*y + 5*z, x + z] # optional - sage.symbolic - sage: rho = linear_transformation(D, C, f) # optional - sage.symbolic - sage: f(1, 2, 3) # optional - sage.symbolic + sage: x, y, z = var('x y z') # needs sage.symbolic + sage: f(x, y, z) = [2*x + 3*y + 5*z, x + z] # needs sage.symbolic + sage: rho = linear_transformation(D, C, f) # needs sage.symbolic + sage: f(1, 2, 3) # needs sage.symbolic (23, 4) - sage: rho([1, 2, 3]) # optional - sage.symbolic + sage: rho([1, 2, 3]) # needs sage.symbolic (10, 4) A "vector space homspace" is the set of all linear transformations @@ -70,13 +70,14 @@ A homomorphism may also be created via a method on the domain. :: - sage: F = QQ[sqrt(3)] # optional - sage.rings.number_field sage.symbolic - sage: a = F.gen(0) # optional - sage.rings.number_field sage.symbolic - sage: D = F^2 # optional - sage.rings.number_field sage.symbolic - sage: C = F^2 # optional - sage.rings.number_field sage.symbolic - sage: A = matrix(F, [[a, 1], [2*a, 2]]) # optional - sage.rings.number_field sage.symbolic - sage: psi = D.hom(A, C) # optional - sage.rings.number_field sage.symbolic - sage: psi # optional - sage.rings.number_field sage.symbolic + sage: # needs sage.rings.number_field sage.symbolic + sage: F = QQ[sqrt(3)] + sage: a = F.gen(0) + sage: D = F^2 + sage: C = F^2 + sage: A = matrix(F, [[a, 1], [2*a, 2]]) + sage: psi = D.hom(A, C) + sage: psi Vector space morphism represented by the matrix: [ sqrt3 1] [2*sqrt3 2] @@ -84,7 +85,7 @@ with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? Codomain: Vector space of dimension 2 over Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? - sage: psi([1, 4]) # optional - sage.rings.number_field sage.symbolic + sage: psi([1, 4]) (9*sqrt3, 9) Properties @@ -151,10 +152,10 @@ matrix representation used to represent linear transformations are relative to the bases of both the domain and codomain. :: - sage: A = graphs.PetersenGraph().adjacency_matrix() # optional - sage.graphs + sage: A = graphs.PetersenGraph().adjacency_matrix() # needs sage.graphs sage: V = QQ^10 - sage: phi = linear_transformation(V, V, A) # optional - sage.graphs - sage: phi # optional - sage.graphs + sage: phi = linear_transformation(V, V, A) # needs sage.graphs + sage: phi # needs sage.graphs Vector space morphism represented by the matrix: [0 1 0 0 1 1 0 0 0 0] [1 0 1 0 0 0 1 0 0 0] @@ -169,13 +170,14 @@ Domain: Vector space of dimension 10 over Rational Field Codomain: Vector space of dimension 10 over Rational Field - sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] # optional - sage.graphs - sage: B2 = [V.gen(0)] + [-V.gen(i-1) + V.gen(i) for i in range(1,10)] # optional - sage.graphs - sage: D = V.subspace_with_basis(B1) # optional - sage.graphs - sage: C = V.subspace_with_basis(B2) # optional - sage.graphs - sage: rho = phi.restrict_codomain(C) # optional - sage.graphs - sage: zeta = rho.restrict_domain(D) # optional - sage.graphs - sage: zeta # optional - sage.graphs + sage: # needs sage.graphs + sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] + sage: B2 = [V.gen(0)] + [-V.gen(i-1) + V.gen(i) for i in range(1,10)] + sage: D = V.subspace_with_basis(B1) + sage: C = V.subspace_with_basis(B2) + sage: rho = phi.restrict_codomain(C) + sage: zeta = rho.restrict_domain(D) + sage: zeta Vector space morphism represented by the matrix: [6 5 4 3 3 2 1 0 0 0] [6 5 4 3 2 2 2 1 0 0] @@ -217,16 +219,17 @@ matrix that has well-behaved eigenvalues, as part of showing that these do not change as the representation changes. :: - sage: A = graphs.PetersenGraph().adjacency_matrix() # optional - sage.graphs + sage: A = graphs.PetersenGraph().adjacency_matrix() # needs sage.graphs sage: V = QQ^10 - sage: phi = linear_transformation(V, V, A) # optional - sage.graphs - sage: phi.eigenvalues() # optional - sage.graphs + sage: phi = linear_transformation(V, V, A) # needs sage.graphs + sage: phi.eigenvalues() # needs sage.graphs [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] - sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] # optional - sage.graphs - sage: C = V.subspace_with_basis(B1) # optional - sage.graphs - sage: zeta = phi.restrict(C) # optional - sage.graphs - sage: zeta # optional - sage.graphs + sage: # needs sage.graphs + sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] + sage: C = V.subspace_with_basis(B1) + sage: zeta = phi.restrict(C) + sage: zeta Vector space morphism represented by the matrix: [ 1 0 1 -1 2 -1 2 -2 2 -2] [ 1 0 1 0 0 0 1 0 0 0] @@ -263,7 +266,7 @@ [0 0 0 0 0 0 0 0 1 1] [0 0 0 0 0 0 0 0 0 1] - sage: zeta.eigenvalues() # optional - sage.graphs + sage: zeta.eigenvalues() # needs sage.graphs [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] Equality @@ -497,10 +500,11 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field - sage: x, y, z = var('x y z') # optional - sage.symbolic - sage: h(x, y, z) = [2*x + z, 5*y] # optional - sage.symbolic - sage: zeta = linear_transformation(QQ^3, QQ^2, h) # optional - sage.symbolic - sage: zeta # optional - sage.symbolic + sage: # needs sage.symbolic + sage: x, y, z = var('x y z') + sage: h(x, y, z) = [2*x + z, 5*y] + sage: zeta = linear_transformation(QQ^3, QQ^2, h) + sage: zeta Vector space morphism represented by the matrix: [2 0] [0 5] @@ -510,7 +514,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): sage: phi == rho True - sage: rho == zeta # optional - sage.symbolic + sage: rho == zeta # needs sage.symbolic True @@ -538,32 +542,34 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): [2 5] [3 7] - sage: s, t = var('s t') # optional - sage.symbolic - sage: h(s, t) = [(-4/5)*s + (1/5)*t, (97/5)*s + (-13/5)*t] # optional - sage.symbolic - sage: zeta = linear_transformation(D, C, h) # optional - sage.symbolic - sage: zeta.matrix() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: s, t = var('s t') + sage: h(s, t) = [(-4/5)*s + (1/5)*t, (97/5)*s + (-13/5)*t] + sage: zeta = linear_transformation(D, C, h) + sage: zeta.matrix() [2 5] [3 7] Finally, we can give an explicit list of images for the basis elements of the domain. :: + sage: # needs sage.rings.number_field sage: x = polygen(QQ) - sage: F. = NumberField(x^3 + x + 1) # optional - sage.rings.number_field - sage: u = vector(F, [1, a, a^2]) # optional - sage.rings.number_field - sage: v = vector(F, [a, a^2, 2]) # optional - sage.rings.number_field - sage: w = u + v # optional - sage.rings.number_field - sage: D = F^3 # optional - sage.rings.number_field - sage: C = F^3 # optional - sage.rings.number_field - sage: rho = linear_transformation(D, C, [u, v, w]) # optional - sage.rings.number_field - sage: rho.matrix() # optional - sage.rings.number_field + sage: F. = NumberField(x^3 + x + 1) + sage: u = vector(F, [1, a, a^2]) + sage: v = vector(F, [a, a^2, 2]) + sage: w = u + v + sage: D = F^3 + sage: C = F^3 + sage: rho = linear_transformation(D, C, [u, v, w]) + sage: rho.matrix() [ 1 a a^2] [ a a^2 2] [ a + 1 a^2 + a a^2 + 2] - sage: C = (F^3).subspace_with_basis([u, v]) # optional - sage.rings.number_field - sage: D = (F^3).subspace_with_basis([u, v]) # optional - sage.rings.number_field - sage: psi = linear_transformation(C, D, [u+v, u-v]) # optional - sage.rings.number_field - sage: psi.matrix() # optional - sage.rings.number_field + sage: C = (F^3).subspace_with_basis([u, v]) + sage: D = (F^3).subspace_with_basis([u, v]) + sage: psi = linear_transformation(C, D, [u+v, u-v]) + sage: psi.matrix() [ 1 1] [ 1 -1] @@ -657,30 +663,30 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): A Sage symbolic function can come in a variety of forms that are not representative of a linear transformation. :: - sage: x, y = var('x, y') # optional - sage.symbolic - sage: f(x, y) = [y, x, y] # optional - sage.symbolic - sage: linear_transformation(QQ^3, QQ^3, f) # optional - sage.symbolic + sage: x, y = var('x, y') # needs sage.symbolic + sage: f(x, y) = [y, x, y] # needs sage.symbolic + sage: linear_transformation(QQ^3, QQ^3, f) # needs sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function has the wrong number of inputs for domain - sage: linear_transformation(QQ^2, QQ^2, f) # optional - sage.symbolic + sage: linear_transformation(QQ^2, QQ^2, f) # needs sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function has the wrong number of outputs for codomain - sage: x, y = var('x y') # optional - sage.symbolic - sage: f(x, y) = [y, x*y] # optional - sage.symbolic - sage: linear_transformation(QQ^2, QQ^2, f) # optional - sage.symbolic + sage: x, y = var('x y') # needs sage.symbolic + sage: f(x, y) = [y, x*y] # needs sage.symbolic + sage: linear_transformation(QQ^2, QQ^2, f) # needs sage.symbolic Traceback (most recent call last): ... ValueError: symbolic function must be linear in all the inputs: unable to convert y to a rational - sage: x, y = var('x y') # optional - sage.symbolic - sage: f(x, y) = [x, 2*y] # optional - sage.symbolic + sage: x, y = var('x y') # needs sage.symbolic + sage: f(x, y) = [x, 2*y] # needs sage.symbolic sage: C = (QQ^2).span([vector(QQ, [1, 1])]) - sage: linear_transformation(QQ^2, C, f) # optional - sage.symbolic + sage: linear_transformation(QQ^2, C, f) Traceback (most recent call last): ... ArithmeticError: some image of the function is not in the codomain, because @@ -904,15 +910,16 @@ def is_invertible(self): A non-invertible linear transformation, an endomorphism of a vector space over a finite field. :: - sage: F. = GF(11^2) # optional - sage.libs.pari - sage: A = matrix(F, [[6*a + 3, 8*a + 2, 10*a + 3], # optional - sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: F. = GF(11^2) + sage: A = matrix(F, [[6*a + 3, 8*a + 2, 10*a + 3], ....: [2*a + 7, 4*a + 3, 2*a + 3], ....: [9*a + 2, 10*a + 10, 3*a + 3]]) - sage: A.nullity() # optional - sage.libs.pari + sage: A.nullity() 1 - sage: E = End(F^3) # optional - sage.libs.pari - sage: zeta = E(A) # optional - sage.libs.pari - sage: zeta.is_invertible() # optional - sage.libs.pari + sage: E = End(F^3) + sage: zeta = E(A) + sage: zeta.is_invertible() False """ # endomorphism or not, this is equivalent to invertibility of diff --git a/src/sage/modules/with_basis/indexed_element.pyx b/src/sage/modules/with_basis/indexed_element.pyx index 4b784a5a5d7..b1d4e6ba691 100644 --- a/src/sage/modules/with_basis/indexed_element.pyx +++ b/src/sage/modules/with_basis/indexed_element.pyx @@ -77,9 +77,9 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: [i for i in sorted(f)] [('a', 1), ('c', 3)] - sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat - sage: a = s([2,1]) + s([3]) # optional - sage.combinat - sage: [i for i in sorted(a)] # optional - sage.combinat + sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat + sage: a = s([2,1]) + s([3]) # needs sage.combinat + sage: [i for i in sorted(a)] # needs sage.combinat [([2, 1], 1), ([3], 1)] """ return iter(self._monomial_coefficients.items()) @@ -102,11 +102,12 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: 'b' in f False - sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat - sage: a = s([2,1]) + s([3]) # optional - sage.combinat - sage: Partition([2,1]) in a # optional - sage.combinat + sage: # needs sage.combinat + sage: s = SymmetricFunctions(QQ).schur() + sage: a = s([2,1]) + s([3]) + sage: Partition([2,1]) in a True - sage: Partition([1,1,1]) in a # optional - sage.combinat + sage: Partition([1,1,1]) in a False """ deprecation(34509, "using 'index in vector' is deprecated; use 'index in vector.support()' instead") @@ -128,11 +129,12 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: hash(f) == hash(B['a'] + 4*B['c']) False - sage: F = RootSystem(['A',2]).ambient_space() # optional - sage.combinat - sage: f = F.simple_root(0) # optional - sage.combinat - sage: hash(f) == hash(F.simple_root(0)) # optional - sage.combinat + sage: # needs sage.combinat + sage: F = RootSystem(['A',2]).ambient_space() + sage: f = F.simple_root(0) + sage: hash(f) == hash(F.simple_root(0)) True - sage: hash(f) == hash(F.simple_root(1)) # optional - sage.combinat + sage: hash(f) == hash(F.simple_root(1)) False This uses the recipe that was proposed for frozendicts in @@ -259,14 +261,15 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat - sage: a = s([2,1])+2*s([3,2]) # optional - sage.combinat - sage: d = a.monomial_coefficients() # optional - sage.combinat - sage: type(d) # optional - sage.combinat + sage: # needs sage.combinat + sage: s = SymmetricFunctions(QQ).schur() + sage: a = s([2,1])+2*s([3,2]) + sage: d = a.monomial_coefficients() + sage: type(d) <... 'dict'> - sage: d[ Partition([2,1]) ] # optional - sage.combinat + sage: d[ Partition([2,1]) ] 1 - sage: d[ Partition([3,2]) ] # optional - sage.combinat + sage: d[ Partition([3,2]) ] 2 """ if copy: @@ -342,17 +345,18 @@ cdef class IndexedFreeModuleElement(ModuleElement): """ TESTS:: - sage: M = QuasiSymmetricFunctions(QQ).M() # optional - sage.combinat - sage: ascii_art(M[1,3]**2) # indirect doctest # optional - sage.combinat + sage: # needs sage.combinat + sage: M = QuasiSymmetricFunctions(QQ).M() + sage: ascii_art(M[1,3]**2) # indirect doctest 4*M + 2*M + 2*M + 2*M + 2*M + M *** ****** *** *** *** ****** *** * * **** *** ** * * *** * ** * * - sage: ascii_art(M.zero()) # optional - sage.combinat + sage: ascii_art(M.zero()) 0 - sage: DA = DescentAlgebra(QQ, 4) # optional - sage.combinat - sage: ascii_art(DA.an_element()) # optional - sage.combinat + sage: DA = DescentAlgebra(QQ, 4) + sage: ascii_art(DA.an_element()) 2*B + 2*B + 3*B * ** * * * ** @@ -419,8 +423,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): """ TESTS:: - sage: M = QuasiSymmetricFunctions(QQ).M() # optional - sage.combinat - sage: unicode_art(M[1,1]**2) # indirect doctest # optional - sage.combinat + sage: M = QuasiSymmetricFunctions(QQ).M() # needs sage.combinat + sage: unicode_art(M[1,1]**2) # indirect doctest # needs sage.combinat 6*M + 2*M + 2*M + 2*M + M ┌┐ ┌┬┐ ┌┐ ┌┐ ┌┬┐ ├┤ ├┼┘ ┌┼┤ ├┤ ┌┼┼┘ @@ -430,7 +434,7 @@ cdef class IndexedFreeModuleElement(ModuleElement): The following test failed before :trac:`26850`:: - sage: unicode_art([M.zero()]) # indirect doctest # optional - sage.combinat + sage: unicode_art([M.zero()]) # indirect doctest # needs sage.combinat [ 0 ] """ from sage.misc.repr import coeff_repr @@ -501,9 +505,9 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat - sage: a = 2 + QS3([2,1,3]) # optional - sage.combinat - sage: latex(a) #indirect doctest # optional - sage.combinat + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # needs sage.combinat + sage: a = 2 + QS3([2,1,3]) # needs sage.combinat + sage: latex(a) #indirect doctest # needs sage.combinat 2 [1, 2, 3] + [2, 1, 3] :: @@ -563,10 +567,11 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat - sage: a = s([2,1]) # optional - sage.combinat - sage: b = s([1,1,1]) # optional - sage.combinat - sage: a == b # optional - sage.combinat + sage: # needs sage.combinat + sage: s = SymmetricFunctions(QQ).schur() + sage: a = s([2,1]) + sage: b = s([1,1,1]) + sage: a == b False .. TODO:: @@ -590,20 +595,20 @@ cdef class IndexedFreeModuleElement(ModuleElement): Traceback (most recent call last): ... TypeError: do not know how to make x (= 0) an element of self (=Free module generated by {1, 2, 3} over Rational Field) - sage: F = AlgebrasWithBasis(QQ).example() # optional - sage.combinat - sage: F.one() == 1 # optional - sage.combinat + sage: F = AlgebrasWithBasis(QQ).example() # needs sage.combinat + sage: F.one() == 1 # needs sage.combinat True - sage: 1 == F.one() # optional - sage.combinat + sage: 1 == F.one() # needs sage.combinat True - sage: 2 * F.one() == int(2) # optional - sage.combinat + sage: 2 * F.one() == int(2) # needs sage.combinat True - sage: int(2) == 2 * F.one() # optional - sage.combinat + sage: int(2) == 2 * F.one() # needs sage.combinat True - sage: S = SymmetricFunctions(QQ); s = S.s(); p = S.p() # optional - sage.combinat - sage: p[2] == s[2] - s[1, 1] # optional - sage.combinat + sage: S = SymmetricFunctions(QQ); s = S.s(); p = S.p() # needs sage.combinat + sage: p[2] == s[2] - s[1, 1] # needs sage.combinat True - sage: p[2] == s[2] # optional - sage.combinat + sage: p[2] == s[2] # needs sage.combinat False This feature is disputable, in particular since it can make @@ -613,19 +618,20 @@ cdef class IndexedFreeModuleElement(ModuleElement): can vary because their indices are incomparable with ``cmp``. The following test did fail before :trac:`12489` :: - sage: F = CombinatorialFreeModule(QQ, Subsets([1,2,3])) # optional - sage.combinat - sage: x = F.an_element() # optional - sage.combinat - sage: (x+F.zero()).terms() # random # optional - sage.combinat + sage: # needs sage.combinat + sage: F = CombinatorialFreeModule(QQ, Subsets([1,2,3])) + sage: x = F.an_element() + sage: (x+F.zero()).terms() # random [2*B[{1}], 3*B[{2}], B[{}]] - sage: x.terms() # random # optional - sage.combinat + sage: x.terms() # random [2*B[{1}], B[{}], 3*B[{2}]] - sage: x+F.zero() == x # optional - sage.combinat + sage: x+F.zero() == x True TESTS:: sage: TestSuite(F1).run() - sage: TestSuite(F).run() # optional - sage.combinat + sage: TestSuite(F).run() """ cdef IndexedFreeModuleElement elt = other @@ -653,11 +659,12 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat - sage: s([2,1]) + s([5,4]) # indirect doctest # optional - sage.combinat + sage: # needs sage.combinat + sage: s = SymmetricFunctions(QQ).schur() + sage: s([2,1]) + s([5,4]) # indirect doctest s[2, 1] + s[5, 4] - sage: a = s([2,1]) + 0 # optional - sage.combinat - sage: len(a.monomial_coefficients()) # optional - sage.combinat + sage: a = s([2,1]) + 0 + sage: len(a.monomial_coefficients()) 1 """ return type(self)(self._parent, @@ -676,8 +683,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat - sage: -s([2,1]) # indirect doctest # optional - sage.combinat + sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat + sage: -s([2,1]) # indirect doctest # needs sage.combinat -s[2, 1] """ return type(self)(self._parent, negate(self._monomial_coefficients)) @@ -693,8 +700,8 @@ cdef class IndexedFreeModuleElement(ModuleElement): :: - sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat - sage: s([2,1]) - s([5,4]) # indirect doctest # optional - sage.combinat + sage: s = SymmetricFunctions(QQ).schur() # needs sage.combinat + sage: s([2,1]) - s([5,4]) # indirect doctest # needs sage.combinat s[2, 1] - s[5, 4] """ return type(self)(self._parent, @@ -708,15 +715,16 @@ cdef class IndexedFreeModuleElement(ModuleElement): EXAMPLES:: - sage: p = Partition([2,1]) # optional - sage.combinat - sage: q = Partition([1,1,1]) # optional - sage.combinat - sage: s = SymmetricFunctions(QQ).schur() # optional - sage.combinat - sage: a = s(p) # optional - sage.combinat - sage: a[p] # optional - sage.combinat + sage: # needs sage.combinat + sage: p = Partition([2,1]) + sage: q = Partition([1,1,1]) + sage: s = SymmetricFunctions(QQ).schur() + sage: a = s(p) + sage: a[p] 1 - sage: a[q] # optional - sage.combinat + sage: a[q] 0 - sage: a[[2,1]] # optional - sage.combinat + sage: a[[2,1]] Traceback (most recent call last): ... TypeError: unhashable type: 'list' @@ -765,23 +773,24 @@ cdef class IndexedFreeModuleElement(ModuleElement): More examples:: - sage: QS3 = SymmetricGroupAlgebra(QQ, 3) # optional - sage.combinat - sage: a = 2*QS3([1,2,3]) + 4*QS3([3,2,1]) # optional - sage.combinat - sage: a._vector_() # optional - sage.combinat + sage: # needs sage.combinat + sage: QS3 = SymmetricGroupAlgebra(QQ, 3) + sage: a = 2*QS3([1,2,3]) + 4*QS3([3,2,1]) + sage: a._vector_() (2, 0, 0, 0, 0, 4) - sage: a.to_vector() # optional - sage.combinat + sage: a.to_vector() (2, 0, 0, 0, 0, 4) - sage: vector(a) # optional - sage.combinat + sage: vector(a) (2, 0, 0, 0, 0, 4) - sage: a == QS3.from_vector(a.to_vector()) # optional - sage.combinat + sage: a == QS3.from_vector(a.to_vector()) True - sage: a.to_vector(sparse=True) # optional - sage.combinat + sage: a.to_vector(sparse=True) (2, 0, 0, 0, 0, 4) If ``new_base_ring`` is specified, then a vector over ``new_base_ring`` is returned:: - sage: a._vector_(RDF) # optional - sage.combinat + sage: a._vector_(RDF) # needs sage.combinat (2.0, 0.0, 0.0, 0.0, 0.0, 4.0) .. NOTE:: @@ -859,18 +868,18 @@ cdef class IndexedFreeModuleElement(ModuleElement): example with polynomials or fraction fields (:trac:`8832`):: sage: P. = QQ['q'] - sage: V = CombinatorialFreeModule(P, Permutations()) # optional - sage.combinat - sage: el = V(Permutation([3,1,2])) # optional - sage.combinat - sage: (3/2)*el # optional - sage.combinat + sage: V = CombinatorialFreeModule(P, Permutations()) + sage: el = V(Permutation([3,1,2])) + sage: (3/2)*el 3/2*B[[3, 1, 2]] sage: P. = QQ['q'] sage: F = FractionField(P) - sage: V = CombinatorialFreeModule(F, Words()) # optional - sage.combinat - sage: w = Words()('abc') # optional - sage.combinat - sage: (1+q)*V(w) # optional - sage.combinat + sage: V = CombinatorialFreeModule(F, Words()) # needs sage.combinat + sage: w = Words()('abc') # needs sage.combinat + sage: (1+q)*V(w) # needs sage.combinat (q+1)*B[word: abc] - sage: ((1+q)/q)*V(w) # optional - sage.combinat + sage: ((1+q)/q)*V(w) # needs sage.combinat ((q+1)/q)*B[word: abc] .. TODO:: From 0d6b51baee1347e299f587d69da6d85074422918 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:10 -0700 Subject: [PATCH 67/99] src/sage/matrix: Update file-level doctest tag --- src/sage/matrix/benchmark.py | 2 +- src/sage/matrix/compute_J_ideal.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/benchmark.py b/src/sage/matrix/benchmark.py index 1b9b846d3a8..97117632584 100644 --- a/src/sage/matrix/benchmark.py +++ b/src/sage/matrix/benchmark.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.flint +# sage.doctest: needs sage.flint """ Benchmarks for matrices diff --git a/src/sage/matrix/compute_J_ideal.py b/src/sage/matrix/compute_J_ideal.py index ad20c0ebd15..3055f283a78 100644 --- a/src/sage/matrix/compute_J_ideal.py +++ b/src/sage/matrix/compute_J_ideal.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari (for charpoly, minimal_polynomial in __init__) +# sage.doctest: needs sage.libs.pari (for charpoly, minimal_polynomial in __init__) r""" `J`-ideals of matrices From feb46f807729d8c5aee3930f01ef3559bab84282 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:11 -0700 Subject: [PATCH 68/99] src/sage/modules: Update file-level doctest tag --- src/sage/modules/diamond_cutting.py | 2 +- src/sage/modules/finite_submodule_iter.pyx | 2 +- src/sage/modules/fp_graded/element.py | 2 +- src/sage/modules/fp_graded/free_module.py | 2 +- src/sage/modules/fp_graded/homspace.py | 2 +- src/sage/modules/fp_graded/module.py | 2 +- src/sage/modules/fp_graded/morphism.py | 2 +- src/sage/modules/with_basis/cell_module.py | 2 +- src/sage/modules/with_basis/invariant.py | 2 +- src/sage/modules/with_basis/representation.py | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/modules/diamond_cutting.py b/src/sage/modules/diamond_cutting.py index 97363f37e5b..786a783fabf 100644 --- a/src/sage/modules/diamond_cutting.py +++ b/src/sage/modules/diamond_cutting.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.geometry.polyhedron +# sage.doctest: needs sage.geometry.polyhedron """ Diamond cutting implementation diff --git a/src/sage/modules/finite_submodule_iter.pyx b/src/sage/modules/finite_submodule_iter.pyx index babfbdf7dbc..bb4a730cad9 100644 --- a/src/sage/modules/finite_submodule_iter.pyx +++ b/src/sage/modules/finite_submodule_iter.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: needs sage.rings.finite_rings r""" Iterators over finite submodules of a `\ZZ`-module diff --git a/src/sage/modules/fp_graded/element.py b/src/sage/modules/fp_graded/element.py index a4055b3e3b5..5e348276c33 100755 --- a/src/sage/modules/fp_graded/element.py +++ b/src/sage/modules/fp_graded/element.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat +# sage.doctest: needs sage.combinat r""" Elements of finitely presented graded modules diff --git a/src/sage/modules/fp_graded/free_module.py b/src/sage/modules/fp_graded/free_module.py index cb1caa3581c..f8f2fac3f72 100755 --- a/src/sage/modules/fp_graded/free_module.py +++ b/src/sage/modules/fp_graded/free_module.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat +# sage.doctest: needs sage.combinat r""" Finitely generated free graded left modules over connected graded algebras diff --git a/src/sage/modules/fp_graded/homspace.py b/src/sage/modules/fp_graded/homspace.py index 985cb1d727b..6edb4bb7dd6 100755 --- a/src/sage/modules/fp_graded/homspace.py +++ b/src/sage/modules/fp_graded/homspace.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat +# sage.doctest: needs sage.combinat r""" Homsets of finitely presented graded modules diff --git a/src/sage/modules/fp_graded/module.py b/src/sage/modules/fp_graded/module.py index a61f1d08d49..cb715523ad7 100755 --- a/src/sage/modules/fp_graded/module.py +++ b/src/sage/modules/fp_graded/module.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat +# sage.doctest: needs sage.combinat r""" Finitely presented graded modules diff --git a/src/sage/modules/fp_graded/morphism.py b/src/sage/modules/fp_graded/morphism.py index 75eacd961e7..47f74fd49e5 100755 --- a/src/sage/modules/fp_graded/morphism.py +++ b/src/sage/modules/fp_graded/morphism.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat +# sage.doctest: needs sage.combinat r""" Homomorphisms of finitely presented graded modules diff --git a/src/sage/modules/with_basis/cell_module.py b/src/sage/modules/with_basis/cell_module.py index 8c2fe5a3ac4..66d72f648f8 100644 --- a/src/sage/modules/with_basis/cell_module.py +++ b/src/sage/modules/with_basis/cell_module.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.combinat +# sage.doctest: needs sage.combinat r""" Cell modules """ diff --git a/src/sage/modules/with_basis/invariant.py b/src/sage/modules/with_basis/invariant.py index 1fa4c20c23f..71a4c938424 100644 --- a/src/sage/modules/with_basis/invariant.py +++ b/src/sage/modules/with_basis/invariant.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.groups +# sage.doctest: needs sage.groups r""" Invariant modules """ diff --git a/src/sage/modules/with_basis/representation.py b/src/sage/modules/with_basis/representation.py index 1ee49a740f7..a781fc39ec3 100644 --- a/src/sage/modules/with_basis/representation.py +++ b/src/sage/modules/with_basis/representation.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.groups +# sage.doctest: needs sage.groups """ Representations of a semigroup From 91febfea0297cce8c6475ed1f2abf88bb38b9804 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:13 -0700 Subject: [PATCH 69/99] src/sage/quadratic_forms: Update file-level doctest tag --- src/sage/quadratic_forms/genera/genus.py | 2 +- src/sage/quadratic_forms/genera/normal_form.py | 2 +- src/sage/quadratic_forms/genera/spinor_genus.py | 2 +- src/sage/quadratic_forms/qfsolve.py | 2 +- src/sage/quadratic_forms/quadratic_form__automorphisms.py | 2 +- src/sage/quadratic_forms/quadratic_form__genus.py | 2 +- .../quadratic_form__local_representation_conditions.py | 2 +- src/sage/quadratic_forms/quadratic_form__siegel_product.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/quadratic_forms/genera/genus.py b/src/sage/quadratic_forms/genera/genus.py index 86942da84e1..d0347044906 100644 --- a/src/sage/quadratic_forms/genera/genus.py +++ b/src/sage/quadratic_forms/genera/genus.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: needs sage.libs.pari r""" Genus diff --git a/src/sage/quadratic_forms/genera/normal_form.py b/src/sage/quadratic_forms/genera/normal_form.py index e072adff683..6fdcbb01e56 100644 --- a/src/sage/quadratic_forms/genera/normal_form.py +++ b/src/sage/quadratic_forms/genera/normal_form.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari sage.rings.padics +# sage.doctest: needs sage.libs.pari sage.rings.padics r""" Normal forms for `p`-adic quadratic and bilinear forms diff --git a/src/sage/quadratic_forms/genera/spinor_genus.py b/src/sage/quadratic_forms/genera/spinor_genus.py index 7e6afff21a0..f049496965d 100644 --- a/src/sage/quadratic_forms/genera/spinor_genus.py +++ b/src/sage/quadratic_forms/genera/spinor_genus.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.groups +# sage.doctest: needs sage.groups r""" Spinor genus computations. diff --git a/src/sage/quadratic_forms/qfsolve.py b/src/sage/quadratic_forms/qfsolve.py index f8d82f48cbb..8420d3026e0 100644 --- a/src/sage/quadratic_forms/qfsolve.py +++ b/src/sage/quadratic_forms/qfsolve.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: needs sage.libs.pari """ Solving quadratic equations diff --git a/src/sage/quadratic_forms/quadratic_form__automorphisms.py b/src/sage/quadratic_forms/quadratic_form__automorphisms.py index d12fc95eb5c..d0bf38f71a5 100644 --- a/src/sage/quadratic_forms/quadratic_form__automorphisms.py +++ b/src/sage/quadratic_forms/quadratic_form__automorphisms.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: needs sage.libs.pari """ Automorphisms of Quadratic Forms """ diff --git a/src/sage/quadratic_forms/quadratic_form__genus.py b/src/sage/quadratic_forms/quadratic_form__genus.py index 9f6371b5cdb..8727645b453 100644 --- a/src/sage/quadratic_forms/quadratic_form__genus.py +++ b/src/sage/quadratic_forms/quadratic_form__genus.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: needs sage.libs.pari """ Local and Global Genus Symbols """ diff --git a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py index ccff02a6368..888f4ae2832 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py +++ b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari sage.rings.number_field +# sage.doctest: needs sage.libs.pari sage.rings.number_field """ Local Representation Conditions """ diff --git a/src/sage/quadratic_forms/quadratic_form__siegel_product.py b/src/sage/quadratic_forms/quadratic_form__siegel_product.py index fd5f539c36b..8c381462ce5 100644 --- a/src/sage/quadratic_forms/quadratic_form__siegel_product.py +++ b/src/sage/quadratic_forms/quadratic_form__siegel_product.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.libs.pari +# sage.doctest: needs sage.libs.pari """ Siegel Products """ From f32adef1735e76122d68bfc8e9dfea99b492ddd4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:14 -0700 Subject: [PATCH 70/99] src/sage/stats: Update file-level doctest tag --- src/sage/stats/distributions/discrete_gaussian_integer.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/stats/distributions/discrete_gaussian_integer.pyx b/src/sage/stats/distributions/discrete_gaussian_integer.pyx index f87915b4e4f..2aa28609180 100644 --- a/src/sage/stats/distributions/discrete_gaussian_integer.pyx +++ b/src/sage/stats/distributions/discrete_gaussian_integer.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.symbolic +# sage.doctest: needs sage.symbolic # # distutils: sources = sage/stats/distributions/dgs_gauss_mp.c sage/stats/distributions/dgs_gauss_dp.c sage/stats/distributions/dgs_bern.c # distutils: depends = sage/stats/distributions/dgs_gauss.h sage/stats/distributions/dgs_bern.h sage/stats/distributions/dgs_misc.h From 35dee0eedbc5ca1ef6bb6fc5d2e04da174fa6fd8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 6 Aug 2023 20:45:15 -0700 Subject: [PATCH 71/99] src/sage/tensor: Update file-level doctest tag --- src/sage/tensor/modules/tensor_with_indices.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/tensor/modules/tensor_with_indices.py b/src/sage/tensor/modules/tensor_with_indices.py index 03b160bf37f..3771bb52a3d 100644 --- a/src/sage/tensor/modules/tensor_with_indices.py +++ b/src/sage/tensor/modules/tensor_with_indices.py @@ -1,4 +1,4 @@ -# sage.doctest: optional - sage.groups +# sage.doctest: needs sage.groups r""" Index notation for tensors From 63675beef6fea81fdee1b5da4050294de14b27e1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:19 -0700 Subject: [PATCH 72/99] src/sage/modules: sage -fixdoctests --only-tags --- src/sage/modules/fg_pid/fgp_module.py | 2 +- src/sage/modules/free_module.py | 8 ++-- src/sage/modules/free_module_element.pyx | 2 +- src/sage/modules/free_module_integer.py | 5 +- ...free_quadratic_module_integer_symmetric.py | 48 ++++++++++--------- src/sage/modules/torsion_quadratic_module.py | 2 +- .../modules/with_basis/indexed_element.pyx | 12 +++-- 7 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/sage/modules/fg_pid/fgp_module.py b/src/sage/modules/fg_pid/fgp_module.py index dfc74231fe9..8178afada2d 100644 --- a/src/sage/modules/fg_pid/fgp_module.py +++ b/src/sage/modules/fg_pid/fgp_module.py @@ -1238,7 +1238,7 @@ def gens_vector(self, x, reduce=False): Let us check:: - sage: x == sum(v[i]*D.gen(i) for i in range(len(D.gens()))) + sage: x == sum(v[i]*D.gen(i) for i in range(len(D.gens()))) # needs sage.libs.pari True """ x = self(x) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 3ba7073a381..82af0741d03 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -2775,13 +2775,13 @@ def coordinate_module(self, V): symbols:: sage: M = ModularSymbols(54) # needs sage.modular - sage: S = M.cuspidal_subspace() + sage: S = M.cuspidal_subspace() # needs sage.modular sage: K = S.integral_structure(); K Free module of degree 19 and rank 8 over Integer Ring Echelon basis matrix: [ 0 1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ... - sage: L = M[0].integral_structure(); L + sage: L = M[0].integral_structure(); L # needs sage.modular Free module of degree 19 and rank 2 over Integer Ring Echelon basis matrix: [ 0 1 1 0 -2 1 -1 1 -1 -2 2 0 0 0 0 0 0 0 0] @@ -3814,8 +3814,8 @@ def intersection(self, other): sage: L. = NumberField(x^2 - x + 2) # needs sage.rings.number_field sage: OL = L.ring_of_integers() sage: V = L**3 - sage: W1 = V.span([[0,w/5,0], [1,0,-1/17]], OL) - sage: W2 = V.span([[0,(1-w)/5,0]], OL) + sage: W1 = V.span([[0,w/5,0], [1,0,-1/17]], OL) # needs sage.rings.number_field + sage: W2 = V.span([[0,(1-w)/5,0]], OL) # needs sage.rings.number_field sage: W1.intersection(W2) Free module of degree 3 and rank 1 over Maximal Order in Number Field in w with defining polynomial x^2 - x + 2 diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index e6e81aa6cc9..ca1a6a25dec 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1725,7 +1725,7 @@ cdef class FreeModuleElement(Vector): # abstract base class Symbolic Ring sage: numeric = N(nrm); numeric # needs sage.symbolic 5.83095189484... - sage: numeric.parent() + sage: numeric.parent() # needs sage.symbolic Real Field with 53 bits of precision TESTS: diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index c97438ba210..ea4fcdddf11 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -112,8 +112,9 @@ def IntegerLattice(basis, lll_reduce=True): We construct an ideal lattice from an element of an absolute order:: sage: K. = CyclotomicField(17) # needs sage.rings.number_field - sage: O = K.ring_of_integers() - sage: f = O(-a^15 + a^13 + 4*a^12 - 12*a^11 - 256*a^10 + a^9 - a^7 - 4*a^6 + a^5 + 210*a^4 + 2*a^3 - 2*a^2 + 2*a - 2) + sage: O = K.ring_of_integers() # needs sage.rings.number_field + sage: f = O(-a^15 + a^13 + 4*a^12 - 12*a^11 - 256*a^10 + a^9 - a^7 # needs sage.rings.number_field + ....: - 4*a^6 + a^5 + 210*a^4 + 2*a^3 - 2*a^2 + 2*a - 2) sage: from sage.modules.free_module_integer import IntegerLattice sage: IntegerLattice(f) Free module of degree 16 and rank 16 over Integer Ring diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index d722a2d9195..6354deabfd5 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -1183,30 +1183,32 @@ def orthogonal_group(self, gens=None, is_finite=None): The group acts from the right on the lattice and its discriminant group:: - sage: x = A4.an_element() # needs sage.graphs - sage: g = Aut.an_element(); g # needs sage.graphs sage.libs.gap + sage: # needs sage.graphs + sage: x = A4.an_element() + sage: g = Aut.an_element(); g # needs sage.libs.gap [-1 -1 -1 0] [ 0 0 1 0] [ 0 0 -1 -1] [ 0 1 1 1] - sage: x*g # needs sage.graphs sage.libs.gap + sage: x*g # needs sage.libs.gap (-1, -1, -1, 0) - sage: (x*g).parent() == A4 # needs sage.graphs sage.libs.gap + sage: (x*g).parent() == A4 # needs sage.libs.gap True - sage: (g*x).parent() # needs sage.graphs sage.libs.gap + sage: (g*x).parent() # needs sage.libs.gap Vector space of dimension 4 over Rational Field - sage: y = A4.discriminant_group().an_element() # needs sage.graphs sage.libs.gap - sage: y*g # needs sage.graphs sage.libs.gap + sage: y = A4.discriminant_group().an_element() # needs sage.libs.gap + sage: y*g # needs sage.libs.gap (4) If the group is finite we can compute the usual things:: - sage: Aut.order() # needs sage.graphs sage.libs.gap + sage: # needs sage.graphs sage.libs.gap + sage: Aut.order() 240 - sage: conj = Aut.conjugacy_classes_representatives() # needs sage.graphs sage.libs.gap - sage: len(conj) # needs sage.graphs sage.libs.gap + sage: conj = Aut.conjugacy_classes_representatives() + sage: len(conj) 14 - sage: Aut.structure_description() # needs sage.graphs sage.libs.gap + sage: Aut.structure_description() 'C2 x S5' The lattice can live in a larger ambient space:: @@ -1333,8 +1335,9 @@ def tensor_product(self, other, discard_basis=False): EXAMPLES:: - sage: L = IntegralLattice("D3", [[1,-1,0], [0,1,-1]]) # needs sage.graphs - sage: L1 = L.tensor_product(L); L1 # needs sage.graphs + sage: # needs sage.graphs + sage: L = IntegralLattice("D3", [[1,-1,0], [0,1,-1]]) + sage: L1 = L.tensor_product(L); L1 Lattice of degree 9 and rank 4 over Integer Ring Basis matrix: [ 1 -1 0 -1 1 0 0 0 0] @@ -1351,12 +1354,12 @@ def tensor_product(self, other, discard_basis=False): [-2 1 1 0 0 0 4 -2 -2] [ 1 -2 0 0 0 0 -2 4 0] [ 1 0 -2 0 0 0 -2 0 4] - sage: L1.gram_matrix() # needs sage.graphs + sage: L1.gram_matrix() [ 36 -12 -12 4] [-12 24 4 -8] [-12 4 24 -8] [ 4 -8 -8 16] - sage: L2 = L.tensor_product(L, True); L2 # needs sage.graphs + sage: L2 = L.tensor_product(L, True); L2 Lattice of degree 4 and rank 4 over Integer Ring Standard basis Inner product matrix: @@ -1596,16 +1599,17 @@ def local_modification(M, G, p, check=True): EXAMPLES:: + sage: # needs sage.graphs sage: from sage.modules.free_quadratic_module_integer_symmetric import local_modification - sage: L = IntegralLattice("A3").twist(15) # needs sage.graphs - sage: M = L.maximal_overlattice() # needs sage.graphs - sage: for p in prime_divisors(L.determinant()): # needs sage.graphs + sage: L = IntegralLattice("A3").twist(15) + sage: M = L.maximal_overlattice() + sage: for p in prime_divisors(L.determinant()): ....: M = local_modification(M, L.gram_matrix(), p) - sage: M.genus() == L.genus() # needs sage.graphs + sage: M.genus() == L.genus() True - sage: L = IntegralLattice("D4").twist(3*4) # needs sage.graphs - sage: M = L.maximal_overlattice() # needs sage.graphs - sage: local_modification(M, L.gram_matrix(), 2) # needs sage.graphs + sage: L = IntegralLattice("D4").twist(3*4) + sage: M = L.maximal_overlattice() + sage: local_modification(M, L.gram_matrix(), 2) Lattice of degree 4 and rank 4 over Integer Ring Basis matrix: [1/3 0 2/3 2/3] diff --git a/src/sage/modules/torsion_quadratic_module.py b/src/sage/modules/torsion_quadratic_module.py index 19f4a6104da..c01b8ce8be3 100644 --- a/src/sage/modules/torsion_quadratic_module.py +++ b/src/sage/modules/torsion_quadratic_module.py @@ -847,7 +847,7 @@ def orthogonal_group(self, gens=None, check=False): sage: OD.order() # needs sage.groups 6 sage: fd = D.hom([D.1, D.0, D.2]) # needs sage.symbolic - sage: OD(fd) # needs sage.groups + sage: OD(fd) # needs sage.groups sage.symbolic [0 1 0] [1 0 0] [0 0 1] diff --git a/src/sage/modules/with_basis/indexed_element.pyx b/src/sage/modules/with_basis/indexed_element.pyx index b1d4e6ba691..b47cbd85633 100644 --- a/src/sage/modules/with_basis/indexed_element.pyx +++ b/src/sage/modules/with_basis/indexed_element.pyx @@ -595,14 +595,16 @@ cdef class IndexedFreeModuleElement(ModuleElement): Traceback (most recent call last): ... TypeError: do not know how to make x (= 0) an element of self (=Free module generated by {1, 2, 3} over Rational Field) - sage: F = AlgebrasWithBasis(QQ).example() # needs sage.combinat - sage: F.one() == 1 # needs sage.combinat + + sage: # needs sage.combinat + sage: F = AlgebrasWithBasis(QQ).example() + sage: F.one() == 1 True - sage: 1 == F.one() # needs sage.combinat + sage: 1 == F.one() True - sage: 2 * F.one() == int(2) # needs sage.combinat + sage: 2 * F.one() == int(2) True - sage: int(2) == 2 * F.one() # needs sage.combinat + sage: int(2) == 2 * F.one() True sage: S = SymmetricFunctions(QQ); s = S.s(); p = S.p() # needs sage.combinat From 48aae7d6f5f95e1e3de1be6a1751717b5f4f7720 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:20 -0700 Subject: [PATCH 73/99] src/sage/probability: sage -fixdoctests --only-tags --- src/sage/probability/probability_distribution.pyx | 10 +++++----- src/sage/probability/random_variable.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index 19233136f9a..9df29e85842 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -114,8 +114,8 @@ cdef class ProbabilityDistribution: sage: from sage.probability.probability_distribution import GeneralDiscreteDistribution sage: P = [0.3, 0.4, 0.3] sage: X = GeneralDiscreteDistribution(P) - sage: h, b = X.generate_histogram_data(bins=10) # optional - sage.plot - sage: h # rel tol 1e-08 # optional - sage.plot + sage: h, b = X.generate_histogram_data(bins=10) # needs sage.plot + sage: h # rel tol 1e-08 # needs sage.plot [1.6299999999999999, 0.0, 0.0, @@ -126,7 +126,7 @@ cdef class ProbabilityDistribution: 0.0, 0.0, 1.4650000000000003] - sage: b # optional - sage.plot + sage: b # needs sage.plot [0.0, 0.2, 0.4, @@ -167,7 +167,7 @@ cdef class ProbabilityDistribution: sage: import tempfile sage: P = [0.3, 0.4, 0.3] sage: X = GeneralDiscreteDistribution(P) - sage: with tempfile.NamedTemporaryFile() as f: # optional - sage.plot + sage: with tempfile.NamedTemporaryFile() as f: # needs sage.plot ....: X.generate_histogram_plot(f.name) """ import pylab @@ -963,7 +963,7 @@ cdef class RealDistribution(ProbabilityDistribution): EXAMPLES:: sage: T = RealDistribution('uniform', [0, 2]) - sage: P = T.plot() # optional - sage.plot + sage: P = T.plot() # needs sage.plot """ from sage.plot.plot import plot return plot(self.distribution_function, *args, **kwds) diff --git a/src/sage/probability/random_variable.py b/src/sage/probability/random_variable.py index eb2aebe102e..4a385e55150 100644 --- a/src/sage/probability/random_variable.py +++ b/src/sage/probability/random_variable.py @@ -326,7 +326,7 @@ def __init__(self, X, P, codomain=None, check=False): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) sage: X.set() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} - sage: X.entropy().n() # optional - sage.libs.pari + sage: X.entropy().n() # needs sage.libs.pari 1.99993896484375 A probability space can be defined on any list of elements:: @@ -337,7 +337,7 @@ def __init__(self, X, P, codomain=None, check=False): sage: X = DiscreteProbabilitySpace(S,P) sage: X Discrete probability space defined by {'A': 1/2, 'B': 1/4, 'C': 1/4} - sage: X.entropy().n() # optional - sage.libs.pari + sage: X.entropy().n() # needs sage.libs.pari 1.50000000000000 """ if codomain is None: From 2639932c804ce522866534c5bf5baf1806b81a52 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:21 -0700 Subject: [PATCH 74/99] src/sage/quadratic_forms: sage -fixdoctests --only-tags --- src/sage/quadratic_forms/binary_qf.py | 153 +++++++++--------- src/sage/quadratic_forms/constructions.py | 2 +- src/sage/quadratic_forms/extras.py | 2 +- src/sage/quadratic_forms/genera/genus.py | 4 +- src/sage/quadratic_forms/quadratic_form.py | 61 +++---- .../quadratic_form__equivalence_testing.py | 140 ++++++++-------- ...uadratic_form__local_density_congruence.py | 4 +- ...uadratic_form__local_density_interfaces.py | 2 +- .../quadratic_form__local_field_invariants.py | 86 +++++----- ...dratic_form__mass__Conway_Sloane_masses.py | 12 +- .../quadratic_form__mass__Siegel_densities.py | 10 +- .../quadratic_form__neighbors.py | 22 +-- .../quadratic_form__reduction_theory.py | 8 +- .../quadratic_form__split_local_covering.py | 10 +- .../quadratic_form__ternary_Tornaria.py | 68 ++++---- .../quadratic_forms/quadratic_form__theta.py | 18 +-- src/sage/quadratic_forms/special_values.py | 40 ++--- src/sage/quadratic_forms/ternary.pyx | 20 +-- src/sage/quadratic_forms/ternary_qf.py | 32 ++-- 19 files changed, 354 insertions(+), 340 deletions(-) diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index ba34c3e0e08..91a2bad58cf 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -11,7 +11,7 @@ x^2 + 2*x*y + 3*y^2 sage: Q.discriminant() -8 - sage: Q.reduced_form() # optional - sage.libs.pari + sage: Q.reduced_form() # needs sage.libs.pari x^2 + 2*y^2 sage: Q(1, 1) 6 @@ -166,13 +166,13 @@ def _pari_init_(self): 2*x^2 + 3*x*y + 4*y^2 sage: f._pari_init_() 'Qfb(2,3,4)' - sage: pari(f) # optional - sage.libs.pari + sage: pari(f) # needs sage.libs.pari Qfb(2, 3, 4) - sage: type(pari(f)) # optional - sage.libs.pari + sage: type(pari(f)) # needs sage.libs.pari <... 'cypari2.gen.Gen'> - sage: gp(f) # optional - sage.libs.pari + sage: gp(f) # needs sage.libs.pari Qfb(2, 3, 4) - sage: type(gp(f)) # optional - sage.libs.pari + sage: type(gp(f)) # needs sage.libs.pari """ return 'Qfb(%s,%s,%s)' % (self._a, self._b, self._c) @@ -190,13 +190,13 @@ def __mul__(self, right): sage: R = BinaryQF_reduced_representatives(-23, primitive_only=False); R [x^2 + x*y + 6*y^2, 2*x^2 - x*y + 3*y^2, 2*x^2 + x*y + 3*y^2] - sage: R[0] * R[0] # optional - sage.libs.pari + sage: R[0] * R[0] # needs sage.libs.pari x^2 + x*y + 6*y^2 - sage: R[1] * R[1] # optional - sage.libs.pari + sage: R[1] * R[1] # needs sage.libs.pari 4*x^2 + 3*x*y + 2*y^2 - sage: (R[1] * R[1]).reduced_form() # optional - sage.libs.pari + sage: (R[1] * R[1]).reduced_form() # needs sage.libs.pari 2*x^2 + x*y + 3*y^2 - sage: (R[1] * R[1] * R[1]).reduced_form() # optional - sage.libs.pari + sage: (R[1] * R[1] * R[1]).reduced_form() # needs sage.libs.pari x^2 + x*y + 6*y^2 sage: q1 = BinaryQF(1, 1, 4) sage: M = Matrix(ZZ, [[1, 3], [0, 1]]) @@ -601,13 +601,13 @@ def has_fundamental_discriminant(self): sage: Q = BinaryQF([1, 0, 1]) sage: Q.discriminant() -4 - sage: Q.has_fundamental_discriminant() # optional - sage.libs.pari + sage: Q.has_fundamental_discriminant() # needs sage.libs.pari True sage: Q = BinaryQF([2, 0, 2]) sage: Q.discriminant() -16 - sage: Q.has_fundamental_discriminant() # optional - sage.libs.pari + sage: Q.has_fundamental_discriminant() # needs sage.libs.pari False """ return self.discriminant().is_fundamental_discriminant() @@ -816,17 +816,17 @@ def reduced_form(self, transformation=False, algorithm="default"): sage: a = BinaryQF([33, 11, 5]) sage: a.is_reduced() False - sage: b = a.reduced_form(); b # optional - sage.libs.pari + sage: b = a.reduced_form(); b # needs sage.libs.pari 5*x^2 - x*y + 27*y^2 - sage: b.is_reduced() # optional - sage.libs.pari + sage: b.is_reduced() # needs sage.libs.pari True sage: a = BinaryQF([15, 0, 15]) sage: a.is_reduced() True - sage: b = a.reduced_form(); b # optional - sage.libs.pari + sage: b = a.reduced_form(); b # needs sage.libs.pari 15*x^2 + 15*y^2 - sage: b.is_reduced() # optional - sage.libs.pari + sage: b.is_reduced() # needs sage.libs.pari True Examples of reducing indefinite forms:: @@ -834,26 +834,26 @@ def reduced_form(self, transformation=False, algorithm="default"): sage: f = BinaryQF(1, 0, -3) sage: f.is_reduced() False - sage: g = f.reduced_form(); g # optional - sage.libs.pari + sage: g = f.reduced_form(); g # needs sage.libs.pari x^2 + 2*x*y - 2*y^2 - sage: g.is_reduced() # optional - sage.libs.pari + sage: g.is_reduced() # needs sage.libs.pari True sage: q = BinaryQF(1, 0, -1) - sage: q.reduced_form() # optional - sage.libs.pari + sage: q.reduced_form() # needs sage.libs.pari x^2 + 2*x*y - sage: BinaryQF(1, 9, 4).reduced_form(transformation=True) # optional - sage.libs.pari + sage: BinaryQF(1, 9, 4).reduced_form(transformation=True) # needs sage.libs.pari ( [ 0 -1] 4*x^2 + 7*x*y - y^2, [ 1 2] ) - sage: BinaryQF(3, 7, -2).reduced_form(transformation=True) # optional - sage.libs.pari + sage: BinaryQF(3, 7, -2).reduced_form(transformation=True) # needs sage.libs.pari ( [1 0] 3*x^2 + 7*x*y - 2*y^2, [0 1] ) - sage: BinaryQF(-6, 6, -1).reduced_form(transformation=True) # optional - sage.libs.pari + sage: BinaryQF(-6, 6, -1).reduced_form(transformation=True) # needs sage.libs.pari ( [ 0 -1] -x^2 + 2*x*y + 2*y^2, [ 1 -4] @@ -863,12 +863,12 @@ def reduced_form(self, transformation=False, algorithm="default"): Check for :trac:`34229`:: - sage: BinaryQF([1,2,3]).reduced_form(transformation=True) # optional - sage.libs.pari + sage: BinaryQF([1,2,3]).reduced_form(transformation=True) # needs sage.libs.pari ( [ 1 -1] x^2 + 2*y^2, [ 0 1] ) - sage: BinaryQF([-225, -743, -743]).reduced_form().is_reduced() # optional - sage.libs.pari + sage: BinaryQF([-225, -743, -743]).reduced_form().is_reduced() # needs sage.libs.pari True Some randomized testing:: @@ -881,17 +881,17 @@ def reduced_form(self, transformation=False, algorithm="default"): sage: if f.discriminant() > 0: ....: algos.append('sage') sage: a = choice(algos) - sage: g = f.reduced_form(algorithm=a) # optional - sage.libs.pari - sage: g.is_reduced() # optional - sage.libs.pari + sage: g = f.reduced_form(algorithm=a) # needs sage.libs.pari + sage: g.is_reduced() # needs sage.libs.pari True - sage: g.is_equivalent(f) # optional - sage.libs.pari + sage: g.is_equivalent(f) # needs sage.libs.pari True - sage: g,M = f.reduced_form(transformation=True, algorithm=a) # optional - sage.libs.pari - sage: g.is_reduced() # optional - sage.libs.pari + sage: g,M = f.reduced_form(transformation=True, algorithm=a) # needs sage.libs.pari + sage: g.is_reduced() # needs sage.libs.pari True - sage: g.is_equivalent(f) # optional - sage.libs.pari + sage: g.is_equivalent(f) # needs sage.libs.pari True - sage: f * M == g # optional - sage.libs.pari + sage: f * M == g # needs sage.libs.pari True """ if self.is_reduced(): @@ -1260,23 +1260,23 @@ def is_equivalent(self, other, proper=True): sage: Q3 = BinaryQF(4, 4, 15) sage: Q2 = BinaryQF(4, -4, 15) - sage: Q2.is_equivalent(Q3) # optional - sage.libs.pari + sage: Q2.is_equivalent(Q3) # needs sage.libs.pari True sage: a = BinaryQF([33, 11, 5]) - sage: b = a.reduced_form(); b # optional - sage.libs.pari + sage: b = a.reduced_form(); b # needs sage.libs.pari 5*x^2 - x*y + 27*y^2 - sage: a.is_equivalent(b) # optional - sage.libs.pari + sage: a.is_equivalent(b) # needs sage.libs.pari True - sage: a.is_equivalent(BinaryQF((3, 4, 5))) # optional - sage.libs.pari + sage: a.is_equivalent(BinaryQF((3, 4, 5))) # needs sage.libs.pari False Some indefinite examples:: sage: Q1 = BinaryQF(9, 8, -7) sage: Q2 = BinaryQF(9, -8, -7) - sage: Q1.is_equivalent(Q2, proper=True) # optional - sage.libs.pari + sage: Q1.is_equivalent(Q2, proper=True) # needs sage.libs.pari False - sage: Q1.is_equivalent(Q2, proper=False) # optional - sage.libs.pari + sage: Q1.is_equivalent(Q2, proper=False) # needs sage.libs.pari True TESTS: @@ -1285,11 +1285,11 @@ def is_equivalent(self, other, proper=True): sage: Q1 = BinaryQF(3, 4, -2) sage: Q2 = BinaryQF(-2, 4, 3) - sage: Q1.is_equivalent(Q2) == Q2.is_equivalent(Q1) # optional - sage.libs.pari + sage: Q1.is_equivalent(Q2) == Q2.is_equivalent(Q1) # needs sage.libs.pari True - sage: Q1.is_equivalent(Q2, proper=False) == Q2.is_equivalent(Q1, proper=False) # optional - sage.libs.pari + sage: Q1.is_equivalent(Q2, proper=False) == Q2.is_equivalent(Q1, proper=False) # needs sage.libs.pari True - sage: Q1.is_equivalent(Q2, proper=True) # optional - sage.libs.pari + sage: Q1.is_equivalent(Q2, proper=True) # needs sage.libs.pari True We check that the first part of :trac:`29028` is fixed:: @@ -1297,22 +1297,22 @@ def is_equivalent(self, other, proper=True): sage: Q = BinaryQF(0, 2, 0) sage: Q.discriminant() 4 - sage: Q.is_equivalent(Q, proper=True) # optional - sage.libs.pari + sage: Q.is_equivalent(Q, proper=True) # needs sage.libs.pari True - sage: Q.is_equivalent(Q, proper=False) # optional - sage.libs.pari + sage: Q.is_equivalent(Q, proper=False) # needs sage.libs.pari True A test for rational forms:: sage: Q1 = BinaryQF(0, 4, 2) sage: Q2 = BinaryQF(2, 4, 0) - sage: Q1.is_equivalent(Q2, proper=False) # optional - sage.libs.pari + sage: Q1.is_equivalent(Q2, proper=False) # needs sage.libs.pari True Test another part of :trac:`28989`:: sage: Q1, Q2 = BinaryQF(1, 1, -1), BinaryQF(-1, 1, 1) - sage: Q1.is_equivalent(Q2, proper=True) # optional - sage.libs.pari + sage: Q1.is_equivalent(Q2, proper=True) # needs sage.libs.pari True """ if not isinstance(other, BinaryQF): @@ -1454,7 +1454,7 @@ def complex_point(self): EXAMPLES:: sage: Q = BinaryQF([1, 0, 1]) - sage: Q.complex_point() # optional - sage.libs.pari + sage: Q.complex_point() # needs sage.libs.pari 1.00000000000000*I """ if self.discriminant() >= 0: @@ -1525,10 +1525,10 @@ def small_prime_value(self, Bmax=1000): EXAMPLES:: - sage: [Q.small_prime_value() # optional - sage.libs.pari + sage: [Q.small_prime_value() # needs sage.libs.pari ....: for Q in BinaryQF_reduced_representatives(-23, primitive_only=True)] [23, 2, 2] - sage: [Q.small_prime_value() # optional - sage.libs.pari + sage: [Q.small_prime_value() # needs sage.libs.pari ....: for Q in BinaryQF_reduced_representatives(-47, primitive_only=True)] [47, 2, 2, 3, 3] """ @@ -1569,7 +1569,7 @@ def solve_integer(self, n, *, algorithm="general"): EXAMPLES:: sage: Q = BinaryQF([1, 0, 419]) - sage: Q.solve_integer(773187972) # optional - sage.libs.pari + sage: Q.solve_integer(773187972) # needs sage.libs.pari (4919, 1337) If `Q` is of the form `[1,0,c]` as above and `n` is a prime or @@ -1578,9 +1578,9 @@ def solve_integer(self, n, *, algorithm="general"): sage: Q = BinaryQF([1, 0, 12345]) sage: n = 2^99 + 5273 - sage: Q.solve_integer(n) # optional - sage.libs.pari + sage: Q.solve_integer(n) # needs sage.libs.pari (-67446480057659, 7139620553488) - sage: Q.solve_integer(n, algorithm='cornacchia') # optional - sage.libs.pari + sage: Q.solve_integer(n, algorithm='cornacchia') # needs sage.libs.pari (67446480057659, 7139620553488) sage: timeit('Q.solve_integer(n)') # not tested 125 loops, best of 3: 3.13 ms per loop @@ -1589,14 +1589,15 @@ def solve_integer(self, n, *, algorithm="general"): :: - sage: Qs = BinaryQF_reduced_representatives(-23, primitive_only=True) # optional - sage.libs.pari - sage: Qs # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: Qs = BinaryQF_reduced_representatives(-23, primitive_only=True) + sage: Qs [x^2 + x*y + 6*y^2, 2*x^2 - x*y + 3*y^2, 2*x^2 + x*y + 3*y^2] - sage: [Q.solve_integer(3) for Q in Qs] # optional - sage.libs.pari + sage: [Q.solve_integer(3) for Q in Qs] [None, (0, -1), (0, -1)] - sage: [Q.solve_integer(5) for Q in Qs] # optional - sage.libs.pari + sage: [Q.solve_integer(5) for Q in Qs] [None, None, None] - sage: [Q.solve_integer(6) for Q in Qs] # optional - sage.libs.pari + sage: [Q.solve_integer(6) for Q in Qs] [(1, -1), (1, -1), (-1, -1)] TESTS: @@ -1605,22 +1606,22 @@ def solve_integer(self, n, *, algorithm="general"): sage: Q = BinaryQF([randrange(-10^3, 10^3) for _ in 'abc']) sage: n = randrange(-10^9, 10^9) - sage: xy = Q.solve_integer(n) # optional - sage.libs.pari - sage: xy is None or Q(*xy) == n # optional - sage.libs.pari + sage: xy = Q.solve_integer(n) # needs sage.libs.pari + sage: xy is None or Q(*xy) == n # needs sage.libs.pari True Also when using the ``"cornacchia"`` algorithm:: sage: abc = [1, 0, randrange(1,10^3)] sage: Q = BinaryQF(abc) - sage: n = random_prime(10^9) # optional - sage.libs.pari - sage: if randrange(2): # optional - sage.libs.pari + sage: n = random_prime(10^9) # needs sage.libs.pari + sage: if randrange(2): # needs sage.libs.pari ....: n *= 4 - sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') # optional - sage.libs.pari - sage: xy1 is None or Q(*xy1) == n # optional - sage.libs.pari + sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') # needs sage.libs.pari + sage: xy1 is None or Q(*xy1) == n # needs sage.libs.pari True - sage: xy2 = Q.solve_integer(n) # optional - sage.libs.pari - sage: (xy1 is None) == (xy2 is None) # optional - sage.libs.pari + sage: xy2 = Q.solve_integer(n) # needs sage.libs.pari + sage: (xy1 is None) == (xy2 is None) # needs sage.libs.pari True Test for square discriminants specifically (:trac:`33026`):: @@ -1633,14 +1634,14 @@ def solve_integer(self, n, *, algorithm="general"): sage: Q = Q.matrix_action_right(U) sage: Q.discriminant().is_square() True - sage: xy = Q.solve_integer(n) # optional - sage.libs.pari - sage: Q(*xy) == n # optional - sage.libs.pari + sage: xy = Q.solve_integer(n) # needs sage.libs.pari + sage: Q(*xy) == n # needs sage.libs.pari True Also test the `n=0` special case separately:: - sage: xy = Q.solve_integer(0) # optional - sage.libs.pari - sage: Q(*xy) # optional - sage.libs.pari + sage: xy = Q.solve_integer(0) # needs sage.libs.pari + sage: Q(*xy) # needs sage.libs.pari 0 """ n = ZZ(n) @@ -1742,13 +1743,13 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): sage: len(BinaryQF_reduced_representatives(-13*4)) 2 - sage: QuadraticField(-13*4, 'a').class_number() + sage: QuadraticField(-13*4, 'a').class_number() # needs sage.rings.number_field 2 - sage: p = next_prime(2^20); p + sage: p = next_prime(2^20); p # needs sage.libs.pari 1048583 - sage: len(BinaryQF_reduced_representatives(-p)) # optional - sage.libs.pari + sage: len(BinaryQF_reduced_representatives(-p)) # needs sage.libs.pari 689 - sage: QuadraticField(-p, 'a').class_number() # optional - sage.libs.pari sage.rings.number_field + sage: QuadraticField(-p, 'a').class_number() # needs sage.libs.pari sage.rings.number_field 689 sage: BinaryQF_reduced_representatives(-23*9) @@ -1761,7 +1762,7 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): 6*x^2 - 3*x*y + 9*y^2, 6*x^2 + 3*x*y + 9*y^2, 8*x^2 + 7*x*y + 8*y^2] - sage: BinaryQF_reduced_representatives(-23*9, primitive_only=True) # optional - sage.libs.pari + sage: BinaryQF_reduced_representatives(-23*9, primitive_only=True) # needs sage.libs.pari [x^2 + x*y + 52*y^2, 2*x^2 - x*y + 26*y^2, 2*x^2 + x*y + 26*y^2, @@ -1773,7 +1774,7 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): sage: BinaryQF_reduced_representatives(73) [4*x^2 + 3*x*y - 4*y^2] - sage: BinaryQF_reduced_representatives(76, primitive_only=True) # optional - sage.libs.pari + sage: BinaryQF_reduced_representatives(76, primitive_only=True) # needs sage.libs.pari [-3*x^2 + 4*x*y + 5*y^2, 3*x^2 + 4*x*y - 5*y^2] sage: BinaryQF_reduced_representatives(136) @@ -1788,9 +1789,9 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): sage: BinaryQF_reduced_representatives(148, proper=False, primitive_only=False) [x^2 + 12*x*y - y^2, 4*x^2 + 6*x*y - 7*y^2, 6*x^2 + 2*x*y - 6*y^2] - sage: BinaryQF_reduced_representatives(148, proper=False, primitive_only=True) # optional - sage.libs.pari + sage: BinaryQF_reduced_representatives(148, proper=False, primitive_only=True) # needs sage.libs.pari [x^2 + 12*x*y - y^2, 4*x^2 + 6*x*y - 7*y^2] - sage: BinaryQF_reduced_representatives(148, proper=True, primitive_only=True) # optional - sage.libs.pari + sage: BinaryQF_reduced_representatives(148, proper=True, primitive_only=True) # needs sage.libs.pari [-7*x^2 + 6*x*y + 4*y^2, x^2 + 12*x*y - y^2, 4*x^2 + 6*x*y - 7*y^2] sage: BinaryQF_reduced_representatives(148, proper=True, primitive_only=False) [-7*x^2 + 6*x*y + 4*y^2, @@ -1809,9 +1810,9 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): x^2 + 10*x*y, 2*x^2 + 10*x*y, 5*x^2 + 10*x*y] - sage: BinaryQF_reduced_representatives(10^2, proper=False, primitive_only=True) # optional - sage.libs.pari + sage: BinaryQF_reduced_representatives(10^2, proper=False, primitive_only=True) # needs sage.libs.pari [-3*x^2 + 10*x*y, -x^2 + 10*x*y, x^2 + 10*x*y] - sage: BinaryQF_reduced_representatives(10^2, proper=True, primitive_only=True) # optional - sage.libs.pari + sage: BinaryQF_reduced_representatives(10^2, proper=True, primitive_only=True) # needs sage.libs.pari [-3*x^2 + 10*x*y, -x^2 + 10*x*y, x^2 + 10*x*y, 3*x^2 + 10*x*y] sage: BinaryQF_reduced_representatives(10^2, proper=True, primitive_only=False) [-4*x^2 + 10*x*y, diff --git a/src/sage/quadratic_forms/constructions.py b/src/sage/quadratic_forms/constructions.py index 48a4d056e28..2fe117d2e29 100644 --- a/src/sage/quadratic_forms/constructions.py +++ b/src/sage/quadratic_forms/constructions.py @@ -32,7 +32,7 @@ def BezoutianQuadraticForm(f, g): sage: R = PolynomialRing(ZZ, 'x') sage: f = R([1,2,3]) sage: g = R([2,5]) - sage: Q = BezoutianQuadraticForm(f, g); Q # optional - sage.libs.singular + sage: Q = BezoutianQuadraticForm(f, g); Q # needs sage.libs.singular Quadratic form in 2 variables over Integer Ring with coefficients: [ 1 -12 ] [ * -15 ] diff --git a/src/sage/quadratic_forms/extras.py b/src/sage/quadratic_forms/extras.py index a64e3518207..7bdba23c32e 100644 --- a/src/sage/quadratic_forms/extras.py +++ b/src/sage/quadratic_forms/extras.py @@ -151,7 +151,7 @@ def least_quadratic_nonresidue(p): sage: least_quadratic_nonresidue(5) 2 - sage: [least_quadratic_nonresidue(p) for p in prime_range(3, 100)] # optional - sage.libs.pari + sage: [least_quadratic_nonresidue(p) for p in prime_range(3, 100)] # needs sage.libs.pari [2, 2, 3, 2, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 2, 2, 2, 7, 5, 3, 2, 3, 5] TESTS: diff --git a/src/sage/quadratic_forms/genera/genus.py b/src/sage/quadratic_forms/genera/genus.py index d0347044906..b379c6b98e6 100644 --- a/src/sage/quadratic_forms/genera/genus.py +++ b/src/sage/quadratic_forms/genera/genus.py @@ -3162,7 +3162,7 @@ def _standard_mass(self): sage: A = matrix.diagonal(ZZ, [1, 1, 1, 1]) sage: GS = Genus(A) - sage: GS._standard_mass() # optional - sage.symbolic + sage: GS._standard_mass() # needs sage.symbolic 1/48 """ @@ -3215,7 +3215,7 @@ def mass(self, backend='sage'): sage: from sage.quadratic_forms.genera.genus import genera sage: G = genera((8,0), 1, even=True)[0] - sage: G.mass() # optional - sage.symbolic + sage: G.mass() # needs sage.symbolic 1/696729600 sage: G.mass(backend='magma') # optional - magma 1/696729600 diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 84a00cd8418..20ce1c66937 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -100,24 +100,24 @@ def quadratic_form_from_invariants(F, rk, det, P, sminus): EXAMPLES:: sage: P = [3,5] - sage: q = quadratic_form_from_invariants(QQ,2,-15,P,1); q # optional - sage.rings.padics + sage: q = quadratic_form_from_invariants(QQ,2,-15,P,1); q # needs sage.rings.padics Quadratic form in 2 variables over Rational Field with coefficients: [ 5 0 ] [ * -3 ] - sage: all(q.hasse_invariant(p) == -1 for p in P) # optional - sage.rings.padics + sage: all(q.hasse_invariant(p) == -1 for p in P) # needs sage.rings.padics True TESTS: This shows that :trac:`28955` is fixed:: - sage: quadratic_form_from_invariants(QQ,3,2,[2],2) # optional - sage.rings.padics + sage: quadratic_form_from_invariants(QQ,3,2,[2],2) # needs sage.rings.padics Quadratic form in 3 variables over Rational Field with coefficients: [ -1 0 0 ] [ * 1 0 ] [ * * -2 ] - sage: quadratic_form_from_invariants(QQ,4,2,[2],4) # optional - sage.rings.padics + sage: quadratic_form_from_invariants(QQ,4,2,[2],4) # needs sage.rings.padics Traceback (most recent call last): ... ValueError: invariants do not define a rational quadratic form @@ -668,23 +668,24 @@ def list_external_initializations(self): sage: Q = QuadraticForm(ZZ, 2, [1,0,5]) sage: Q.list_external_initializations() [] - sage: T = Q.theta_series() # optional - sage.libs.pari - sage: Q.list_external_initializations() # optional - sage.libs.pari + sage: T = Q.theta_series() # needs sage.libs.pari + sage: Q.list_external_initializations() # needs sage.libs.pari [] - sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=False, # optional - sage.libs.pari + sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=False, # needs sage.libs.pari ....: number_of_automorphisms=3, determinant=0) - sage: Q.list_external_initializations() # optional - sage.libs.pari + sage: Q.list_external_initializations() # needs sage.libs.pari [] :: - sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=False, # optional - sage.libs.pari + sage: # needs sage.libs.pari + sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=False, ....: number_of_automorphisms=3, determinant=0) - sage: Q.list_external_initializations() # optional - sage.libs.pari + sage: Q.list_external_initializations() [] - sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=True, # optional - sage.libs.pari + sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=True, ....: number_of_automorphisms=3, determinant=0) - sage: Q.list_external_initializations() # optional - sage.libs.pari + sage: Q.list_external_initializations() ['number_of_automorphisms', 'determinant'] """ return deepcopy(self._external_initialization_list) @@ -696,7 +697,7 @@ def __pari__(self): EXAMPLES:: sage: Q = QuadraticForm(ZZ, 2, [1,0,5]) - sage: Q.__pari__() # optional - sage.libs.pari + sage: Q.__pari__() # needs sage.libs.pari [2, 0; 0, 10] """ @@ -709,7 +710,7 @@ def _pari_init_(self): EXAMPLES:: sage: Q = QuadraticForm(ZZ, 2, [1,0,5]) - sage: Q._pari_init_() # optional - sage.libs.pari + sage: Q._pari_init_() # needs sage.libs.pari 'Mat([2,0;0,10])' """ return self.matrix()._pari_init_() @@ -836,10 +837,10 @@ def __hash__(self): sage: Q1 = QuadraticForm(QQ, 2, [1,1,1]) sage: Q2 = QuadraticForm(QQ, 2, [1,1,1]) - sage: Q3 = QuadraticForm(QuadraticField(2), 2, [1,1,1]) # optional - sage.rings.number_field + sage: Q3 = QuadraticForm(QuadraticField(2), 2, [1,1,1]) # needs sage.rings.number_field sage: hash(Q1) == hash(Q2) True - sage: hash(Q1) == hash(Q3) # optional - sage.rings.number_field + sage: hash(Q1) == hash(Q3) # needs sage.rings.number_field False """ return hash(self.__base_ring) ^ hash(tuple(self.__coeffs)) @@ -1308,20 +1309,21 @@ def polynomial(self,names='x'): :: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: F. = NumberField(x^2 - 5) # optional - sage.rings.number_field - sage: Z = F.ring_of_integers() # optional - sage.rings.number_field - sage: Q = QuadraticForm(Z, 3, [2*a, 3*a, 0, 1 - a, 0, 2*a + 4]) # optional - sage.rings.number_field - sage: P = Q.polynomial(names='y'); P # optional - sage.rings.number_field + sage: F. = NumberField(x^2 - 5) + sage: Z = F.ring_of_integers() + sage: Q = QuadraticForm(Z, 3, [2*a, 3*a, 0, 1 - a, 0, 2*a + 4]) + sage: P = Q.polynomial(names='y'); P 2*a*y0^2 + 3*a*y0*y1 + (-a + 1)*y1^2 + (2*a + 4)*y2^2 - sage: Q = QuadraticForm(F, 4, # optional - sage.rings.number_field + sage: Q = QuadraticForm(F, 4, ....: [a, 3*a, 0, 1 - a, a - 3, 0, 2*a + 4, 4 + a, 0, 1]) - sage: Q.polynomial(names='z') # optional - sage.rings.number_field + sage: Q.polynomial(names='z') a*z0^2 + (3*a)*z0*z1 + (a - 3)*z1^2 + (a + 4)*z2^2 + (-a + 1)*z0*z3 + (2*a + 4)*z1*z3 + z3^2 - sage: B. = QuaternionAlgebra(F,-1,-1) # optional - sage.rings.number_field - sage: Q = QuadraticForm(B, 3, [2*a, 3*a, i, 1 - a, 0, 2*a + 4]) # optional - sage.rings.number_field - sage: Q.polynomial() # optional - sage.rings.number_field + sage: B. = QuaternionAlgebra(F,-1,-1) + sage: Q = QuadraticForm(B, 3, [2*a, 3*a, i, 1 - a, 0, 2*a + 4]) + sage: Q.polynomial() Traceback (most recent call last): ... ValueError: Can only create polynomial rings over commutative rings. @@ -1723,10 +1725,11 @@ def bilinear_map(self, v, w): This does not work if the characteristic is 2:: - sage: Q = DiagonalQuadraticForm(GF(2), [1,1,1]) # optional - sage.rings.finite_rings - sage: v = vector((1,1,1)) # optional - sage.rings.finite_rings - sage: w = vector((1,1,1)) # optional - sage.rings.finite_rings - sage: Q.bilinear_map(v, w) # optional - sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: Q = DiagonalQuadraticForm(GF(2), [1,1,1]) + sage: v = vector((1,1,1)) + sage: w = vector((1,1,1)) + sage: Q.bilinear_map(v, w) Traceback (most recent call last): ... TypeError: not defined for rings of characteristic 2 diff --git a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py index 9766f1f4b96..2e817bbecf5 100644 --- a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py +++ b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py @@ -47,10 +47,10 @@ def is_globally_equivalent_to(self, other, return_matrix=False): sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: M = Matrix(ZZ, 4, 4, [1,2,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]) sage: Q1 = Q(M) - sage: Q.is_globally_equivalent_to(Q1) # optional - sage.libs.pari + sage: Q.is_globally_equivalent_to(Q1) # needs sage.libs.pari True - sage: MM = Q.is_globally_equivalent_to(Q1, return_matrix=True) # optional - sage.libs.pari - sage: Q(MM) == Q1 # optional - sage.libs.pari + sage: MM = Q.is_globally_equivalent_to(Q1, return_matrix=True) # needs sage.libs.pari + sage: Q(MM) == Q1 # needs sage.libs.pari True :: @@ -58,23 +58,23 @@ def is_globally_equivalent_to(self, other, return_matrix=False): sage: Q1 = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) sage: Q2 = QuadraticForm(ZZ, 3, [2, 1, 2, 2, 1, 3]) sage: Q3 = QuadraticForm(ZZ, 3, [8, 6, 5, 3, 4, 2]) - sage: Q1.is_globally_equivalent_to(Q2) # optional - sage.libs.pari + sage: Q1.is_globally_equivalent_to(Q2) # needs sage.libs.pari False - sage: Q1.is_globally_equivalent_to(Q2, return_matrix=True) # optional - sage.libs.pari + sage: Q1.is_globally_equivalent_to(Q2, return_matrix=True) # needs sage.libs.pari False - sage: Q1.is_globally_equivalent_to(Q3) # optional - sage.libs.pari + sage: Q1.is_globally_equivalent_to(Q3) # needs sage.libs.pari True - sage: M = Q1.is_globally_equivalent_to(Q3, True); M # optional - sage.libs.pari + sage: M = Q1.is_globally_equivalent_to(Q3, True); M # needs sage.libs.pari [-1 -1 0] [ 1 1 1] [-1 0 0] - sage: Q1(M) == Q3 # optional - sage.libs.pari + sage: Q1(M) == Q3 # needs sage.libs.pari True :: sage: Q = DiagonalQuadraticForm(ZZ, [1, -1]) - sage: Q.is_globally_equivalent_to(Q) # optional - sage.libs.pari + sage: Q.is_globally_equivalent_to(Q) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: not a definite form in QuadraticForm.is_globally_equivalent_to() @@ -88,9 +88,9 @@ def is_globally_equivalent_to(self, other, return_matrix=False): sage: Q = QuadraticForm(ZZ, 2, [2, 3, 5]) sage: P = QuadraticForm(ZZ, 2, [8, 6, 5]) - sage: Q.is_globally_equivalent_to(P) # optional - sage.libs.pari + sage: Q.is_globally_equivalent_to(P) # needs sage.libs.pari False - sage: P.is_globally_equivalent_to(Q) # optional - sage.libs.pari + sage: P.is_globally_equivalent_to(Q) # needs sage.libs.pari False """ from sage.quadratic_forms.quadratic_form import QuadraticForm @@ -132,9 +132,9 @@ def is_locally_equivalent_to(self, other, check_primes_only=False, force_jordan_ sage: Q1 = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) sage: Q2 = QuadraticForm(ZZ, 3, [2, 1, 2, 2, 1, 3]) - sage: Q1.is_globally_equivalent_to(Q2) # optional - sage.libs.pari + sage: Q1.is_globally_equivalent_to(Q2) # needs sage.libs.pari False - sage: Q1.is_locally_equivalent_to(Q2) # optional - sage.libs.pari + sage: Q1.is_locally_equivalent_to(Q2) # needs sage.libs.pari True """ # TO IMPLEMENT: @@ -189,17 +189,17 @@ def has_equivalent_Jordan_decomposition_at_prime(self, other, p): sage: Q3 = QuadraticForm(ZZ, 3, [1, 0, 0, 1, 0, 11]) sage: [Q1.level(), Q2.level(), Q3.level()] [44, 44, 44] - sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2, 2) # optional - sage.libs.pari + sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2, 2) # needs sage.libs.pari False - sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2, 11) # optional - sage.libs.pari + sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2, 11) # needs sage.libs.pari False - sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3, 2) # optional - sage.libs.pari + sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3, 2) # needs sage.libs.pari False - sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3, 11) # optional - sage.libs.pari + sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3, 11) # needs sage.libs.pari True - sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3, 2) # optional - sage.libs.pari + sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3, 2) # needs sage.libs.pari True - sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3, 11) # optional - sage.libs.pari + sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3, 11) # needs sage.libs.pari False """ # Sanity Checks @@ -318,34 +318,36 @@ def is_rationally_isometric(self, other, return_matrix=False): sage: V = DiagonalQuadraticForm(QQ, [1, 1, 2]) sage: W = DiagonalQuadraticForm(QQ, [2, 2, 2]) - sage: V.is_rationally_isometric(W) # optional - sage.libs.pari + sage: V.is_rationally_isometric(W) # needs sage.libs.pari True :: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field - sage: V = QuadraticForm(K, 4, [1, 0, 0, 0, 2*a, 0, 0, a, 0, 2]); V # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 3) + sage: V = QuadraticForm(K, 4, [1, 0, 0, 0, 2*a, 0, 0, a, 0, 2]); V Quadratic form in 4 variables over Number Field in a with defining polynomial x^2 - 3 with coefficients: [ 1 0 0 0 ] [ * 2*a 0 0 ] [ * * a 0 ] [ * * * 2 ] - sage: W = QuadraticForm(K, 4, [1, 2*a, 4, 6, 3, 10, 2, 1, 2, 5]); W # optional - sage.rings.number_field + sage: W = QuadraticForm(K, 4, [1, 2*a, 4, 6, 3, 10, 2, 1, 2, 5]); W Quadratic form in 4 variables over Number Field in a with defining polynomial x^2 - 3 with coefficients: [ 1 2*a 4 6 ] [ * 3 10 2 ] [ * * 1 2 ] [ * * * 5 ] - sage: V.is_rationally_isometric(W) # optional - sage.rings.number_field + sage: V.is_rationally_isometric(W) False :: - sage: K. = NumberField(x^4 + 2*x + 6) # optional - sage.rings.number_field - sage: V = DiagonalQuadraticForm(K, [a, 2, 3, 2, 1]); V # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = NumberField(x^4 + 2*x + 6) + sage: V = DiagonalQuadraticForm(K, [a, 2, 3, 2, 1]); V Quadratic form in 5 variables over Number Field in a with defining polynomial x^4 + 2*x + 6 with coefficients: [ a 0 0 0 0 ] @@ -353,7 +355,7 @@ def is_rationally_isometric(self, other, return_matrix=False): [ * * 3 0 0 ] [ * * * 2 0 ] [ * * * * 1 ] - sage: W = DiagonalQuadraticForm(K, [a, a, a, 2, 1]); W # optional - sage.rings.number_field + sage: W = DiagonalQuadraticForm(K, [a, a, a, 2, 1]); W Quadratic form in 5 variables over Number Field in a with defining polynomial x^4 + 2*x + 6 with coefficients: [ a 0 0 0 0 ] @@ -361,88 +363,92 @@ def is_rationally_isometric(self, other, return_matrix=False): [ * * a 0 0 ] [ * * * 2 0 ] [ * * * * 1 ] - sage: V.is_rationally_isometric(W) # optional - sage.rings.number_field + sage: V.is_rationally_isometric(W) False :: - sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field - sage: V = DiagonalQuadraticForm(K, [-1, a, -2*a]) # optional - sage.rings.number_field - sage: W = DiagonalQuadraticForm(K, [-1, -a, 2*a]) # optional - sage.rings.number_field - sage: V.is_rationally_isometric(W) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = NumberField(x^2 - 3) + sage: V = DiagonalQuadraticForm(K, [-1, a, -2*a]) + sage: W = DiagonalQuadraticForm(K, [-1, -a, 2*a]) + sage: V.is_rationally_isometric(W) True - sage: V = DiagonalQuadraticForm(QQ, [1, 1, 2]) # optional - sage.rings.number_field - sage: W = DiagonalQuadraticForm(QQ, [2, 2, 2]) # optional - sage.rings.number_field - sage: T = V.is_rationally_isometric(W, True); T # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: V = DiagonalQuadraticForm(QQ, [1, 1, 2]) + sage: W = DiagonalQuadraticForm(QQ, [2, 2, 2]) + sage: T = V.is_rationally_isometric(W, True); T [ 0 0 1] [-1/2 -1/2 0] [ 1/2 -1/2 0] - sage: V.Gram_matrix() == T.transpose() * W.Gram_matrix() * T # optional - sage.rings.number_field + sage: V.Gram_matrix() == T.transpose() * W.Gram_matrix() * T True - sage: T = W.is_rationally_isometric(V, True); T # optional - sage.rings.number_field + sage: T = W.is_rationally_isometric(V, True); T # needs sage.rings.number_field [ 0 -1 1] [ 0 -1 -1] [ 1 0 0] - sage: W.Gram_matrix() == T.T * V.Gram_matrix() * T # optional - sage.rings.number_field + sage: W.Gram_matrix() == T.T * V.Gram_matrix() * T # needs sage.rings.number_field True :: sage: L = QuadraticForm(QQ, 3, [2, 2, 0, 2, 2, 5]) sage: M = QuadraticForm(QQ, 3, [2, 2, 0, 3, 2, 3]) - sage: L.is_rationally_isometric(M, True) # optional - sage.libs.pari + sage: L.is_rationally_isometric(M, True) # needs sage.libs.pari False :: sage: A = DiagonalQuadraticForm(QQ, [1, 5]) sage: B = QuadraticForm(QQ, 2, [1, 12, 81]) - sage: T = A.is_rationally_isometric(B, True); T # optional - sage.libs.pari + sage: T = A.is_rationally_isometric(B, True); T # needs sage.libs.pari [ 1 -2] [ 0 1/3] - sage: A.Gram_matrix() == T.T * B.Gram_matrix() * T # optional - sage.libs.pari + sage: A.Gram_matrix() == T.T * B.Gram_matrix() * T # needs sage.libs.pari True :: sage: C = DiagonalQuadraticForm(QQ, [1, 5, 9]) sage: D = DiagonalQuadraticForm(QQ, [6, 30, 1]) - sage: T = C.is_rationally_isometric(D, True); T # optional - sage.libs.pari + sage: T = C.is_rationally_isometric(D, True); T # needs sage.libs.pari [ 0 -5/6 1/2] [ 0 1/6 1/2] [ -1 0 0] - sage: C.Gram_matrix() == T.T * D.Gram_matrix() * T # optional - sage.libs.pari + sage: C.Gram_matrix() == T.T * D.Gram_matrix() * T # needs sage.libs.pari True :: sage: E = DiagonalQuadraticForm(QQ, [1, 1]) sage: F = QuadraticForm(QQ, 2, [17, 94, 130]) - sage: T = F.is_rationally_isometric(E, True); T # optional - sage.libs.pari + sage: T = F.is_rationally_isometric(E, True); T # needs sage.libs.pari [ -4 -189/17] [ -1 -43/17] - sage: F.Gram_matrix() == T.T * E.Gram_matrix() * T # optional - sage.libs.pari + sage: F.Gram_matrix() == T.T * E.Gram_matrix() * T # needs sage.libs.pari True TESTS:: - sage: K. = QuadraticField(3) # optional - sage.rings.number_field - sage: V = DiagonalQuadraticForm(K, [1, 2]) # optional - sage.rings.number_field - sage: W = DiagonalQuadraticForm(K, [1, 0]) # optional - sage.rings.number_field - sage: V.is_rationally_isometric(W) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(3) + sage: V = DiagonalQuadraticForm(K, [1, 2]) + sage: W = DiagonalQuadraticForm(K, [1, 0]) + sage: V.is_rationally_isometric(W) Traceback (most recent call last): ... NotImplementedError: This only tests regular forms Forms must have the same base ring otherwise a `TypeError` is raised:: - sage: K1. = QuadraticField(5) # optional - sage.rings.number_field - sage: K2. = QuadraticField(7) # optional - sage.rings.number_field - sage: V = DiagonalQuadraticForm(K1, [1, a]) # optional - sage.rings.number_field - sage: W = DiagonalQuadraticForm(K2, [1, b]) # optional - sage.rings.number_field - sage: V.is_rationally_isometric(W) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K1. = QuadraticField(5) + sage: K2. = QuadraticField(7) + sage: V = DiagonalQuadraticForm(K1, [1, a]) + sage: W = DiagonalQuadraticForm(K2, [1, b]) + sage: V.is_rationally_isometric(W) Traceback (most recent call last): ... TypeError: forms must have the same base ring. @@ -456,18 +462,20 @@ def is_rationally_isometric(self, other, return_matrix=False): Forms whose determinants do not differ by a square in the base field are not isometric:: - sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field - sage: V = DiagonalQuadraticForm(K, [-1, a, -2*a]) # optional - sage.rings.number_field - sage: W = DiagonalQuadraticForm(K, [-1, a, 2*a]) # optional - sage.rings.number_field - sage: V.is_rationally_isometric(W) # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = NumberField(x^2 - 3) + sage: V = DiagonalQuadraticForm(K, [-1, a, -2*a]) + sage: W = DiagonalQuadraticForm(K, [-1, a, 2*a]) + sage: V.is_rationally_isometric(W) False :: - sage: K. = NumberField(x^5 - x + 2, 'a') # optional - sage.rings.number_field - sage: Q = QuadraticForm(K, 3, [a, 1, 0, -a**2, -a**3, -1]) # optional - sage.rings.number_field - sage: m = Q.matrix() # optional - sage.rings.number_field - sage: for _ in range(5): # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = NumberField(x^5 - x + 2, 'a') + sage: Q = QuadraticForm(K, 3, [a, 1, 0, -a**2, -a**3, -1]) + sage: m = Q.matrix() + sage: for _ in range(5): ....: t = random_matrix(ZZ, 3, algorithm='unimodular') ....: m2 = t*m*t.transpose() ....: Q2 = QuadraticForm(K, 3, [m2[i,j] / (2 if i==j else 1) @@ -565,18 +573,18 @@ def _diagonal_isometry(V, W): sage: Q = DiagonalQuadraticForm(QQ, [1, 2, 4]) sage: F = DiagonalQuadraticForm(QQ, [2, 2, 2]) - sage: T = _diagonal_isometry(Q, F); T # optional - sage.libs.pari + sage: T = _diagonal_isometry(Q, F); T # needs sage.libs.pari [ 0 1 0] [-1/2 0 1] [ 1/2 0 1] - sage: Q.Gram_matrix() == T.T * F.Gram_matrix() * T # optional - sage.libs.pari + sage: Q.Gram_matrix() == T.T * F.Gram_matrix() * T # needs sage.libs.pari True - sage: T = _diagonal_isometry(F, Q); T # optional - sage.libs.pari + sage: T = _diagonal_isometry(F, Q); T # needs sage.libs.pari [ 0 -1 -1] [ 1 0 0] [ 0 -1/2 1/2] - sage: F.Gram_matrix() == T.T * Q.Gram_matrix() * T # optional - sage.libs.pari + sage: F.Gram_matrix() == T.T * Q.Gram_matrix() * T # needs sage.libs.pari True """ import copy diff --git a/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py b/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py index 0ab0050d046..a39637df8f0 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py +++ b/src/sage/quadratic_forms/quadratic_form__local_density_congruence.py @@ -208,9 +208,9 @@ def local_good_density_congruence_even(self, m, Zvec, NZvec): [ * 10 5 6 ] [ * * 15 8 ] [ * * * 20 ] - sage: Q.theta_series(20) # optional - sage.libs.pari + sage: Q.theta_series(20) # needs sage.libs.pari 1 + 2*q^5 + 2*q^10 + 2*q^14 + 2*q^15 + 2*q^16 + 2*q^18 + O(q^20) - sage: Q.local_normal_form(2) # optional - sage.libs.pari sage.rings.padics + sage: Q.local_normal_form(2) # needs sage.libs.pari sage.rings.padics Quadratic form in 4 variables over Integer Ring with coefficients: [ 0 1 0 0 ] [ * 0 0 0 ] diff --git a/src/sage/quadratic_forms/quadratic_form__local_density_interfaces.py b/src/sage/quadratic_forms/quadratic_form__local_density_interfaces.py index 4bfe7ebe6a7..ec39e489494 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_density_interfaces.py +++ b/src/sage/quadratic_forms/quadratic_form__local_density_interfaces.py @@ -92,7 +92,7 @@ def local_primitive_density(self, p, m): [ * 10 5 6 ] [ * * 15 8 ] [ * * * 20 ] - sage: Q.theta_series(20) # optional - sage.libs.pari + sage: Q.theta_series(20) # needs sage.libs.pari 1 + 2*q^5 + 2*q^10 + 2*q^14 + 2*q^15 + 2*q^16 + 2*q^18 + O(q^20) sage: Q.local_normal_form(2) Quadratic form in 4 variables over Integer Ring with coefficients: diff --git a/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py b/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py index 5c2beb6f7b6..e3d72e2cb37 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py +++ b/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py @@ -411,33 +411,33 @@ def hasse_invariant(self, p): Quadratic form in 2 variables over Rational Field with coefficients: [ 1 0 ] [ * 2 ] - sage: [Q.hasse_invariant(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant(p) for p in prime_range(20)] # needs sage.libs.pari [1, 1, 1, 1, 1, 1, 1, 1] - sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # needs sage.libs.pari [1, 1, 1, 1, 1, 1, 1, 1] :: sage: Q = DiagonalQuadraticForm(ZZ, [1,-1]) - sage: [Q.hasse_invariant(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant(p) for p in prime_range(20)] # needs sage.libs.pari [1, 1, 1, 1, 1, 1, 1, 1] - sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # needs sage.libs.pari [-1, 1, 1, 1, 1, 1, 1, 1] :: sage: Q = DiagonalQuadraticForm(ZZ, [1,-1,5]) - sage: [Q.hasse_invariant(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant(p) for p in prime_range(20)] # needs sage.libs.pari [1, 1, 1, 1, 1, 1, 1, 1] - sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # needs sage.libs.pari [-1, 1, 1, 1, 1, 1, 1, 1] :: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^2 - 23) # optional - sage.rings.number_field - sage: Q = DiagonalQuadraticForm(K, [-a, a + 2]) # optional - sage.rings.number_field - sage: [Q.hasse_invariant(p) for p in K.primes_above(19)] # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 23) # needs sage.rings.number_field + sage: Q = DiagonalQuadraticForm(K, [-a, a + 2]) # needs sage.rings.number_field + sage: [Q.hasse_invariant(p) for p in K.primes_above(19)] # needs sage.rings.number_field [-1, 1] """ # TO DO: Need to deal with the case n=1 separately somewhere! @@ -494,33 +494,33 @@ def hasse_invariant__OMeara(self, p): Quadratic form in 2 variables over Rational Field with coefficients: [ 1 0 ] [ * 2 ] - sage: [Q.hasse_invariant(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant(p) for p in prime_range(20)] # needs sage.libs.pari [1, 1, 1, 1, 1, 1, 1, 1] - sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # needs sage.libs.pari [1, 1, 1, 1, 1, 1, 1, 1] :: sage: Q = DiagonalQuadraticForm(ZZ, [1,-1]) - sage: [Q.hasse_invariant(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant(p) for p in prime_range(20)] # needs sage.libs.pari [1, 1, 1, 1, 1, 1, 1, 1] - sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # needs sage.libs.pari [-1, 1, 1, 1, 1, 1, 1, 1] :: sage: Q = DiagonalQuadraticForm(ZZ,[1,-1,-1]) - sage: [Q.hasse_invariant(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant(p) for p in prime_range(20)] # needs sage.libs.pari [-1, 1, 1, 1, 1, 1, 1, 1] - sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # optional - sage.libs.pari + sage: [Q.hasse_invariant__OMeara(p) for p in prime_range(20)] # needs sage.libs.pari [-1, 1, 1, 1, 1, 1, 1, 1] :: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^2 - 23) # optional - sage.rings.number_field - sage: Q = DiagonalQuadraticForm(K, [-a, a + 2]) # optional - sage.rings.number_field - sage: [Q.hasse_invariant__OMeara(p) for p in K.primes_above(19)] # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 23) # needs sage.rings.number_field + sage: Q = DiagonalQuadraticForm(K, [-a, a + 2]) # needs sage.rings.number_field + sage: [Q.hasse_invariant__OMeara(p) for p in K.primes_above(19)] # needs sage.rings.number_field [1, 1] """ # TO DO: Need to deal with the case n=1 separately somewhere! @@ -564,17 +564,17 @@ def is_hyperbolic(self, p): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1]) - sage: Q.is_hyperbolic(-1) # optional - sage.libs.pari + sage: Q.is_hyperbolic(-1) # needs sage.libs.pari False - sage: Q.is_hyperbolic(2) # optional - sage.libs.pari + sage: Q.is_hyperbolic(2) # needs sage.libs.pari False - sage: Q.is_hyperbolic(3) # optional - sage.libs.pari + sage: Q.is_hyperbolic(3) # needs sage.libs.pari False - sage: Q.is_hyperbolic(5) # Here -1 is a square, so it's true. # optional - sage.libs.pari + sage: Q.is_hyperbolic(5) # Here -1 is a square, so it's true. # needs sage.libs.pari True - sage: Q.is_hyperbolic(7) # optional - sage.libs.pari + sage: Q.is_hyperbolic(7) # needs sage.libs.pari False - sage: Q.is_hyperbolic(13) # Here -1 is a square, so it's true. # optional - sage.libs.pari + sage: Q.is_hyperbolic(13) # Here -1 is a square, so it's true. # needs sage.libs.pari True """ # False for odd-dim'l forms @@ -614,33 +614,33 @@ def is_anisotropic(self, p): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1]) - sage: Q.is_anisotropic(2) # optional - sage.libs.pari + sage: Q.is_anisotropic(2) # needs sage.libs.pari True - sage: Q.is_anisotropic(3) # optional - sage.libs.pari + sage: Q.is_anisotropic(3) # needs sage.libs.pari True - sage: Q.is_anisotropic(5) # optional - sage.libs.pari + sage: Q.is_anisotropic(5) # needs sage.libs.pari False :: sage: Q = DiagonalQuadraticForm(ZZ, [1,-1]) - sage: Q.is_anisotropic(2) # optional - sage.libs.pari + sage: Q.is_anisotropic(2) # needs sage.libs.pari False - sage: Q.is_anisotropic(3) # optional - sage.libs.pari + sage: Q.is_anisotropic(3) # needs sage.libs.pari False - sage: Q.is_anisotropic(5) # optional - sage.libs.pari + sage: Q.is_anisotropic(5) # needs sage.libs.pari False :: - sage: [DiagonalQuadraticForm(ZZ, # optional - sage.libs.pari + sage: [DiagonalQuadraticForm(ZZ, # needs sage.libs.pari ....: [1, -least_quadratic_nonresidue(p)]).is_anisotropic(p) ....: for p in prime_range(3, 30)] [True, True, True, True, True, True, True, True, True] :: - sage: [DiagonalQuadraticForm(ZZ, [1, -least_quadratic_nonresidue(p), # optional - sage.libs.pari + sage: [DiagonalQuadraticForm(ZZ, [1, -least_quadratic_nonresidue(p), # needs sage.libs.pari ....: p, -p*least_quadratic_nonresidue(p)]).is_anisotropic(p) ....: for p in prime_range(3, 30)] [True, True, True, True, True, True, True, True, True] @@ -684,33 +684,33 @@ def is_isotropic(self, p): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1]) - sage: Q.is_isotropic(2) # optional - sage.libs.pari + sage: Q.is_isotropic(2) # needs sage.libs.pari False - sage: Q.is_isotropic(3) # optional - sage.libs.pari + sage: Q.is_isotropic(3) # needs sage.libs.pari False - sage: Q.is_isotropic(5) # optional - sage.libs.pari + sage: Q.is_isotropic(5) # needs sage.libs.pari True :: sage: Q = DiagonalQuadraticForm(ZZ, [1,-1]) - sage: Q.is_isotropic(2) # optional - sage.libs.pari + sage: Q.is_isotropic(2) # needs sage.libs.pari True - sage: Q.is_isotropic(3) # optional - sage.libs.pari + sage: Q.is_isotropic(3) # needs sage.libs.pari True - sage: Q.is_isotropic(5) # optional - sage.libs.pari + sage: Q.is_isotropic(5) # needs sage.libs.pari True :: - sage: [DiagonalQuadraticForm(ZZ, # optional - sage.libs.pari + sage: [DiagonalQuadraticForm(ZZ, # needs sage.libs.pari ....: [1, -least_quadratic_nonresidue(p)]).is_isotropic(p) ....: for p in prime_range(3, 30)] [False, False, False, False, False, False, False, False, False] :: - sage: [DiagonalQuadraticForm(ZZ, [1, -least_quadratic_nonresidue(p), # optional - sage.libs.pari + sage: [DiagonalQuadraticForm(ZZ, [1, -least_quadratic_nonresidue(p), # needs sage.libs.pari ....: p, -p*least_quadratic_nonresidue(p)]).is_isotropic(p) ....: for p in prime_range(3, 30)] [False, False, False, False, False, False, False, False, False] @@ -728,15 +728,15 @@ def anisotropic_primes(self): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) - sage: Q.anisotropic_primes() # optional - sage.libs.pari + sage: Q.anisotropic_primes() # needs sage.libs.pari [2, -1] sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) - sage: Q.anisotropic_primes() # optional - sage.libs.pari + sage: Q.anisotropic_primes() # needs sage.libs.pari [2, -1] sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1,1]) - sage: Q.anisotropic_primes() # optional - sage.libs.pari + sage: Q.anisotropic_primes() # needs sage.libs.pari [-1] """ # Look at all prime divisors of 2 * Det(Q) to find the diff --git a/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py b/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py index 86e33d1d9c9..894ee68cec9 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py +++ b/src/sage/quadratic_forms/quadratic_form__mass__Conway_Sloane_masses.py @@ -555,13 +555,13 @@ def conway_standard_mass(self): EXAMPLES:: sage: Q = QuadraticForm(ZZ, 3, [2, -2, 0, 3, -5, 4]) - sage: Q.conway_standard_mass() # optional - sage.symbolic + sage: Q.conway_standard_mass() # needs sage.symbolic 1/6 :: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) - sage: Q.conway_standard_mass() # optional - sage.symbolic + sage: Q.conway_standard_mass() # needs sage.symbolic 1/6 """ from sage.quadratic_forms.special_values import gamma__exact, zeta__exact, quadratic_L_function__exact @@ -595,19 +595,19 @@ def conway_mass(self): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) - sage: Q.conway_mass() # optional - sage.symbolic + sage: Q.conway_mass() # needs sage.symbolic 1/48 sage: Q = DiagonalQuadraticForm(ZZ, [7,1,1]) - sage: Q.conway_mass() # optional - sage.symbolic + sage: Q.conway_mass() # needs sage.symbolic 3/16 sage: Q = QuadraticForm(ZZ, 3, [7, 2, 2, 2, 0, 2]) + DiagonalQuadraticForm(ZZ, [1]) - sage: Q.conway_mass() # optional - sage.symbolic + sage: Q.conway_mass() # needs sage.symbolic 3/32 sage: Q = QuadraticForm(Matrix(ZZ, 2, [2,1,1,2])) - sage: Q.conway_mass() # optional - sage.symbolic + sage: Q.conway_mass() # needs sage.symbolic 1/12 """ # Try to use the cached result diff --git a/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py b/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py index 2281139adaf..a99eb439e0f 100644 --- a/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py +++ b/src/sage/quadratic_forms/quadratic_form__mass__Siegel_densities.py @@ -47,17 +47,17 @@ def mass__by_Siegel_densities(self, odd_algorithm="Pall", even_algorithm="Watson EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) - sage: m = Q.mass__by_Siegel_densities(); m # optional - sage.symbolic + sage: m = Q.mass__by_Siegel_densities(); m # needs sage.symbolic 1/384 - sage: m - (2^Q.dim() * factorial(Q.dim()))^(-1) # optional - sage.symbolic + sage: m - (2^Q.dim() * factorial(Q.dim()))^(-1) # needs sage.symbolic 0 :: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) - sage: m = Q.mass__by_Siegel_densities(); m # optional - sage.symbolic + sage: m = Q.mass__by_Siegel_densities(); m # needs sage.symbolic 1/48 - sage: m - (2^Q.dim() * factorial(Q.dim()))^(-1) # optional - sage.symbolic + sage: m - (2^Q.dim() * factorial(Q.dim()))^(-1) # needs sage.symbolic 0 """ from sage.symbolic.constants import pi @@ -181,7 +181,7 @@ def Watson_mass_at_2(self): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1]) - sage: Q.Watson_mass_at_2() # WARNING: WE NEED TO CHECK THIS CAREFULLY! # optional - sage.symbolic + sage: Q.Watson_mass_at_2() # WARNING: WE NEED TO CHECK THIS CAREFULLY! # needs sage.symbolic 384 """ from sage.functions.all import sgn diff --git a/src/sage/quadratic_forms/quadratic_form__neighbors.py b/src/sage/quadratic_forms/quadratic_form__neighbors.py index 4a490717863..b2299e19fc2 100644 --- a/src/sage/quadratic_forms/quadratic_form__neighbors.py +++ b/src/sage/quadratic_forms/quadratic_form__neighbors.py @@ -151,7 +151,7 @@ def find_p_neighbor_from_vec(self, p, y): sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: v = vector([0,2,1,1]) - sage: X = Q.find_p_neighbor_from_vec(3, v); X # optional - sage.libs.pari + sage: X = Q.find_p_neighbor_from_vec(3, v); X # needs sage.libs.pari Quadratic form in 4 variables over Integer Ring with coefficients: [ 1 0 0 0 ] [ * 1 4 4 ] @@ -164,7 +164,7 @@ def find_p_neighbor_from_vec(self, p, y): sage: Q = QuadraticForm(QQ, matrix.diagonal([1,1,1,1])) sage: v = vector([1,1,1,1]) - sage: Q.find_p_neighbor_from_vec(2, v) # optional - sage.libs.pari + sage: Q.find_p_neighbor_from_vec(2, v) # needs sage.libs.pari Quadratic form in 4 variables over Rational Field with coefficients: [ 1/2 1 1 1 ] [ * 1 1 2 ] @@ -262,28 +262,28 @@ def neighbor_iteration(seeds, p, mass=None, max_classes=ZZ(10)**3, sage: Q = QuadraticForm(ZZ, 3, [1, 0, 0, 2, 1, 3]) sage: Q.det() 46 - sage: mass = Q.conway_mass() # optional - sage.symbolic - sage: g1 = neighbor_iteration([Q], 3, # long time # optional - sage.symbolic + sage: mass = Q.conway_mass() # needs sage.symbolic + sage: g1 = neighbor_iteration([Q], 3, # long time # needs sage.symbolic ....: mass=mass, algorithm='random') sage: g2 = neighbor_iteration([Q], 3, algorithm='exhaustion') # long time - sage: g3 = neighbor_iteration([Q], 3, algorithm='orbits') # optional - sage.libs.gap - sage: mass == sum(1/q.number_of_automorphisms() for q in g1) # long time # optional - sage.symbolic + sage: g3 = neighbor_iteration([Q], 3, algorithm='orbits') # needs sage.libs.gap + sage: mass == sum(1/q.number_of_automorphisms() for q in g1) # long time, needs sage.symbolic True - sage: mass == sum(1/q.number_of_automorphisms() for q in g2) # long time # optional - sage.symbolic + sage: mass == sum(1/q.number_of_automorphisms() for q in g2) # long time, needs sage.symbolic True - sage: mass == sum(1/q.number_of_automorphisms() for q in g3) # optional - sage.libs.gap sage.symbolic + sage: mass == sum(1/q.number_of_automorphisms() for q in g3) # needs sage.libs.gap sage.symbolic True TESTS:: sage: from sage.quadratic_forms.quadratic_form__neighbors import neighbor_iteration sage: Q = QuadraticForm(ZZ, 3, [1, 0, 0, 2, 1, 3]) - sage: g = neighbor_iteration([Q], 3, mass=Q.conway_mass(), max_classes=2) # optional - sage.symbolic + sage: g = neighbor_iteration([Q], 3, mass=Q.conway_mass(), max_classes=2) # needs sage.symbolic ... UserWarning: reached the maximum number of isometry classes=2. Increase the optional argument max_classes to obtain more. Warning: not all classes in the genus were found - sage: neighbor_iteration([Q], 3, # optional - sage.symbolic + sage: neighbor_iteration([Q], 3, # needs sage.symbolic ....: mass=Q.conway_mass(), max_neighbors=0, algorithm='random') Warning: not all classes in the genus were found [] @@ -369,7 +369,7 @@ def orbits_lines_mod_p(self, p): sage: from sage.quadratic_forms.quadratic_form__neighbors import orbits_lines_mod_p sage: Q = QuadraticForm(ZZ, 3, [1, 0, 0, 2, 1, 3]) - sage: Q.orbits_lines_mod_p(2) # optional - sage.libs.gap sage.libs.pari + sage: Q.orbits_lines_mod_p(2) # needs sage.libs.gap sage.libs.pari [(0, 0, 1), (0, 1, 0), (0, 1, 1), diff --git a/src/sage/quadratic_forms/quadratic_form__reduction_theory.py b/src/sage/quadratic_forms/quadratic_form__reduction_theory.py index ebf18b15adc..87323962097 100644 --- a/src/sage/quadratic_forms/quadratic_form__reduction_theory.py +++ b/src/sage/quadratic_forms/quadratic_form__reduction_theory.py @@ -18,7 +18,7 @@ def reduced_binary_form1(self): EXAMPLES:: - sage: QuadraticForm(ZZ, 2, [5,5,2]).reduced_binary_form1() # optional - sage.symbolic + sage: QuadraticForm(ZZ, 2, [5,5,2]).reduced_binary_form1() # needs sage.symbolic ( Quadratic form in 2 variables over Integer Ring with coefficients: [ 2 -1 ] @@ -30,12 +30,12 @@ def reduced_binary_form1(self): TESTS:: - sage: QuadraticForm(ZZ, 2, [4,-7,6]).reduced_binary_form1()[0] # optional - sage.symbolic + sage: QuadraticForm(ZZ, 2, [4,-7,6]).reduced_binary_form1()[0] # needs sage.symbolic Quadratic form in 2 variables over Integer Ring with coefficients: [ 3 -1 ] [ * 4 ] - sage: QuadraticForm(ZZ, 3, [1,2,3,4,5,6]).reduced_binary_form1() # optional - sage.symbolic + sage: QuadraticForm(ZZ, 3, [1,2,3,4,5,6]).reduced_binary_form1() # needs sage.symbolic Traceback (most recent call last): ... TypeError: only available for binary forms @@ -92,7 +92,7 @@ def reduced_binary_form(self): EXAMPLES:: - sage: QuadraticForm(ZZ, 2, [5,5,2]).reduced_binary_form() # optional - sage.symbolic + sage: QuadraticForm(ZZ, 2, [5,5,2]).reduced_binary_form() # needs sage.symbolic ( Quadratic form in 2 variables over Integer Ring with coefficients: [ 2 -1 ] diff --git a/src/sage/quadratic_forms/quadratic_form__split_local_covering.py b/src/sage/quadratic_forms/quadratic_form__split_local_covering.py index 65076096db2..61f8c1a027f 100644 --- a/src/sage/quadratic_forms/quadratic_form__split_local_covering.py +++ b/src/sage/quadratic_forms/quadratic_form__split_local_covering.py @@ -143,7 +143,7 @@ def vectors_by_length(self, bound): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1]) - sage: Q.vectors_by_length(5) # optional - sage.symbolic + sage: Q.vectors_by_length(5) # needs sage.symbolic [[[0, 0]], [[0, -1], [-1, 0]], [[-1, -1], [1, -1]], @@ -154,7 +154,7 @@ def vectors_by_length(self, bound): :: sage: Q1 = DiagonalQuadraticForm(ZZ, [1,3,5,7]) - sage: Q1.vectors_by_length(5) # optional - sage.symbolic + sage: Q1.vectors_by_length(5) # needs sage.symbolic [[[0, 0, 0, 0]], [[-1, 0, 0, 0]], [], @@ -165,13 +165,13 @@ def vectors_by_length(self, bound): :: sage: Q = QuadraticForm(ZZ, 4, [1,1,1,1, 1,0,0, 1,0, 1]) - sage: list(map(len, Q.vectors_by_length(2))) # optional - sage.symbolic + sage: list(map(len, Q.vectors_by_length(2))) # needs sage.symbolic [1, 12, 12] :: sage: Q = QuadraticForm(ZZ, 4, [1,-1,-1,-1, 1,0,0, 4,-3, 4]) - sage: list(map(len, Q.vectors_by_length(3))) # optional - sage.symbolic + sage: list(map(len, Q.vectors_by_length(3))) # needs sage.symbolic [1, 3, 0, 3] """ # pari uses eps = 1e-6 ; nothing bad should happen if eps is too big @@ -377,7 +377,7 @@ def split_local_cover(self): EXAMPLES:: sage: Q1 = DiagonalQuadraticForm(ZZ, [7,5,3]) - sage: Q1.split_local_cover() # optional - sage.symbolic + sage: Q1.split_local_cover() # needs sage.symbolic Quadratic form in 3 variables over Integer Ring with coefficients: [ 3 0 0 ] [ * 5 0 ] diff --git a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py index 3651c8dfddc..bf7346b999d 100644 --- a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +++ b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py @@ -150,7 +150,7 @@ def antiadjoint(self): [ 1 0 -1 ] [ * 2 -1 ] [ * * 5 ] - sage: Q.antiadjoint() # optional - sage.symbolic + sage: Q.antiadjoint() # needs sage.symbolic Traceback (most recent call last): ... ValueError: not an adjoint @@ -174,7 +174,7 @@ def is_adjoint(self) -> bool: EXAMPLES:: sage: Q = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) - sage: Q.is_adjoint() # optional - sage.symbolic + sage: Q.is_adjoint() # needs sage.symbolic False sage: Q.adjoint().is_adjoint() True @@ -294,16 +294,16 @@ def hasse_conductor(self): EXAMPLES:: sage: Q = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) - sage: Q.hasse_invariant(2) # optional - sage.libs.pari + sage: Q.hasse_invariant(2) # needs sage.libs.pari -1 - sage: Q.hasse_invariant(37) # optional - sage.libs.pari + sage: Q.hasse_invariant(37) # needs sage.libs.pari -1 - sage: Q.hasse_conductor() # optional - sage.libs.pari + sage: Q.hasse_conductor() # needs sage.libs.pari 74 - sage: DiagonalQuadraticForm(ZZ, [1, 1, 1]).hasse_conductor() # optional - sage.libs.pari + sage: DiagonalQuadraticForm(ZZ, [1, 1, 1]).hasse_conductor() # needs sage.libs.pari 1 - sage: QuadraticForm(ZZ, 3, [2, -2, 0, 2, 0, 5]).hasse_conductor() # optional - sage.libs.pari + sage: QuadraticForm(ZZ, 3, [2, -2, 0, 2, 0, 5]).hasse_conductor() # needs sage.libs.pari 10 """ return prod([x[0] for x in factor(2 * self.level()) @@ -323,13 +323,13 @@ def clifford_invariant(self, p): For hyperbolic spaces, the Clifford invariant is +1:: sage: H = QuadraticForm(ZZ, 2, [0, 1, 0]) - sage: H.clifford_invariant(2) # optional - sage.libs.pari + sage: H.clifford_invariant(2) # needs sage.libs.pari 1 - sage: (H + H).clifford_invariant(2) # optional - sage.libs.pari + sage: (H + H).clifford_invariant(2) # needs sage.libs.pari 1 - sage: (H + H + H).clifford_invariant(2) # optional - sage.libs.pari + sage: (H + H + H).clifford_invariant(2) # needs sage.libs.pari 1 - sage: (H + H + H + H).clifford_invariant(2) # optional - sage.libs.pari + sage: (H + H + H + H).clifford_invariant(2) # needs sage.libs.pari 1 """ n = self.dim() % 8 @@ -357,28 +357,28 @@ def clifford_conductor(self): EXAMPLES:: sage: Q = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) - sage: Q.clifford_invariant(2) # optional - sage.libs.pari + sage: Q.clifford_invariant(2) # needs sage.libs.pari 1 - sage: Q.clifford_invariant(37) # optional - sage.libs.pari + sage: Q.clifford_invariant(37) # needs sage.libs.pari -1 - sage: Q.clifford_conductor() # optional - sage.libs.pari + sage: Q.clifford_conductor() # needs sage.libs.pari 37 - sage: DiagonalQuadraticForm(ZZ, [1, 1, 1]).clifford_conductor() # optional - sage.libs.pari + sage: DiagonalQuadraticForm(ZZ, [1, 1, 1]).clifford_conductor() # needs sage.libs.pari 2 - sage: QuadraticForm(ZZ, 3, [2, -2, 0, 2, 0, 5]).clifford_conductor() # optional - sage.libs.pari + sage: QuadraticForm(ZZ, 3, [2, -2, 0, 2, 0, 5]).clifford_conductor() # needs sage.libs.pari 30 For hyperbolic spaces, the Clifford conductor is 1:: sage: H = QuadraticForm(ZZ, 2, [0, 1, 0]) - sage: H.clifford_conductor() # optional - sage.libs.pari + sage: H.clifford_conductor() # needs sage.libs.pari 1 - sage: (H + H).clifford_conductor() # optional - sage.libs.pari + sage: (H + H).clifford_conductor() # needs sage.libs.pari 1 - sage: (H + H + H).clifford_conductor() # optional - sage.libs.pari + sage: (H + H + H).clifford_conductor() # needs sage.libs.pari 1 - sage: (H + H + H + H).clifford_conductor() # optional - sage.libs.pari + sage: (H + H + H + H).clifford_conductor() # needs sage.libs.pari 1 """ return prod([x[0] for x in factor(2 * self.level()) @@ -460,10 +460,10 @@ def xi(self, p): sage: Q2 = QuadraticForm(ZZ, 3, [2, -1, 0, 2, 0, 50]) sage: [Q1.omega(), Q2.omega()] [5, 5] - sage: [Q1.hasse_invariant(5), # equivalent over Q_5 # optional - sage.libs.pari + sage: [Q1.hasse_invariant(5), # equivalent over Q_5 # needs sage.libs.pari ....: Q2.hasse_invariant(5)] [1, 1] - sage: [Q1.xi(5), Q2.xi(5)] # not equivalent over Z_5 # optional - sage.libs.pari + sage: [Q1.xi(5), Q2.xi(5)] # not equivalent over Z_5 # needs sage.libs.pari [1, -1] """ if self.dim() == 2 and self.disc() % p: @@ -483,18 +483,18 @@ def xi_rec(self,p): sage: Q1 = QuadraticForm(ZZ, 3, [1, 1, 1, 14, 3, 14]) sage: Q2 = QuadraticForm(ZZ, 3, [2, -1, 0, 2, 0, 50]) - sage: [Q1.clifford_conductor(), # equivalent over Q # optional - sage.libs.pari + sage: [Q1.clifford_conductor(), # equivalent over Q # needs sage.libs.pari ....: Q2.clifford_conductor()] [3, 3] - sage: Q1.is_locally_equivalent_to(Q2) # not in the same genus # optional - sage.libs.pari + sage: Q1.is_locally_equivalent_to(Q2) # not in the same genus # needs sage.libs.pari False - sage: [Q1.delta(), Q2.delta()] # optional - sage.libs.pari + sage: [Q1.delta(), Q2.delta()] # needs sage.libs.pari [480, 480] - sage: factor(480) # optional - sage.libs.pari + sage: factor(480) # needs sage.libs.pari 2^5 * 3 * 5 - sage: list(map(Q1.xi_rec, [-1,2,3,5])) # optional - sage.libs.pari + sage: list(map(Q1.xi_rec, [-1,2,3,5])) # needs sage.libs.pari [-1, -1, -1, 1] - sage: list(map(Q2.xi_rec, [-1,2,3,5])) # optional - sage.libs.pari + sage: list(map(Q2.xi_rec, [-1,2,3,5])) # needs sage.libs.pari [-1, -1, -1, -1] """ return self.reciprocal().xi(p) @@ -509,7 +509,7 @@ def lll(self): sage: Q = QuadraticForm(ZZ, 4, range(1,11)) sage: Q.is_definite() True - sage: Q.lll() # optional - sage.libs.pari + sage: Q.lll() # needs sage.libs.pari Quadratic form in 4 variables over Integer Ring with coefficients: [ 1 0 1 0 ] [ * 4 3 3 ] @@ -526,7 +526,7 @@ def representation_number_list(self, B): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1,1,1,1,1]) - sage: Q.representation_number_list(10) # optional - sage.libs.pari + sage: Q.representation_number_list(10) # needs sage.libs.pari [1, 16, 112, 448, 1136, 2016, 3136, 5504, 9328, 12112] """ from sage.libs.pari.all import pari @@ -544,7 +544,7 @@ def representation_vector_list(self, B, maxvectors=10**8): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1, 1]) - sage: Q.representation_vector_list(10) # optional - sage.libs.pari + sage: Q.representation_vector_list(10) # needs sage.libs.pari [[(0, 0)], [(0, 1), (0, -1), (1, 0), (-1, 0)], [(1, 1), (-1, -1), (1, -1), (-1, 1)], @@ -555,15 +555,15 @@ def representation_vector_list(self, B, maxvectors=10**8): [], [(2, 2), (-2, -2), (2, -2), (-2, 2)], [(0, 3), (0, -3), (3, 0), (-3, 0)]] - sage: list(map(len, _)) # optional - sage.libs.pari + sage: list(map(len, _)) # needs sage.libs.pari [1, 4, 4, 0, 4, 8, 0, 0, 4, 4] - sage: Q.representation_number_list(10) # optional - sage.libs.pari + sage: Q.representation_number_list(10) # needs sage.libs.pari [1, 4, 4, 0, 4, 8, 0, 0, 4, 4] TESTS:: sage: R = QuadraticForm(ZZ, 2, [-4,-3,0]) - sage: R.representation_vector_list(10) # optional - sage.libs.pari + sage: R.representation_vector_list(10) # needs sage.libs.pari Traceback (most recent call last): ... PariError: domain error in minim0: form is not positive definite diff --git a/src/sage/quadratic_forms/quadratic_form__theta.py b/src/sage/quadratic_forms/quadratic_form__theta.py index 98b955f60e4..c827772037c 100644 --- a/src/sage/quadratic_forms/quadratic_form__theta.py +++ b/src/sage/quadratic_forms/quadratic_form__theta.py @@ -43,10 +43,10 @@ def theta_series(self, Max=10, var_str='q', safe_flag=True): EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7]) - sage: Q.theta_series() # optional - sage.libs.pari + sage: Q.theta_series() # needs sage.libs.pari 1 + 2*q + 2*q^3 + 6*q^4 + 2*q^5 + 4*q^6 + 6*q^7 + 8*q^8 + 14*q^9 + O(q^10) - sage: Q.theta_series(25) # optional - sage.libs.pari + sage: Q.theta_series(25) # needs sage.libs.pari 1 + 2*q + 2*q^3 + 6*q^4 + 2*q^5 + 4*q^6 + 6*q^7 + 8*q^8 + 14*q^9 + 4*q^10 + 12*q^11 + 18*q^12 + 12*q^13 + 12*q^14 + 8*q^15 + 34*q^16 + 12*q^17 + 8*q^18 + 32*q^19 + 10*q^20 + 28*q^21 + 16*q^23 + 44*q^24 + O(q^25) @@ -98,10 +98,10 @@ def theta_by_pari(self, Max, var_str='q', safe_flag=True): sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: Prec = 100 - sage: compute = Q.theta_by_pari(Prec, '') # optional - sage.libs.pari - sage: exact = [1] + [8 * sum([d for d in divisors(i) if d % 4 != 0]) # optional - sage.libs.pari + sage: compute = Q.theta_by_pari(Prec, '') # needs sage.libs.pari + sage: exact = [1] + [8 * sum([d for d in divisors(i) if d % 4 != 0]) # needs sage.libs.pari ....: for i in range(1, Prec)] - sage: compute == exact # optional - sage.libs.pari + sage: compute == exact # needs sage.libs.pari True """ @@ -288,12 +288,12 @@ def theta_series_degree_2(Q, prec): EXAMPLES:: sage: Q2 = QuadraticForm(ZZ, 4, [1,1,1,1, 1,0,0, 1,0, 1]) - sage: S = Q2.theta_series_degree_2(10) - sage: S[(0,0,2)] + sage: S = Q2.theta_series_degree_2(10) # needs sage.symbolic + sage: S[(0,0,2)] # needs sage.symbolic 24 - sage: S[(1,0,1)] + sage: S[(1,0,1)] # needs sage.symbolic 144 - sage: S[(1,1,1)] + sage: S[(1,1,1)] # needs sage.symbolic 192 AUTHORS: diff --git a/src/sage/quadratic_forms/special_values.py b/src/sage/quadratic_forms/special_values.py index 6a734c5754b..a6a26064da8 100644 --- a/src/sage/quadratic_forms/special_values.py +++ b/src/sage/quadratic_forms/special_values.py @@ -38,22 +38,24 @@ def gamma__exact(n): sage: gamma__exact(1) 1 - sage: gamma__exact(1/2) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: gamma__exact(1/2) sqrt(pi) - sage: gamma__exact(3/2) # optional - sage.symbolic + sage: gamma__exact(3/2) 1/2*sqrt(pi) - sage: gamma__exact(5/2) # optional - sage.symbolic + sage: gamma__exact(5/2) 3/4*sqrt(pi) - sage: gamma__exact(7/2) # optional - sage.symbolic + sage: gamma__exact(7/2) 15/8*sqrt(pi) - sage: gamma__exact(-1/2) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: gamma__exact(-1/2) -2*sqrt(pi) - sage: gamma__exact(-3/2) # optional - sage.symbolic + sage: gamma__exact(-3/2) 4/3*sqrt(pi) - sage: gamma__exact(-5/2) # optional - sage.symbolic + sage: gamma__exact(-5/2) -8/15*sqrt(pi) - sage: gamma__exact(-7/2) # optional - sage.symbolic + sage: gamma__exact(-7/2) 16/105*sqrt(pi) TESTS:: @@ -105,7 +107,7 @@ def zeta__exact(n): Let us test the accuracy for negative special values:: sage: RR = RealField(100) - sage: for i in range(1,10): # optional - sage.symbolic + sage: for i in range(1,10): # needs sage.symbolic ....: print("zeta({}): {}".format(1 - 2*i, ....: RR(zeta__exact(1-2*i)) - zeta(RR(1-2*i)))) zeta(-1): 0.00000000000000000000000000000 @@ -120,13 +122,13 @@ def zeta__exact(n): Let us test the accuracy for positive special values:: - sage: all(abs(RR(zeta__exact(2*i)) - zeta(RR(2*i))) < 10**(-28) # optional - sage.symbolic + sage: all(abs(RR(zeta__exact(2*i)) - zeta(RR(2*i))) < 10**(-28) # needs sage.symbolic ....: for i in range(1,10)) True TESTS:: - sage: zeta__exact(4) # optional - sage.symbolic + sage: zeta__exact(4) # needs sage.symbolic 1/90*pi^4 sage: zeta__exact(-3) 1/120 @@ -168,13 +170,13 @@ def QuadraticBernoulliNumber(k, d): Let us create a list of some odd negative fundamental discriminants:: - sage: test_set = [d for d in srange(-163, -3, 4) # optional - sage.libs.pari + sage: test_set = [d for d in srange(-163, -3, 4) # needs sage.libs.pari ....: if d.is_fundamental_discriminant()] In general, we have `B_{1, \chi_d} = -2 h/w` for odd negative fundamental discriminants:: - sage: all(QuadraticBernoulliNumber(1, d) # optional - sage.libs.pari + sage: all(QuadraticBernoulliNumber(1, d) # needs sage.libs.pari ....: == -len(BinaryQF_reduced_representatives(d)) ....: for d in test_set) True @@ -209,16 +211,16 @@ def quadratic_L_function__exact(n, d): EXAMPLES:: - sage: quadratic_L_function__exact(1, -4) # optional - sage.libs.pari sage.symbolic + sage: quadratic_L_function__exact(1, -4) # needs sage.libs.pari sage.symbolic 1/4*pi - sage: quadratic_L_function__exact(-4, -4) # optional - sage.libs.pari + sage: quadratic_L_function__exact(-4, -4) # needs sage.libs.pari 5/2 - sage: quadratic_L_function__exact(2, 1) # optional - sage.libs.pari sage.symbolic + sage: quadratic_L_function__exact(2, 1) # needs sage.libs.pari sage.symbolic 1/6*pi^2 TESTS:: - sage: quadratic_L_function__exact(2, -4) # optional - sage.libs.pari + sage: quadratic_L_function__exact(2, -4) # needs sage.libs.pari Traceback (most recent call last): ... TypeError: n must be a critical value (i.e. odd > 0 or even <= 0) @@ -272,7 +274,7 @@ def quadratic_L_function__numerical(n, d, num_terms=1000): First, let us test several values for a given character:: sage: RR = RealField(100) - sage: for i in range(5): # optional - sage.symbolic + sage: for i in range(5): # needs sage.symbolic ....: print("L({}, (-4/.)): {}".format(1+2*i, ....: RR(quadratic_L_function__exact(1+2*i, -4)) ....: - quadratic_L_function__numerical(RR(1+2*i), -4, 10000))) @@ -293,7 +295,7 @@ def quadratic_L_function__numerical(n, d, num_terms=1000): Test for several characters that the result agrees with the exact value, to a given accuracy :: - sage: for d in range(-20,0): # long time (2s on sage.math 2014) # optional - sage.symbolic + sage: for d in range(-20,0): # long time (2s on sage.math 2014), needs sage.symbolic ....: if abs(RR(quadratic_L_function__numerical(1, d, 10000) ....: - quadratic_L_function__exact(1, d))) > 0.001: ....: print("We have a problem at d = {}: exact = {}, numerical = {}".format(d, diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index 93b248becf6..ee07b83d147 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -477,10 +477,10 @@ def pseudorandom_primitive_zero_mod_p(a, b, c, r, s, t, p): sage: Q = TernaryQF([1, 2, 2, -1, 0, 0]) sage: p = 1009 sage: from sage.quadratic_forms.ternary import pseudorandom_primitive_zero_mod_p - sage: v = pseudorandom_primitive_zero_mod_p(1, 2, 2, -1, 0, 0, p) # optional - sage.libs.pari - sage: v[2] # optional - sage.libs.pari + sage: v = pseudorandom_primitive_zero_mod_p(1, 2, 2, -1, 0, 0, p) # needs sage.libs.pari + sage: v[2] # needs sage.libs.pari 1 - sage: Q(v)%p # optional - sage.libs.pari + sage: Q(v)%p # needs sage.libs.pari 0 """ # [a, b, c, r, s, t] = Q.coefficients() @@ -582,16 +582,16 @@ def _find_zeros_mod_p(a, b, c, r, s, t, p): sage: from sage.quadratic_forms.ternary import _find_zeros_mod_p sage: Q = TernaryQF([1, 2, 2, -1, 0, 0]) sage: p = 1009 - sage: zeros_1009 = _find_zeros_mod_p(1, 2, 2, -1, 0, 0, p) # optional - sage.libs.pari - sage: len(zeros_1009) # optional - sage.libs.pari + sage: zeros_1009 = _find_zeros_mod_p(1, 2, 2, -1, 0, 0, p) # needs sage.libs.pari + sage: len(zeros_1009) # needs sage.libs.pari 1010 - sage: zeros_1009.sort() # optional - sage.libs.pari - sage: zeros_1009[0] # optional - sage.libs.pari + sage: zeros_1009.sort() # needs sage.libs.pari + sage: zeros_1009[0] # needs sage.libs.pari (0, 32, 1) sage: Q((0, 32, 1)) 2018 - sage: zeros_2 = _find_zeros_mod_p(1, 2, 2, -1, 0, 0, 2) # optional - sage.libs.pari - sage: zeros_2 # optional - sage.libs.pari + sage: zeros_2 = _find_zeros_mod_p(1, 2, 2, -1, 0, 0, 2) # needs sage.libs.pari + sage: zeros_2 # needs sage.libs.pari [(0, 1, 0), (0, 0, 1), (1, 1, 1)] """ if p == 2: @@ -913,7 +913,7 @@ def _find_p_neighbor_from_vec(a, b, c, r, s, t, p, v, mat=False): sage: Q.disc() 29 sage: v = (9, 7, 1) - sage: v in Q.find_zeros_mod_p(11) # optional - sage.libs.pari + sage: v in Q.find_zeros_mod_p(11) # needs sage.libs.pari True sage: q11, M = _find_p_neighbor_from_vec(1, 3, 3, -2, 0, -1, 11, v, mat=True) sage: Q11 = TernaryQF(q11) diff --git a/src/sage/quadratic_forms/ternary_qf.py b/src/sage/quadratic_forms/ternary_qf.py index ce74661ffdd..a8854ba9811 100644 --- a/src/sage/quadratic_forms/ternary_qf.py +++ b/src/sage/quadratic_forms/ternary_qf.py @@ -815,10 +815,10 @@ def pseudorandom_primitive_zero_mod_p(self, p): (1, 2, 1) sage: Q((1, 2, 1)) 15 - sage: v = Q.pseudorandom_primitive_zero_mod_p(1009) # optional - sage.libs.pari - sage: Q(v) % 1009 # optional - sage.libs.pari + sage: v = Q.pseudorandom_primitive_zero_mod_p(1009) # needs sage.libs.pari + sage: Q(v) % 1009 # needs sage.libs.pari 0 - sage: v[2] # optional - sage.libs.pari + sage: v[2] # needs sage.libs.pari 1 """ [a,b,c,r,s,t] = self.coefficients() @@ -851,10 +851,10 @@ def find_zeros_mod_p(self, p): 3 * 13 * 19 sage: Q.find_zeros_mod_p(2) [(1, 0, 0), (1, 1, 0), (0, 0, 1)] - sage: zeros_17 = Q.find_zeros_mod_p(17) # optional - sage.libs.pari - sage: len(zeros_17) # optional - sage.libs.pari + sage: zeros_17 = Q.find_zeros_mod_p(17) # needs sage.libs.pari + sage: len(zeros_17) # needs sage.libs.pari 18 - sage: [Q(v)%17 for v in zeros_17] # optional - sage.libs.pari + sage: [Q(v)%17 for v in zeros_17] # needs sage.libs.pari [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] """ @@ -890,18 +890,18 @@ def find_p_neighbor_from_vec(self, p, v, mat=False): sage: Q.disc() 29 sage: v = (9, 7, 1) - sage: v in Q.find_zeros_mod_p(11) # optional - sage.libs.pari + sage: v in Q.find_zeros_mod_p(11) # needs sage.libs.pari True - sage: Q11, M = Q.find_p_neighbor_from_vec(11, v, mat=True) # optional - sage.libs.pari - sage: Q11 # optional - sage.libs.pari + sage: Q11, M = Q.find_p_neighbor_from_vec(11, v, mat=True) # needs sage.libs.pari + sage: Q11 # needs sage.libs.pari Ternary quadratic form with integer coefficients: [1 2 4] [-1 -1 0] - sage: M # optional - sage.libs.pari + sage: M # needs sage.libs.pari [ -1 -5/11 7/11] [ 0 -10/11 3/11] [ 0 -3/11 13/11] - sage: Q(M) == Q11 # optional - sage.libs.pari + sage: Q(M) == Q11 # needs sage.libs.pari True """ if mat: @@ -923,16 +923,16 @@ def find_p_neighbors(self, p, mat=False): Ternary quadratic form with integer coefficients: [1 3 3] [-2 0 -1] - sage: neig = Q0.find_p_neighbors(5) # optional - sage.libs.pari - sage: len(neig) # optional - sage.libs.pari + sage: neig = Q0.find_p_neighbors(5) # needs sage.libs.pari + sage: len(neig) # needs sage.libs.pari 6 sage: Q1 = TernaryQF([1, 1, 10, 1, 1, 1]) sage: Q2 = TernaryQF([1, 2, 4, -1, -1, 0]) - sage: neig.count(Q0) # optional - sage.libs.pari + sage: neig.count(Q0) # needs sage.libs.pari 2 - sage: neig.count(Q1) # optional - sage.libs.pari + sage: neig.count(Q1) # needs sage.libs.pari 1 - sage: neig.count(Q2) # optional - sage.libs.pari + sage: neig.count(Q2) # needs sage.libs.pari 3 """ From 2ddf14906aa0a3596f660eadf87683810b5545f4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:23 -0700 Subject: [PATCH 75/99] src/sage/stats: sage -fixdoctests --only-tags --- src/sage/stats/basic_stats.py | 56 +++++++++---------- .../discrete_gaussian_lattice.py | 18 +++--- .../discrete_gaussian_polynomial.py | 6 +- src/sage/stats/hmm/distributions.pyx | 2 +- src/sage/stats/hmm/hmm.pyx | 8 +-- src/sage/stats/intlist.pyx | 6 +- src/sage/stats/time_series.pyx | 20 +++---- 7 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index 4919a406297..b18f3dac6f3 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -68,22 +68,22 @@ def mean(v): EXAMPLES:: - sage: mean([pi, e]) # optional - sage.symbolic + sage: mean([pi, e]) # needs sage.symbolic doctest:warning... DeprecationWarning: sage.stats.basic_stats.mean is deprecated; use numpy.mean or numpy.nanmean instead See https://github.com/sagemath/sage/issues/29662 for details. 1/2*pi + 1/2*e - sage: mean([]) # optional - sage.symbolic + sage: mean([]) # needs sage.symbolic NaN - sage: mean([I, sqrt(2), 3/5]) # optional - sage.symbolic + sage: mean([I, sqrt(2), 3/5]) # needs sage.symbolic 1/3*sqrt(2) + 1/3*I + 1/5 sage: mean([RIF(1.0103,1.0103), RIF(2)]) 1.5051500000000000? sage: mean(range(4)) 3/2 - sage: v = stats.TimeSeries([1..100]) # optional - numpy - sage: mean(v) # optional - numpy + sage: v = stats.TimeSeries([1..100]) # needs numpy + sage: mean(v) # needs numpy 50.5 """ deprecation(29662, 'sage.stats.basic_stats.mean is deprecated; use numpy.mean or numpy.nanmean instead') @@ -198,8 +198,8 @@ def std(v, bias=False): EXAMPLES:: - sage: # optional - sage.symbolic - sage: std([1..6], bias=True) # optional - sage.symbolic + sage: # needs sage.symbolic + sage: std([1..6], bias=True) doctest:warning... DeprecationWarning: sage.stats.basic_stats.std is deprecated; use numpy.std or numpy.nanstd instead @@ -213,25 +213,25 @@ def std(v, bias=False): use numpy.mean or numpy.nanmean instead See https://github.com/sagemath/sage/issues/29662 for details. 1/2*sqrt(35/3) - sage: std([1..6], bias=False) # optional - sage.symbolic + sage: std([1..6], bias=False) sqrt(7/2) - sage: std([e, pi]) # optional - sage.symbolic + sage: std([e, pi]) sqrt(1/2)*abs(pi - e) - sage: std([]) # optional - sage.symbolic + sage: std([]) NaN - sage: std([I, sqrt(2), 3/5]) # optional - sage.symbolic + sage: std([I, sqrt(2), 3/5]) 1/15*sqrt(1/2)*sqrt((10*sqrt(2) - 5*I - 3)^2 + (5*sqrt(2) - 10*I + 3)^2 + (5*sqrt(2) + 5*I - 6)^2) sage: std([RIF(1.0103, 1.0103), RIF(2)]) 0.6998235813403261? - sage: # optional - numpy - sage: import numpy # optional - numpy - sage: x = numpy.array([1,2,3,4,5]) # optional - numpy - sage: std(x, bias=False) # optional - numpy + sage: # needs numpy + sage: import numpy + sage: x = numpy.array([1,2,3,4,5]) + sage: std(x, bias=False) 1.5811388300841898 - sage: x = stats.TimeSeries([1..100]) # optional - numpy - sage: std(x) # optional - numpy + sage: x = stats.TimeSeries([1..100]) + sage: std(x) 29.011491975882016 TESTS:: @@ -294,18 +294,18 @@ def variance(v, bias=False): 7/2 sage: variance([1..6], bias=True) 35/12 - sage: variance([e, pi]) # optional - sage.symbolic + sage: variance([e, pi]) # needs sage.symbolic 1/2*(pi - e)^2 sage: variance([]) NaN - sage: variance([I, sqrt(2), 3/5]) # optional - sage.symbolic + sage: variance([I, sqrt(2), 3/5]) # needs sage.symbolic 1/450*(10*sqrt(2) - 5*I - 3)^2 + 1/450*(5*sqrt(2) - 10*I + 3)^2 + 1/450*(5*sqrt(2) + 5*I - 6)^2 sage: variance([RIF(1.0103, 1.0103), RIF(2)]) 0.4897530450000000? - sage: import numpy # optional - numpy - sage: x = numpy.array([1,2,3,4,5]) # optional - numpy - sage: variance(x, bias=False) # optional - numpy + sage: import numpy # needs numpy + sage: x = numpy.array([1,2,3,4,5]) # needs numpy + sage: variance(x, bias=False) # needs numpy 2.5 sage: x = stats.TimeSeries([1..100]) sage: variance(x) @@ -398,11 +398,11 @@ def median(v): use numpy.median or numpy.nanmedian instead See https://github.com/sagemath/sage/issues/29662 for details. 3 - sage: median([e, pi]) # optional - sage.symbolic + sage: median([e, pi]) # needs sage.symbolic 1/2*pi + 1/2*e sage: median(['sage', 'linux', 'python']) 'python' - sage: median([]) # optional - sage.symbolic + sage: median([]) # needs sage.symbolic NaN sage: class MyClass: ....: def median(self): @@ -459,7 +459,7 @@ def moving_average(v, n): [5/2, 7/2, 9/2, 11/2, 13/2, 15/2, 17/2] sage: moving_average([], 1) [] - sage: moving_average([pi, e, I, sqrt(2), 3/5], 2) # optional - sage.symbolic + sage: moving_average([pi, e, I, sqrt(2), 3/5], 2) # needs sage.symbolic [1/2*pi + 1/2*e, 1/2*e + 1/2*I, 1/2*sqrt(2) + 1/2*I, 1/2*sqrt(2) + 3/10] @@ -468,10 +468,10 @@ def moving_average(v, n): different) meaning as defined above (the point is that the :meth:`simple_moving_average` on time series returns `n` values:: - sage: a = stats.TimeSeries([1..10]) # optional - numpy - sage: stats.moving_average(a, 3) # optional - numpy + sage: a = stats.TimeSeries([1..10]) # needs numpy + sage: stats.moving_average(a, 3) # needs numpy [2.0000, 3.0000, 4.0000, 5.0000, 6.0000, 7.0000, 8.0000, 9.0000] - sage: stats.moving_average(list(a), 3) # optional - numpy + sage: stats.moving_average(list(a), 3) # needs numpy [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] """ diff --git a/src/sage/stats/distributions/discrete_gaussian_lattice.py b/src/sage/stats/distributions/discrete_gaussian_lattice.py index 73d1a269f9c..8e35d45129f 100644 --- a/src/sage/stats/distributions/discrete_gaussian_lattice.py +++ b/src/sage/stats/distributions/discrete_gaussian_lattice.py @@ -139,7 +139,7 @@ class DiscreteGaussianDistributionLatticeSampler(SageObject): sage: D = DiscreteGaussianDistributionLatticeSampler(identity_matrix(2), 3.0) sage: S = [D() for _ in range(2^12)] sage: l = [vector(v.list() + [S.count(v)]) for v in set(S)] - sage: list_plot3d(l, point_list=True, interpolation='nn') # optional - sage.plot + sage: list_plot3d(l, point_list=True, interpolation='nn') # needs sage.plot Graphics3d Object REFERENCES: @@ -205,7 +205,7 @@ def _normalisation_factor_zz(self, tau=3): sage: n = 3; sigma = 1.0 sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^n, sigma) sage: f = D.f - sage: c = D._normalisation_factor_zz(); c # optional - sage.symbolic + sage: c = D._normalisation_factor_zz(); c # needs sage.symbolic 15.528... sage: from collections import defaultdict @@ -222,7 +222,7 @@ def _normalisation_factor_zz(self, tau=3): sage: while v not in counter: ....: add_samples(1000) - sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # optional - sage.symbolic + sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # needs sage.symbolic ....: add_samples(1000) sage: v = vector(ZZ, n, (-1, 2, 3)) @@ -230,7 +230,7 @@ def _normalisation_factor_zz(self, tau=3): sage: while v not in counter: ....: add_samples(1000) - sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.2: # long time, optional - sage.symbolic + sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.2: # long time, needs sage.symbolic ....: add_samples(1000) """ if self.B != identity_matrix(ZZ, self.B.nrows()): @@ -265,7 +265,7 @@ def __init__(self, B, sigma=1, c=None, precision=None): sage: n = 2; sigma = 3.0 sage: D = DiscreteGaussianDistributionLatticeSampler(ZZ^n, sigma) sage: f = D.f - sage: c = D._normalisation_factor_zz(); c # optional - sage.symbolic + sage: c = D._normalisation_factor_zz(); c # needs sage.symbolic 56.2162803067524 sage: from collections import defaultdict @@ -281,25 +281,25 @@ def __init__(self, B, sigma=1, c=None, precision=None): sage: v.set_immutable() sage: while v not in counter: ....: add_samples(1000) - sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # optional - sage.symbolic + sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # needs sage.symbolic ....: add_samples(1000) sage: v = vector(ZZ, n, (0, 0)) sage: v.set_immutable() sage: while v not in counter: ....: add_samples(1000) - sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # optional - sage.symbolic + sage: while abs(m*f(v)*1.0/c/counter[v] - 1.0) >= 0.1: # needs sage.symbolic ....: add_samples(1000) sage: from sage.stats.distributions.discrete_gaussian_lattice import DiscreteGaussianDistributionLatticeSampler sage: qf = QuadraticForm(matrix(3, [2, 1, 1, 1, 2, 1, 1, 1, 2])) - sage: D = DiscreteGaussianDistributionLatticeSampler(qf, 3.0); D # optional - sage.symbolic + sage: D = DiscreteGaussianDistributionLatticeSampler(qf, 3.0); D # needs sage.symbolic Discrete Gaussian sampler with σ = 3.000000, c=(0, 0, 0) over lattice with basis [2 1 1] [1 2 1] [1 1 2] - sage: D().parent() is D.c.parent() # optional - sage.symbolic + sage: D().parent() is D.c.parent() # needs sage.symbolic True """ precision = DiscreteGaussianDistributionLatticeSampler.compute_precision(precision, sigma) diff --git a/src/sage/stats/distributions/discrete_gaussian_polynomial.py b/src/sage/stats/distributions/discrete_gaussian_polynomial.py index fa975ebab69..7d61ab7eb0c 100644 --- a/src/sage/stats/distributions/discrete_gaussian_polynomial.py +++ b/src/sage/stats/distributions/discrete_gaussian_polynomial.py @@ -17,9 +17,9 @@ sage: sigma = 3.0; n = 1000 sage: l = [DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], 64, sigma)() ....: for _ in range(n)] - sage: l = [vector(f).norm().n() for f in l] # optional - sage.symbolic - sage: from numpy import mean # optional - numpy - sage: mean(l), sqrt(64)*sigma # abs tol 5e-1 # optional - numpy sage.symbolic + sage: l = [vector(f).norm().n() for f in l] # needs sage.symbolic + sage: from numpy import mean # needs numpy + sage: mean(l), sqrt(64)*sigma # abs tol 5e-1 # needs numpy sage.symbolic (24.0, 24.0) """ diff --git a/src/sage/stats/hmm/distributions.pyx b/src/sage/stats/hmm/distributions.pyx index a6380cf6b9f..1620730544c 100644 --- a/src/sage/stats/hmm/distributions.pyx +++ b/src/sage/stats/hmm/distributions.pyx @@ -134,7 +134,7 @@ cdef class Distribution: EXAMPLES:: sage: P = hmm.GaussianMixtureDistribution([(.2,-10,.5),(.6,1,1),(.2,20,.5)]) - sage: P.plot(-10,30) # optional - sage.plot + sage: P.plot(-10,30) # needs sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.all import plot diff --git a/src/sage/stats/hmm/hmm.pyx b/src/sage/stats/hmm/hmm.pyx index 0f2d10074ff..04b266cc3e0 100644 --- a/src/sage/stats/hmm/hmm.pyx +++ b/src/sage/stats/hmm/hmm.pyx @@ -148,11 +148,11 @@ cdef class HiddenMarkovModel: sage: m = hmm.DiscreteHiddenMarkovModel([[.3,0,.7],[0,0,1],[.5,.5,0]], ....: [[.5,.5,.2]]*3, ....: [1/3]*3) - sage: G = m.graph(); G # optional - sage.graphs + sage: G = m.graph(); G # needs sage.graphs Looped digraph on 3 vertices - sage: G.edges(sort=True) # optional - sage.graphs + sage: G.edges(sort=True) # needs sage.graphs [(0, 0, 0.3), (0, 2, 0.7), (1, 2, 1.0), (2, 0, 0.5), (2, 1, 0.5)] - sage: G.plot() # optional - sage.graphs sage.plot + sage: G.plot() # needs sage.graphs sage.plot Graphics object consisting of 11 graphics primitives """ cdef int i, j @@ -314,7 +314,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): Initial probabilities: [0.0000, 1.0000] sage: m.sample(10) [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] - sage: m.graph().plot() # optional - sage.plot + sage: m.graph().plot() # needs sage.plot Graphics object consisting of 6 graphics primitives A 3-state model that happens to always outputs 'b':: diff --git a/src/sage/stats/intlist.pyx b/src/sage/stats/intlist.pyx index 0b39a0ebfad..1bfc74aed96 100644 --- a/src/sage/stats/intlist.pyx +++ b/src/sage/stats/intlist.pyx @@ -520,9 +520,9 @@ cdef class IntList: EXAMPLES:: - sage: stats.IntList([3,7,19,-2]).plot() # optional - sage.plot + sage: stats.IntList([3,7,19,-2]).plot() # needs sage.plot Graphics object consisting of 1 graphics primitive - sage: stats.IntList([3,7,19,-2]).plot(color='red', # optional - sage.plot + sage: stats.IntList([3,7,19,-2]).plot(color='red', # needs sage.plot ....: pointsize=50, points=True) Graphics object consisting of 1 graphics primitive """ @@ -538,7 +538,7 @@ cdef class IntList: EXAMPLES:: - sage: stats.IntList([1..15]).plot_histogram() # optional - sage.plot + sage: stats.IntList([1..15]).plot_histogram() # needs sage.plot Graphics object consisting of 50 graphics primitives """ return self.time_series().plot_histogram(*args, **kwds) diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index fd1c193c52b..7c3dbde6b12 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -97,7 +97,7 @@ cdef class TimeSeries: This implicitly calls init:: - sage: stats.TimeSeries([pi, 3, 18.2]) # optional - sage.symbolic + sage: stats.TimeSeries([pi, 3, 18.2]) # needs sage.symbolic [3.1416, 3.0000, 18.2000] Conversion from a NumPy 1-D array, which is very fast:: @@ -1032,7 +1032,7 @@ cdef class TimeSeries: Draw a plot of a time series:: - sage: stats.TimeSeries([1..10]).show() # optional - sage.plot + sage: stats.TimeSeries([1..10]).show() # needs sage.plot Graphics object consisting of 1 graphics primitive """ return self.plot(*args, **kwds) @@ -1060,13 +1060,13 @@ cdef class TimeSeries: sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000] - sage: v.plot() # optional - sage.plot + sage: v.plot() # needs sage.plot Graphics object consisting of 1 graphics primitive - sage: v.plot(points=True) # optional - sage.plot + sage: v.plot(points=True) # needs sage.plot Graphics object consisting of 1 graphics primitive - sage: v.plot() + v.plot(points=True, rgbcolor='red') # optional - sage.plot + sage: v.plot() + v.plot(points=True, rgbcolor='red') # needs sage.plot Graphics object consisting of 2 graphics primitives - sage: v.plot() + v.plot(points=True, rgbcolor='red', pointsize=50) # optional - sage.plot + sage: v.plot() + v.plot(points=True, rgbcolor='red', pointsize=50) # needs sage.plot Graphics object consisting of 2 graphics primitives """ from sage.plot.all import line, point @@ -2000,12 +2000,12 @@ cdef class TimeSeries: EXAMPLES:: sage: v = stats.TimeSeries([1..50]) - sage: v.plot_histogram(bins=10) # optional - sage.plot + sage: v.plot_histogram(bins=10) # needs sage.plot Graphics object consisting of 10 graphics primitives :: - sage: v.plot_histogram(bins=3,normalize=False,aspect_ratio=1) # optional - sage.plot + sage: v.plot_histogram(bins=3,normalize=False,aspect_ratio=1) # needs sage.plot Graphics object consisting of 3 graphics primitives """ from sage.plot.all import polygon @@ -2044,7 +2044,7 @@ cdef class TimeSeries: Here we look at the candlestick plot for Brownian motion:: sage: v = stats.TimeSeries(1000).randomize() - sage: v.plot_candlestick(bins=20) # optional - sage.plot + sage: v.plot_candlestick(bins=20) # needs sage.plot Graphics object consisting of 40 graphics primitives """ from sage.plot.all import line, polygon, Graphics @@ -2407,7 +2407,7 @@ cdef class TimeSeries: sage: v = stats.TimeSeries(10^6) sage: v.randomize('lognormal').mean() 1.647351973... - sage: exp(0.5) # optional - sage.symbolic + sage: exp(0.5) # needs sage.symbolic 1.648721270... A log-normal distribution can be simply thought of as the logarithm From 8833cf920b6115c655d7bd63908702237c17186e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 7 Aug 2023 22:44:23 -0700 Subject: [PATCH 76/99] src/sage/tensor: sage -fixdoctests --only-tags --- src/sage/tensor/modules/comp.py | 6 +++--- src/sage/tensor/modules/free_module_alt_form.py | 11 ++++++----- src/sage/tensor/modules/free_module_morphism.py | 2 +- src/sage/tensor/modules/free_module_tensor.py | 9 +++++---- src/sage/tensor/modules/reflexive_module.py | 12 ++++++------ 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/sage/tensor/modules/comp.py b/src/sage/tensor/modules/comp.py index 198fdc7479a..482324c1b44 100644 --- a/src/sage/tensor/modules/comp.py +++ b/src/sage/tensor/modules/comp.py @@ -1235,9 +1235,9 @@ def display(self, symbol, latex_symbol=None, index_positions=None, Check that the bug reported in :trac:`22520` is fixed:: - sage: c = Components(SR, [1, 2], 1) # optional - sage.symbolic - sage: c[0] = SR.var('t', domain='real') # optional - sage.symbolic - sage: c.display('c') # optional - sage.symbolic + sage: c = Components(SR, [1, 2], 1) # needs sage.symbolic + sage: c[0] = SR.var('t', domain='real') # needs sage.symbolic + sage: c.display('c') # needs sage.symbolic c_0 = t """ diff --git a/src/sage/tensor/modules/free_module_alt_form.py b/src/sage/tensor/modules/free_module_alt_form.py index 3569f686681..a11d3a447c9 100644 --- a/src/sage/tensor/modules/free_module_alt_form.py +++ b/src/sage/tensor/modules/free_module_alt_form.py @@ -554,11 +554,12 @@ def display(self, basis=None, format_spec=None): Check that the bug reported in :trac:`22520` is fixed:: - sage: M = FiniteRankFreeModule(SR, 2, name='M') # optional - sage.symbolic - sage: e = M.basis('e') # optional - sage.symbolic - sage: a = M.alternating_form(2) # optional - sage.symbolic - sage: a[0,1] = SR.var('t', domain='real') # optional - sage.symbolic - sage: a.display() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: M = FiniteRankFreeModule(SR, 2, name='M') + sage: e = M.basis('e') + sage: a = M.alternating_form(2) + sage: a[0,1] = SR.var('t', domain='real') + sage: a.display() t e^0∧e^1 """ diff --git a/src/sage/tensor/modules/free_module_morphism.py b/src/sage/tensor/modules/free_module_morphism.py index 3430172033a..073cb91e60c 100644 --- a/src/sage/tensor/modules/free_module_morphism.py +++ b/src/sage/tensor/modules/free_module_morphism.py @@ -1058,7 +1058,7 @@ def matrix(self, basis1=None, basis2=None): sage: phi.matrix(e, f) # given bases [-1 2 0] [ 5 1 2] - sage: type(phi.matrix()) # optional - sage.libs.flint + sage: type(phi.matrix()) # needs sage.libs.flint Matrix in bases different from those in which the homomorphism has diff --git a/src/sage/tensor/modules/free_module_tensor.py b/src/sage/tensor/modules/free_module_tensor.py index 7a74aa8098e..4d84d76b58a 100644 --- a/src/sage/tensor/modules/free_module_tensor.py +++ b/src/sage/tensor/modules/free_module_tensor.py @@ -680,10 +680,11 @@ def display(self, basis=None, format_spec=None): Check that the bug reported in :trac:`22520` is fixed:: - sage: M = FiniteRankFreeModule(SR, 3, name='M') # optional - sage.symbolic - sage: e = M.basis('e') # optional - sage.symbolic - sage: t = SR.var('t', domain='real') # optional - sage.symbolic - sage: (t*e[0]).display() # optional - sage.symbolic + sage: # needs sage.symbolic + sage: M = FiniteRankFreeModule(SR, 3, name='M') + sage: e = M.basis('e') + sage: t = SR.var('t', domain='real') + sage: (t*e[0]).display() t e_0 """ diff --git a/src/sage/tensor/modules/reflexive_module.py b/src/sage/tensor/modules/reflexive_module.py index 504b45e05b6..073f76e4659 100644 --- a/src/sage/tensor/modules/reflexive_module.py +++ b/src/sage/tensor/modules/reflexive_module.py @@ -256,9 +256,9 @@ def base_module(self): sage: M.base_module() is M True - sage: M = Manifold(2, 'M') # optional - sage.symbolic - sage: XM = M.vector_field_module() # optional - sage.symbolic - sage: XM.base_module() is XM # optional - sage.symbolic + sage: M = Manifold(2, 'M') # needs sage.symbolic + sage: XM = M.vector_field_module() # needs sage.symbolic + sage: XM.base_module() is XM # needs sage.symbolic True """ return self @@ -273,9 +273,9 @@ def tensor_type(self): sage: M.tensor_type() (1, 0) - sage: M = Manifold(2, 'M') # optional - sage.symbolic - sage: XM = M.vector_field_module() # optional - sage.symbolic - sage: XM.tensor_type() # optional - sage.symbolic + sage: M = Manifold(2, 'M') # needs sage.symbolic + sage: XM = M.vector_field_module() # needs sage.symbolic + sage: XM.tensor_type() # needs sage.symbolic (1, 0) """ return (1, 0) From adb22d54583186377aa34450eb995bc6e1f57661 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 10 Aug 2023 22:23:34 -0700 Subject: [PATCH 77/99] Use more block tags --- src/sage/matrix/args.pyx | 29 ++-- src/sage/matrix/constructor.pyx | 37 +++-- src/sage/matrix/matrix_generic_dense.pyx | 9 +- .../matrix/matrix_modn_dense_template.pxi | 152 ++++++++--------- src/sage/matrix/matrix_polynomial_dense.pyx | 155 +++++++----------- src/sage/matrix/matrix_sparse.pyx | 11 +- src/sage/modules/filtered_vector_space.py | 9 +- src/sage/modules/free_module_integer.py | 50 +++--- src/sage/modules/vector_double_dense.pyx | 14 +- 9 files changed, 230 insertions(+), 236 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index 8b0378dec6b..5dde6772ebb 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -194,24 +194,27 @@ cdef class MatrixArgs: [1 2] [3 4] - sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized() # needs sage.libs.pari + + sage: # needs sage.libs.pari + sage: ma = MatrixArgs(QQ, entries=pari("[1,2;3,4]")); ma.finalized() sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized() # needs sage.libs.pari + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("[1,2,3,4]")); ma.finalized() sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized() # needs sage.libs.pari + sage: ma = MatrixArgs(QQ, 2, 2, entries=pari("3/5")); ma.finalized() - sage: ma.matrix() # needs sage.libs.pari + sage: ma.matrix() [3/5 0] [ 0 3/5] + sage: ma = MatrixArgs(entries=matrix(2,2)); ma.finalized(); ma.matrix() @@ -225,33 +228,37 @@ cdef class MatrixArgs: > [1 2] [3 4] - sage: from numpy import array # needs numpy - sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized() # needs numpy + + sage: # needs numpy + sage: from numpy import array + sage: ma = MatrixArgs(array([[1,2],[3,4]])); ma.finalized() sage: ma.matrix() [1 2] [3 4] - sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized() # needs numpy + sage: ma = MatrixArgs(array([[1.,2.],[3.,4.]])); ma.finalized() sage: ma.matrix() [1.0 2.0] [3.0 4.0] - sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized() # needs numpy + sage: ma = MatrixArgs(RealField(20), array([[1.,2.],[3.,4.]])); ma.finalized() - sage: ma.matrix() # needs numpy + sage: ma.matrix() [1.0000 2.0000] [3.0000 4.0000] - sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized() # needs sage.graphs + + sage: # needs sage.graphs + sage: ma = MatrixArgs(graphs.CycleGraph(3)); ma.finalized() - sage: ma.matrix() # needs sage.graphs + sage: ma.matrix() [0 1 1] [1 0 1] [1 1 0] diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index 3617c9ae96a..74541580cef 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -456,53 +456,54 @@ def matrix(*args, **kwds): Check conversion from numpy:: - sage: import numpy # needs numpy - sage: n = numpy.array([[complex(0,1),complex(0,2)], [3,4]], complex) # needs numpy - sage: m = matrix(n); m; m.parent() # needs numpy + sage: # needs numpy + sage: import numpy + sage: n = numpy.array([[complex(0,1),complex(0,2)], [3,4]], complex) + sage: m = matrix(n); m; m.parent() [1.0*I 2.0*I] [ 3.0 4.0] Full MatrixSpace of 2 by 2 dense matrices over Complex Double Field - sage: n = numpy.array([[1,2], [3,4]], 'int32') # needs numpy - sage: m = matrix(n); m; m.parent() # needs numpy + sage: n = numpy.array([[1,2], [3,4]], 'int32') + sage: m = matrix(n); m; m.parent() [1 2] [3 4] Full MatrixSpace of 2 by 2 dense matrices over Integer Ring - sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'float32') # needs numpy - sage: m = matrix(n); m; m.parent() # needs numpy + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'float32') + sage: m = matrix(n); m; m.parent() [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Real Double Field - sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'float64') # needs numpy - sage: m = matrix(n); m; m.parent() # needs numpy + sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'float64') + sage: m = matrix(n); m; m.parent() [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Real Double Field - sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'complex64') # needs numpy - sage: m = matrix(n); m; m.parent() # needs numpy + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'complex64') + sage: m = matrix(n); m; m.parent() [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Complex Double Field - sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'complex128') # needs numpy - sage: m = matrix(n); m; m.parent() # needs numpy + sage: n = numpy.matrix([[1,2,3], [4,5,6], [7,8,9]], 'complex128') + sage: m = matrix(n); m; m.parent() [1.0 2.0 3.0] [4.0 5.0 6.0] [7.0 8.0 9.0] Full MatrixSpace of 3 by 3 dense matrices over Complex Double Field sage: a = matrix([[1,2], [3,4]]) - sage: b = matrix(a.numpy()); b # needs numpy + sage: b = matrix(a.numpy()); b [1 2] [3 4] - sage: a == b # needs numpy + sage: a == b True - sage: c = matrix(a.numpy('float32')); c # needs numpy + sage: c = matrix(a.numpy('float32')); c [1.0 2.0] [3.0 4.0] - sage: matrix(numpy.array([[5]])) # needs numpy + sage: matrix(numpy.array([[5]])) [5] - sage: matrix(numpy.matrix([[5]])) # needs numpy + sage: matrix(numpy.matrix([[5]])) [5] A ring and a numpy array:: diff --git a/src/sage/matrix/matrix_generic_dense.pyx b/src/sage/matrix/matrix_generic_dense.pyx index cdf77388e25..9c16ac3c486 100644 --- a/src/sage/matrix/matrix_generic_dense.pyx +++ b/src/sage/matrix/matrix_generic_dense.pyx @@ -69,12 +69,13 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): We check that the problem related to :trac:`9049` is not an issue any more:: + sage: # needs sage.rings.number_field sage: S. = PolynomialRing(QQ) - sage: F. = QQ.extension(t^4 + 1) # needs sage.rings.number_field - sage: R. = PolynomialRing(F) # needs sage.rings.number_field - sage: M = MatrixSpace(R, 1, 2) # needs sage.rings.number_field + sage: F. = QQ.extension(t^4 + 1) + sage: R. = PolynomialRing(F) + sage: M = MatrixSpace(R, 1, 2) sage: from sage.matrix.matrix_generic_dense import Matrix_generic_dense - sage: Matrix_generic_dense(M, (x, y), True, True) # needs sage.rings.number_field + sage: Matrix_generic_dense(M, (x, y), True, True) [x y] """ ma = MatrixArgs_init(parent, entries) diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index 6db1a5a0411..fbf25fce27e 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -462,7 +462,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): TESTS:: sage: import gc - sage: for i in range(10): # needs sage.libs.pari + sage: for i in range(10): # needs sage.rings.finite_rings ....: A = random_matrix(GF(7),1000,1000) ....: B = random_matrix(Integers(10),1000,1000) ....: C = random_matrix(GF(16007),1000,1000) @@ -508,7 +508,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): [6 5] [4 2] - sage: Matrix(GF(6434383), 2, 2, [-1, int(-2), GF(7)(-3), 1/4]) # needs sage.libs.pari + sage: Matrix(GF(6434383), 2, 2, [-1, int(-2), GF(7)(-3), 1/4]) # needs sage.rings.finite_rings [6434382 6434381] [ 4 1608596] @@ -668,7 +668,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): And for larger modulus:: - sage: A = random_matrix(GF(1009), 51, 5) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(1009), 51, 5) sage: data, version = A._pickle() sage: B = A.parent()(0) sage: B._unpickle(data, version) @@ -1061,8 +1062,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(16007),2,2) # needs sage.libs.pari - sage: B = random_matrix(GF(16007),2,2) # needs sage.libs.pari + sage: A = random_matrix(GF(16007),2,2) # needs sage.rings.finite_rings + sage: B = random_matrix(GF(16007),2,2) # needs sage.rings.finite_rings sage: C = A*B sage: all(C[i, j] == sum(A[i, k]*B[k, j] for k in range(2)) for i in range(2) for j in range(2)) True @@ -1073,7 +1074,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: # needs sage.libs.pari + sage: # needs sage.rings.finite_rings sage: A = random_matrix(GF(15991), 201, 117) sage: B = random_matrix(GF(15991), 117, 195) sage: C = random_matrix(GF(15991), 201, 117) @@ -1088,7 +1089,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(16007), 200, 200) # needs sage.libs.pari + sage: A = random_matrix(GF(16007), 200, 200) # needs sage.rings.finite_rings sage: MS = parent(A) sage: (MS(0) * A) == 0 True @@ -1161,13 +1162,13 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: matrix(v*A) == matrix(v)*A True - sage: A = random_matrix(GF(4796509), 10, 20) # needs sage.libs.pari - sage: v = random_vector(GF(4796509), 10) # needs sage.libs.pari + sage: A = random_matrix(GF(4796509), 10, 20) # needs sage.rings.finite_rings + sage: v = random_vector(GF(4796509), 10) # needs sage.rings.finite_rings sage: matrix(v*A) == matrix(v)*A True sage: A = random_matrix(Integers(16337), 10, 20) - sage: v = random_vector(Integers(16337), 10) # needs sage.libs.pari + sage: v = random_vector(Integers(16337), 10) # needs sage.rings.finite_rings sage: matrix(v*A) == matrix(v)*A True @@ -1214,13 +1215,13 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: matrix(A*v).transpose() == A*matrix(v).transpose() True - sage: A = random_matrix(GF(4796509), 10, 20) # needs sage.libs.pari - sage: v = random_vector(GF(4796509), 20) # needs sage.libs.pari + sage: A = random_matrix(GF(4796509), 10, 20) # needs sage.rings.finite_rings + sage: v = random_vector(GF(4796509), 20) # needs sage.rings.finite_rings sage: matrix(A*v).transpose() == A*matrix(v).transpose() True sage: A = random_matrix(Integers(16337), 10, 20) - sage: v = random_vector(Integers(16337), 20) # needs sage.libs.pari + sage: v = random_vector(Integers(16337), 20) # needs sage.rings.finite_rings sage: matrix(A*v).transpose() == A*matrix(v).transpose() True """ @@ -1290,7 +1291,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(2916337), 7, 7) # needs sage.libs.pari + sage: A = random_matrix(GF(2916337), 7, 7) # needs sage.rings.finite_rings sage: B = copy(A) sage: char_p = A.characteristic_polynomial() sage: char_p(A) == 0 @@ -1332,24 +1333,24 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: A.minimal_polynomial() # needs sage.libs.pari x - sage: A = random_matrix(GF(4198973), 0, 0) # needs sage.libs.pari - sage: A.minimal_polynomial() # needs sage.libs.pari + sage: A = random_matrix(GF(4198973), 0, 0) # needs sage.rings.finite_rings + sage: A.minimal_polynomial() # needs sage.rings.finite_rings 1 - sage: A = random_matrix(GF(4198973), 0, 1) # needs sage.libs.pari - sage: A.minimal_polynomial() # needs sage.libs.pari + sage: A = random_matrix(GF(4198973), 0, 1) # needs sage.rings.finite_rings + sage: A.minimal_polynomial() # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix must be square - sage: A = random_matrix(GF(4198973), 1, 0) # needs sage.libs.pari - sage: A.minimal_polynomial() # needs sage.libs.pari + sage: A = random_matrix(GF(4198973), 1, 0) # needs sage.rings.finite_rings + sage: A.minimal_polynomial() # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix must be square - sage: A = matrix(GF(4198973), 10, 10) # needs sage.libs.pari - sage: A.minimal_polynomial() # needs sage.libs.pari + sage: A = matrix(GF(4198973), 10, 10) # needs sage.rings.finite_rings + sage: A.minimal_polynomial() # needs sage.rings.finite_rings x sage: A = Mat(GF(7),3,3)([0, 1, 2] * 3) @@ -1444,7 +1445,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(1214471), 10, 10) # needs sage.libs.pari + sage: A = random_matrix(GF(1214471), 10, 10) # needs sage.rings.finite_rings sage: B = copy(A) sage: min_p = A.minimal_polynomial(proof=True) sage: min_p(A) == 0 @@ -1480,24 +1481,24 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(2535919), 0, 0) # needs sage.libs.pari - sage: A.minimal_polynomial() # needs sage.libs.pari + sage: A = random_matrix(GF(2535919), 0, 0) # needs sage.rings.finite_rings + sage: A.minimal_polynomial() # needs sage.rings.finite_rings 1 - sage: A = random_matrix(GF(2535919), 0, 1) # needs sage.libs.pari - sage: A.minimal_polynomial() # needs sage.libs.pari + sage: A = random_matrix(GF(2535919), 0, 1) # needs sage.rings.finite_rings + sage: A.minimal_polynomial() # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix must be square - sage: A = random_matrix(GF(2535919), 1, 0) # needs sage.libs.pari - sage: A.minimal_polynomial() # needs sage.libs.pari + sage: A = random_matrix(GF(2535919), 1, 0) # needs sage.rings.finite_rings + sage: A.minimal_polynomial() # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matrix must be square - sage: A = matrix(GF(2535919), 10, 10) # needs sage.libs.pari - sage: A.minimal_polynomial() # needs sage.libs.pari + sage: A = matrix(GF(2535919), 10, 10) # needs sage.rings.finite_rings + sage: A.minimal_polynomial() # needs sage.rings.finite_rings x EXAMPLES:: @@ -1640,7 +1641,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(16007), 10, 20) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(16007), 10, 20) sage: E = A.echelon_form() sage: A.row_space() == E.row_space() True @@ -1657,7 +1659,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): Parallel computation:: - sage: A = random_matrix(GF(65521),100,200) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(65521),100,200) sage: Parallelism().set('linbox', nproc=2) sage: E = A.echelon_form() sage: Parallelism().set('linbox', nproc=1) # switch off parallelization @@ -1688,16 +1691,18 @@ cdef class Matrix_modn_dense_template(Matrix_dense): [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] - sage: A = random_matrix(GF(16007), 0, 10) # needs sage.libs.pari + + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(16007), 0, 10) sage: A.echelon_form() [] - sage: A = random_matrix(GF(16007), 10, 0) # needs sage.libs.pari + sage: A = random_matrix(GF(16007), 10, 0) sage: A.echelon_form() [] - sage: A = random_matrix(GF(16007), 0, 0) # needs sage.libs.pari + sage: A = random_matrix(GF(16007), 0, 0) sage: A.echelon_form() [] - sage: A = matrix(GF(16007), 10, 10) # needs sage.libs.pari + sage: A = matrix(GF(16007), 10, 10) sage: A.echelon_form() [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] @@ -2127,7 +2132,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): :: - sage: A = random_matrix(GF(16007), 100, 100) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(16007), 100, 100) sage: B = copy(A) sage: A.rank() 100 @@ -2148,13 +2154,15 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: A = random_matrix(GF(7), 0, 1) sage: A.rank() 0 - sage: A = random_matrix(GF(16007), 0, 0) # needs sage.libs.pari + + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(16007), 0, 0) sage: A.rank() 0 - sage: A = random_matrix(GF(16007), 1, 0) # needs sage.libs.pari + sage: A = random_matrix(GF(16007), 1, 0) sage: A.rank() 0 - sage: A = random_matrix(GF(16007), 0, 1) # needs sage.libs.pari + sage: A = random_matrix(GF(16007), 0, 1) sage: A.rank() 0 """ @@ -2178,49 +2186,49 @@ cdef class Matrix_modn_dense_template(Matrix_dense): EXAMPLES:: sage: s = set() - sage: while s != set(GF(7)): # needs sage.libs.pari + sage: while s != set(GF(7)): ....: A = random_matrix(GF(7), 10, 10) ....: s.add(A.determinant()) :: sage: A = random_matrix(GF(7), 100, 100) - sage: A.determinant() == A.transpose().determinant() # needs sage.libs.pari + sage: A.determinant() == A.transpose().determinant() True sage: B = random_matrix(GF(7), 100, 100) - sage: (A*B).determinant() == A.determinant() * B.determinant() # needs sage.libs.pari + sage: (A*B).determinant() == A.determinant() * B.determinant() True :: - sage: A = random_matrix(GF(16007), 10, 10) # needs sage.libs.pari - sage: A.determinant().parent() is GF(16007) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(16007), 10, 10) + sage: A.determinant().parent() is GF(16007) True :: - sage: A = random_matrix(GF(16007), 100, 100) # needs sage.libs.pari - sage: A.determinant().parent() is GF(16007) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(16007), 100, 100) + sage: A.determinant().parent() is GF(16007) True - - - sage: A.determinant() == A.transpose().determinant() # needs sage.libs.pari + sage: A.determinant() == A.transpose().determinant() True - - sage: B = random_matrix(GF(16007), 100, 100) # needs sage.libs.pari - sage: (A*B).determinant() == A.determinant() * B.determinant() # needs sage.libs.pari + sage: B = random_matrix(GF(16007), 100, 100) + sage: (A*B).determinant() == A.determinant() * B.determinant() True Parallel computation:: - sage: A = random_matrix(GF(65521),200) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(65521),200) sage: B = copy(A) sage: Parallelism().set('linbox', nproc=2) - sage: d = A.determinant() # needs sage.libs.pari + sage: d = A.determinant() sage: Parallelism().set('linbox', nproc=1) # switch off parallelization - sage: e = B.determinant() # needs sage.libs.pari - sage: d==e # needs sage.libs.pari + sage: e = B.determinant() + sage: d==e True TESTS:: @@ -2241,20 +2249,18 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: A = matrix(GF(7), 5, 5); A.det() # needs sage.libs.pari 0 - sage: A = random_matrix(GF(16007), 0, 0); A.det() # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = random_matrix(GF(16007), 0, 0); A.det() 1 - - sage: A = random_matrix(GF(16007), 0, 1); A.det() # needs sage.libs.pari + sage: A = random_matrix(GF(16007), 0, 1); A.det() Traceback (most recent call last): ... ValueError: self must be a square matrix - - sage: A = random_matrix(GF(16007), 1, 0); A.det() # needs sage.libs.pari + sage: A = random_matrix(GF(16007), 1, 0); A.det() Traceback (most recent call last): ... ValueError: self must be a square matrix - - sage: A = matrix(GF(16007), 5, 5); A.det() # needs sage.libs.pari + sage: A = matrix(GF(16007), 5, 5); A.det() 0 """ if self._nrows != self._ncols: @@ -2739,7 +2745,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: A.lift().parent() Full MatrixSpace of 2 by 3 dense matrices over Integer Ring - sage: A = matrix(GF(16007),2,3,[1..6]) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = matrix(GF(16007),2,3,[1..6]) sage: A.lift() [1 2 3] [4 5 6] @@ -3082,15 +3089,14 @@ cdef class Matrix_modn_dense_template(Matrix_dense): sage: bool(A) False - sage: A = matrix(GF(16007), 0, 0) # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: A = matrix(GF(16007), 0, 0) sage: A.is_zero() True - - sage: A = matrix(GF(16007), 1, 0) # needs sage.libs.pari + sage: A = matrix(GF(16007), 1, 0) sage: A.is_zero() True - - sage: A = matrix(GF(16007), 0, 1) # needs sage.libs.pari + sage: A = matrix(GF(16007), 0, 1) sage: A.is_zero() True """ @@ -3110,8 +3116,8 @@ cdef class Matrix_modn_dense_template(Matrix_dense): EXAMPLES:: - sage: M = Matrix(GF(49), 2, [1,2,-2,0]) # needs sage.libs.pari - sage: M.zero_pattern_matrix() # indirect doctest # needs sage.libs.pari + sage: M = Matrix(GF(49), 2, [1,2,-2,0]) # needs sage.rings.finite_rings + sage: M.zero_pattern_matrix() # indirect doctest # needs sage.rings.finite_rings [0 0] [0 1] diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 22bde66b787..e8b4d4d9176 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -267,8 +267,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: sage: pR. = GF(7)[] - - sage: # needs sage.rings.finite_rings sage: M = Matrix([ ....: [ x^3+5*x^2+5*x+1, 5, 6*x+4, 0], ....: [ 6*x^2+3*x+1, 1, 2, 0], @@ -743,7 +741,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: pR. = GF(7)[] sage: A = Matrix(pR, 3, 3, ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], @@ -756,18 +753,18 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: (B*A).truncate(4) == 1 True - sage: A.inverse_series_trunc(0) # needs sage.rings.finite_rings + sage: A.inverse_series_trunc(0) Traceback (most recent call last): ... ValueError: the precision must be positive - sage: A[:2,:].inverse_series_trunc(4) # needs sage.rings.finite_rings + sage: A[:2,:].inverse_series_trunc(4) Traceback (most recent call last): ... ArithmeticError: the input matrix must be square - sage: A[0,:] = A[0,:] - A[0,:](0) + A[1,:](0) + A[2,:](0) # needs sage.rings.finite_rings - sage: A.inverse_series_trunc(4) # needs sage.rings.finite_rings + sage: A[0,:] = A[0,:] - A[0,:](0) + A[1,:](0) + A[2,:](0) + sage: A.inverse_series_trunc(4) Traceback (most recent call last): ... ZeroDivisionError: the constant matrix term self(0) must be invertible @@ -841,7 +838,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: # needs sage.rings.finite_rings + sage: pR. = GF(7)[] sage: A = Matrix(pR, 3, 3, ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], @@ -855,48 +852,48 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: B == X*A % x**4 True - sage: B = Matrix(pR, 2, 3, # needs sage.rings.finite_rings + sage: B = Matrix(pR, 2, 3, ....: [[3*x, x^2 + x + 2, x^2 + 2*x + 3], ....: [ 0, 6*x^2 + 1, 1]]) - sage: A.solve_left_series_trunc(B, 3) # needs sage.rings.finite_rings + sage: A.solve_left_series_trunc(B, 3) [6*x^2 + 2*x + 2 4*x + 3 2*x^2 + 3*x] [3*x^2 + 4*x + 5 4*x^2 + 3 x^2 + 6*x + 3] - sage: X = A.solve_left_series_trunc(B, 37); B == X*A % x**37 # needs sage.rings.finite_rings + sage: X = A.solve_left_series_trunc(B, 37); B == X*A % x**37 True Dimensions of input are checked:: - sage: A.solve_left_series_trunc(B[:,:2], 3) # needs sage.rings.finite_rings + sage: A.solve_left_series_trunc(B[:,:2], 3) Traceback (most recent call last): ... ValueError: number of columns of self must equal number of columns of right-hand side Raises an exception when no solution:: - sage: A[2:,:].solve_left_series_trunc(B, 4) # needs sage.rings.finite_rings + sage: A[2:,:].solve_left_series_trunc(B, 4) Traceback (most recent call last): ... ValueError: matrix equation has no solutions - sage: Ax = x*A; C = vector(pR, [1,1,1]) # needs sage.rings.finite_rings - sage: Ax.solve_left_series_trunc(C, 5) # needs sage.rings.finite_rings + sage: Ax = x*A; C = vector(pR, [1,1,1]) + sage: Ax.solve_left_series_trunc(C, 5) Traceback (most recent call last): ... ValueError: matrix equation has no solutions Supports rectangular and rank-deficient cases:: - sage: A[:,:2].solve_left_series_trunc(B[:,:2], 4) # needs sage.rings.finite_rings + sage: A[:,:2].solve_left_series_trunc(B[:,:2], 4) [5*x^2 + 2*x + 5 5*x + 5 2*x + 4] [5*x^3 + 2*x + 1 2*x^2 + 2*x + 5 4*x^2] - sage: V = Matrix([[3*x^2 + 4*x + 1, 4*x]]) # needs sage.rings.finite_rings - sage: A[:2,:].solve_left_series_trunc(V*A[:2,:], 4) == V # needs sage.rings.finite_rings + sage: V = Matrix([[3*x^2 + 4*x + 1, 4*x]]) + sage: A[:2,:].solve_left_series_trunc(V*A[:2,:], 4) == V True - sage: A[1,:] = (x+1) * A[0,:]; A[2,:] = (x+5) * A[0,:] # needs sage.rings.finite_rings - sage: B = (3*x^3+x^2+2)*A[0,:] # needs sage.rings.finite_rings - sage: A.solve_left_series_trunc(B, 6) # needs sage.rings.finite_rings + sage: A[1,:] = (x+1) * A[0,:]; A[2,:] = (x+5) * A[0,:] + sage: B = (3*x^3+x^2+2)*A[0,:] + sage: A.solve_left_series_trunc(B, 6) [4*x^2 + 6*x + 2 3*x^2 + x 0] .. SEEALSO:: @@ -989,7 +986,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: pR. = GF(7)[] sage: A = Matrix(pR, 3, 3, ....: [[4*x+5, 5*x^2 + x + 1, 4*x^2 + 4], @@ -1003,51 +999,51 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: B == A*X % x**4 True - sage: B = Matrix(pR, 3, 2, # needs sage.rings.finite_rings + sage: B = Matrix(pR, 3, 2, ....: [[5*x^2 + 6*x + 3, 4*x^2 + 6*x + 4], ....: [ x^2 + 4*x + 2, 5*x + 2], ....: [ 5*x + 3, 0]]) - sage: A.solve_right_series_trunc(B, 3) # needs sage.rings.finite_rings + sage: A.solve_right_series_trunc(B, 3) [ 3*x^2 + x + 1 5*x^2 + 4*x + 3] [6*x^2 + 3*x + 1 4*x + 1] [ 6*x^2 + 1 2*x^2 + x + 4] - sage: X = A.solve_right_series_trunc(B, 37); B == A*X % x**37 # needs sage.rings.finite_rings + sage: X = A.solve_right_series_trunc(B, 37); B == A*X % x**37 True Dimensions of input are checked:: - sage: A.solve_right_series_trunc(B[:2,:], 3) # needs sage.rings.finite_rings + sage: A.solve_right_series_trunc(B[:2,:], 3) Traceback (most recent call last): ... ValueError: number of rows of self must equal number of rows of right-hand side Raises an exception when no solution:: - sage: A[:,2:].solve_right_series_trunc(B, 4) # needs sage.rings.finite_rings + sage: A[:,2:].solve_right_series_trunc(B, 4) Traceback (most recent call last): ... ValueError: matrix equation has no solutions - sage: Ax = x*A; C = vector(pR, [1,1,1]) # needs sage.rings.finite_rings - sage: Ax.solve_right_series_trunc(C, 5) # needs sage.rings.finite_rings + sage: Ax = x*A; C = vector(pR, [1,1,1]) + sage: Ax.solve_right_series_trunc(C, 5) Traceback (most recent call last): ... ValueError: matrix equation has no solutions Supports rectangular and rank-deficient cases:: - sage: A[:2,:].solve_right_series_trunc(B[:2,:],4) # needs sage.rings.finite_rings + sage: A[:2,:].solve_right_series_trunc(B[:2,:],4) [ 5*x^2 + 4*x x + 4] [ x^2 + 3*x + 5 3*x^2 + 4*x + 4] [ 5*x + 3 3*x + 2] - sage: V = Matrix([[2*x^2 + 5*x + 1], [3*x^2+4]]) # needs sage.rings.finite_rings - sage: A[:,:2].solve_right_series_trunc(A[:,:2]*V, 4) == V # needs sage.rings.finite_rings + sage: V = Matrix([[2*x^2 + 5*x + 1], [3*x^2+4]]) + sage: A[:,:2].solve_right_series_trunc(A[:,:2]*V, 4) == V True - sage: A[:,1] = (x+1) * A[:,0]; A[:,2] = (x+5) * A[:,0] # needs sage.rings.finite_rings - sage: B = (3*x^3+x^2+2)*A[:,0] # needs sage.rings.finite_rings - sage: A.solve_right_series_trunc(B, 6) # needs sage.rings.finite_rings + sage: A[:,1] = (x+1) * A[:,0]; A[:,2] = (x+5) * A[:,0] + sage: B = (3*x^3+x^2+2)*A[:,0] + sage: A.solve_right_series_trunc(B, 6) [4*x^2 + 6*x + 2] [ 3*x^2 + x] [ 0] @@ -1322,7 +1318,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: pR. = GF(7)[] sage: M = Matrix(pR, 0, 0) sage: M._is_empty_popov() @@ -1330,7 +1325,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: M._is_empty_popov(include_zero_vectors=False) True - sage: # needs sage.rings.finite_rings sage: M = Matrix(pR, 0, 3) sage: M._is_empty_popov(include_zero_vectors=False) True @@ -1897,7 +1891,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: M.is_hermite(row_wise=False, lower_echelon=True) False - sage: # needs sage.rings.finite_rings sage: N = Matrix(pR, [[x+5, 0, 0 ], ....: [2, x^4+6*x^3+4*x+4, 0 ], ....: [3, 3*x^3+6, x^2+5*x+5]]) @@ -1914,7 +1907,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): columns) can be forbidden, and otherwise they should be at the bottom (resp. the right-hand side) of the matrix:: - sage: # needs sage.rings.finite_rings sage: N[:,1:].is_hermite(lower_echelon=True) False sage: N[[1,2,0],1:].is_hermite(lower_echelon=True) @@ -2006,8 +1998,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: M = Matrix(pR, [ ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - - sage: # needs sage.combinat sage.rings.finite_rings sage: P, U = M.weak_popov_form(transformation=True) sage: P [ 4 x^2 6*x^2 + x + 2] @@ -2020,7 +2010,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Demonstrating the ``ordered`` option:: - sage: P.leading_positions() # needs sage.combinat sage.rings.finite_rings + sage: P.leading_positions() # needs sage.combinat [2, 1] sage: PP = M.weak_popov_form(ordered=True); PP [ 2 4*x^2 + 2*x + 4 5] @@ -2047,7 +2037,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [x + 4 6 0] [ 5 1 0] - sage: # needs sage.combinat sage.rings.finite_rings + sage: # needs sage.combinat sage: P, U = M.weak_popov_form(transformation=True, ....: row_wise=False, ....: include_zero_vectors=False) @@ -2294,7 +2284,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): ....: [ 6*x+4, 5*x^3+5*x, 6*x^2+2*x+2], ....: [4*x^2+5*x+2, x^4+5*x^2+2*x+4, 4*x^3+6*x^2+6*x+5]]) - sage: # needs sage.combinat sage.rings.finite_rings + sage: # needs sage.combinat sage: P, U = M.popov_form(transformation=True) sage: P [ 4 x^2 + 4*x + 1 3] @@ -2307,7 +2297,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Demonstrating shifts and specific case of Hermite form:: - sage: # needs sage.combinat sage.rings.finite_rings + sage: # needs sage.combinat sage: P = M.popov_form(shifts=[0,2,4]); P [ 4*x^2 + 3*x + 4 x^4 + 3*x^3 + 5*x^2 + 5*x + 5 0] [ 6 5*x^2 + 6*x + 5 1] @@ -2330,7 +2320,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [x + 2 6 0] [ 0 1 0] - sage: # needs sage.combinat sage.rings.finite_rings + sage: # needs sage.combinat sage: P, U = M.popov_form(transformation=True, ....: row_wise=False, ....: include_zero_vectors=False) @@ -2483,7 +2473,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: pR. = GF(3)[] sage: A = matrix(pR, 3, [x, x^2, x^3, ....: x^2, x^1, 0, @@ -2507,17 +2496,17 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): `R` has a single non-zero entry and that entry is a scalar multiple of the greatest-common-divisor of the entries of the matrix:: - sage: A = matrix([[x*(x-1)*(x+1)], [x*(x-2)*(x+2)], [x]]) # needs sage.rings.finite_rings - sage: R = A.reduced_form() # needs sage.rings.finite_rings - sage: R # needs sage.rings.finite_rings + sage: A = matrix([[x*(x-1)*(x+1)], [x*(x-2)*(x+2)], [x]]) + sage: R = A.reduced_form() + sage: R [x] [0] [0] A zero matrix is already reduced:: - sage: A = matrix(pR, 2, [0,0,0,0]) # needs sage.rings.finite_rings - sage: A.reduced_form() # needs sage.rings.finite_rings + sage: A = matrix(pR, 2, [0,0,0,0]) + sage: A.reduced_form() [0 0] [0 0] @@ -2594,7 +2583,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: M. = GF(7)[] sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2]) sage: A.hermite_form() @@ -2657,7 +2645,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): EXAMPLES:: - sage: # needs sage.rings.finite_rings sage: pR. = GF(7)[] sage: A = Matrix(pR, 3, 2, ....: [[ 3*x^3 + 3*x, 2*x^3 + 4], @@ -2677,7 +2664,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: A == B*Q+R and all(rdegR[i] < rdegB[i] for i in range(3)) True - sage: A[:2,:].left_quo_rem(B) # needs sage.rings.finite_rings + sage: A[:2,:].left_quo_rem(B) Traceback (most recent call last): ... ValueError: row dimension of self should be the row dimension of @@ -2687,7 +2674,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): no quotient and remainder (unless the matrix has full row rank, see :meth:`right_quo_rem`):: - sage: # needs sage.rings.finite_rings sage: Q, R = A[:2,:].left_quo_rem(B[:2,:]); Q, R ( [ 3*x + 3 2*x + 1] @@ -2700,7 +2686,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: all([rdegR[i] < rdegB[i] for i in range(len(rdegR))]) True - sage: A.left_quo_rem(B[:,:2]) # needs sage.rings.finite_rings + sage: A.left_quo_rem(B[:,:2]) Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder @@ -2758,8 +2744,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: A = Matrix(pR, 2, 3, ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 3, 3, ....: [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], ....: [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], @@ -2779,7 +2763,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): ValueError: column dimension of self should be the column dimension of the input matrix - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 3, 3, ....: [[3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], ....: [x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], @@ -2801,7 +2784,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): With a nonsingular but also non-reduced matrix, there exists a solution, but it might not be unique:: - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 3, 3, ....: [[ 5, 0, 2*x + 6], ....: [ 4*x, 3*x^2 + 4*x + 5, x + 1], @@ -2826,7 +2808,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: R2 = Matrix(pR, 2, 3, ....: [[ 5*x, 3*x + 4, 5], ....: [4*x + 6, 5*x, 4]]) - sage: A == Q2*B + R2 # needs sage.rings.finite_rings + sage: A == Q2*B + R2 True The same remark holds more generally for full column rank matrices: @@ -2834,8 +2816,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): other cases (rank-deficient matrix `B` or matrix `B` having strictly fewer rows than columns) there may be no solution:: - sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # needs sage.rings.finite_rings - sage: Q, R = A.right_quo_rem(C); Q, R # needs sage.rings.finite_rings + sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank + sage: Q, R = A.right_quo_rem(C); Q, R ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1 0] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2 0], @@ -2844,13 +2826,13 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 6*x + 3 5*x^2 + 6 3] ) - sage: A.right_quo_rem(B[:2,:]) # matrix 2 x 3, full row rank # needs sage.rings.finite_rings + sage: A.right_quo_rem(B[:2,:]) # matrix 2 x 3, full row rank Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder with the required degree property - sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # needs sage.rings.finite_rings - sage: A.right_quo_rem(D) # needs sage.rings.finite_rings + sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular + sage: A.right_quo_rem(D) Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder @@ -2861,7 +2843,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): remainder, in which case this method will find it via normal form computation:: - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 1, 2, [[x, x]]) sage: A = Matrix(pR, 1, 2, [[x, x+2]]) sage: A.right_quo_rem(B) @@ -2918,8 +2899,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: A = Matrix(pR, 2, 3, ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 3, 3, ....: [[4*x^2 + 3*x + 3, 3*x^2 + 3*x + 1, 4*x^2 + x + 4], ....: [6*x^2 + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], @@ -2934,7 +2913,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: A == Q*B+R and R.degree() < 2 True - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 3, 3, ....: [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], ....: [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], @@ -2999,8 +2977,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: A = Matrix(pR, 2, 3, ....: [[3*x^3 + 3*x, 3*x^3 + 6*x + 5, 2*x^3 + 2*x + 6], ....: [2*x^3 + 4, 6*x^3 + 5*x^2 + 1, 3*x^2 + 2*x + 2]]) - - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 3, 3, ....: [[4*x + 3*x + 3, 3*x^3 + 3*x + 1, 4*x^2 + x + 4], ....: [6*x + 2*x + 3, 4*x^2 + 3*x, 3*x^2 + 4*x], @@ -3022,7 +2998,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): With a nonsingular but also non-reduced matrix, there exists a solution and one is found by this method, but it might not be unique:: - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 3, 3, ....: [[ 5, 0, 2*x + 6], ....: [ 4*x, 3*x^2 + 4*x + 5, x + 1], @@ -3047,7 +3022,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: R2 = Matrix(pR, 2, 3, ....: [[ 5*x, 3*x + 4, 5], ....: [4*x + 6, 5*x, 4]]) - sage: A == Q2*B + R2 # needs sage.rings.finite_rings + sage: A == Q2*B + R2 True The same remark holds more generally for full column rank matrices: @@ -3055,8 +3030,8 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): other cases (rank-deficient or strictly fewer rows than columns) there might be no solution:: - sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank # needs sage.rings.finite_rings - sage: Q, R = A._right_quo_rem_solve(C); Q, R # needs sage.rings.finite_rings + sage: C = B.stack(B[1,:] + B[2,:]) # 4 x 3, full column rank + sage: Q, R = A._right_quo_rem_solve(C); Q, R ( [ 6*x^2 + 3*x 4*x^2 + 3*x + 1 5*x + 1 0] [ x^2 + 5*x + 5 5*x^2 + 3*x + 5 x + 2 0], @@ -3065,12 +3040,12 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): [ 6*x + 3 5*x^2 + 6 3] ) - sage: A._right_quo_rem_solve(B[:2,:]) # 2 x 3, full row rank # needs sage.rings.finite_rings + sage: A._right_quo_rem_solve(B[:2,:]) # 2 x 3, full row rank Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution - sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular # needs sage.rings.finite_rings - sage: A._right_quo_rem_solve(D) # needs sage.rings.finite_rings + sage: D = copy(B); D[2,:] = B[0,:]+B[1,:] # square, singular + sage: A._right_quo_rem_solve(D) Traceback (most recent call last): ... ValueError: dividing via system solving yields no solution @@ -3079,7 +3054,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): columns), even when there is a solution, this method might not find it:: - sage: # needs sage.rings.finite_rings sage: B = Matrix(pR, 1, 2, [[x, x]]) sage: A = Matrix(pR, 1, 2, [[x, x+2]]) sage: A == 1*B + Matrix([[0,2]]) # a valid quo_rem @@ -3172,7 +3146,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: A = Matrix(pR, 1, 3, [ ....: [3*x^4+3*x^3+4*x^2+5*x+1, x^4+x^3+5*x^2+4*x+4, 4*x^4+2*x^3+x]]) - sage: # needs sage.rings.finite_rings sage: Q, R = A.reduce(B,return_quotient=True); R [3*x^4 + 3*x^3 + 4*x + 3 2*x + 2 2*x + 6] sage: A == Q*B + R @@ -3191,7 +3164,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Demonstrating shifts:: - sage: # needs sage.rings.finite_rings sage: Qs, Rs = A.reduce(B, shifts=[0,2,4], return_quotient=True); Rs [3*x^4 + 3*x^3 + 6*x + 2 4*x^3 + 5*x 0] sage: A == Qs*B + Rs @@ -3206,14 +3178,13 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): If ``return_quotient`` is ``False``, only the normal form is returned:: - sage: R == A.reduce(B) and Rs == A.reduce(B, shifts=[0,2,4]) # needs sage.rings.finite_rings + sage: R == A.reduce(B) and Rs == A.reduce(B, shifts=[0,2,4]) True Demonstrating column-wise normal forms, with a matrix `A` which has several columns, and a matrix `B` which does not have full column rank (its column-wise Popov form has a zero column):: - sage: # needs sage.rings.finite_rings sage: A = Matrix(pR, 2, 2, ....: [[5*x^3 + 2*x^2 + 4*x + 1, x^3 + 4*x + 4], ....: [2*x^3 + 5*x^2 + 2*x + 4, 2*x^3 + 3*x + 2]]) @@ -3332,7 +3303,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): We consider the following example from [Arne Storjohann, Notes on computing minimal approximant bases, 2006]:: - sage: # needs sage.rings.finite_rings sage: order = 8; shifts = [1,1,0,0,0] sage: pmat = Matrix(pR, 5, 1, [ ....: pR([35, 0, 41, 87, 3, 42, 22, 90]), @@ -3356,7 +3326,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): contained in the set of approximants for ``pmat`` at order 8:: sage: M = x^8 * Matrix.identity(pR, 5) - sage: M.is_minimal_approximant_basis(pmat, 8) # needs sage.rings.finite_rings + sage: M.is_minimal_approximant_basis(pmat, 8) False Since ``pmat`` is a single column, with nonzero constant coefficient, @@ -3364,26 +3334,26 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): matrices `[c x^8]` for some nonzero field element `c`:: sage: M = Matrix(pR, [x^8]) - sage: M.is_minimal_approximant_basis( # needs sage.rings.finite_rings + sage: M.is_minimal_approximant_basis( ....: pmat, 8, row_wise=False, normal_form=True) True Exceptions are raised if input dimensions are not sound:: - sage: appbas.is_minimal_approximant_basis(pmat, [8,8], shifts) # needs sage.rings.finite_rings + sage: appbas.is_minimal_approximant_basis(pmat, [8,8], shifts) Traceback (most recent call last): ... ValueError: order length should be the column dimension of the input matrix - sage: appbas.is_minimal_approximant_basis( # needs sage.rings.finite_rings + sage: appbas.is_minimal_approximant_basis( ....: pmat, order, shifts, row_wise=False) Traceback (most recent call last): ... ValueError: shifts length should be the column dimension of the input matrix - sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, 8) # needs sage.rings.finite_rings + sage: Matrix(pR, [x^8]).is_minimal_approximant_basis(pmat, 8) Traceback (most recent call last): ... ValueError: column dimension should be the row dimension of the @@ -3697,7 +3667,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): This method supports any number of columns or rows, as well as arbitrary shifts and orders:: - sage: # needs sage.rings.finite_rings sage: order = [4, 1, 2]; shifts = [-3, 4] sage: pmat = Matrix(pR, [[5*x^3 + 4*x^2 + 4*x + 6, 5, 4], ....: [2*x^3 + 2*x^2 + 2*x + 3, 6, 6*x + 3]]) @@ -3708,7 +3677,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): The returned list is the shifted row degrees of ``appbas``:: - sage: rdeg == appbas.row_degrees(shifts) # needs sage.rings.finite_rings + sage: rdeg == appbas.row_degrees(shifts) True Approximant bases for the zero matrix are all constant unimodular diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index ada66d6a2ce..bdb3cf865bf 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -1,4 +1,3 @@ - r""" Base class for sparse matrices """ @@ -672,13 +671,15 @@ cdef class Matrix_sparse(matrix.Matrix): EXAMPLES:: sage: m = matrix(ZZ, 10000, {(1,2): 17}, sparse=True) - sage: k. = GF(9) # needs sage.rings.finite_rings + + sage: # needs sage.rings.finite_rings + sage: k. = GF(9) sage: f = lambda x: k(x) - sage: n = m.apply_map(f) # needs sage.rings.finite_rings - sage: n.parent() # needs sage.rings.finite_rings + sage: n = m.apply_map(f) + sage: n.parent() Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field in a of size 3^2 - sage: n[1, 2] # needs sage.rings.finite_rings + sage: n[1, 2] 2 An example where the codomain is explicitly specified. diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index 4ddaee182c7..8bd7e986ced 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -1150,15 +1150,16 @@ def exterior_power(self, n): EXAMPLES:: + sage: # needs sage.groups sage: F = FilteredVectorSpace(1, 1) + FilteredVectorSpace(1, 2); F QQ^2 >= QQ^1 >= 0 - sage: F.exterior_power(1) # needs sage.groups + sage: F.exterior_power(1) QQ^2 >= QQ^1 >= 0 - sage: F.exterior_power(2) # needs sage.groups + sage: F.exterior_power(2) QQ^1 >= 0 - sage: F.exterior_power(3) # needs sage.groups + sage: F.exterior_power(3) 0 - sage: F.wedge(2) # needs sage.groups + sage: F.wedge(2) QQ^1 >= 0 """ return self._power_operation(n, 'antisymmetric') diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index ea4fcdddf11..6401c144dc7 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -111,9 +111,10 @@ def IntegerLattice(basis, lll_reduce=True): We construct an ideal lattice from an element of an absolute order:: - sage: K. = CyclotomicField(17) # needs sage.rings.number_field - sage: O = K.ring_of_integers() # needs sage.rings.number_field - sage: f = O(-a^15 + a^13 + 4*a^12 - 12*a^11 - 256*a^10 + a^9 - a^7 # needs sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = CyclotomicField(17) + sage: O = K.ring_of_integers() + sage: f = O(-a^15 + a^13 + 4*a^12 - 12*a^11 - 256*a^10 + a^9 - a^7 ....: - 4*a^6 + a^5 + 210*a^4 + 2*a^3 - 2*a^2 + 2*a - 2) sage: from sage.modules.free_module_integer import IntegerLattice sage: IntegerLattice(f) @@ -156,11 +157,12 @@ def IntegerLattice(basis, lll_reduce=True): Sage also interfaces with fpylll's lattice generator:: + sage: # needs fpylll sage: from sage.modules.free_module_integer import IntegerLattice - sage: from fpylll import IntegerMatrix # needs fpylll - sage: A = IntegerMatrix.random(8, "simdioph", bits=20, bits2=10) # needs fpylll - sage: A = A.to_matrix(matrix(ZZ, 8, 8)) # needs fpylll - sage: IntegerLattice(A, lll_reduce=False) # needs fpylll + sage: from fpylll import IntegerMatrix + sage: A = IntegerMatrix.random(8, "simdioph", bits=20, bits2=10) + sage: A = A.to_matrix(matrix(ZZ, 8, 8)) + sage: IntegerLattice(A, lll_reduce=False) Free module of degree 8 and rank 8 over Integer Ring User basis matrix: [ 1024 829556 161099 11567 521155 769480 639201 689979] @@ -202,7 +204,8 @@ class FreeModule_submodule_with_basis_integer(FreeModule_submodule_with_basis_pi EXAMPLES:: sage: from sage.modules.free_module_integer import IntegerLattice - sage: L = IntegerLattice(sage.crypto.gen_lattice(type='modular', m=10, seed=1337, dual=True)); L + sage: L = IntegerLattice(sage.crypto.gen_lattice(type='modular', m=10, + ....: seed=1337, dual=True)); L Free module of degree 10 and rank 10 over Integer Ring User basis matrix: [-1 1 2 -2 0 1 0 -1 2 1] @@ -404,22 +407,19 @@ def BKZ(self, *args, **kwds): EXAMPLES:: + sage: # needs sage.libs.flint sage: from sage.modules.free_module_integer import IntegerLattice sage: A = sage.crypto.gen_lattice(type='random', n=1, m=60, q=2^60, seed=42) - sage: L = IntegerLattice(A, lll_reduce=False) # needs sage.libs.flint - sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.libs.flint + sage: L = IntegerLattice(A, lll_reduce=False) + sage: min(v.norm().n() for v in L.reduced_basis) 4.17330740711759e15 - - sage: L.LLL() # needs sage.libs.flint + sage: L.LLL() 60 x 60 dense matrix over Integer Ring (use the '.str()' method to see the entries) - - sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.libs.flint + sage: min(v.norm().n() for v in L.reduced_basis) 5.19615242270663 - - sage: L.BKZ(block_size=10) # needs sage.libs.flint + sage: L.BKZ(block_size=10) 60 x 60 dense matrix over Integer Ring (use the '.str()' method to see the entries) - - sage: min(v.norm().n() for v in L.reduced_basis) # needs sage.libs.flint + sage: min(v.norm().n() for v in L.reduced_basis) 4.12310562561766 .. NOTE:: @@ -655,7 +655,10 @@ def voronoi_cell(self, radius=None): sage: L = IntegerLattice([[1, 0], [0, 1]]) sage: V = L.voronoi_cell() sage: V.Vrepresentation() - (A vertex at (1/2, -1/2), A vertex at (1/2, 1/2), A vertex at (-1/2, 1/2), A vertex at (-1/2, -1/2)) + (A vertex at (1/2, -1/2), + A vertex at (1/2, 1/2), + A vertex at (-1/2, 1/2), + A vertex at (-1/2, -1/2)) The volume of the Voronoi cell is the square root of the discriminant of the lattice:: @@ -667,8 +670,8 @@ def voronoi_cell(self, radius=None): [ 1 -1 2 1] [ -6 0 3 3] [ -6 -24 -6 -5] - sage: V = L.voronoi_cell() # long time - sage: V.volume() # long time + sage: V = L.voronoi_cell() # long time + sage: V.volume() # long time 678 sage: sqrt(L.discriminant()) 678 @@ -678,7 +681,10 @@ def voronoi_cell(self, radius=None): sage: L = IntegerLattice([[2, 0, 0], [0, 2, 0]]) sage: V = L.voronoi_cell() sage: V.Hrepresentation() - (An inequality (-1, 0, 0) x + 1 >= 0, An inequality (0, -1, 0) x + 1 >= 0, An inequality (1, 0, 0) x + 1 >= 0, An inequality (0, 1, 0) x + 1 >= 0) + (An inequality (-1, 0, 0) x + 1 >= 0, + An inequality (0, -1, 0) x + 1 >= 0, + An inequality (1, 0, 0) x + 1 >= 0, + An inequality (0, 1, 0) x + 1 >= 0) ALGORITHM: diff --git a/src/sage/modules/vector_double_dense.pyx b/src/sage/modules/vector_double_dense.pyx index eaab8f6c098..bf49aa2ad3d 100644 --- a/src/sage/modules/vector_double_dense.pyx +++ b/src/sage/modules/vector_double_dense.pyx @@ -7,17 +7,19 @@ Complex Double Field EXAMPLES:: - sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]); v # needs sage.symbolic + sage: # needs sage.symbolic + sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)]); v (1.0 - 1.0*I, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: type(v) # needs sage.symbolic + sage: type(v) - sage: parent(v) # needs sage.symbolic + sage: parent(v) Vector space of dimension 3 over Complex Double Field - sage: v[0] = 5 # needs sage.symbolic - sage: v # needs sage.symbolic + sage: v[0] = 5 + sage: v (5.0, 2.0 + 3.141592653589793*I, 3.0 + 5.0*I) - sage: loads(dumps(v)) == v # needs sage.symbolic + sage: loads(dumps(v)) == v True + sage: v = vector(RDF, [1,2,3,4]); v (1.0, 2.0, 3.0, 4.0) sage: loads(dumps(v)) == v From fc36e24257925f8814c740f93c810b7b9735f1b5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 10 Aug 2023 23:17:08 -0700 Subject: [PATCH 78/99] Use more block tags, update # needs --- src/sage/matrix/matrix0.pyx | 56 ++++---- src/sage/matrix/special.py | 6 +- src/sage/modules/free_module.py | 8 +- src/sage/modules/free_module_morphism.py | 92 ++++++------ src/sage/modules/quotient_module.py | 101 ++++++------- src/sage/modules/torsion_quadratic_module.py | 16 +-- src/sage/modules/vector_modn_dense.pyx | 17 +-- src/sage/modules/vector_space_morphism.py | 136 +++++++++--------- .../modules/with_basis/indexed_element.pyx | 11 +- src/sage/quadratic_forms/quadratic_form.py | 10 +- .../quadratic_form__equivalence_testing.py | 25 ++-- .../quadratic_form__local_field_invariants.py | 13 +- 12 files changed, 257 insertions(+), 234 deletions(-) diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 4657008f6c5..c437b7428cc 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -1926,11 +1926,12 @@ cdef class Matrix(sage.structure.element.Matrix): Prior to :trac:`11544` this could take a full minute to run (2011). :: + sage: # needs sage.rings.number_field sage: A = matrix(QQ, 4, 4, [1, 2, -2, 2, 1, 0, -1, -1, 0, -1, 1, 1, -1, 2, 1/2, 0]) - sage: e = A.eigenvalues()[3] # needs sage.rings.number_field - sage: K = (A - e).kernel() # needs sage.rings.number_field - sage: P = K.basis_matrix() # needs sage.rings.number_field - sage: P.str() # needs sage.rings.number_field + sage: e = A.eigenvalues()[3] + sage: K = (A - e).kernel() + sage: P = K.basis_matrix() + sage: P.str() '[ 1.000000000000000? + 0.?e-17*I -2.116651487479748? + 0.0255565807096352?*I -0.2585224251020429? + 0.2886023409047535?*I -0.4847545623533090? - 1.871890760086142?*I]' Use single-row delimiters where appropriate:: @@ -2946,7 +2947,7 @@ cdef class Matrix(sage.structure.element.Matrix): Traceback (most recent call last): ... TypeError: Multiplying row by Symbolic Ring element cannot be done over - Rational Field, use change_ring or with_added_multiple_of_row instead. + Rational Field, use change_ring or with_added_multiple_of_row instead. """ self.check_row_bounds_and_mutability(i,j) try: @@ -3031,7 +3032,7 @@ cdef class Matrix(sage.structure.element.Matrix): Traceback (most recent call last): ... TypeError: Multiplying column by Symbolic Ring element cannot be done over - Rational Field, use change_ring or with_added_multiple_of_column instead. + Rational Field, use change_ring or with_added_multiple_of_column instead. """ self.check_column_bounds_and_mutability(i,j) try: @@ -3135,7 +3136,8 @@ cdef class Matrix(sage.structure.element.Matrix): sage: a.rescale_row(1,1/2) Traceback (most recent call last): ... - TypeError: Rescaling row by Rational Field element cannot be done over Integer Ring, use change_ring or with_rescaled_row instead. + TypeError: Rescaling row by Rational Field element cannot be done + over Integer Ring, use change_ring or with_rescaled_row instead. To rescale the matrix by 1/2, you must change the base ring to the rationals:: @@ -3249,7 +3251,8 @@ cdef class Matrix(sage.structure.element.Matrix): sage: a.rescale_col(2,1/2) Traceback (most recent call last): ... - TypeError: Rescaling column by Rational Field element cannot be done over Integer Ring, use change_ring or with_rescaled_col instead. + TypeError: Rescaling column by Rational Field element cannot be done + over Integer Ring, use change_ring or with_rescaled_col instead. To rescale the matrix by 1/2, you must change the base ring to the rationals:: @@ -3940,21 +3943,21 @@ cdef class Matrix(sage.structure.element.Matrix): def is_symmetric(self): """ - Return True if this is a symmetric matrix. + Return ``True`` if this is a symmetric matrix. A symmetric matrix is necessarily square. EXAMPLES:: - sage: m=Matrix(QQ,2,range(0,4)) + sage: m = Matrix(QQ, 2, range(0,4)) sage: m.is_symmetric() False - sage: m=Matrix(QQ,2,(1,1,1,1,1,1)) + sage: m = Matrix(QQ, 2, (1,1,1,1,1,1)) sage: m.is_symmetric() False - sage: m=Matrix(QQ,1,(2,)) + sage: m = Matrix(QQ, 1, (2,)) sage: m.is_symmetric() True @@ -4901,7 +4904,7 @@ cdef class Matrix(sage.structure.element.Matrix): Over finite fields:: sage: A = matrix(GF(59), 3, [10,56,39,53,56,33,58,24,55]) - sage: A.multiplicative_order() # needs sage.rings.finite_rings + sage: A.multiplicative_order() # needs sage.groups 580 sage: (A^580).is_one() True @@ -5243,7 +5246,7 @@ cdef class Matrix(sage.structure.element.Matrix): sage: R. = FreeAlgebra(QQ,2) sage: a = matrix(2, 2, [1,2,x*y,y*x]) sage: b = matrix(2, 2, [1,2,y*x,y*x]) - sage: a - b # indirect doctest + sage: a - b # indirect doctest [ 0 0] [x*y - y*x 0] @@ -5316,11 +5319,12 @@ cdef class Matrix(sage.structure.element.Matrix): [ x*y x^2*y x*y^2] [ -x^2*y^2 x^2*y + x*y^2 x^2*y - x*y^2] - sage: R. = FreeAlgebra(ZZ,2) # needs sage.combinat + sage: # needs sage.combinat + sage: R. = FreeAlgebra(ZZ,2) sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a [ 1 x y] [ -x*y x + y x - y] - sage: (x*y) * a # indirect doctest # needs sage.combinat + sage: (x*y) * a # indirect doctest [ x*y x*y*x x*y^2] [ -x*y*x*y x*y*x + x*y^2 x*y*x - x*y^2] """ @@ -5361,11 +5365,12 @@ cdef class Matrix(sage.structure.element.Matrix): [ x*y y^2] [x^2*y y^3] - sage: R. = FreeAlgebra(ZZ,2) # needs sage.combinat - sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a # needs sage.combinat + sage: # needs sage.combinat + sage: R. = FreeAlgebra(ZZ,2) + sage: a = matrix(R, 2, 3, [1,x,y, -x*y,x+y,x-y]); a [ 1 x y] [ -x*y x + y x - y] - sage: a * (x*y) # needs sage.combinat + sage: a * (x*y) [ x*y x^2*y y*x*y] [ -x*y*x*y x^2*y + y*x*y x^2*y - y*x*y] """ @@ -5396,10 +5401,10 @@ cdef class Matrix(sage.structure.element.Matrix): [ 1 -x*y] [ x x + y] [ y x - y] - sage: a*b # indirect doctest + sage: a*b # indirect doctest [ x^2 + y^2 + 1 x^2 + x*y - y^2] [ x^2 + x*y - y^2 x^2*y^2 + 2*x^2 + 2*y^2] - sage: b*a # indirect doctest + sage: b*a # indirect doctest [ x^2*y^2 + 1 -x^2*y - x*y^2 + x -x^2*y + x*y^2 + y] [ -x^2*y - x*y^2 + x 2*x^2 + 2*x*y + y^2 x^2 + x*y - y^2] [ -x^2*y + x*y^2 + y x^2 + x*y - y^2 x^2 - 2*x*y + 2*y^2] @@ -5487,7 +5492,9 @@ cdef class Matrix(sage.structure.element.Matrix): sage: a*v Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 3 dense matrices over Integer Ring' and 'Ambient free module of rank 2 over the principal ideal domain Integer Ring' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 3 dense matrices over Integer Ring' and + 'Ambient free module of rank 2 over the principal ideal domain Integer Ring' This illustrates how coercion works:: @@ -5672,8 +5679,9 @@ cdef class Matrix(sage.structure.element.Matrix): Matrices over p-adics. See :trac:`17272` :: - sage: R = ZpCA(5, 5, print_mode='val-unit') # needs sage.rings.padics - sage: A = matrix(R, 3, 3, [250,2369,1147,106,927,362,90,398,2483]) # needs sage.rings.padics + sage: # needs sage.rings.padics + sage: R = ZpCA(5, 5, print_mode='val-unit') + sage: A = matrix(R, 3, 3, [250,2369,1147,106,927,362,90,398,2483]) sage: A [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 2570b95a316..908d06180f9 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -2449,9 +2449,9 @@ def random_rref_matrix(parent, num_pivots): sage: B = random_matrix(FiniteField(7), 4, 4, ....: algorithm='echelon_form', num_pivots=3); B - [1 0 0 0] - [0 1 0 6] - [0 0 1 4] + [1 0 0 5] + [0 1 0 2] + [0 0 1 6] [0 0 0 0] sage: B.rank() == 3 True diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 82af0741d03..508548f245c 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -2776,7 +2776,7 @@ def coordinate_module(self, V): sage: M = ModularSymbols(54) # needs sage.modular sage: S = M.cuspidal_subspace() # needs sage.modular - sage: K = S.integral_structure(); K + sage: K = S.integral_structure(); K # needs sage.modular Free module of degree 19 and rank 8 over Integer Ring Echelon basis matrix: [ 0 1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] @@ -2786,12 +2786,12 @@ def coordinate_module(self, V): Echelon basis matrix: [ 0 1 1 0 -2 1 -1 1 -1 -2 2 0 0 0 0 0 0 0 0] [ 0 0 3 0 -3 2 -1 2 -1 -4 2 -1 -2 1 2 0 0 -1 1] - sage: K.coordinate_module(L) + sage: K.coordinate_module(L) # needs sage.modular Free module of degree 8 and rank 2 over Integer Ring User basis matrix: [ 1 1 1 -1 1 -1 0 0] [ 0 3 2 -1 2 -1 -1 -2] - sage: K.coordinate_module(L).basis_matrix() * K.basis_matrix() + sage: K.coordinate_module(L).basis_matrix() * K.basis_matrix() # needs sage.modular [ 0 1 1 0 -2 1 -1 1 -1 -2 2 0 0 0 0 0 0 0 0] [ 0 0 3 0 -3 2 -1 2 -1 -4 2 -1 -2 1 2 0 0 -1 1] """ @@ -3816,7 +3816,7 @@ def intersection(self, other): sage: V = L**3 sage: W1 = V.span([[0,w/5,0], [1,0,-1/17]], OL) # needs sage.rings.number_field sage: W2 = V.span([[0,(1-w)/5,0]], OL) # needs sage.rings.number_field - sage: W1.intersection(W2) + sage: W1.intersection(W2) # needs sage.rings.number_field Free module of degree 3 and rank 1 over Maximal Order in Number Field in w with defining polynomial x^2 - x + 2 Echelon basis matrix: diff --git a/src/sage/modules/free_module_morphism.py b/src/sage/modules/free_module_morphism.py index dd7b0ab4803..2dbf903eba8 100644 --- a/src/sage/modules/free_module_morphism.py +++ b/src/sage/modules/free_module_morphism.py @@ -9,12 +9,12 @@ TESTS:: - sage: V = ZZ^2; f = V.hom([V.1,-2*V.0]) + sage: V = ZZ^2; f = V.hom([V.1, -2*V.0]) sage: loads(dumps(f)) Free module morphism defined by the matrix [ 0 1] [-2 0] - Domain: Ambient free module of rank 2 over the principal ideal domain ... + Domain: Ambient free module of rank 2 over the principal ideal domain ... Codomain: Ambient free module of rank 2 over the principal ideal domain ... sage: loads(dumps(f)) == f True @@ -53,7 +53,7 @@ def is_FreeModuleMorphism(x): """ EXAMPLES:: - sage: V = ZZ^2; f = V.hom([V.1,-2*V.0]) + sage: V = ZZ^2; f = V.hom([V.1, -2*V.0]) sage: sage.modules.free_module_morphism.is_FreeModuleMorphism(f) True sage: sage.modules.free_module_morphism.is_FreeModuleMorphism(0) @@ -158,7 +158,7 @@ def _repr_(self): sage: phi Vector space morphism represented by the matrix: 40 x 40 dense matrix over Rational Field - Domain: Vector space of dimension 40 over Rational Field + Domain: Vector space of dimension 40 over Rational Field Codomain: Vector space of dimension 40 over Rational Field The representation displays which side of the vectors the matrix is acting:: @@ -169,14 +169,14 @@ def _repr_(self): [0 1 0] [0 0 1] [1 0 0] - Domain: Ambient free module of rank 3 over the principal ideal domain Integer Ring + Domain: Ambient free module of rank 3 over the principal ideal domain Integer Ring Codomain: Ambient free module of rank 3 over the principal ideal domain Integer Ring sage: h2 = V.hom([V.1, V.2, V.0], side="right"); h2 Free module morphism defined as left-multiplication by the matrix [0 0 1] [1 0 0] [0 1 0] - Domain: Ambient free module of rank 3 over the principal ideal domain Integer Ring + Domain: Ambient free module of rank 3 over the principal ideal domain Integer Ring Codomain: Ambient free module of rank 3 over the principal ideal domain Integer Ring """ r = "Free module morphism defined {}by the matrix\n{!r}\nDomain: {}\nCodomain: {}" @@ -187,13 +187,15 @@ def _repr_(self): def change_ring(self, R): """ - Change the ring over which this morphism is defined. This changes the ring of the - domain, codomain, and underlying matrix. + Change the ring over which this morphism is defined. + + This changes the ring of the domain, codomain, and underlying matrix. EXAMPLES:: - sage: V0 = span([[0,0,1],[0,2,0]],ZZ); V1 = span([[1/2,0],[0,2]],ZZ); W = span([[1,0],[0,6]],ZZ) - sage: h = V0.hom([-3*V1.0-3*V1.1, -3*V1.0-3*V1.1]) + sage: V0 = span([[0,0,1],[0,2,0]], ZZ); V1 = span([[1/2,0],[0,2]], ZZ) + sage: W = span([[1,0],[0,6]], ZZ) + sage: h = V0.hom([-3*V1.0 - 3*V1.1, -3*V1.0 - 3*V1.1]) sage: h.base_ring() Integer Ring sage: h @@ -206,10 +208,10 @@ def change_ring(self, R): Vector space morphism represented by the matrix: [-3 -3] [-3 -3] - Domain: Vector space of degree 3 and dimension 2 over Rational Field - Basis matrix: - [0 1 0] - [0 0 1] + Domain: Vector space of degree 3 and dimension 2 over Rational Field + Basis matrix: + [0 1 0] + [0 0 1] Codomain: Vector space of degree 2 and dimension 2 over Rational Field Basis matrix: [1 0] @@ -218,14 +220,14 @@ def change_ring(self, R): Vector space morphism represented by the matrix: [4 4] [4 4] - Domain: Vector space of degree 3 and dimension 2 over Finite Field of size 7 - Basis matrix: - [0 1 0] - [0 0 1] + Domain: Vector space of degree 3 and dimension 2 over Finite Field of size 7 + Basis matrix: + [0 1 0] + [0 0 1] Codomain: Vector space of degree 2 and dimension 2 over Finite Field of size 7 - Basis matrix: - [1 0] - [0 1] + Basis matrix: + [1 0] + [0 1] """ D = self.domain().change_ring(R) C = self.codomain().change_ring(R) @@ -262,8 +264,9 @@ def inverse_image(self, V): We test computing inverse images between two spaces embedded in different ambient spaces.:: - sage: V0 = span([[0,0,1],[0,2,0]],ZZ); V1 = span([[1/2,0],[0,2]],ZZ); W = span([[1,0],[0,6]],ZZ) - sage: h = V0.hom([-3*V1.0-3*V1.1, -3*V1.0-3*V1.1]) + sage: V0 = span([[0,0,1],[0,2,0]],ZZ); V1 = span([[1/2,0],[0,2]],ZZ) + sage: W = span([[1,0],[0,6]],ZZ) + sage: h = V0.hom([-3*V1.0 - 3*V1.1, -3*V1.0 - 3*V1.1]) sage: h.inverse_image(W) Free module of degree 3 and rank 2 over Integer Ring Echelon basis matrix: @@ -282,7 +285,7 @@ def inverse_image(self, V): We test computing inverse images over the integers:: sage: V = QQ^3; W = V.span_of_basis([[2,2,3],[-1,2,5/3]], ZZ) - sage: phi = W.hom([W.0, W.0-W.1]) + sage: phi = W.hom([W.0, W.0 - W.1]) sage: Z = W.span([2*W.1]); Z Free module of degree 3 and rank 1 over Integer Ring Echelon basis matrix: @@ -395,7 +398,7 @@ def lift(self, x): sage: V = X.span([[2, 0], [0, 8]], ZZ) sage: W = (QQ**1).span([[1/12]], ZZ) sage: f = V.hom([W([1/3]), W([1/2])], W) - sage: l=f.lift([1/3]); l # random + sage: l=f.lift([1/3]); l # random (8, -16) sage: f(l) (1/3) @@ -414,7 +417,6 @@ def lift(self, x): This works for vector spaces, too:: - sage: # needs sage.libs.pari sage: V = VectorSpace(GF(3), 2) sage: W = VectorSpace(GF(3), 3) sage: f = V.hom([W.1, W.1 - W.0]) @@ -441,7 +443,7 @@ def lift(self, x): :: sage: V = QQ^2; m = matrix(2, [1, 1, 0, 1]) - sage: V.hom(m, side="right").lift(V.0+V.1) + sage: V.hom(m, side="right").lift(V.0 + V.1) (0, 1) sage: V.hom(m).lift(V.0+V.1) (1, 0) @@ -489,16 +491,16 @@ def eigenvalues(self, extend=True): sage: V = QQ^3 sage: H = V.endomorphism_ring()([[1,-1,0], [-1,1,1], [0,3,1]]) - sage: H.eigenvalues() # needs sage.rings.number_field + sage: H.eigenvalues() # needs sage.rings.number_field [3, 1, -1] Note the effect of the ``extend`` option:: sage: V = QQ^2 sage: H = V.endomorphism_ring()([[0,-1], [1,0]]) - sage: H.eigenvalues() # needs sage.rings.number_field + sage: H.eigenvalues() # needs sage.rings.number_field [-1*I, 1*I] - sage: H.eigenvalues(extend=False) # needs sage.libs.pari + sage: H.eigenvalues(extend=False) # needs sage.libs.pari [] """ if self.base_ring().is_field(): @@ -526,19 +528,20 @@ def eigenvectors(self, extend=True): EXAMPLES:: + sage: # needs sage.rings.number_field sage: V = (QQ^4).subspace([[0,2,1,4], [1,2,5,0], [1,1,1,1]]) sage: H = (V.Hom(V))(matrix(QQ, [[0,1,0], [-1,0,0], [0,0,3]])) - sage: H.eigenvectors() # needs sage.rings.number_field + sage: H.eigenvectors() [(3, [ (0, 0, 1, -6/7) ], 1), (-1*I, [ (1, 1*I, 0, -0.571428571428572? + 2.428571428571429?*I) ], 1), (1*I, [ (1, -1*I, 0, -0.571428571428572? - 2.428571428571429?*I) ], 1)] - sage: H.eigenvectors(extend=False) # needs sage.rings.number_field + sage: H.eigenvectors(extend=False) [(3, [ (0, 0, 1, -6/7) ], 1)] sage: H1 = (V.Hom(V))(matrix(QQ, [[2,1,0],[0,2,0],[0,0,3]])) - sage: H1.eigenvectors() # needs sage.rings.number_field + sage: H1.eigenvectors() [(3, [ (0, 0, 1, -6/7) ], 1), (2, [ (0, 1, 0, 17/7) ], 2)] - sage: H1.eigenvectors(extend=False) # needs sage.rings.number_field + sage: H1.eigenvectors(extend=False) [(3, [ (0, 0, 1, -6/7) ], 1), (2, [ (0, 1, 0, 17/7) ], 2)] @@ -605,18 +608,18 @@ def eigenspaces(self, extend=True): sage: h = V.hom([[2,1,0], [0,2,0], [0,0,-1]], V) sage: h.eigenspaces() # needs sage.rings.number_field [(-1, Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 0 1]), + Basis matrix: + [0 0 1]), (2, Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [0 1 0])] + Basis matrix: + [0 1 0])] sage: h = V.hom([[2,1,0], [0,2,0], [0,0,2]], V) sage: h.eigenspaces() # needs sage.rings.number_field [(2, Vector space of degree 3 and dimension 2 over Rational Field - Basis matrix: - [0 1 0] - [0 0 1])] + Basis matrix: + [0 1 0] + [0 0 1])] :: @@ -659,7 +662,7 @@ def minimal_polynomial(self,var='x'): [0 1 2] [6 0 3] [2 4 1] - Domain: Vector space of dimension 3 over Finite Field of size 7 + Domain: Vector space of dimension 3 over Finite Field of size 7 Codomain: Vector space of dimension 3 over Finite Field of size 7 sage: H.minpoly() # needs sage.libs.pari @@ -673,7 +676,7 @@ def minimal_polynomial(self,var='x'): [0 0 0] [0 0 0] [0 0 0] - Domain: Vector space of dimension 3 over Finite Field of size 7 + Domain: Vector space of dimension 3 over Finite Field of size 7 Codomain: Vector space of dimension 3 over Finite Field of size 7 """ if self.is_endomorphism(): @@ -693,7 +696,8 @@ class BaseIsomorphism1D(Morphism): sage: V, from_V, to_V = R.free_module(R) sage: from_V Isomorphism morphism: - From: Ambient free module of rank 1 over the integral domain Multivariate Polynomial Ring in x, y over Rational Field + From: Ambient free module of rank 1 over the integral domain + Multivariate Polynomial Ring in x, y over Rational Field To: Multivariate Polynomial Ring in x, y over Rational Field """ def _repr_type(self): diff --git a/src/sage/modules/quotient_module.py b/src/sage/modules/quotient_module.py index 462e44c4165..c50c1d044fc 100644 --- a/src/sage/modules/quotient_module.py +++ b/src/sage/modules/quotient_module.py @@ -163,12 +163,13 @@ def _coerce_map_from_(self, M): sage: Q.coerce_map_from(M) Coercion map: From: Ambient free module of rank 2 over the integral domain - Multivariate Polynomial Ring in x, y, z over Rational Field - To: Quotient module by Submodule of Ambient free module of rank 2 - over the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field - Generated by the rows of the matrix: - [x - y z] - [ y*z x*z] + Multivariate Polynomial Ring in x, y, z over Rational Field + To: Quotient module by Submodule of + Ambient free module of rank 2 over the integral domain + Multivariate Polynomial Ring in x, y, z over Rational Field + Generated by the rows of the matrix: + [x - y z] + [ y*z x*z] """ if isinstance(M, FreeModule_ambient): return (self.base_ring().has_coerce_map_from(M.base_ring()) and @@ -277,7 +278,8 @@ def free_relations(self): sage: NQ = Q.submodule([Q([1, x])]) sage: QNQ = Q / NQ sage: QNQ.free_relations() - Submodule of Ambient free module of rank 2 over the integral domain Multivariate Polynomial Ring in x, y, z over Rational Field + Submodule of Ambient free module of rank 2 over the integral domain + Multivariate Polynomial Ring in x, y, z over Rational Field Generated by the rows of the matrix: [ 1 x] [x - y z] @@ -314,35 +316,35 @@ class FreeModule_ambient_field_quotient(FreeModule_ambient_field): sage: U = V/W; U Vector space quotient V/W of dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I where - V: Vector space of degree 3 and dimension 2 over Number Field in i + V: Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 0 i] - [ 0 1 -2] - W: Vector space of degree 3 and dimension 1 over Number Field in i + Basis matrix: + [ 1 0 i] + [ 0 1 -2] + W: Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I Basis matrix: [ 1 1/3*i 1/3*i] sage: U.V() Vector space of degree 3 and dimension 2 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 0 i] - [ 0 1 -2] + Basis matrix: + [ 1 0 i] + [ 0 1 -2] sage: U.W() Vector space of degree 3 and dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 1/3*i 1/3*i] + Basis matrix: + [ 1 1/3*i 1/3*i] sage: U.quotient_map() Vector space morphism represented by the matrix: [ 1] [3*i] - Domain: Vector space of degree 3 and dimension 2 over Number Field in i - with defining polynomial x^2 + 1 with i = 1*I - Basis matrix: - [ 1 0 i] - [ 0 1 -2] + Domain: Vector space of degree 3 and dimension 2 over Number Field in i + with defining polynomial x^2 + 1 with i = 1*I + Basis matrix: + [ 1 0 i] + [ 0 1 -2] Codomain: Vector space quotient V/W of dimension 1 over Number Field in i with defining polynomial x^2 + 1 with i = 1*I where V: Vector space of degree 3 and dimension 2 over Number Field in i @@ -376,7 +378,7 @@ class FreeModule_ambient_field_quotient(FreeModule_ambient_field): TESTS:: - sage: A = QQ^0; V = A.span([]) # corner case + sage: A = QQ^0; V = A.span([]) # corner case sage: W = A.span([]) sage: U = V/W @@ -442,19 +444,20 @@ def _repr_(self): We create a quotient vector space over a finite field:: - sage: k. = GF(9); A = k^3; V = A.span_of_basis([[1,0,a], [a,a,1]]); W = V.span([V.1]) # needs sage.libs.pari - sage: Q = V/W # needs sage.libs.pari + sage: # needs sage.rings.finite_rings + sage: k. = GF(9); A = k^3; V = A.span_of_basis([[1,0,a], [a,a,1]]); W = V.span([V.1]) + sage: Q = V/W Note the type:: - sage: type(Q) # needs sage.libs.pari + sage: type(Q) # needs sage.rings.finite_rings The string representation mentions that this is a quotient `V/W`, that the quotient has dimension 1 and is over a finite field, and also describes `V` and `W`:: - sage: Q._repr_() # needs sage.libs.pari + sage: Q._repr_() # needs sage.rings.finite_rings 'Vector space quotient V/W of dimension 1 over Finite Field in a of size 3^2 where\nV: Vector space of degree 3 and dimension 2 over Finite Field in a of size 3^2\nUser basis matrix:\n[1 0 a]\n[a a 1]\nW: Vector space of degree 3 and dimension 1 over Finite Field in a of size 3^2\nBasis matrix:\n[ 1 1 a + 2]' """ return "%s space quotient V/W of dimension %s over %s where\nV: %s\nW: %s" % ( @@ -549,23 +552,23 @@ def _coerce_map_from_(self, M): Composite map: From: Ambient free module of rank 2 over the principal ideal domain Integer Ring To: Vector space quotient V/W of dimension 1 over Rational Field where - V: Vector space of dimension 2 over Rational Field - W: Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 2] + V: Vector space of dimension 2 over Rational Field + W: Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [1 2] Defn: Coercion map: From: Ambient free module of rank 2 over the principal ideal domain Integer Ring To: Vector space of dimension 2 over Rational Field then Vector space morphism represented by the matrix: - [ 1] - [-1/2] - Domain: Vector space of dimension 2 over Rational Field - Codomain: Vector space quotient V/W of dimension 1 over Rational Field where - V: Vector space of dimension 2 over Rational Field - W: Vector space of degree 2 and dimension 1 over Rational Field - Basis matrix: - [1 2] + [ 1] + [-1/2] + Domain: Vector space of dimension 2 over Rational Field + Codomain: Vector space quotient V/W of dimension 1 over Rational Field where + V: Vector space of dimension 2 over Rational Field + W: Vector space of degree 2 and dimension 1 over Rational Field + Basis matrix: + [1 2] Make sure :trac:`10513` is fixed (no coercion from an abstract vector space to an isomorphic quotient vector space):: @@ -602,12 +605,12 @@ def quotient_map(self): [ 1 0] [ 0 1] [-1/3 -2/3] - Domain: Vector space of dimension 3 over Rational Field + Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space quotient V/W of dimension 2 over Rational Field where - V: Vector space of dimension 3 over Rational Field - W: Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [1 2 3] + V: Vector space of dimension 3 over Rational Field + W: Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [1 2 3] sage: M.quotient_map()( (QQ^3)([1,2,3]) ) (0, 0) @@ -626,11 +629,11 @@ def lift_map(self): Vector space morphism represented by the matrix: [1 0 0] [0 1 0] - Domain: Vector space quotient V/W of dimension 2 over Rational Field where - V: Vector space of dimension 3 over Rational Field - W: Vector space of degree 3 and dimension 1 over Rational Field - Basis matrix: - [1 2 3] + Domain: Vector space quotient V/W of dimension 2 over Rational Field where + V: Vector space of dimension 3 over Rational Field + W: Vector space of degree 3 and dimension 1 over Rational Field + Basis matrix: + [1 2 3] Codomain: Vector space of dimension 3 over Rational Field """ return self.__lift_map diff --git a/src/sage/modules/torsion_quadratic_module.py b/src/sage/modules/torsion_quadratic_module.py index c01b8ce8be3..b98e6f89c4b 100644 --- a/src/sage/modules/torsion_quadratic_module.py +++ b/src/sage/modules/torsion_quadratic_module.py @@ -854,17 +854,17 @@ def orthogonal_group(self, gens=None, check=False): We compute the kernel of the action of the orthogonal group of `L` on the discriminant group:: - sage: # needs sage.combinat + sage: # needs sage.combinat sage.groups sage: L = IntegralLattice('A4') - sage: O = L.orthogonal_group() # needs sage.groups - sage: D = L.discriminant_group() # needs sage.groups - sage: Obar = D.orthogonal_group(O.gens()) # needs sage.groups - sage: O.order() # needs sage.groups + sage: O = L.orthogonal_group() + sage: D = L.discriminant_group() + sage: Obar = D.orthogonal_group(O.gens()) + sage: O.order() 240 - sage: Obar.order() # needs sage.groups + sage: Obar.order() 2 - sage: phi = O.hom(Obar.gens()) # needs sage.groups - sage: phi.kernel().order() # needs sage.groups + sage: phi = O.hom(Obar.gens()) + sage: phi.kernel().order() 120 """ from sage.groups.fqf_orthogonal import FqfOrthogonalGroup, _isom_fqf diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index 322a3a00f6f..8608672031d 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -81,18 +81,19 @@ TESTS:: Test that :trac:`28042` is fixed:: + sage: # needs sage.rings.finite_rings sage: p = 193379 - sage: K = GF(p) # needs sage.rings.finite_rings - sage: a = K(1) # needs sage.rings.finite_rings - sage: b = K(191495) # needs sage.rings.finite_rings - sage: c = K(109320) # needs sage.rings.finite_rings - sage: d = K(167667) # needs sage.rings.finite_rings + sage: K = GF(p) + sage: a = K(1) + sage: b = K(191495) + sage: c = K(109320) + sage: d = K(167667) sage: e = 103937 - sage: a*c + b*d - e # needs sage.rings.finite_rings + sage: a*c + b*d - e 102041 - sage: vector([a,b]) * vector([c,d]) - e # needs sage.rings.finite_rings + sage: vector([a,b]) * vector([c,d]) - e 102041 - sage: type(vector([a,b]) * vector([c,d])) # needs sage.rings.finite_rings + sage: type(vector([a,b]) * vector([c,d])) AUTHOR: diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 9b86bd457a3..2685462a74e 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -29,7 +29,7 @@ Vector space morphism represented by the matrix: [-1 2 3] [ 4 2 0] - Domain: Vector space of dimension 2 over Rational Field + Domain: Vector space of dimension 2 over Rational Field Codomain: Vector space of dimension 3 over Rational Field sage: phi([2, -3]) (-14, -2, 6) @@ -38,15 +38,16 @@ linear transformation, along with explicit descriptions of the domain and codomain. :: + sage: # needs sage.symbolic sage: F = Integers(13) sage: D = F^3 sage: C = F^2 - sage: x, y, z = var('x y z') # needs sage.symbolic - sage: f(x, y, z) = [2*x + 3*y + 5*z, x + z] # needs sage.symbolic - sage: rho = linear_transformation(D, C, f) # needs sage.symbolic - sage: f(1, 2, 3) # needs sage.symbolic + sage: x, y, z = var('x y z') + sage: f(x, y, z) = [2*x + 3*y + 5*z, x + z] + sage: rho = linear_transformation(D, C, f) + sage: f(1, 2, 3) (23, 4) - sage: rho([1, 2, 3]) # needs sage.symbolic + sage: rho([1, 2, 3]) (10, 4) A "vector space homspace" is the set of all linear transformations @@ -65,7 +66,7 @@ [ 2 -1] [ 4 0] [ 3 7] - Domain: Vector space of dimension 4 over Rational Field + Domain: Vector space of dimension 4 over Rational Field Codomain: Vector space of dimension 2 over Rational Field A homomorphism may also be created via a method on the domain. :: @@ -81,10 +82,10 @@ Vector space morphism represented by the matrix: [ sqrt3 1] [2*sqrt3 2] - Domain: Vector space of dimension 2 over Number Field in sqrt3 - with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? + Domain: Vector space of dimension 2 over Number Field in sqrt3 + with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? Codomain: Vector space of dimension 2 over Number Field in sqrt3 - with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? + with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878? sage: psi([1, 4]) (9*sqrt3, 9) @@ -167,7 +168,7 @@ [0 0 1 0 0 1 0 0 0 1] [0 0 0 1 0 1 1 0 0 0] [0 0 0 0 1 0 1 1 0 0] - Domain: Vector space of dimension 10 over Rational Field + Domain: Vector space of dimension 10 over Rational Field Codomain: Vector space of dimension 10 over Rational Field sage: # needs sage.graphs @@ -189,43 +190,42 @@ [6 6 6 5 4 4 2 1 1 1] [6 6 6 6 5 4 3 1 0 0] [3 3 3 3 3 2 2 1 0 0] - Domain: Vector space of degree 10 and dimension 10 over Rational Field - User basis matrix: - [1 1 0 0 0 0 0 0 0 0] - [0 1 1 0 0 0 0 0 0 0] - [0 0 1 1 0 0 0 0 0 0] - [0 0 0 1 1 0 0 0 0 0] - [0 0 0 0 1 1 0 0 0 0] - [0 0 0 0 0 1 1 0 0 0] - [0 0 0 0 0 0 1 1 0 0] - [0 0 0 0 0 0 0 1 1 0] - [0 0 0 0 0 0 0 0 1 1] - [0 0 0 0 0 0 0 0 0 1] + Domain: Vector space of degree 10 and dimension 10 over Rational Field + User basis matrix: + [1 1 0 0 0 0 0 0 0 0] + [0 1 1 0 0 0 0 0 0 0] + [0 0 1 1 0 0 0 0 0 0] + [0 0 0 1 1 0 0 0 0 0] + [0 0 0 0 1 1 0 0 0 0] + [0 0 0 0 0 1 1 0 0 0] + [0 0 0 0 0 0 1 1 0 0] + [0 0 0 0 0 0 0 1 1 0] + [0 0 0 0 0 0 0 0 1 1] + [0 0 0 0 0 0 0 0 0 1] Codomain: Vector space of degree 10 and dimension 10 over Rational Field - User basis matrix: - [ 1 0 0 0 0 0 0 0 0 0] - [-1 1 0 0 0 0 0 0 0 0] - [ 0 -1 1 0 0 0 0 0 0 0] - [ 0 0 -1 1 0 0 0 0 0 0] - [ 0 0 0 -1 1 0 0 0 0 0] - [ 0 0 0 0 -1 1 0 0 0 0] - [ 0 0 0 0 0 -1 1 0 0 0] - [ 0 0 0 0 0 0 -1 1 0 0] - [ 0 0 0 0 0 0 0 -1 1 0] - [ 0 0 0 0 0 0 0 0 -1 1] + User basis matrix: + [ 1 0 0 0 0 0 0 0 0 0] + [-1 1 0 0 0 0 0 0 0 0] + [ 0 -1 1 0 0 0 0 0 0 0] + [ 0 0 -1 1 0 0 0 0 0 0] + [ 0 0 0 -1 1 0 0 0 0 0] + [ 0 0 0 0 -1 1 0 0 0 0] + [ 0 0 0 0 0 -1 1 0 0 0] + [ 0 0 0 0 0 0 -1 1 0 0] + [ 0 0 0 0 0 0 0 -1 1 0] + [ 0 0 0 0 0 0 0 0 -1 1] An endomorphism is a linear transformation with an equal domain and codomain, and here each needs to have the same basis. We are using a matrix that has well-behaved eigenvalues, as part of showing that these do not change as the representation changes. :: - sage: A = graphs.PetersenGraph().adjacency_matrix() # needs sage.graphs + sage: # needs sage.graphs + sage: A = graphs.PetersenGraph().adjacency_matrix() sage: V = QQ^10 - sage: phi = linear_transformation(V, V, A) # needs sage.graphs - sage: phi.eigenvalues() # needs sage.graphs + sage: phi = linear_transformation(V, V, A) + sage: phi.eigenvalues() [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] - - sage: # needs sage.graphs sage: B1 = [V.gen(i) + V.gen(i+1) for i in range(9)] + [V.gen(9)] sage: C = V.subspace_with_basis(B1) sage: zeta = phi.restrict(C) @@ -241,32 +241,31 @@ [ 0 0 1 0 0 2 -1 1 -1 2] [ 0 0 0 1 0 1 1 0 0 0] [ 0 0 0 0 1 -1 2 -1 1 -1] - Domain: Vector space of degree 10 and dimension 10 over Rational Field - User basis matrix: - [1 1 0 0 0 0 0 0 0 0] - [0 1 1 0 0 0 0 0 0 0] - [0 0 1 1 0 0 0 0 0 0] - [0 0 0 1 1 0 0 0 0 0] - [0 0 0 0 1 1 0 0 0 0] - [0 0 0 0 0 1 1 0 0 0] - [0 0 0 0 0 0 1 1 0 0] - [0 0 0 0 0 0 0 1 1 0] - [0 0 0 0 0 0 0 0 1 1] - [0 0 0 0 0 0 0 0 0 1] + Domain: Vector space of degree 10 and dimension 10 over Rational Field + User basis matrix: + [1 1 0 0 0 0 0 0 0 0] + [0 1 1 0 0 0 0 0 0 0] + [0 0 1 1 0 0 0 0 0 0] + [0 0 0 1 1 0 0 0 0 0] + [0 0 0 0 1 1 0 0 0 0] + [0 0 0 0 0 1 1 0 0 0] + [0 0 0 0 0 0 1 1 0 0] + [0 0 0 0 0 0 0 1 1 0] + [0 0 0 0 0 0 0 0 1 1] + [0 0 0 0 0 0 0 0 0 1] Codomain: Vector space of degree 10 and dimension 10 over Rational Field - User basis matrix: - [1 1 0 0 0 0 0 0 0 0] - [0 1 1 0 0 0 0 0 0 0] - [0 0 1 1 0 0 0 0 0 0] - [0 0 0 1 1 0 0 0 0 0] - [0 0 0 0 1 1 0 0 0 0] - [0 0 0 0 0 1 1 0 0 0] - [0 0 0 0 0 0 1 1 0 0] - [0 0 0 0 0 0 0 1 1 0] - [0 0 0 0 0 0 0 0 1 1] - [0 0 0 0 0 0 0 0 0 1] - - sage: zeta.eigenvalues() # needs sage.graphs + User basis matrix: + [1 1 0 0 0 0 0 0 0 0] + [0 1 1 0 0 0 0 0 0 0] + [0 0 1 1 0 0 0 0 0 0] + [0 0 0 1 1 0 0 0 0 0] + [0 0 0 0 1 1 0 0 0 0] + [0 0 0 0 0 1 1 0 0 0] + [0 0 0 0 0 0 1 1 0 0] + [0 0 0 0 0 0 0 1 1 0] + [0 0 0 0 0 0 0 0 1 1] + [0 0 0 0 0 0 0 0 0 1] + sage: zeta.eigenvalues() [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] Equality @@ -509,7 +508,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): [2 0] [0 5] [1 0] - Domain: Vector space of dimension 3 over Rational Field + Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field sage: phi == rho @@ -683,8 +682,9 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): ValueError: symbolic function must be linear in all the inputs: unable to convert y to a rational - sage: x, y = var('x y') # needs sage.symbolic - sage: f(x, y) = [x, 2*y] # needs sage.symbolic + sage: # needs sage.symbolic + sage: x, y = var('x y') + sage: f(x, y) = [x, 2*y] sage: C = (QQ^2).span([vector(QQ, [1, 1])]) sage: linear_transformation(QQ^2, C, f) Traceback (most recent call last): @@ -830,7 +830,7 @@ def __init__(self, homspace, A, side="left"): [0 1] [2 3] [4 5] - Domain: Vector space of dimension 3 over Rational Field + Domain: Vector space of dimension 3 over Rational Field Codomain: Vector space of dimension 2 over Rational Field See the constructor, diff --git a/src/sage/modules/with_basis/indexed_element.pyx b/src/sage/modules/with_basis/indexed_element.pyx index b47cbd85633..90f7b8ec580 100644 --- a/src/sage/modules/with_basis/indexed_element.pyx +++ b/src/sage/modules/with_basis/indexed_element.pyx @@ -633,7 +633,7 @@ cdef class IndexedFreeModuleElement(ModuleElement): TESTS:: sage: TestSuite(F1).run() - sage: TestSuite(F).run() + sage: TestSuite(F).run() # needs sage.combinat """ cdef IndexedFreeModuleElement elt = other @@ -875,13 +875,14 @@ cdef class IndexedFreeModuleElement(ModuleElement): sage: (3/2)*el 3/2*B[[3, 1, 2]] + sage: # needs sage.combinat sage: P. = QQ['q'] sage: F = FractionField(P) - sage: V = CombinatorialFreeModule(F, Words()) # needs sage.combinat - sage: w = Words()('abc') # needs sage.combinat - sage: (1+q)*V(w) # needs sage.combinat + sage: V = CombinatorialFreeModule(F, Words()) + sage: w = Words()('abc') + sage: (1+q)*V(w) (q+1)*B[word: abc] - sage: ((1+q)/q)*V(w) # needs sage.combinat + sage: ((1+q)/q)*V(w) ((q+1)/q)*B[word: abc] .. TODO:: diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 20ce1c66937..3db01b9fe2f 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -668,12 +668,14 @@ def list_external_initializations(self): sage: Q = QuadraticForm(ZZ, 2, [1,0,5]) sage: Q.list_external_initializations() [] - sage: T = Q.theta_series() # needs sage.libs.pari - sage: Q.list_external_initializations() # needs sage.libs.pari + + sage: # needs sage.libs.pari + sage: T = Q.theta_series() + sage: Q.list_external_initializations() [] - sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=False, # needs sage.libs.pari + sage: Q = QuadraticForm(ZZ, 2, [1,0,5], unsafe_initialization=False, ....: number_of_automorphisms=3, determinant=0) - sage: Q.list_external_initializations() # needs sage.libs.pari + sage: Q.list_external_initializations() [] :: diff --git a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py index 2e817bbecf5..7b109b3dc01 100644 --- a/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py +++ b/src/sage/quadratic_forms/quadratic_form__equivalence_testing.py @@ -55,20 +55,21 @@ def is_globally_equivalent_to(self, other, return_matrix=False): :: + sage: # needs sage.libs.pari sage: Q1 = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) sage: Q2 = QuadraticForm(ZZ, 3, [2, 1, 2, 2, 1, 3]) sage: Q3 = QuadraticForm(ZZ, 3, [8, 6, 5, 3, 4, 2]) - sage: Q1.is_globally_equivalent_to(Q2) # needs sage.libs.pari + sage: Q1.is_globally_equivalent_to(Q2) False - sage: Q1.is_globally_equivalent_to(Q2, return_matrix=True) # needs sage.libs.pari + sage: Q1.is_globally_equivalent_to(Q2, return_matrix=True) False - sage: Q1.is_globally_equivalent_to(Q3) # needs sage.libs.pari + sage: Q1.is_globally_equivalent_to(Q3) True - sage: M = Q1.is_globally_equivalent_to(Q3, True); M # needs sage.libs.pari + sage: M = Q1.is_globally_equivalent_to(Q3, True); M [-1 -1 0] [ 1 1 1] [-1 0 0] - sage: Q1(M) == Q3 # needs sage.libs.pari + sage: Q1(M) == Q3 True :: @@ -189,17 +190,19 @@ def has_equivalent_Jordan_decomposition_at_prime(self, other, p): sage: Q3 = QuadraticForm(ZZ, 3, [1, 0, 0, 1, 0, 11]) sage: [Q1.level(), Q2.level(), Q3.level()] [44, 44, 44] - sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2, 2) # needs sage.libs.pari + + sage: # needs sage.libs.pari + sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2, 2) False - sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2, 11) # needs sage.libs.pari + sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2, 11) False - sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3, 2) # needs sage.libs.pari + sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3, 2) False - sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3, 11) # needs sage.libs.pari + sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3, 11) True - sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3, 2) # needs sage.libs.pari + sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3, 2) True - sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3, 11) # needs sage.libs.pari + sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3, 11) False """ # Sanity Checks diff --git a/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py b/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py index e3d72e2cb37..6380b06e938 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py +++ b/src/sage/quadratic_forms/quadratic_form__local_field_invariants.py @@ -563,18 +563,19 @@ def is_hyperbolic(self, p): EXAMPLES:: + sage: # needs sage.libs.pari sage: Q = DiagonalQuadraticForm(ZZ, [1,1]) - sage: Q.is_hyperbolic(-1) # needs sage.libs.pari + sage: Q.is_hyperbolic(-1) False - sage: Q.is_hyperbolic(2) # needs sage.libs.pari + sage: Q.is_hyperbolic(2) False - sage: Q.is_hyperbolic(3) # needs sage.libs.pari + sage: Q.is_hyperbolic(3) False - sage: Q.is_hyperbolic(5) # Here -1 is a square, so it's true. # needs sage.libs.pari + sage: Q.is_hyperbolic(5) # Here -1 is a square, so it's true. True - sage: Q.is_hyperbolic(7) # needs sage.libs.pari + sage: Q.is_hyperbolic(7) False - sage: Q.is_hyperbolic(13) # Here -1 is a square, so it's true. # needs sage.libs.pari + sage: Q.is_hyperbolic(13) # Here -1 is a square, so it's true. True """ # False for odd-dim'l forms From cb4af4044773245c7461500ec62e51de5713adff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Aug 2023 08:57:16 -0700 Subject: [PATCH 79/99] src/sage/stats/time_series.pyx: More block tags --- src/sage/stats/time_series.pyx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 7c3dbde6b12..8fe93fbb703 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -1058,15 +1058,16 @@ cdef class TimeSeries: EXAMPLES:: + sage: # needs sage.plot sage: v = stats.TimeSeries([5,4,1.3,2,8,10,3,-5]); v [5.0000, 4.0000, 1.3000, 2.0000, 8.0000, 10.0000, 3.0000, -5.0000] - sage: v.plot() # needs sage.plot + sage: v.plot() Graphics object consisting of 1 graphics primitive - sage: v.plot(points=True) # needs sage.plot + sage: v.plot(points=True) Graphics object consisting of 1 graphics primitive - sage: v.plot() + v.plot(points=True, rgbcolor='red') # needs sage.plot + sage: v.plot() + v.plot(points=True, rgbcolor='red') Graphics object consisting of 2 graphics primitives - sage: v.plot() + v.plot(points=True, rgbcolor='red', pointsize=50) # needs sage.plot + sage: v.plot() + v.plot(points=True, rgbcolor='red', pointsize=50) Graphics object consisting of 2 graphics primitives """ from sage.plot.all import line, point From ee025b069f7e6d28ea6c948b164c8a0559760b28 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Aug 2023 09:40:35 -0700 Subject: [PATCH 80/99] src/sage/stats/basic_stats.py: Fix import --- src/sage/stats/basic_stats.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index b18f3dac6f3..bf89b040b11 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -40,6 +40,7 @@ ###################################################################### from sage.rings.integer_ring import ZZ +from sage.misc.lazy_import import lazy_import from sage.misc.functional import sqrt from sage.misc.superseded import deprecation From 33f8c9821bc42b09610017f32e6c1dda1d032a15 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Aug 2023 14:53:08 -0700 Subject: [PATCH 81/99] Use more block tags, update # needs --- src/sage/matrix/matrix1.pyx | 98 ++-- src/sage/matrix/matrix2.pyx | 536 ++++++++++-------- src/sage/matrix/special.py | 47 +- src/sage/modules/free_module.py | 95 ++-- src/sage/modules/free_module_element.pyx | 143 +++-- ...free_quadratic_module_integer_symmetric.py | 40 +- src/sage/quadratic_forms/binary_qf.py | 65 ++- .../quadratic_form__neighbors.py | 26 +- .../quadratic_form__ternary_Tornaria.py | 52 +- .../quadratic_forms/quadratic_form__theta.py | 9 +- src/sage/quadratic_forms/ternary.pyx | 13 +- src/sage/quadratic_forms/ternary_qf.py | 37 +- 12 files changed, 646 insertions(+), 515 deletions(-) diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 0c74c820166..14e8ddc8547 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -96,21 +96,22 @@ cdef class Matrix(Matrix0): EXAMPLES:: + sage: # needs sage.libs.gap sage: A = MatrixSpace(QQ,3,3)([0,1,2,3,4,5,6,7,8]) - sage: g = gap(A) # indirect doctest # needs sage.libs.gap - sage: g # needs sage.libs.gap + sage: g = gap(A) # indirect doctest + sage: g [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ] - sage: g.CharacteristicPolynomial() # needs sage.libs.gap + sage: g.CharacteristicPolynomial() x_1^3-12*x_1^2-18*x_1 - sage: A.characteristic_polynomial() # needs sage.libs.gap + sage: A.characteristic_polynomial() x^3 - 12*x^2 - 18*x - sage: matrix(QQ, g) == A # needs sage.libs.gap + sage: matrix(QQ, g) == A True Particularly difficult is the case of matrices over cyclotomic fields and general number fields. See :trac:`5618` and :trac:`8909`:: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.gap sage.rings.number_field sage: K. = CyclotomicField(8) sage: A = MatrixSpace(K, 2, 2)([0, 1+zeta, 2*zeta, 3]) sage: g = gap(A); g @@ -120,7 +121,7 @@ cdef class Matrix(Matrix0): sage: g.IsMatrix() true - sage: # needs sage.rings.number_field + sage: # needs sage.libs.gap sage.rings.number_field sage: x = polygen(ZZ, 'x') sage: L. = NumberField(x^3 - 2) sage: A = MatrixSpace(L, 2, 2)([0, 1+tau, 2*tau, 3]) @@ -157,7 +158,7 @@ cdef class Matrix(Matrix0): sage: libgap(identity_matrix(ZZ, 2)) # needs sage.libs.gap [ [ 1, 0 ], [ 0, 1 ] ] - sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # needs sage.libs.gap sage.rings.finite_rings + sage: libgap(matrix(GF(3), 2, 2, [4,5,6,7])) # needs sage.libs.gap [ [ Z(3)^0, Z(3) ], [ 0*Z(3), Z(3)^0 ] ] """ from sage.libs.gap.libgap import libgap @@ -301,26 +302,28 @@ cdef class Matrix(Matrix0): We first coerce a square matrix. :: + sage: # optional - magma sage: A = MatrixSpace(QQ,3)([1,2,3,4/3,5/3,6/4,7,8,9]) - sage: B = magma(A); B # (indirect doctest) optional - magma + sage: B = magma(A); B # indirect doctest [ 1 2 3] [4/3 5/3 3/2] [ 7 8 9] - sage: B.Type() # optional - magma + sage: B.Type() AlgMatElt - sage: B.Parent() # optional - magma + sage: B.Parent() Full Matrix Algebra of degree 3 over Rational Field We coerce a non-square matrix over `\ZZ/8\ZZ`. :: + sage: # optional - magma sage: A = MatrixSpace(Integers(8),2,3)([-1,2,3,4,4,-2]) - sage: B = magma(A); B # optional - magma + sage: B = magma(A); B [7 2 3] [4 4 6] - sage: B.Type() # optional - magma + sage: B.Type() ModMatRngElt - sage: B.Parent() # optional - magma + sage: B.Parent() Full RMatrixSpace of 2 by 3 matrices over IntegerRing(8) sage: R. = QQ[] @@ -338,17 +341,17 @@ cdef class Matrix(Matrix0): We coerce a matrix over a cyclotomic field, where the generator must be named during the coercion. :: - sage: K = CyclotomicField(9); z = K.0 # needs sage.rings.number_field - sage: M = matrix(K, 3, 3, [0,1,3,z,z**4,z-1,z**17,1,0]) # needs sage.rings.number_field - sage: M # needs sage.rings.number_field + sage: # optional - magma, needs sage.rings.number_field + sage: K = CyclotomicField(9); z = K.0 + sage: M = matrix(K, 3, 3, [0,1,3,z,z**4,z-1,z**17,1,0]); M [ 0 1 3] [ zeta9 zeta9^4 zeta9 - 1] [-zeta9^5 - zeta9^2 1 0] - sage: magma(M) # optional - magma + sage: magma(M) [ 0 1 3] [ zeta9 zeta9^4 zeta9 - 1] [-zeta9^5 - zeta9^2 1 0] - sage: magma(M**2) == magma(M)**2 # optional - magma + sage: magma(M**2) == magma(M)**2 True One sparse matrix:: @@ -438,7 +441,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: sage: m = matrix(ZZ, [[1,2],[3,4]]) - sage: macaulay2(m) #optional - macaulay2 (indirect doctest) + sage: macaulay2(m) # indirect doctest # optional - macaulay2 | 1 2 | | 3 4 | @@ -446,7 +449,7 @@ cdef class Matrix(Matrix0): sage: R. = QQ[] sage: m = matrix([[x,y],[1+x,1+y]]) - sage: macaulay2(m) #optional - macaulay2 + sage: macaulay2(m) # optional - macaulay2 | x y | | x+1 y+1 | @@ -462,9 +465,9 @@ cdef class Matrix(Matrix0): Check that degenerate matrix dimensions are handled correctly (:trac:`28591`):: - sage: macaulay2(matrix(QQ, 2, 0)).numrows() # optional - macaulay2 + sage: macaulay2(matrix(QQ, 2, 0)).numrows() # optional - macaulay2 2 - sage: macaulay2(matrix(QQ, 0, 2)).numcols() # optional - macaulay2 + sage: macaulay2(matrix(QQ, 0, 2)).numcols() # optional - macaulay2 2 """ if macaulay2 is None: @@ -516,7 +519,7 @@ cdef class Matrix(Matrix0): [1 2 3] [4 5 6] [7 8 9] - sage: b = scilab(a); b # optional - scilab (indirect doctest) + sage: b = scilab(a); b # indirect doctest # optional - scilab 1. 2. 3. 4. 5. 6. 7. 8. 9. @@ -577,14 +580,15 @@ cdef class Matrix(Matrix0): Symbolic matrices are supported:: - sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M # needs sage.symbolic + sage: # needs sympy sage.symbolic + sage: M = matrix([[sin(x), cos(x)], [-cos(x), sin(x)]]); M [ sin(x) cos(x)] [-cos(x) sin(x)] - sage: sM = M._sympy_(); sM # needs sympy sage.symbolic + sage: sM = M._sympy_(); sM Matrix([ [ sin(x), cos(x)], [-cos(x), sin(x)]]) - sage: sM.subs(x, pi/4) # needs sympy sage.symbolic + sage: sM.subs(x, pi/4) Matrix([ [ sqrt(2)/2, sqrt(2)/2], [-sqrt(2)/2, sqrt(2)/2]]) @@ -680,20 +684,21 @@ cdef class Matrix(Matrix0): EXAMPLES:: + sage: # needs numpy sage: a = matrix(3, range(12)) - sage: a.numpy() # needs numpy + sage: a.numpy() array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) - sage: a.numpy('f') # needs numpy + sage: a.numpy('f') array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]], dtype=float32) - sage: a.numpy('d') # needs numpy + sage: a.numpy('d') array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]]) - sage: a.numpy('B') # needs numpy + sage: a.numpy('B') array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], dtype=uint8) @@ -712,15 +717,16 @@ cdef class Matrix(Matrix0): the magic :meth:`__array__` method) to convert Sage matrices to numpy arrays:: - sage: import numpy # needs numpy - sage: b = numpy.array(a); b # needs numpy + sage: # needs numpy + sage: import numpy + sage: b = numpy.array(a); b array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) - sage: b.dtype # needs numpy + sage: b.dtype dtype('int32') # 32-bit dtype('int64') # 64-bit - sage: b.shape # needs numpy + sage: b.shape (3, 4) """ import numpy @@ -762,7 +768,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: M = Matrix(Integers(7), 2, 2, [5, 9, 13, 15]) ; M + sage: M = Matrix(Integers(7), 2, 2, [5, 9, 13, 15]); M [5 2] [6 1] sage: M.lift() @@ -806,7 +812,7 @@ cdef class Matrix(Matrix0): EXAMPLES:: - sage: M = Matrix(Integers(8), 2, 4, range(8)) ; M + sage: M = Matrix(Integers(8), 2, 4, range(8)); M [0 1 2 3] [4 5 6 7] sage: L = M.lift_centered(); L @@ -1106,7 +1112,8 @@ cdef class Matrix(Matrix0): sage: c = a.dense_columns(); c [(x, 2/3*x), (x^2, x^5 + 1)] sage: parent(c[1]) - Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 2 over the principal ideal domain + Univariate Polynomial Ring in x over Rational Field TESTS: @@ -1640,7 +1647,8 @@ cdef class Matrix(Matrix0): [ 1 2/3] [ y y^2] sage: C.parent() - Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in y over Rational Field + Full MatrixSpace of 2 by 2 dense matrices over + Univariate Polynomial Ring in y over Rational Field Stacking a dense matrix atop a sparse one returns a sparse matrix:: @@ -1911,7 +1919,8 @@ cdef class Matrix(Matrix0): sage: C = B.augment(A); C [ y y^2 1 2] sage: C.parent() - Full MatrixSpace of 1 by 4 dense matrices over Univariate Polynomial Ring in y over Rational Field + Full MatrixSpace of 1 by 4 dense matrices over + Univariate Polynomial Ring in y over Rational Field sage: D = A.augment(B) Traceback (most recent call last): @@ -1922,7 +1931,8 @@ cdef class Matrix(Matrix0): sage: F = E.augment(B); F [ 1 2 y y^2] sage: F.parent() - Full MatrixSpace of 1 by 4 dense matrices over Univariate Polynomial Ring in y over Rational Field + Full MatrixSpace of 1 by 4 dense matrices over + Univariate Polynomial Ring in y over Rational Field AUTHORS: @@ -2098,8 +2108,8 @@ cdef class Matrix(Matrix0): INPUT: - * ``drows`` - list of indices of rows to be deleted from self. - * ``check`` - checks whether any index in ``drows`` is out of range. Defaults to ``True``. + * ``drows`` -- list of indices of rows to be deleted from ``self``. + * ``check`` -- (boolean, default: ``True``); whether to check if any index in ``drows`` is out of range. .. SEEALSO:: @@ -2161,7 +2171,7 @@ cdef class Matrix(Matrix0): def matrix_from_rows_and_columns(self, rows, columns): """ - Return the matrix constructed from self from the given rows and + Return the matrix constructed from ``self`` from the given rows and columns. EXAMPLES:: diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 7fadf4fdc46..35a161b16ba 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -594,28 +594,29 @@ cdef class Matrix(Matrix1): Solving some systems over `\ZZ/n\ZZ`:: + sage: # needs sage.libs.pari sage: A = Matrix(Zmod(6), 3, 2, [1,2,3,4,5,6]) sage: B = vector(Zmod(6), [1,1,1]) - sage: A.solve_right(B) # needs sage.libs.pari + sage: A.solve_right(B) (5, 1) sage: B = vector(Zmod(6), [5,1,1]) - sage: A.solve_right(B) # needs sage.libs.pari + sage: A.solve_right(B) Traceback (most recent call last): ... ValueError: matrix equation has no solutions sage: A = Matrix(Zmod(128), 2, 3, [23,11,22,4,1,0]) sage: B = Matrix(Zmod(128), 2, 1, [1,0]) - sage: A.solve_right(B) # needs sage.libs.pari + sage: A.solve_right(B) [ 5] [108] [127] sage: B = B.column(0) - sage: A.solve_right(B) # needs sage.libs.pari + sage: A.solve_right(B) (5, 108, 127) sage: A = Matrix(Zmod(15), 3,4, range(12)) sage: B = Matrix(Zmod(15), 3,3, range(3,12)) - sage: X = A.solve_right(B) # needs sage.libs.pari - sage: A*X == B # needs sage.libs.pari + sage: X = A.solve_right(B) + sage: A*X == B True Solving a system over the p-adics:: @@ -2245,13 +2246,13 @@ cdef class Matrix(Matrix1): sage: R. = LaurentPolynomialRing(S) sage: MS = MatrixSpace(S, 3, sparse=True) sage: A = MS([[x, y, 3], [4, 2+y, x^2], [0, 1-x, x+y]]) - sage: A.det() # needs sage.rings.finite_rings + sage: A.det() x^4 - x^3 + x^2*y + x*y^2 + 2*x^2 - 2*x*y + 3*y^2 + 2*x - 2 - sage: A.quantum_determinant() # needs sage.rings.finite_rings + sage: A.quantum_determinant() (2*x - 2)*q^2 + (x^4 - x^3 + 3*x*y + 3*y^2)*q + x^2*y + x*y^2 + 2*x^2 + 2*x*y - sage: A.quantum_determinant(int(2)) # needs sage.rings.finite_rings + sage: A.quantum_determinant(int(2)) 2*x^4 - 2*x^3 + x^2*y + x*y^2 + 2*x^2 + x*y - y^2 + x - 1 - sage: A.quantum_determinant(q*x + q^-1*y) # needs sage.rings.finite_rings + sage: A.quantum_determinant(q*x + q^-1*y) (2*x*y^2 - 2*y^2)*q^-2 + (x^4*y - x^3*y + 3*x*y^2 + 3*y^3)*q^-1 + (-2*x^2*y + x*y^2 + 2*x^2 - 2*x*y) + (x^5 - x^4 + 3*x^2*y + 3*x*y^2)*q + (2*x^3 - 2*x^2)*q^2 @@ -2979,12 +2980,13 @@ cdef class Matrix(Matrix1): Here is an example over a number field:: + sage: # needs sage.rings.number_field sage: x = QQ['x'].gen() - sage: K. = NumberField(x^2 - 2) # needs sage.rings.number_field - sage: m = matrix(K, [[a-1, 2], [a, a+1]]) # needs sage.rings.number_field - sage: m.charpoly('Z') # needs sage.rings.number_field + sage: K. = NumberField(x^2 - 2) + sage: m = matrix(K, [[a-1, 2], [a, a+1]]) + sage: m.charpoly('Z') Z^2 - 2*a*Z - 2*a + 1 - sage: m.charpoly('a')(m) == 0 # needs sage.rings.number_field + sage: m.charpoly('a')(m) == 0 True Over integers modulo `n` with composite `n`:: @@ -2999,8 +3001,8 @@ cdef class Matrix(Matrix1): computation of the characteristic polynomial succeeds as follows:: sage: R. = QQ[] - sage: S. = R.quo((b^3)) # needs sage.rings.function_field - sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) # needs sage.rings.function_field + sage: S. = R.quo((b^3)) + sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) sage: A [ x*y^2 2*x] [ 2 x^10*y] @@ -3138,8 +3140,8 @@ cdef class Matrix(Matrix1): Test that :trac:`27937` is fixed:: - sage: R = FreeAbelianMonoid('u,v').algebra(QQ) # needs sage.groups - sage: matrix(4, 4, lambda i, j: R.an_element())._charpoly_df() # needs sage.groups + sage: R = FreeAbelianMonoid('u,v').algebra(QQ) # needs sage.combinat + sage: matrix(4, 4, lambda i, j: R.an_element())._charpoly_df() # needs sage.combinat B[1]*x^4 - 4*B[u]*x^3 .. NOTE:: @@ -3717,36 +3719,36 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.pari sage.rings.number_field sage: Q = QuadraticField(-7) sage: a = Q.gen(0) sage: A = matrix(Q, [[ 2, 5 - a, 15 - a], ....: [2 + a, a, -7 + 5*a]]) - sage: result = A._right_kernel_matrix_over_number_field() # needs sage.libs.pari - sage: result[0] # needs sage.libs.pari + sage: result = A._right_kernel_matrix_over_number_field() + sage: result[0] 'pivot-pari-numberfield' - sage: P = result[1]; P # needs sage.libs.pari + sage: P = result[1]; P [-a -3 1] - sage: A * P.transpose() == zero_matrix(Q, 2, 1) # needs sage.libs.pari + sage: A * P.transpose() == zero_matrix(Q, 2, 1) True TESTS: We test some trivial cases. :: - sage: # needs sage.rings.number_field + sage: # needs sage.libs.pari sage.rings.number_field sage: Q = QuadraticField(-7) sage: A = matrix(Q, 0, 2) - sage: A._right_kernel_matrix_over_number_field()[1] # needs sage.libs.pari + sage: A._right_kernel_matrix_over_number_field()[1] [1 0] [0 1] - sage: A = matrix(Q, 2, 0) # needs sage.libs.pari - sage: A._right_kernel_matrix_over_number_field()[1].parent() # needs sage.libs.pari + sage: A = matrix(Q, 2, 0) + sage: A._right_kernel_matrix_over_number_field()[1].parent() Full MatrixSpace of 0 by 0 dense matrices over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I - sage: A = zero_matrix(Q, 4, 3) # needs sage.libs.pari - sage: A._right_kernel_matrix_over_number_field()[1] # needs sage.libs.pari + sage: A = zero_matrix(Q, 4, 3) + sage: A._right_kernel_matrix_over_number_field()[1] [1 0 0] [0 1 0] [0 0 1] @@ -3924,15 +3926,16 @@ cdef class Matrix(Matrix1): EXAMPLES:: + sage: # needs sage.libs.pari sage: A = matrix(Zmod(24480), [[1,2,3,4,5], [7,7,7,7,7]]) - sage: result = A._right_kernel_matrix_over_integer_mod_ring() # needs sage.libs.pari - sage: result[0] # needs sage.libs.pari + sage: result = A._right_kernel_matrix_over_integer_mod_ring() + sage: result[0] 'computed-pari-matkermod' - sage: P = result[1]; P # needs sage.libs.pari + sage: P = result[1]; P [ 1 24478 1 0 0] [ 2 24477 0 1 0] [ 3 24476 0 0 1] - sage: A * P.transpose() == 0 # needs sage.libs.pari + sage: A * P.transpose() == 0 True """ R = self.base_ring() @@ -4123,6 +4126,7 @@ cdef class Matrix(Matrix1): We check that number fields are handled by the right routine as part of typical right kernel computation. :: + sage" # needs sage.rings.number_field sage: Q = QuadraticField(-7) # needs sage.rings.number_field sage: a = Q.gen(0) # needs sage.rings.number_field sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], [2+a, a, -7 + 5*a, -3+3*a]]) # needs sage.rings.number_field @@ -4132,7 +4136,8 @@ cdef class Matrix(Matrix1): verbose 1 () computing right kernel matrix over a number field for 2x4 matrix verbose 1 () done computing right kernel matrix over a number field for 2x4 matrix ... - Vector space of degree 4 and dimension 2 over Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I + Vector space of degree 4 and dimension 2 over + Number Field in a with defining polynomial x^2 + 7 with a = 2.645751311064591?*I Basis matrix: [ 1 0 7/88*a + 3/88 -3/176*a - 39/176] [ 0 1 -1/88*a - 13/88 13/176*a - 7/176] @@ -4178,7 +4183,7 @@ cdef class Matrix(Matrix1): [1 0 0 0 0 1] sage: A*DP.transpose() == zero_matrix(GF(2), 3, 4) True - sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') # needs sage.rings.finite_rings + sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') [1 0 0 0 0 1] [0 1 1 0 0 0] [0 0 0 1 0 0] @@ -4190,7 +4195,7 @@ cdef class Matrix(Matrix1): ....: [1, 0, 0, 0, 1, 1,], ....: [1, 0, 0, 0, 1, 1]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') # needs sage.rings.finite_rings + sage: A.right_kernel(algorithm='default') verbose ... verbose 1 () computing right kernel matrix over integers mod 2 for 3x6 matrix verbose 1 () done computing right kernel matrix over integers mod 2 for 3x6 matrix @@ -4249,12 +4254,13 @@ cdef class Matrix(Matrix1): We test that the generic code is called for matrices over fields, lacking any more specific routine. :: - sage: F. = FiniteField(5^2) # needs sage.rings.finite_rings - sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(5^2) + sage: A = matrix(F, 3, 4, [[ 1, a, 1+a, a^3+a^5], ....: [ a, a^4, a+a^4, a^4+a^8], ....: [a^2, a^6, a^2+a^6, a^5+a^10]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') # needs sage.rings.finite_rings + sage: A.right_kernel(algorithm='default') verbose ... verbose 1 () computing right kernel matrix over an arbitrary field for 3x4 matrix ... @@ -4294,6 +4300,7 @@ cdef class Matrix(Matrix1): sage: A*X.transpose() == zero_matrix(ZZ, 4, 3) True + sage: # needs sage.libs.pari sage: X = A.right_kernel_matrix(algorithm='pari', basis='computed'); X [ 3 1 -5 -7 -2 3 2] [ 3 1 2 5 -5 2 -6] @@ -4368,7 +4375,8 @@ cdef class Matrix(Matrix1): sage: A.right_kernel_matrix() Traceback (most recent call last): ... - ArithmeticError: Ideal Ideal (x^2 - x, x^2 - 8) of Univariate Polynomial Ring in x over Integer Ring not principal + ArithmeticError: Ideal Ideal (x^2 - x, x^2 - 8) of + Univariate Polynomial Ring in x over Integer Ring not principal We test that the domain code is called for domains that lack any extra structure. :: @@ -4382,7 +4390,8 @@ cdef class Matrix(Matrix1): verbose 1 () computing right kernel matrix over a domain for 2x3 matrix verbose 1 () done computing right kernel matrix over a domain for 2x3 matrix ... - Free module of degree 3 and rank 1 over Univariate Polynomial Ring in y over Rational Field + Free module of degree 3 and rank 1 over + Univariate Polynomial Ring in y over Rational Field Echelon basis matrix: [-1 -y 1] sage: set_verbose(0) @@ -5677,6 +5686,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: +i sage: # needs sage.libs.pari sage: t = matrix(QQ, 3, [3, 0, -2, 0, -2, 0, 0, 0, 0]); t [ 3 0 -2] [ 0 -2 0] @@ -6829,17 +6839,18 @@ cdef class Matrix(Matrix1): :: + sage: # needs sage.rings.number_field sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenvectors_left(); es # needs sage.rings.number_field + sage: es = A.eigenvectors_left(); es [(0, [ (1, -2, 1) ], 1), (-1.348469228349535?, [(1, 0.3101020514433644?, -0.3797958971132713?)], 1), (13.34846922834954?, [(1, 1.289897948556636?, 1.579795897113272?)], 1)] - sage: eval, [evec], mult = es[0] # needs sage.rings.number_field - sage: delta = eval*evec - evec*A # needs sage.rings.number_field - sage: abs(abs(delta)) < 1e-10 # needs sage.rings.number_field + sage: eval, [evec], mult = es[0] + sage: delta = eval*evec - evec*A + sage: abs(abs(delta)) < 1e-10 True Notice the difference between considering ring extensions or not. @@ -6868,16 +6879,17 @@ cdef class Matrix(Matrix1): Check the deprecation:: - sage: matrix(QQ, [[1, 2], [3, 4]]).eigenvectors_left(False) # needs sage.rings.number_field + sage: matrix(QQ, [[1, 2], [3, 4]]).eigenvectors_left(False) # needs sage.rings.number_field doctest:...: DeprecationWarning: "extend" should be used as keyword argument See https://github.com/sagemath/sage/issues/29243 for details. [] Check :trac:`30518`:: - sage: K. = QuadraticField(-1) # needs sage.rings.number_field - sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4, 4*i-4,1-i,-2]) # needs sage.rings.number_field - sage: assert all(m*v == e*v for e, vs, _ in m.eigenvectors_right() for v in vs) # needs sage.rings.number_field + sage: # needs sage.rings.number_field + sage: K. = QuadraticField(-1) + sage: m = matrix(K, 4, [2,4*i,-i,0, -4*i,2,-1,0, 2*i,-2,0,0, 4*i+4, 4*i-4,1-i,-2]) + sage: assert all(m*v == e*v for e, vs, _ in m.eigenvectors_right() for v in vs) """ if other is not None: if isinstance(other, bool): @@ -6961,21 +6973,22 @@ cdef class Matrix(Matrix1): :: + sage: # needs sage.rings.number_field sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: es = A.eigenvectors_right(); es # needs sage.rings.number_field + sage: es = A.eigenvectors_right(); es [(0, [ (1, -2, 1) ], 1), (-1.348469228349535?, [(1, 0.1303061543300932?, -0.7393876913398137?)], 1), (13.34846922834954?, [(1, 3.069693845669907?, 5.139387691339814?)], 1)] - sage: A.eigenvectors_right(extend=False) # needs sage.rings.number_field + sage: A.eigenvectors_right(extend=False) [(0, [ (1, -2, 1) ], 1)] - sage: eval, [evec], mult = es[0] # needs sage.rings.number_field - sage: delta = eval*evec - A*evec # needs sage.rings.number_field - sage: abs(abs(delta)) < 1e-10 # needs sage.rings.number_field + sage: eval, [evec], mult = es[0] + sage: delta = eval*evec - A*evec + sage: abs(abs(delta)) < 1e-10 True TESTS:: @@ -7031,20 +7044,21 @@ cdef class Matrix(Matrix1): EXAMPLES:: + sage: # needs sage.rings.number_field sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: D, P = A.eigenmatrix_left() # needs sage.rings.number_field - sage: D # needs sage.rings.number_field + sage: D, P = A.eigenmatrix_left() + sage: D [ 0 0 0] [ 0 -1.348469228349535? 0] [ 0 0 13.34846922834954?] - sage: P # needs sage.rings.number_field + sage: P [ 1 -2 1] [ 1 0.3101020514433644? -0.3797958971132713?] [ 1 1.289897948556636? 1.579795897113272?] - sage: P*A == D*P # needs sage.rings.number_field + sage: P*A == D*P True Because `P` is invertible, `A` is diagonalizable. @@ -7060,20 +7074,21 @@ cdef class Matrix(Matrix1): :: + sage: # needs sage.rings.number_field sage: A = jordan_block(2, 3); A [2 1 0] [0 2 1] [0 0 2] - sage: D, P = A.eigenmatrix_left() # needs sage.rings.number_field - sage: D # needs sage.rings.number_field + sage: D, P = A.eigenmatrix_left() + sage: D [2 0 0] [0 2 0] [0 0 2] - sage: P # needs sage.rings.number_field + sage: P [0 0 1] [0 0 0] [0 0 0] - sage: P*A == D*P # needs sage.rings.number_field + sage: P*A == D*P True A generalized eigenvector decomposition:: @@ -7250,20 +7265,21 @@ cdef class Matrix(Matrix1): EXAMPLES:: + sage: # needs sage.rings.number_field sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: D, P = A.eigenmatrix_right() # needs sage.rings.number_field - sage: D # needs sage.rings.number_field + sage: D, P = A.eigenmatrix_right() + sage: D [ 0 0 0] [ 0 -1.348469228349535? 0] [ 0 0 13.34846922834954?] - sage: P # needs sage.rings.number_field + sage: P [ 1 1 1] [ -2 0.1303061543300932? 3.069693845669907?] [ 1 -0.7393876913398137? 5.139387691339814?] - sage: A*P == P*D # needs sage.rings.number_field + sage: A*P == P*D True Because `P` is invertible, `A` is diagonalizable. @@ -7279,20 +7295,21 @@ cdef class Matrix(Matrix1): :: + sage: # needs sage.rings.number_field sage: A = jordan_block(2, 3); A [2 1 0] [0 2 1] [0 0 2] - sage: D, P = A.eigenmatrix_right() # needs sage.rings.number_field - sage: D # needs sage.rings.number_field + sage: D, P = A.eigenmatrix_right() + sage: D [2 0 0] [0 2 0] [0 0 2] - sage: P # needs sage.rings.number_field + sage: P [1 0 0] [0 0 0] [0 0 0] - sage: A*P == P*D # needs sage.rings.number_field + sage: A*P == P*D True A generalized eigenvector decomposition:: @@ -7446,7 +7463,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: A=matrix(3,range(9)); A + sage: A = matrix(3,range(9)); A [0 1 2] [3 4 5] [6 7 8] @@ -7926,13 +7943,14 @@ cdef class Matrix(Matrix1): sage: a._echelon('classical') [ 1 0 -1] [ 0 1 2] - sage: R = ZpCA(5, 5, print_mode='val-unit') # needs sage.rings.padics - sage: A = matrix(R, 3, 3, [250,2369,1147, 106,927,362, 90,398,2483]) # needs sage.rings.padics - sage: A # needs sage.rings.padics + + sage: # needs sage.rings.padics + sage: R = ZpCA(5, 5, print_mode='val-unit') + sage: A = matrix(R, 3, 3, [250,2369,1147, 106,927,362, 90,398,2483]); A [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: A._echelon('partial_pivoting') # needs sage.rings.padics + sage: A._echelon('partial_pivoting') [1 + O(5^5) O(5^5) O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5)] @@ -8005,13 +8023,14 @@ cdef class Matrix(Matrix1): sage: P = a._echelon_in_place('classical'); a [ 1 0 -1] [ 0 1 2] - sage: R = ZpCA(5, 5, print_mode='val-unit') # needs sage.rings.padics - sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]) # needs sage.rings.padics - sage: A # needs sage.rings.padics + + sage: # needs sage.rings.padics + sage: R = ZpCA(5, 5, print_mode='val-unit') + sage: A = matrix(R,3,3,[250,2369,1147,106,927,362,90,398,2483]); A [5^3 * 2 + O(5^5) 2369 + O(5^5) 1147 + O(5^5)] [ 106 + O(5^5) 927 + O(5^5) 362 + O(5^5)] [ 5 * 18 + O(5^5) 398 + O(5^5) 2483 + O(5^5)] - sage: P = A._echelon_in_place('partial_pivoting'); A # needs sage.rings.padics + sage: P = A._echelon_in_place('partial_pivoting'); A [1 + O(5^5) O(5^5) O(5^5)] [ O(5^5) 1 + O(5^5) O(5^5)] [ O(5^5) O(5^5) 1 + O(5^5)] @@ -8163,12 +8182,12 @@ cdef class Matrix(Matrix1): def extended_echelon_form(self, subdivide=False, **kwds): r""" - Returns the echelon form of ``self`` augmented with an identity matrix. + Return the echelon form of ``self`` augmented with an identity matrix. INPUT: - - ``subdivide`` - default: ``False`` - determines if the - returned matrix is subdivided. See the description of the + - ``subdivide`` -- (boolean, default: ``False``) whether to + subdivide the returned matrix. See the description of the (output) below for details. - ``kwds`` - additional keywords that can be passed to the method that computes the echelon form. @@ -8384,8 +8403,7 @@ cdef class Matrix(Matrix1): [ 8 -5] sage: # needs sage.graphs - sage: B = M.as_bipartite_graph() - sage: B + sage: B = M.as_bipartite_graph(); B Bipartite graph on 5 vertices sage: B.edges(sort=True) [(1, 4, 1/3), (1, 5, 7), (2, 4, 6), (2, 5, 1/4), (3, 4, 8), (3, 5, -5)] @@ -8413,17 +8431,16 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = matrix(ZZ,[[1,0],[1,0],[0,1]]) - sage: M + sage: # needs sage.groups + sage: M = matrix(ZZ,[[1,0],[1,0],[0,1]]); M [1 0] [1 0] [0 1] - sage: A = M.automorphisms_of_rows_and_columns() # needs sage.groups - sage: A # needs sage.groups + sage: A = M.automorphisms_of_rows_and_columns(); A [((), ()), ((1,2), ())] sage: M = matrix(ZZ, [[1,1,1,1],[1,1,1,1]]) - sage: A = M.automorphisms_of_rows_and_columns() # needs sage.groups - sage: len(A) # needs sage.groups + sage: A = M.automorphisms_of_rows_and_columns() + sage: len(A) 48 One can now apply these automorphisms to ``M`` to show @@ -8470,9 +8487,9 @@ cdef class Matrix(Matrix1): INPUT: - ``check`` -- (default: ``False``) If ``True`` return a tuple of - the maximal matrix and the permutations taking ``self`` - to the maximal matrix. - If ``False``, return only the maximal matrix. + the maximal matrix and the permutations taking ``self`` + to the maximal matrix. + If ``False``, return only the maximal matrix. OUTPUT: @@ -8680,16 +8697,17 @@ cdef class Matrix(Matrix1): And for when ``check`` is True:: + sage: # needs sage.graphs sage: N = matrix(ZZ, [[3,5,3], [2,6,4], [1,2,3]]) sage: N [3 5 3] [2 6 4] [1 2 3] - sage: r = M.is_permutation_of(N, check=True) # needs sage.graphs - sage: r # needs sage.graphs + sage: r = M.is_permutation_of(N, check=True) + sage: r (True, ((1,2,3), ())) - sage: p = r[1] # needs sage.graphs - sage: M.with_permuted_rows_and_columns(*p) == N # needs sage.graphs + sage: p = r[1] + sage: M.with_permuted_rows_and_columns(*p) == N True """ ncols = self.ncols() @@ -9683,7 +9701,7 @@ cdef class Matrix(Matrix1): sage: (2 * Matrix(5,5,1)).is_bistochastic() False - sage: (2 * Matrix(5,5,1)).is_bistochastic(normalized = False) + sage: (2 * Matrix(5,5,1)).is_bistochastic(normalized=False) True Here is a matrix whose row and column sums is 1, but not all entries are @@ -9930,7 +9948,7 @@ cdef class Matrix(Matrix1): Test :trac:`17341`:: - sage: random_matrix(GF(2), 8, 586, sparse=True).visualize_structure() # needs sage.rings.finite_rings + sage: random_matrix(GF(2), 8, 586, sparse=True).visualize_structure() # needs pillow 512x6px 24-bit RGB image """ cdef Py_ssize_t x, y, _x, _y, v, bi, bisq @@ -10173,20 +10191,21 @@ cdef class Matrix(Matrix1): Finally, an example over a general ring ``S`` that is not an integral domain:: + sage: # needs sage.libs.singular sage: R. = QQ[] - sage: S. = R.quo((b^3)) # needs sage.libs.singular - sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) # needs sage.libs.singular - sage: A # needs sage.libs.singular + sage: S. = R.quo((b^3)) + sage: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]) + sage: A [ x*y^2 2*x] [ 2 x^10*y] - sage: A.det() # needs sage.libs.singular + sage: A.det() -4*x - sage: A.charpoly('T') # needs sage.libs.singular + sage: A.charpoly('T') T^2 + (-x^10*y - x*y^2)*T - 4*x - sage: A.adjugate() # needs sage.libs.singular + sage: A.adjugate() [x^10*y -2*x] [ -2 x*y^2] - sage: A.adjugate() * A # needs sage.libs.singular + sage: A.adjugate() * A [-4*x 0] [ 0 -4*x] @@ -10646,7 +10665,8 @@ cdef class Matrix(Matrix1): sage: A._gram_schmidt_noscale() Traceback (most recent call last): ... - TypeError: Gram-Schmidt orthogonalization requires a base ring with a fraction field, not Ring of integers modulo 6 + TypeError: Gram-Schmidt orthogonalization requires a base ring + with a fraction field, not Ring of integers modulo 6 """ from sage.matrix.constructor import matrix, zero_matrix R = self.base_ring() @@ -11071,20 +11091,21 @@ cdef class Matrix(Matrix1): EXAMPLES:: + sage: # needs sage.combinat sage: a = matrix(ZZ,4,[1, 0, 0, 0, 0, 1, 0, 0, ....: 1, -1, 1, 0, 1, -1, 1, 2]); a [ 1 0 0 0] [ 0 1 0 0] [ 1 -1 1 0] [ 1 -1 1 2] - sage: a.jordan_form() # needs sage.combinat + sage: a.jordan_form() [2|0 0|0] [-+---+-] [0|1 1|0] [0|0 1|0] [-+---+-] [0|0 0|1] - sage: a.jordan_form(subdivide=False) # needs sage.combinat + sage: a.jordan_form(subdivide=False) [2 0 0 0] [0 1 1 0] [0 0 1 0] @@ -11093,11 +11114,11 @@ cdef class Matrix(Matrix1): [0 1 2] [3 4 5] [6 7 8] - sage: b.jordan_form() # needs sage.combinat + sage: b.jordan_form() Traceback (most recent call last): ... RuntimeError: Some eigenvalue does not exist in Rational Field. - sage: b.jordan_form(RealField(15)) # needs sage.combinat + sage: b.jordan_form(RealField(15)) Traceback (most recent call last): ... ValueError: Jordan normal form not implemented over inexact rings. @@ -11158,27 +11179,29 @@ cdef class Matrix(Matrix1): :: + sage: # needs sage.combinat sage: evals = [(i,i) for i in range(1,6)] sage: n = sum(range(1,6)) sage: jf = block_diagonal_matrix([jordan_block(ev,size) for ev,size in evals]) sage: p = random_matrix(ZZ,n,n) sage: while p.rank() != n: p = random_matrix(ZZ,n,n) sage: m = p * jf * ~p - sage: mjf, mp = m.jordan_form(transformation=True) # needs sage.combinat - sage: mjf == jf # needs sage.combinat + sage: mjf, mp = m.jordan_form(transformation=True) + sage: mjf == jf True sage: m = diagonal_matrix([1,1,0,0]) - sage: jf, P = m.jordan_form(transformation=True) # needs sage.combinat - sage: jf == ~P*m*P # needs sage.combinat + sage: jf, P = m.jordan_form(transformation=True) + sage: jf == ~P*m*P True We verify that the bug from :trac:`6942` is fixed:: + sage: # needs sage.combinat sage: M = Matrix(GF(2),[[1,0,1,0,0,0,1], [1,0,0,1,1,1,0], [1,1,0,1,1,1,1], ....: [1,1,1,0,1,1,1], [1,1,1,0,0,1,0], [1,1,1,0,1,0,0], ....: [1,1,1,1,1,1,0]]) - sage: J, T = M.jordan_form(transformation=True) # needs sage.combinat sage.rings.finite_rings - sage: J # needs sage.combinat sage.rings.finite_rings + sage: J, T = M.jordan_form(transformation=True) + sage: J [1 1|0 0|0 0|0] [0 1|0 0|0 0|0] [---+---+---+-] @@ -11189,9 +11212,9 @@ cdef class Matrix(Matrix1): [0 0|0 0|0 1|0] [---+---+---+-] [0 0|0 0|0 0|1] - sage: M * T == T * J # needs sage.combinat sage.rings.finite_rings + sage: M * T == T * J True - sage: T.rank() # needs sage.combinat sage.rings.finite_rings + sage: T.rank() 7 sage: M.rank() 7 @@ -11303,9 +11326,10 @@ cdef class Matrix(Matrix1): Verify that we smoothly move to QQ from ZZ (:trac:`12693`), i.e. we work in the vector space over the field:: + sage: # needs sage.combinat sage: M = matrix(((2,2,2), (0,0,0), (-2,-2,-2))) - sage: J, P = M.jordan_form(transformation=True) # needs sage.combinat - sage: J; P # needs sage.combinat + sage: J, P = M.jordan_form(transformation=True) + sage: J; P [0 1|0] [0 0|0] [---+-] @@ -11313,15 +11337,15 @@ cdef class Matrix(Matrix1): [ 2 1 0] [ 0 0 1] [-2 0 -1] - sage: J - ~P * M * P # needs sage.combinat + sage: J - ~P * M * P [0 0 0] [0 0 0] [0 0 0] sage: parent(M) Full MatrixSpace of 3 by 3 dense matrices over Integer Ring - sage: parent(J) == parent(P) == MatrixSpace(QQ, 3) # needs sage.combinat + sage: parent(J) == parent(P) == MatrixSpace(QQ, 3) True - sage: M.jordan_form(transformation=True) == (M/1).jordan_form(transformation=True) # needs sage.combinat + sage: M.jordan_form(transformation=True) == (M/1).jordan_form(transformation=True) True By providing eigenvalues ourselves, we can compute the Jordan form even @@ -11528,32 +11552,34 @@ cdef class Matrix(Matrix1): EXAMPLES:: + sage: # needs sage.libs.pari sage: A = matrix(QQ, 4, [-4, 6, 3, 3, -3, 5, 3, 3, 3, -6, -4, -3, -3, 6, 3, 2]) sage: A [-4 6 3 3] [-3 5 3 3] [ 3 -6 -4 -3] [-3 6 3 2] - sage: A.is_diagonalizable() # needs sage.libs.pari + sage: A.is_diagonalizable() True - sage: A.diagonalization() # needs sage.libs.pari + sage: A.diagonalization() ( [ 2 0 0 0] [ 1 1 0 0] [ 0 -1 0 0] [ 1 0 1 0] [ 0 0 -1 0] [-1 0 0 1] [ 0 0 0 -1], [ 1 1 -2 -1] ) - sage: D, P = A.diagonalization() # needs sage.libs.pari - sage: P^-1*A*P == D # needs sage.libs.pari + sage: D, P = A.diagonalization() + sage: P^-1*A*P == D True + sage: # needs sage.libs.pari sage: A = matrix(QQ, 2, [0, 2, 1, 0]) - sage: A.is_diagonalizable() # needs sage.libs.pari + sage: A.is_diagonalizable() False - sage: A.is_diagonalizable(QQbar) # needs sage.libs.pari sage.rings.number_field + sage: A.is_diagonalizable(QQbar) # needs sage.rings.number_field True - sage: D, P = A.diagonalization(QQbar) # needs sage.libs.pari sage.rings.number_field - sage: P^-1*A*P == D # needs sage.libs.pari sage.rings.number_field + sage: D, P = A.diagonalization(QQbar) # needs sage.rings.number_field + sage: P^-1*A*P == D # needs sage.rings.number_field True Matrices may fail to be diagonalizable for various reasons:: @@ -11928,37 +11954,40 @@ cdef class Matrix(Matrix1): ....: [ 0, 6, 1]]) sage: A.is_similar(B) True - sage: _, T = A.is_similar(B, transformation=True) # needs sage.libs.pari - sage: T # needs sage.libs.pari + + sage: # needs sage.libs.pari + sage: _, T = A.is_similar(B, transformation=True) + sage: T [ 1.00000000000000? + 0.?e-14*I 0.?e-14 + 0.?e-14*I 0.?e-14 + 0.?e-14*I] [-0.66666666666667? + 0.?e-15*I 0.166666666666667? + 0.?e-15*I -0.83333333333334? + 0.?e-14*I] [ 0.66666666666667? + 0.?e-14*I 0.?e-14 + 0.?e-14*I -0.33333333333333? + 0.?e-14*I] - sage: T.change_ring(QQ) # needs sage.libs.pari + sage: T.change_ring(QQ) [ 1 0 0] [-2/3 1/6 -5/6] [ 2/3 0 -1/3] - sage: A == T.inverse()*B*T # needs sage.libs.pari + sage: A == T.inverse()*B*T True Other exact fields are supported. :: - sage: F. = FiniteField(7^2) # needs sage.rings.finite_rings - sage: A = matrix(F, [[2*a + 5, 6*a + 6, a + 3], # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(7^2) + sage: A = matrix(F, [[2*a + 5, 6*a + 6, a + 3], ....: [ a + 3, 2*a + 2, 4*a + 2], ....: [2*a + 6, 5*a + 5, 3*a]]) - sage: B = matrix(F, [[5*a + 5, 6*a + 4, a + 1], # needs sage.rings.finite_rings + sage: B = matrix(F, [[5*a + 5, 6*a + 4, a + 1], ....: [ a + 5, 4*a + 3, 3*a + 3], ....: [3*a + 5, a + 4, 5*a + 6]]) sage: A.is_similar(B) True sage: B.is_similar(A) True - sage: _, T = A.is_similar(B, transformation=True) # needs sage.rings.finite_rings - sage: T # needs sage.rings.finite_rings + sage: _, T = A.is_similar(B, transformation=True) + sage: T [ 1 0 0] [6*a + 1 4*a + 3 4*a + 2] [6*a + 3 3*a + 5 3*a + 6] - sage: A == T.inverse() * B * T # needs sage.rings.finite_rings + sage: A == T.inverse() * B * T True Two matrices with different sets of eigenvalues, so they @@ -12040,9 +12069,10 @@ cdef class Matrix(Matrix1): algebraic closure of this field to find the change-of-basis matrix:: - sage: cox = posets.TamariLattice(3).coxeter_transformation() # needs sage.combinat sage.graphs sage.rings.finite_rings - sage: M = cox.change_ring(GF(3)) # needs sage.combinat sage.graphs sage.rings.finite_rings - sage: M.is_similar(M**3, True) # long time # needs sage.combinat sage.graphs sage.rings.finite_rings + sage: # needs sage.combinat sage.graphs sage.rings.finite_rings + sage: cox = posets.TamariLattice(3).coxeter_transformation() + sage: M = cox.change_ring(GF(3)) + sage: M.is_similar(M**3, True) # long time ( [1 0 0 0 0] [0 1 1 0 2] @@ -13053,13 +13083,14 @@ cdef class Matrix(Matrix1): and rational one because inverting a matrix with algebraic entries is harder and requires smaller test cases:: + sage: # needs sage.rings.number_field sage: from sage.misc.prandom import choice sage: n = ZZ.random_element(2) - sage: ring = choice([AA, QQbar]) # needs sage.rings.number_field + sage: ring = choice([AA, QQbar]) sage: A = matrix.random(ring, n) sage: I = matrix.identity(ring, n) sage: A = A*A.conjugate_transpose() + I - sage: A.is_positive_definite() # needs sage.rings.number_field + sage: A.is_positive_definite() True sage: actual = A.inverse_positive_definite() sage: expected = A.inverse() @@ -13315,13 +13346,15 @@ cdef class Matrix(Matrix1): sage: P, L, U = A.LU() Traceback (most recent call last): ... - TypeError: base ring of the matrix must be exact, not Real Field with 100 bits of precision + TypeError: base ring of the matrix must be exact, + not Real Field with 100 bits of precision sage: A = matrix(Integers(6), 3, 2, range(6)) sage: A.LU() Traceback (most recent call last): ... - TypeError: base ring of the matrix needs a field of fractions, not Ring of integers modulo 6 + TypeError: base ring of the matrix needs a field of fractions, + not Ring of integers modulo 6 sage: R. = PolynomialRing(QQ, 'y') sage: B = matrix(R, [[y+1, y^2+y], [y^2, y^3]]) @@ -13344,8 +13377,9 @@ cdef class Matrix(Matrix1): sage: B == P*L*U True - sage: F. = FiniteField(5^2) # needs sage.rings.finite_rings - sage: C = matrix(F, [[a + 3, 4*a + 4, 2, 4*a + 2], # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(5^2) + sage: C = matrix(F, [[a + 3, 4*a + 4, 2, 4*a + 2], ....: [3, 2*a + 4, 2*a + 4, 2*a + 1], ....: [3*a + 1, a + 3, 2*a + 4, 4*a + 3], ....: [a, 3, 3*a + 1, a]]) @@ -13355,17 +13389,17 @@ cdef class Matrix(Matrix1): [0 1 0 0] [0 0 1 0] [0 0 0 1] - sage: L # needs sage.combinat sage.rings.finite_rings + sage: L # needs sage.combinat [ 1 0 0 0] [3*a + 3 1 0 0] [ 2*a 4*a + 2 1 0] [2*a + 3 2 2*a + 4 1] - sage: U # needs sage.combinat sage.rings.finite_rings + sage: U # needs sage.combinat [ a + 3 4*a + 4 2 4*a + 2] [ 0 a + 1 a + 3 2*a + 4] [ 0 0 1 4*a + 2] [ 0 0 0 0] - sage: L.base_ring() # needs sage.combinat sage.rings.finite_rings + sage: L.base_ring() # needs sage.combinat Finite Field in a of size 5^2 sage: C == P*L*U True @@ -13952,27 +13986,28 @@ cdef class Matrix(Matrix1): may be factored. This provides a reasonable alternative to the Cholesky decomposition. :: - sage: F. = FiniteField(5^3) # needs sage.rings.finite_rings - sage: A = matrix(F, # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(5^3) + sage: A = matrix(F, ....: [[ a^2 + 2*a, 4*a^2 + 3*a + 4, 3*a^2 + a, 2*a^2 + 2*a + 1], ....: [4*a^2 + 3*a + 4, 4*a^2 + 2, 3*a, 2*a^2 + 4*a + 2], ....: [ 3*a^2 + a, 3*a, 3*a^2 + 2, 3*a^2 + 2*a + 3], ....: [2*a^2 + 2*a + 1, 2*a^2 + 4*a + 2, 3*a^2 + 2*a + 3, 3*a^2 + 2*a + 4]]) sage: A.is_symmetric() True - sage: L, d = A.indefinite_factorization() # needs sage.rings.finite_rings + sage: L, d = A.indefinite_factorization() sage: D = diagonal_matrix(d) - sage: L # needs sage.rings.finite_rings + sage: L [ 1 0 0 0] [4*a^2 + 4*a + 3 1 0 0] [ 3 4*a^2 + a + 2 1 0] [ 4*a^2 + 4 2*a^2 + 3*a + 3 2*a^2 + 3*a + 1 1] - sage: D # needs sage.rings.finite_rings + sage: D [ a^2 + 2*a 0 0 0] [ 0 2*a^2 + 2*a + 4 0 0] [ 0 0 3*a^2 + 4*a + 3 0] [ 0 0 0 a^2 + 3*a] - sage: A == L*D*L.transpose() # needs sage.rings.finite_rings + sage: A == L*D*L.transpose() True This works correctly for the 0x0 matrix:: @@ -14378,13 +14413,14 @@ cdef class Matrix(Matrix1): The same is true of the following complex Hermitian matrix:: - sage: A = matrix(QQbar, [ [ 0,I], # needs sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [ [ 0,I], ....: [-I,0] ]) sage: A.block_ldlt(classical=True) Traceback (most recent call last): ... ValueError: matrix has no classical LDL^T factorization - sage: A.block_ldlt() # needs sage.rings.number_field + sage: A.block_ldlt() ( [1 0] [1 0] [ 0 I] [0 1], [0 1], [-I 0] @@ -14507,9 +14543,10 @@ cdef class Matrix(Matrix1): Ensure that a "random" complex Hermitian matrix is factored correctly:: + sage: # needs sage.rings.number_field sage: n = ZZ.random_element(6) - sage: F = QuadraticField(-1, 'I') # needs sage.rings.number_field - sage: A = matrix.random(F, n) # needs sage.rings.number_field + sage: F = QuadraticField(-1, 'I') + sage: A = matrix.random(F, n) sage: A = A + A.conjugate_transpose() sage: P,L,D = A.block_ldlt() sage: A == P*L*D*L.conjugate_transpose()*P.conjugate_transpose() @@ -14519,9 +14556,10 @@ cdef class Matrix(Matrix1): factored correctly and that the resulting block-diagonal matrix is in fact diagonal:: + sage: # needs sage.rings.number_field sage: n = ZZ.random_element(6) - sage: F = QuadraticField(-1, 'I') # needs sage.rings.number_field - sage: A = matrix.random(F, n) # needs sage.rings.number_field + sage: F = QuadraticField(-1, 'I') + sage: A = matrix.random(F, n) sage: A = A * A.conjugate_transpose() sage: P,L,D = A.block_ldlt() sage: A == P * L * D * L.conjugate_transpose() * P.conjugate_transpose() @@ -14888,12 +14926,13 @@ cdef class Matrix(Matrix1): confirmed by the positive determinants of its leading principal submatrices:: - sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], # needs sage.rings.number_field + sage: # needs sage.rings.number_field + sage: A = matrix(QQbar, [[ 2, 4 + 2*I, 6 - 4*I], ....: [ -2*I + 4, 11, 10 - 12*I], ....: [ 4*I + 6, 10 + 12*I, 37]]) - sage: A.is_positive_definite() # needs sage.rings.number_field + sage: A.is_positive_definite() True - sage: [A[:i,:i].determinant() for i in range(1, A.nrows() + 1)] # needs sage.rings.number_field + sage: [A[:i,:i].determinant() for i in range(1, A.nrows() + 1)] [2, 2, 6] TESTS: @@ -14927,10 +14966,12 @@ cdef class Matrix(Matrix1): We can check positive-definiteness of matrices over approximate real/complex and symbolic rings:: + sage: # needs sage.rings.real_mpfr sage: matrix.identity(RR,4).is_positive_definite() True sage: matrix.identity(CC,4).is_positive_definite() True + sage: matrix.identity(SR,4).is_positive_definite() # needs sage.symbolic True """ @@ -15002,7 +15043,7 @@ cdef class Matrix(Matrix1): (automatically) using MPFR instead of doubles, since doubles overflow:: - sage: a = matrix(ZZ, 2, [2^10000,3^10000,2^50,3^19292]) + sage: a = matrix(ZZ, 2, [2^10000, 3^10000, 2^50, 3^19292]) sage: a.hadamard_bound() 12215 sage: len(str(a.det())) @@ -15050,7 +15091,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: sage: M = matrix(4,3,[1, -1/2, -1, 1, -1, -1/2, -1, 0, 0, 2, 0, 1]) - sage: M.find(lambda entry:entry==0) + sage: M.find(lambda entry: entry == 0) [0 0 0] [0 0 0] [0 1 1] @@ -15058,7 +15099,7 @@ cdef class Matrix(Matrix1): :: - sage: M.find(lambda u:u<0) + sage: M.find(lambda u: u < 0) [0 1 1] [0 1 1] [1 0 0] @@ -15072,7 +15113,7 @@ cdef class Matrix(Matrix1): :: - sage: M.find(lambda u:u!=1/2) + sage: M.find(lambda u: u != 1/2) [1 1 1] [1 1 1] [1 1 1] @@ -15080,7 +15121,7 @@ cdef class Matrix(Matrix1): :: - sage: M.find(lambda u:u>1.2) + sage: M.find(lambda u: u > 1.2) [0 0 0] [0 0 0] [0 0 0] @@ -15088,7 +15129,7 @@ cdef class Matrix(Matrix1): :: - sage: sorted(M.find(lambda u:u!=0,indices=True).keys()) == M.nonzero_positions() + sage: sorted(M.find(lambda u: u != 0, indices=True).keys()) == M.nonzero_positions() True """ from sage.matrix.matrix_space import MatrixSpace @@ -15195,7 +15236,10 @@ cdef class Matrix(Matrix1): [ I + 2 6*I + 9] [-4*I + 3 -5*I] - sage: P = matrix(CC, 3, 2, [0.95-0.63*I, 0.84+0.13*I, 0.94+0.23*I, 0.23+0.59*I, 0.52-0.41*I, -0.50+0.90*I]) + sage: # needs sage.rings.real_mpfr sage.symbolic + sage: P = matrix(CC, 3, 2, [0.95-0.63*I, 0.84+0.13*I, + ....: 0.94+0.23*I, 0.23+0.59*I, + ....: 0.52-0.41*I, -0.50+0.90*I]) sage: P.base_ring() Complex Field with 53 bits of precision sage: P.conjugate_transpose() @@ -15250,7 +15294,8 @@ cdef class Matrix(Matrix1): sage: N.conjugate_transpose() Traceback (most recent call last): ... - AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object has no attribute 'conjugate' + AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object + has no attribute 'conjugate' """ # limited testing on a 1000 x 1000 matrix over CC: # transpose is fast, conjugate is slow @@ -15300,6 +15345,8 @@ cdef class Matrix(Matrix1): sage: Id = identity_matrix(12) sage: Id.norm(2) 1.0 + + sage: # needs sage.rings.real_mpfr sage: A = matrix(RR, 2, 2, [13,-4,-4,7]) sage: A.norm() # rel tol 2e-16 14.999999999999998 @@ -15308,6 +15355,7 @@ cdef class Matrix(Matrix1): Faster routines for double precision entries from `RDF` or `CDF` are provided by the :class:`~sage.matrix.matrix_double_dense.Matrix_double_dense` class. :: + sage: # needs sage.rings.real_mpfr sage: A = matrix(CC, 2, 3, [3*I,4,1-I,1,2,0]) sage: A.norm('frob') 5.656854249492381 @@ -15376,26 +15424,18 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: d = matrix([[3, 0], [0, sqrt(2)]]) # needs sage.symbolic - sage: b = matrix([[1, -1], [2, 2]]); e = b * d * b.inverse(); e # needs sage.symbolic + sage: # needs sage.symbolic + sage: d = matrix([[3, 0], [0, sqrt(2)]]) + sage: b = matrix([[1, -1], [2, 2]]); e = b * d * b.inverse(); e [ 1/2*sqrt(2) + 3/2 -1/4*sqrt(2) + 3/4] [ -sqrt(2) + 3 1/2*sqrt(2) + 3/2] - - :: - - sage: e.numerical_approx(53) # needs sage.symbolic + sage: e.numerical_approx(53) [ 2.20710678118655 0.396446609406726] [ 1.58578643762690 2.20710678118655] - - :: - - sage: e.numerical_approx(20) # needs sage.symbolic + sage: e.numerical_approx(20) [ 2.2071 0.39645] [ 1.5858 2.2071] - - :: - - sage: (e - I).numerical_approx(20) # needs sage.symbolic + sage: (e - I).numerical_approx(20) [2.2071 - 1.0000*I 0.39645] [ 1.5858 2.2071 - 1.0000*I] @@ -15482,7 +15522,7 @@ cdef class Matrix(Matrix1): Another random plot, but over GF(389):: sage: A = random_matrix(GF(389), 10) - sage: A.plot(cmap='Oranges') # needs sage.plot sage.rings.finite_rings + sage: A.plot(cmap='Oranges') # needs sage.plot Graphics object consisting of 1 graphics primitive """ from sage.plot.matrix_plot import matrix_plot @@ -15534,8 +15574,9 @@ cdef class Matrix(Matrix1): EXAMPLES:: + sage: # needs sage.symbolic sage: a = matrix([[1,2], [3,4]]) - sage: a.exp() # needs sage.symbolic + sage: a.exp() [-1/22*((sqrt(33) - 11)*e^sqrt(33) - sqrt(33) - 11)*e^(-1/2*sqrt(33) + 5/2) 2/33*(sqrt(33)*e^sqrt(33) - sqrt(33))*e^(-1/2*sqrt(33) + 5/2)] [ 1/11*(sqrt(33)*e^sqrt(33) - sqrt(33))*e^(-1/2*sqrt(33) + 5/2) 1/22*((sqrt(33) + 11)*e^sqrt(33) - sqrt(33) + 11)*e^(-1/2*sqrt(33) + 5/2)] @@ -15562,7 +15603,7 @@ cdef class Matrix(Matrix1): sage: matrix.diagonal([0], sparse=True).exp() # not tested # needs sage.symbolic [1] - sage: matrix.zero(CBF, 2, sparse=True).exp() # needs sage.symbolic + sage: matrix.zero(CBF, 2, sparse=True).exp() # needs sage.libs.flint sage.symbolic [1.000000000000000 0] [ 0 1.000000000000000] """ @@ -15896,7 +15937,8 @@ cdef class Matrix(Matrix1): [ -x + 1 -1 -x^2 + 2*x - 1] [-x^2 + 2*x - 1 -x + 1 -1] sage: H = A.__copy__() - sage: U = H._hermite_form_euclidean(transformation=True, normalization=lambda p: ~p.lc()) + sage: U = H._hermite_form_euclidean(transformation=True, + ....: normalization=lambda p: ~p.lc()) sage: H [ 1 x^2 - 2*x + 1 x - 1] [ 0 x^3 - 3*x^2 + 3*x - 2 0] @@ -16935,8 +16977,9 @@ cdef class Matrix(Matrix1): Rational form may be computed over any field. The matrix below is an example where the eigenvalues lie outside the field. :: - sage: F. = FiniteField(7^2) # needs sage.rings.finite_rings - sage: A = matrix(F, # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(7^2) + sage: A = matrix(F, ....: [[5*a + 3, 4*a + 1, 6*a + 2, 2*a + 5, 6, 4*a + 5, 4*a + 5, 5, a + 6, 5, 4*a + 4], ....: [6*a + 3, 2*a + 4, 0, 6, 5*a + 5, 2*a, 5*a + 1, 1, 5*a + 2, 4*a, 5*a + 6], ....: [3*a + 1, 6*a + 6, a + 6, 2, 0, 3*a + 6, 5*a + 4, 5*a + 6, 5*a + 2, 3, 4*a + 2], @@ -16948,7 +16991,7 @@ cdef class Matrix(Matrix1): ....: [3*a + 5, 6*a + 2, 4*a, a + 5, 0, 5*a, 6*a + 5, 2*a + 1, 3*a + 1, 3*a + 5, 4*a + 2], ....: [3*a + 2, a + 3, 3*a + 6, a, 3*a + 5, 5*a + 1, 3*a + 2, a + 3, a + 2, 6*a + 1, 3*a + 3], ....: [6*a + 6, 5*a + 1, 4*a, 2, 5*a + 5, 3*a + 5, 3*a + 1, 2*a, 2*a, 2*a + 4, 4*a + 2]]) - sage: A.rational_form() # needs sage.rings.finite_rings + sage: A.rational_form() [ a + 2| 0 0 0| 0 0 0 0 0 0 0] [-------+-----------------------+-------------------------------------------------------] [ 0| 0 0 a + 6| 0 0 0 0 0 0 0] @@ -16963,17 +17006,17 @@ cdef class Matrix(Matrix1): [ 0| 0 0 0| 0 0 0 0 1 0 2*a + 1] [ 0| 0 0 0| 0 0 0 0 0 1 2*a + 1] sage: invariants = A.rational_form(format='invariants') - sage: invariants # needs sage.rings.finite_rings + sage: invariants [[6*a + 5, 1], [6*a + 1, a + 3, a + 3, 1], [5*a, a + 4, a + 6, 6*a + 5, 6*a + 1, 5*a + 6, 5*a + 6, 1]] sage: R. = F[] sage: polys = [R(p) for p in invariants] - sage: [p.factor() for p in polys] # needs sage.rings.finite_rings + sage: [p.factor() for p in polys] [x + 6*a + 5, (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a), (x + 6*a + 5) * (x^2 + (2*a + 5)*x + 5*a)^3] - sage: polys[-1] == A.minimal_polynomial() # needs sage.rings.finite_rings + sage: polys[-1] == A.minimal_polynomial() True - sage: prod(polys) == A.characteristic_polynomial() # needs sage.rings.finite_rings + sage: prod(polys) == A.characteristic_polynomial() True - sage: A.eigenvalues() # needs sage.rings.finite_rings + sage: A.eigenvalues() Traceback (most recent call last): ... NotImplementedError: algebraic closures of finite fields are only implemented for prime fields @@ -17187,12 +17230,13 @@ cdef class Matrix(Matrix1): Your matrix can be over any exact ring, for example the ring of univariate polynomials with rational coefficients:: - sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) # needs sage.geometry.polyhedron - sage: K.is_full_space() # needs sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron + sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)]) + sage: K.is_full_space() True sage: x = polygen(ZZ, 'x') sage: L = matrix(QQ[x], [[x,0],[0,1]]) - sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron + sage: L.is_positive_operator_on(K) True TESTS: @@ -17220,12 +17264,12 @@ cdef class Matrix(Matrix1): the underlying ring symbolic (the usual case is tested by the ``positive_operators_gens`` method):: - sage: # needs sage.geometry.polyhedron + sage: # needs sage.geometry.polyhedron sage.symbolic sage: K1 = random_cone(max_ambient_dim=5) sage: K2 = random_cone(max_ambient_dim=5) - sage: results = ( L.change_ring(SR).is_positive_operator_on(K1, K2) # needs sage.symbolic + sage: results = ( L.change_ring(SR).is_positive_operator_on(K1, K2) ....: for L in K1.positive_operators_gens(K2) ) - sage: all(results) # long time # needs sage.symbolic + sage: all(results) # long time True Technically we could test this, but for now only closed convex cones @@ -17250,11 +17294,12 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR # needs sage.symbolic + sage: # needs sage.geometry.polyhedron sage.symbolic + sage: SCR = SR.subring(no_variables=True); SCR Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron - sage: L = identity_matrix(SCR, 3) # needs sage.symbolic - sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron sage.symbolic + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_positive_operator_on(K) True """ import sage.geometry.abc @@ -17373,10 +17418,11 @@ cdef class Matrix(Matrix1): symbolic (the usual case is tested by the ``cross_positive_operators_gens`` method):: - sage: K = random_cone(max_ambient_dim=5) # needs sage.geometry.polyhedron - sage: results = ( L.change_ring(SR).is_cross_positive_on(K) # needs sage.geometry.polyhedron sage.symbolic + sage: # needs sage.geometry.polyhedron sage.symbolic + sage: K = random_cone(max_ambient_dim=5) + sage: results = ( L.change_ring(SR).is_cross_positive_on(K) ....: for L in K.cross_positive_operators_gens() ) - sage: all(results) # long time # needs sage.geometry.polyhedron sage.symbolic + sage: all(results) # long time True Technically we could test this, but for now only closed convex cones @@ -17401,11 +17447,12 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR # needs sage.symbolic + sage: # needs sage.geometry.polyhedron sage.symbolic + sage: SCR = SR.subring(no_variables=True); SCR Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron - sage: L = identity_matrix(SCR, 3) # needs sage.symbolic - sage: L.is_cross_positive_on(K) # needs sage.geometry.polyhedron sage.symbolic + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_cross_positive_on(K) True """ import sage.geometry.abc @@ -17659,11 +17706,12 @@ cdef class Matrix(Matrix1): Symbolic subrings are fine:: - sage: SCR = SR.subring(no_variables=True); SCR # needs sage.symbolic + sage: # needs sage.geometry.polyhedron sage.symbolic + sage: SCR = SR.subring(no_variables=True); SCR Symbolic Constants Subring - sage: K = Cone([(1,2,3), (4,5,6)]) # needs sage.geometry.polyhedron - sage: L = identity_matrix(SCR, 3) # needs sage.symbolic - sage: L.is_lyapunov_like_on(K) # needs sage.geometry.polyhedron sage.symbolic + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_lyapunov_like_on(K) True A matrix is Lyapunov-like on a cone if and only if both the @@ -17673,10 +17721,10 @@ cdef class Matrix(Matrix1): sage: K = random_cone(max_ambient_dim=5) sage: R = K.lattice().vector_space().base_ring() sage: L = random_matrix(R, K.lattice_dim()) - sage: actual = L.is_lyapunov_like_on(K) # long time + sage: actual = L.is_lyapunov_like_on(K) # long time sage: expected = (L.is_cross_positive_on(K) and # long time ....: (-L).is_cross_positive_on(K)) - sage: actual == expected # long time + sage: actual == expected # long time True """ import sage.geometry.abc @@ -17881,16 +17929,17 @@ def _smith_diag(d, transformation=True): EXAMPLES:: + sage: # needs sage.rings.number_field sage: from sage.matrix.matrix2 import _smith_diag sage: x = polygen(ZZ, 'x') - sage: OE = EquationOrder(x^2 - x + 2, 'w') # needs sage.rings.number_field - sage: A = matrix(OE, 2, [2, 0, 0, 3]) # needs sage.rings.number_field - sage: D,U,V = _smith_diag(A); D,U,V # needs sage.rings.number_field + sage: OE = EquationOrder(x^2 - x + 2, 'w') + sage: A = matrix(OE, 2, [2, 0, 0, 3]) + sage: D,U,V = _smith_diag(A); D,U,V ( [1 0] [2 1] [ 1 -3] [0 6], [3 2], [-1 4] ) - sage: D == U*A*V # needs sage.rings.number_field + sage: D == U*A*V True sage: m = matrix(GF(7), 2, [3,0,0,6]); d,u,v = _smith_diag(m); d [1 0] @@ -18277,47 +18326,48 @@ def _matrix_power_symbolic(A, n): General power of a two by two matrix:: - sage: n = SR.var('n') # needs sage.symbolic + sage: # needs sage.symbolic + sage: n = SR.var('n') sage: A = matrix(QQ, [[2, -1], [1, 0]]) - sage: B = A^n; B # needs sage.symbolic + sage: B = A^n; B [ n + 1 -n] [ n -n + 1] - sage: all(A^k == B.subs({n: k}) for k in range(8)) # needs sage.symbolic + sage: all(A^k == B.subs({n: k}) for k in range(8)) True General power of a three by three matrix in Jordan form:: - sage: n = SR.var('n') # needs sage.symbolic - sage: A = matrix(QQ, 3, [[2, 1, 0], [0, 2, 0], [0, 0, 3]]) - sage: A + sage: # needs sage.symbolic + sage: n = SR.var('n') + sage: A = matrix(QQ, 3, [[2, 1, 0], [0, 2, 0], [0, 0, 3]]); A [2 1 0] [0 2 0] [0 0 3] - sage: B = A^n; B # needs sage.symbolic + sage: B = A^n; B [ 2^n 2^(n - 1)*n 0] [ 0 2^n 0] [ 0 0 3^n] - sage: all(A^k == B.subs({n: k}) for k in range(8)) # needs sage.symbolic + sage: all(A^k == B.subs({n: k}) for k in range(8)) True General power of a three by three matrix not in Jordan form:: - sage: A = matrix([[4, 1, 2], [0, 2, -4], [0, 1, 6]]) - sage: A + sage: # needs sage.symbolic + sage: A = matrix([[4, 1, 2], [0, 2, -4], [0, 1, 6]]); A [ 4 1 2] [ 0 2 -4] [ 0 1 6] - sage: B = A^n; B # needs sage.symbolic + sage: B = A^n; B [ 4^n 4^(n - 1)*n 2*4^(n - 1)*n] [ 0 -2*4^(n - 1)*n + 4^n -4*4^(n - 1)*n] [ 0 4^(n - 1)*n 2*4^(n - 1)*n + 4^n] - sage: [B.subs({n: k}) for k in range(4)] # needs sage.symbolic + sage: [B.subs({n: k}) for k in range(4)] [ [1 0 0] [ 4 1 2] [ 16 8 16] [ 64 48 96] [0 1 0] [ 0 2 -4] [ 0 0 -32] [ 0 -32 -192] [0 0 1], [ 0 1 6], [ 0 8 32], [ 0 48 160] ] - sage: all(A^k == B.subs({n: k}) for k in range(8)) # needs sage.symbolic + sage: all(A^k == B.subs({n: k}) for k in range(8)) True TESTS: diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 908d06180f9..94e8d545b5b 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -749,32 +749,35 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): NumPy arrays may be used as input. :: - sage: import numpy # needs numpy - sage: entries = numpy.array([1.2, 5.6]); entries # needs numpy + sage: # needs numpy + sage: import numpy + sage: entries = numpy.array([1.2, 5.6]); entries array([1.2, 5.6]) - sage: A = diagonal_matrix(3, entries); A # needs numpy + sage: A = diagonal_matrix(3, entries); A [1.2 0.0 0.0] [0.0 5.6 0.0] [0.0 0.0 0.0] - sage: A.parent() # needs numpy + sage: A.parent() Full MatrixSpace of 3 by 3 sparse matrices over Real Double Field + sage: # needs numpy sage: j = complex(0,1) - sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries # needs numpy + sage: entries = numpy.array([2.0+j, 8.1, 3.4+2.6*j]); entries array([2. +1.j , 8.1+0.j , 3.4+2.6j]) - sage: A = diagonal_matrix(entries); A # needs numpy + sage: A = diagonal_matrix(entries); A [2.0 + 1.0*I 0.0 0.0] [ 0.0 8.1 0.0] [ 0.0 0.0 3.4 + 2.6*I] - sage: A.parent() # needs numpy + sage: A.parent() Full MatrixSpace of 3 by 3 sparse matrices over Complex Double Field - sage: entries = numpy.array([4, 5, 6]) # needs numpy - sage: A = diagonal_matrix(entries); A # needs numpy + sage: # needs numpy + sage: entries = numpy.array([4, 5, 6]) + sage: A = diagonal_matrix(entries); A [4 0 0] [0 5 0] [0 0 6] - sage: A.parent() # needs numpy + sage: A.parent() Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring sage: entries = numpy.array([4.1, 5.2, 6.3]) # needs numpy @@ -2449,9 +2452,9 @@ def random_rref_matrix(parent, num_pivots): sage: B = random_matrix(FiniteField(7), 4, 4, ....: algorithm='echelon_form', num_pivots=3); B - [1 0 0 5] - [0 1 0 2] - [0 0 1 6] + [1 0 0 0] + [0 1 0 6] + [0 0 1 1] [0 0 0 0] sage: B.rank() == 3 True @@ -3071,10 +3074,12 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): sage: from sage.matrix.constructor import random_diagonalizable_matrix sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5) sage: A = random_diagonalizable_matrix(matrix_space) - sage: eigenvalues = A.eigenvalues() # needs sage.rings.number_field - sage: S = A.right_eigenmatrix()[1] # needs sage.rings.number_field - sage: eigenvalues2 = (S.inverse()*A*S).diagonal() # needs sage.rings.number_field - sage: sorted(eigenvalues) == sorted(eigenvalues2) # needs sage.rings.number_field + + sage: # needs sage.rings.number_field + sage: eigenvalues = A.eigenvalues() + sage: S = A.right_eigenmatrix()[1] + sage: eigenvalues2 = (S.inverse()*A*S).diagonal() + sage: sorted(eigenvalues) == sorted(eigenvalues2) True A diagonalizable matrix with eigenvalues and dimensions designated, @@ -3090,9 +3095,11 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): True sage: all(x in ZZ for x in (B-(6*identity_matrix(6))).rref().list()) True - sage: S = B.right_eigenmatrix()[1] # needs sage.rings.number_field - sage: eigenvalues2 = (S.inverse()*B*S).diagonal() # needs sage.rings.number_field - sage: all(e in eigenvalues for e in eigenvalues2) # needs sage.rings.number_field + + sage: # needs sage.rings.number_field + sage: S = B.right_eigenmatrix()[1] + sage: eigenvalues2 = (S.inverse()*B*S).diagonal() + sage: all(e in eigenvalues for e in eigenvalues2) True TESTS: diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 508548f245c..51226dbd22b 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -1188,15 +1188,17 @@ def __richcmp__(self, other, op): More exotic comparisons:: - sage: R1 = ZZ[sqrt(2)] # needs sage.symbolic - sage: F1 = R1^3 # needs sage.symbolic - sage: V1 = F1.span([[sqrt(2), sqrt(2), 0]]) # needs sage.symbolic + sage: # needs sage.symbolic + sage: R1 = ZZ[sqrt(2)] + sage: F1 = R1^3 + sage: V1 = F1.span([[sqrt(2), sqrt(2), 0]]) sage: F2 = ZZ^3 sage: V2 = F2.span([[2,2,0]]) - sage: V2 <= V1 # Different ambient vector spaces # needs sage.symbolic + sage: V2 <= V1 # Different ambient vector spaces False - sage: V1 <= V2 # needs sage.symbolic + sage: V1 <= V2 False + sage: R2. = GF(5)[] sage: F3 = R2^3 sage: V3 = F3.span([[x^5 - 1, 1 + x + x^2 + x^3 + x^4, 0]]) @@ -1811,8 +1813,7 @@ def free_resolution(self, *args, **kwds): sage: S. = PolynomialRing(QQ) sage: M = S**2 sage: N = M.submodule([vector([x - y, z]), vector([y * z, x * z])]) - sage: res = N.free_resolution() # needs sage.libs.singular - sage: res # needs sage.libs.singular + sage: res = N.free_resolution(); res # needs sage.libs.singular S^2 <-- S^2 <-- 0 sage: ascii_art(res.chain_complex()) # needs sage.libs.singular [x - y y*z] @@ -1894,7 +1895,8 @@ class FreeModule_generic(Module_free_ambient): EXAMPLES:: sage: PolynomialRing(QQ,3,'x')^3 - Ambient free module of rank 3 over the integral domain Multivariate Polynomial Ring in x0, x1, x2 over Rational Field + Ambient free module of rank 3 over the integral domain + Multivariate Polynomial Ring in x0, x1, x2 over Rational Field sage: FreeModule(GF(7), 3).category() Category of enumerated finite dimensional vector spaces with basis over @@ -2466,17 +2468,20 @@ def cardinality(self): EXAMPLES:: - sage: k. = FiniteField(9) # needs sage.rings.finite_rings - sage: V = VectorSpace(k, 3) # needs sage.rings.finite_rings - sage: V.cardinality() # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: k. = FiniteField(9) + sage: V = VectorSpace(k, 3) + sage: V.cardinality() 729 - sage: W = V.span([[1,2,1], [0,1,1]]) # needs sage.rings.finite_rings - sage: W.cardinality() # needs sage.rings.finite_rings + sage: W = V.span([[1,2,1], [0,1,1]]) + sage: W.cardinality() 81 + sage: R = IntegerModRing(12) sage: M = FreeModule(R, 2) sage: M.cardinality() 144 + sage: (QQ^3).cardinality() +Infinity @@ -2774,24 +2779,25 @@ def coordinate_module(self, V): function to write a submodule in terms of integral cuspidal modular symbols:: - sage: M = ModularSymbols(54) # needs sage.modular - sage: S = M.cuspidal_subspace() # needs sage.modular - sage: K = S.integral_structure(); K # needs sage.modular + sage: # needs sage.modular + sage: M = ModularSymbols(54) + sage: S = M.cuspidal_subspace() + sage: K = S.integral_structure(); K Free module of degree 19 and rank 8 over Integer Ring Echelon basis matrix: [ 0 1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ... - sage: L = M[0].integral_structure(); L # needs sage.modular + sage: L = M[0].integral_structure(); L Free module of degree 19 and rank 2 over Integer Ring Echelon basis matrix: [ 0 1 1 0 -2 1 -1 1 -1 -2 2 0 0 0 0 0 0 0 0] [ 0 0 3 0 -3 2 -1 2 -1 -4 2 -1 -2 1 2 0 0 -1 1] - sage: K.coordinate_module(L) # needs sage.modular + sage: K.coordinate_module(L) Free module of degree 8 and rank 2 over Integer Ring User basis matrix: [ 1 1 1 -1 1 -1 0 0] [ 0 3 2 -1 2 -1 -1 -2] - sage: K.coordinate_module(L).basis_matrix() * K.basis_matrix() # needs sage.modular + sage: K.coordinate_module(L).basis_matrix() * K.basis_matrix() [ 0 1 1 0 -2 1 -1 1 -1 -2 2 0 0 0 0 0 0 0 0] [ 0 0 3 0 -3 2 -1 2 -1 -4 2 -1 -2 1 2 0 0 -1 1] """ @@ -3351,78 +3357,80 @@ def _magma_init_(self, magma): :: + sage: # optional - magma sage: A = matrix([[1,0],[0,-1]]) sage: M = FreeModule(ZZ,2,inner_product_matrix=A); M Ambient free quadratic module of rank 2 over the principal ideal domain Integer Ring Inner product matrix: [ 1 0] [ 0 -1] - sage: M._magma_init_(magma) # optional - magma + sage: M._magma_init_(magma) 'RSpace(_sage_[...],2,_sage_ref...)' - sage: m = magma(M); m # optional - magma + sage: m = magma(M); m Full RSpace of degree 2 over Integer Ring Inner Product Matrix: [ 1 0] [ 0 -1] - sage: m.Type() # optional - magma + sage: m.Type() ModTupRng - sage: m.sage() # optional - magma + sage: m.sage() Ambient free quadratic module of rank 2 over the principal ideal domain Integer Ring Inner product matrix: [ 1 0] [ 0 -1] - sage: m.sage() is M # optional - magma + sage: m.sage() is M True Now over a field:: + sage: # optional - magma sage: N = FreeModule(QQ,2,inner_product_matrix=A); N Ambient quadratic space of dimension 2 over Rational Field Inner product matrix: [ 1 0] [ 0 -1] - sage: n = magma(N); n # optional - magma + sage: n = magma(N); n Full Vector space of degree 2 over Rational Field Inner Product Matrix: [ 1 0] [ 0 -1] - sage: n.Type() # optional - magma + sage: n.Type() ModTupFld - sage: n.sage() # optional - magma + sage: n.sage() Ambient quadratic space of dimension 2 over Rational Field Inner product matrix: [ 1 0] [ 0 -1] - sage: n.sage() is N # optional - magma + sage: n.sage() is N True How about some inexact fields:: - sage: # needs sage.symbolic + sage: # optional - magma, needs sage.symbolic sage: v = vector(RR, [1, pi, 5/6]) sage: F = v.parent() - sage: M = magma(F); M # optional - magma + sage: M = magma(F); M Full Vector space of degree 3 over Real field of precision 15 - sage: M.Type() # optional - magma + sage: M.Type() ModTupFld - sage: m = M.sage(); m # optional - magma + sage: m = M.sage(); m Vector space of dimension 3 over Real Field with 53 bits of precision - sage: m is F # optional - magma + sage: m is F True For interval fields, we can convert to Magma but there is no interval field in Magma so we cannot convert back:: - sage: # needs sage.symbolic + sage: # optional - magma, needs sage.symbolic sage: v = vector(RealIntervalField(100), [1, pi, 0.125]) sage: F = v.parent() - sage: M = magma(v.parent()); M # optional - magma + sage: M = magma(v.parent()); M Full Vector space of degree 3 over Real field of precision 30 - sage: M.Type() # optional - magma + sage: M.Type() ModTupFld - sage: m = M.sage(); m # optional - magma + sage: m = M.sage(); m Vector space of dimension 3 over Real Field with 100 bits of precision - sage: m is F # optional - magma + sage: m is F False """ K = magma(self.base_ring()) @@ -3437,7 +3445,7 @@ def _macaulay2_(self, macaulay2=None): EXAMPLES:: sage: R = QQ^2 - sage: macaulay2(R) # optional - macaulay2 + sage: macaulay2(R) # optional - macaulay2 2 QQ """ @@ -3810,13 +3818,14 @@ def intersection(self, other): We intersect two modules over the ring of integers of a number field:: + sage: # needs sage.rings.number_field sage: x = polygen(ZZ, 'x') - sage: L. = NumberField(x^2 - x + 2) # needs sage.rings.number_field + sage: L. = NumberField(x^2 - x + 2) sage: OL = L.ring_of_integers() sage: V = L**3 - sage: W1 = V.span([[0,w/5,0], [1,0,-1/17]], OL) # needs sage.rings.number_field - sage: W2 = V.span([[0,(1-w)/5,0]], OL) # needs sage.rings.number_field - sage: W1.intersection(W2) # needs sage.rings.number_field + sage: W1 = V.span([[0,w/5,0], [1,0,-1/17]], OL) + sage: W2 = V.span([[0,(1-w)/5,0]], OL) + sage: W1.intersection(W2) Free module of degree 3 and rank 1 over Maximal Order in Number Field in w with defining polynomial x^2 - x + 2 Echelon basis matrix: diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index ca1a6a25dec..b801cb2b27e 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1078,37 +1078,40 @@ cdef class FreeModuleElement(Vector): # abstract base class INPUT: - ``dtype`` -- the `numpy dtype `_ - of the returned array + of the returned array EXAMPLES:: + sage: # needs numpy sage: v = vector([1,2,3]) - sage: v.numpy() # needs numpy + sage: v.numpy() array([1, 2, 3], dtype=object) - sage: v.numpy() * v.numpy() # needs numpy + sage: v.numpy() * v.numpy() array([1, 4, 9], dtype=object) sage: vector(QQ, [1, 2, 5/6]).numpy() # needs numpy array([1, 2, 5/6], dtype=object) - By default the ``object`` `dtype `_ is used. + By default, the ``object`` `dtype `_ is used. Alternatively, the desired dtype can be passed in as a parameter:: + sage: # needs numpy sage: v = vector(QQ, [1, 2, 5/6]) - sage: v.numpy() # needs numpy + sage: v.numpy() array([1, 2, 5/6], dtype=object) - sage: v.numpy(dtype=float) # needs numpy + sage: v.numpy(dtype=float) array([1. , 2. , 0.83333333]) - sage: v.numpy(dtype=int) # needs numpy + sage: v.numpy(dtype=int) array([1, 2, 0]) - sage: import numpy # needs numpy - sage: v.numpy(dtype=numpy.uint8) # needs numpy + sage: import numpy + sage: v.numpy(dtype=numpy.uint8) array([1, 2, 0], dtype=uint8) Passing a dtype of None will let numpy choose a native type, which can be more efficient but may have unintended consequences:: - sage: v.numpy(dtype=None) # needs numpy + sage: # needs numpy + sage: v.numpy(dtype=None) array([1. , 2. , 0.83333333]) sage: w = vector(ZZ, [0, 1, 2^63 -1]); w @@ -1127,7 +1130,9 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: vector([1, 1/2, QQ['x'].0]).numpy(dtype=float) # needs numpy Traceback (most recent call last): ... - ValueError: Could not convert vector over Univariate Polynomial Ring in x over Rational Field to numpy array of type <... 'float'>: setting an array element with a sequence. + ValueError: Could not convert vector over Univariate Polynomial Ring in x + over Rational Field to numpy array of type <... 'float'>: + setting an array element with a sequence. """ from numpy import array try: @@ -1665,12 +1670,12 @@ cdef class FreeModuleElement(Vector): # abstract base class INPUT: - - ``p`` - default: 2 - ``p`` can be a real number greater than 1, + - ``p`` - default: 2 -- ``p`` can be a real number greater than 1, infinity (``oo`` or ``Infinity``), or a symbolic expression. - - `p=1`: the taxicab (Manhattan) norm - - `p=2`: the usual Euclidean norm (the default) - - `p=\infty`: the maximum entry (in absolute value) + - `p=1`: the taxicab (Manhattan) norm + - `p=2`: the usual Euclidean norm (the default) + - `p=\infty`: the maximum entry (in absolute value) .. NOTE:: @@ -1702,10 +1707,12 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v=vector(RDF,[1,2,3]) sage: v.norm(5) 3.077384885394063 - sage: v.norm(pi/2) #abs tol 1e-15 # needs sage.symbolic + + sage: # needs sage.symbolic + sage: v.norm(pi/2) # abs tol 1e-15 4.216595864704748 - sage: _=var('a b c d p'); v=vector([a, b, c, d]) # needs sage.symbolic - sage: v.norm(p) # needs sage.symbolic + sage: _ = var('a b c d p'); v = vector([a, b, c, d]) + sage: v.norm(p) (abs(a)^p + abs(b)^p + abs(c)^p + abs(d)^p)^(1/p) Notice that the result may be a symbolic expression, owing to @@ -1718,14 +1725,15 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: nrm.parent() Rational Field + sage: # needs sage.symbolic sage: v = vector(QQ, [3, 5]) - sage: nrm = v.norm(); nrm # needs sage.symbolic + sage: nrm = v.norm(); nrm sqrt(34) - sage: nrm.parent() # needs sage.symbolic + sage: nrm.parent() Symbolic Ring - sage: numeric = N(nrm); numeric # needs sage.symbolic + sage: numeric = N(nrm); numeric 5.83095189484... - sage: numeric.parent() # needs sage.symbolic + sage: numeric.parent() Real Field with 53 bits of precision TESTS: @@ -2303,7 +2311,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v = vector(RDF, (1,2)) sage: A = plot(v) # needs sage.plot sage: B = v.plot() # needs sage.plot - sage: A+B # should just show one vector # needs sage.plot + sage: A + B # should just show one vector # needs sage.plot Graphics object consisting of 2 graphics primitives Examples of the plot types:: @@ -2374,12 +2382,13 @@ cdef class FreeModuleElement(Vector): # abstract base class :: - sage: plot(u, start=v) #test when coordinate dimension mismatch exists # needs sage.plot + sage: # needs sage.plot + sage: plot(u, start=v) #test when coordinate dimension mismatch exists Traceback (most recent call last): ... ValueError: vector coordinates are not of the same dimension - sage: P = plot(v, start=z) # test when start coordinates are passed as a tuple # needs sage.plot - sage: P = plot(v, start=list(z)) # test when start coordinates are passed as a list # needs sage.plot + sage: P = plot(v, start=z) # test when start coordinates are passed as a tuple + sage: P = plot(v, start=list(z)) # test when start coordinates are passed as a list """ # Give sensible defaults based on the vector length if plot_type is None: @@ -2777,9 +2786,10 @@ cdef class FreeModuleElement(Vector): # abstract base class TESTS:: - sage: F = GF(previous_prime(2^32)) # needs sage.rings.finite_rings - sage: v = random_vector(F, 3) # needs sage.rings.finite_rings - sage: w = random_vector(F, 3) # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F = GF(previous_prime(2^32)) + sage: v = random_vector(F, 3) + sage: w = random_vector(F, 3) sage: vh = v.cross_product_matrix() sage: vh*w == v.cross_product(w) True @@ -2787,8 +2797,8 @@ cdef class FreeModuleElement(Vector): # abstract base class True sage: vh.is_alternating() True - sage: v = random_vector(F, 7) # needs sage.rings.finite_rings - sage: w = random_vector(F, 7) # needs sage.rings.finite_rings + sage: v = random_vector(F, 7) + sage: w = random_vector(F, 7) sage: vh = v.cross_product_matrix() sage: vh*w == v.cross_product(w) True @@ -2796,7 +2806,7 @@ cdef class FreeModuleElement(Vector): # abstract base class True sage: vh.is_alternating() True - sage: random_vector(F, 5).cross_product_matrix() # needs sage.rings.finite_rings + sage: random_vector(F, 5).cross_product_matrix() Traceback (most recent call last): ... TypeError: Cross product only defined for vectors of length three or seven, not 5 @@ -2889,42 +2899,56 @@ cdef class FreeModuleElement(Vector): # abstract base class :: sage: parent(vector(QQ,[1,2,3,4]).pairwise_product(vector(ZZ['x']['y'],[1,2,3,4]))) - Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 4 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field sage: parent(vector(ZZ['x']['y'],[1,2,3,4]).pairwise_product(vector(QQ,[1,2,3,4]))) - Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 4 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field :: sage: parent(vector(QQ['x'],[1,2,3,4]).pairwise_product(vector(ZZ['x']['y'],[1,2,3,4]))) - Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 4 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field sage: parent(vector(ZZ['x']['y'],[1,2,3,4]).pairwise_product(vector(QQ['x'],[1,2,3,4]))) - Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 4 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field :: sage: parent(vector(QQ['y'],[1,2,3,4]).pairwise_product(vector(ZZ['x']['y'],[1,2,3,4]))) - Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 4 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field sage: parent(vector(ZZ['x']['y'],[1,2,3,4]).pairwise_product(vector(QQ['y'],[1,2,3,4]))) - Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field + Ambient free module of rank 4 over the integral domain + Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field :: sage: parent(vector(ZZ['x'],[1,2,3,4]).pairwise_product(vector(ZZ['y'],[1,2,3,4]))) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + TypeError: no common canonical parent for objects with parents: + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' sage: parent(vector(ZZ['x'],[1,2,3,4]).pairwise_product(vector(QQ['y'],[1,2,3,4]))) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + TypeError: no common canonical parent for objects with parents: + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in x over Integer Ring' and + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' sage: parent(vector(QQ['x'],[1,2,3,4]).pairwise_product(vector(ZZ['y'],[1,2,3,4]))) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' + TypeError: no common canonical parent for objects with parents: + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 4 over the integral domain Univariate Polynomial Ring in y over Integer Ring' sage: parent(vector(QQ['x'],[1,2,3,4]).pairwise_product(vector(QQ['y'],[1,2,3,4]))) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + TypeError: no common canonical parent for objects with parents: + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 4 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' sage: v = vector({1: 1, 3: 2}) # test sparse vectors sage: w = vector({0: 6, 3: -4}) sage: v.pairwise_product(w) @@ -3040,7 +3064,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: v.curl() # needs sage.symbolic (x, y, z) |--> (0, 0, 2) - In two-dimensions, this returns a scalar value:: + In two dimensions, this returns a scalar value:: sage: R. = QQ[] sage: vector([-y, x]).curl() @@ -3200,7 +3224,7 @@ cdef class FreeModuleElement(Vector): # abstract base class We test this by building a specialized vector space with a non-standard inner product, and constructing a test vector in this space. :: - sage: V = VectorSpace(CDF, 2, inner_product_matrix = [[2,1],[1,5]]) + sage: V = VectorSpace(CDF, 2, inner_product_matrix=[[2,1],[1,5]]) sage: v = vector(CDF, [2-3*I, 4+5*I]) sage: w = V(v) sage: w.parent() @@ -3269,11 +3293,11 @@ cdef class FreeModuleElement(Vector): # abstract base class through to subspaces. :: sage: ipm = matrix(ZZ,[[2,0,-1], [0,2,0], [-1,0,6]]) - sage: M = FreeModule(ZZ, 3, inner_product_matrix = ipm) + sage: M = FreeModule(ZZ, 3, inner_product_matrix=ipm) sage: v = M([1,0,0]) sage: v.inner_product(v) 2 - sage: K = M.span_of_basis([[0/2,-1/2,-1/2], [0,1/2,-1/2],[2,0,0]]) + sage: K = M.span_of_basis([[0/2,-1/2,-1/2], [0,1/2,-1/2], [2,0,0]]) sage: (K.0).inner_product(K.0) 2 sage: w = M([1,3,-1]) @@ -3309,7 +3333,7 @@ cdef class FreeModuleElement(Vector): # abstract base class But with an inner product defined, this method will check that the input is a vector or free module element. :: - sage: W = VectorSpace(RDF, 2, inner_product_matrix = matrix(RDF, 2, [1.0,2.0,3.0,4.0])) + sage: W = VectorSpace(RDF, 2, inner_product_matrix=matrix(RDF, 2, [1.0,2.0,3.0,4.0])) sage: v = W([2.0, 4.0]) sage: v.inner_product(5) Traceback (most recent call last): @@ -3429,7 +3453,9 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: z = w.outer_product(v) # needs sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 1 dense matrices over Finite Field of size 5' and 'Full MatrixSpace of 1 by 4 dense matrices over Finite Field of size 7' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 1 dense matrices over Finite Field of size 5' and + 'Full MatrixSpace of 1 by 4 dense matrices over Finite Field of size 7' And some inputs don't make any sense at all. :: @@ -3437,7 +3463,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: z=w.outer_product(6) Traceback (most recent call last): ... - TypeError: right operand in an outer product must be a vector, not an element of Integer Ring + TypeError: right operand in an outer product must be a vector, + not an element of Integer Ring """ if not isinstance(right, FreeModuleElement): raise TypeError('right operand in an outer product must be a vector, not an element of %s' % right.parent()) @@ -3594,17 +3621,17 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: vector(QQ, [1, 2, 3])._macaulay2_() # optional - macaulay2 + sage: vector(QQ, [1, 2, 3])._macaulay2_() # optional - macaulay2 | 1 | | 2 | | 3 | - sage: _.ring() # optional - macaulay2 + sage: _.ring() # optional - macaulay2 QQ :: sage: R. = QQ[] - sage: macaulay2(vector(R, [1, x+y])) # optional - macaulay2 + sage: macaulay2(vector(R, [1, x+y])) # optional - macaulay2 | 1 | | x+y | @@ -4698,16 +4725,20 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): sage: from sage.modules.free_module_element import FreeModuleElement_generic_sparse sage: def S(R,n): ....: return FreeModule(R, n, sparse=True) - sage: FreeModuleElement_generic_sparse(S(RR,5), {0:-1, 2:2/3, 3:pi, 4:oo}) # needs sage.symbolic + + sage: # needs sage.symbolic + sage: FreeModuleElement_generic_sparse(S(RR,5), {0:-1, 2:2/3, 3:pi, 4:oo}) (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), [-1,0,2/3,pi,oo]) # needs sage.symbolic + sage: FreeModuleElement_generic_sparse(S(RR,5), [-1,0,2/3,pi,oo]) (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), (-1,0,2/3,pi,oo)) # needs sage.symbolic + sage: FreeModuleElement_generic_sparse(S(RR,5), (-1,0,2/3,pi,oo)) (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) - sage: FreeModuleElement_generic_sparse(S(RR,5), Sequence([-1,0,2/3,pi,oo])) # needs sage.symbolic + sage: FreeModuleElement_generic_sparse(S(RR,5), Sequence([-1,0,2/3,pi,oo])) (-1.00000000000000, 0.000000000000000, 0.666666666666667, 3.14159265358979, +infinity) + sage: FreeModuleElement_generic_sparse(S(RR,0), 0) () + sage: from collections import defaultdict sage: D = defaultdict(RR) sage: D[0] = -1 diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index 6354deabfd5..f8cb98c3c6b 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -485,8 +485,9 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Different gluings can be composed:: - sage: D4 = IntegralLattice("D4") # needs sage.graphs - sage: D4.discriminant_group() # needs sage.graphs + sage: # needs sage.graphs + sage: D4 = IntegralLattice("D4") + sage: D4.discriminant_group() Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] @@ -497,23 +498,23 @@ def IntegralLatticeGluing(Lattices, glue, return_embeddings=False): Gram matrix of the quadratic form with values in Q/2Z: [1/2 0] [ 0 1/2] - sage: g1 = D4.discriminant_group().gens()[0] # needs sage.graphs + sage: g1 = D4.discriminant_group().gens()[0] sage: g2 = L2.discriminant_group().gens()[0] + L2.discriminant_group().gens()[1] - sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) # needs sage.graphs - sage: AD6 = D6.discriminant_group() # needs sage.graphs - sage: AD6.normal_form() # needs sage.graphs + sage: D6, phi = IntegralLatticeGluing([D4, L2], [[g1, g2]], True) + sage: AD6 = D6.discriminant_group() + sage: AD6.normal_form() Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [3/2 0] [ 0 3/2] - sage: f1, g1 = AD6.normal_form().gens() # needs sage.graphs + sage: f1, g1 = AD6.normal_form().gens() sage: f2, g2 = L2.discriminant_group().gens() - sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) # needs sage.graphs - sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) # needs sage.graphs - sage: x = D4([1, 0, 0, 0]) # needs sage.graphs - sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x))) == x.inner_product(x) # needs sage.graphs + sage: E8, psi = IntegralLatticeGluing([D6, L2], [[f1, f2], [g1, g2]], True) + sage: D4embed = E8.sublattice(psi[0](phi[0].image()).basis_matrix()) + sage: x = D4([1, 0, 0, 0]) + sage: psi[0](phi[0](x)).inner_product(psi[0](phi[0](x))) == x.inner_product(x) True - sage: D4embed # needs sage.graphs + sage: D4embed Lattice of degree 8 and rank 4 over Integer Ring Basis matrix: [1 0 0 0 0 0 0 0] @@ -1183,21 +1184,21 @@ def orthogonal_group(self, gens=None, is_finite=None): The group acts from the right on the lattice and its discriminant group:: - sage: # needs sage.graphs + sage: # needs sage.graphs sage.libs.gap sage: x = A4.an_element() - sage: g = Aut.an_element(); g # needs sage.libs.gap + sage: g = Aut.an_element(); g [-1 -1 -1 0] [ 0 0 1 0] [ 0 0 -1 -1] [ 0 1 1 1] - sage: x*g # needs sage.libs.gap + sage: x*g (-1, -1, -1, 0) - sage: (x*g).parent() == A4 # needs sage.libs.gap + sage: (x*g).parent() == A4 True - sage: (g*x).parent() # needs sage.libs.gap + sage: (g*x).parent() Vector space of dimension 4 over Rational Field - sage: y = A4.discriminant_group().an_element() # needs sage.libs.gap - sage: y*g # needs sage.libs.gap + sage: y = A4.discriminant_group().an_element() + sage: y*g (4) If the group is finite we can compute the usual things:: @@ -1463,6 +1464,7 @@ def LLL(self): sage: L = IntegralLattice('A2') # needs sage.graphs sage: L.lll() == L # needs sage.graphs True + sage: G = matrix(ZZ, 3, [0,1,0, 1,0,0, 0,0,7]) sage: V = matrix(ZZ, 3, [-14,-15,-15, -4,1,16, -5,-5,-4]) sage: L = IntegralLattice(V * G * V.T) diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 91a2bad58cf..037cde8681b 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -166,13 +166,15 @@ def _pari_init_(self): 2*x^2 + 3*x*y + 4*y^2 sage: f._pari_init_() 'Qfb(2,3,4)' - sage: pari(f) # needs sage.libs.pari + + sage: # needs sage.libs.pari + sage: pari(f) Qfb(2, 3, 4) - sage: type(pari(f)) # needs sage.libs.pari + sage: type(pari(f)) <... 'cypari2.gen.Gen'> - sage: gp(f) # needs sage.libs.pari + sage: gp(f) Qfb(2, 3, 4) - sage: type(gp(f)) # needs sage.libs.pari + sage: type(gp(f)) """ return 'Qfb(%s,%s,%s)' % (self._a, self._b, self._c) @@ -188,16 +190,18 @@ def __mul__(self, right): We explicitly compute in the group of classes of positive definite binary quadratic forms of discriminant -23:: + sage: # needs sage.libs.pari sage: R = BinaryQF_reduced_representatives(-23, primitive_only=False); R [x^2 + x*y + 6*y^2, 2*x^2 - x*y + 3*y^2, 2*x^2 + x*y + 3*y^2] - sage: R[0] * R[0] # needs sage.libs.pari + sage: R[0] * R[0] x^2 + x*y + 6*y^2 - sage: R[1] * R[1] # needs sage.libs.pari + sage: R[1] * R[1] 4*x^2 + 3*x*y + 2*y^2 - sage: (R[1] * R[1]).reduced_form() # needs sage.libs.pari + sage: (R[1] * R[1]).reduced_form() 2*x^2 + x*y + 3*y^2 - sage: (R[1] * R[1] * R[1]).reduced_form() # needs sage.libs.pari + sage: (R[1] * R[1] * R[1]).reduced_form() x^2 + x*y + 6*y^2 + sage: q1 = BinaryQF(1, 1, 4) sage: M = Matrix(ZZ, [[1, 3], [0, 1]]) sage: q1*M @@ -877,21 +881,22 @@ def reduced_form(self, transformation=False, algorithm="default"): ....: f = BinaryQF([randrange(-10^3, 10^3) for _ in 'abc']) ....: if not f.discriminant().is_square(): ....: break - sage: algos = ['default', 'pari'] + sage: algos = ['default'] + sage: assert pari; algos.append('pari') # needs sage.libs.pari sage: if f.discriminant() > 0: ....: algos.append('sage') sage: a = choice(algos) - sage: g = f.reduced_form(algorithm=a) # needs sage.libs.pari - sage: g.is_reduced() # needs sage.libs.pari + sage: g = f.reduced_form(algorithm=a) + sage: g.is_reduced() True - sage: g.is_equivalent(f) # needs sage.libs.pari + sage: g.is_equivalent(f) True - sage: g,M = f.reduced_form(transformation=True, algorithm=a) # needs sage.libs.pari - sage: g.is_reduced() # needs sage.libs.pari + sage: g,M = f.reduced_form(transformation=True, algorithm=a) + sage: g.is_reduced() True - sage: g.is_equivalent(f) # needs sage.libs.pari + sage: g.is_equivalent(f) True - sage: f * M == g # needs sage.libs.pari + sage: f * M == g True """ if self.is_reduced(): @@ -1258,16 +1263,17 @@ def is_equivalent(self, other, proper=True): EXAMPLES:: + sage: # needs sage.libs.pari sage: Q3 = BinaryQF(4, 4, 15) sage: Q2 = BinaryQF(4, -4, 15) - sage: Q2.is_equivalent(Q3) # needs sage.libs.pari + sage: Q2.is_equivalent(Q3) True sage: a = BinaryQF([33, 11, 5]) - sage: b = a.reduced_form(); b # needs sage.libs.pari + sage: b = a.reduced_form(); b 5*x^2 - x*y + 27*y^2 - sage: a.is_equivalent(b) # needs sage.libs.pari + sage: a.is_equivalent(b) True - sage: a.is_equivalent(BinaryQF((3, 4, 5))) # needs sage.libs.pari + sage: a.is_equivalent(BinaryQF((3, 4, 5))) False Some indefinite examples:: @@ -1283,13 +1289,14 @@ def is_equivalent(self, other, proper=True): We check that :trac:`25888` is fixed:: + sage: # needs sage.libs.pari sage: Q1 = BinaryQF(3, 4, -2) sage: Q2 = BinaryQF(-2, 4, 3) - sage: Q1.is_equivalent(Q2) == Q2.is_equivalent(Q1) # needs sage.libs.pari + sage: Q1.is_equivalent(Q2) == Q2.is_equivalent(Q1) True - sage: Q1.is_equivalent(Q2, proper=False) == Q2.is_equivalent(Q1, proper=False) # needs sage.libs.pari + sage: Q1.is_equivalent(Q2, proper=False) == Q2.is_equivalent(Q1, proper=False) True - sage: Q1.is_equivalent(Q2, proper=True) # needs sage.libs.pari + sage: Q1.is_equivalent(Q2, proper=True) True We check that the first part of :trac:`29028` is fixed:: @@ -1612,6 +1619,7 @@ def solve_integer(self, n, *, algorithm="general"): Also when using the ``"cornacchia"`` algorithm:: + asge: # needs sage.libs.pari sage: abc = [1, 0, randrange(1,10^3)] sage: Q = BinaryQF(abc) sage: n = random_prime(10^9) # needs sage.libs.pari @@ -1745,13 +1753,14 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): 2 sage: QuadraticField(-13*4, 'a').class_number() # needs sage.rings.number_field 2 - sage: p = next_prime(2^20); p # needs sage.libs.pari + + sage: # needs sage.libs.pari + sage: p = next_prime(2^20); p 1048583 - sage: len(BinaryQF_reduced_representatives(-p)) # needs sage.libs.pari + sage: len(BinaryQF_reduced_representatives(-p)) 689 - sage: QuadraticField(-p, 'a').class_number() # needs sage.libs.pari sage.rings.number_field + sage: QuadraticField(-p, 'a').class_number() # needs sage.rings.number_field 689 - sage: BinaryQF_reduced_representatives(-23*9) [x^2 + x*y + 52*y^2, 2*x^2 - x*y + 26*y^2, @@ -1762,7 +1771,7 @@ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True): 6*x^2 - 3*x*y + 9*y^2, 6*x^2 + 3*x*y + 9*y^2, 8*x^2 + 7*x*y + 8*y^2] - sage: BinaryQF_reduced_representatives(-23*9, primitive_only=True) # needs sage.libs.pari + sage: BinaryQF_reduced_representatives(-23*9, primitive_only=True) [x^2 + x*y + 52*y^2, 2*x^2 - x*y + 26*y^2, 2*x^2 + x*y + 26*y^2, diff --git a/src/sage/quadratic_forms/quadratic_form__neighbors.py b/src/sage/quadratic_forms/quadratic_form__neighbors.py index b2299e19fc2..ba2e51ac74d 100644 --- a/src/sage/quadratic_forms/quadratic_form__neighbors.py +++ b/src/sage/quadratic_forms/quadratic_form__neighbors.py @@ -262,16 +262,18 @@ def neighbor_iteration(seeds, p, mass=None, max_classes=ZZ(10)**3, sage: Q = QuadraticForm(ZZ, 3, [1, 0, 0, 2, 1, 3]) sage: Q.det() 46 - sage: mass = Q.conway_mass() # needs sage.symbolic - sage: g1 = neighbor_iteration([Q], 3, # long time # needs sage.symbolic + + sage: # needs sage.symbolic + sage: mass = Q.conway_mass() + sage: g1 = neighbor_iteration([Q], 3, # long time ....: mass=mass, algorithm='random') - sage: g2 = neighbor_iteration([Q], 3, algorithm='exhaustion') # long time + sage: g2 = neighbor_iteration([Q], 3, algorithm='exhaustion') # long time sage: g3 = neighbor_iteration([Q], 3, algorithm='orbits') # needs sage.libs.gap - sage: mass == sum(1/q.number_of_automorphisms() for q in g1) # long time, needs sage.symbolic + sage: mass == sum(1/q.number_of_automorphisms() for q in g1) # long time True - sage: mass == sum(1/q.number_of_automorphisms() for q in g2) # long time, needs sage.symbolic + sage: mass == sum(1/q.number_of_automorphisms() for q in g2) # long time True - sage: mass == sum(1/q.number_of_automorphisms() for q in g3) # needs sage.libs.gap sage.symbolic + sage: mass == sum(1/q.number_of_automorphisms() for q in g3) # needs sage.libs.gap True TESTS:: @@ -371,12 +373,12 @@ def orbits_lines_mod_p(self, p): sage: Q = QuadraticForm(ZZ, 3, [1, 0, 0, 2, 1, 3]) sage: Q.orbits_lines_mod_p(2) # needs sage.libs.gap sage.libs.pari [(0, 0, 1), - (0, 1, 0), - (0, 1, 1), - (1, 0, 0), - (1, 0, 1), - (1, 1, 0), - (1, 1, 1)] + (0, 1, 0), + (0, 1, 1), + (1, 0, 0), + (1, 0, 1), + (1, 1, 0), + (1, 1, 1)] """ from sage.libs.gap.libgap import libgap from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF diff --git a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py index bf7346b999d..f2d1f89188e 100644 --- a/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +++ b/src/sage/quadratic_forms/quadratic_form__ternary_Tornaria.py @@ -293,12 +293,13 @@ def hasse_conductor(self): EXAMPLES:: + sage: # needs sage.libs.pari sage: Q = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) - sage: Q.hasse_invariant(2) # needs sage.libs.pari + sage: Q.hasse_invariant(2) -1 - sage: Q.hasse_invariant(37) # needs sage.libs.pari + sage: Q.hasse_invariant(37) -1 - sage: Q.hasse_conductor() # needs sage.libs.pari + sage: Q.hasse_conductor() 74 sage: DiagonalQuadraticForm(ZZ, [1, 1, 1]).hasse_conductor() # needs sage.libs.pari @@ -322,14 +323,15 @@ def clifford_invariant(self, p): For hyperbolic spaces, the Clifford invariant is +1:: + sage: # needs sage.libs.pari sage: H = QuadraticForm(ZZ, 2, [0, 1, 0]) - sage: H.clifford_invariant(2) # needs sage.libs.pari + sage: H.clifford_invariant(2) 1 - sage: (H + H).clifford_invariant(2) # needs sage.libs.pari + sage: (H + H).clifford_invariant(2) 1 - sage: (H + H + H).clifford_invariant(2) # needs sage.libs.pari + sage: (H + H + H).clifford_invariant(2) 1 - sage: (H + H + H + H).clifford_invariant(2) # needs sage.libs.pari + sage: (H + H + H + H).clifford_invariant(2) 1 """ n = self.dim() % 8 @@ -356,12 +358,13 @@ def clifford_conductor(self): EXAMPLES:: + sage: # needs sage.libs.pari sage: Q = QuadraticForm(ZZ, 3, [1, 0, -1, 2, -1, 5]) - sage: Q.clifford_invariant(2) # needs sage.libs.pari + sage: Q.clifford_invariant(2) 1 - sage: Q.clifford_invariant(37) # needs sage.libs.pari + sage: Q.clifford_invariant(37) -1 - sage: Q.clifford_conductor() # needs sage.libs.pari + sage: Q.clifford_conductor() 37 sage: DiagonalQuadraticForm(ZZ, [1, 1, 1]).clifford_conductor() # needs sage.libs.pari @@ -371,14 +374,15 @@ def clifford_conductor(self): For hyperbolic spaces, the Clifford conductor is 1:: + sage: # needs sage.libs.pari sage: H = QuadraticForm(ZZ, 2, [0, 1, 0]) - sage: H.clifford_conductor() # needs sage.libs.pari + sage: H.clifford_conductor() 1 - sage: (H + H).clifford_conductor() # needs sage.libs.pari + sage: (H + H).clifford_conductor() 1 - sage: (H + H + H).clifford_conductor() # needs sage.libs.pari + sage: (H + H + H).clifford_conductor() 1 - sage: (H + H + H + H).clifford_conductor() # needs sage.libs.pari + sage: (H + H + H + H).clifford_conductor() 1 """ return prod([x[0] for x in factor(2 * self.level()) @@ -481,20 +485,21 @@ def xi_rec(self,p): EXAMPLES:: + sage: # needs sage.libs.pari sage: Q1 = QuadraticForm(ZZ, 3, [1, 1, 1, 14, 3, 14]) sage: Q2 = QuadraticForm(ZZ, 3, [2, -1, 0, 2, 0, 50]) - sage: [Q1.clifford_conductor(), # equivalent over Q # needs sage.libs.pari + sage: [Q1.clifford_conductor(), # equivalent over Q ....: Q2.clifford_conductor()] [3, 3] - sage: Q1.is_locally_equivalent_to(Q2) # not in the same genus # needs sage.libs.pari + sage: Q1.is_locally_equivalent_to(Q2) # not in the same genus False - sage: [Q1.delta(), Q2.delta()] # needs sage.libs.pari + sage: [Q1.delta(), Q2.delta()] [480, 480] - sage: factor(480) # needs sage.libs.pari + sage: factor(480) 2^5 * 3 * 5 - sage: list(map(Q1.xi_rec, [-1,2,3,5])) # needs sage.libs.pari + sage: list(map(Q1.xi_rec, [-1,2,3,5])) [-1, -1, -1, 1] - sage: list(map(Q2.xi_rec, [-1,2,3,5])) # needs sage.libs.pari + sage: list(map(Q2.xi_rec, [-1,2,3,5])) [-1, -1, -1, -1] """ return self.reciprocal().xi(p) @@ -543,8 +548,9 @@ def representation_vector_list(self, B, maxvectors=10**8): EXAMPLES:: + sage: # needs sage.libs.pari sage: Q = DiagonalQuadraticForm(ZZ, [1, 1]) - sage: Q.representation_vector_list(10) # needs sage.libs.pari + sage: Q.representation_vector_list(10) [[(0, 0)], [(0, 1), (0, -1), (1, 0), (-1, 0)], [(1, 1), (-1, -1), (1, -1), (-1, 1)], @@ -555,9 +561,9 @@ def representation_vector_list(self, B, maxvectors=10**8): [], [(2, 2), (-2, -2), (2, -2), (-2, 2)], [(0, 3), (0, -3), (3, 0), (-3, 0)]] - sage: list(map(len, _)) # needs sage.libs.pari + sage: list(map(len, _)) [1, 4, 4, 0, 4, 8, 0, 0, 4, 4] - sage: Q.representation_number_list(10) # needs sage.libs.pari + sage: Q.representation_number_list(10) [1, 4, 4, 0, 4, 8, 0, 0, 4, 4] TESTS:: diff --git a/src/sage/quadratic_forms/quadratic_form__theta.py b/src/sage/quadratic_forms/quadratic_form__theta.py index c827772037c..7aa257d5e71 100644 --- a/src/sage/quadratic_forms/quadratic_form__theta.py +++ b/src/sage/quadratic_forms/quadratic_form__theta.py @@ -287,13 +287,14 @@ def theta_series_degree_2(Q, prec): EXAMPLES:: + sage: # needs sage.symbolic sage: Q2 = QuadraticForm(ZZ, 4, [1,1,1,1, 1,0,0, 1,0, 1]) - sage: S = Q2.theta_series_degree_2(10) # needs sage.symbolic - sage: S[(0,0,2)] # needs sage.symbolic + sage: S = Q2.theta_series_degree_2(10) + sage: S[(0,0,2)] 24 - sage: S[(1,0,1)] # needs sage.symbolic + sage: S[(1,0,1)] 144 - sage: S[(1,1,1)] # needs sage.symbolic + sage: S[(1,1,1)] 192 AUTHORS: diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index ee07b83d147..ddcfbfdb6a9 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -579,19 +579,20 @@ def _find_zeros_mod_p(a, b, c, r, s, t, p): EXAMPLES:: + sage: # needs sage.libs.pari sage: from sage.quadratic_forms.ternary import _find_zeros_mod_p sage: Q = TernaryQF([1, 2, 2, -1, 0, 0]) sage: p = 1009 - sage: zeros_1009 = _find_zeros_mod_p(1, 2, 2, -1, 0, 0, p) # needs sage.libs.pari - sage: len(zeros_1009) # needs sage.libs.pari + sage: zeros_1009 = _find_zeros_mod_p(1, 2, 2, -1, 0, 0, p) + sage: len(zeros_1009) 1010 - sage: zeros_1009.sort() # needs sage.libs.pari - sage: zeros_1009[0] # needs sage.libs.pari + sage: zeros_1009.sort() + sage: zeros_1009[0] (0, 32, 1) sage: Q((0, 32, 1)) 2018 - sage: zeros_2 = _find_zeros_mod_p(1, 2, 2, -1, 0, 0, 2) # needs sage.libs.pari - sage: zeros_2 # needs sage.libs.pari + sage: zeros_2 = _find_zeros_mod_p(1, 2, 2, -1, 0, 0, 2) + sage: zeros_2 [(0, 1, 0), (0, 0, 1), (1, 1, 1)] """ if p == 2: diff --git a/src/sage/quadratic_forms/ternary_qf.py b/src/sage/quadratic_forms/ternary_qf.py index a8854ba9811..119e8dfdc24 100644 --- a/src/sage/quadratic_forms/ternary_qf.py +++ b/src/sage/quadratic_forms/ternary_qf.py @@ -883,6 +883,7 @@ def find_p_neighbor_from_vec(self, p, v, mat=False): EXAMPLES:: + sage: # needs sage.libs.pari sage: Q = TernaryQF([1, 3, 3, -2, 0, -1]); Q Ternary quadratic form with integer coefficients: [1 3 3] @@ -890,18 +891,18 @@ def find_p_neighbor_from_vec(self, p, v, mat=False): sage: Q.disc() 29 sage: v = (9, 7, 1) - sage: v in Q.find_zeros_mod_p(11) # needs sage.libs.pari + sage: v in Q.find_zeros_mod_p(11) True - sage: Q11, M = Q.find_p_neighbor_from_vec(11, v, mat=True) # needs sage.libs.pari - sage: Q11 # needs sage.libs.pari + sage: Q11, M = Q.find_p_neighbor_from_vec(11, v, mat=True) + sage: Q11 Ternary quadratic form with integer coefficients: [1 2 4] [-1 -1 0] - sage: M # needs sage.libs.pari + sage: M [ -1 -5/11 7/11] [ 0 -10/11 3/11] [ 0 -3/11 13/11] - sage: Q(M) == Q11 # needs sage.libs.pari + sage: Q(M) == Q11 True """ if mat: @@ -918,21 +919,21 @@ def find_p_neighbors(self, p, mat=False): EXAMPLES:: - sage: Q0 = TernaryQF([1, 3, 3, -2, 0, -1]) - sage: Q0 + sage: # needs sage.libs.pari + sage: Q0 = TernaryQF([1, 3, 3, -2, 0, -1]); Q0 Ternary quadratic form with integer coefficients: [1 3 3] [-2 0 -1] - sage: neig = Q0.find_p_neighbors(5) # needs sage.libs.pari - sage: len(neig) # needs sage.libs.pari + sage: neig = Q0.find_p_neighbors(5) + sage: len(neig) 6 sage: Q1 = TernaryQF([1, 1, 10, 1, 1, 1]) sage: Q2 = TernaryQF([1, 2, 4, -1, -1, 0]) - sage: neig.count(Q0) # needs sage.libs.pari + sage: neig.count(Q0) 2 - sage: neig.count(Q1) # needs sage.libs.pari + sage: neig.count(Q1) 1 - sage: neig.count(Q2) # needs sage.libs.pari + sage: neig.count(Q2) 3 """ @@ -1669,14 +1670,16 @@ def _automorphisms_reduced_slow(self): sage: Q = TernaryQF([1, 1, 7, 0, 0, 0]) sage: Q.is_eisenstein_reduced() True - sage: auts = Q._automorphisms_reduced_slow() # long time (3s on sage.math, 2014) - sage: len(auts) # long time + + sage: # long time + sage: auts = Q._automorphisms_reduced_slow() # 3s on sage.math, 2014 + sage: len(auts) 8 - sage: A = auts[randint(0,7)] # long time - sage: Q(A) == Q # long time + sage: A = auts[randint(0,7)] + sage: Q(A) == Q True sage: Q = TernaryQF([3, 4, 5, 3, 3, 2]) - sage: Q._automorphisms_reduced_slow() # long time + sage: Q._automorphisms_reduced_slow() [ [1 0 0] [0 1 0] From e9643d8664feda9b8e19de739489cb393ec11ed6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Aug 2023 16:56:50 -0700 Subject: [PATCH 82/99] Use more block tags, fix # needs, docstring cosmetics --- src/sage/matrix/matrix2.pyx | 151 ++++++++++++----------- src/sage/matrix/special.py | 26 ++-- src/sage/modules/free_module.py | 4 +- src/sage/modules/free_module_element.pyx | 9 +- 4 files changed, 99 insertions(+), 91 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 35a161b16ba..d84c455fcbf 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -349,9 +349,11 @@ cdef class Matrix(Matrix1): True sage: X (-1, 2, 0, 0) + + sage: # needs sage.libs.pari sage: A = Matrix(Zmod(128), 2, 3, [5, 29, 33, 64, 0, 7]) sage: B = vector(Zmod(128), [31,39,56]) - sage: X = A.solve_left(B); X # needs sage.libs.pari + sage: X = A.solve_left(B); X (19, 83) sage: X * A == B True @@ -393,9 +395,10 @@ cdef class Matrix(Matrix1): The vector of constants needs to be compatible with the base ring of the coefficient matrix:: - sage: F. = FiniteField(27) # needs sage.rings.finite_rings - sage: b = vector(F, [a,a,a,a,a]) # needs sage.rings.finite_rings - sage: A.solve_left(b) # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(27) + sage: b = vector(F, [a,a,a,a,a]) + sage: A.solve_left(b) Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: ... @@ -4126,12 +4129,12 @@ cdef class Matrix(Matrix1): We check that number fields are handled by the right routine as part of typical right kernel computation. :: - sage" # needs sage.rings.number_field - sage: Q = QuadraticField(-7) # needs sage.rings.number_field - sage: a = Q.gen(0) # needs sage.rings.number_field - sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], [2+a, a, -7 + 5*a, -3+3*a]]) # needs sage.rings.number_field + sage: # needs sage.rings.number_field + sage: Q = QuadraticField(-7) + sage: a = Q.gen(0) + sage: A = matrix(Q, [[2, 5-a, 15-a, 16+4*a], [2+a, a, -7 + 5*a, -3+3*a]]) sage: set_verbose(1) - sage: A.right_kernel(algorithm='default') # needs sage.rings.number_field + sage: A.right_kernel(algorithm='default') verbose ... verbose 1 () computing right kernel matrix over a number field for 2x4 matrix verbose 1 () done computing right kernel matrix over a number field for 2x4 matrix @@ -5686,33 +5689,38 @@ cdef class Matrix(Matrix1): EXAMPLES:: -i sage: # needs sage.libs.pari + sage: # needs sage.libs.pari sage: t = matrix(QQ, 3, [3, 0, -2, 0, -2, 0, 0, 0, 0]); t [ 3 0 -2] [ 0 -2 0] [ 0 0 0] - sage: t.fcp('X') # factored charpoly # needs sage.libs.pari + sage: t.fcp('X') # factored charpoly (X - 3) * X * (X + 2) - sage: v = kernel(t*(t+2)); v # an invariant subspace + sage: v = kernel(t*(t+2)); v # an invariant subspace Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [0 1 0] [0 0 1] - sage: D = t.decomposition_of_subspace(v); D # needs sage.libs.pari + sage: D = t.decomposition_of_subspace(v); D [ (Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [0 0 1], True), (Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [0 1 0], True) ] - sage: t.restrict(D[0][0]) # needs sage.libs.pari + sage: t.restrict(D[0][0]) [0] - sage: t.restrict(D[1][0]) # needs sage.libs.pari + sage: t.restrict(D[1][0]) [-2] We do a decomposition over ZZ:: - sage: a = matrix(ZZ, 6, [0, 0, -2, 0, 2, 0, 2, -4, -2, 0, 2, 0, 0, 0, -2, -2, 0, 0, 2, 0, -2, -4, 2, -2, 0, 2, 0, -2, -2, 0, 0, 2, 0, -2, 0, 0]) + sage: a = matrix(ZZ, 6, [0, 0, -2, 0, 2, 0, + ....: 2, -4, -2, 0, 2, 0, + ....: 0, 0, -2, -2, 0, 0, + ....: 2, 0, -2, -4, 2, -2, + ....: 0, 2, 0, -2, -2, 0, + ....: 0, 2, 0, -2, 0, 0]) sage: a.decomposition_of_subspace(ZZ^6) # needs sage.libs.pari [ (Free module of degree 6 and rank 2 over Integer Ring Echelon basis matrix: @@ -5730,7 +5738,7 @@ i sage: # needs sage.libs.pari TESTS:: sage: t = matrix(QQ, 3, [3, 0, -2, 0, -2, 0, 0, 0, 0]) - sage: t.decomposition_of_subspace(v, check_restrict = False) == t.decomposition_of_subspace(v) # needs sage.libs.pari + sage: t.decomposition_of_subspace(v, check_restrict=False) == t.decomposition_of_subspace(v) # needs sage.libs.pari True """ if not sage.modules.free_module.is_FreeModule(M): @@ -6041,14 +6049,14 @@ i sage: # needs sage.libs.pari INPUT: - - ``format`` - ``None``, ``'all'`` or ``'galois'`` + - ``format`` -- ``None``, ``'all'`` or ``'galois'`` OUTPUT: Any format except ``None`` is just passed through. When the - format is ``None`` a choice is made about the style of the output. + format is ``None``, a choice is made about the style of the output. If there is an algebraically closed field that will contain the - possible eigenvalues, then 'all" of the eigenspaces are given. + possible eigenvalues, then ``'all'`` of the eigenspaces are given. However if this is not the case, then only one eigenspace is output for each irreducible factor of the characteristic polynomial. @@ -6100,48 +6108,48 @@ i sage: # needs sage.libs.pari r""" Compute the left eigenspaces of a matrix. - Note that ``eigenspaces_left()`` and ``left_eigenspaces()`` + Note that :meth:`eigenspaces_left` and :meth:`left_eigenspaces` are identical methods. Here "left" refers to the eigenvectors being placed to the left of the matrix. INPUT: - - ``self`` - a square matrix over an exact field. For inexact + - ``self`` -- a square matrix over an exact field. For inexact matrices consult the numerical or symbolic matrix classes. - - ``format`` - default: ``None`` + - ``format`` -- one of: - - ``'all'`` - attempts to create every eigenspace. This will + - ``'all'`` -- Attempts to create every eigenspace. This will always be possible for matrices with rational entries. - - ``'galois'`` - for each irreducible factor of the characteristic + - ``'galois'`` -- For each irreducible factor of the characteristic polynomial, a single eigenspace will be output for a single root/eigenvalue for the irreducible factor. - - ``None`` - Uses the 'all' format if the base ring is contained + - ``None`` (default) -- Uses the ``'all'`` format if the base ring is contained in an algebraically closed field which is implemented. - Otherwise, uses the 'galois' format. + Otherwise, uses the ``'galois'`` format. - - ``var`` - default: 'a' - variable name used to + - ``var`` -- string (default: ``'a'``); variable name used to represent elements of the root field of each irreducible factor of the characteristic polynomial. - If var='a', then the root fields will be in terms of - a0, a1, a2, ...., where the numbering runs across all + If ``var='a'``, then the root fields will be in terms of + ``a0, a1, a2, ...``, where the numbering runs across all the irreducible factors of the characteristic polynomial, even for linear factors. - - ``algebraic_multiplicity`` - default: False - whether or - not to include the algebraic multiplicity of each eigenvalue + - ``algebraic_multiplicity`` -- (boolean, default: ``False``); + whether to include the algebraic multiplicity of each eigenvalue in the output. See the discussion below. OUTPUT: - If algebraic_multiplicity=False, return a list of pairs (e, V) - where e is an eigenvalue of the matrix, and V is the corresponding + If ``algebraic_multiplicity=False``, return a list of pairs `(e, V)` + where `e` is an eigenvalue of the matrix, and `V` is the corresponding left eigenspace. For Galois conjugates of eigenvalues, there may be just one representative eigenspace, depending on the ``format`` keyword. - If algebraic_multiplicity=True, return a list of triples (e, V, n) - where e and V are as above and n is the algebraic multiplicity of + If ``algebraic_multiplicity=True``, return a list of triples `(e, V, n)` + where `e` and `V` are as above and `n` is the algebraic multiplicity of the eigenvalue. .. warning:: @@ -6153,10 +6161,10 @@ i sage: # needs sage.libs.pari EXAMPLES: We compute the left eigenspaces of a `3\times 3` - rational matrix. First, we request `all` of the eigenvalues, - so the results are in the field of algebraic numbers, `QQbar`. + rational matrix. First, we request ``'all'`` of the eigenvalues, + so the results are in the field of algebraic numbers, ``QQbar``. Then we request just one eigenspace per irreducible factor of - the characteristic polynomial with the `galois` keyword. :: + the characteristic polynomial with ``format='galois'``. :: sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] @@ -6349,15 +6357,15 @@ i sage: # needs sage.libs.pari possible, will raise an error. Using the ``'galois'`` format option is more likely to be successful. :: - sage: F. = FiniteField(11^2) # needs sage.rings.finite_rings - sage: A = matrix(F, [[b + 1, b + 1], [10*b + 4, 5*b + 4]]) # needs sage.rings.finite_rings - sage: A.eigenspaces_left(format='all') # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings + sage: F. = FiniteField(11^2) + sage: A = matrix(F, [[b + 1, b + 1], [10*b + 4, 5*b + 4]]) + sage: A.eigenspaces_left(format='all') Traceback (most recent call last): ... NotImplementedError: unable to construct eigenspaces for eigenvalues outside the base field, try the keyword option: format='galois' - - sage: A.eigenspaces_left(format='galois') # needs sage.rings.finite_rings + sage: A.eigenspaces_left(format='galois') [ (a0, Vector space of degree 2 and dimension 1 over Univariate Quotient Polynomial Ring in a0 over @@ -6526,11 +6534,12 @@ i sage: # needs sage.libs.pari We compute the right eigenspaces of a `3\times 3` rational matrix. :: + sage: # needs sage.rings.number_field sage: A = matrix(QQ, 3, 3, range(9)); A [0 1 2] [3 4 5] [6 7 8] - sage: A.eigenspaces_right() # needs sage.rings.number_field + sage: A.eigenspaces_right() [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6543,7 +6552,7 @@ i sage: # needs sage.libs.pari Vector space of degree 3 and dimension 1 over Algebraic Field User basis matrix: [ 1 3.069693845669907? 5.139387691339814?]) ] - sage: es = A.eigenspaces_right(format='galois'); es # needs sage.rings.number_field + sage: es = A.eigenspaces_right(format='galois'); es [ (0, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -6553,7 +6562,7 @@ i sage: # needs sage.libs.pari Number Field in a1 with defining polynomial x^2 - 12*x - 18 User basis matrix: [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5]) ] - sage: es = A.eigenspaces_right(format='galois', # needs sage.rings.number_field + sage: es = A.eigenspaces_right(format='galois', ....: algebraic_multiplicity=True); es [ (0, Vector space of degree 3 and dimension 1 over Rational Field @@ -6566,9 +6575,9 @@ i sage: # needs sage.libs.pari User basis matrix: [ 1 1/5*a1 + 2/5 2/5*a1 - 1/5], 1) ] - sage: e, v, n = es[0]; v = v.basis()[0] # needs sage.rings.number_field - sage: delta = v*e - A*v # needs sage.rings.number_field - sage: abs(abs(delta)) < 1e-10 # needs sage.rings.number_field + sage: e, v, n = es[0]; v = v.basis()[0] + sage: delta = v*e - A*v + sage: abs(abs(delta)) < 1e-10 True The same computation, but with implicit base change to a field:: @@ -6600,11 +6609,12 @@ i sage: # needs sage.libs.pari sage: B.eigenspaces_right() Traceback (most recent call last): ... - NotImplementedError: eigenspaces cannot be computed reliably for inexact rings such as Real Field with 53 bits of precision, + NotImplementedError: eigenspaces cannot be computed reliably + for inexact rings such as Real Field with 53 bits of precision, consult numerical or symbolic matrix classes for other options sage: em = B.change_ring(RDF).eigenmatrix_right() - sage: eigenvalues = em[0]; eigenvalues.dense_matrix() # abs tol 1e-13 + sage: eigenvalues = em[0]; eigenvalues.dense_matrix() # abs tol 1e-13 [13.348469228349522 0.0 0.0] [ 0.0 -1.348469228349534 0.0] [ 0.0 0.0 0.0] @@ -6681,7 +6691,7 @@ i sage: # needs sage.libs.pari then ``QQbar`` elements are returned that represent each separate root. - If the option extend is set to False, only eigenvalues in the base + If the option ``extend`` is set to ``False``, only eigenvalues in the base ring are considered. EXAMPLES:: @@ -6734,12 +6744,12 @@ i sage: # needs sage.libs.pari sage: e.as_number_field_element() # needs sage.rings.number_field (Number Field in a - with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264, - a + 7, - Ring morphism: - From: Number Field in a with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264 - To: Algebraic Real Field - Defn: a |--> -15.35066086057957?) + with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264, + a + 7, + Ring morphism: + From: Number Field in a with defining polynomial y^4 - 2*y^3 - 507*y^2 - 3972*y - 4264 + To: Algebraic Real Field + Defn: a |--> -15.35066086057957?) Notice the effect of the ``extend`` option. @@ -6863,9 +6873,7 @@ i sage: # needs sage.libs.pari (-1*I, [(1, -1*I, 0)], 1), (1*I, [(1, 1*I, 0)], 1)] sage: M.eigenvectors_left(extend=False) # needs sage.rings.number_field - [(2, [ - (0, 0, 1) - ], 1)] + [(2, [ (0, 0, 1) ], 1)] TESTS:: @@ -6983,9 +6991,7 @@ i sage: # needs sage.libs.pari (-1.348469228349535?, [(1, 0.1303061543300932?, -0.7393876913398137?)], 1), (13.34846922834954?, [(1, 3.069693845669907?, 5.139387691339814?)], 1)] sage: A.eigenvectors_right(extend=False) - [(0, [ - (1, -2, 1) - ], 1)] + [(0, [ (1, -2, 1) ], 1)] sage: eval, [evec], mult = es[0] sage: delta = eval*evec - A*evec sage: abs(abs(delta)) < 1e-10 @@ -7137,7 +7143,7 @@ i sage: # needs sage.libs.pari sage: A = matrix(QQ, 3, 3, range(9)) sage: em = A.change_ring(RDF).eigenmatrix_left() - sage: evalues = em[0]; evalues.dense_matrix() # abs tol 1e-13 + sage: evalues = em[0]; evalues.dense_matrix() # abs tol 1e-13 [13.348469228349522 0.0 0.0] [ 0.0 -1.348469228349534 0.0] [ 0.0 0.0 0.0] @@ -7409,8 +7415,8 @@ i sage: # needs sage.libs.pari sage: M.eigenvalue_multiplicity(1) 0 - sage: M = posets.DiamondPoset(5).coxeter_transformation() # needs sage.combinat - sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] # needs sage.combinat + sage: M = posets.DiamondPoset(5).coxeter_transformation() # needs sage.graphs + sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] # needs sage.graphs [3, 2] TESTS:: @@ -7517,7 +7523,8 @@ i sage: # needs sage.libs.pari sage: C.echelon_form() Traceback (most recent call last): ... - NotImplementedError: Ideal Ideal (2, x + 1) of Univariate Polynomial Ring in x over Integer Ring not principal + NotImplementedError: Ideal Ideal (2, x + 1) of Univariate + Polynomial Ring in x over Integer Ring not principal Echelon form not implemented over 'Univariate Polynomial Ring in x over Integer Ring'. sage: C = matrix(3,[2,x,x^2,x+1,3-x,-1,3,2,1/2]) sage: C.echelon_form() @@ -7776,8 +7783,8 @@ i sage: # needs sage.libs.pari Check that :trac:`34724` is fixed (indirect doctest):: - sage: a=6.12323399573677e-17 - sage: m=matrix(RR,[[-a, -1.72508242466029], [ 0.579682446302195, a]]) + sage: a = 6.12323399573677e-17 + sage: m = matrix(RR,[[-a, -1.72508242466029], [ 0.579682446302195, a]]) sage: (~m*m).norm() 1.0 """ @@ -18014,7 +18021,7 @@ def _generic_clear_column(m): sage: OL = L.ring_of_integers(); w = OL(w) sage: m = matrix(OL, 8, 4, [2*w - 2, 2*w + 1, -2, w, 2, -2, -2*w - 2, -2*w + 2, -w + 2, 2*w + 1, -w + 2, -w - 2, -2*w, ....: 2*w, -w+ 2, w - 1, -2*w + 2, 2*w + 2, 2*w - 1, -w, 2*w + 2, -w + 2, 2, 2*w -1, w - 4, -2*w - 2, 2*w - 1, 0, 6, 7, 2*w + 1, 14]) - sage: s,t = m.echelon_form(transformation=True); t*m == s # indirect doctest + sage: s,t = m.echelon_form(transformation=True); t*m == s # indirect doctest True sage: s[0] (w, 0, 0, 0) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 94e8d545b5b..5efca848716 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -2277,19 +2277,19 @@ def companion_matrix(poly, format='right'): [ 1 0 -8] [ 0 1 4] - sage: y = var('y') # needs sage.symbolic - sage: q = y^3 - 2*y + 1 # needs sage.symbolic - sage: companion_matrix(q) # needs sage.symbolic + sage: # needs sage.symbolic + sage: y = var('y') + sage: q = y^3 - 2*y + 1 + sage: companion_matrix(q) Traceback (most recent call last): ... TypeError: input must be a polynomial (not a symbolic expression, see docstring), or other iterable, not y^3 - 2*y + 1 - - sage: coeff_list = [q(y=0)] + [q.coefficient(y^k) # needs sage.symbolic - ....: for k in range(1, q.degree(y)+1)] - sage: coeff_list # needs sage.symbolic + sage: coeff_list = [q(y=0)] + [q.coefficient(y^k) + ....: for k in range(1, q.degree(y) + 1)] + sage: coeff_list [1, -2, 0, 1] - sage: companion_matrix(coeff_list) # needs sage.symbolic + sage: companion_matrix(coeff_list) [ 0 0 -1] [ 1 0 2] [ 0 1 0] @@ -2431,7 +2431,7 @@ def random_rref_matrix(parent, num_pivots): sage: from sage.matrix.constructor import random_rref_matrix sage: matrix_space = sage.matrix.matrix_space.MatrixSpace(QQ, 5, 6) - sage: A = random_rref_matrix(matrix_space, num_pivots=4); A # random + sage: A = random_rref_matrix(matrix_space, num_pivots=4); A # random [ 1 0 0 -6 0 -3] [ 0 1 0 2 0 3] [ 0 0 1 -4 0 -2] @@ -2617,7 +2617,7 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100): sage: A = random_echelonizable_matrix(matrix_space, rank=4, upper_bound=40) sage: A.rank() 4 - sage: max(map(abs,A.list()))<40 + sage: max(map(abs,A.list())) < 40 True sage: A.rref() == A.rref().change_ring(ZZ) True @@ -2858,11 +2858,11 @@ def random_subspaces_matrix(parent, rank=None): (5, 7) sage: all(x in ZZ for x in A.list()) True - sage: A_expanded=A.augment(identity_matrix(5)).rref() + sage: A_expanded = A.augment(identity_matrix(5)).rref() sage: all(x in ZZ for x in A_expanded.list()) True - sage: C = A_expanded.submatrix(0,0,A.nrows()-A.nullity(), A.ncols()) - sage: L = A_expanded.submatrix(A.nrows()-A.nullity(), A.ncols()) + sage: C = A_expanded.submatrix(0, 0, A.nrows() - A.nullity(), A.ncols()) + sage: L = A_expanded.submatrix(A.nrows() - A.nullity(), A.ncols()) sage: A.right_kernel() == C.right_kernel() True sage: A.row_space() == C.row_space() diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 51226dbd22b..313ffb25798 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -5606,13 +5606,13 @@ def _latex_(self): EXAMPLES:: - sage: latex(QQ^3) # indirect doctest + sage: latex(QQ^3) # indirect doctest \Bold{Q}^{3} :: sage: A = GF(5)^20 - sage: latex(A) + sage: latex(A) # indirect doctest \Bold{F}_{5}^{20} :: diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index b801cb2b27e..d5e8256b68c 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -2626,7 +2626,8 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: rings = [ZZ, QQ, RDF, ZZ['x']] sage: rings += [RR] # needs sage.rings.real_mpfr - sage: rings += [GF(2), GF(3), GF(4)] # needs sage.rings.finite_rings + sage: rings += [GF(2), GF(3)] + sage: rings += [GF(4)] # needs sage.rings.finite_rings sage: for R in rings: ....: _ = (R**0)().dot_product((R**0)()) """ @@ -3656,14 +3657,14 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: - sage: # needs sage.symbolic + sage: # optional - mathematica, needs sage.symbolic sage: vector((1,2,3), QQ)._mathematica_init_() '{1/1, 2/1, 3/1}' - sage: mathematica(vector((1,2,3), QQ)) # optional - mathematica + sage: mathematica(vector((1,2,3), QQ)) {1, 2, 3} sage: a = vector(SR, 5, [1, x, x^2, sin(x), pi]); a (1, x, x^2, sin(x), pi) - sage: a._mathematica_init_() # optional - mathematica + sage: a._mathematica_init_() '{1, x, (x)^(2), Sin[x], Pi}' """ return '{' + ', '.join(x._mathematica_init_() for x in self.list()) + '}' From 4e3f558eed94ff8ac77374a3a051b6f645306061 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Aug 2023 17:03:32 -0700 Subject: [PATCH 83/99] Fixups --- src/sage/quadratic_forms/binary_qf.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/quadratic_forms/binary_qf.py b/src/sage/quadratic_forms/binary_qf.py index 037cde8681b..db1fa5b6bab 100755 --- a/src/sage/quadratic_forms/binary_qf.py +++ b/src/sage/quadratic_forms/binary_qf.py @@ -1619,17 +1619,17 @@ def solve_integer(self, n, *, algorithm="general"): Also when using the ``"cornacchia"`` algorithm:: - asge: # needs sage.libs.pari + sage: # needs sage.libs.pari sage: abc = [1, 0, randrange(1,10^3)] sage: Q = BinaryQF(abc) - sage: n = random_prime(10^9) # needs sage.libs.pari - sage: if randrange(2): # needs sage.libs.pari + sage: n = random_prime(10^9) + sage: if randrange(2): ....: n *= 4 - sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') # needs sage.libs.pari - sage: xy1 is None or Q(*xy1) == n # needs sage.libs.pari + sage: xy1 = Q.solve_integer(n, algorithm='cornacchia') + sage: xy1 is None or Q(*xy1) == n True - sage: xy2 = Q.solve_integer(n) # needs sage.libs.pari - sage: (xy1 is None) == (xy2 is None) # needs sage.libs.pari + sage: xy2 = Q.solve_integer(n) + sage: (xy1 is None) == (xy2 is None) True Test for square discriminants specifically (:trac:`33026`):: From cea7d8deb982f4edaafbc8589de9c95497a38c97 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Aug 2023 20:26:51 -0700 Subject: [PATCH 84/99] src/sage/matrix/matrix_modn_dense_template.pxi: Fixup --- src/sage/matrix/matrix_modn_dense_template.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index fbf25fce27e..0658e809fe5 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -668,7 +668,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): And for larger modulus:: - sage: # needs sage.rings.finite_rings + sage: # needs sage.rings.finite_rings sage: A = random_matrix(GF(1009), 51, 5) sage: data, version = A._pickle() sage: B = A.parent()(0) From 786d6a42d4ce849858400af86731986e7b16656b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Aug 2023 20:28:39 -0700 Subject: [PATCH 85/99] src/sage/matrix/special.py: Restore a lost '# random' --- src/sage/matrix/special.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 5efca848716..356b9c5ef88 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -2450,7 +2450,7 @@ def random_rref_matrix(parent, num_pivots): Matrices can be generated over other exact rings. :: - sage: B = random_matrix(FiniteField(7), 4, 4, + sage: B = random_matrix(FiniteField(7), 4, 4, # random ....: algorithm='echelon_form', num_pivots=3); B [1 0 0 0] [0 1 0 6] From 640610af61cba4c5c23ec0b7d88432091d1185ad Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 12 Aug 2023 15:02:52 -0700 Subject: [PATCH 86/99] sage.{homology,matrix,modules}: Protect timing out doctests from probing --- src/sage/homology/homology_group.py | 2 ++ src/sage/matrix/constructor.pyx | 3 ++- src/sage/matrix/special.py | 11 +++++++---- src/sage/modules/fg_pid/fgp_module.py | 10 +++++++--- src/sage/modules/free_module_integer.py | 2 +- .../free_quadratic_module_integer_symmetric.py | 3 ++- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/sage/homology/homology_group.py b/src/sage/homology/homology_group.py index 8db8a47e568..8d86d477ad8 100644 --- a/src/sage/homology/homology_group.py +++ b/src/sage/homology/homology_group.py @@ -165,6 +165,8 @@ def HomologyGroup(n, base_ring, invfac=None): Multiplicative Abelian group isomorphic to Z x Z x Z x Z sage: HomologyGroup(4, ZZ) Z x Z x Z x Z + + sage: # needs sage.libs.flint (otherwise timeout) sage: HomologyGroup(100, ZZ) Z^100 """ diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index 74541580cef..241d01db0f9 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -579,7 +579,8 @@ def matrix(*args, **kwds): Check :trac:`24459`:: - sage: Matrix(ZZ, sys.maxsize, sys.maxsize) # needs sage.libs.flint + sage: # needs sage.libs.flint + sage: Matrix(ZZ, sys.maxsize, sys.maxsize) Traceback (most recent call last): ... RuntimeError... diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 356b9c5ef88..1e0fb27efa3 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -365,19 +365,21 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation sage: while abs(density_sum/total_count - expected_density) > 0.001: ....: add_sample(ZZ, 5, x=-10, y=10, density=0.75) + sage: # needs sage.libs.flint (otherwise timeout) sage: density_sum = 0.0 sage: total_count = 0.0 sage: add_sample(ZZ, 5, x=20, y=30, density=0.75) - sage: while abs(density_sum/total_count - expected_density) > 0.001: # needs sage.libs.flint + sage: while abs(density_sum/total_count - expected_density) > 0.001: ....: add_sample(ZZ, 5, x=20, y=30, density=0.75) + sage: # needs sage.libs.flint (otherwise timeout) sage: density_sum = 0.0 sage: total_count = 0.0 - sage: add_sample(ZZ, 100, x=20, y=30, density=0.75) # needs sage.libs.flint + sage: add_sample(ZZ, 100, x=20, y=30, density=0.75) sage: expected_density = (1 - (99/100)^75) sage: float(expected_density) 0.529... - sage: while abs(density_sum/total_count - expected_density) > 0.001: # needs sage.libs.flint + sage: while abs(density_sum/total_count - expected_density) > 0.001: ....: add_sample(ZZ, 100, x=20, y=30, density=0.75) For a matrix with low density it may be advisable to insist on a sparse @@ -393,7 +395,8 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation For algorithm testing you might want to control the number of bits, say 10,000 entries, each limited to 16 bits. :: - sage: A = random_matrix(ZZ, 100, 100, x=2^16); A # needs sage.libs.flint + sage: # needs sage.libs.flint (otherwise timeout) + sage: A = random_matrix(ZZ, 100, 100, x=2^16); A 100 x 100 dense matrix over Integer Ring (use the '.str()' method to see the entries) One can prescribe a specific matrix implementation:: diff --git a/src/sage/modules/fg_pid/fgp_module.py b/src/sage/modules/fg_pid/fgp_module.py index 8178afada2d..1ca35212682 100644 --- a/src/sage/modules/fg_pid/fgp_module.py +++ b/src/sage/modules/fg_pid/fgp_module.py @@ -1867,7 +1867,9 @@ def construction(self): sage: T2 = A2 / B2 sage: t1 = T1.an_element() sage: t2 = T2.an_element() - sage: t1 + t2 # needs sage.libs.flint (o/w infinite recursion) + + sage: # needs sage.libs.flint (o/w infinite recursion) + sage: t1 + t2 (1, 1) """ from sage.modules.module_functors import QuotientModuleFunctor @@ -2068,8 +2070,10 @@ def _test_morphism_0(*args, **kwds): sage: set_random_seed(s); v = [fgp._test_morphism_0(1) for _ in range(30)] sage: set_random_seed(s); v = [fgp._test_morphism_0(2) for _ in range(30)] sage: set_random_seed(s); v = [fgp._test_morphism_0(3) for _ in range(10)] - sage: set_random_seed(s); v = [fgp._test_morphism_0(i) for i in range(1,20)] # needs sage.libs.flint (o/w timeout) - sage: set_random_seed(s); v = [fgp._test_morphism_0(4) for _ in range(50)] # long time, needs sage.libs.flint + + sage: # needs sage.libs.flint (o/w timeout) + sage: set_random_seed(s); v = [fgp._test_morphism_0(i) for i in range(1,20)] + sage: set_random_seed(s); v = [fgp._test_morphism_0(4) for _ in range(50)] # long time """ phi = random_fgp_morphism_0(*args, **kwds) K = phi.kernel() diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index 6401c144dc7..c16e747a53f 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -407,7 +407,7 @@ def BKZ(self, *args, **kwds): EXAMPLES:: - sage: # needs sage.libs.flint + sage: # needs sage.libs.flint (o/w timeout) sage: from sage.modules.free_module_integer import IntegerLattice sage: A = sage.crypto.gen_lattice(type='random', n=1, m=60, q=2^60, seed=42) sage: L = IntegerLattice(A, lll_reduce=False) diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index f8cb98c3c6b..9cdc7637140 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -1048,8 +1048,9 @@ def maximal_overlattice(self, p=None): TESTS:: + sage: # needs sage.libs.flint (otherwise timeout) sage: L = IntegralLattice(matrix.diagonal([2,4,4,8])) - sage: L.maximal_overlattice().is_even() # needs sage.libs.flint + sage: L.maximal_overlattice().is_even() True """ From f64c91eb12c18cac07f05cfc5974295f76696eb3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 16 Jul 2023 19:54:02 -0700 Subject: [PATCH 87/99] src/sage/features/sagemath.py: Add feature sage.libs.linbox --- src/sage/features/sagemath.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index f7c3c0749ee..6b0a8a49075 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -392,10 +392,37 @@ def __init__(self): PythonModule('sage.interfaces.gap')]) +class sage__libs__linbox(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.linbox` + and other modules depending on Givaro, FFLAS-FFPACK, LinBox. + + In addition to the modularization purposes that this tag serves, it also provides attribution + to the upstream project. + + TESTS:: + + sage: from sage.features.sagemath import sage__libs__linbox + sage: sage__libs__linbox().is_present() # needs sage.libs.linbox + FeatureTestResult('sage.libs.linbox', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__linbox + sage: isinstance(sage__libs__linbox(), sage__libs__linbox) + True + """ + JoinFeature.__init__(self, 'sage.libs.linbox', + [PythonModule('sage.rings.finite_rings.element_givaro')], + spkg='sagemath_linbox', type='standard') + + class sage__libs__ntl(JoinFeature): r""" A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.ntl` - and other modules depending on NTL and arb. + and other modules depending on NTL. In addition to the modularization purposes that this tag serves, it also provides attribution to the upstream project. @@ -1005,6 +1032,7 @@ def all_features(): sage__libs__ecl(), sage__libs__flint(), sage__libs__gap(), + sage__libs__linbox(), sage__libs__ntl(), sage__libs__pari(), sage__libs__singular(), From a34c470aa6cf108bca67d70dbf5dd2eec50940ec Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 12 Aug 2023 18:52:49 -0700 Subject: [PATCH 88/99] src/sage/features/sagemath.py: Add feature sage.libs.m4ri --- src/sage/features/sagemath.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 6b0a8a49075..783b66579da 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -419,6 +419,33 @@ def __init__(self): spkg='sagemath_linbox', type='standard') +class sage__libs__m4ri(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of Cython modules + depending on the M4RI and/or M4RIe libraries. + + In addition to the modularization purposes that this tag serves, it also provides attribution + to the upstream project. + + TESTS:: + + sage: from sage.features.sagemath import sage__libs__m4ri + sage: sage__libs__m4ri().is_present() # needs sage.libs.m4ri + FeatureTestResult('sage.libs.m4ri', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__m4ri + sage: isinstance(sage__libs__m4ri(), sage__libs__m4ri) + True + """ + JoinFeature.__init__(self, 'sage.libs.m4ri', + [PythonModule('sage.matrix.matrix_gf2e_dense')], + spkg='sagemath_m4ri', type='standard') + + class sage__libs__ntl(JoinFeature): r""" A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.ntl` @@ -1033,6 +1060,7 @@ def all_features(): sage__libs__flint(), sage__libs__gap(), sage__libs__linbox(), + sage__libs__m4ri(), sage__libs__ntl(), sage__libs__pari(), sage__libs__singular(), From 4d7780b3c46a3a20145e26d56be660988df34860 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 12 Aug 2023 18:54:20 -0700 Subject: [PATCH 89/99] Update # needs --- src/sage/matrix/matrix_space.py | 2 ++ src/sage/matrix/special.py | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index c4c902a09c6..1ea8c0bca9f 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -683,6 +683,8 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): 200 x 1 dense matrix over Rational Field (use the '.str()' method to see the entries) sage: A = MatrixSpace(RDF,1000,1000).random_element() sage: B = MatrixSpace(RDF,1000,1000).random_element() + + sage: # needs numpy (otherwise timeout) sage: C = A * B We check that :trac:`18186` is fixed:: diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 1e0fb27efa3..3256a636f6b 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -356,6 +356,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation ....: A = random_matrix(*args, **kwds) ....: density_sum += float(A.density()) + sage: # needs sage.libs.flint (otherwise timeout) sage: density_sum = 0.0 sage: total_count = 0.0 sage: add_sample(ZZ, 5, x=-10, y=10, density=0.75) @@ -402,7 +403,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation One can prescribe a specific matrix implementation:: sage: K. = FiniteField(2^8) # needs sage.rings.finite_rings - sage: type(random_matrix(K, 2, 5)) # needs sage.rings.finite_rings + sage: type(random_matrix(K, 2, 5)) # needs sage.rings.finite_rings sage.libs.m4ri sage: type(random_matrix(K, 2, 5, implementation="generic")) # needs sage.rings.finite_rings @@ -1288,14 +1289,18 @@ def elementary_matrix(arg0, arg1=None, **kwds): sage: E.parent() Full MatrixSpace of 4 by 4 dense matrices over Rational Field + sage: # needs sage.symbolic sage: E = elementary_matrix(4, row1=1, scale=I) sage: E.parent() - Full MatrixSpace of 4 by 4 dense matrices over Number Field in I with defining polynomial x^2 + 1 with I = 1*I + Full MatrixSpace of 4 by 4 dense matrices over + Number Field in I with defining polynomial x^2 + 1 with I = 1*I + sage: # needs sage.rings.complex_double sage: E = elementary_matrix(4, row1=1, scale=CDF(I)) sage: E.parent() Full MatrixSpace of 4 by 4 dense matrices over Complex Double Field + sage: # needs sage.rings.number_field sage: E = elementary_matrix(4, row1=1, scale=QQbar(I)) sage: E.parent() Full MatrixSpace of 4 by 4 dense matrices over Algebraic Field @@ -3109,7 +3114,8 @@ def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None): Eigenvalues must all be integers. :: - sage: random_matrix(QQ,3,algorithm='diagonalizable', eigenvalues=[2+I,2-I,2],dimensions=[1,1,1]) + sage: random_matrix(QQ, 3, algorithm='diagonalizable', # needs sage.symbolic + ....: eigenvalues=[2+I, 2-I, 2], dimensions=[1,1,1]) Traceback (most recent call last): ... TypeError: eigenvalues must be integers. From 017414a40e609cc36982b25f49cdc3086dd1ae5a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 12 Aug 2023 19:23:47 -0700 Subject: [PATCH 90/99] Update # needs --- src/sage/matrix/special.py | 4 ++-- src/sage/stats/basic_stats.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 3256a636f6b..db6fabd7d6c 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -1295,12 +1295,12 @@ def elementary_matrix(arg0, arg1=None, **kwds): Full MatrixSpace of 4 by 4 dense matrices over Number Field in I with defining polynomial x^2 + 1 with I = 1*I - sage: # needs sage.rings.complex_double + sage: # needs sage.rings.complex_double sage.symbolic sage: E = elementary_matrix(4, row1=1, scale=CDF(I)) sage: E.parent() Full MatrixSpace of 4 by 4 dense matrices over Complex Double Field - sage: # needs sage.rings.number_field + sage: # needs sage.rings.number_field sage.symbolic sage: E = elementary_matrix(4, row1=1, scale=QQbar(I)) sage: E.parent() Full MatrixSpace of 4 by 4 dense matrices over Algebraic Field diff --git a/src/sage/stats/basic_stats.py b/src/sage/stats/basic_stats.py index bf89b040b11..15e85197f3e 100644 --- a/src/sage/stats/basic_stats.py +++ b/src/sage/stats/basic_stats.py @@ -79,7 +79,7 @@ def mean(v): NaN sage: mean([I, sqrt(2), 3/5]) # needs sage.symbolic 1/3*sqrt(2) + 1/3*I + 1/5 - sage: mean([RIF(1.0103,1.0103), RIF(2)]) + sage: mean([RIF(1.0103,1.0103), RIF(2)]) # needs sage.rings.real_interval_field 1.5051500000000000? sage: mean(range(4)) 3/2 From 60e906e47065ae40878681f0f818c7a34a8cbab0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 13 Aug 2023 12:01:02 -0700 Subject: [PATCH 91/99] sage --fixdoctests --no-test src/sage/{matrix,modules,probability,stats,quadratic_forms,tensor} --- src/sage/matrix/special.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index db6fabd7d6c..acd657ec927 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -403,7 +403,7 @@ def random_matrix(ring, nrows, ncols=None, algorithm='randomize', implementation One can prescribe a specific matrix implementation:: sage: K. = FiniteField(2^8) # needs sage.rings.finite_rings - sage: type(random_matrix(K, 2, 5)) # needs sage.rings.finite_rings sage.libs.m4ri + sage: type(random_matrix(K, 2, 5)) # needs sage.libs.m4ri sage.rings.finite_rings sage: type(random_matrix(K, 2, 5, implementation="generic")) # needs sage.rings.finite_rings From 865e1786c5f310b0cd09aad947b20406ef650126 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 15 Aug 2023 22:05:50 -0700 Subject: [PATCH 92/99] src/sage/probability/probability_distribution.pyx: Docstring/doctest cosmetics --- .../probability/probability_distribution.pyx | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index 9df29e85842..3cbc81a8a39 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -1,4 +1,4 @@ -""" +r""" Probability Distributions This module provides three types of probability distributions: @@ -63,13 +63,13 @@ cdef enum: beta cdef class ProbabilityDistribution: - """ + r""" Concrete probability distributions should be derived from this abstract class. """ def __init__(self): - """ + r""" To be implemented by a derived class:: sage: P = sage.probability.probability_distribution.ProbabilityDistribution() @@ -78,7 +78,7 @@ cdef class ProbabilityDistribution: pass def get_random_element(self): - """ + r""" To be implemented by a derived class:: sage: P = sage.probability.probability_distribution.ProbabilityDistribution() @@ -91,15 +91,15 @@ cdef class ProbabilityDistribution: raise NotImplementedError("implement in derived class") def generate_histogram_data(self, num_samples=1000, bins=50): - """ + r""" Compute a histogram of the probability distribution. INPUT: - - ``num_samples`` - (optional) number of times to sample from + - ``num_samples`` -- (optional) number of times to sample from the probability distribution - - ``bins`` - (optional) number of bins to divide the samples + - ``bins`` -- (optional) number of bins to divide the samples into. OUTPUT: @@ -144,8 +144,8 @@ cdef class ProbabilityDistribution: S = pylab.hist(ell, bins, density=True) return [list(S[0]), list(S[1])] - def generate_histogram_plot(self, name, num_samples = 1000, bins = 50): - """ + def generate_histogram_plot(self, name, num_samples=1000, bins=50): + r""" Save the histogram from :func:`generate_histogram_data() ` to a file. @@ -177,7 +177,7 @@ cdef class ProbabilityDistribution: cdef class SphericalDistribution(ProbabilityDistribution): - """ + r""" This class is capable of producing random points uniformly distributed on the surface of an `(n-1)`-sphere in `n`-dimensional euclidean space. The dimension `n` is selected via the keyword ``dimension``. The random @@ -252,19 +252,19 @@ cdef class SphericalDistribution(ProbabilityDistribution): self.vec = sig_malloc(self.dimension*(sizeof(double))) def set_seed(self, seed): - """ + r""" Set the seed for the underlying random number generator. EXAMPLES:: - sage: T = SphericalDistribution(seed = 0) + sage: T = SphericalDistribution(seed=0) sage: T.set_seed(100) """ gsl_rng_set(self.r, seed) self.seed = seed def set_random_number_generator(self, rng='default'): - """ + r""" Set the gsl random number generator to be one of ``default``, ``luxury``, or ``taus``. @@ -295,12 +295,12 @@ cdef class SphericalDistribution(ProbabilityDistribution): sig_free(self.vec) def get_random_element(self): - """ + r""" Get a random sample from the probability distribution. EXAMPLES:: - sage: T = SphericalDistribution(seed = 0) + sage: T = SphericalDistribution(seed=0) sage: T.get_random_element() # rel tol 4e-16 (0.07961564104639995, -0.05237671627581255, 0.9954486572862178) """ @@ -312,12 +312,12 @@ cdef class SphericalDistribution(ProbabilityDistribution): return vector(sage.rings.real_double.RDF, v) # This could be made more efficient by directly constructing the vector, TODO. def reset_distribution(self): - """ + r""" This method resets the distribution. EXAMPLES:: - sage: T = SphericalDistribution(seed = 0) + sage: T = SphericalDistribution(seed=0) sage: [T.get_random_element() for _ in range(4)] # rel tol 4e-16 [(0.07961564104639995, -0.05237671627581255, 0.9954486572862178), (0.4123599490593727, 0.5606817859360097, -0.7180495855658982), @@ -337,7 +337,7 @@ cdef class SphericalDistribution(ProbabilityDistribution): # gsl_rng_env_setup() cdef class RealDistribution(ProbabilityDistribution): - """ + r""" The :class:`RealDistribution` class provides a number of routines for sampling from and analyzing and visualizing probability distributions. For precise definitions of the distributions and their parameters @@ -523,10 +523,10 @@ cdef class RealDistribution(ProbabilityDistribution): twister. Also available are the RANDLXS algorithm and the Tausworthe generator (see the gsl reference manual for more details). These are all supposed to be simulation quality - generators. For RANDLXS use ``rng = 'luxury'`` and for - tausworth use ``rng = 'taus'``:: + generators. For RANDLXS use ``rng='luxury'`` and for + tausworth use ``rng='taus'``:: - sage: T = RealDistribution('gaussian', 1, rng = 'luxury', seed = 10) + sage: T = RealDistribution('gaussian', 1, rng='luxury', seed=10) To change the seed at a later time use ``set_seed``:: @@ -557,7 +557,7 @@ cdef class RealDistribution(ProbabilityDistribution): r""" EXAMPLES:: - sage: T = RealDistribution('gaussian', 1, seed = 0) + sage: T = RealDistribution('gaussian', 1, seed=0) sage: T.get_random_element() # rel tol 4e-16 0.13391860811867587 @@ -589,20 +589,20 @@ cdef class RealDistribution(ProbabilityDistribution): self.set_distribution(type, parameters) def set_seed(self, seed): - """ + r""" Set the seed for the underlying random number generator. EXAMPLES:: - sage: T = RealDistribution('gaussian', 1, rng = 'luxury', seed = 10) + sage: T = RealDistribution('gaussian', 1, rng='luxury', seed=10) sage: T.set_seed(100) """ gsl_rng_set(self.r, seed) self.seed = seed - def set_random_number_generator(self, rng = 'default'): - """ + def set_random_number_generator(self, rng='default'): + r""" Set the gsl random number generator to be one of ``'default'``, ``'luxury'``, or ``'taus'``. @@ -633,7 +633,7 @@ cdef class RealDistribution(ProbabilityDistribution): sig_free(self.parameters) def __str__(self): - """ + r""" Return the name of the current distribution. EXAMPLES:: @@ -648,12 +648,12 @@ cdef class RealDistribution(ProbabilityDistribution): return self.name def get_random_element(self): - """ + r""" Get a random sample from the probability distribution. EXAMPLES:: - sage: T = RealDistribution('gaussian', 1, seed = 0) + sage: T = RealDistribution('gaussian', 1, seed=0) sage: T.get_random_element() # rel tol 4e-16 0.13391860811867587 @@ -688,7 +688,7 @@ cdef class RealDistribution(ProbabilityDistribution): return sage.rings.real_double.RDF(result) def set_distribution(self, name='uniform', parameters=None): - """ + r""" This method can be called to change the current probability distribution. EXAMPLES:: @@ -821,12 +821,12 @@ cdef class RealDistribution(ProbabilityDistribution): # def _get_random_element_c(): def reset_distribution(self): - """ - This method resets the distribution. + r""" + Reset the distribution. EXAMPLES:: - sage: T = RealDistribution('gaussian', 1, seed = 10) + sage: T = RealDistribution('gaussian', 1, seed=10) sage: [T.get_random_element() for _ in range(10)] # rel tol 4e-16 [-0.7460999595745819, -0.004644606626413462, -0.8720538317207641, 0.6916259921666037, 2.67668674666043, 0.6325002813661014, -0.7974263521959355, -0.5284976893366636, 1.1353119849528792, 0.9912505673230749] sage: T.reset_distribution() @@ -840,7 +840,7 @@ cdef class RealDistribution(ProbabilityDistribution): # gsl_rng_env_setup() def distribution_function(self, x): - """ + r""" Evaluate the distribution function of the probability distribution at ``x``. @@ -882,7 +882,7 @@ cdef class RealDistribution(ProbabilityDistribution): raise TypeError("Not a supported probability distribution") def cum_distribution_function(self, x): - """ + r""" Evaluate the cumulative distribution function of the probability distribution at ``x``. @@ -918,7 +918,7 @@ cdef class RealDistribution(ProbabilityDistribution): raise TypeError("Not a supported probability distribution") def cum_distribution_function_inv(self, x): - """ + r""" Evaluate the inverse of the cumulative distribution distribution function of the probability distribution at ``x``. @@ -955,7 +955,7 @@ cdef class RealDistribution(ProbabilityDistribution): raise TypeError("Not a supported probability distribution") def plot(self, *args, **kwds): - """ + r""" Plot the distribution function for the probability distribution. Parameters to :func:`sage.plot.plot.plot` can be passed through ``*args`` and ``**kwds``. @@ -970,18 +970,18 @@ cdef class RealDistribution(ProbabilityDistribution): cdef class GeneralDiscreteDistribution(ProbabilityDistribution): - """ + r""" Create a discrete probability distribution. INPUT: - - ``P`` - list of probabilities. The list will automatically be + - ``P`` -- list of probabilities. The list will automatically be normalised if ``sum(P)`` is not equal to 1. - - ``rng`` - (optional) random number generator to use. May be + - ``rng`` -- (optional) random number generator to use. May be one of ``'default'``, ``'luxury'``, or ``'taus'``. - - ``seed`` - (optional) seed to use with the random number + - ``seed`` -- (optional) seed to use with the random number generator. OUTPUT: @@ -991,7 +991,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): EXAMPLES: - Constructs a ``GeneralDiscreteDistribution`` with the probability + Construct a ``GeneralDiscreteDistribution`` with the probability distribution `P` where `P(0) = 0.3`, `P(1) = 0.4`, `P(2) = 0.3`:: sage: P = [0.3, 0.4, 0.3] @@ -1013,7 +1013,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): The distribution probabilities will automatically be normalised:: sage: P = [0.1, 0.3] - sage: X = GeneralDiscreteDistribution(P, seed = 0) + sage: X = GeneralDiscreteDistribution(P, seed=0) sage: counts = [0, 0] sage: for _ in range(10000): ....: counts[X.get_random_element()] += 1 @@ -1042,7 +1042,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): cdef gsl_ran_discrete_t *dist cdef long seed - def __init__(self, P, rng = 'default', seed = None): + def __init__(self, P, rng='default', seed=None): r""" Given a list of probabilities P construct an instance of a gsl discrete random variable generator. @@ -1108,7 +1108,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): sig_free(P_vec) def set_seed(self, seed): - """ + r""" Set the seed to be used by the random number generator. EXAMPLES:: @@ -1121,8 +1121,8 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): gsl_rng_set(self.r, seed) self.seed = seed - def set_random_number_generator(self, rng = 'default'): - """ + def set_random_number_generator(self, rng='default'): + r""" Set the random number generator to be used by gsl. EXAMPLES:: @@ -1147,7 +1147,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): gsl_ran_discrete_free(self.dist) def get_random_element(self): - """ + r""" Get a random sample from the probability distribution. EXAMPLES:: @@ -1162,7 +1162,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): return sage.rings.integer.Integer(gsl_ran_discrete(self.r, self.dist)) def reset_distribution(self): - """ + r""" This method resets the distribution. EXAMPLES:: From 045d0e782945082d02ddb55ee01b9cd5a7c34475 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 15 Aug 2023 22:28:02 -0700 Subject: [PATCH 93/99] src/sage/stats/hmm/chmm.pyx: Docstring cosmetics --- src/sage/stats/hmm/chmm.pyx | 193 ++++++++++++++++++------------------ 1 file changed, 96 insertions(+), 97 deletions(-) diff --git a/src/sage/stats/hmm/chmm.pyx b/src/sage/stats/hmm/chmm.pyx index 69b05b6c860..fc2aedb419d 100644 --- a/src/sage/stats/hmm/chmm.pyx +++ b/src/sage/stats/hmm/chmm.pyx @@ -1,5 +1,5 @@ # sage.doctest: optional - numpy -""" +r""" Continuous Emission Hidden Markov Models AUTHOR: @@ -39,7 +39,7 @@ from sage.misc.randstate cimport current_randstate, randstate # TODO: DELETE THIS FUNCTION WHEN MOVE Gaussian stuff to distributions.pyx!!! (next version) cdef double random_normal(double mean, double std, randstate rstate): - """ + r""" Return a number chosen randomly with given mean and standard deviation. INPUT: @@ -50,7 +50,7 @@ cdef double random_normal(double mean, double std, randstate rstate): OUTPUT: - - a double + a double """ # Ported from http://users.tkk.fi/~nbeijar/soft/terrain/source_o2/boxmuller.c # This the box muller algorithm. @@ -68,7 +68,7 @@ cdef double random_normal(double mean, double std, randstate rstate): return mean + y1*std cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): - """ + r""" Gaussian emissions Hidden Markov Model. INPUT: @@ -157,28 +157,28 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): cdef int n_out def __init__(self, A, B, pi, bint normalize=True): - """ + r""" Create a Gaussian emissions HMM with transition probability - matrix A, normal emissions given by B, and initial state - probability distribution pi. + matrix `A`, normal emissions given by `B`, and initial state + probability distribution ``pi``. INPUT: - - A -- a list of lists or a square N x N matrix, whose - (i,j) entry gives the probability of transitioning from - state i to state j. + - ``A`` -- a list of lists or a square `N \times N` matrix, whose + `(i,j)` entry gives the probability of transitioning from + state `i` to state `j`. - - B -- a list of N pairs (mu,std), where if B[i]=(mu,std), - then the probability distribution associated with state i - normal with mean mu and standard deviation std. + - ``B`` -- a list of `N` pairs ``(mu, std)``, where if ``B[i]=(mu,std)``, + then the probability distribution associated with state `i` + normal with mean ``mu`` and standard deviation ``std``. - - pi -- the probabilities of starting in each initial - state, i.e,. pi[i] is the probability of starting in - state i. + - ``pi`` -- the probabilities of starting in each initial + state, i.e., ``pi[i]`` is the probability of starting in + state `i`. - - normalize --bool (default: True); if given, input is + - ``normalize`` -- bool (default: ``True``); if given, input is normalized to define valid probability distributions, - e.g., the entries of A are made nonnegative and the rows + e.g., the entries of `A` are made nonnegative and the rows sum to 1. EXAMPLES:: @@ -193,7 +193,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): [(1.0, 1.0), (-1.0, 1.0)] Initial probabilities: [0.5000, 0.5000] - We input a model in which both A and pi have to be + We input a model in which both `A` and ``pi`` have to be renormalized to define valid probability distributions:: sage: hmm.GaussianHiddenMarkovModel([[-1,.7],[.3,.4]], [(1,1), (-1,1)], [-1,.3]) # rel tol 3e-14 @@ -207,7 +207,8 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): Bad things can happen:: - sage: hmm.GaussianHiddenMarkovModel([[-1,.7],[.3,.4]], [(1,1), (-1,1)], [-1,.3], normalize=False) + sage: hmm.GaussianHiddenMarkovModel([[-1,.7],[.3,.4]], [(1,1), (-1,1)], [-1,.3], + ....: normalize=False) Gaussian Hidden Markov Model with 2 States Transition matrix: [-1.0 0.7] @@ -228,8 +229,8 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): self.probability_init() def __richcmp__(self, other, op): - """ - Compare self and other, which must both be GaussianHiddenMarkovModel's. + r""" + Compare ``self`` and ``other``, which must both be GaussianHiddenMarkovModel's. EXAMPLES:: @@ -250,16 +251,14 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): other.__reduce__()[1], op) def __getitem__(self, Py_ssize_t i): - """ - Return the mean and standard distribution for the i-th state. + r""" + Return the mean and standard distribution for the `i`-th state. INPUT: - - i -- integer - - OUTPUT: + - ``i`` -- integer - - 2 floats + OUTPUT: 2 floats EXAMPLES:: @@ -288,7 +287,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): return self.B[2*i], self.B[2*i+1] def __reduce__(self): - """ + r""" Used in pickling. EXAMPLES:: @@ -301,15 +300,15 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): (self.A, self.B, self.pi, self.prob, self.n_out) def emission_parameters(self): - """ + r""" Return the parameters that define the normal distributions associated to all of the states. OUTPUT: - - a list ``B`` of pairs ``B[i] = (mu, std)``, such that the - distribution associated to state `i` is normal with mean - ``mu`` and standard deviation ``std``. + a list ``B`` of pairs ``B[i] = (mu, std)``, such that the + distribution associated to state `i` is normal with mean + ``mu`` and standard deviation ``std``. EXAMPLES:: @@ -340,7 +339,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): def generate_sequence(self, Py_ssize_t length, starting_state=None): - """ + r""" Return a sample of the given length from this HMM. INPUT: @@ -449,7 +448,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): return obs, states cdef probability_init(self): - """ + r""" Used internally to compute caching information that makes certain computations in the Baum-Welch algorithm faster. This function has no input or output. @@ -461,7 +460,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): self.prob[2*i+1] = -1.0/(2*self.B[2*i+1]*self.B[2*i+1]) cdef double random_sample(self, int state, randstate rstate): - """ + r""" Return a random sample from the normal distribution associated to the given state. @@ -471,17 +470,17 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - state -- integer - - rstate -- randstate instance + - ``state`` -- integer + - ``rstate`` -- randstate instance OUTPUT: - - double + double """ return random_normal(self.B._values[state*2], self.B._values[state*2+1], rstate) cdef double probability_of(self, int state, double observation): - """ + r""" Return a useful continuous analogue of "the probability b_j(o)" of seeing the given observation given that we're in the given state j (=state). @@ -497,12 +496,12 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - state -- integer - - observation -- double + - ``state`` -- integer + - ``observation`` -- double OUTPUT: - - double + double """ # The code below is an optimized version of the following code: # cdef double mean = self.B._values[2*state], \ @@ -525,7 +524,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): return self.prob._values[2*state] * exp(x*x*self.prob._values[2*state+1]) def log_likelihood(self, obs): - """ + r""" Return the logarithm of a continuous analogue of the probability that this model produced the given observation sequence. @@ -539,7 +538,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): OUTPUT: - - float + float EXAMPLES:: @@ -559,17 +558,17 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): return self._forward_scale(obs) def _forward_scale(self, TimeSeries obs): - """ + r""" Memory-efficient implementation of the forward algorithm (with scaling). INPUT: - - obs -- an integer list of observation states. + - ``obs`` -- an integer list of observation states. OUTPUT: - - float -- the log of the probability that the model - produced this sequence + float -- the log of the probability that the model + produced this sequence EXAMPLES:: @@ -615,15 +614,15 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): return log_probability def viterbi(self, obs): - """ + r""" Determine "the" hidden sequence of states that is most likely - to produce the given sequence seq of observations, along with + to produce the given sequence ``obs`` of observations, along with the probability that this hidden sequence actually produced the observation. INPUT: - - seq -- sequence of emitted ints or symbols + - ``obs`` -- sequence of emitted ints or symbols OUTPUT: @@ -719,7 +718,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): return state_sequence, mx cdef TimeSeries _backward_scale_all(self, TimeSeries obs, TimeSeries scale): - """ + r""" This function returns the matrix beta_t(i), and is used internally as part of the Baum-Welch algorithm. @@ -729,8 +728,8 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- TimeSeries - - scale -- TimeSeries + - ``obs`` -- TimeSeries + - ``scale`` -- TimeSeries OUTPUT: @@ -759,7 +758,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): return beta cdef _forward_scale_all(self, TimeSeries obs): - """ + r""" Return scaled values alpha_t(i), the sequence of scalings, and the log probability. @@ -769,7 +768,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - obs -- TimeSeries + - ``obs`` -- TimeSeries OUTPUT: @@ -824,19 +823,19 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): return alpha, scale, log_probability cdef TimeSeries _baum_welch_xi(self, TimeSeries alpha, TimeSeries beta, TimeSeries obs): - """ + r""" Used internally to compute the scaled quantity xi_t(i,j) appearing in the Baum-Welch reestimation algorithm. INPUT: - - alpha -- TimeSeries as output by the scaled forward algorithm - - beta -- TimeSeries as output by the scaled backward algorithm - - obs -- TimeSeries of observations + - ``alpha`` -- TimeSeries as output by the scaled forward algorithm + - ``beta`` -- TimeSeries as output by the scaled backward algorithm + - ``obs`` -- TimeSeries of observations OUTPUT: - - TimeSeries xi such that xi[t*N*N + i*N + j] = xi_t(i,j). + TimeSeries xi such that xi[t*N*N + i*N + j] = xi_t(i,j). """ cdef int i, j, N = self.N cdef double sum @@ -856,9 +855,9 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): def baum_welch(self, obs, int max_iter=500, double log_likelihood_cutoff=1e-4, double min_sd=0.01, bint fix_emissions=False, bint v=False): - """ - Given an observation sequence obs, improve this HMM using the - Baum-Welch algorithm to increase the probability of observing obs. + r""" + Given an observation sequence ``obs``, improve this HMM using the + Baum-Welch algorithm to increase the probability of observing ``obs``. INPUT: @@ -881,8 +880,8 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): OUTPUT: - - changes the model in places, and returns the log - likelihood and number of iterations. + changes the model in place, and returns the log + likelihood and number of iterations. EXAMPLES:: @@ -1047,7 +1046,7 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): - """ + r""" Gaussian mixture Hidden Markov Model. INPUT: @@ -1113,7 +1112,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): cdef object mixture # mixture def __init__(self, A, B, pi=None, bint normalize=True): - """ + r""" Initialize a Gaussian mixture hidden Markov model. EXAMPLES:: @@ -1155,7 +1154,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): return s def __reduce__(self): - """ + r""" Used in pickling. EXAMPLES:: @@ -1169,7 +1168,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): def __richcmp__(self, other, op): - """ + r""" Compare self and other, which must both be GaussianMixtureHiddenMarkovModel's. EXAMPLES:: @@ -1191,17 +1190,17 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): other.__reduce__()[1], op) def __getitem__(self, Py_ssize_t i): - """ + r""" Return the Gaussian mixture distribution associated to the i-th state. INPUT: - - i -- integer + - ``i`` -- integer OUTPUT: - - a Gaussian mixture distribution object + a Gaussian mixture distribution object EXAMPLES:: @@ -1234,12 +1233,12 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): return self.mixture[i] def emission_parameters(self): - """ + r""" Returns a list of all the emission distributions. OUTPUT: - - list of Gaussian mixtures + list of Gaussian mixtures EXAMPLES:: @@ -1252,7 +1251,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): return list(self.mixture) cdef double random_sample(self, int state, randstate rstate): - """ + r""" Return a random sample from the normal distribution associated to the given state. @@ -1262,18 +1261,18 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): INPUT: - - state -- integer - - rstate -- randstate instance + - ``state`` -- integer + - ``rstate`` -- randstate instance OUTPUT: - - double + double """ cdef GaussianMixtureDistribution G = self.mixture[state] return G._sample(rstate) cdef double probability_of(self, int state, double observation): - """ + r""" Return the probability b_j(o) of see the given observation o (=observation) given that we're in the given state j (=state). @@ -1283,19 +1282,19 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): INPUT: - - state -- integer - - observation -- double + - ``state`` -- integer + - ``observation`` -- double OUTPUT: - - double + double """ cdef GaussianMixtureDistribution G = self.mixture[state] return G.prob(observation) cdef TimeSeries _baum_welch_mixed_gamma(self, TimeSeries alpha, TimeSeries beta, TimeSeries obs, int j): - """ + r""" Let gamma_t(j,m) be the m-component (in the mixture) of the probability of being in state j at time t, given the observation sequence. This function outputs a TimeSeries v @@ -1304,14 +1303,14 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): INPUT: - - alpha -- TimeSeries - - beta -- TimeSeries - - obs -- TimeSeries - - j -- int + - ``alpha`` -- TimeSeries + - ``beta`` -- TimeSeries + - ``obs`` -- TimeSeries + - ``j`` -- int OUTPUT: - - TimeSeries + TimeSeries """ cdef int i, k, m, N = self.N cdef Py_ssize_t t, T = alpha._length//N @@ -1348,7 +1347,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): def baum_welch(self, obs, int max_iter=1000, double log_likelihood_cutoff=1e-12, double min_sd=0.01, bint fix_emissions=False): - """ + r""" Given an observation sequence ``obs``, improve this HMM using the Baum-Welch algorithm to increase the probability of observing ``obs``. @@ -1369,8 +1368,8 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): OUTPUT: - - changes the model in places, and returns the log - likelihood and number of iterations. + changes the model in place, and returns the log + likelihood and number of iterations. EXAMPLES:: @@ -1423,7 +1422,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): sage: m.emission_parameters() [0.4*N(0.0,1.0) + 0.6*N(1.0,0.1), 1.0*N(0.0,1.0)] - """ + r""" if not isinstance(obs, TimeSeries): obs = TimeSeries(obs) cdef TimeSeries _obs = obs @@ -1555,7 +1554,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): # We keep the _v0 function for backwards compatible. def unpickle_gaussian_hmm_v0(A, B, pi, name): - """ + r""" EXAMPLES:: sage: m = hmm.GaussianHiddenMarkovModel([[1]], [(0,1)], [1]) @@ -1571,7 +1570,7 @@ def unpickle_gaussian_hmm_v0(A, B, pi, name): def unpickle_gaussian_hmm_v1(A, B, pi, prob, n_out): - """ + r""" EXAMPLES:: sage: m = hmm.GaussianHiddenMarkovModel([[1]], [(0,1)], [1]) @@ -1587,7 +1586,7 @@ def unpickle_gaussian_hmm_v1(A, B, pi, prob, n_out): return m def unpickle_gaussian_mixture_hmm_v1(A, B, pi, mixture): - """ + r""" EXAMPLES:: sage: m = hmm.GaussianMixtureHiddenMarkovModel([[1]], [[(.4,(0,1)), (.6,(1,0.1))]], [1]) From a0544915c9d1ccaf78fe6162acd232cd686966d3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 15 Aug 2023 22:45:38 -0700 Subject: [PATCH 94/99] src/sage/stats/hmm/hmm.pyx: Docstring cosmetics --- src/sage/stats/hmm/hmm.pyx | 73 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/sage/stats/hmm/hmm.pyx b/src/sage/stats/hmm/hmm.pyx index 04b266cc3e0..f48d0c9e4db 100644 --- a/src/sage/stats/hmm/hmm.pyx +++ b/src/sage/stats/hmm/hmm.pyx @@ -1,5 +1,5 @@ # sage.doctest: needs numpy sage.modules -""" +r""" Hidden Markov Models This is a complete pure-Cython optimized implementation of Hidden @@ -48,11 +48,11 @@ cdef HMM_Util util = HMM_Util() ########################################### cdef class HiddenMarkovModel: - """ + r""" Abstract base class for all Hidden Markov Models. """ def initial_probabilities(self): - """ + r""" Return the initial probabilities as a :class:`TimeSeries` of length `N`, where `N` is the number of states of the Markov model. @@ -90,7 +90,7 @@ cdef class HiddenMarkovModel: return TimeSeries(self.pi) def transition_matrix(self): - """ + r""" Return the state transition matrix. OUTPUT: a Sage matrix with real double precision (RDF) entries. @@ -133,15 +133,15 @@ cdef class HiddenMarkovModel: return matrix(RDF, self.N, self.A.list()) def graph(self, eps=1e-3): - """ + r""" Create a weighted directed graph from the transition matrix, not including any edge with a probability less than ``eps``. INPUT: - - eps -- nonnegative real number + - ``eps`` -- nonnegative real number - OUTPUT: a digraph + OUTPUT: a :class:`DiGraph` EXAMPLES:: @@ -165,7 +165,7 @@ cdef class HiddenMarkovModel: return DiGraph(m, weighted=True) def sample(self, Py_ssize_t length, number=None, starting_state=None): - """ + r""" Return number samples from this HMM of given length. INPUT: @@ -225,7 +225,7 @@ cdef class HiddenMarkovModel: # HMM algorithms. ######################################################### cdef TimeSeries _baum_welch_gamma(self, TimeSeries alpha, TimeSeries beta): - """ + r""" Used internally to compute the scaled quantity gamma_t(j) appearing in the Baum-Welch reestimation algorithm. @@ -256,7 +256,7 @@ cdef class HiddenMarkovModel: cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): - """ + r""" A discrete Hidden Markov model implemented using double precision floating point arithmetic. @@ -328,7 +328,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): cdef object _emission_symbols, _emission_symbols_dict def __init__(self, A, B, pi, emission_symbols=None, bint normalize=True): - """ + r""" Create a discrete emissions HMM with transition probability matrix A, emission probabilities given by B, initial state probabilities pi, and given emission symbols (which default @@ -371,7 +371,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): util.normalize_probability_TimeSeries(self.B, i*self.n_out, (i+1)*self.n_out) def __reduce__(self): - """ + r""" Used in pickling. EXAMPLES:: @@ -384,7 +384,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): (self.A, self.B, self.pi, self.n_out, self._emission_symbols, self._emission_symbols_dict) def __richcmp__(self, other, op): - """ + r""" EXAMPLES:: sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.0,1.0],[0.5,0.5]], [.5,.5]) @@ -404,7 +404,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): other.__reduce__()[1], op) def emission_matrix(self): - """ + r""" Return the matrix whose `i`-th row specifies the emission probability distribution for the `i`-th state. @@ -456,12 +456,12 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return s def _emission_symbols_to_IntList(self, obs): - """ + r""" Internal function used to convert a list of emission symbols to an :class:`IntList`. INPUT: - - obs -- a list of objects + - ``obs`` -- a list of objects OUTPUT: an IntList @@ -475,12 +475,12 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return IntList([d[x] for x in obs]) def _IntList_to_emission_symbols(self, obs): - """ + r""" Internal function used to convert a list of emission symbols to an IntList. INPUT: - - obs -- a list of objects + - ``obs`` -- a list of objects OUTPUT: an IntList @@ -494,7 +494,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return [d[x] for x in obs] def log_likelihood(self, obs, bint scale=True): - """ + r""" Return the logarithm of the probability that this model produced the given observation sequence. Thus the output is a non-positive number. @@ -549,7 +549,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return self._forward(obs) def _forward(self, IntList obs): - """ + r""" Memory-efficient implementation of the forward algorithm, without scaling. INPUT: @@ -558,7 +558,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): OUTPUT: - - ``float`` -- the log of the probability that the model produced this sequence + ``float`` -- the log of the probability that the model produced this sequence EXAMPLES:: @@ -604,7 +604,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return log(alpha.sum()) def _forward_scale(self, IntList obs): - """ + r""" Memory-efficient implementation of the forward algorithm, with scaling. INPUT: @@ -613,7 +613,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): OUTPUT: - - ``float`` -- the log of the probability that the model produced this sequence + ``float`` -- the log of the probability that the model produced this sequence EXAMPLES:: @@ -693,7 +693,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return log_probability def generate_sequence(self, Py_ssize_t length, starting_state=None): - """ + r""" Return a sample of the given length from this HMM. INPUT: @@ -704,7 +704,6 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): instead of the initial probabilities to determine the starting state. - OUTPUT: - an :class:`IntList` or list of emission symbols @@ -812,7 +811,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return self._IntList_to_emission_symbols(obs), states cdef int _gen_symbol(self, int q, double r): - """ + r""" Generate a symbol in state q using the randomly chosen floating point number r, which should be between 0 and 1. @@ -823,7 +822,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): OUTPUT: - - a nonnegative int + a nonnegative int EXAMPLES:: @@ -848,7 +847,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return self.n_out - 1 def viterbi(self, obs, log_scale=True): - """ + r""" Determine "the" hidden sequence of states that is most likely to produce the given sequence seq of observations, along with the probability that this hidden sequence actually produced @@ -899,7 +898,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return self._viterbi(obs) cpdef _viterbi(self, IntList obs): - """ + r""" Used internally to compute the viterbi path, without rescaling. This can be useful for short sequences. @@ -979,12 +978,12 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): cpdef _viterbi_scale(self, IntList obs): - """ + r""" Used internally to compute the viterbi path with rescaling. INPUT: - - obs -- IntList + - ``obs`` -- IntList OUTPUT: @@ -1110,7 +1109,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return beta cdef _forward_scale_all(self, IntList obs): - """ + r""" Return scaled values alpha_t(i), the sequence of scalings, and the log probability. @@ -1171,7 +1170,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return alpha, scale, log_probability cdef TimeSeries _baum_welch_xi(self, TimeSeries alpha, TimeSeries beta, IntList obs): - """ + r""" Used internally to compute the scaled quantity xi_t(i,j) appearing in the Baum-Welch reestimation algorithm. @@ -1204,7 +1203,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): return xi def baum_welch(self, obs, int max_iter=100, double log_likelihood_cutoff=1e-4, bint fix_emissions=False): - """ + r""" Given an observation sequence obs, improve this HMM using the Baum-Welch algorithm to increase the probability of observing obs. @@ -1225,8 +1224,8 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): OUTPUT: - - changes the model in places, and returns the log - likelihood and number of iterations. + changes the model in place, and returns the log + likelihood and number of iterations. EXAMPLES:: @@ -1355,7 +1354,7 @@ cdef class DiscreteHiddenMarkovModel(HiddenMarkovModel): # Keep this -- it's for backwards compatibility with the GHMM based implementation def unpickle_discrete_hmm_v0(A, B, pi, emission_symbols, name): - """ + r""" TESTS:: sage: m = hmm.DiscreteHiddenMarkovModel([[0.4,0.6],[0.1,0.9]], [[0.0,1.0],[0.5,0.5]], [1,0]) From 94b2c0bf49b62ab59a7d635d99c437c2f7bbd74d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 15 Aug 2023 22:58:42 -0700 Subject: [PATCH 95/99] src/sage/stats/hmm/distributions.pyx: Raw docstrings --- src/sage/stats/hmm/distributions.pyx | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/sage/stats/hmm/distributions.pyx b/src/sage/stats/hmm/distributions.pyx index 1620730544c..65a743e26f1 100644 --- a/src/sage/stats/hmm/distributions.pyx +++ b/src/sage/stats/hmm/distributions.pyx @@ -1,5 +1,5 @@ # sage.doctest: optional - numpy -""" +r""" Distributions used in implementing Hidden Markov Models These distribution classes are designed specifically for HMM's and not @@ -35,7 +35,7 @@ from sage.stats.time_series cimport TimeSeries cdef double random_normal(double mean, double std, randstate rstate): - """ + r""" Return a floating point number chosen from the normal distribution with given mean and standard deviation, using the given randstate. The computation uses the box muller algorithm. @@ -67,11 +67,11 @@ cdef double random_normal(double mean, double std, randstate rstate): # Abstract base class for distributions used for hidden Markov models. cdef class Distribution: - """ + r""" A distribution. """ def sample(self, n=None): - """ + r""" Return either a single sample (the default) or `n` samples from this probability distribution. @@ -96,7 +96,7 @@ cdef class Distribution: raise NotImplementedError def prob(self, x): - """ + r""" The probability density function evaluated at `x`. INPUT: @@ -120,7 +120,7 @@ cdef class Distribution: raise NotImplementedError def plot(self, *args, **kwds): - """ + r""" Return a plot of the probability density function. INPUT: @@ -141,7 +141,7 @@ cdef class Distribution: return plot(self.prob, *args, **kwds) cdef class GaussianMixtureDistribution(Distribution): - """ + r""" A probability distribution defined by taking a weighted linear combination of Gaussian distributions. @@ -163,17 +163,17 @@ cdef class GaussianMixtureDistribution(Distribution): False """ def __init__(self, B, eps=1e-8, bint normalize=True): - """ + r""" INPUT: - - `B` -- a list of triples `(c_i, mean_i, std_i)`, where - the `c_i` and `std_i` are positive and the sum of the - `c_i` is `1`. + - ``B`` -- a list of triples ``(c_i, mean_i, std_i)``, where + the ``c_i`` and ``std_i`` are positive and the sum of the + ``c_i`` is `1`. - - eps -- positive real number; any standard deviation in B + - ``eps`` -- positive real number; any standard deviation in B less than eps is replaced by eps. - - normalize -- if True, ensure that the c_i are nonnegative + - ``normalize`` -- if ``True``, ensure that the ``c_i`` are nonnegative EXAMPLES:: @@ -202,12 +202,12 @@ cdef class GaussianMixtureDistribution(Distribution): self.fixed = IntList(self.c0._length) def __getitem__(self, Py_ssize_t i): - """ + r""" Return triple (coefficient, mu, std). INPUT: - - i -- integer + - ``i`` -- integer OUTPUT: @@ -239,7 +239,7 @@ cdef class GaussianMixtureDistribution(Distribution): return self.param._values[3*i], self.param._values[3*i+1], self.param._values[3*i+2] def __reduce__(self): - """ + r""" Used in pickling. EXAMPLES:: @@ -252,7 +252,7 @@ cdef class GaussianMixtureDistribution(Distribution): self.c0, self.c1, self.param, self.fixed) def __richcmp__(self, other, op): - """ + r""" EXAMPLES:: sage: G = hmm.GaussianMixtureDistribution([(.1,1,2), (.9,0,1)]) @@ -272,7 +272,7 @@ cdef class GaussianMixtureDistribution(Distribution): other.__reduce__()[1], op) def __len__(self): - """ + r""" Return the number of components of this GaussianMixtureDistribution. EXAMPLES:: @@ -283,7 +283,7 @@ cdef class GaussianMixtureDistribution(Distribution): return self.c0._length cpdef is_fixed(self, i=None): - """ + r""" Return whether or not this :class:`GaussianMixtureDistribution` is fixed when using Baum-Welch to update the corresponding HMM. @@ -312,7 +312,7 @@ cdef class GaussianMixtureDistribution(Distribution): return bool(self.fixed[i]) def fix(self, i=None): - """ + r""" Set that this :class:`GaussianMixtureDistribution` (or its `i`-th component) is fixed when using Baum-Welch to update the corresponding HMM. @@ -340,7 +340,7 @@ cdef class GaussianMixtureDistribution(Distribution): self.fixed[i] = 1 def unfix(self, i=None): - """ + r""" Set that this :class:`GaussianMixtureDistribution` (or its `i`-th component) is not fixed when using Baum-Welch to update the corresponding HMM. @@ -372,7 +372,7 @@ cdef class GaussianMixtureDistribution(Distribution): def __repr__(self): - """ + r""" Return string representation of this mixed Gaussian distribution. EXAMPLES:: @@ -383,7 +383,7 @@ cdef class GaussianMixtureDistribution(Distribution): return ' + '.join("%s*N(%s,%s)" % x for x in self) def sample(self, n=None): - """ + r""" Return a single sample from this distribution (by default), or if `n>1`, return a :class:`TimeSeries` of samples. @@ -435,12 +435,12 @@ cdef class GaussianMixtureDistribution(Distribution): return T cdef double _sample(self, randstate rstate): - """ + r""" Used internally to compute a sample from this distribution quickly. INPUT: - - rstate -- a randstate object + - ``rstate`` -- a randstate object OUTPUT: @@ -460,7 +460,7 @@ cdef class GaussianMixtureDistribution(Distribution): raise RuntimeError("invalid probability distribution") cpdef double prob(self, double x): - """ + r""" Return the probability of `x`. Since this is a continuous distribution, this is defined to be @@ -496,7 +496,7 @@ cdef class GaussianMixtureDistribution(Distribution): return s cpdef double prob_m(self, double x, int m): - """ + r""" Return the probability of `x` using just the `m`-th summand. INPUT: @@ -526,7 +526,7 @@ cdef class GaussianMixtureDistribution(Distribution): def unpickle_gaussian_mixture_distribution_v1(TimeSeries c0, TimeSeries c1, TimeSeries param, IntList fixed): - """ + r""" Used in unpickling :class:`GaussianMixtureDistribution` objects. EXAMPLES:: From 8b80da13ce2220d12c226ab8658b6cdfc56e414b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 15 Aug 2023 23:09:36 -0700 Subject: [PATCH 96/99] src/sage/stats/time_series.pyx: Raw docstrings --- src/sage/stats/time_series.pyx | 112 ++++++++++++++++----------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 8fe93fbb703..65c332d4442 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -1,5 +1,5 @@ # sage.doctest: optional - numpy -""" +r""" Time Series This is a module for working with discrete floating point time series. @@ -67,7 +67,7 @@ digits = 4 cdef class TimeSeries: def __cinit__(self): - """ + r""" Create new empty uninitialized time series. EXAMPLES: @@ -80,7 +80,7 @@ cdef class TimeSeries: self._values = NULL def __init__(self, values, bint initialize=True): - """ + r""" Initialize new time series. INPUT: @@ -172,7 +172,7 @@ cdef class TimeSeries: self._values[i] = 0 def __reduce__(self): - """ + r""" Used in pickling time series. EXAMPLES:: @@ -194,7 +194,7 @@ cdef class TimeSeries: return unpickle_time_series_v1, (buf, self._length) def __richcmp__(TimeSeries self, other, int op): - """ + r""" Compare ``self`` and ``other``. This has the same semantics as list comparison. @@ -225,7 +225,7 @@ cdef class TimeSeries: return rich_to_bool(op, 0) def __dealloc__(self): - """ + r""" Free up memory used by a time series. EXAMPLES: @@ -238,7 +238,7 @@ cdef class TimeSeries: sig_free(self._values) def vector(self): - """ + r""" Return real double vector whose entries are the values of this time series. This is useful since vectors have standard algebraic structure and play well with matrices. @@ -259,7 +259,7 @@ cdef class TimeSeries: return x def __repr__(self): - """ + r""" Return string representation of ``self``. EXAMPLES:: @@ -283,7 +283,7 @@ cdef class TimeSeries: return self._repr() def _repr(self, prec=None): - """ + r""" Print representation of a time series. INPUT: @@ -317,7 +317,7 @@ cdef class TimeSeries: return '[' + ', '.join(format%x for x in self) + ']' def __len__(self): - """ + r""" Return the number of entries in this time series. OUTPUT: @@ -335,8 +335,8 @@ cdef class TimeSeries: return self._length def __getitem__(self, i): - """ - Return i-th entry or slice of ``self``. + r""" + Return `i`-th entry or slice of ``self``. EXAMPLES:: @@ -421,14 +421,14 @@ cdef class TimeSeries: return self._values[j] def __setitem__(self, Py_ssize_t i, double x): - """ - Set the i-th entry of ``self`` to ``x``. + r""" + Set the `i`-th entry of ``self`` to ``x``. INPUT: - - i -- a nonnegative integer. + - ``i`` -- a nonnegative integer. - - x -- a float. + - ``x`` -- a float. EXAMPLES:: @@ -456,7 +456,7 @@ cdef class TimeSeries: self._values[i] = x def __copy__(self): - """ + r""" Return a copy of ``self``. EXAMPLES:: @@ -475,7 +475,7 @@ cdef class TimeSeries: return t def __add__(left, right): - """ + r""" Concatenate the time series ``self`` and ``right``. .. NOTE:: @@ -523,7 +523,7 @@ cdef class TimeSeries: return t def __mul__(left, right): - """ + r""" Multiply a time series by an integer n, which (like for lists) results in the time series concatenated with itself n times. @@ -625,7 +625,7 @@ cdef class TimeSeries: return autoregressive_fit(acvs) def autoregressive_forecast(self, filter): - """ + r""" Given the autoregression coefficients as outputted by the :meth:`autoregressive_fit` command, compute the forecast for the next term in the series. @@ -659,7 +659,7 @@ cdef class TimeSeries: return f def reversed(self): - """ + r""" Return new time series obtain from this time series by reversing the order of the entries in this time series. @@ -681,7 +681,7 @@ cdef class TimeSeries: return t def extend(self, right): - """ + r""" Extend this time series by appending elements from the iterable ``right``. @@ -712,7 +712,7 @@ cdef class TimeSeries: self._length = self._length + T._length def list(self): - """ + r""" Return list of elements of ``self``. EXAMPLES:: @@ -725,7 +725,7 @@ cdef class TimeSeries: return [self._values[i] for i in range(self._length)] def log(self): - """ + r""" Return new time series got by taking the logarithms of all the terms in the time series. @@ -757,7 +757,7 @@ cdef class TimeSeries: return t def exp(self): - """ + r""" Return new time series got by applying the exponential map to all the terms in the time series. @@ -781,7 +781,7 @@ cdef class TimeSeries: return t def abs(self): - """ + r""" Return new time series got by replacing all entries of ``self`` by their absolute value. @@ -893,7 +893,7 @@ cdef class TimeSeries: return t cpdef rescale(self, double s): - """ + r""" Change ``self`` by multiplying every value in the series by ``s``. INPUT: @@ -912,7 +912,7 @@ cdef class TimeSeries: self._values[i] = self._values[i] * s def scale(self, double s): - """ + r""" Return new time series obtained by multiplying every value in the series by ``s``. @@ -937,7 +937,7 @@ cdef class TimeSeries: return t def add_scalar(self, double s): - """ + r""" Return new time series obtained by adding a scalar to every value in the series. @@ -966,7 +966,7 @@ cdef class TimeSeries: return t def add_entries(self, t): - """ + r""" Add corresponding entries of ``self`` and ``t`` together, extending either ``self`` or ``t`` by 0's if they do not have the same length. @@ -1023,7 +1023,7 @@ cdef class TimeSeries: return v def show(self, *args, **kwds): - """ + r""" Return a plot of this time series. This is an alias of :meth:`plot`. @@ -1093,7 +1093,7 @@ cdef class TimeSeries: return L def simple_moving_average(self, Py_ssize_t k): - """ + r""" Return the moving average time series over the last `k` time units. Assumes the input time series was constant with its starting value @@ -1144,7 +1144,7 @@ cdef class TimeSeries: return t def exponential_moving_average(self, double alpha): - """ + r""" Return the exponential moving average time series. Assumes the input time series was constant with its starting @@ -1197,7 +1197,7 @@ cdef class TimeSeries: return t def sums(self, double s=0): - """ + r""" Return the new time series got by taking the running partial sums of the terms of this time series. @@ -1224,7 +1224,7 @@ cdef class TimeSeries: return t cpdef double sum(self): - """ + r""" Return the sum of all the entries of ``self``. If ``self`` has length 0, returns 0. @@ -1247,7 +1247,7 @@ cdef class TimeSeries: return s def prod(self): - """ + r""" Return the product of all the entries of ``self``. If ``self`` has length 0, returns 1. @@ -1271,7 +1271,7 @@ cdef class TimeSeries: def mean(self): - """ + r""" Return the mean (average) of the elements of ``self``. OUTPUT: @@ -1288,7 +1288,7 @@ cdef class TimeSeries: return self.sum() / self._length def pow(self, double k): - """ + r""" Return a new time series with all elements of ``self`` raised to the `k`-th power. @@ -1314,7 +1314,7 @@ cdef class TimeSeries: return t def moment(self, int k): - """ + r""" Return the `k`-th moment of ``self``, which is just the mean of the `k`-th powers of the elements of ``self``. @@ -1346,7 +1346,7 @@ cdef class TimeSeries: return s / self._length def central_moment(self, int k): - """ + r""" Return the `k`-th central moment of ``self``, which is just the mean of the `k`-th powers of the differences ``self[i] - mu``, where ``mu`` is the mean of ``self``. @@ -1481,7 +1481,7 @@ cdef class TimeSeries: return s / self._length def correlation(self, TimeSeries other): - """ + r""" Return the correlation of ``self`` and ``other``, which is the covariance of ``self`` and ``other`` divided by the product of their standard deviation. @@ -1546,7 +1546,7 @@ cdef class TimeSeries: return self.autocovariance(k) / self.variance(bias=True) def variance(self, bias=False): - """ + r""" Return the variance of the elements of ``self``, which is the mean of the squares of the differences from the mean. @@ -1591,7 +1591,7 @@ cdef class TimeSeries: return s / (self._length - 1) def standard_deviation(self, bias=False): - """ + r""" Return the standard deviation of the entries of ``self``. INPUT: @@ -1681,7 +1681,7 @@ cdef class TimeSeries: return (Z.max() - Z.min()) / sigma def hurst_exponent(self): - """ + r""" Return an estimate of the Hurst exponent of this time series. We use the algorithm from pages 61 -- 63 of [Peteres, Fractal @@ -1762,7 +1762,7 @@ cdef class TimeSeries: return coeffs[0] def min(self, bint index=False): - """ + r""" Return the smallest value in this time series. If this series has length 0 we raise a ``ValueError``. @@ -1800,7 +1800,7 @@ cdef class TimeSeries: return s def max(self, bint index=False): - """ + r""" Return the largest value in this time series. If this series has length 0 we raise a :class:`ValueError`. @@ -1837,7 +1837,7 @@ cdef class TimeSeries: return s def clip_remove(self, min=None, max=None): - """ + r""" Return new time series obtained from ``self`` by removing all values that are less than or equal to a certain minimum value or greater than or equal to a certain maximum. @@ -1915,7 +1915,7 @@ cdef class TimeSeries: return t def histogram(self, Py_ssize_t bins=50, bint normalize=False): - """ + r""" Return the frequency histogram of the values in this time series divided up into the given number of bins. @@ -1984,7 +1984,7 @@ cdef class TimeSeries: return counts, v def plot_histogram(self, bins=50, normalize=True, **kwds): - """ + r""" Return histogram plot of this time series with given number of bins. INPUT: @@ -2020,7 +2020,7 @@ cdef class TimeSeries: return s def plot_candlestick(self, int bins=30): - """ + r""" Return a candlestick plot of this time series with the given number of bins. @@ -2080,7 +2080,7 @@ cdef class TimeSeries: return p def numpy(self, copy=True): - """ + r""" Return a NumPy version of this time series. .. NOTE:: @@ -2240,7 +2240,7 @@ cdef class TimeSeries: return self def _randomize_uniform(self, double left, double right): - """ + r""" Generates a uniform random distribution of doubles between ``left`` and ``right`` and stores values in place. @@ -2277,7 +2277,7 @@ cdef class TimeSeries: self._values[k] = rstate.c_rand_double() * d + left def _randomize_normal(self, double m, double s): - """ + r""" Generates a normal random distribution of doubles with mean ``m`` and standard deviation ``s`` and stores values in place. Uses the Box-Muller algorithm. @@ -2334,7 +2334,7 @@ cdef class TimeSeries: self._values[k] = m + y2*s def _randomize_semicircle(self, double center): - """ + r""" Generates a semicircle random distribution of doubles about center and stores values in place. Uses the acceptance-rejection method. @@ -2552,7 +2552,7 @@ cdef class TimeSeries: cdef new_time_series(Py_ssize_t length): - """ + r""" Return a new uninitialized time series of the given length. The entries of the time series are garbage. @@ -2582,7 +2582,7 @@ cdef new_time_series(Py_ssize_t length): @cython.binding(True) def unpickle_time_series_v1(bytes v, Py_ssize_t n): - """ + r""" Version 1 unpickle method. INPUT: From 48e8294400ce1601def6ae59a88dbdf550a6f054 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 17 Aug 2023 11:06:03 -0700 Subject: [PATCH 97/99] src/sage/matrix/constructor.pyx: Doctest cosmetics --- src/sage/matrix/constructor.pyx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index 241d01db0f9..5acd5a46d59 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -238,7 +238,8 @@ def matrix(*args, **kwds): sage: M[0] = [9,9,9] Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). TESTS: @@ -509,7 +510,7 @@ def matrix(*args, **kwds): A ring and a numpy array:: sage: # needs numpy - sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]],'float32') + sage: n = numpy.array([[1,2,3], [4,5,6], [7,8,9]], 'float32') sage: m = matrix(ZZ, n); m; m.parent() [1 2 3] [4 5 6] From aecbedcebbe8ab477c6c67721a3d33b31c4180b2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 17 Aug 2023 11:08:30 -0700 Subject: [PATCH 98/99] src/sage/features/sagemath.py: Break some long docstring lines --- src/sage/features/sagemath.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 783b66579da..ac3922552e4 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -397,8 +397,8 @@ class sage__libs__linbox(JoinFeature): A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.linbox` and other modules depending on Givaro, FFLAS-FFPACK, LinBox. - In addition to the modularization purposes that this tag serves, it also provides attribution - to the upstream project. + In addition to the modularization purposes that this tag serves, + it also provides attribution to the upstream project. TESTS:: @@ -424,8 +424,8 @@ class sage__libs__m4ri(JoinFeature): A :class:`sage.features.Feature` describing the presence of Cython modules depending on the M4RI and/or M4RIe libraries. - In addition to the modularization purposes that this tag serves, it also provides attribution - to the upstream project. + In addition to the modularization purposes that this tag serves, + it also provides attribution to the upstream project. TESTS:: @@ -451,8 +451,8 @@ class sage__libs__ntl(JoinFeature): A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.ntl` and other modules depending on NTL. - In addition to the modularization purposes that this tag serves, it also provides attribution - to the upstream project. + In addition to the modularization purposes that this tag serves, + it also provides attribution to the upstream project. TESTS:: @@ -477,11 +477,12 @@ class sage__libs__pari(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of :mod:`sage.libs.pari`. - SageMath uses the :ref:`PARI ` library (via :ref:`cypari2 `) for numerous purposes. - Doctests that involves such features should be marked ``# needs sage.libs.pari``. + SageMath uses the :ref:`PARI ` library (via :ref:`cypari2 + `) for numerous purposes. Doctests that involves such features + should be marked ``# needs sage.libs.pari``. - In addition to the modularization purposes that this tag serves, it also provides attribution - to the upstream project. + In addition to the modularization purposes that this tag serves, it also + provides attribution to the upstream project. EXAMPLES:: From 4c4d62fe102ea1622860f3c3314c093b3cef5905 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 21 Aug 2023 17:12:59 -0700 Subject: [PATCH 99/99] src/sage/stats/hmm/chmm.pyx: Fix docstring indentation --- src/sage/stats/hmm/chmm.pyx | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/sage/stats/hmm/chmm.pyx b/src/sage/stats/hmm/chmm.pyx index fc2aedb419d..fe84e176a8a 100644 --- a/src/sage/stats/hmm/chmm.pyx +++ b/src/sage/stats/hmm/chmm.pyx @@ -1,4 +1,4 @@ -# sage.doctest: optional - numpy +# sage.doctest: needs numpy r""" Continuous Emission Hidden Markov Models @@ -164,26 +164,25 @@ cdef class GaussianHiddenMarkovModel(HiddenMarkovModel): INPUT: - - ``A`` -- a list of lists or a square `N \times N` matrix, whose - `(i,j)` entry gives the probability of transitioning from - state `i` to state `j`. + - ``A`` -- a list of lists or a square `N \times N` matrix, whose + `(i,j)` entry gives the probability of transitioning from + state `i` to state `j`. - - ``B`` -- a list of `N` pairs ``(mu, std)``, where if ``B[i]=(mu,std)``, - then the probability distribution associated with state `i` - normal with mean ``mu`` and standard deviation ``std``. + - ``B`` -- a list of `N` pairs ``(mu, std)``, where if ``B[i]=(mu,std)``, + then the probability distribution associated with state `i` + normal with mean ``mu`` and standard deviation ``std``. - - ``pi`` -- the probabilities of starting in each initial - state, i.e., ``pi[i]`` is the probability of starting in - state `i`. + - ``pi`` -- the probabilities of starting in each initial + state, i.e., ``pi[i]`` is the probability of starting in + state `i`. - - ``normalize`` -- bool (default: ``True``); if given, input is - normalized to define valid probability distributions, - e.g., the entries of `A` are made nonnegative and the rows - sum to 1. + - ``normalize`` -- bool (default: ``True``); if given, input is + normalized to define valid probability distributions, + e.g., the entries of `A` are made nonnegative and the rows + sum to 1. EXAMPLES:: - sage: hmm.GaussianHiddenMarkovModel([[.1,.9],[.5,.5]], [(1,1), (-1,1)], [.5,.5]) Gaussian Hidden Markov Model with 2 States Transition matrix: @@ -1422,7 +1421,7 @@ cdef class GaussianMixtureHiddenMarkovModel(GaussianHiddenMarkovModel): sage: m.emission_parameters() [0.4*N(0.0,1.0) + 0.6*N(1.0,0.1), 1.0*N(0.0,1.0)] - r""" + """ if not isinstance(obs, TimeSeries): obs = TimeSeries(obs) cdef TimeSeries _obs = obs