Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Misc matrix algorithms
Code goes here mainly when it needs access to the internal structure of several classes, and we want to avoid circular cimports.
NOTE: The whole problem of avoiding circular imports -- the reason for existence of this file -- is now a non-issue, since some bugs in Cython were fixed. Probably all this code should be moved into the relevant classes and this file deleted. """ from __future__ import absolute_import
from cysignals.signals cimport sig_on, sig_off
from sage.ext.mod_int cimport * from sage.libs.gmp.mpz cimport * from sage.libs.gmp.mpq cimport * from sage.libs.mpfr cimport *
from sage.libs.flint.fmpz cimport fmpz_set_mpz, fmpz_one from sage.libs.flint.fmpq cimport fmpq_set_mpq, fmpq_canonicalise from sage.libs.flint.fmpq_mat cimport fmpq_mat_entry_num, fmpq_mat_entry_den, fmpq_mat_entry
from sage.arith.rational_reconstruction cimport mpq_rational_reconstruction
from sage.data_structures.binary_search cimport * from sage.modules.vector_integer_sparse cimport * from sage.modules.vector_rational_sparse cimport * from sage.modules.vector_modn_sparse cimport *
from .matrix0 cimport Matrix from .matrix_integer_dense cimport Matrix_integer_dense from .matrix_integer_sparse cimport Matrix_integer_sparse from .matrix_rational_dense cimport Matrix_rational_dense from .matrix_rational_sparse cimport Matrix_rational_sparse
from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ
from sage.rings.integer cimport Integer from sage.arith.all import previous_prime, CRT_basis
from sage.rings.real_mpfr import is_RealField from sage.rings.real_mpfr cimport RealNumber
from sage.misc.misc import verbose, get_verbose
def matrix_integer_dense_rational_reconstruction(Matrix_integer_dense A, Integer N): """ Given a matrix over the integers and an integer modulus, do rational reconstruction on all entries of the matrix, viewed as numbers mod N. This is done efficiently by assuming there is a large common factor dividing the denominators.
INPUT:
A -- matrix N -- an integer
EXAMPLES:
sage: B = ((matrix(ZZ, 3,4, [1,2,3,-4,7,2,18,3,4,3,4,5])/3)%500).change_ring(ZZ) sage: sage.matrix.misc.matrix_integer_dense_rational_reconstruction(B, 500) [ 1/3 2/3 1 -4/3] [ 7/3 2/3 6 1] [ 4/3 1 4/3 5/3]
TESTS:
Check that :trac:`9345` is fixed::
sage: A = random_matrix(ZZ, 3) sage: sage.matrix.misc.matrix_integer_dense_rational_reconstruction(A, 0) Traceback (most recent call last): ... ZeroDivisionError: The modulus cannot be zero """ cdef Matrix_rational_dense R
cdef mpz_t a, bnd, other_bnd, one, denom, tmp cdef mpq_t qtmp cdef Integer _bnd cdef Py_ssize_t i, j cdef int do_it
else: else: # Otherwise have to do it the hard way
finally:
def matrix_integer_sparse_rational_reconstruction(Matrix_integer_sparse A, Integer N): """ Given a sparse matrix over the integers and an integer modulus, do rational reconstruction on all entries of the matrix, viewed as numbers mod N.
EXAMPLES:
sage: A = matrix(ZZ, 3, 4, [(1/3)%500, 2, 3, (-4)%500, 7, 2, 2, 3, 4, 3, 4, (5/7)%500], sparse=True) sage: sage.matrix.misc.matrix_integer_sparse_rational_reconstruction(A, 500) [1/3 2 3 -4] [ 7 2 2 3] [ 4 3 4 5/7]
TESTS:
Check that :trac:`9345` is fixed::
sage: A = random_matrix(ZZ, 3, sparse=True) sage: sage.matrix.misc.matrix_integer_sparse_rational_reconstruction(A, 0) Traceback (most recent call last): ... ZeroDivisionError: The modulus cannot be zero """ cdef Matrix_rational_sparse R
cdef mpq_t t cdef mpz_t a, bnd, other_bnd, one, denom cdef Integer _bnd cdef Py_ssize_t i, j cdef int do_it cdef mpz_vector* A_row cdef mpq_vector* R_row
else: else: # Otherwise have to do it the hard way
finally:
def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, proof=None): """ Returns reduced row-echelon form using a multi-modular algorithm. Does not change self.
REFERENCE: Chapter 7 of Stein's "Explicitly Computing Modular Forms".
INPUT:
- height_guess -- integer or None - proof -- boolean or None (default: None, see proof.linear_algebra or sage.structure.proof). Note that the global Sage default is proof=True
OUTPUT: a pair consisting of a matrix in echelon form and a tuple of pivot positions.
ALGORITHM:
The following is a modular algorithm for computing the echelon form. Define the height of a matrix to be the max of the absolute values of the entries.
Given Matrix A with n columns (self).
0. Rescale input matrix A to have integer entries. This does not change echelon form and makes reduction modulo lots of primes significantly easier if there were denominators. Henceforth we assume A has integer entries.
1. Let c be a guess for the height of the echelon form. E.g., c=1000, e.g., if matrix is very sparse and application is to computing modular symbols.
2. Let M = n * c * H(A) + 1, where n is the number of columns of A.
3. List primes p_1, p_2, ..., such that the product of the p_i is at least M.
4. Try to compute the rational reconstruction CRT echelon form of A mod the product of the p_i. If rational reconstruction fails, compute 1 more echelon forms mod the next prime, and attempt again. Make sure to keep the result of CRT on the primes from before, so we don't have to do that computation again. Let E be this matrix.
5. Compute the denominator d of E. Attempt to prove that result is correct by checking that
H(d*E)*ncols(A)*H(A) < (prod of reduction primes)
where H denotes the height. If this fails, do step 4 with a few more primes.
EXAMPLES:
sage: A = matrix(QQ, 3, 7, [1..21]) sage: from sage.matrix.misc import matrix_rational_echelon_form_multimodular sage: E, pivots = matrix_rational_echelon_form_multimodular(A) sage: E [ 1 0 -1 -2 -3 -4 -5] [ 0 1 2 3 4 5 6] [ 0 0 0 0 0 0 0] sage: pivots (0, 1)
sage: A = matrix(QQ, 3, 4, [0,0] + [1..9] + [-1/2^20]) sage: E, pivots = matrix_rational_echelon_form_multimodular(A) sage: E [ 1 0 0 -10485761/1048576] [ 0 1 0 27262979/4194304] [ 0 0 1 2] sage: pivots (0, 1, 2)
sage: A.echelon_form() [ 1 0 0 -10485761/1048576] [ 0 1 0 27262979/4194304] [ 0 0 1 2] sage: A.pivots() (0, 1, 2) """
cdef Matrix E
else: M = height_guess + 1
else:
# We use denoms=False, since we made self integral by calling clear_denom above.
# a worthwhile check / shortcut.
else: # do not save A since it is bad. verbose("Excluding this prime (bad pivots).", caller_name="multimod echelon") # Find set of best matrices. # recompute product, since may drop bad matrices
# take the linear combination of the lifts of the elements # of Y times coefficients in a
verbose("Not checking validity of result (since proof=False).", level=2, caller_name="multimod echelon") break #end while
###########################
def cmp_pivots(x, y): """ Compare two sequences of pivot columns.
If x is shorter than y, return -1, i.e., x < y, "not as good". If x is longer than y, then x > y, so "better" and return +1. If the length is the same, then x is better, i.e., x > y if the entries of x are correspondingly <= those of y with one being strictly less.
INPUT:
- x, y -- lists or tuples of integers
EXAMPLES:
We illustrate each of the above comparisons. ::
sage: sage.matrix.misc.cmp_pivots([1,2,3], [4,5,6,7]) -1 sage: sage.matrix.misc.cmp_pivots([1,2,3,5], [4,5,6]) 1 sage: sage.matrix.misc.cmp_pivots([1,2,4], [1,2,3]) -1 sage: sage.matrix.misc.cmp_pivots([1,2,3], [1,2,3]) 0 sage: sage.matrix.misc.cmp_pivots([1,2,3], [1,2,4]) 1 """ else:
#######################################
####################################### def hadamard_row_bound_mpfr(Matrix A): """ Given a matrix A with entries that coerce to RR, compute the row Hadamard bound on the determinant.
INPUT:
A -- a matrix over RR
OUTPUT:
integer -- an integer n such that the absolute value of the determinant of this matrix is at most $10^n$.
EXAMPLES:
We create a very large matrix, compute the row Hadamard bound, and also compute the row Hadamard bound of the transpose, which happens to be sharp. ::
sage: a = matrix(ZZ, 2, [2^10000,3^10000,2^50,3^19292]) sage: import sage.matrix.misc sage: sage.matrix.misc.hadamard_row_bound_mpfr(a.change_ring(RR)) 13976 sage: len(str(a.det())) 12215 sage: sage.matrix.misc.hadamard_row_bound_mpfr(a.transpose().change_ring(RR)) 12215
Note that in the above example using RDF would overflow::
sage: b = a.change_ring(RDF) sage: b._hadamard_row_bound() Traceback (most recent call last): ... OverflowError: cannot convert float infinity to integer """ raise TypeError("A must have base field an mpfr real field.")
cdef RealNumber a, b cdef mpfr_t s, d, pr cdef Py_ssize_t i, j
|