Skip to content

Commit

Permalink
Trac #20665: Remove code deprecated in #4492
Browse files Browse the repository at this point in the history
Remove code deprecated in #4492. This is documentation proclaiming
removal of code:
1a09d97
7a353920#diff-84e5eb676ee10e60dfb12694d35fcdeeR1798
what exactly should be done with the flat input now? Should dimensions
be mandatory?

Some kind of prehistoric deprecation ! Plus a few pep8 changes.

URL: https://trac.sagemath.org/20665
Reported by: novoselt
Ticket author(s): Frédéric Chapoton
Reviewer(s): Travis Scrimshaw
  • Loading branch information
Release Manager committed Jun 23, 2020
2 parents 409f2a2 + c4e2671 commit 9ae4ffb
Showing 1 changed file with 47 additions and 67 deletions.
114 changes: 47 additions & 67 deletions src/sage/matrix/special.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,24 +818,22 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True):
except TypeError:
raise TypeError('unable to determine number of entries for diagonal matrix construction')
# sometimes catches a negative size
if not nrows is None and nentries > nrows:
if nrows is not None and nentries > nrows:
raise ValueError('number of diagonal matrix entries (%s) exceeds the requested matrix size (%s)' % (nentries, nrows))
if nrows is None:
nrows = nentries

# provide a default ring for an empty list
if not len(entries) and ring is None:
ring = ZZ
ring = ZZ

# Convert entries to a list v over a common ring
from sage.modules.free_module_element import prepare
v, ring = prepare(entries, ring)

# Create a "diagonal" dictionary for matrix constructor
# If nentries < nrows, diagonal is effectively padded with zeros at end
w = {}
for i in range(len(v)):
w[(i, i)] = v[i]
w = {(i, i): v[i] for i in range(len(v))}

# Ship ring, matrix size, dictionary to matrix constructor
if ring is None:
Expand Down Expand Up @@ -880,6 +878,7 @@ def identity_matrix(ring, n=0, sparse=False):
ring = ZZ
return matrix_space.MatrixSpace(ring, n, n, sparse)(1)


@matrix_method
def lehmer(ring, n=0):
r"""
Expand All @@ -906,6 +905,7 @@ def lehmer(ring, n=0):
ring = QQ
return matrix_space.MatrixSpace(ring, n, n).matrix([[min(i, j)/max(i, j) for i in IntegerRange(1, n+1)] for j in IntegerRange(1, n+1)])


@matrix_method
def zero_matrix(ring, nrows=None, ncols=None, sparse=False):
r"""
Expand Down Expand Up @@ -949,6 +949,7 @@ def zero_matrix(ring, nrows=None, ncols=None, sparse=False):
ring = ZZ
return matrix_space.MatrixSpace(ring, nrows, ncols, sparse)(0)


@matrix_method
def ones_matrix(ring, nrows=None, ncols=None, sparse=False):
r"""
Expand Down Expand Up @@ -1351,7 +1352,7 @@ def elementary_matrix(arg0, arg1=None, **kwds):
"""
import sage.structure.element
# determine ring and matrix size
if not arg1 is None and not is_Ring(arg0):
if arg1 is not None and not is_Ring(arg0):
raise TypeError('optional first parameter must be a ring, not {0}'.format(arg0))
scale = kwds.pop('scale', None)
if is_Ring(arg0):
Expand All @@ -1377,9 +1378,9 @@ def elementary_matrix(arg0, arg1=None, **kwds):
col1 = kwds.pop('col1', None)
if row1 is None and col1 is None:
raise ValueError('row1 or col1 must be specified')
if not row1 is None and not col1 is None:
if row1 is not None and col1 is not None:
raise ValueError('cannot specify both row1 and col1')
rowop = not row1 is None
rowop = row1 is not None
if rowop:
opstring = "row"
row2 = kwds.pop('row2', None)
Expand All @@ -1397,16 +1398,16 @@ def elementary_matrix(arg0, arg1=None, **kwds):
row1 = Integer(row1)
except TypeError:
raise TypeError('{0} of elementary matrix must be an integer, not {1}'.format(opstring, row1))
if row1 < 0 or row1 >= n :
if row1 < 0 or row1 >= n:
raise ValueError('{0} of elementary matrix must be positive and smaller than {1}, not {2}'.format(opstring, n, row1))
if not row2 is None:
if row2 is not None:
try:
row2 = Integer(row2)
except TypeError:
raise TypeError('{0} of elementary matrix must be an integer, not {1}'.format(opstring, row2))
if row2 < 0 or row2 >= n :
if row2 < 0 or row2 >= n:
raise ValueError('{0} of elementary matrix must be positive and smaller than {1}, not {2}'.format(opstring, n, row2))
if not scale is None:
if scale is not None:
try:
scale = R(scale)
except Exception:
Expand All @@ -1417,16 +1418,16 @@ def elementary_matrix(arg0, arg1=None, **kwds):
elem = identity_matrix(R, n, sparse=sparse)
if row2 is None and scale is None:
raise ValueError('insufficient parameters provided to construct elementary matrix')
elif not row2 is None and not scale is None:
elif row2 is not None and scale is not None:
if row1 == row2:
raise ValueError('cannot add a multiple of a {0} to itself'.format(opstring))
elem[row1, row2] = scale
elif not row2 is None and scale is None:
elif row2 is not None and scale is None:
elem[row1, row1] = 0
elem[row2, row2] = 0
elem[row1, row2] = 1
elem[row2, row1] = 1
elif row2 is None and not scale is None:
elif row2 is None and scale is not None:
if scale == 0:
raise ValueError('scale parameter of {0} of elementary matrix must be non-zero'.format(opstring))
elem[row1, row1] = scale
Expand All @@ -1435,6 +1436,7 @@ def elementary_matrix(arg0, arg1=None, **kwds):
else:
return elem.transpose()


@matrix_method
def circulant(v, sparse=None):
r"""
Expand Down Expand Up @@ -1563,6 +1565,7 @@ def _determine_block_matrix_grid(sub_matrices):

return (row_heights, col_widths)


def _determine_block_matrix_rows(sub_matrices):
"""
For internal use. This tests if the matrices in sub_matrices
Expand All @@ -1578,7 +1581,7 @@ def _determine_block_matrix_rows(sub_matrices):
Non-zero scalars are considered to be square matrices of any size,
and zeroes are considered to be zero matrices of any size.
A ValueError is raised if there is insufficient or
A ``ValueError`` is raised if there is insufficient or
conflicting information.
TESTS::
Expand All @@ -1593,9 +1596,8 @@ def _determine_block_matrix_rows(sub_matrices):
([2, 2], [0, 0], 4)
"""
total_width = None

row_heights = [ None ] * len(sub_matrices)
zero_widths = [ 0 ] * len(sub_matrices)
row_heights = [None] * len(sub_matrices)
zero_widths = [0] * len(sub_matrices)

# We first do a pass to see if we can determine the width
unknowns = False
Expand Down Expand Up @@ -1667,7 +1669,7 @@ def _determine_block_matrix_rows(sub_matrices):
elif zero_state == 2:
zero_state = 3
else:
scalars += 1
scalars += 1

remaining_width = total_width - width
# This remaining width has to be split over the
Expand All @@ -1688,7 +1690,7 @@ def _determine_block_matrix_rows(sub_matrices):
# if we don't know the height, and there are zeroes,
# we can't determine the height
raise ValueError("insufficient information to determine submatrix heights")
elif total_width % len(R) != 0:
elif total_width % len(R):
raise ValueError("incompatible submatrix widths")
else:
height = int(total_width / len(R))
Expand Down Expand Up @@ -1844,32 +1846,14 @@ def block_matrix(*args, **kwds):
...
ValueError: insufficient information to determine submatrix widths
Historically, giving only a flat list of submatrices, whose number
was a perfect square, would create a new matrix by laying out the submatrices
in a square grid. This behavior is now deprecated. ::
Giving only a flat list of submatrices does not work::
sage: A = matrix(2, 3, range(6))
sage: B = matrix(3, 3, range(9))
sage: block_matrix([A, A, B, B])
doctest:...: DeprecationWarning: invocation of block_matrix with just a list whose length is a perfect square is deprecated. See the documentation for details.
[0 1 2|0 1 2]
[3 4 5|3 4 5]
[-----+-----]
[0 1 2|0 1 2]
[3 4 5|3 4 5]
[6 7 8|6 7 8]
Historically, a flat list of matrices whose number is not a perfect square,
with no specification of the number of rows or columns, would raise an error.
This behavior continues, but could be removed when the deprecation above is
completed. ::
sage: A = matrix(2, 3, range(6))
sage: B = matrix(3, 3, range(9))
sage: block_matrix([A, A, A, B, B, B])
Traceback (most recent call last):
...
ValueError: must specify nrows or ncols for non-square block matrix.
ValueError: must specify either nrows or ncols
TESTS::
Expand Down Expand Up @@ -1971,24 +1955,19 @@ def block_matrix(*args, **kwds):
else:
# A flat list
# determine the block dimensions
n = ZZ(len(sub_matrices))
n = len(sub_matrices)
if nrows is None:
if ncols is None:
if n.is_square():
import warnings
warnings.warn("invocation of block_matrix with just a list whose length is a perfect square is deprecated. See the documentation for details.", DeprecationWarning, stacklevel=2)
nrows = ncols = n.sqrt()
else:
# this form (ie just a flat list) could be allowed once deprecated invocation (above) goes away
raise ValueError("must specify nrows or ncols for non-square block matrix.")
raise ValueError("must specify either nrows or ncols")
else:
nrows = int(n/ncols)
nrows = n // ncols
elif ncols is None:
ncols = int(n/nrows)
ncols = n // nrows
if nrows * ncols != n:
raise ValueError("given number of rows (%s), columns (%s) incompatible with number of submatrices (%s)" % (nrows, ncols, n))
# Now create a list of lists from this
sub_matrices = [ sub_matrices[i*ncols : (i+1)*ncols] for i in range(nrows) ]
sub_matrices = [sub_matrices[i * ncols: (i + 1) * ncols]
for i in range(nrows)]

# At this point sub_matrices is a list of lists

Expand Down Expand Up @@ -2021,7 +2000,6 @@ def block_matrix(*args, **kwds):
if subdivide:
raise ValueError(e)


if col_widths is None:
# Try placing the matrices in rows instead
# (Only if subdivide is False)
Expand Down Expand Up @@ -2696,21 +2674,20 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100):
matrix.add_multiple_of_row(0, randint(1,rows-1), randint(-3,3))
else:
if rank == 1: # would be better just to have a special generator...
tries = 0
while max(map(abs,matrix.list())) >= upper_bound:
matrix = random_rref_matrix(parent, rank)
tries += 1
if tries > max_tries: # to prevent endless attempts
raise ValueError("tried "+str(max_tries)+" times to get a rank 1 random matrix. Try bigger upper_bound?")
matrix_copy = matrix

rrr = range(len(matrix.pivots())-1,-1,-1)
for pivots in rrr:
tries = 0
while max(abs(c) for c in matrix.list()) >= upper_bound:
matrix = random_rref_matrix(parent, rank)
tries += 1
if tries > max_tries: # to prevent endless attempts
raise ValueError("tried "+str(max_tries)+" times to get a rank 1 random matrix. Try bigger upper_bound?")
matrix_copy = matrix

for pivots in range(len(matrix.pivots()) - 1, -1, -1):
# keep track of the pivot column positions from the pivot column with the largest index to
# the one with the smallest.
row_index=0
row_index = 0
tries = 0
while row_index<rows:
while row_index < rows:
# To each row in a pivot column add a scalar multiple of the pivot row.
# for full rank, square matrices, using only this row operation preserves the determinant of 1.
if pivots!=row_index:
Expand Down Expand Up @@ -2750,6 +2727,7 @@ def random_echelonizable_matrix(parent, rank, upper_bound=None, max_tries=100):
matrix.add_multiple_of_row(0,randint(1,rows-1),ring.random_element())
return matrix


@matrix_method
def random_subspaces_matrix(parent, rank=None):
r"""
Expand Down Expand Up @@ -2937,7 +2915,8 @@ def random_subspaces_matrix(parent, rank=None):
# By multiplying the B matrix by J.inverse() we hide the B matrix of the
# solution using row operations required to change the solution K matrix to
# the identity matrix.
return J.inverse()*B
return J.inverse() * B


@matrix_method
def random_unimodular_matrix(parent, upper_bound=None, max_tries=100):
Expand Down Expand Up @@ -3516,7 +3495,7 @@ def hilbert(dim, ring=QQ):
[1/5 1/6 1/7 1/8 1/9]
"""
def entries(i, j):
return 1 / (i + j + 1)
return ZZ.one() / (i + j + 1)
return matrix(entries, nrows=dim, ncols=dim, ring=ring)


Expand Down Expand Up @@ -3664,6 +3643,7 @@ def hankel(c, r=None, ring=None):
m = len(c)
r = [0] * (m - 1) if r is None else list(r)
n = len(r)

def entries(i):
return c[i] if i < m else r[i - m]
return matrix(lambda i, j: entries(i + j), nrows=m, ncols=n + 1, ring=ring)

0 comments on commit 9ae4ffb

Please sign in to comment.