From 8b0824e1d4b0001f96ced5f9740461e547d4da81 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 17 Aug 2023 12:31:37 -0700 Subject: [PATCH 01/19] sage.matrix: Fix # needs (sage -fixdoctests, manual) --- src/sage/matrix/args.pyx | 1 + src/sage/matrix/matrix0.pyx | 22 ++-- src/sage/matrix/matrix1.pyx | 2 +- src/sage/matrix/matrix2.pyx | 215 ++++++++++++++++++++---------------- 4 files changed, 130 insertions(+), 110 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index bdb6eb796dd..3a86f44df7f 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -871,6 +871,7 @@ cdef class MatrixArgs: Check github issue #36065: + sage: # needs sage.rings.number_field sage: class MyAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): ....: def __bool__(self): ....: raise ValueError diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index d7a0487e6cd..afffb037d11 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): # needs sage.rings.number_fields + sage: class MyAlgebraicNumber(sage.rings.qqbar.AlgebraicNumber): # needs sage.rings.number_field ....: def __bool__(self): ....: raise ValueError - sage: mat = matrix(1, 1, MyAlgebraicNumber(1)) # needs sage.rings.number_fields - sage: bool(mat) # needs sage.rings.number_fields + sage: mat = matrix(1, 1, MyAlgebraicNumber(1)) # needs sage.rings.number_field + sage: bool(mat) # needs sage.rings.number_field Traceback (most recent call last): ... ValueError @@ -4898,7 +4898,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.groups + sage: A.multiplicative_order() # needs sage.libs.pari 580 sage: (A^580).is_one() True @@ -4918,7 +4918,7 @@ cdef class Matrix(sage.structure.element.Matrix): Over `\ZZ`:: sage: m = matrix(ZZ, 2, 2, [-1,1,-1,0]) - sage: m.multiplicative_order() # needs sage.groups + sage: m.multiplicative_order() # needs sage.libs.pari 3 sage: m = posets.ChainPoset(6).coxeter_transformation() # needs sage.combinat sage.graphs @@ -4930,10 +4930,10 @@ cdef class Matrix(sage.structure.element.Matrix): 10 sage: M = matrix(ZZ, 2, 2, [1, 1, 0, 1]) - sage: M.multiplicative_order() # needs sage.groups + sage: M.multiplicative_order() # needs sage.libs.pari +Infinity - sage: for k in range(600): # needs sage.groups + sage: for k in range(600): # needs sage.groups sage.modular ....: m = SL2Z.random_element() ....: o = m.multiplicative_order() ....: if o != Infinity and m**o != SL2Z.one(): @@ -4948,7 +4948,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() # needs sage.groups + sage: (rnd * m24 * rnd.inverse_of_unit()).multiplicative_order() # needs sage.libs.pari 24 TESTS:: @@ -5827,9 +5827,9 @@ cdef class Matrix(sage.structure.element.Matrix): Tests for :trac:`28570`:: - 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 + sage: P = posets.TamariLattice(7) # needs sage.graphs + sage: M = P._hasse_diagram._leq_matrix # needs sage.graphs + sage: M.inverse_of_unit() # this was very slow, now 1s # needs sage.graphs 429 x 429 sparse matrix over Integer Ring... sage: m = matrix(Zmod(2**2), 1, 1, [1], sparse=True) diff --git a/src/sage/matrix/matrix1.pyx b/src/sage/matrix/matrix1.pyx index 14a8538a535..1193b0a6ca0 100644 --- a/src/sage/matrix/matrix1.pyx +++ b/src/sage/matrix/matrix1.pyx @@ -103,7 +103,7 @@ cdef class Matrix(Matrix0): [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ] sage: g.CharacteristicPolynomial() x_1^3-12*x_1^2-18*x_1 - sage: A.characteristic_polynomial() + sage: A.characteristic_polynomial() # needs sage.libs.pari x^3 - 12*x^2 - 18*x sage: matrix(QQ, g) == A True diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 8af0889927f..a028f087578 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -313,6 +313,7 @@ cdef class Matrix(Matrix1): Over the complex numbers:: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, [[ 0, -1 + 2*I, 1 - 3*I, I], ....: [2 + 4*I, -2 + 3*I, -1 + 2*I, -1 - I], ....: [ 2 + I, 1 - I, -1, 5], @@ -416,6 +417,7 @@ cdef class Matrix(Matrix1): Check that coercions work correctly (:trac:`17405`):: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(RDF, 2, range(4)) sage: b = vector(CDF, [1+I, 2]) sage: A.solve_left(b) @@ -435,7 +437,6 @@ cdef class Matrix(Matrix1): ... ValueError: matrix equation has no solutions - In this case, turning off the ``check`` leads to a wrong result:: sage: A.solve_left(b, check=False) # needs sage.symbolic @@ -694,6 +695,7 @@ cdef class Matrix(Matrix1): Over the complex numbers:: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, [[ 0, -1 + 2*I, 1 - 3*I, I], ....: [2 + 4*I, -2 + 3*I, -1 + 2*I, -1 - I], ....: [ 2 + I, 1 - I, -1, 5], @@ -805,6 +807,7 @@ cdef class Matrix(Matrix1): Check that coercions work correctly (:trac:`17405`):: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(RDF, 2, range(4)) sage: b = vector(CDF, [1+I, 2]) sage: A.solve_right(b) @@ -1542,8 +1545,8 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: M = diagonal_matrix(CDF, [0, I, 1+I]) - sage: M + sage: # needs sage.rings.complex_double sage.symbolic + sage: M = diagonal_matrix(CDF, [0, I, 1+I]); M [ 0.0 0.0 0.0] [ 0.0 1.0*I 0.0] [ 0.0 0.0 1.0 + 1.0*I] @@ -1765,7 +1768,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") # needs sage.graphs + sage: A.rook_vector(algorithm="Godsil") # needs sage.graphs sage.libs.flint [1, 8, 20, 16, 4] When the matrix `A` has more ones then zeroes it is usually faster @@ -1805,17 +1808,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") # needs sage.graphs + sage: matrix([[0,0],[0,0]]).rook_vector(algorithm="Godsil") # needs sage.graphs sage.libs.flint [1, 0, 0] sage: matrix.ones(4, 2).rook_vector("Ryser") [1, 8, 12] - sage: matrix.ones(4, 2).rook_vector("Godsil") # needs sage.graphs + sage: matrix.ones(4, 2).rook_vector("Godsil") # needs sage.graphs sage.libs.flint [1, 8, 12] sage: m = matrix(ZZ,4,5) sage: m[:4,:4] = identity_matrix(4) sage: algos = ["Ryser", "ButeraPernici"] sage: algos += ["Godsil"] - sage: for algorithm in algos: # needs sage.graphs + sage: for algorithm in algos: # needs sage.graphs sage.libs.flint ....: 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)) @@ -2062,17 +2065,18 @@ cdef class Matrix(Matrix1): We verify that :trac:`10063` is resolved:: + sage: # needs sage.libs.singular 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) # needs sage.rings.finite_rings - sage: R.inject_variables() # needs sage.rings.finite_rings + sage: R = A.quotient(x^2 + 1).quotient(y^2 + 1).quotient(z^2 + 1) + sage: R.inject_variables() Defining xbarbarbar, ybarbarbar, zbarbarbar - sage: M = matrix([[1, 1, 1, 1], # needs sage.rings.finite_rings + sage: M = matrix([[1, 1, 1, 1], ....: [xbarbarbar, ybarbarbar, 1, 1], ....: [0, 1, zbarbarbar, 1], ....: [xbarbarbar, zbarbarbar, 1, 1]]) - sage: M.determinant() # needs sage.rings.finite_rings + sage: M.determinant() xbarbarbar*ybarbarbar*zbarbarbar + xbarbarbar*ybarbarbar + xbarbarbar*zbarbarbar + ybarbarbar*zbarbarbar + xbarbarbar + ybarbarbar + zbarbarbar + 1 @@ -2448,7 +2452,7 @@ cdef class Matrix(Matrix1): In that case, the definition by perfect matchings is used instead:: - sage: A.pfaffian() # needs sage.combinat sage.rings.finite_rings + sage: A.pfaffian() # needs sage.combinat 2 """ @@ -3014,10 +3018,10 @@ cdef class Matrix(Matrix1): ``S`` in the following example is an integral domain. But the computation of the characteristic polynomial succeeds as follows:: + sage: # needs sage.libs.singular 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: A = matrix(S, [[x*y^2, 2*x], [2, x^10*y]]); A [ x*y^2 2*x] [ 2 x^10*y] sage: A.charpoly('T') @@ -4197,7 +4201,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') + sage: A.right_kernel_matrix(algorithm='pluq', basis='echelon') # needs sage.libs.m4ri [1 0 0 0 0 1] [0 1 1 0 0 0] [0 0 0 1 0 0] @@ -4455,7 +4459,8 @@ cdef class Matrix(Matrix1): sage: A.right_kernel_matrix() Traceback (most recent call last): ... - NotImplementedError: Cannot compute a matrix kernel over Quaternion Algebra (-1, -1) with base ring Rational Field + NotImplementedError: Cannot compute a matrix kernel over + Quaternion Algebra (-1, -1) with base ring Rational Field We test error messages for improper choices of the 'algorithm' keyword. :: @@ -4467,15 +4472,18 @@ cdef class Matrix(Matrix1): 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 + ValueError: 'padic' matrix kernel algorithm only available over + the rationals and the integers, not over Finite Field of size 2 sage: matrix(QQ, 2, 2).right_kernel_matrix(algorithm='pari') Traceback (most recent call last): ... - ValueError: 'pari' matrix kernel algorithm only available over non-trivial number fields and the integers, not over Rational Field - sage: matrix(QQ, 2, 2).right_kernel_matrix(algorithm='pluq') + ValueError: 'pari' matrix kernel algorithm only available over + non-trivial number fields and the integers, not over Rational Field + sage: matrix(QQ, 2, 2).right_kernel_matrix(algorithm='pluq') # needs sage.libs.m4ri Traceback (most recent call last): ... - ValueError: 'pluq' matrix kernel algorithm only available over integers mod 2, not over Rational Field + ValueError: 'pluq' matrix kernel algorithm only available over + integers mod 2, not over Rational Field We test error messages for improper basis format requests. :: @@ -4490,7 +4498,8 @@ cdef class Matrix(Matrix1): sage: matrix(QQ, 2, 2).right_kernel_matrix(basis='LLL') Traceback (most recent call last): ... - ValueError: LLL-reduced basis only available over the integers, not over Rational Field + ValueError: LLL-reduced basis only available over the integers, + not over Rational Field Finally, error messages for the 'proof' keyword. :: @@ -5435,8 +5444,10 @@ cdef class Matrix(Matrix1): [1 0 0] [0 1 0] [0 0 1] - sage: W = MatrixSpace(CC,2,2) - sage: B = W([1, 2+3*I,4+5*I,9]); B + + sage: # needs sage.rings.real_mpfr sage.symbolic + sage: W = MatrixSpace(CC, 2, 2) + sage: B = W([1, 2 + 3*I, 4 + 5*I, 9]); B [ 1.00000000000000 2.00000000000000 + 3.00000000000000*I] [4.00000000000000 + 5.00000000000000*I 9.00000000000000] sage: B.column_space() @@ -6092,7 +6103,7 @@ cdef class Matrix(Matrix1): 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) # needs sage.rings.finite_rings + sage: B._eigenspace_format(None) 'all' Subrings are promoted to fraction fields and then checked for the @@ -6373,12 +6384,12 @@ cdef class Matrix(Matrix1): 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') + sage: A.eigenspaces_left(format='all') # needs sage.rings.number_field 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') # needs sage.rings.number_field [ (a0, Vector space of degree 2 and dimension 1 over Univariate Quotient Polynomial Ring in a0 over @@ -6771,7 +6782,7 @@ cdef class Matrix(Matrix1): sage: M = matrix(QQ, [[0,-1,0], [1,0,0], [0,0,2]]) sage: M.eigenvalues() # needs sage.rings.number_field [2, -1*I, 1*I] - sage: M.eigenvalues(extend=False) # needs sage.rings.number_field + sage: M.eigenvalues(extend=False) # needs sage.libs.pari [2] The method also works for matrices over finite fields:: @@ -7119,23 +7130,25 @@ cdef class Matrix(Matrix1): The matrix `B` in a generalized eigenvalue problem may be singular:: + sage: # needs sage.rings.complex_double sage.symbolic 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 # needs sage.symbolic + sage: D.diagonal() # tol 1e-14 [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] # needs sage.symbolic + sage: # needs sage.rings.complex_double sage.symbolic + sage: l = D[0, 0] sage: v = P[0, :] - sage: (v * A - l * v * B).norm() < 1e-14 # needs sage.symbolic + sage: (v * A - l * v * B).norm() < 1e-14 True The second eigenvector is contained in the left kernel of `B`:: - sage: (P[1, :] * B).norm() < 1e-14 + sage: (P[1, :] * B).norm() < 1e-14 # needs sage.rings.complex_double sage.symbolic True .. SEEALSO:: @@ -7170,6 +7183,7 @@ cdef class Matrix(Matrix1): The following example shows that :trac:`20439` has been resolved:: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, [[-2.53634347567, 2.04801738686, -0.0, -62.166145304], ....: [ 0.7, -0.6, 0.0, 0.0], ....: [0.547271128842, 0.0, -0.3015, -21.7532081652], @@ -7181,6 +7195,7 @@ cdef class Matrix(Matrix1): The following example shows that the fix for :trac:`20439` (conjugating eigenvectors rather than eigenvalues) is the correct one:: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = Matrix(CDF,[[I,0],[0,1]]) sage: D, P = A.eigenmatrix_left() sage: (P*A - D*P).norm() < 10^(-2) @@ -7212,6 +7227,7 @@ cdef class Matrix(Matrix1): The following example shows that :trac:`12595` has been resolved:: + sage: # needs sage.rings.complex_double sage: m = Matrix(CDF, 8, [[-1, -1, -1, -1, 1, -3, -1, -1], ....: [1, 1, 1, 1, -1, -1, 1, -3], ....: [-1, 3, -1, -1, 1, 1, -1, -1], @@ -7391,6 +7407,7 @@ cdef class Matrix(Matrix1): The following example shows that :trac:`20439` has been resolved:: + sage: # needs sage.rings.complex_double sage: A = matrix(CDF, [[-2.53634347567, 2.04801738686, -0.0, -62.166145304], ....: [ 0.7, -0.6, 0.0, 0.0], ....: [0.547271128842, 0.0, -0.3015, -21.7532081652], @@ -7402,6 +7419,7 @@ cdef class Matrix(Matrix1): The following example shows that the fix for :trac:`20439` (conjugating eigenvectors rather than eigenvalues) is the correct one:: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = Matrix(CDF,[[I,0],[0,1]]) sage: D, P = A.eigenmatrix_right() sage: (A*P - P*D).norm() < 10^(-2) @@ -8449,7 +8467,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: # needs sage.groups + sage: # needs sage.graphs sage.groups sage: M = matrix(ZZ,[[1,0],[1,0],[0,1]]); M [1 0] [1 0] @@ -8464,7 +8482,7 @@ cdef class Matrix(Matrix1): 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) # needs sage.groups + sage: all(M.with_permuted_rows_and_columns(*i) == M for i in A) # needs sage.graphs sage.groups True Check that :trac:`25426` is fixed:: @@ -8474,7 +8492,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() # needs sage.groups + sage: j.automorphisms_of_rows_and_columns() # needs sage.graphs sage.groups [((), ()), ((1,3)(2,5), (1,3)(2,5))] """ from sage.groups.perm_gps.constructor import \ @@ -8699,15 +8717,13 @@ cdef class Matrix(Matrix1): Some examples that are not permutations of each other:: - sage: N = matrix(ZZ, [[1,2,3], [4,5,6], [7,8,9]]) - sage: N + sage: N = matrix(ZZ, [[1,2,3], [4,5,6], [7,8,9]]); N [1 2 3] [4 5 6] [7 8 9] sage: M.is_permutation_of(N) # needs sage.graphs False - sage: N = matrix(ZZ, [[1,2], [3,4]]) - sage: N + sage: N = matrix(ZZ, [[1,2], [3,4]]); N [1 2] [3 4] sage: M.is_permutation_of(N) @@ -8715,9 +8731,8 @@ 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 + sage: # needs sage.graphs sage.groups + sage: N = matrix(ZZ, [[3,5,3], [2,6,4], [1,2,3]]); N [3 5 3] [2 6 4] [1 2 3] @@ -9331,7 +9346,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) # needs sage.rings.finite_rings + sage: E = C.tensor_product(B) Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: @@ -9667,9 +9682,9 @@ cdef class Matrix(Matrix1): [0 0 0 1 0] sage: P.is_unitary() True - sage: P.change_ring(GF(3)).is_unitary() # needs sage.rings.finite_rings + sage: P.change_ring(GF(3)).is_unitary() True - sage: P.change_ring(GF(3)).is_unitary() # needs sage.rings.finite_rings + sage: P.change_ring(GF(3)).is_unitary() True A square matrix far from unitary. :: @@ -9902,14 +9917,14 @@ cdef class Matrix(Matrix1): 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 + sage: decomp = bistochastic_as_sum_of_permutations(M) # needs sage.combinat sage.graphs + sage: print(decomp) # needs sage.combinat sage.graphs 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 = bistochastic_as_sum_of_permutations(M) # needs sage.combinat + sage: decomp = bistochastic_as_sum_of_permutations(M) # needs sage.graphs Traceback (most recent call last): ... ValueError: The matrix is not bistochastic @@ -10766,6 +10781,7 @@ cdef class Matrix(Matrix1): First, the inexact rings, ``CDF`` and ``RDF``. :: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, [[ 0.6454 + 0.7491*I, -0.8662 + 0.1489*I, 0.7656 - 0.00344*I], ....: [-0.2913 + 0.8057*I, 0.8321 + 0.8170*I, -0.6744 + 0.9248*I], ....: [ 0.2554 + 0.3517*I, -0.4454 - 0.1715*I, 0.8325 - 0.6282*I]]) @@ -10799,7 +10815,7 @@ cdef class Matrix(Matrix1): sage: M.round(6).zero_at(10^-6) [1.611147 0.0] [0.958116 0.867778] - sage: (A-M*G).zero_at(10^-12) + sage: (A - M*G).zero_at(10^-12) [0.0 0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0 0.0] sage: (G*G.transpose()).round(6).zero_at(10^-6) @@ -11110,7 +11126,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: - sage: # needs sage.combinat + sage: # needs sage.combinat sage.libs.pari 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] @@ -11156,20 +11172,21 @@ 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: # needs sage.combinat sage.libs.pari 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) # needs sage.combinat - sage: jf # needs sage.combinat + sage: jf, p = m.jordan_form(transformation=True) + sage: jf [2|0|0 0] [-+-+---] [0|1|0 0] [-+-+---] [0|0|4 1] [0|0|0 4] - sage: ~p * m * p # needs sage.combinat + sage: ~p * m * p [2 0 0 0] [0 1 0 0] [0 0 4 1] @@ -11191,14 +11208,14 @@ cdef class Matrix(Matrix1): [1 1 1] [1 1 1] [1 1 1] - sage: c.jordan_form(subdivide=False) # needs sage.combinat + sage: c.jordan_form(subdivide=False) # needs sage.combinat sage.libs.pari [3 0 0] [0 0 0] [0 0 0] :: - sage: # needs sage.combinat + sage: # needs sage.combinat sage.libs.pari 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]) @@ -11215,10 +11232,10 @@ cdef class Matrix(Matrix1): 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: # needs sage.combinat 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) sage: J [1 1|0 0|0 0|0] @@ -11247,6 +11264,7 @@ cdef class Matrix(Matrix1): We now go through three `10 \times 10` matrices to exhibit cases where there are multiple blocks of the same size:: + sage: # needs sage.combinat sage.libs.pari sage: A = matrix(QQ, [[15, 37/3, -16, -104/3, -29, -7/3, 0, 2/3, -29/3, -1/3], [2, 9, -1, -6, -6, 0, 0, 0, -2, 0], [24, 74/3, -41, -208/3, -58, -23/3, 0, 4/3, -58/3, -2/3], [-6, -19, 3, 21, 19, 0, 0, 0, 6, 0], [2, 6, 3, -6, -3, 1, 0, 0, -2, 0], [-96, -296/3, 176, 832/3, 232, 101/3, 0, -16/3, 232/3, 8/3], [-4, -2/3, 21, 16/3, 4, 14/3, 3, -1/3, 4/3, -25/3], [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]]); A [ 15 37/3 -16 -104/3 -29 -7/3 0 2/3 -29/3 -1/3] [ 2 9 -1 -6 -6 0 0 0 -2 0] @@ -11258,7 +11276,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 # needs sage.combinat + sage: J, T = A.jordan_form(transformation=True); J [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] @@ -11272,13 +11290,14 @@ 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 # needs sage.combinat + sage: T * J * T**(-1) == A True - sage: T.rank() # needs sage.combinat + sage: T.rank() 10 :: + sage: # needs sage.combinat sage.libs.pari sage: A = matrix(QQ, [[15, 37/3, -16, -14/3, -29, -7/3, 0, 2/3, 1/3, 44/3], [2, 9, -1, 0, -6, 0, 0, 0, 0, 3], [24, 74/3, -41, -28/3, -58, -23/3, 0, 4/3, 2/3, 88/3], [-6, -19, 3, 3, 19, 0, 0, 0, 0, -9], [2, 6, 3, 0, -3, 1, 0, 0, 0, 3], [-96, -296/3, 176, 112/3, 232, 101/3, 0, -16/3, -8/3, -352/3], [-4, -2/3, 21, 16/3, 4, 14/3, 3, -1/3, 4/3, -25/3], [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]]); A [ 15 37/3 -16 -14/3 -29 -7/3 0 2/3 1/3 44/3] [ 2 9 -1 0 -6 0 0 0 0 3] @@ -11290,7 +11309,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 # needs sage.combinat + sage: J, T = A.jordan_form(transformation=True); J [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] @@ -11304,13 +11323,14 @@ 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 # needs sage.combinat + sage: T * J * T**(-1) == A True - sage: T.rank() # needs sage.combinat + sage: T.rank() 10 :: + sage: # needs sage.combinat sage.libs.pari sage: A = matrix(QQ, [[15, 37/3, -16, -104/3, -29, -7/3, 35, 2/3, -29/3, -1/3], [2, 9, -1, -6, -6, 0, 7, 0, -2, 0], [24, 74/3, -29, -208/3, -58, -14/3, 70, 4/3, -58/3, -2/3], [-6, -19, 3, 21, 19, 0, -21, 0, 6, 0], [2, 6, -1, -6, -3, 0, 7, 0, -2, 0], [-96, -296/3, 128, 832/3, 232, 65/3, -279, -16/3, 232/3, 8/3], [0, 0, 0, 0, 0, 0, 3, 0, 0, 0], [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]]); A [ 15 37/3 -16 -104/3 -29 -7/3 35 2/3 -29/3 -1/3] [ 2 9 -1 -6 -6 0 7 0 -2 0] @@ -11322,7 +11342,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 # needs sage.combinat + sage: J, T = A.jordan_form(transformation=True); J [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] @@ -11337,15 +11357,15 @@ 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 # needs sage.combinat + sage: T * J * T**(-1) == A True - sage: T.rank() # needs sage.combinat + sage: T.rank() 10 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: # needs sage.combinat sage.libs.pari sage: M = matrix(((2,2,2), (0,0,0), (-2,-2,-2))) sage: J, P = M.jordan_form(transformation=True) sage: J; P @@ -11603,8 +11623,7 @@ cdef class Matrix(Matrix1): Matrices may fail to be diagonalizable for various reasons:: - sage: A = matrix(QQ, 2, [1,2,3, 4,5,6]) - sage: A + sage: A = matrix(QQ, 2, [1,2,3, 4,5,6]); A [1 2 3] [4 5 6] sage: A.diagonalization() @@ -11612,8 +11631,7 @@ cdef class Matrix(Matrix1): ... TypeError: not a square matrix - sage: B = matrix(ZZ, 2, [1, 2, 3, 4]) - sage: B + sage: B = matrix(ZZ, 2, [1, 2, 3, 4]); B [1 2] [3 4] sage: B.diagonalization() @@ -11621,17 +11639,16 @@ cdef class Matrix(Matrix1): ... ValueError: matrix entries must be from a field - sage: C = matrix(RR, 2, [1., 2., 3., 4.]) - sage: C + sage: C = matrix(RR, 2, [1., 2., 3., 4.]); C [1.00000000000000 2.00000000000000] [3.00000000000000 4.00000000000000] sage: C.diagonalization() Traceback (most recent call last): ... - ValueError: base field must be exact, but Real Field with 53 bits of precision is not + ValueError: base field must be exact, + but Real Field with 53 bits of precision is not - sage: D = matrix(QQ, 2, [0, 2, 1, 0]) - sage: D + sage: D = matrix(QQ, 2, [0, 2, 1, 0]); D [0 2] [1 0] sage: D.diagonalization() # needs sage.libs.pari @@ -11639,15 +11656,14 @@ cdef class Matrix(Matrix1): ... ValueError: not diagonalizable over Rational Field - sage: E = matrix(QQ, 2, [3, 1, 0, 3]) - sage: E + sage: E = matrix(QQ, 2, [3, 1, 0, 3]); E [3 1] [0 3] sage: E.diagonalization() # needs sage.libs.pari Traceback (most recent call last): ... ValueError: not diagonalizable - sage: E.jordan_form() # needs sage.combinat + sage: E.jordan_form() # needs sage.combinat sage.libs.pari [3 1] [0 3] """ @@ -11751,7 +11767,7 @@ cdef class Matrix(Matrix1): ....: [-1, 6, 1, -3, 1]]) sage: A.is_diagonalizable() # needs sage.libs.pari False - sage: A.jordan_form(subdivide=False) # needs sage.libs.pari + sage: A.jordan_form(subdivide=False) # needs sage.combinat sage.libs.pari [-1 1 0 0 0] [ 0 -1 0 0 0] [ 0 0 2 1 0] @@ -11794,7 +11810,7 @@ cdef class Matrix(Matrix1): ....: [ 2*b, 3*b, 4*b + 4, 3*b + 3]]) sage: A.is_diagonalizable() False - sage: A.jordan_form() + sage: A.jordan_form() # needs sage.combinat [ 4 1| 0 0] [ 0 4| 0 0] [---------------+---------------] @@ -11974,7 +11990,7 @@ cdef class Matrix(Matrix1): sage: A.is_similar(B) True - sage: # needs sage.libs.pari + sage: # needs sage.combinat 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] @@ -12074,11 +12090,11 @@ cdef class Matrix(Matrix1): sage: D = S.inverse()*C*S sage: C.is_similar(D) True - sage: C.is_similar(D, transformation=True) + sage: C.is_similar(D, transformation=True) # needs sage.combinat Traceback (most recent call last): ... RuntimeError: unable to compute transformation for similar matrices - sage: C.jordan_form() + sage: C.jordan_form() # needs sage.combinat Traceback (most recent call last): ... RuntimeError: Some eigenvalue does not exist in @@ -12126,7 +12142,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) # needs sage.rings.finite_rings + sage: A.is_similar(B, transformation=True) Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: @@ -13420,7 +13436,7 @@ cdef class Matrix(Matrix1): [ 0 0 0 0] sage: L.base_ring() # needs sage.combinat Finite Field in a of size 5^2 - sage: C == P*L*U + sage: C == P*L*U # needs sage.combinat True With no pivoting strategy given (i.e. ``pivot=None``) @@ -14472,6 +14488,7 @@ cdef class Matrix(Matrix1): but `P^{T}AP` will ideally be close to `LDL^{*}` in the metric induced by the norm:: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, 2, 2, [ [-1.1933, -0.3185 - 1.3553*I], ....: [-0.3185 + 1.3553*I, 1.5729 ] ]) sage: P,L,D = A.block_ldlt() @@ -14759,21 +14776,19 @@ cdef class Matrix(Matrix1): Any of the preceding examples are valid over inexact rings and with complex numbers as well:: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, [ [ 2, I], ....: [-I, 2] ] ) sage: A.is_positive_semidefinite() True - sage: A = matrix(CDF, [ [ 1, I], ....: [-I, 1] ] ) sage: A.is_positive_semidefinite() True - sage: A = matrix(CDF, [ [0,I], ....: [I,0] ] ) sage: A.is_positive_semidefinite() False - sage: A = matrix(CDF, [ [2,I], ....: [0,0] ]) sage: A.is_positive_semidefinite() @@ -14792,7 +14807,8 @@ cdef class Matrix(Matrix1): a Hermitian matrix (for a non-Hermitian matrix, both "obviously" return ``False``):: - sage: rings = [ZZ, QQ, RDF, CDF] + sage: rings = [ZZ, QQ, RDF] + sage: ring.append(CDF) # needs sage.rings.complex_double sage: rings.append(QuadraticField(-1, 'I')) # needs sage.rings.number_field sage: from sage.misc.prandom import choice sage: ring = choice(rings) @@ -15191,6 +15207,7 @@ cdef class Matrix(Matrix1): EXAMPLES:: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, [[1+I,1],[0,2*I]]) sage: A.conjugate() [1.0 - 1.0*I 1.0] @@ -15380,7 +15397,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: # needs sage.rings.real_mpfr sage.symbolic sage: A = matrix(CC, 2, 3, [3*I,4,1-I,1,2,0]) sage: A.norm('frob') 5.656854249492381 @@ -15390,6 +15407,7 @@ cdef class Matrix(Matrix1): 6.0 sage: A.norm(Infinity) 8.414213562373096 + sage: a = matrix([[],[],[],[]]) sage: a.norm() 0.0 @@ -15404,13 +15422,14 @@ cdef class Matrix(Matrix1): 0.0 """ from sage.rings.real_double import RDF - from sage.rings.complex_double import CDF if self._nrows == 0 or self._ncols == 0: return RDF(0) # 2-norm: if p == 2: + from sage.rings.complex_double import CDF + A = self.change_ring(CDF) A = A.conjugate().transpose() * A S = A.SVD()[1] @@ -16738,7 +16757,7 @@ cdef class Matrix(Matrix1): sage: U.inverse()*B*U == Z True - sage: A.jordan_form() == B.jordan_form() # needs sage.combinat + sage: A.jordan_form() == B.jordan_form() # needs sage.combinat sage.libs.pari True Two more examples, illustrating the two extremes of the zig-zag @@ -16799,7 +16818,7 @@ cdef class Matrix(Matrix1): sage: U.inverse()*D*U == Z True - sage: C.jordan_form() == D.jordan_form() # needs sage.combinat + sage: C.jordan_form() == D.jordan_form() # needs sage.combinat sage.libs.pari True ZigZag form is achieved entirely with the operations of the field, so @@ -17117,7 +17136,7 @@ cdef class Matrix(Matrix1): ....: [-155, -3, -55, 45, 50, -245, -27, 65, -328, 77, 365, 583]]) sage: A.characteristic_polynomial().factor() # needs sage.libs.pari (x^2 - 2)^2 * (x^2 + 2*x + 5)^4 - sage: A.eigenvalues(extend=False) # needs sage.rings.number_field + sage: A.eigenvalues(extend=False) # needs sage.libs.pari [] sage: A.rational_form() [ 0 -5| 0 0 0 0| 0 0 0 0 0 0] @@ -17389,7 +17408,7 @@ cdef class Matrix(Matrix1): sage: L = matrix(SR, [ [0, e, 0 ], # needs sage.symbolic ....: [0, 2, pi], ....: [sqrt(2), 0, 0 ] ]) - sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron sage.symbolic + sage: L.is_positive_operator_on(K) # needs sage.geometry.polyhedron True Your matrix can be over any exact ring, for example the ring of @@ -17816,7 +17835,7 @@ cdef class Matrix(Matrix1): sage: L = matrix(SR, [ [e, 0, 0 ], # needs sage.symbolic ....: [0, pi, 0 ], ....: [0, 0, sqrt(2)] ]) - sage: L.is_lyapunov_like_on(K) # needs sage.geometry.polyhedron sage.symbolic + sage: L.is_lyapunov_like_on(K) # needs sage.geometry.polyhedron True TESTS: From 1d01569b5a5b2468809148c3a67d1664b13b52f0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 17 Aug 2023 12:47:38 -0700 Subject: [PATCH 02/19] sage -fixdoctests --distribution all --fixed-point --only-tags --probe all --verbose src/sage/matrix; followed by manual fixes --- src/sage/matrix/matrix_double_sparse.pyx | 2 + src/sage/matrix/matrix_gap.pyx | 8 ++- src/sage/matrix/matrix_polynomial_dense.pyx | 14 ++--- src/sage/matrix/matrix_space.py | 64 ++++++++++----------- src/sage/matrix/matrix_sparse.pyx | 2 +- src/sage/matrix/operation_table.py | 4 +- src/sage/matrix/special.py | 2 +- src/sage/matrix/tests.py | 8 +-- 8 files changed, 56 insertions(+), 48 deletions(-) diff --git a/src/sage/matrix/matrix_double_sparse.pyx b/src/sage/matrix/matrix_double_sparse.pyx index adf285a311c..fc7d65a880c 100644 --- a/src/sage/matrix/matrix_double_sparse.pyx +++ b/src/sage/matrix/matrix_double_sparse.pyx @@ -143,6 +143,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): :: + sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, [[ 2, 4 + 2*I, 6 - 4*I], ....: [ -2*I + 4, 11, 10 - 12*I], ....: [ 4*I + 6, 10 + 12*I, 37]]) @@ -173,6 +174,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): :: + sage: # needs sage.rings.complex_double sage.symbolic sage: n = ZZ.random_element(1,5) sage: A = matrix.random(CDF, n, sparse=True) sage: I = matrix.identity(CDF, n, sparse=True) diff --git a/src/sage/matrix/matrix_gap.pyx b/src/sage/matrix/matrix_gap.pyx index 853cb0626a1..09849b784fb 100644 --- a/src/sage/matrix/matrix_gap.pyx +++ b/src/sage/matrix/matrix_gap.pyx @@ -48,6 +48,7 @@ cdef class Matrix_gap(Matrix_dense): sage: m.transpose().parent() is M True + sage: # needs sage.rings.number_field sage: UCF = UniversalCyclotomicField() sage: M = MatrixSpace(UCF, 3, implementation='gap') sage: m = M([UCF.zeta(i) for i in range(1,10)]) @@ -60,7 +61,9 @@ cdef class Matrix_gap(Matrix_dense): TESTS:: - sage: for ring in [ZZ, QQ, UniversalCyclotomicField(), GF(2), GF(3)]: + sage: rings = [ZZ, QQ, UniversalCyclotomicField(), GF(2), GF(3)] + sage: rings += [UniversalCyclotomicField()] # needs sage.rings.number_field + sage: for ring in rings: ....: M = MatrixSpace(ring, 2, implementation='gap') ....: TestSuite(M).run(skip=['_test_construction']) ....: M = MatrixSpace(ring, 2, 3, implementation='gap') @@ -233,6 +236,7 @@ cdef class Matrix_gap(Matrix_dense): sage: m1 != m3 True + sage: # needs sage.rings.number_field sage: UCF = UniversalCyclotomicField() sage: M = MatrixSpace(UCF, 2, implementation='gap') sage: m1 = M([E(2), E(3), 0, E(4)]) @@ -367,6 +371,7 @@ cdef class Matrix_gap(Matrix_dense): sage: parent(M(1).determinant()) Rational Field + sage: # needs sage.rings.number_field sage: M = MatrixSpace(UniversalCyclotomicField(), 1, implementation='gap') sage: parent(M(1).determinant()) Universal Cyclotomic Field @@ -395,6 +400,7 @@ cdef class Matrix_gap(Matrix_dense): sage: parent(M(1).trace()) Rational Field + sage: # needs sage.rings.number_field sage: M = MatrixSpace(UniversalCyclotomicField(), 1, implementation='gap') sage: parent(M(1).trace()) Universal Cyclotomic Field diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 10d9a9248b6..b565952024c 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -2010,7 +2010,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): Demonstrating the ``ordered`` option:: - sage: P.leading_positions() # needs sage.combinat + sage: P.leading_positions() [2, 1] sage: PP = M.weak_popov_form(ordered=True); PP [ 2 4*x^2 + 2*x + 4 5] @@ -2129,12 +2129,12 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): sage: A = matrix(PF,[[1, a*x^17 + 1 ], ....: [0, a*x^11 + a^2*x^7 + 1 ]]) sage: M = A.__copy__() - sage: U = M._weak_popov_form(transformation=True) # needs sage.combinat - sage: U * A == M # needs sage.combinat + sage: U = M._weak_popov_form(transformation=True) + sage: U * A == M True - sage: M.is_weak_popov() # needs sage.combinat + sage: M.is_weak_popov() True - sage: U.is_invertible() # needs sage.combinat + sage: U.is_invertible() True sage: PF. = QQ[] @@ -3316,7 +3316,7 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): ....: [ 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( + sage: appbas.is_minimal_approximant_basis( # needs sage.libs.pari ....: pmat, order, shifts, row_wise=True, normal_form=True) True @@ -3326,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) + sage: M.is_minimal_approximant_basis(pmat, 8) # needs sage.libs.pari False Since ``pmat`` is a single column, with nonzero constant coefficient, diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 279eba44511..278fd272b68 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -112,9 +112,9 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(ZZ, 4, 5, True, None) - sage: get_matrix_class(ZZ, 3, 3, False, 'flint') + sage: get_matrix_class(ZZ, 3, 3, False, 'flint') # needs sage.libs.flint - sage: get_matrix_class(ZZ, 3, 3, False, 'gap') # needs sage.modules + sage: get_matrix_class(ZZ, 3, 3, False, 'gap') # needs sage.libs.gap sage: get_matrix_class(ZZ, 3, 3, False, 'generic') @@ -124,14 +124,13 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(GF(2^17), 3, 3, False, None) # needs sage.rings.finite_rings - sage: # needs sage.rings.finite_rings - sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri') + sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri') # needs sage.libs.m4ri - sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri') + sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri') # needs sage.libs.m4ri sage.rings.finite_rings - sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float') + sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float') # needs sage.libs.linbox - sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double') + sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double') # needs sage.libs.linbox sage: get_matrix_class(RDF, 2, 2, False, 'numpy') # needs numpy @@ -139,9 +138,9 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(CDF, 2, 3, False, 'numpy') # needs numpy - sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe, needs sage.rings.finite_rings + 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 + sage: get_matrix_class(IntegerModRing(3), 4, 4, False, 'meataxe') # optional - meataxe sage: get_matrix_class(IntegerModRing(4), 4, 4, False, 'meataxe') Traceback (most recent call last): @@ -159,12 +158,13 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): 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 - sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-float') + ValueError: 'm4ri' matrices are only available + for fields of characteristic 2 and order <= 65536 + sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-float') # needs sage.libs.linbox Traceback (most recent call last): ... ValueError: 'linbox-float' matrices can only deal with order < 256 - sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-double') + sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-double') # needs sage.libs.linbox Traceback (most recent call last): ... ValueError: 'linbox-double' matrices can only deal with order < 94906266 @@ -173,17 +173,17 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: type(matrix(SR, 2, 2, 0, sparse=True)) # needs sage.symbolic - sage: type(matrix(GF(7), 2, range(4))) # needs sage.rings.finite_rings + sage: type(matrix(GF(7), 2, range(4))) # needs sage.libs.linbox - sage: type(matrix(GF(16007), 2, range(4))) # needs sage.rings.finite_rings + sage: type(matrix(GF(16007), 2, range(4))) # needs sage.libs.linbox sage: type(matrix(CBF, 2, range(4))) # needs sage.libs.flint - sage: type(matrix(GF(2), 2, range(4))) # needs sage.rings.finite_rings + sage: type(matrix(GF(2), 2, range(4))) # needs sage.libs.m4ri - sage: type(matrix(GF(64, 'z'), 2, range(4))) # needs sage.rings.finite_rings + sage: type(matrix(GF(64, 'z'), 2, range(4))) # needs sage.libs.m4ri sage.rings.finite_rings - sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe # needs sage.rings.finite_rings + sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe, needs sage.rings.finite_rings """ @@ -496,29 +496,28 @@ class MatrixSpace(UniqueRepresentation, Parent): Check that different implementations play together as expected:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.flint + sage: # needs sage.libs.flint + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - - sage: type(M1(range(4))) # needs sage.libs.flint + sage: type(M1(range(4))) sage: type(M2(range(4))) - - sage: M1(M2.an_element()) # needs sage.libs.flint + sage: M1(M2.an_element()) [ 0 1] [-1 2] - sage: M2(M1.an_element()) # needs sage.libs.flint + sage: M2(M1.an_element()) [ 0 1] [-1 2] - - sage: all((A.get_action(B) is not None) == (A is B) # needs sage.libs.flint + sage: all((A.get_action(B) is not None) == (A is B) ....: 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') # needs sage.libs.gap sage.rings.finite_rings - sage: M2.one() # needs sage.libs.gap sage.rings.finite_rings + sage: # needs sage.libs.gap + sage: M2 = MatrixSpace(GF(2), 5, implementation='gap') + sage: M2.one() [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] @@ -526,7 +525,7 @@ class MatrixSpace(UniqueRepresentation, Parent): [0 0 0 0 1] sage: m = M2.random_element() sage: M1 = MatrixSpace(GF(2), 5) - sage: M1(m * m) == M1(m) * M1(m) # needs sage.libs.gap sage.rings.finite_rings + sage: M1(m * m) == M1(m) * M1(m) True """ @@ -648,7 +647,8 @@ def __init__(self, base_ring, nrows, ncols, sparse, implementation): Category of infinite enumerated finite dimensional algebras with basis over (euclidean domains and infinite enumerated sets and metric spaces) sage: MatrixSpace(QQ,10).category() - Category of infinite finite dimensional algebras with basis over (number fields and quotient fields and metric spaces) + Category of infinite finite dimensional algebras with basis over + (number fields and quotient fields and metric spaces) TESTS: @@ -769,7 +769,7 @@ def _has_default_implementation(self): sage: MatrixSpace(ZZ, 2, implementation='generic')._has_default_implementation() False - sage: MatrixSpace(ZZ, 2, implementation='flint')._has_default_implementation() + sage: MatrixSpace(ZZ, 2, implementation='flint')._has_default_implementation() # needs sage.libs.flint True """ default = get_matrix_class(self.base_ring(), self.nrows(), self.ncols(), self.is_sparse(), None) @@ -1159,8 +1159,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)) # needs sage.rings.finite_rings - sage: MS.coerce_map_from(Gamma1(5)) # needs sage.rings.finite_rings + sage: MS.coerce_map_from(GL(2, 2)) + sage: MS.coerce_map_from(Gamma1(5)) # needs sage.modular Coercion map: From: Congruence Subgroup Gamma1(5) To: Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3 diff --git a/src/sage/matrix/matrix_sparse.pyx b/src/sage/matrix/matrix_sparse.pyx index a98c6bfe64c..ef707ebe3f8 100644 --- a/src/sage/matrix/matrix_sparse.pyx +++ b/src/sage/matrix/matrix_sparse.pyx @@ -1178,7 +1178,7 @@ cdef class Matrix_sparse(matrix.Matrix): Check that the bug in :trac:`13854` has been fixed:: - sage: # needs sage.combinat + sage: # needs sage.combinat sage.libs.singular sage: A. = FreeAlgebra(QQ, 2) sage: P. = A.g_algebra(relations={y*x: -x*y}, order='lex') sage: M = Matrix([[x]], sparse=True) diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index 4b3f1dc905c..50fe4f257dd 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -977,7 +977,7 @@ 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) # needs sage.groups sage.plot + sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # needs sage.groups sage: OTa.color_table() # needs sage.groups sage.plot Graphics object consisting of 37 graphics primitives @@ -1036,7 +1036,7 @@ def gray_table(self, **options): EXAMPLES:: sage: from sage.matrix.operation_table import OperationTable - sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # needs sage.groups sage.plot + sage: OTa = OperationTable(SymmetricGroup(3), operation=operator.mul) # needs sage.groups sage: OTa.gray_table() # needs sage.groups sage.plot Graphics object consisting of 37 graphics primitives diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 0b23f80123a..b72daee9802 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -556,7 +556,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() # needs sage.combinat + sage: A.jordan_form() # needs sage.combinat sage.libs.pari [ 2| 0| 0| 0| 0] [--+--+--+--+--] [ 0| 3| 0| 0| 0] diff --git a/src/sage/matrix/tests.py b/src/sage/matrix/tests.py index 9208a5d4d72..b4747bff5c9 100644 --- a/src/sage/matrix/tests.py +++ b/src/sage/matrix/tests.py @@ -48,10 +48,10 @@ 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 + sage: A = matrix(CC, 2, 2, [1, 1, 1, 1]) / I; A # needs sage.rings.real_mpfr sage.symbolic [-1.00000000000000*I -1.00000000000000*I] [-1.00000000000000*I -1.00000000000000*I] - sage: A.parent() + sage: A.parent() # needs sage.rings.real_mpfr sage.symbolic Full MatrixSpace of 2 by 2 dense matrices over Complex Field with 53 bits of precision We test an example determinant computation where LinBox gave an incorrect @@ -64,8 +64,8 @@ Test that a certain bug in GP's mathnf was fixed:: - sage: a = gp('Mat([-15,18,-23,-20,-32,11,-19,2,-1,15,22,29,-29,3,-31,25,11,-6,32,7; -31,0,30,-27,-15,13,-21,6,-27,6,3,-4,-4,-28,-30,-16,29,-4,29,-20; -15,-19,-30,9,-18,-31,23,-15,15,-9,20,10,-29,9,18,-6,-1,-20,19,-29; 2,-32,4,-13,17,21,12,-32,12,0,27,-10,-31,-33,-8,-31,-23,25,-18,6; -10,33,4,27,1,25,1,6,31,-7,3,30,23,-4,18,16,-12,21,0,4; -19,20,31,-34,-24,20,-13,-2,18,12,-18,33,22,0,0,10,-25,-29,6,-23; -15,-33,27,-9,-21,-20,5,-20,-31,-11,20,19,31,25,16,20,5,23,-32,-2; 20,18,12,-10,-3,-29,-14,4,-9,21,7,-34,6,16,7,10,11,-21,8,28; 10,-4,-11,-8,-29,33,-23,21,-3,-17,21,7,-28,-10,-16,-1,-29,32,12,16; 13,33,-7,15,-31,20,22,33,21,8,-24,20,27,30,24,20,-29,31,-20,-16; -24,-16,24,-8,7,-22,3,12,-1,-4,-9,10,13,-2,-14,-4,-3,-26,28,-25; 7,-7,19,-26,25,-27,33,12,6,3,31,-30,-14,6,-17,11,-6,5,15,0; 9,-32,-14,9,12,-8,-19,22,20,-23,14,29,-17,-28,-34,-10,4,26,-3,-14; 7,-13,-16,32,-2,11,-2,3,33,-22,-7,-3,12,-24,-7,-7,-1,31,26,22; 8,7,30,29,26,-12,13,21,-18,-5,-27,-33,1,16,-34,-10,-1,8,6,20; 32,-30,27,-21,33,5,14,30,13,24,10,-23,30,-18,13,25,0,-22,18,-19; -4,-6,7,28,-4,9,32,21,29,2,-7,7,-24,-10,2,-9,-23,-18,6,5; 3,19,0,23,-24,-16,-33,-15,-2,16,2,19,28,33,-16,32,-20,-15,28,-18])') - sage: a.mathnf(1)[1][1,] == gp('[4, 2, 1, 0, 3, 1, 1, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 3]') + sage: a = gp('Mat([-15,18,-23,-20,-32,11,-19,2,-1,15,22,29,-29,3,-31,25,11,-6,32,7; -31,0,30,-27,-15,13,-21,6,-27,6,3,-4,-4,-28,-30,-16,29,-4,29,-20; -15,-19,-30,9,-18,-31,23,-15,15,-9,20,10,-29,9,18,-6,-1,-20,19,-29; 2,-32,4,-13,17,21,12,-32,12,0,27,-10,-31,-33,-8,-31,-23,25,-18,6; -10,33,4,27,1,25,1,6,31,-7,3,30,23,-4,18,16,-12,21,0,4; -19,20,31,-34,-24,20,-13,-2,18,12,-18,33,22,0,0,10,-25,-29,6,-23; -15,-33,27,-9,-21,-20,5,-20,-31,-11,20,19,31,25,16,20,5,23,-32,-2; 20,18,12,-10,-3,-29,-14,4,-9,21,7,-34,6,16,7,10,11,-21,8,28; 10,-4,-11,-8,-29,33,-23,21,-3,-17,21,7,-28,-10,-16,-1,-29,32,12,16; 13,33,-7,15,-31,20,22,33,21,8,-24,20,27,30,24,20,-29,31,-20,-16; -24,-16,24,-8,7,-22,3,12,-1,-4,-9,10,13,-2,-14,-4,-3,-26,28,-25; 7,-7,19,-26,25,-27,33,12,6,3,31,-30,-14,6,-17,11,-6,5,15,0; 9,-32,-14,9,12,-8,-19,22,20,-23,14,29,-17,-28,-34,-10,4,26,-3,-14; 7,-13,-16,32,-2,11,-2,3,33,-22,-7,-3,12,-24,-7,-7,-1,31,26,22; 8,7,30,29,26,-12,13,21,-18,-5,-27,-33,1,16,-34,-10,-1,8,6,20; 32,-30,27,-21,33,5,14,30,13,24,10,-23,30,-18,13,25,0,-22,18,-19; -4,-6,7,28,-4,9,32,21,29,2,-7,7,-24,-10,2,-9,-23,-18,6,5; 3,19,0,23,-24,-16,-33,-15,-2,16,2,19,28,33,-16,32,-20,-15,28,-18])') # needs sage.libs.pari + sage: a.mathnf(1)[1][1,] == gp('[4, 2, 1, 0, 3, 1, 1, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 3]') # needs sage.libs.pari True """ From 95d63df81451435432aa53ba7ab8517826b595ad Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 1 Sep 2023 11:51:46 -0700 Subject: [PATCH 03/19] src/sage/matrix/matrix2.pyx (determinant): Fall back when PARI is not available --- src/sage/matrix/matrix2.pyx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index a028f087578..05c836d2ca4 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -2141,10 +2141,15 @@ cdef class Matrix(Matrix1): # word, use PARI. ch = R.characteristic() if ch.is_prime() and ch < (2*sys.maxsize): - d = R(self.__pari__().matdet()) - else: - # Lift to ZZ and compute there. - d = R(self.apply_map(lambda x : x.lift_centered()).det()) + try: + d = R(self.__pari__().matdet()) + except ImportError: + pass + else: + self.cache('det', d) + return d + # Lift to ZZ and compute there. + d = R(self.apply_map(lambda x: x.lift_centered()).det()) self.cache('det', d) return d From 8177e8a5b65a651980b91191b316dca6c6565cca Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Sep 2023 23:46:22 -0700 Subject: [PATCH 04/19] Add # needs --- src/sage/matrix/matrix2.pyx | 2 +- src/sage/matrix/matrix_polynomial_dense.pyx | 1 - src/sage/modules/vector_space_morphism.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 05c836d2ca4..9fe2684eb2d 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -14813,7 +14813,7 @@ cdef class Matrix(Matrix1): return ``False``):: sage: rings = [ZZ, QQ, RDF] - sage: ring.append(CDF) # needs sage.rings.complex_double + sage: rings.append(CDF) # needs sage.rings.complex_double sage: rings.append(QuadraticField(-1, 'I')) # needs sage.rings.number_field sage: from sage.misc.prandom import choice sage: ring = choice(rings) diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index b565952024c..5d9e99a6a4c 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -998,7 +998,6 @@ cdef class Matrix_polynomial_dense(Matrix_generic_dense): (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 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], diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 2685462a74e..764c6ac39e5 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -224,7 +224,7 @@ sage: A = graphs.PetersenGraph().adjacency_matrix() sage: V = QQ^10 sage: phi = linear_transformation(V, V, A) - sage: phi.eigenvalues() + sage: phi.eigenvalues() # needs sage.rings.number_field [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) From a8a4b8e6c5938e56fa3d10a1268af8c4ca772095 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 6 Sep 2023 20:13:40 -0700 Subject: [PATCH 05/19] Add # needs --- src/sage/matrix/matrix2.pyx | 90 ++++++++++++----------- src/sage/matrix/matrix_space.py | 3 + src/sage/modules/filtered_vector_space.py | 4 +- src/sage/modules/vector_double_dense.pyx | 3 + 4 files changed, 57 insertions(+), 43 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 9fe2684eb2d..1a3690a466e 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -304,11 +304,11 @@ cdef class Matrix(Matrix1): [ 7.6 2.3 1.0] [ 1.0 2.0 -1.0] sage: b = vector(RDF,[1,2,3]) - sage: x = A.solve_left(b); x.zero_at(2e-17) # fix noisy zeroes + sage: x = A.solve_left(b); x.zero_at(2e-17) # fix noisy zeroes # needs scipy (0.666666666..., 0.0, 0.333333333...) - sage: x.parent() + sage: x.parent() # needs scipy Vector space of dimension 3 over Real Double Field - sage: x*A # tol 1e-14 + sage: x*A # tol 1e-14 # needs scipy (0.9999999999999999, 1.9999999999999998, 3.0) Over the complex numbers:: @@ -319,18 +319,19 @@ cdef class Matrix(Matrix1): ....: [ 2 + I, 1 - I, -1, 5], ....: [ 3*I, -1 - I, -1 + I, -3 + I]]) sage: b = vector(CDF, [2 -3*I, 3, -2 + 3*I, 8]) - sage: x = A.solve_left(b); x - (-1.55765124... - 0.644483985...*I, 0.183274021... + 0.286476868...*I, 0.270818505... + 0.246619217...*I, -1.69003558... - 0.828113879...*I) - sage: x.parent() + sage: x = A.solve_left(b); x # needs scipy + (-1.55765124... - 0.644483985...*I, 0.183274021... + 0.286476868...*I, + 0.270818505... + 0.246619217...*I, -1.69003558... - 0.828113879...*I) + sage: x.parent() # needs scipy Vector space of dimension 4 over Complex Double Field - sage: abs(x*A - b) < 1e-14 + sage: abs(x*A - b) < 1e-14 # needs scipy True If ``b`` is given as a matrix, the result will be a matrix, as well:: sage: A = matrix(RDF, 3, 3, [2, 5, 0, 7, 7, -2, -4.3, 0, 1]) sage: b = matrix(RDF, 2, 3, [2, -4, -5, 1, 1, 0.1]) - sage: A.solve_left(b) # tol 1e-14 + sage: A.solve_left(b) # tol 1e-14 # needs scipy [ -6.495454545454545 4.068181818181818 3.1363636363636354] [ 0.5277272727272727 -0.2340909090909091 -0.36818181818181817] @@ -340,16 +341,16 @@ cdef class Matrix(Matrix1): sage: A = matrix(RDF, 3, 2, [1, 3, 4, 2, 0, -3]) sage: b = vector(RDF, [5, 6]) - sage: x = A.solve_left(b) - sage: (x * A - b).norm() < 1e-14 + sage: x = A.solve_left(b) # needs scipy + sage: (x * A - b).norm() < 1e-14 # needs scipy True For a wide matrix `A`, the error is usually not small:: sage: A = matrix(RDF, 2, 3, [1, 3, 4, 2, 0, -3]) sage: b = vector(RDF, [5, 6, 1]) - sage: x = A.solve_left(b) - sage: (x * A - b).norm() # tol 1e-14 + sage: x = A.solve_left(b) # needs scipy + sage: (x * A - b).norm() # tol 1e-14 # needs scipy 0.9723055853282466 TESTS:: @@ -389,7 +390,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(RDF, 5, range(25)) sage: b = vector(RDF, [1,2,3,4,5]) - sage: A.solve_left(b) + sage: A.solve_left(b) # needs scipy Traceback (most recent call last): ... LinAlgError: Matrix is singular. @@ -398,7 +399,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(RDF, 5, range(25)) sage: b = vector(RDF, [1,2,3,4]) - sage: A.solve_left(b) + sage: A.solve_left(b) # needs scipy Traceback (most recent call last): ... ValueError: number of columns of self must equal degree of @@ -420,10 +421,10 @@ cdef class Matrix(Matrix1): sage: # needs sage.rings.complex_double sage.symbolic sage: A = matrix(RDF, 2, range(4)) sage: b = vector(CDF, [1+I, 2]) - sage: A.solve_left(b) + sage: A.solve_left(b) # needs scipy (0.5 - 1.5*I, 0.5 + 0.5*I) sage: b = vector(QQ[I], [1+I, 2]) - sage: x = A.solve_left(b) + sage: x = A.solve_left(b) # needs scipy Over the inexact ring ``SR``, we can still verify the solution if all of the elements involved were exact to begin with; if @@ -674,7 +675,7 @@ cdef class Matrix(Matrix1): sage: A = matrix(RDF, 3, 2, [1, 3, 4, 2, 0, -3]) sage: b = vector(RDF, [5, 6, 1]) - sage: A.solve_right(b) # tol 1e-14 + sage: A.solve_right(b) # tol 1e-14 # needs scipy (1.4782608695652177, 0.35177865612648235) sage: ~(A.T * A) * A.T * b # closed form solution, tol 1e-14 (1.4782608695652177, 0.35177865612648235) @@ -685,12 +686,12 @@ cdef class Matrix(Matrix1): [ 1.0 2.0 5.0] [ 7.6 2.3 1.0] [ 1.0 2.0 -1.0] - sage: b = vector(RDF,[1,2,3]) - sage: x = A.solve_right(b); x # tol 1e-14 + sage: b = vector(RDF, [1,2,3]) + sage: x = A.solve_right(b); x # tol 1e-14 # needs scipy (-0.1136950904392765, 1.3901808785529717, -0.33333333333333337) - sage: x.parent() + sage: x.parent() # needs scipy Vector space of dimension 3 over Real Double Field - sage: A*x # tol 1e-14 + sage: A*x # tol 1e-14 # needs scipy (1.0, 1.9999999999999996, 3.0000000000000004) Over the complex numbers:: @@ -700,19 +701,20 @@ cdef class Matrix(Matrix1): ....: [2 + 4*I, -2 + 3*I, -1 + 2*I, -1 - I], ....: [ 2 + I, 1 - I, -1, 5], ....: [ 3*I, -1 - I, -1 + I, -3 + I]]) - sage: b = vector(CDF, [2 -3*I, 3, -2 + 3*I, 8]) - sage: x = A.solve_right(b); x - (1.96841637... - 1.07606761...*I, -0.614323843... + 1.68416370...*I, 0.0733985765... + 1.73487544...*I, -1.6018683... + 0.524021352...*I) - sage: x.parent() + sage: b = vector(CDF, [2 - 3*I, 3, -2 + 3*I, 8]) + sage: x = A.solve_right(b); x # needs scipy + (1.96841637... - 1.07606761...*I, -0.614323843... + 1.68416370...*I, + 0.0733985765... + 1.73487544...*I, -1.6018683... + 0.524021352...*I) + sage: x.parent() # needs scipy Vector space of dimension 4 over Complex Double Field - sage: abs(A*x - b) < 1e-14 + sage: abs(A*x - b) < 1e-14 # needs scipy True If ``b`` is given as a matrix, the result will be a matrix, as well:: sage: A = matrix(RDF, 3, 3, [1, 2, 2, 3, 4, 5, 2, 2, 2]) sage: b = matrix(RDF, 3, 2, [3, 2, 3, 2, 3, 2]) - sage: A.solve_right(b) # tol 1e-14 + sage: A.solve_right(b) # tol 1e-14 # needs scipy [ 0.0 0.0] [ 4.5 3.0] [-3.0 -2.0] @@ -723,16 +725,16 @@ cdef class Matrix(Matrix1): sage: A = matrix(RDF, 2, 3, [1, 3, 4, 2, 0, -3]) sage: b = vector(RDF, [5, 6]) - sage: x = A.solve_right(b) - sage: (A * x - b).norm() < 1e-14 + sage: x = A.solve_right(b) # needs scipy + sage: (A * x - b).norm() < 1e-14 # needs scipy True For a tall matrix `A`, the error is usually not small:: sage: A = matrix(RDF, 3, 2, [1, 3, 4, 2, 0, -3]) sage: b = vector(RDF, [5, 6, 1]) - sage: x = A.solve_right(b) - sage: (A * x - b).norm() # tol 1e-14 + sage: x = A.solve_right(b) # needs scipy + sage: (A * x - b).norm() # tol 1e-14 # needs scipy 3.2692119900020438 TESTS: @@ -742,8 +744,9 @@ cdef class Matrix(Matrix1): sage: A = matrix(QQ, 2, [1, 2, 3, 4]) sage: b = vector(RDF, [pi, e]) # needs sage.symbolic - sage: A.solve_right(b) # tol 1e-15 # needs sage.symbolic + sage: A.solve_right(b) # tol 1e-15 # needs scipy sage.symbolic (-3.564903478720541, 3.353248066155167) + sage: R. = ZZ[] sage: b = vector(R, [1, t]) sage: x = A.solve_right(b); x @@ -1572,8 +1575,8 @@ cdef class Matrix(Matrix1): Beware that the ``exact`` algorithm is not numerically stable, but the default ``numpy`` algorithm is:: - sage: M = matrix.hilbert(12,ring=RR) - sage: (~M*M).norm() # a considerable error + sage: M = matrix.hilbert(12, ring=RR) + sage: (~M * M).norm() # a considerable error # needs scipy 1.3... sage: Mx = M.pseudoinverse(algorithm="exact") sage: (Mx*M).norm() # huge error @@ -6361,6 +6364,7 @@ cdef class Matrix(Matrix1): 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: # needs scipy sage: em = A.change_ring(RDF).eigenmatrix_left() sage: eigenvalues = em[0]; eigenvalues.dense_matrix() # abs tol 1e-13 [13.348469228349522 0.0 0.0] @@ -6642,6 +6646,7 @@ cdef class Matrix(Matrix1): for inexact rings such as Real Field with 53 bits of precision, consult numerical or symbolic matrix classes for other options + sage: # needs scipy sage: em = B.change_ring(RDF).eigenmatrix_right() sage: eigenvalues = em[0]; eigenvalues.dense_matrix() # abs tol 1e-13 [13.348469228349522 0.0 0.0] @@ -7127,6 +7132,7 @@ cdef class Matrix(Matrix1): A generalized eigenvector decomposition:: + sage: # needs scipy sage: A = matrix(RDF, [[1, -2], [3, 4]]) sage: B = matrix(RDF, [[0, 7], [2, -3]]) sage: D, P = A.eigenmatrix_left(B) @@ -7135,7 +7141,7 @@ cdef class Matrix(Matrix1): The matrix `B` in a generalized eigenvalue problem may be singular:: - sage: # needs sage.rings.complex_double sage.symbolic + sage: # needs scipy sage.rings.complex_double sage.symbolic sage: A = matrix.identity(CDF, 2) sage: B = matrix(CDF, [[2, 1+I], [4, 2+2*I]]) sage: D, P = A.eigenmatrix_left(B) @@ -7145,7 +7151,7 @@ cdef class Matrix(Matrix1): In this case, we can still verify the eigenvector equation for the first eigenvalue and first eigenvector:: - sage: # needs sage.rings.complex_double sage.symbolic + sage: # needs scipy sage.rings.complex_double sage.symbolic sage: l = D[0, 0] sage: v = P[0, :] sage: (v * A - l * v * B).norm() < 1e-14 @@ -7353,6 +7359,7 @@ cdef class Matrix(Matrix1): A generalized eigenvector decomposition:: + sage: # needs scipy sage: A = matrix(RDF, [[1, -2], [3, 4]]) sage: B = matrix(RDF, [[0, 7], [2, -3]]) sage: D, P = A.eigenmatrix_right(B) @@ -7361,6 +7368,7 @@ cdef class Matrix(Matrix1): The matrix `B` in a generalized eigenvalue problem may be singular:: + sage: # needs scipy sage: A = matrix.identity(RDF, 2) sage: B = matrix(RDF, [[3, 5], [6, 10]]) sage: D, P = A.eigenmatrix_right(B); D # tol 1e-14 @@ -10786,7 +10794,7 @@ cdef class Matrix(Matrix1): First, the inexact rings, ``CDF`` and ``RDF``. :: - sage: # needs sage.rings.complex_double sage.symbolic + sage: # needs scipy sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, [[ 0.6454 + 0.7491*I, -0.8662 + 0.1489*I, 0.7656 - 0.00344*I], ....: [-0.2913 + 0.8057*I, 0.8321 + 0.8170*I, -0.6744 + 0.9248*I], ....: [ 0.2554 + 0.3517*I, -0.4454 - 0.1715*I, 0.8325 - 0.6282*I]]) @@ -12836,7 +12844,7 @@ cdef class Matrix(Matrix1): sage: L = A.cholesky(); L [ 1.000... 0.000...] [ 2.000... 1.414...] - sage: (L*L.transpose() - A).norm() < 1e-10 + sage: (L*L.transpose() - A).norm() < 1e-10 # needs scipy True Even symbolic matrices can sometimes be factored:: @@ -14823,9 +14831,9 @@ 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) # needs numpy + sage: expected = is_positive_semidefinite_naive(A) # needs scipy sage: actual = A.is_positive_semidefinite() - sage: actual == expected # needs numpy + sage: actual == expected # needs scipy True We reject matrices whose base fields cannot be coerced to @@ -15390,7 +15398,7 @@ cdef class Matrix(Matrix1): :: sage: Id = identity_matrix(12) - sage: Id.norm(2) + sage: Id.norm(2) # needs scipy 1.0 sage: # needs sage.rings.real_mpfr diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 278fd272b68..cd0dd2e3117 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -2500,10 +2500,13 @@ def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, check sage: tinv(GF(2), sparse=False) sage: tinv(SR, sparse=True) # needs sage.symbolic sage: tinv(SR, sparse=False) # needs sage.symbolic + + sage: # needs scipy 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) # needs sage.rings.number_field sage: tinv(CyclotomicField(7), sparse=False) # needs sage.rings.number_field sage: tinv(QQ['x,y'], sparse=True) diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index f34c0abfe71..c5e4b7058bf 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -1002,7 +1002,7 @@ def direct_sum(self, other): sage: v = [(1,0), (0,1)] sage: F1 = FilteredVectorSpace(v, {0:[0], 1:[1]}, base_ring=QQ) sage: F2 = FilteredVectorSpace(v, {0:[0], 1:[1]}, base_ring=RDF) - sage: F1 + F2 + sage: F1 + F2 # needs scipy RDF^4 >= RDF^2 >= 0 """ from sage.structure.element import get_coercion_model @@ -1067,7 +1067,7 @@ def tensor_product(self, other): sage: v = [(1,0), (0,1)] sage: F1 = FilteredVectorSpace(v, {0:[0], 1:[1]}, base_ring=QQ) sage: F2 = FilteredVectorSpace(v, {0:[0], 1:[1]}, base_ring=RDF) - sage: F1 * F2 + sage: F1 * F2 # needs scipy RDF^4 >= RDF^3 >= RDF^1 >= 0 """ V = self diff --git a/src/sage/modules/vector_double_dense.pyx b/src/sage/modules/vector_double_dense.pyx index a47d91a7fdd..063b665922c 100644 --- a/src/sage/modules/vector_double_dense.pyx +++ b/src/sage/modules/vector_double_dense.pyx @@ -212,6 +212,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): EXAMPLES:: + sage: # needs scipy sage: v = vector(CDF,[1,2,3,4]) sage: w = v.fft() sage: max(v - w.inv_fft()) < 1e-12 @@ -233,6 +234,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): EXAMPLES:: + sage: # needs scipy sage: v = vector(CDF,[1+2*I,2,3*I,4]) sage: v.fft() (7.0 + 5.0*I, 1.0 + 1.0*I, -5.0 + 5.0*I, 1.0 - 3.0*I) @@ -246,6 +248,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): sage: v (7.0 + 5.0*I, 1.0 + 1.0*I, -5.0 + 5.0*I, 1.0 - 3.0*I) + sage: # needs scipy sage: v = vector(RDF,4,range(4)); v (0.0, 1.0, 2.0, 3.0) sage: v.fft() From bdd0506db8315602ebe22943a88700969eaad464 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Sep 2023 22:56:02 -0700 Subject: [PATCH 06/19] sage.matrix: Add # needs --- .../matrix/matrix_complex_double_dense.pyx | 8 +- src/sage/matrix/matrix_double_dense.pyx | 76 ++++++++++++++----- src/sage/matrix/matrix_numpy_dense.pyx | 4 +- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/src/sage/matrix/matrix_complex_double_dense.pyx b/src/sage/matrix/matrix_complex_double_dense.pyx index 162332eb44e..b86516fd121 100644 --- a/src/sage/matrix/matrix_complex_double_dense.pyx +++ b/src/sage/matrix/matrix_complex_double_dense.pyx @@ -17,6 +17,7 @@ We deal with the case of zero rows or zero columns:: TESTS:: + sage: # needs sage.symbolic sage: a = matrix(CDF,2,[i+(4-i)*I for i in range(4)], sparse=False) sage: TestSuite(a).run() sage: Mat(CDF,0,0).zero_matrix().inverse() @@ -53,6 +54,7 @@ cdef class Matrix_complex_double_dense(Matrix_double_dense): EXAMPLES:: + sage: # needs sage.symbolic sage: m = Matrix(CDF, [[1,2*I],[3+I,4]]) sage: m**2 [-1.0 + 6.0*I 10.0*I] @@ -65,7 +67,7 @@ cdef class Matrix_complex_double_dense(Matrix_double_dense): :meth:`~.Matrix_double_dense.left_eigenvectors` or :meth:`~.Matrix_double_dense.right_eigenvectors`:: - sage: p,e = m.right_eigenvectors() + sage: p,e = m.right_eigenvectors() # needs sage.symbolic The result is a pair ``(p,e)``, where ``p`` is a diagonal matrix of eigenvalues and ``e`` is a matrix whose columns are the @@ -74,8 +76,8 @@ cdef class Matrix_complex_double_dense(Matrix_double_dense): To solve a linear system `Ax = b` where ``A = [[1,2*I],[3+I,4]]`` and ``b = [5,6]``:: - sage: b = vector(CDF,[5,6]) - sage: m.solve_right(b) # abs tol 1e-14 + sage: b = vector(CDF,[5,6]) # needs sage.symbolic + sage: m.solve_right(b) # abs tol 1e-14 # needs sage.symbolic (2.6666666666666665 + 0.6666666666666669*I, -0.3333333333333333 - 1.1666666666666667*I) See the methods :meth:`~.Matrix_double_dense.QR`, diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx index f4312a479e5..10239ae77e6 100644 --- a/src/sage/matrix/matrix_double_dense.pyx +++ b/src/sage/matrix/matrix_double_dense.pyx @@ -624,6 +624,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): And over the complex numbers. :: + sage: # needs sage.symbolic sage: B = matrix(CDF, 2, [[1+I, 2+3*I],[3+4*I,3*I]]); B [1.0 + 1.0*I 2.0 + 3.0*I] [3.0 + 4.0*I 3.0*I] @@ -1144,13 +1145,14 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): sage: m.eigenvalues(algorithm='default') [1.0*I, -1.0*I] - sage: m = matrix(CDF, 2, 2, [I,1,-I,0]) - sage: m.eigenvalues() + sage: m = matrix(CDF, 2, 2, [I,1,-I,0]) # needs sage.symbolic + sage: m.eigenvalues() # needs sage.symbolic [-0.624810533... + 1.30024259...*I, 0.624810533... - 0.30024259...*I] The adjacency matrix of a graph will be symmetric, and the eigenvalues will be real. :: + sage: # needs sage.graphs sage: A = graphs.PetersenGraph().adjacency_matrix() sage: A = A.change_ring(RDF) sage: ev = A.eigenvalues(algorithm='symmetric'); ev # tol 1e-14 @@ -1163,6 +1165,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): the eigenvalues of a Hermitian matrix are real, and the eigenvalues of a positive-definite matrix will be positive. :: + sage: # needs sage.symbolic sage: A = matrix([[ 4*I + 5, 8*I + 1, 7*I + 5, 3*I + 5], ....: [ 7*I - 2, -4*I + 7, -2*I + 4, 8*I + 8], ....: [-2*I + 1, 6*I + 6, 5*I + 5, -I - 4], @@ -1178,19 +1181,19 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): it might split too finely. Too large, and it can go wrong very badly. Use with care. :: + sage: # needs sage.graphs sage: G = graphs.PetersenGraph() sage: G.spectrum() [3, 1, 1, 1, 1, 1, -2, -2, -2, -2] - sage: A = G.adjacency_matrix().change_ring(RDF) sage: A.eigenvalues(algorithm='symmetric', tol=1.0e-5) # tol 1e-15 [(-2.0, 4), (1.0, 5), (3.0, 1)] - sage: A.eigenvalues(algorithm='symmetric', tol=2.5) # tol 1e-15 [(-2.0, 4), (1.3333333333333333, 6)] An (extreme) example of properly grouping similar eigenvalues. :: + sage: # needs sage.graphs sage: G = graphs.HigmanSimsGraph() sage: A = G.adjacency_matrix().change_ring(RDF) sage: A.eigenvalues(algorithm='symmetric', tol=1.0e-5) # tol 2e-15 @@ -1268,6 +1271,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): Test the deprecation:: + sage: # needs sage.graphs sage: A = graphs.PetersenGraph().adjacency_matrix().change_ring(RDF) sage: ev = A.eigenvalues('symmetric', 1e-13) doctest:...: DeprecationWarning: "algorithm" and "tol" should be used @@ -1705,6 +1709,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): TESTS:: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[1, 2], [3, 3+I]]) sage: b = matrix(CDF, [[1, 0], [2, 1]]) sage: x = A._solve_right_nonsingular_square(b) @@ -1830,6 +1835,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): EXAMPLES:: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[1+I, 3-I], [0, 2*I]]) sage: A.conjugate() [1.0 - 1.0*I 3.0 + 1.0*I] @@ -1837,7 +1843,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): There is a shorthand notation:: - sage: A.conjugate() == A.C + sage: A.conjugate() == A.C # needs sage.symbolic True Conjugates work (trivially) for real matrices:: @@ -2265,6 +2271,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): The QR decomposition will produce a unitary matrix as Q and the SVD decomposition will create two unitary matrices, U and V. :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 1 - I, -3*I, -2 + I, 1, -2 + 3*I], ....: [ 1 - I, -2 + I, 1 + 4*I, 0, 2 + I], ....: [ -1, -5 + I, -2 + I, 1 + I, -5 - 4*I], @@ -2427,6 +2434,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): EXAMPLES:: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 1 + I, 1 - 6*I, -1 - I], ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) @@ -2439,6 +2447,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): A matrix that is nearly Hermitian, but for one non-real diagonal entry:: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 2, 2-I, 1+4*I], ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) @@ -2461,6 +2470,8 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): False A matrix that is skew-Hermitian:: + + sage: # needs sage.symbolic sage: A = matrix(CDF, [[-I, 2.0+I], [-2.0+I, 0.0]]) sage: A._is_hermitian_orthonormal() False @@ -2549,6 +2560,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): EXAMPLES:: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 1 + I, 1 - 6*I, -1 - I], ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) @@ -2565,6 +2577,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): A matrix that is nearly Hermitian, but for one non-real diagonal entry. :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 2, 2-I, 1+4*I], ....: [ 2+I, 3+I, 2-6*I], ....: [1-4*I, 2+6*I, 5]]) @@ -2582,11 +2595,12 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): of entries and may achieve the wrong result (depending on the system):: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 1 + I, 1 - 6*I, -1 - I], ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) sage: U, _, _ = A.SVD() - sage: B=U*U.conjugate_transpose() + sage: B = U*U.conjugate_transpose() sage: B.is_hermitian(algorithm='naive') True sage: B.is_hermitian(algorithm='naive', tol=1.0e-17) # random @@ -2685,6 +2699,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): A matrix that is nearly skew-Hermitian, but for a non-real diagonal entry. :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ -I, -1, 1-I], ....: [ 1, 1, -1], ....: [-1-I, 1, -I]]) @@ -2702,11 +2717,12 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): be too strict about the equality of entries and may achieve the wrong result (depending on the system):: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 1 + I, 1 - 6*I, -1 - I], ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) sage: U, _, _ = A.SVD() - sage: B=1j*U*U.conjugate_transpose() + sage: B = 1j*U*U.conjugate_transpose() sage: B.is_skew_hermitian(algorithm='naive') True sage: B.is_skew_hermitian(algorithm='naive', tol=1.0e-17) # random @@ -2798,6 +2814,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): First over the complexes. ``B`` is Hermitian, hence normal. :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 1 + I, 1 - 6*I, -1 - I], ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) @@ -2816,22 +2833,24 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): Now over the reals. 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() sage: A = A.change_ring(RDF) sage: A.is_normal() True - sage: A.is_normal(algorithm = 'naive') + sage: A.is_normal(algorithm='naive') True sage: A[19,0] = 4.0 sage: A.is_normal() False - sage: A.is_normal(algorithm = 'naive') + sage: A.is_normal(algorithm='naive') False Skew-Hermitian matrices are normal. :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 1 + I, 1 - 6*I, -1 - I], ....: [-3 - I, -4*I, -2], ....: [-1 + I, -2 - 8*I, 2 + I]]) @@ -2856,6 +2875,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): Sage has several fields besides the entire complex numbers where conjugation is non-trivial. :: + 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], @@ -2991,7 +3011,9 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): First over the complexes. The similar matrix is always upper-triangular in this case. :: - sage: A = matrix(CDF, 4, 4, range(16)) + matrix(CDF, 4, 4, [x^3*I for x in range(0, 16)]) + sage: # needs sage.symbolic + sage: A = matrix(CDF, 4, 4, range(16)) + matrix(CDF, 4, 4, + ....: [x^3*I for x in range(0, 16)]) sage: Q, T = A.schur() sage: (Q*Q.conjugate().transpose()).zero_at(1e-12) # tol 1e-12 [ 0.999999999999999 0.0 0.0 0.0] @@ -3000,7 +3022,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): [ 0.0 0.0 0.0 0.9999999999999999] sage: all(T.zero_at(1.0e-12)[i,j] == 0 for i in range(4) for j in range(i)) True - sage: (Q*T*Q.conjugate().transpose()-A).zero_at(1.0e-11) + sage: (Q*T*Q.conjugate().transpose() - A).zero_at(1.0e-11) [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] @@ -3027,7 +3049,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): Full MatrixSpace of 4 by 4 dense matrices over Complex Double Field sage: all(T.zero_at(1.0e-12)[i,j] == 0 for i in range(4) for j in range(i)) True - sage: (Q*T*Q.conjugate().transpose()-A).zero_at(1.0e-11) + sage: (Q*T*Q.conjugate().transpose() - A).zero_at(1.0e-11) [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] @@ -3054,7 +3076,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): False sage: all(T.zero_at(1.0e-12)[i,j] == 0 for i in range(4) for j in range(i-1)) True - sage: (Q*T*Q.conjugate().transpose()-A).zero_at(1.0e-11) + sage: (Q*T*Q.conjugate().transpose() - A).zero_at(1.0e-11) [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] @@ -3069,6 +3091,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): Starting with complex numbers and requesting a result over the reals will never happen. :: + sage: # needs sage.symbolic sage: A = matrix(CDF, 2, 2, [[2+I, -1+3*I], [5-4*I, 2-7*I]]) sage: A.schur(base_ring=RDF) Traceback (most recent call last): @@ -3095,7 +3118,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): sage: T.round(6) [ 0.5 1.5] [-0.5 0.5] - sage: (Q*T*Q.conjugate().transpose()-B).zero_at(1.0e-11) + sage: (Q*T*Q.conjugate().transpose() - B).zero_at(1.0e-11) [0.0 0.0] [0.0 0.0] @@ -3105,6 +3128,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): of eigenvectors of the matrix. Here that basis is the set of columns of the unitary matrix. :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 52, -9*I - 8, 6*I - 187, -188*I + 2], ....: [ 9*I - 8, 12, -58*I + 59, 30*I + 42], ....: [-6*I - 187, 58*I + 59, 2677, 2264*I + 65], @@ -3121,7 +3145,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): [ 0.0 0.9999999999999989 0.0 0.0] [ 0.0 0.0 1.0000000000000002 0.0] [ 0.0 0.0 0.0 0.9999999999999992] - sage: (Q*T*Q.conjugate().transpose()-A).zero_at(1.0e-11) + sage: (Q*T*Q.conjugate().transpose() - A).zero_at(1.0e-11) [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] @@ -3142,14 +3166,15 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): [ 0.4361 0.359 0.7599 0.3217] [ -0.836 0.3945 0.1438 0.3533] sage: T = T.zero_at(10^-12) - sage: all(abs(e) < 10^-4 for e in (T - diagonal_matrix(RDF, [-13.5698, -0.8508, 7.7664, 11.6542])).list()) + sage: all(abs(e) < 10^-4 + ....: for e in (T - diagonal_matrix(RDF, [-13.5698, -0.8508, 7.7664, 11.6542])).list()) True sage: (Q*Q.transpose()) # tol 1e-12 [0.9999999999999998 0.0 0.0 0.0] [ 0.0 1.0 0.0 0.0] [ 0.0 0.0 0.9999999999999998 0.0] [ 0.0 0.0 0.0 0.9999999999999996] - sage: (Q*T*Q.transpose()-A).zero_at(1.0e-11) + sage: (Q*T*Q.transpose() - A).zero_at(1.0e-11) [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] [0.0 0.0 0.0 0.0] @@ -3294,6 +3319,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): A complex matrix that is Hermitian and positive definite. :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[ 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], @@ -3332,6 +3358,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): ... ValueError: matrix is not positive definite + sage: # needs sage.symbolic sage: B = matrix(CDF, [[ 2, 4 - 2*I, 2 + 2*I], ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) @@ -3363,6 +3390,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[1+I]]) sage: A.cholesky() Traceback (most recent call last): @@ -3464,6 +3492,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): A matrix over ``CDF`` that is positive definite. :: + sage: # needs sage.symbolic sage: C = matrix(CDF, [[ 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], @@ -3495,6 +3524,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): A matrix over ``CDF`` that is not positive definite. :: + sage: # needs sage.symbolic sage: B = matrix(CDF, [[ 2, 4 - 2*I, 2 + 2*I], ....: [4 + 2*I, 8, 10*I], ....: [2 - 2*I, -10*I, -3]]) @@ -3539,6 +3569,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): :: + sage: # needs sage.symbolic sage: A = matrix(CDF, [[1+I]]) sage: A.is_positive_definite() False @@ -3641,10 +3672,10 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): sage: A.exp() # tol 1e-14 [51.968956198705044 74.73656456700327] [112.10484685050491 164.07380304920997] - sage: A = matrix(CDF, 2, [1,2+I,3*I,4]); A + sage: A = matrix(CDF, 2, [1,2+I,3*I,4]); A # needs sage.symbolic [ 1.0 2.0 + 1.0*I] [ 3.0*I 4.0] - sage: A.exp() # tol 1.1e-14 + sage: A.exp() # tol 1.1e-14 # needs sage.symbolic [-19.614602953804912 + 12.517743846762578*I 3.7949636449582176 + 28.88379930658099*I] [ -32.383580980922254 + 21.88423595789845*I 2.269633004093535 + 44.901324827684824*I] @@ -3655,8 +3686,8 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): [51.968956198705044 74.73656456700327] [112.10484685050491 164.07380304920997] - sage: A = matrix(CDF, 2, [1,2+I,3*I,4]) - sage: A.exp() # tol 3e-14 + sage: A = matrix(CDF, 2, [1,2+I,3*I,4]) # needs sage.symbolic + sage: A.exp() # tol 3e-14 # needs sage.symbolic [-19.614602953804923 + 12.51774384676257*I 3.7949636449582016 + 28.883799306580997*I] [-32.38358098092227 + 21.884235957898433*I 2.2696330040935084 + 44.90132482768484*I] """ @@ -3690,6 +3721,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): EXAMPLES:: + sage: # needs sage.symbolic sage: a = matrix(CDF, [[1, 1e-4r, 1+1e-100jr], [1e-8+3j, 0, 1e-58r]]) sage: a [ 1.0 0.0001 1.0 + 1e-100*I] @@ -3765,6 +3797,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): EXAMPLES:: + sage: # needs sage.symbolic sage: a = matrix(CDF, [[1, -2+I, 0, -3*I], [2, 2, -2, 2], [-3, -3, -3, -2]]) sage: a [ 1.0 -2.0 + 1.0*I 0.0 -3.0*I] @@ -3803,6 +3836,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): EXAMPLES:: + sage: # needs sage.symbolic sage: a = matrix(CDF, [[1, 2, -3], [-2+I, 2, -3], [0, -2, -3], [-3*I, 2, -2]]) sage: a [ 1.0 2.0 -3.0] diff --git a/src/sage/matrix/matrix_numpy_dense.pyx b/src/sage/matrix/matrix_numpy_dense.pyx index d0e55fa927a..bd74e424bee 100644 --- a/src/sage/matrix/matrix_numpy_dense.pyx +++ b/src/sage/matrix/matrix_numpy_dense.pyx @@ -134,7 +134,7 @@ cdef class Matrix_numpy_dense(Matrix_dense): [0.0 1.0 2.0] [3.0 4.0 5.0] [6.0 7.0 8.0] - sage: matrix(CDF,2,2,[CDF(1+I)*j for j in range(4)]) + sage: matrix(CDF,2,2,[CDF(1+I)*j for j in range(4)]) # needs sage.symbolic [ 0.0 1.0 + 1.0*I] [2.0 + 2.0*I 3.0 + 3.0*I] """ @@ -308,7 +308,7 @@ cdef class Matrix_numpy_dense(Matrix_dense): Complex entries are supported (:trac:`27831`). :: - sage: a = matrix(CDF, [(21, 0.6 + 18.5*i), (0.6 - 18.5*i, 21)]) + sage: a = matrix(CDF, [(21, 0.6 + 18.5*i), (0.6 - 18.5*i, 21)]) # needs sage.symbolic sage: a.is_symmetric() False """ From d366696f6ae35b6f49d0a87ba533c1bd78665356 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 9 Sep 2023 12:36:27 -0700 Subject: [PATCH 07/19] sage.{matrix,modules}: Update # needs --- src/sage/matrix/matrix2.pyx | 5 +++-- src/sage/modules/free_module_element.pyx | 17 +++++++++-------- src/sage/modules/matrix_morphism.py | 4 +++- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 1a3690a466e..68707247ffa 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -7378,9 +7378,10 @@ 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] # needs sage.symbolic + sage: # needs scipy + sage: l = D[0, 0] sage: v = P[:, 0] - sage: (A * v - B * v * l).norm() < 1e-14 # needs sage.symbolic + sage: (A * v - B * v * l).norm() < 1e-14 True The second eigenvector is contained in the right kernel of `B`:: diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index a2c077cc8c8..bffc5762a9c 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -416,8 +416,8 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): Complex numbers can be converted naturally to a sequence of length 2. And then to a vector. :: - sage: c = CDF(2 + 3*I) - sage: v = vector(c); v + sage: c = CDF(2 + 3*I) # needs sage.rings.complex_double sage.symbolic + sage: v = vector(c); v # needs sage.rings.complex_double sage.symbolic (2.0, 3.0) A generator, or other iterable, may also be supplied as input. Anything @@ -3435,8 +3435,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: R. = ZZ[] sage: v = vector(R, [12, 24*t]) sage: w = vector(QQ, [1/2, 1/3, 1/4]) - sage: op = v.outer_product(w) - sage: op + sage: op = v.outer_product(w); op [ 6 4 3] [12*t 8*t 6*t] sage: op.base_ring() @@ -3451,7 +3450,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) # needs sage.rings.finite_rings + sage: z = w.outer_product(v) Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: @@ -3460,8 +3459,8 @@ cdef class FreeModuleElement(Vector): # abstract base class And some inputs don't make any sense at all. :: - sage: w=vector(QQ, [5,10]) - sage: z=w.outer_product(6) + sage: w = vector(QQ, [5,10]) + sage: z = w.outer_product(6) Traceback (most recent call last): ... TypeError: right operand in an outer product must be a vector, @@ -3531,7 +3530,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: # needs sage.rings.complex_double 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]) @@ -3550,6 +3549,7 @@ cdef class FreeModuleElement(Vector): # abstract base class default for the :meth:`norm` method). The norm squared equals the Hermitian inner product of the vector with itself. :: + sage: # needs sage.rings.complex_double sage.symbolic sage: v = vector(CDF, [-0.66+0.47*I, -0.60+0.91*I, -0.62-0.87*I, 0.53+0.32*I]) sage: abs(v.norm()^2 - v.hermitian_inner_product(v)) < 1.0e-10 True @@ -3560,6 +3560,7 @@ cdef class FreeModuleElement(Vector): # abstract base class which allows for a wide variety of inputs. Any error handling happens there. :: + sage: # needs sage.rings.complex_double sage.symbolic sage: v = vector(CDF, [2+3*I]) sage: w = vector(CDF, [5+2*I, 3+9*I]) sage: v.hermitian_inner_product(w) diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index b9d45e9755f..d342dc00237 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -212,13 +212,15 @@ def _call_with_args(self, x, args=(), kwds={}): EXAMPLES:: + sage: # needs sage.rings.real_mpfr sage.symbolic sage: V = RR^2 sage: f = V.hom(V.gens()) sage: f._matrix *= I # f is now invalid sage: f((1, 0)) Traceback (most recent call last): ... - TypeError: Unable to coerce entries (=[1.00000000000000*I, 0.000000000000000]) to coefficients in Real Field with 53 bits of precision + TypeError: Unable to coerce entries (=[1.00000000000000*I, 0.000000000000000]) + to coefficients in Real Field with 53 bits of precision sage: f((1, 0), coerce=False) (1.00000000000000*I, 0.000000000000000) From 433eb4154630f52d7aaeceb1a06c9710a6788204 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 10 Sep 2023 16:40:01 -0700 Subject: [PATCH 08/19] sage.matrix: Add # needs --- src/sage/matrix/matrix2.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 68707247ffa..77d52e854b8 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -7386,7 +7386,7 @@ cdef class Matrix(Matrix1): The second eigenvector is contained in the right kernel of `B`:: - sage: (B * P[:, 1]).norm() < 1e-14 + sage: (B * P[:, 1]).norm() < 1e-14 # needs scipy True .. SEEALSO:: From 171adf5d32ce2529cd300704d8d2a098ee5ee0e5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 10 Sep 2023 16:40:29 -0700 Subject: [PATCH 09/19] sage.modules: Update # needs --- src/sage/modules/free_module_element.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index bffc5762a9c..e8903fc9bfe 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -3225,6 +3225,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: # needs sage.rings.complex_double sage.symbolic 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) From 4537cb4610fb5fbd32417f2c8da6a69e29a8b1f9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 10 Sep 2023 23:24:30 -0700 Subject: [PATCH 10/19] sage.{matrix,modules}: Update # needs --- src/sage/matrix/matrix_numpy_dense.pyx | 2 +- src/sage/modules/free_module_element.pyx | 4 ++-- src/sage/modules/vector_numpy_dense.pyx | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/matrix/matrix_numpy_dense.pyx b/src/sage/matrix/matrix_numpy_dense.pyx index bd74e424bee..a829b457f3a 100644 --- a/src/sage/matrix/matrix_numpy_dense.pyx +++ b/src/sage/matrix/matrix_numpy_dense.pyx @@ -309,7 +309,7 @@ cdef class Matrix_numpy_dense(Matrix_dense): Complex entries are supported (:trac:`27831`). :: sage: a = matrix(CDF, [(21, 0.6 + 18.5*i), (0.6 - 18.5*i, 21)]) # needs sage.symbolic - sage: a.is_symmetric() + sage: a.is_symmetric() # needs sage.symbolic False """ cdef Py_ssize_t i, j diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index e8903fc9bfe..267624236c2 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -457,9 +457,9 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): sage: v.is_immutable() True - sage: # needs numpy + sage: # needs numpy sage.symbolic sage: import numpy as np - sage: w = np.array([1, 2, pi], float) # needs sage.symbolic + sage: w = np.array([1, 2, pi], float) sage: v = vector(w, immutable=True) sage: v.is_immutable() True diff --git a/src/sage/modules/vector_numpy_dense.pyx b/src/sage/modules/vector_numpy_dense.pyx index fc14cc4829a..884b3a39839 100644 --- a/src/sage/modules/vector_numpy_dense.pyx +++ b/src/sage/modules/vector_numpy_dense.pyx @@ -151,7 +151,7 @@ cdef class Vector_numpy_dense(FreeModuleElement): (0.0, 0.0, 0.0, 0.0) sage: vector(RDF, 4) (0.0, 0.0, 0.0, 0.0) - sage: vector(CDF, [CDF(1+I)*j for j in range(4)]) + sage: vector(CDF, [CDF(1+I)*j for j in range(4)]) # needs sage.symbolic (0.0, 1.0 + 1.0*I, 2.0 + 2.0*I, 3.0 + 3.0*I) sage: vector(RDF, 4, range(4)) (0.0, 1.0, 2.0, 3.0) @@ -211,13 +211,13 @@ cdef class Vector_numpy_dense(FreeModuleElement): """ EXAMPLES:: - sage: v = vector(CDF, [1,CDF(3,2), -1]); v + sage: v = vector(CDF, [1, CDF(3,2), -1]); v (1.0, 3.0 + 2.0*I, -1.0) sage: v[1] = 2 - sage: v[-1] = I - sage: v + sage: v[-1] = I # needs sage.symbolic + sage: v # needs sage.symbolic (1.0, 2.0, 1.0*I) - sage: v[1:3] = [1, 1]; v + sage: v[1:3] = [1, 1]; v # needs sage.symbolic (1.0, 1.0, 1.0) """ # We assume that Py_ssize_t is the same as npy_intp From 23ac349a53f173410d30de57bc422f64b6c65296 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 11 Sep 2023 22:33:43 -0700 Subject: [PATCH 11/19] sage.matrix: Add # needs --- src/sage/matrix/matrix_complex_ball_dense.pyx | 4 ++-- src/sage/matrix/matrix_double_dense.pyx | 2 +- src/sage/matrix/matrix_double_sparse.pyx | 4 ++-- src/sage/matrix/matrix_real_double_dense.pyx | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index 22366b5f1f2..36828fdcf97 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -19,8 +19,8 @@ TESTS:: [8.000000000000000 11.00000000000000] [22.00000000000000 41.00000000000000] - sage: mat = matrix(ComplexBallField(20), 2, 2, list(range(4)))*i/3 - sage: loads(dumps(mat)).identical(mat) + sage: mat = matrix(ComplexBallField(20), 2, 2, list(range(4)))*i/3 # needs sage.symbolic + sage: loads(dumps(mat)).identical(mat) # needs sage.symbolic True """ # **************************************************************************** diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx index 10239ae77e6..46fc9b9752d 100644 --- a/src/sage/matrix/matrix_double_dense.pyx +++ b/src/sage/matrix/matrix_double_dense.pyx @@ -99,7 +99,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): sage: m**2 [ 7.0 10.0] [15.0 22.0] - sage: m^(-1) # rel tol 1e-15 + sage: m^(-1) # rel tol 1e-15 # needs scipy [-1.9999999999999996 0.9999999999999998] [ 1.4999999999999998 -0.4999999999999999] diff --git a/src/sage/matrix/matrix_double_sparse.pyx b/src/sage/matrix/matrix_double_sparse.pyx index fc7d65a880c..9871ee7bba1 100644 --- a/src/sage/matrix/matrix_double_sparse.pyx +++ b/src/sage/matrix/matrix_double_sparse.pyx @@ -169,7 +169,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): sage: (A - L*L.T).norm(1) < 1e-10 True sage: B = A.dense_matrix() - sage: (B.cholesky() - L).norm(1) < 1e-10 + sage: (B.cholesky() - L).norm(1) < 1e-10 # needs scipy True :: @@ -183,7 +183,7 @@ cdef class Matrix_double_sparse(Matrix_generic_sparse): sage: (A - L*L.H).norm(1) < 1e-10 True sage: B = A.dense_matrix() - sage: (B.cholesky() - L).norm(1) < 1e-10 + sage: (B.cholesky() - L).norm(1) < 1e-10 # needs scipy True """ cdef Matrix L # output matrix diff --git a/src/sage/matrix/matrix_real_double_dense.pyx b/src/sage/matrix/matrix_real_double_dense.pyx index 542638ed17d..1d270580ff5 100644 --- a/src/sage/matrix/matrix_real_double_dense.pyx +++ b/src/sage/matrix/matrix_real_double_dense.pyx @@ -70,7 +70,7 @@ cdef class Matrix_real_double_dense(Matrix_double_dense): :: - sage: p,e = m.right_eigenvectors() + sage: p,e = m.right_eigenvectors() # needs scipy The result is a pair ``(p,e)``, where ``p`` is a diagonal matrix of eigenvalues and ``e`` is a matrix whose columns are the @@ -80,7 +80,7 @@ cdef class Matrix_real_double_dense(Matrix_double_dense): `b = [5,6]`:: sage: b = vector(RDF,[5,6]) - sage: m.solve_right(b) # rel tol 1e-15 + sage: m.solve_right(b) # rel tol 1e-15 # needs scipy (-3.9999999999999987, 4.499999999999999) See the methods :meth:`~.Matrix_double_dense.QR`, From 38119de421aeae1771821d95b9164abd572c0a00 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 12 Sep 2023 00:06:32 -0700 Subject: [PATCH 12/19] sage.matrix: Add # needs --- src/sage/matrix/constructor.pyx | 2 +- src/sage/matrix/matrix2.pyx | 21 +++++++++++-------- .../matrix/matrix_modn_dense_template.pxi | 2 +- src/sage/matrix/matrix_polynomial_dense.pyx | 2 +- src/sage/matrix/matrix_space.py | 4 ++-- src/sage/matrix/special.py | 8 +++---- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/sage/matrix/constructor.pyx b/src/sage/matrix/constructor.pyx index a31543e0795..46f1b95d661 100644 --- a/src/sage/matrix/constructor.pyx +++ b/src/sage/matrix/constructor.pyx @@ -580,7 +580,7 @@ def matrix(*args, **kwds): Check :trac:`24459`:: - sage: # needs sage.libs.flint + sage: # needs sage.libs.linbox sage: Matrix(ZZ, sys.maxsize, sys.maxsize) Traceback (most recent call last): ... diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 77d52e854b8..80d06af7cbe 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -382,7 +382,7 @@ cdef class Matrix(Matrix1): A degenerate case:: sage: A = matrix(RDF, 0, 0, []) - sage: A.solve_left(vector(RDF,[])) + sage: A.solve_left(vector(RDF,[])) # needs scipy () Over an inexact ring like ``RDF``, the coefficient matrix of a @@ -677,7 +677,7 @@ cdef class Matrix(Matrix1): sage: b = vector(RDF, [5, 6, 1]) sage: A.solve_right(b) # tol 1e-14 # needs scipy (1.4782608695652177, 0.35177865612648235) - sage: ~(A.T * A) * A.T * b # closed form solution, tol 1e-14 + sage: ~(A.T * A) * A.T * b # closed form solution, tol 1e-14 # needs scipy (1.4782608695652177, 0.35177865612648235) Over the reals:: @@ -1579,7 +1579,7 @@ cdef class Matrix(Matrix1): sage: (~M * M).norm() # a considerable error # needs scipy 1.3... sage: Mx = M.pseudoinverse(algorithm="exact") - sage: (Mx*M).norm() # huge error + sage: (Mx * M).norm() # huge error # needs scipy 11.5... sage: Mx = M.pseudoinverse(algorithm="numpy") # needs numpy sage: (Mx * M).norm() # still OK @@ -7404,6 +7404,7 @@ cdef class Matrix(Matrix1): Running this test independently, without adjusting the eigenvectors could indicate this situation on your hardware. :: + sage: # needs scipy sage: B = matrix(QQ, 3, 3, range(9)) sage: em = B.change_ring(RDF).eigenmatrix_right() sage: evalues = em[0]; evalues.dense_matrix() # abs tol 1e-13 @@ -7421,7 +7422,7 @@ cdef class Matrix(Matrix1): The following example shows that :trac:`20439` has been resolved:: - sage: # needs sage.rings.complex_double + sage: # needs scipy sage.rings.complex_double sage: A = matrix(CDF, [[-2.53634347567, 2.04801738686, -0.0, -62.166145304], ....: [ 0.7, -0.6, 0.0, 0.0], ....: [0.547271128842, 0.0, -0.3015, -21.7532081652], @@ -7433,7 +7434,7 @@ cdef class Matrix(Matrix1): The following example shows that the fix for :trac:`20439` (conjugating eigenvectors rather than eigenvalues) is the correct one:: - sage: # needs sage.rings.complex_double sage.symbolic + sage: # needs scipy sage.rings.complex_double sage.symbolic sage: A = Matrix(CDF,[[I,0],[0,1]]) sage: D, P = A.eigenmatrix_right() sage: (A*P - P*D).norm() < 10^(-2) @@ -10820,6 +10821,7 @@ cdef class Matrix(Matrix1): A rectangular matrix. Note that the ``orthonormal`` keyword is ignored in these cases. :: + sage: # needs scipy sage: A = matrix(RDF, [[-0.978325, -0.751994, 0.925305, -0.200512, 0.420458], ....: [-0.474877, -0.983403, 0.089836, 0.132218, 0.672965]]) sage: G, M = A.gram_schmidt(orthonormal=False) @@ -10842,6 +10844,7 @@ cdef class Matrix(Matrix1): are treated as being of full rank. Try one of the base rings that provide exact results if you need exact results. :: + sage: # needs scipy sage: entries = [[1,1,2], [2,1,3], [3,1,4]] sage: A = matrix(QQ, entries) sage: A.rank() @@ -14492,7 +14495,7 @@ cdef class Matrix(Matrix1): sage: L*D*L.T [1e-10 1.0] [ 1.0 0.0] - sage: A.block_ldlt() + sage: A.block_ldlt() # needs scipy ( [1.0 0.0] [1.0 0.0] [1e-10 1.0] [0.0 1.0], [0.0 1.0], [ 1.0 2e-10] @@ -14502,7 +14505,7 @@ cdef class Matrix(Matrix1): but `P^{T}AP` will ideally be close to `LDL^{*}` in the metric induced by the norm:: - sage: # needs sage.rings.complex_double sage.symbolic + sage: # needs scipy sage.rings.complex_double sage.symbolic sage: A = matrix(CDF, 2, 2, [ [-1.1933, -0.3185 - 1.3553*I], ....: [-0.3185 + 1.3553*I, 1.5729 ] ]) sage: P,L,D = A.block_ldlt() @@ -14833,7 +14836,7 @@ cdef class Matrix(Matrix1): ....: return ( A.is_hermitian() and ....: all(v >= 0 for v in A.eigenvalues()) ) sage: expected = is_positive_semidefinite_naive(A) # needs scipy - sage: actual = A.is_positive_semidefinite() + sage: actual = A.is_positive_semidefinite() # needs scipy sage: actual == expected # needs scipy True @@ -15402,7 +15405,7 @@ cdef class Matrix(Matrix1): sage: Id.norm(2) # needs scipy 1.0 - sage: # needs sage.rings.real_mpfr + sage: # needs scipy sage.rings.real_mpfr sage: A = matrix(RR, 2, 2, [13,-4,-4,7]) sage: A.norm() # rel tol 2e-16 14.999999999999998 diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index 55cff5b9ac7..73e8f708110 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -465,7 +465,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): TESTS:: sage: import gc - sage: for i in range(10): # needs sage.rings.finite_rings + sage: for i in range(10): # needs sage.libs.linbox 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) diff --git a/src/sage/matrix/matrix_polynomial_dense.pyx b/src/sage/matrix/matrix_polynomial_dense.pyx index 5d9e99a6a4c..31a13cd83d6 100644 --- a/src/sage/matrix/matrix_polynomial_dense.pyx +++ b/src/sage/matrix/matrix_polynomial_dense.pyx @@ -2825,7 +2825,7 @@ 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 # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: division of these matrices does not admit a remainder diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index cd0dd2e3117..0d48de627f3 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -138,7 +138,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(CDF, 2, 3, False, 'numpy') # needs numpy - sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe, needs sage.rings.finite_rings + 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 @@ -183,7 +183,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: type(matrix(GF(64, 'z'), 2, range(4))) # needs sage.libs.m4ri sage.rings.finite_rings - sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe, needs sage.rings.finite_rings + sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe # needs sage.rings.finite_rings """ diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index b72daee9802..7233892ce2f 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -356,7 +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: # needs sage.libs.linbox (otherwise timeout) sage: density_sum = 0.0 sage: total_count = 0.0 sage: add_sample(ZZ, 5, x=-10, y=10, density=0.75) @@ -366,14 +366,14 @@ 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: # needs sage.libs.linbox (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: ....: add_sample(ZZ, 5, x=20, y=30, density=0.75) - sage: # needs sage.libs.flint (otherwise timeout) + sage: # needs sage.libs.linbox (otherwise timeout) sage: density_sum = 0.0 sage: total_count = 0.0 sage: add_sample(ZZ, 100, x=20, y=30, density=0.75) @@ -396,7 +396,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: # needs sage.libs.flint (otherwise timeout) + sage: # needs sage.libs.linbox (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) From 3cbfb0f410704f484c671b4535141fc06696cc22 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 12 Sep 2023 00:06:40 -0700 Subject: [PATCH 13/19] sage.modules: Update # needs --- src/sage/modules/free_module_integer.py | 2 +- src/sage/modules/vector_double_dense.pyx | 1 + src/sage/modules/vector_real_double_dense.pyx | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index c16e747a53f..5f20d55a89c 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 (o/w timeout) + sage: # needs sage.libs.linbox (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/vector_double_dense.pyx b/src/sage/modules/vector_double_dense.pyx index 063b665922c..f0d9a96f41a 100644 --- a/src/sage/modules/vector_double_dense.pyx +++ b/src/sage/modules/vector_double_dense.pyx @@ -558,6 +558,7 @@ cdef class Vector_double_dense(Vector_numpy_dense): EXAMPLES:: + sage: # needs scipy sage: v = vector(RDF, range(9)) sage: w = vector(CDF, [k+(9-k)*I for k in range(9)]) sage: v.stats_kurtosis() # rel tol 5e-15 diff --git a/src/sage/modules/vector_real_double_dense.pyx b/src/sage/modules/vector_real_double_dense.pyx index bf7c75f1605..e05895f0011 100644 --- a/src/sage/modules/vector_real_double_dense.pyx +++ b/src/sage/modules/vector_real_double_dense.pyx @@ -72,7 +72,7 @@ cdef class Vector_real_double_dense(Vector_double_dense): EXAMPLES:: sage: v = vector(RDF, range(9)) - sage: v.stats_skew() + sage: v.stats_skew() # needs scipy 0.0 """ import scipy.stats From 403ece7da214c3cb3fba058aae33cfa961dce0de Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 12 Sep 2023 18:59:26 -0700 Subject: [PATCH 14/19] sage.matrix: Update # needs --- src/sage/matrix/matrix_space.py | 68 ++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 0d48de627f3..a826efa1f27 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -107,12 +107,12 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: from sage.matrix.matrix_space import get_matrix_class - sage: get_matrix_class(ZZ, 4, 5, False, None) + sage: get_matrix_class(ZZ, 4, 5, False, None) # needs sage.libs.linbox - sage: get_matrix_class(ZZ, 4, 5, True, None) + sage: get_matrix_class(ZZ, 4, 5, True, None) # needs sage.libs.linbox - sage: get_matrix_class(ZZ, 3, 3, False, 'flint') # needs sage.libs.flint + sage: get_matrix_class(ZZ, 3, 3, False, 'flint') # needs sage.libs.linbox sage: get_matrix_class(ZZ, 3, 3, False, 'gap') # needs sage.libs.gap @@ -135,10 +135,10 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: get_matrix_class(RDF, 2, 2, False, 'numpy') # needs numpy - sage: get_matrix_class(CDF, 2, 3, False, 'numpy') # needs numpy + sage: get_matrix_class(CDF, 2, 3, False, 'numpy') # needs numpy sage.rings.complex_double - sage: get_matrix_class(GF(25,'x'), 4, 4, False, 'meataxe') # optional - meataxe, needs sage.rings.finite_rings + 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 @@ -158,9 +158,9 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): 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 - sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-float') # needs sage.libs.linbox + ValueError: 'm4ri' matrices are only available for fields of characteristic 2 + and order <= 65536 + sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-float') Traceback (most recent call last): ... ValueError: 'linbox-float' matrices can only deal with order < 256 @@ -183,7 +183,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: type(matrix(GF(64, 'z'), 2, range(4))) # needs sage.libs.m4ri sage.rings.finite_rings - sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe # needs sage.rings.finite_rings + sage: type(matrix(GF(125, 'z'), 2, range(4))) # optional - meataxe, needs sage.rings.finite_rings """ @@ -496,7 +496,7 @@ class MatrixSpace(UniqueRepresentation, Parent): Check that different implementations play together as expected:: - sage: # needs sage.libs.flint + sage: # needs sage.libs.linbox sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') sage: type(M1(range(4))) @@ -769,7 +769,7 @@ def _has_default_implementation(self): sage: MatrixSpace(ZZ, 2, implementation='generic')._has_default_implementation() False - sage: MatrixSpace(ZZ, 2, implementation='flint')._has_default_implementation() # needs sage.libs.flint + sage: MatrixSpace(ZZ, 2, implementation='flint')._has_default_implementation() # needs sage.libs.linbox True """ default = get_matrix_class(self.base_ring(), self.nrows(), self.ncols(), self.is_sparse(), None) @@ -806,14 +806,14 @@ def _copy_zero(self): EXAMPLES:: sage: MS = MatrixSpace(GF(2), 20, 20) - sage: MS._copy_zero # needs sage.rings.finite_rings + sage: MS._copy_zero False sage: MS = MatrixSpace(GF(3), 20, 20) - sage: MS._copy_zero # needs sage.rings.finite_rings + sage: MS._copy_zero True sage: MS = MatrixSpace(GF(3), 200, 200) - sage: MS._copy_zero # needs sage.rings.finite_rings + sage: MS._copy_zero False sage: MS = MatrixSpace(ZZ,200,200) @@ -880,8 +880,9 @@ def _element_constructor_(self, entries, **kwds): [1 2] [3 4] + sage: # needs sage.modular sage: MS = MatrixSpace(ZZ, 2) - sage: g = Gamma0(5)([1,1,0,1]) # needs sage.modular + sage: g = Gamma0(5)([1,1,0,1]) sage: MS(g) [1 1] [0 1] @@ -901,11 +902,14 @@ def _element_constructor_(self, entries, **kwds): Ensure that :trac:`12020` is fixed:: - sage: rings = [ZZ, QQ, RealField(100), ComplexField(100), RDF, CDF] + sage: rings = [ZZ, QQ, RDF] + sage: rings.extend([RealField(100), ComplexField(100)] # needs sage.rings.real_mpfr + sage: rings.append(CDF) # needs sage.rings.complex_double sage: rings.append(PolynomialRing(QQ, 'x')) - sage: rings.append(PolynomialRing(CC, 2, 'x')) + sage: rings.append(PolynomialRing(CC, 2, 'x')) # needs sage.rings.real_mpfr 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: rings.extend([GF(2), GF(11)] + sage: rings.extend([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)]) # needs sage.rings.number_field sage: for R in rings: @@ -1017,7 +1021,8 @@ def construction(self): sage: A.parent().construction() (MatrixFunctor, Integer Ring) sage: A.parent().construction()[0](QQ['x']) - Full MatrixSpace of 2 by 2 sparse matrices over Univariate Polynomial Ring in x over Rational Field + Full MatrixSpace of 2 by 2 sparse matrices over + Univariate Polynomial Ring in x over Rational Field sage: parent(A/2) Full MatrixSpace of 2 by 2 sparse matrices over Rational Field """ @@ -1202,7 +1207,7 @@ def _coerce_map_from_(self, S): poset):: sage: S = [] - sage: S += [MatrixSpace(ZZ, 3, implementation='flint')] # needs sage.libs.flint + sage: S += [MatrixSpace(ZZ, 3, implementation='flint')] # needs sage.libs.linbox sage: S += [MatrixSpace(ZZ, 3, implementation='generic')] sage: S += [MatrixSpace(ZZ, 3, implementation='gap')] # needs sage.libs.gap sage: S += [MatrixSpace(ZZ, 3, sparse=True)] @@ -1214,7 +1219,7 @@ def _coerce_map_from_(self, S): ....: else: ....: mult += ' ' ....: mult += '\n' - sage: print(mult) # needs sage.libs.flint sage.libs.gap + sage: print(mult) # needs sage.libs.linbox sage.libs.gap XXXX X X XX @@ -1294,7 +1299,7 @@ def _repr_(self): sage: MS Full MatrixSpace of 2 by 4 sparse matrices over Integer Ring - sage: MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.flint + sage: MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.linbox 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) @@ -1810,10 +1815,10 @@ def identity_matrix(self): Check different implementations:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.flint + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.linbox sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1.identity_matrix()) # needs sage.libs.flint + sage: type(M1.identity_matrix()) # needs sage.libs.linbox sage: type(M2.identity_matrix()) @@ -1868,10 +1873,10 @@ def diagonal_matrix(self, entries): Check different implementations:: - sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.flint + sage: M1 = MatrixSpace(ZZ, 2, implementation='flint') # needs sage.libs.linbox sage: M2 = MatrixSpace(ZZ, 2, implementation='generic') - sage: type(M1.diagonal_matrix([1, 2])) # needs sage.libs.flint + sage: type(M1.diagonal_matrix([1, 2])) # needs sage.libs.linbox sage: type(M2.diagonal_matrix([1, 2])) @@ -2063,6 +2068,8 @@ def matrix(self, x=None, **kwds): sage: MS([[1],[2]]) [1] [2] + + sage: # needs sage.rings.real_mpfr sage: MS = MatrixSpace(CC, 2, 1) sage: x = polygen(ZZ, 'x') sage: F = NumberField(x^2 + 1, name='x') # needs sage.rings.number_field @@ -2489,10 +2496,10 @@ 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') # needs sage.libs.linbox 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') # needs sage.libs.linbox sage: tinv(QQ, sparse=False, implementation='generic') sage: tinv(GF(11), sparse=True) sage: tinv(GF(11), sparse=False) @@ -2504,9 +2511,8 @@ def _test_trivial_matrices_inverse(ring, sparse=True, implementation=None, check sage: # needs scipy sage: tinv(RDF, sparse=True) sage: tinv(RDF, sparse=False) - sage: tinv(CDF, sparse=True) - sage: tinv(CDF, sparse=False) - + sage: tinv(CDF, sparse=True) # needs sage.rings.complex_double + sage: tinv(CDF, sparse=False) # needs sage.rings.complex_double 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) From fabdf8624a38367e77b4ac7db3264055d55d10c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 22:27:42 -0700 Subject: [PATCH 15/19] Update # needs --- src/sage/matrix/matrix_space.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index a826efa1f27..a184eb7f708 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -160,7 +160,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): ... ValueError: 'm4ri' matrices are only available for fields of characteristic 2 and order <= 65536 - sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-float') + sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-float') # needs sage.libs.linbox Traceback (most recent call last): ... ValueError: 'linbox-float' matrices can only deal with order < 256 @@ -903,7 +903,7 @@ def _element_constructor_(self, entries, **kwds): Ensure that :trac:`12020` is fixed:: sage: rings = [ZZ, QQ, RDF] - sage: rings.extend([RealField(100), ComplexField(100)] # needs sage.rings.real_mpfr + sage: rings.extend([RealField(100), ComplexField(100)]) # needs sage.rings.real_mpfr sage: rings.append(CDF) # needs sage.rings.complex_double sage: rings.append(PolynomialRing(QQ, 'x')) sage: rings.append(PolynomialRing(CC, 2, 'x')) # needs sage.rings.real_mpfr From 119673d6f1e39044f74ad3c5dc1bc4207ddbb0a5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 11:19:28 -0700 Subject: [PATCH 16/19] sage.matrix: Update # needs --- 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 80d06af7cbe..a40fbdb4eae 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -7460,8 +7460,8 @@ cdef class Matrix(Matrix1): sage: M.eigenvalue_multiplicity(1) 0 - sage: M = posets.DiamondPoset(5).coxeter_transformation() # needs sage.graphs - sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] # needs sage.graphs + sage: M = posets.DiamondPoset(5).coxeter_transformation() # needs sage.graphs sage.libs.flint + sage: [M.eigenvalue_multiplicity(x) for x in [-1, 1]] # needs sage.graphs sage.libs.flint [3, 2] TESTS:: From e23670dd13a1139747541d197075008fec990200 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Sep 2023 11:21:39 -0700 Subject: [PATCH 17/19] sage.modules: Update # needs --- .../free_quadratic_module_integer_symmetric.py | 14 +++++++------- src/sage/modules/vector_space_morphism.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index e4959cc7a55..60f3cc131f6 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -1037,7 +1037,7 @@ def maximal_overlattice(self, p=None): EXAMPLES:: - sage: # needs sage.graphs + sage: # needs sage.graphs sage.libs.pari sage: L = IntegralLattice("A4").twist(25*89) sage: L.maximal_overlattice().determinant() 5 @@ -1048,7 +1048,7 @@ def maximal_overlattice(self, p=None): TESTS:: - sage: # needs sage.libs.flint (otherwise timeout) + sage: # needs sage.libs.flint (otherwise timeout) sage.libs.pari sage: L = IntegralLattice(matrix.diagonal([2,4,4,8])) sage: L.maximal_overlattice().is_even() True @@ -1441,7 +1441,7 @@ def maximum(self): sage: L = IntegralLattice('A2') # needs sage.graphs sage: L.maximum() # needs sage.graphs +Infinity - sage: L.twist(-1).maximum() # needs sage.graphs + sage: L.twist(-1).maximum() # needs sage.graphs sage.libs.pari -2 """ if self.rank() == 0: @@ -1463,7 +1463,7 @@ def LLL(self): EXAMPLES:: sage: L = IntegralLattice('A2') # needs sage.graphs - sage: L.lll() == L # needs sage.graphs + sage: L.lll() == L # needs sage.graphs sage.libs.pari True sage: G = matrix(ZZ, 3, [0,1,0, 1,0,0, 0,0,7]) @@ -1511,9 +1511,9 @@ def short_vectors(self, n, **kwargs): EXAMPLES:: sage: A2 = IntegralLattice('A2') # needs sage.graphs - sage: A2.short_vectors(3) # needs sage.graphs + sage: A2.short_vectors(3) # needs sage.graphs sage.libs.pari [[(0, 0)], [], [(1, 1), (-1, -1), (0, 1), (0, -1), (1, 0), (-1, 0)]] - sage: A2.short_vectors(3,up_to_sign_flag=True) # needs sage.graphs + sage: A2.short_vectors(3, up_to_sign_flag=True) # needs sage.graphs sage.libs.pari [[(0, 0)], [], [(1, 1), (0, 1), (1, 0)]] """ p, m = self.signature_pair() @@ -1602,7 +1602,7 @@ def local_modification(M, G, p, check=True): EXAMPLES:: - sage: # needs sage.graphs + sage: # needs sage.graphs sage.libs.pari sage: from sage.modules.free_quadratic_module_integer_symmetric import local_modification sage: L = IntegralLattice("A3").twist(15) sage: M = L.maximal_overlattice() diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 764c6ac39e5..91f8f6f64b2 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -265,7 +265,7 @@ [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() + sage: zeta.eigenvalues() # needs sage.rings.number_field [3, -2, -2, -2, -2, 1, 1, 1, 1, 1] Equality From 8402a7b35ef8067d73ff3f105cb6a793dcf288ea Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 29 Oct 2023 14:08:32 -0700 Subject: [PATCH 18/19] src/sage/matrix/matrix_space.py: Fix change to doctest --- src/sage/matrix/matrix_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index a184eb7f708..3795ff4b0fa 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -908,7 +908,7 @@ def _element_constructor_(self, entries, **kwds): sage: rings.append(PolynomialRing(QQ, 'x')) sage: rings.append(PolynomialRing(CC, 2, 'x')) # needs sage.rings.real_mpfr sage: rings.append(SR) # needs sage.symbolic - sage: rings.extend([GF(2), GF(11)] + sage: rings.extend([GF(2), GF(11)]) sage: rings.extend([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)]) # needs sage.rings.number_field From c3b6f2fe3e7a79c65999cf376ad3ca61ea31307d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 29 Oct 2023 14:10:26 -0700 Subject: [PATCH 19/19] src/sage/matrix/matrix2.pyx: Fix doctest dataflow warning --- src/sage/matrix/matrix2.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index a40fbdb4eae..997c8118254 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -7159,7 +7159,7 @@ cdef class Matrix(Matrix1): The second eigenvector is contained in the left kernel of `B`:: - sage: (P[1, :] * B).norm() < 1e-14 # needs sage.rings.complex_double sage.symbolic + sage: (P[1, :] * B).norm() < 1e-14 # needs scipy sage.rings.complex_double sage.symbolic True .. SEEALSO::