Ticket #13678: 13678-matrix-methods_vb.patch

File 13678-matrix-methods_vb.patch, 10.3 KB (added by vbraun, 9 years ago)

Improved patch

  • sage/matrix/constructor.py

    # HG changeset patch
    # User Robert Bradshaw <robertwb@math.washington.edu>
    # Date 1351720134 25200
    # Node ID d7dba156b1c8ffe5460fa4c59fb7614ff1053b16
    # Parent  4b00f434bdd1bcfcb00c1cb8738ccaf866b4aa91
    Add identity, random, etc. methods to matrix constructor object.
    
    diff --git a/sage/matrix/constructor.py b/sage/matrix/constructor.py
    a b  
    3131
    3232import sage.categories.pushout
    3333
    34 def matrix(*args, **kwds):
     34def matrix_method(*function, **kwds):
    3535    """
    36     Create a matrix.
    37    
    38     INPUT: The matrix command takes the entries of a matrix, optionally
     36    Allows a function to be tab-completed on the global matrix
     37    constructor object.
     38
     39    INPUT:
     40
     41    - ``*function`` -- a single argument. The function that is being
     42      decorated.
     43
     44    - ``**kwds`` -- a single optional keyword argument
     45      ``name=<string>``. The name of the corresponding method in the
     46      global matrix constructor object. If not given, it is derived
     47      from the function name.
     48
     49    EXAMPLES::
     50
     51        sage: from sage.matrix.constructor import matrix_method
     52        sage: def foo_matrix(n): return matrix.diagonal(range(n))
     53        sage: matrix_method(foo_matrix)
     54        <function foo_matrix at ...>
     55        sage: matrix.foo(5)
     56        [0 0 0 0 0]
     57        [0 1 0 0 0]
     58        [0 0 2 0 0]
     59        [0 0 0 3 0]
     60        [0 0 0 0 4]
     61        sage: matrix_method(foo_matrix, name='bar')
     62        <function foo_matrix at ...>
     63        sage: matrix.bar(3)
     64        [0 0 0]
     65        [0 1 0]
     66        [0 0 2]
     67    """
     68    name = kwds.get('name', None)
     69    if function:
     70        func = function[0]
     71        if name is None:
     72            name = func.__name__.replace('matrix', '').strip('_')
     73        setattr(matrix, name, func)
     74        return func
     75    else:
     76        return lambda func:matrix_method(func, name=name)
     77
     78
     79def _matrix_constructor(*args, **kwds):
     80    """
     81    Create a matrix. 
     82
     83    This is the class of the ``matrix`` callable object::
     84
     85        sage: matrix([[1,2],[3,4]])
     86        [1 2]
     87        [3 4]
     88
     89    It also contains methods to create special types of matrices, see
     90    ``matrix.[tab]`` for more options. For example::
     91
     92        sage: matrix.identity(2)
     93        [1 0]
     94        [0 1]
     95
     96    INPUT:
     97
     98    The matrix command takes the entries of a matrix, optionally
    3999    preceded by a ring and the dimensions of the matrix, and returns a
    40100    matrix.
    41101   
     
    668728    return matrix_space.MatrixSpace(ring, nrows, ncols, sparse=sparse)(entries)
    669729       
    670730
     731class MatrixFactory(object):
     732    """
     733    The class of the ``matrix`` object.
     734   
     735    See :func:`_matrix_constructor` for the implementation of the call
     736    interface.
     737
     738    EXAMPLES::
     739       
     740        sage: from sage.misc.sageinspect import sage_getdoc, sage_getsource
     741        sage: sage_getdoc(matrix)       # used in output of matrix?
     742        '   Create a matrix.\n\n   This object implements the "matrix" ...'
     743        sage: sage_getsource(matrix)    # used in output of matrix??
     744        'class MatrixFactory(object):...'
     745    """
     746
     747    __doc__ = _matrix_constructor.__doc__
     748
     749    def __call__(self, *args, **kwds):
     750        """
     751        This method is called by ``matrix()``
     752        """
     753        return _matrix_constructor(*args, **kwds)
     754
     755matrix = MatrixFactory()
     756Matrix = matrix
     757
    671758
    672759def prepare(w):
    673760    """
     
    799886        return 0
    800887    return max([0] + [ij[1] for ij in d.keys()]) + 1   
    801888
    802 Matrix = matrix
    803 
     889
     890@matrix_method
    804891def column_matrix(*args, **kwds):
    805892    r"""
    806893    Constructs a matrix, and then swaps rows for columns and columns for rows.
    807894
    808895    .. note::
    809896
    810         Linear algebra in Sage favors rows over columns.  So, generally,
    811         when creating a matrix, input vectors and lists are treated as rows.
    812         This function is a convenience that turns around this convention
    813         when creating a matrix.  If you are not familiar with the usual
    814         :func:`matrix` constructor, you might want to consider it first.
     897        Linear algebra in Sage favors rows over columns.  So,
     898        generally, when creating a matrix, input vectors and lists are
     899        treated as rows.  This function is a convenience that turns
     900        around this convention when creating a matrix.  If you are not
     901        familiar with the usual :class:`matrix <MatrixFactory>`
     902        constructor, you might want to consider it first.
    815903
    816904    INPUT:
    817905
    818     Inputs are almost exactly the same as for the :func:`matrix`
    819     constructor, which are documented there.  But see examples below
    820     for how dimensions are handled.
     906    Inputs are almost exactly the same as for the :class:`matrix
     907    <MatrixFactory>` constructor, which are documented there.  But see
     908    examples below for how dimensions are handled.
    821909
    822910    OUTPUT:
    823911
    824     Output is exactly the transpose of what the :func:`matrix`
    825     constructor would return.  In other words, the ``matrix``
    826     constructor builds a matrix and then this function exchanges
    827     rows for columns, and columns for rows.
     912    Output is exactly the transpose of what the :class:`matrix
     913    <MatrixFactory>` constructor would return.  In other words, the
     914    ``matrix`` constructor builds a matrix and then this function
     915    exchanges rows for columns, and columns for rows.
    828916
    829917    EXAMPLES:
    830918
    831     The most compelling use of this function is when you have
    832     a collection of lists or vectors that you would like to
    833     become the columns of a matrix. In almost any other
    834     situation, the :func:`matrix` constructor can probably do
    835     the job just as easily, or easier. ::
     919    The most compelling use of this function is when you have a
     920    collection of lists or vectors that you would like to become the
     921    columns of a matrix. In almost any other situation, the
     922    :class:`matrix <MatrixFactory>` constructor can probably do the
     923    job just as easily, or easier. ::
    836924
    837925        sage: col_1 = [1,2,3]
    838926        sage: col_2 = [4,5,6]
     
    886974    return matrix(*args, **kwds).transpose()
    887975
    888976
     977@matrix_method
    889978def random_matrix(ring, nrows, ncols=None, algorithm='randomize', *args, **kwds):
    890979    r"""
    891980    Return a random matrix with entries in a specified ring, and possibly with additional properties.
     
    12621351        raise ValueError('random matrix algorithm "%s" is not recognized' % algorithm)
    12631352
    12641353
     1354@matrix_method
    12651355def diagonal_matrix(arg0=None, arg1=None, arg2=None, sparse=True):
    12661356    r"""
    12671357    Return a square matrix with specified diagonal entries, and zeros elsewhere.
     
    14811571        return matrix(ring, nrows, nrows, w, sparse=sparse)
    14821572
    14831573
     1574@matrix_method
    14841575def identity_matrix(ring, n=0, sparse=False):
    14851576    r"""
    14861577    Return the `n \times n` identity matrix over the given
     
    15171608    return matrix_space.MatrixSpace(ring, n, n, sparse)(1)
    15181609
    15191610
     1611@matrix_method
    15201612def zero_matrix(ring, nrows, ncols=None, sparse=False):
    15211613    r"""
    15221614    Return the `nrows \times ncols` zero matrix over the given
     
    15521644        ring = rings.ZZ
    15531645    return matrix_space.MatrixSpace(ring, nrows, ncols, sparse)(0)
    15541646
     1647
     1648@matrix_method
    15551649def ones_matrix(ring, nrows=None, ncols=None, sparse=False):
    15561650    r"""
    15571651    Return a matrix with all entries equal to 1.
     
    16431737    one = ring(1)
    16441738    return matrix_space.MatrixSpace(ring, nrows, ncols, sparse).matrix([one]*nents)
    16451739
     1740
     1741@matrix_method
    16461742def elementary_matrix(arg0, arg1=None, **kwds):
    16471743    r"""
    16481744    Creates a square matrix that corresponds to a row operation or a column operation.
     
    22472343    # If we got this far, then everything fits
    22482344    return (row_heights, zero_widths, total_width)
    22492345
     2346
     2347@matrix_method
    22502348def block_matrix(*args, **kwds):
    22512349    r"""
    22522350    Returns a larger matrix made by concatenating submatrices
     
    26202718
    26212719    return big
    26222720
     2721
     2722@matrix_method
    26232723def block_diagonal_matrix(*sub_matrices, **kwds):
    26242724    """
    26252725    Create a block matrix whose diagonal block entries are given by
     
    26552755        entries[n*i+i] = sub_matrices[i]
    26562756    return block_matrix(n, n, entries, **kwds)
    26572757
     2758
     2759@matrix_method
    26582760def jordan_block(eigenvalue, size, sparse=False):
    26592761    r"""
    26602762    Returns the Jordan block for the given eigenvalue with given size.
     
    26972799        block[i,i+1]=1
    26982800    return block
    26992801
     2802
     2803@matrix_method
    27002804def companion_matrix(poly, format='right'):
    27012805    r"""
    27022806    Create a companion matrix from a monic polynomial.
     
    28932997        raise TypeError("unable to find common ring for coefficients from polynomial")
    28942998    return M
    28952999
     3000@matrix_method
    28963001def random_rref_matrix(parent, num_pivots):
    28973002    r"""
    28983003    Generate a matrix in reduced row-echelon form with a specified number of non-zero rows.
     
    30583163                    return_matrix[rest_entries,rest_non_pivot_column]=ring.random_element()
    30593164    return return_matrix
    30603165
     3166@matrix_method
    30613167def random_echelonizable_matrix(parent, rank, upper_bound=None):
    30623168    r"""
    30633169    Generate a matrix of a desired size and rank, over a desired ring, whose reduced
     
    32463352            matrix.add_multiple_of_row(0,randint(1,rows-1),ring.random_element())
    32473353    return matrix
    32483354
     3355@matrix_method
    32493356def random_subspaces_matrix(parent, rank=None):
    32503357    r"""
    32513358    Create a matrix of the designated size and rank whose right and
     
    34273534    # K matrix to the identity matrix.
    34283535    return J.inverse()*B
    34293536
     3537@matrix_method
    34303538def random_unimodular_matrix(parent, upper_bound=None):
    34313539    """
    34323540    Generate a random unimodular (determinant 1) matrix of a desired size over a desired ring.
     
    35263634        return random_matrix(ring, size,algorithm='echelonizable',rank=size, upper_bound=upper_bound)
    35273635
    35283636
     3637@matrix_method
    35293638def random_diagonalizable_matrix(parent,eigenvalues=None,dimensions=None):
    35303639    """
    35313640    Create a random matrix that diagonalizes nicely. 
     
    37723881            eigenvector_matrix.add_multiple_of_row(upper_row,row,randint(-4,4))
    37733882    return eigenvector_matrix*diagonal_matrix*(eigenvector_matrix.inverse())
    37743883
     3884
     3885@matrix_method
    37753886def vector_on_axis_rotation_matrix(v, i, ring=None):
    37763887    r"""
    37773888    Return a rotation matrix `M` such that `det(M)=1` sending the vector
     
    38453956        m = rot * m
    38463957    return m
    38473958
     3959
     3960@matrix_method
    38483961def ith_to_zero_rotation_matrix(v, i, ring=None):
    38493962    r"""
    38503963    Return a rotation matrix that sends the i-th coordinates of the