Ticket #10477: trac_10477-random-vector-constructor-v2.patch

File trac_10477-random-vector-constructor-v2.patch, 6.4 KB (added by rbeezer, 10 years ago)
  • sage/modules/all.py

    # HG changeset patch
    # User Rob Beezer <beezer@ups.edu>
    # Date 1292380286 28800
    # Node ID 9719271d54da17c635d1cc6d27093a936a913e9b
    # Parent  2ca6e12afcc8f36d65ec808a4d0cf0b74a64d2c8
    10477: random vector constructor
    
    diff -r 2ca6e12afcc8 -r 9719271d54da sage/modules/all.py
    a b  
    1717
    1818from free_quadratic_module import FreeQuadraticModule, QuadraticSpace, InnerProductSpace, is_FreeQuadraticModule
    1919
    20 from free_module_element import is_FreeModuleElement, vector, free_module_element, zero_vector
     20from free_module_element import is_FreeModuleElement, vector, free_module_element, zero_vector, random_vector
    2121
    2222from free_module_homspace import is_FreeModuleHomspace
    2323
  • sage/modules/free_module_element.pyx

    diff -r 2ca6e12afcc8 -r 9719271d54da sage/modules/free_module_element.pyx
    a b  
    570570        raise ValueError("elements of a zero vector belong in a ring, not %s" % arg0)
    571571    return vector(arg0, arg1)
    572572
     573def random_vector(ring, degree=None, *args, **kwds):
     574    r"""
     575    Returns a vector (or module element) with random entries.
     576
     577    INPUT:
     578
     579    - ring - default: ``ZZ`` - the base ring for the entries
     580    - degree - a non-negative integer for the number of entries in the vector
     581    - sparse - default: ``False`` - whether to use a sparse implementation
     582    - args, kwds - additional arguments and keywords are passed
     583      to the ``random_element()`` method of the ring
     584
     585    OUTPUT:
     586
     587    A vector, or free module element, with ``degree`` elements
     588    from ``ring``, chosen randomly from the ring according to
     589    the ring's ``random_element()`` method.
     590
     591    .. note::
     592        See below for examples of how random elements are
     593        generated by some common base rings.
     594
     595    EXAMPLES:
     596
     597    First, module elements over the integers.
     598    The default distribution is tightly clustered around -1, 0, 1.
     599    Uniform distributions can be specified by giving bounds, though
     600    the upper bound is never met.  See
     601    :meth:`sage.rings.integer_ring.IntegerRing_class.random_element`
     602    for several other variants. ::
     603
     604        sage: random_vector(10)
     605        (-8, 2, 0, 0, 1, -1, 2, 1, -95, -1)
     606
     607        sage: sorted(random_vector(20))
     608        [-12, -6, -4, -4, -2, -2, -2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 4, 5]
     609
     610        sage: random_vector(ZZ, 20, x=4)
     611        (2, 0, 3, 0, 1, 0, 2, 0, 2, 3, 0, 3, 1, 2, 2, 2, 1, 3, 2, 3)
     612
     613        sage: random_vector(ZZ, 20, x=-20, y=100)
     614        (43, 47, 89, 31, 56, -20, 23, 52, 13, 53, 49, -12, -2, 94, -1, 95, 60, 83, 28, 63)
     615
     616        sage: random_vector(ZZ, 20, distribution="1/n")
     617        (0, -1, -2, 0, -1, -2, 0, 0, 27, -1, 1, 1, 0, 2, -1, 1, -1, -2, -1, 3)
     618
     619    If the ring is not specified, the default is the integers, and
     620    parameters for the random distribution may be passed without using
     621    keywords.  This is a random vector with 20 entries uniformly distributed
     622    between -20 and 100.  ::
     623
     624        sage: random_vector(20, -20, 100)
     625        (70, 19, 98, 2, -18, 88, 36, 66, 76, 52, 82, 99, 55, -17, 82, -15, 36, 28, 79, 18)
     626
     627    Now over the rationals.  Note that bounds on the numerator and
     628    denominator may be specified.  See
     629    :meth:`sage.rings.rational_field.RationalField.random_element`
     630    for documentation. ::
     631
     632        sage: random_vector(QQ, 10)
     633        (0, -1, -4/3, 2, 0, -13, 2/3, 0, -4/5, -1)
     634
     635        sage: random_vector(QQ, 10, num_bound = 15, den_bound = 5)
     636        (-12/5, 9/4, -13/3, -1/3, 1, 5/4, 4, 1, -15, 10/3)
     637
     638    Inexact rings may be used as well.  The reals have
     639    uniform distributions, with the range `(-1,1)` as
     640    the default.  More at:
     641    :meth:`sage.rings.real_mpfr.RealField_class.random_element` ::
     642
     643        sage: random_vector(RR, 5)
     644        (-0.162476075552..., -0.272027441467..., 0.877820717384..., 0.387744557392..., -0.947492937002...)
     645
     646        sage: random_vector(RR, 5, min = 8, max = 14)
     647        (8.64181279757..., 11.7911822725..., 11.5512323803..., 11.4412004296..., 10.5708483184...)
     648
     649    Any ring with a ``random_element()`` method may be used. ::
     650
     651        sage: F = FiniteField(23)
     652        sage: hasattr(F, 'random_element')
     653        True
     654        sage: random_vector(F, 10)
     655        (21, 6, 5, 2, 6, 2, 18, 9, 9, 7)
     656
     657    The default implementation is a dense representation, equivalent to
     658    setting ``sparse=False``. ::
     659
     660        sage: v = random_vector(10)
     661        sage: v.is_sparse()
     662        False
     663
     664        sage: w = random_vector(ZZ, 20, sparse=True)
     665        sage: w.is_sparse()
     666        True
     667
     668    Inputs get checked before constructing the vector. ::
     669
     670        sage: random_vector('junk')
     671        Traceback (most recent call last):
     672        ...
     673        TypeError: degree of a random vector must be an integer, not None
     674
     675        sage: random_vector('stuff', 5)
     676        Traceback (most recent call last):
     677        ...
     678        TypeError: elements of a vector, or module element, must come from a ring, not stuff
     679
     680        sage: random_vector(ZZ, -9)
     681        Traceback (most recent call last):
     682        ...
     683        ValueError: degree of a random vector must be non-negative, not -9
     684    """
     685    if sage.rings.integer.is_Integer(ring) or isinstance(ring,(int,long)):
     686        if not degree is None:
     687            arglist = list(args)
     688            arglist.insert(0, degree)
     689            args = tuple(arglist)
     690        degree = ring
     691        ring = sage.rings.integer_ring.IntegerRing()
     692    if not (sage.rings.integer.is_Integer(degree) or isinstance(degree,(int,long))):
     693        raise TypeError("degree of a random vector must be an integer, not %s" % degree)
     694    if degree < 0:
     695        raise ValueError("degree of a random vector must be non-negative, not %s" % degree)
     696    if not is_Ring(ring):
     697        raise TypeError("elements of a vector, or module element, must come from a ring, not %s" % ring)
     698    if not hasattr(ring, "random_element"):
     699        raise AttributeError("cannot create a random vector since there is no random_element() method for %s" % ring )
     700    sparse = kwds.pop('sparse', False)
     701    entries = [ring.random_element(*args, **kwds) for _ in range(degree)]
     702    return vector(ring, degree, entries, sparse)
     703
    573704cdef class FreeModuleElement(element_Vector):   # abstract base class
    574705    """
    575706    An element of a generic free module.