diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index f27497a437c..5bc4e4e116e 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -818,14 +818,14 @@ 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 @@ -833,9 +833,7 @@ def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True): # 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: @@ -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""" @@ -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""" @@ -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""" @@ -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): @@ -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) @@ -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: @@ -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 @@ -1435,6 +1436,7 @@ def elementary_matrix(arg0, arg1=None, **kwds): else: return elem.transpose() + @matrix_method def circulant(v, sparse=None): r""" @@ -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 @@ -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:: @@ -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 @@ -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 @@ -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)) @@ -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:: @@ -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 @@ -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) @@ -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