Beispiel #1
0
    def random_element(self):
        r"""
        Return a random element in self.

        EXAMPLES::

            sage: F = FreeGroup(3)
            sage: F.subset(3).random_element()  # random
            aBa
        """
        if self._n == 0:
            return self._free_group.one()

        alphabet = self._free_group.alphabet().list()
        D = len(alphabet)
        d = D/2
        from sage.misc.prandom import randint
        j = randint(0,D-1)
        data = [alphabet[j]]
        
        while len(data) != self._n:
            if j < d:
                i = j + d
            else:
                i = j - d
            j = randint(0,D-2)
            if j >= i:
                j += 1
            data.append(alphabet[j])
        
        return self(data, check=False)
Beispiel #2
0
def random_integer_vector(n, length):
    r"""
    Give a random list of length *length*, consisting of nonnegative
    integers that sum to *n*.

    This is an approximation to IntegerVectors(n, length).random_element().
    That gives values uniformly at random, but might be slow; this
    routine is not uniform, but should always be fast.  

    (This routine is uniform if *length* is 1 or 2; for longer vectors,
    we prefer approximately balanced vectors, where all the values
    are around `n/{length}`.)

    EXAMPLES::

        sage: from sage.symbolic.random_tests import *
        sage: random_integer_vector(100, 2)
        [11, 89]
        sage: random_integer_vector(100, 2)
        [51, 49]
        sage: random_integer_vector(100, 2)
        [4, 96]
        sage: random_integer_vector(10000, 20)
        [332, 529, 185, 738, 82, 964, 596, 892, 732, 134, 834, 765, 398, 608, 358, 300, 652, 249, 586, 66]
    """
    if length == 0:
        return []
    elif length == 1:
        return [n]
    elif length == 2:
        v = randint(0, n)
        return [v, n-v]
    else:
        v = randint(0, 2*n//length)
        return [v] + random_integer_vector(n-v, length-1)
Beispiel #3
0
def random_chain_complex(level=1):
    """
    Return a random chain complex, defined by specifying a single
    random matrix in a random degree, with differential of degree
    either 1 or -1.  The matrix is randomly sparse or dense.

    :param level: measure of complexity: the larger this is, the
      larger the matrix can be, and the larger its degree can be in
      the chain complex.
    :type level: positive integer; optional, default 1

    EXAMPLES::

        sage: from sage.homology.tests import random_chain_complex
        sage: C = random_chain_complex()
        sage: C
        Chain complex with at most 2 nonzero terms over Integer Ring
        sage: C.degree_of_differential() # random: either 1 or -1
        1
    """
    bound = 50*level
    nrows = randint(0, bound)
    ncols = randint(0, bound)
    sparseness = bool(randint(0, 1))
    mat = random_matrix(ZZ, nrows, ncols, sparse=sparseness)
    dim = randint(-bound, bound)
    deg = 2 * randint(0, 1) - 1  # -1 or 1
    return ChainComplex({dim: mat}, degree = deg)
Beispiel #4
0
def random_simplicial_complex(level=1, p=0.5):
    """
    Return a random simplicial complex.

    :param level: measure of complexity: the larger this is, the more
      vertices and therefore the larger the possible dimension of the
      complex.
    :type level: positive integer; optional, default 1
    :param p: probability, passed on to ``simplicial_complexes.RandomComplex``
    :type p: float between 0 and 1; optional; default 0.5

    EXAMPLES::

        sage: from sage.homology.tests import random_simplicial_complex
        sage: X = random_simplicial_complex()
        sage: X # random
        Simplicial complex with vertex set (0, 1, 2, 3, 4, 5, 6, 7) and 31 facets
        sage: X.dimension() < 11
        True
    """
    from sage.misc.prandom import randint
    from sage.homology.examples import simplicial_complexes
    n = randint(2, 4*level)
    dim = randint(1, n)
    return simplicial_complexes.RandomComplex(n, dim, p)
Beispiel #5
0
    def transmit_unsafe(self, message):
        r"""
        Returns ``message`` with as many errors as ``self._number_errors`` in it, and as many erasures
        as ``self._number_erasures`` in it.

        If ``self._number_errors`` was passed as an tuple for the number of errors, it will
        pick a random integer between the bounds of the tuple and use it as the number of errors.
        It does the same with ``self._number_erasures``.

        All erased positions are set to 0 in the transmitted message.
        It is guaranteed that the erasures and the errors will never overlap:
        the received message will always contains exactly as many errors and erasures
        as expected.

        This method does not check if ``message`` belongs to the input space of``self``.

        INPUT:

        - ``message`` -- a vector

        OUTPUT:

        - a couple of vectors, namely:

            - the transmitted message, which is ``message`` with erroneous and erased positions
            - the erasure vector, which contains ``1`` at the erased positions of the transmitted message
              , 0 elsewhere.

        EXAMPLES::

            sage: F = GF(59)^11
            sage: n_err, n_era = 2, 2
            sage: Chan = channels.ErrorErasureChannel(F, n_err, n_era)
            sage: msg = F((3, 14, 15, 9, 26, 53, 58, 9, 7, 9, 3))
            sage: set_random_seed(10)
            sage: Chan.transmit_unsafe(msg)
            ((31, 0, 15, 9, 38, 53, 58, 9, 0, 9, 3), (0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0))
        """
        number_errors = randint(*self.number_errors())
        number_erasures = randint(*self.number_erasures())
        V = self.input_space()
        n = V.dimension()
        zero = V.base_ring().zero()

        errors = sample(xrange(n), number_errors + number_erasures)
        error_positions   = errors[:number_errors]
        erasure_positions = errors[number_errors:]

        error_vector = random_error_vector(n, V.base_ring(), error_positions)
        erasure_vector = random_error_vector(n , GF(2), erasure_positions)

        message = message + error_vector

        for i in erasure_positions:
            message[i] = zero
        return message, erasure_vector
Beispiel #6
0
def random_even_arithgroup(index,nu2_max=None,nu3_max=None):
    r"""
    Return a random even arithmetic subgroup

    EXAMPLES::

        sage: import sage.modular.arithgroup.tests as tests
        sage: G = tests.random_even_arithgroup(30); G # random
        Arithmetic subgroup of index 30
        sage: G.is_even()
        True
    """
    from sage.groups.perm_gps.permgroup import PermutationGroup

    test = False

    if nu2_max is None:
        nu2_max = index//5
    elif nu2_max == 0:
        assert index%2 == 0
    if nu3_max is None:
        nu3_max = index//7
    elif nu3_max == 0:
        assert index%3 == 0

    while not test:
        nu2 = prandom.randint(0,nu2_max)
        nu2 = index%2 + nu2*2
        nu3 = prandom.randint(0,nu3_max)
        nu3 = index%3 + nu3*3

        l = range(1,index+1)
        prandom.shuffle(l)
        S2 = []
        for i in xrange(nu2):
            S2.append((l[i],))
        for i in xrange(nu2,index,2):
            S2.append((l[i],l[i+1]))
        prandom.shuffle(l)
        S3 = []
        for i in xrange(nu3):
            S3.append((l[i],))
        for i in xrange(nu3,index,3):
            S3.append((l[i],l[i+1],l[i+2]))
        G = PermutationGroup([S2,S3])
        test = G.is_transitive()

    return ArithmeticSubgroup_Permutation(S2=S2,S3=S3)
Beispiel #7
0
    def random_element(self):
        """
        Return a random element of this dual group.

        EXAMPLES::

            sage: G = AbelianGroup([2,3,9])
            sage: Gd = G.dual_group(base_ring=CC)
            sage: Gd.random_element()
            X1^2

            sage: N = 43^2-1
            sage: G = AbelianGroup([N],names="a")
            sage: Gd = G.dual_group(names="A", base_ring=CC)
            sage: a, = G.gens()
            sage: A, = Gd.gens()
            sage: x = a^(N/4); y = a^(N/3); z = a^(N/14)
            sage: X = A*Gd.random_element(); X
            A^615
            sage: len([a for a in [x,y,z] if abs(X(a)-1)>10^(-8)])
            2
        """
        from sage.misc.prandom import randint
        result = self.one()
        for g in self.gens():
            order = g.order()
            result *= g**(randint(0,order))
        return result
Beispiel #8
0
    def transmit_unsafe(self, message):
        r"""
        Returns ``message`` with as many errors as ``self._number_errors`` in it.

        If ``self._number_errors`` was passed as a tuple for the number of errors, it will
        pick a random integer between the bounds of the tuple and use it as the number of errors.

        This method does not check if ``message`` belongs to the input space of``self``.

        INPUT:

        - ``message`` -- a vector

        OUTPUT:

        - a vector of the output space

        EXAMPLES::

            sage: F = GF(59)^6
            sage: n_err = 2
            sage: Chan = channels.StaticErrorRateChannel(F, n_err)
            sage: msg = F((4, 8, 15, 16, 23, 42))
            sage: set_random_seed(10)
            sage: Chan.transmit_unsafe(msg)
            (4, 8, 4, 16, 23, 53)
        """
        w = copy(message)
        number_errors = randint(*self.number_errors())
        V = self.input_space()
        for i in sample(xrange(V.dimension()), number_errors):
            w[i] = V.base_ring().random_element()
        return w
Beispiel #9
0
def random_lattice():    # Random Lattice
    from sage.misc.prandom import randint
    n = get_stats().counts()['nlattice']
    n = randint(0,n-1)
    C = getDBConnection()
    res = C.Lattices.lat.find()[n]
    return redirect(url_for(".render_lattice_webpage", label=res['label']))
        def _random_element_from_unrank(self):
            """
            A random element in ``self``.

            ``self.random_element()`` returns a random element in
            ``self`` with uniform probability.

            This is the default implementation from the category
            ``EnumeratedSet()`` which uses the method ``unrank``.

            EXAMPLES::

                sage: C = FiniteEnumeratedSets().example()
                sage: C.random_element()
                1
                sage: C._random_element_from_unrank()
                2

            TODO: implement _test_random which checks uniformness
            """
            from sage.misc.prandom import randint

            c = self.cardinality()
            r = randint(0, c - 1)
            return self.unrank(r)
    def random_letter(self, exclude=[]):
        """
        A random letter, different from the letters in ``exclude``.

        INPUT:

        - ``exclude`` -- (default:[]) list of letter to exclude

        OUTPUT:

        - return a random letter different from letter in exclude

        EXAMPLES::

            sage: A = AlphabetWithInverses(['a','b','c'], ['A','B','C'])
            sage: A.random_letter(['a','b','c','A','C'])
            'B'
        """
        from sage.misc.prandom import randint

        done = False
        while not done:
            j = randint(0, 2 * len(self) - 1)
            a = self[j]
            done = a not in exclude
        return a
Beispiel #12
0
    def random_element(self):
        r"""
        Return a random parking function of size `n`.

        The algorithm uses a circular parking space with `n+1`
        spots. Then all `n` cars can park and there remains one empty
        spot. Spots are then renumbered so that the empty spot is `0`.

        The probability distribution is uniform on the set of
        `(n+1)^{n-1}` parking functions of size `n`.

        EXAMPLES::

            sage: pf = ParkingFunctions(8)
            sage: a = pf.random_element(); a  # random
            [5, 7, 2, 4, 2, 5, 1, 3]
            sage: a in pf
            True
        """
        n = self.n
        Zm = Zmod(n + 1)
        fun = [Zm(randint(0, n)) for i in range(n)]
        free = [Zm(j) for j in range(n + 1)]
        for car in fun:
            position = car
            while not(position in free):
                position += Zm.one()
            free.remove(position)
        return ParkingFunction([(i - free[0]).lift() for i in fun])
Beispiel #13
0
 def random_element(self):
     """
     Return a random element of this dual group.
     
     EXAMPLES::
     
         sage: G = AbelianGroup([2,3,9])
         sage: Gd = DualAbelianGroup(G)
         sage: Gd.random_element()
         X0*X1^2*X2
         sage: N = 43^2-1
         sage: G = AbelianGroup([N],names="a")
         sage: Gd = DualAbelianGroup(G,names="A")
         sage: a, = G.gens()
         sage: A, = Gd.gens()
         sage: x = a^(N/4); y = a^(N/3); z = a^(N/14)
         sage: X = Gd.random_element(); X
         A^615
         sage: len([a for a in [x,y,z] if abs(X(a)-1)>10^(-8)])
         2
     """
     from sage.misc.prandom import randint
     gens = self.gens()
     g = gens[0]**0
     for i in range(len(gens)):
         g = g*gens[i]**(randint(1,gens[i].order()))
     return g
Beispiel #14
0
def random_hmf():    # Random Hilbert modular form
    from sage.misc.prandom import randint
    n = get_stats().counts()['nforms']
    n = randint(0,n-1)
    C = getDBConnection()
    res = C.hmfs.forms.find()[n]
    return redirect(url_for(".render_hmf_webpage", field_label=res['field_label'], label=res['label']))
Beispiel #15
0
    def random_element(self, bound=None):
        """
        Return a random element of this ring.

        INPUT:

        - ``bound``, a positive integer or ``None`` (the default). Is given,
          return  the coercion of an integer in the interval
          ``[-bound, bound]`` into this ring.

        EXAMPLES::

            sage: R = IntegerModRing(18)
            sage: R.random_element()
            2

        We test ``bound``-option::

            sage: R.random_element(2) in [R(16), R(17), R(0), R(1), R(2)]
            True
        """
        if not (bound is None):
            return commutative_ring.CommutativeRing.random_element(self, bound)
        a = random.randint(0, self.order() - 1)
        return self(a)
Beispiel #16
0
    def _rand_der(self):
        """
        Produces a random derangement of `[1, 2, \ldots, n]`.

        This is an
        implementation of the algorithm described by Martinez et. al. in
        [Martinez08]_.

        EXAMPLES::

            sage: D = Derangements(4)
            sage: D._rand_der()
            [2, 3, 4, 1]
        """
        n = len(self._set)
        A = list(range(1, n + 1))
        mark = [x<0 for x in A]
        i,u = n,n
        while u >= 2:
            if not(mark[i-1]):
                while True:
                    j = randint(1,i-1)
                    if not(mark[j-1]):
                        A[i-1], A[j-1] = A[j-1], A[i-1]
                        break
                p = random()
                if p < (u-1) * self._count_der(u-2) // self._count_der(u):
                    mark[j-1] = True
                    u -= 1
                u -= 1
            i -= 1
        return A
def random_hmf():    # Random Hilbert modular form
    from sage.misc.prandom import randint
    n = get_stats().counts()['nforms']
    n = randint(0,n-1)
    C = getDBConnection()
    res = C.hmfs.forms.find()[n]
    return hilbert_modular_form_by_label(res)
Beispiel #18
0
def RandomToleranceGraph(n):
    r"""
    Returns a random tolerance graph.

    The random tolerance graph is built from a random tolerance representation
    by using the function `ToleranceGraph`. This representation is a list
    `((l_0,r_0,t_0), (l_1,r_1,t_1), ..., (l_k,r_k,t_k))` where `k = n-1` and
    `I_i = (l_i,r_i)` denotes a random interval and `t_i` a random positive
    value. The width of the representation is limited to n**2 * 2**n.

    .. NOTE::

        The vertices are named 0, 1, ..., n-1. The tolerance representation used
        to create the graph is saved with the graph and can be recovered using
        ``get_vertex()`` or ``get_vertices()``.

    INPUT:

    - ``n`` -- number of vertices of the random graph.

    EXAMPLE:

    Every tolerance graph is perfect. Hence, the chromatic number is equal to
    the clique number ::

        sage: g = graphs.RandomToleranceGraph(8)
        sage: g.clique_number() == g.chromatic_number()
        True

    TEST:

        sage: g = graphs.RandomToleranceGraph(-2)
        Traceback (most recent call last):
        ...
        ValueError: The number `n` of vertices must be >= 0.
    """
    from sage.misc.prandom import randint
    from sage.graphs.generators.intersection import ToleranceGraph

    if n<0:
        raise ValueError('The number `n` of vertices must be >= 0.')

    W = n**2 * 2**n

    tolrep = [tuple(sorted((randint(0,W), randint(0,W)))) + (randint(0,W),) for i in range(n)]

    return ToleranceGraph(tolrep)
 def random_element(self, prec=None, total_measure_zero=False):
     #RH: copied from RP's change
     if prec == None:
         prec = self._prec_cap
     if prec == 0:
         V = self.approx_module(0)
         return CoeffMod_OMS_element(V([]), self, ordp=randint(1, self._prec_cap), check=False)
     R = self.base_ring().integer_ring()
     return self((R**prec).random_element())
Beispiel #20
0
def random_curve():
    from sage.misc.prandom import randint
    n = get_stats().counts()['ncurves']
    n = randint(0,n-1)
    label = db_ec().find()[n]['label']
    # This version leaves the word 'random' in the URL:
    # return render_curve_webpage_by_label(label)
    # This version uses the curve's own URL:
    return redirect(url_for(".by_ec_label", label=label), 301)
Beispiel #21
0
    def __call__(self):
        """
        Return a new sample.

        EXAMPLE::

            sage: from sage.crypto.lwe import DiscreteGaussianSamplerRejection
            sage: sampler = DiscreteGaussianSamplerRejection(12.0)
            sage: sampler()
            -5
        """
        x = 0
        y = 0
        z = 0
        while y >= z :
            x = randint(0, self.upper_bound-1)
            y = randint(0, self.max_precs-1)
            z = self.rho[x]
        return (2*randint(0,1)-1)*x
Beispiel #22
0
 def random_braid(self,n=1):
     """
     A random braid automorphism of ``self`` of length at most
     ``n``.
     """
     A=self._alphabet
     if n==0:
         return self.identity_automorphism()
     i=randint(1,len(A)-1)
     j=randint(0,1)
     result=self.braid_automorphism(i,j!=0)
     for ii in xrange(n-1):
         l=randint(0,1)
         if l==j: i=randint(1,len(A)-1)
         else:
             k=randint(1,len(A)-2)
             if j<=k: i=k+1
         result=result*self.braid_automorphism(i,j)
     return result
Beispiel #23
0
def RandomBoundedToleranceGraph(n):
    r"""
    Returns a random bounded tolerance graph.

    The random tolerance graph is built from a random bounded
    tolerance representation by using the function
    `ToleranceGraph`. This representation is a list
    `((l_0,r_0,t_0), (l_1,r_1,t_1), ..., (l_k,r_k,t_k))` where
    `k = n-1` and `I_i = (l_i,r_i)` denotes a random interval and
    `t_i` a random positive value less then or equal to the length
    of the interval `I_i`. The width of the representation is
    limited to n**2 * 2**n.

    .. NOTE::

        The tolerance representation used to create the graph can
        be recovered using ``get_vertex()`` or ``get_vertices()``.

    INPUT:

    - ``n`` -- number of vertices of the random graph.

    EXAMPLE:

    Every (bounded) tolerance graph is perfect. Hence, the
    chromatic number is equal to the clique number ::

        sage: g = graphs.RandomBoundedToleranceGraph(8)
        sage: g.clique_number() == g.chromatic_number()
        True
    """
    from sage.misc.prandom import randint
    from sage.graphs.generators.intersection import ToleranceGraph

    W = n ** 2 * 2 ** n

    tolrep = [
        (l_r[0], l_r[1], randint(0, l_r[1] - l_r[0]))
        for l_r in [sorted((randint(0, W), randint(0, W))) for i in range(n)]
    ]

    return ToleranceGraph(tolrep)
Beispiel #24
0
def random_nfglobal():
    from sage.misc.prandom import randint
    C = getDBConnection()
    init_nf_count()
    n = randint(0,nfields-1)
    label = C.numberfields.fields.find()[n]['label']
    #This version leaves the word 'random' in the URL:
    #return render_field_webpage({'label': label})
    #This version uses the number field's own URL:
    #url =
    return redirect(url_for(".by_label", label= label))
Beispiel #25
0
    def random(self):
        """
        Returns a random curve from the database.

        EXAMPLES::

            sage: CremonaDatabase().random() # random -- depends on database installed
            Elliptic Curve defined by y^2 + x*y  = x^3 - x^2 - 224*x + 3072 over Rational Field
        """
        N = randint(11, self.largest_conductor())
        q = self.__connection__.cursor().execute('SELECT conductor FROM ' \
            + 't_class WHERE conductor>=? ORDER BY conductor',(int(N),))
        try:
            N = q.next()[0]
        except StopIteration:
            N = 11
        iso = randint(0, self.number_of_isogeny_classes(N)-1)
        iso = cremona_letter_code(iso)
        num = randint(1, self.number_of_curves(N,iso))
        return self.elliptic_curve(str(N)+iso+str(num))
Beispiel #26
0
Datei: p4.py Projekt: vidirr/STFO
def getJump(pos, n):

	#Right
	if pos == _sage_const_0 :
		return _sage_const_2 

	#Left
	if pos == n - _sage_const_1 :
		return _sage_const_1 

	#Else random
	return r.randint(_sage_const_1 , _sage_const_2 )
    def random_letter(self,exclude=[]):
        """
        A random letter, different from the letters in ``exclude``.
        """
        from sage.misc.prandom import randint

        done=False
        while not done:
            j=randint(0,2*len(self)-1)
            a=self[j]
            done=a not in exclude
        return a
Beispiel #28
0
    def __call__(self):
        """
        Return a new sample.

        EXAMPLES::

            sage: from sage.crypto.lwe import UniformSampler
            sage: sampler = UniformSampler(-12, 12)
            sage: sampler()
            -10
        """
        return randint(self.lower_bound, self.upper_bound)
Beispiel #29
0
    def random_mapping_class(self,n=1,verbose=False):
        """
        Random mapping class of length (as a product of generating dehn twists)
        at most ``n``. `

        WARNING:

        The rank of ``self` is assumed to be even.
        """
        from sage.misc.prandom import randint

        assert len(self._alphabet)%2==0

        if n==0:
            return self.identity_automorphism()

        r=3*len(self._alphabet)/2-2
        i=randint(0,r)
        j=randint(0,1)
        if j==0:
            result=self.surface_dehn_twist(i)
        else:
            result=self.surface_dehn_twist(i).inverse()
        used_dehn_twists=[(i,1-2*j)]
        for ii in xrange(n-1):
            l=randint(0,1)
            if j==l:
                i=randint(0,r)
            else:
                k=randint(0,r-1)
                if k>=i: i=k+1
                j=l
            if j==0:
                result=result*self.surface_dehn_twist(i)
            else:
                result=result*self.surface_dehn_twist(i).inverse()
            used_dehn_twists.append((i,1-2*j))
        if verbose:
            print "List of surface Dehn twists used:",used_dehn_twists       
        return result
Beispiel #30
0
    def random_element(self):
        r"""
        Produces all derangements of a positive integer, a list, or
        a string.  The list or string may contain repeated elements.
        If an integer `n` is given, then a random
        derangements of `[1, 2, 3, \ldots, n]` is returned

        For an integer, or a list or string with all elements
        distinct, the value is obtained by an algorithm described in
        [Martinez08]_. For a list or string with repeated elements the
        derangement is formed by choosing an element at random from the list of
        all possible derangements.

        OUTPUT:

        A single list or string containing a derangement, or an
        empty list if there are no derangements.

        REFERENCES:

        .. [Martinez08]
           http://www.siam.org/proceedings/analco/2008/anl08_022martinezc.pdf

        EXAMPLES::

            sage: D = Derangements(4)
            sage: D.random_element() # random
            [2, 3, 4, 1]
            sage: D = Derangements(['A','AT','CAT','CATS','CARTS','CARETS'])
            sage: D.random_element() # random
            ['AT', 'CARTS', 'A', 'CAT', 'CARETS', 'CATS']
            sage: D = Derangements('UNCOPYRIGHTABLE')
            sage: D.random_element() # random
            ['C', 'U', 'I', 'H', 'O', 'G', 'N', 'B', 'E', 'L', 'A', 'R', 'P', 'Y', 'T']
            sage: D = Derangements([1,1,1,1,2,2,2,2,3,3,3,3])
            sage: D.random_element() # random
            [3, 2, 2, 3, 1, 3, 1, 3, 2, 1, 1, 2]
            sage: D = Derangements('ESSENCES')
            sage: D.random_element() # random
            ['N', 'E', 'E', 'C', 'S', 'S', 'S', 'E']
            sage: D = Derangements([1,1,2,2,2])
            sage: D.random_element()
            []
        """
        if self.__multi:
            L = list(self)
            if len(L) == 0:
                return self.element_class(self, [])
            i = randint(0, len(L))
            return L[i]
        temp = self._rand_der()
        return self.element_class(self, [self._set[i-1] for i in temp])
Beispiel #31
0
    def random_element(self):
        r"""
        Produces all derangements of a positive integer, a list, or
        a string.  The list or string may contain repeated elements.
        If an integer `n` is given, then a random
        derangements of `[1, 2, 3, \ldots, n]` is returned

        For an integer, or a list or string with all elements
        distinct, the value is obtained by an algorithm described in
        [Martinez08]_. For a list or string with repeated elements the
        derangement is formed by choosing an element at random from the list of
        all possible derangements.

        OUTPUT:

        A single list or string containing a derangement, or an
        empty list if there are no derangements.

        REFERENCES:

        .. [Martinez08]
           http://www.siam.org/proceedings/analco/2008/anl08_022martinezc.pdf

        EXAMPLES::

            sage: D = Derangements(4)
            sage: D.random_element() # random
            [2, 3, 4, 1]
            sage: D = Derangements(['A','AT','CAT','CATS','CARTS','CARETS'])
            sage: D.random_element() # random
            ['AT', 'CARTS', 'A', 'CAT', 'CARETS', 'CATS']
            sage: D = Derangements('UNCOPYRIGHTABLE')
            sage: D.random_element() # random
            ['C', 'U', 'I', 'H', 'O', 'G', 'N', 'B', 'E', 'L', 'A', 'R', 'P', 'Y', 'T']
            sage: D = Derangements([1,1,1,1,2,2,2,2,3,3,3,3])
            sage: D.random_element() # random
            [3, 2, 2, 3, 1, 3, 1, 3, 2, 1, 1, 2]
            sage: D = Derangements('ESSENCES')
            sage: D.random_element() # random
            ['N', 'E', 'E', 'C', 'S', 'S', 'S', 'E']
            sage: D = Derangements([1,1,2,2,2])
            sage: D.random_element()
            []
        """
        if self.__multi:
            L = list(self)
            if len(L) == 0:
                return self.element_class(self, [])
            i = randint(0, len(L))
            return L[i]
        temp = self._rand_der()
        return self.element_class(self, [self._set[i - 1] for i in temp])
Beispiel #32
0
    def random_element(self):
        r"""
        Return a random element of self with uniform law

        EXAMPLES::

            sage: S = Subsets([1,1,2,3], submultiset=True)
            sage: S.random_element()
            [2]
        """
        l = []
        for i in self._d:
            l.extend([i] * rnd.randint(0, self._d[i]))
        return l
Beispiel #33
0
    def random_element(self):
        r"""
        Return a random element of ``self`` with uniform law.

        EXAMPLES::

            sage: S = Subsets([1,1,2,3], submultiset=True)
            sage: S.random_element()
            [2]
        """
        l = []
        for i, di in self._d.items():
            l.extend([i] * rnd.randint(0, di))
        return l
Beispiel #34
0
def random_simplicial_complex(level=1, p=0.5):
    """
    Return a random simplicial complex.

    :param level: measure of complexity: the larger this is, the more
      vertices and therefore the larger the possible dimension of the
      complex.
    :type level: positive integer; optional, default 1
    :param p: probability, passed on to ``simplicial_complexes.RandomComplex``
    :type p: float between 0 and 1; optional; default 0.5

    EXAMPLES::

        sage: from sage.homology.tests import random_simplicial_complex
        sage: X = random_simplicial_complex()
        sage: X # random
        Simplicial complex with vertex set (0, 1, 2, 3, 4, 5, 6, 7) and 31 facets
        sage: X.dimension() < 11
        True
    """
    n = randint(2, 4*level)
    dim = randint(1, n)
    return RandomComplex(n, dim, p)
Beispiel #35
0
def random_integer_vector(n, length):
    r"""
    Give a random list of length *length*, consisting of nonnegative
    integers that sum to *n*.

    This is an approximation to IntegerVectors(n, length).random_element().
    That gives values uniformly at random, but might be slow; this
    routine is not uniform, but should always be fast.

    (This routine is uniform if *length* is 1 or 2; for longer vectors,
    we prefer approximately balanced vectors, where all the values
    are around `n/{length}`.)

    EXAMPLES::

        sage: from sage.symbolic.random_tests import *
        sage: random_integer_vector(100, 2)
        [11, 89]
        sage: random_integer_vector(100, 2)
        [51, 49]
        sage: random_integer_vector(100, 2)
        [4, 96]
        sage: random_integer_vector(10000, 20)
        [332, 529, 185, 738, 82, 964, 596, 892, 732, 134,
         834, 765, 398, 608, 358, 300, 652, 249, 586, 66]
    """
    if length == 0:
        return []
    elif length == 1:
        return [n]
    elif length == 2:
        v = randint(0, n)
        return [v, n-v]
    else:
        v = randint(0, 2*n//length)
        return [v] + random_integer_vector(n-v, length-1)
    def random_element(self):
        """
        Returns a random element of the class of subsets of s (in other
        words, a random subset of s).

        EXAMPLES::

            sage: Subsets(3).random_element()
            {2}
            sage: Subsets([4,5,6]).random_element()
            {5}
        """
        lset = __builtin__.list(self.s)
        n = len(self.s)
        return Set(filter(lambda x: rnd.randint(0, 1), lset))
Beispiel #37
0
    def random_irreducible(self, degree=2, monic=True, *args, **kwds):
        r"""
        Return a random irreducible Ore polynomial.

        .. WARNING::

            Elements of this Ore polynomial ring need to have a method
            is_irreducible(). Currently, this method is implemented only
            when the base ring is a finite field.

        INPUT:

        -  ``degree`` - Integer with degree (default: 2)
           or a tuple of integers with minimum and maximum degrees

        -  ``monic`` - if ``True``, returns a monic Ore polynomial
           (default: ``True``)

        -  ``*args, **kwds`` - passed in to the ``random_element`` method for
           the base ring

        EXAMPLES::

            sage: k.<t> = GF(5^3)
            sage: Frob = k.frobenius_endomorphism()
            sage: S.<x> = k['x',Frob]
            sage: A = S.random_irreducible(); A
            x^2 + (4*t^2 + 3*t + 4)*x + 4*t^2 + t
            sage: A.is_irreducible()
            True
            sage: B = S.random_irreducible(degree=3,monic=False); B  # random
            (4*t + 1)*x^3 + (t^2 + 3*t + 3)*x^2 + (3*t^2 + 2*t + 2)*x + 3*t^2 + 3*t + 1
            sage: B.is_irreducible()
            True
        """
        if isinstance(degree, (list, tuple)):
            if len(degree) != 2:
                raise ValueError(
                    "degree argument must be an integer or a tuple of 2 integers (min_degree, max_degree)"
                )
            if degree[0] > degree[1]:
                raise ValueError(
                    "minimum degree must be less or equal than maximum degree")
            degree = randint(*degree)
        while True:
            irred = self.random_element((degree, degree), monic=monic)
            if irred.is_irreducible():
                return irred
Beispiel #38
0
    def random_element(self):
        r"""
        Return a random endofunction on [0..n-1].

        EXAMPLES::

            sage: from slabbe import Endofunctions
            sage: E = Endofunctions(10)
            sage: E.random_element()          # random
            Endofunction:
            [0..9] -> [2, 8, 7, 0, 0, 6, 2, 3, 5, 9]
            sage: E.random_element()          # random
            Endofunction:
            [0..9] -> [8, 7, 7, 5, 4, 1, 0, 3, 8, 6]
        """
        L = [randint(0,self._n-1) for a in range(self._n)]
        return Endofunction(L)
Beispiel #39
0
 def random_element(self, bound=None):
     """
     Return a random element of this ring.
     
     If bound is not None, return the coercion of an integer in the
     interval [-bound, bound] into this ring.
     
     EXAMPLES::
     
         sage: R = IntegerModRing(18)
         sage: R.random_element()
         2
     """
     if not (bound is None):
         return commutative_ring.CommutativeRing.random_element(self, bound)
     a = random.randint(0, self.order() - 1)
     return self(a)
Beispiel #40
0
    def transmit_unsafe(self, message):
        r"""
        Returns ``message`` with as many errors as ``self._number_errors`` in it.

        If ``self._number_errors`` was passed as a tuple for the number of errors, it will
        pick a random integer between the bounds of the tuple and use it as the number of errors.

        This method does not check if ``message`` belongs to the input space of``self``.

        INPUT:

        - ``message`` -- a vector

        OUTPUT:

        - a vector of the output space

        EXAMPLES::

            sage: F = GF(59)^6
            sage: n_err = 2
            sage: Chan = channels.StaticErrorRateChannel(F, n_err)
            sage: msg = F((4, 8, 15, 16, 23, 42))
            sage: set_random_seed(10)
            sage: Chan.transmit_unsafe(msg)
            (4, 8, 4, 16, 23, 53)

        This checks that :trac:`19863` is fixed::

            sage: V = VectorSpace(GF(2), 1000)
            sage: Chan = channels.StaticErrorRateChannel(V, 367)
            sage: c = V.random_element()
            sage: (c - Chan(c)).hamming_weight()
            367
        """
        w = copy(message)
        number_errors = randint(*self.number_errors())
        V = self.input_space()
        R = V.base_ring()
        for i in sample(range(V.dimension()), number_errors):
            err = R.random_element()
            while (w[i] == err):
                err = R.random_element()
            w[i] = err
        return w
Beispiel #41
0
    def random_element(self):
        r"""
        Return a random subword with uniform law.

        EXAMPLES::

            sage: S1 = Subwords([1,2,3,2,1,3])
            sage: S2 = Subwords([4,6,6,6,7,4,5,5])
            sage: for i in xrange(100):
            ....:   w = S1.random_element()
            ....:   if w in S2:
            ....:       assert(w == [])
            sage: for i in xrange(100):
            ....:   w = S2.random_element()
            ....:   if w in S1:
            ....:       assert(w == [])
        """
        return self._build(elt for elt in self._w if prandom.randint(0, 1))
Beispiel #42
0
 def random_element(self):
     """
     Return a random element of this group. (Renamed random to
     random_element.)
     
     EXAMPLES::
     
         sage: G = AbelianGroup([2,3,9])
         sage: G.random_element()
         f0*f1^2*f2
     """
     from sage.misc.prandom import randint
     if self.order() is infinity:
         NotImplementedError, "The group must be finite"
     gens = self.gens()
     g = gens[0]**0
     for i in range(len(gens)):
         g = g * gens[i]**(randint(1, gens[i].order()))
     return g
Beispiel #43
0
    def random_permutation(self):
        r"""
        Return a random permutation of ``self``.
        """
        from sage.misc.prandom import randint
        from sage.groups.perm_gps.permgroup_named import SymmetricGroup

        A = self.alphabet()
        P = A.positive_letters()
        s = SymmetricGroup(P).random_element()
        f = {}
        for a in P:
            if randint(0,1):
                f[a] = self([s(a)])
            else:
                f[a] = self([A.inverse_letter(s(a))])

        from free_group_automorphism import FreeGroupAutomorphism #this has to be here and not in the preamble to prevent loop on import statements
        return FreeGroupAutomorphism(f, group=self)
Beispiel #44
0
        def _random_element_from_unrank(self):
            """
            A random element in ``self``.

            ``self.random_element()`` returns a random element in
            ``self`` with uniform probability.

            This is the default implementation from the category
            ``EnumeratedSet()`` which uses the method ``unrank``.

            EXAMPLES::

                sage: C = FiniteEnumeratedSets().example()
                sage: C.random_element()
                1
                sage: C._random_element_from_unrank()
                2

            TODO: implement _test_random which checks uniformness
            """
            from sage.misc.prandom import randint
            c = self.cardinality()
            r = randint(0, c - 1)
            return self.unrank(r)
Beispiel #45
0
 def coeff_generator():
     return randint(-100,100)/randint(1,100)
Beispiel #46
0
    def __contains__(self, elt):
        r"""
        Return ``True`` if ``elt`` is in ``self``.

        .. warning::

           This is achieved by iterating through the elements until
           ``elt`` is found. In particular, this method will never
           stop when ``elt`` is not in ``self`` and ``self`` is
           infinite.

        EXAMPLES::

            sage: S = SearchForest( [[]], lambda l: [l+[0], l+[1]] if len(l) < 3 else [], category=FiniteEnumeratedSets())
            doctest:...: DeprecationWarning: This class soon will not be
            available in that way anymore. Use RecursivelyEnumeratedSet
            instead.  See http://trac.sagemath.org/6637 for details.
            sage: [4] in S
            False
            sage: [1] in S
            True
            sage: [1,1,1,1] in S
            False
            sage: all(S.__contains__(i) for i in iter(S))
            True
            sage: S = SearchForest([1], lambda x: [x+1], category=InfiniteEnumeratedSets())
            sage: 1 in S
            True
            sage: 732 in S
            True
            sage: -1 in S # not tested : Will never stop

        The algorithm uses a random enumeration of the nodes of the
        forest. This choice was motivated by examples in which both
        depth first search and breadth first search failed. The
        following example enumerates all ordered pairs of nonnegative
        integers, starting from an infinite set of roots, where each
        roots has an infinite number of children::

            sage: S = SearchForest(Family(NN, lambda x : (x, 0)),
            ....: lambda x : Family(PositiveIntegers(), lambda y : (x[0], y)) if x[1] == 0 else [])
            doctest:...: DeprecationWarning: This class soon will not be
            available in that way anymore. Use RecursivelyEnumeratedSet
            instead.  See http://trac.sagemath.org/6637 for details.
            sage: p = S.depth_first_search_iterator()
            sage: [next(p), next(p), next(p), next(p), next(p), next(p), next(p)]
            [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6)]
            sage: p = S.breadth_first_search_iterator()
            sage: [next(p), next(p), next(p), next(p), next(p), next(p), next(p)]
            [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0)]
            sage: (0,0) in S
            True
            sage: (1,1) in S
            True
            sage: (10,10) in S
            True
            sage: (42,18) in S
            True

        We now consider the same set of all ordered pairs of
        nonnegative integers but constructed in a different way. There
        still are infinitely many roots, but each node has a single
        child. From each root starts an infinite branch of breadth
        `1`::

            sage: S = SearchForest(Family(NN, lambda x : (x, 0)) , lambda x : [(x[0], x[1]+1)])
            sage: p = S.depth_first_search_iterator()
            sage: [next(p), next(p), next(p), next(p), next(p), next(p), next(p)]
            [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6)]
            sage: p = S.breadth_first_search_iterator()
            sage: [next(p), next(p), next(p), next(p), next(p), next(p), next(p)]
            [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0)]
            sage: (0,0) in S
            True
            sage: (1,1) in S
            True
            sage: (10,10) in S
            True
            sage: (37,11) in S
            True
        """
        stack = [iter(self.roots())]
        while len(stack) > 0:
            position = randint(0, len(stack) - 1)
            try:
                node = next(stack[position])
            except StopIteration:
                stack.pop(position)
                continue

            if node == elt:
                return True
            stack.append(iter(self.children(node)))
        return False
Beispiel #47
0
def m():
	if prandom.randint(0,1):
		return prandom.uniform(-1,1)
	else:
		return prandom.gauss(0,2)
Beispiel #48
0
def RandomBlockGraph(m, k, kmax=None, incidence_structure=False):
    r"""
    Return a Random Block Graph.

    A block graph is a connected graph in which every biconnected component
    (block) is a clique.

    .. SEEALSO::

        - :wikipedia:`Block_graph` for more details on these graphs
        - :meth:`~sage.graphs.graph.Graph.is_block_graph` -- test if a graph is a block graph
        - :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`
        - :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cuts_tree`
        - :meth:`~sage.combinat.designs.incidence_structures.IncidenceStructure` 

    INPUT:

    - ``m`` -- integer; number of blocks (at least one).

    - ``k`` -- integer; minimum number of vertices of a block (at least two).

    - ``kmax`` -- integer (default: ``None``) By default, each block has `k`
      vertices. When the parameter `kmax` is specified (with `kmax \geq k`), the
      number of vertices of each block is randomly chosen between `k` and
      `kmax`.

    - ``incidence_structure`` -- boolean (default: ``False``) when set to
      ``True``, the incidence structure of the graphs is returned instead of the
      graph itself, that is the list of the lists of vertices in each
      block. This is useful for the creation of some hypergraphs.

    OUTPUT:

    A Graph when ``incidence_structure==False`` (default), and otherwise an
    incidence structure.

    EXAMPLES:

    A block graph with a single block is a clique::

        sage: B = graphs.RandomBlockGraph(1, 4)
        sage: B.is_clique()
        True

    A block graph with blocks of order 2 is a tree::

        sage: B = graphs.RandomBlockGraph(10, 2)
        sage: B.is_tree()
        True

    Every biconnected component of a block graph is a clique::

        sage: B = graphs.RandomBlockGraph(5, 3, kmax=6)
        sage: blocks,cuts = B.blocks_and_cut_vertices()
        sage: all(B.is_clique(block) for block in blocks)
        True

    A block graph with blocks of order `k` has `m*(k-1)+1` vertices::

        sage: m, k = 6, 4
        sage: B = graphs.RandomBlockGraph(m, k)
        sage: B.order() == m*(k-1)+1
        True

    Test recognition methods::

        sage: B = graphs.RandomBlockGraph(6, 2, kmax=6)
        sage: B.is_block_graph()
        True
        sage: B in graph_classes.Block
        True

    Asking for the incidence structure::

        sage: m, k = 6, 4
        sage: IS = graphs.RandomBlockGraph(m, k, incidence_structure=True)
        sage: from sage.combinat.designs.incidence_structures import IncidenceStructure
        sage: IncidenceStructure(IS)
        Incidence structure with 19 points and 6 blocks
        sage: m*(k-1)+1
        19

    TESTS:

    A block graph has at least one block, so `m\geq 1`::

        sage: B = graphs.RandomBlockGraph(0, 1)
        Traceback (most recent call last):
        ...
        ValueError: the number `m` of blocks must be >= 1

    A block has at least 2 vertices, so `k\geq 2`::

        sage: B = graphs.RandomBlockGraph(1, 1)
        Traceback (most recent call last):
        ...
        ValueError: the minimum number `k` of vertices in a block must be >= 2

    The maximum size of a block is at least its minimum size, so `k\leq kmax`::

        sage: B = graphs.RandomBlockGraph(1, 3, kmax=2)
        Traceback (most recent call last):
        ...
        ValueError: the maximum number `kmax` of vertices in a block must be >= `k`
    """
    import itertools
    from sage.misc.prandom import choice
    from sage.sets.disjoint_set import DisjointSet

    if m < 1:
        raise ValueError("the number `m` of blocks must be >= 1")
    if k < 2:
        raise ValueError(
            "the minimum number `k` of vertices in a block must be >= 2")
    if kmax is None:
        kmax = k
    elif kmax < k:
        raise ValueError(
            "the maximum number `kmax` of vertices in a block must be >= `k`")

    if m == 1:
        # A block graph with a single block is a clique
        IS = [list(range(randint(k, kmax)))]

    elif kmax == 2:
        # A block graph with blocks of order 2 is a tree
        IS = [list(e) for e in RandomTree(m + 1).edges(labels=False)]

    else:
        # We start with a random tree of order m
        T = RandomTree(m)

        # We create a block of order in range [k,kmax] per vertex of the tree
        B = {u: [(u, i) for i in range(randint(k, kmax))] for u in T}

        # For each edge of the tree, we choose 1 vertex in each of the
        # corresponding blocks and we merge them. We use a disjoint set data
        # structure to keep a unique identifier per merged vertices
        DS = DisjointSet([i for u in B for i in B[u]])
        for u, v in T.edges(labels=0):
            DS.union(choice(B[u]), choice(B[v]))

        # We relabel vertices in the range [0, m*(k-1)] and build the incidence
        # structure
        new_label = {
            root: i
            for i, root in enumerate(DS.root_to_elements_dict())
        }
        IS = [[new_label[DS.find(v)] for v in B[u]] for u in B]

    if incidence_structure:
        return IS

    # We finally build the block graph
    if k == kmax:
        BG = Graph(
            name="Random Block Graph with {} blocks of order {}".format(m, k))
    else:
        BG = Graph(
            name="Random Block Graph with {} blocks of order {} to {}".format(
                m, k, kmax))
    for block in IS:
        BG.add_clique(block)
    return BG
Beispiel #49
0
def julia_plot(f=None, **kwds):
    r"""
    Plots the Julia set of a given polynomial ``f``. Users can specify whether
    they would like to display the Mandelbrot side by side with the Julia set
    with the ``mandelbrot`` argument. If ``f`` is not specified, this method
    defaults to `f(z) = z^2-1`.

    The Julia set of a polynomial ``f`` is the set of complex numbers `z` for
    which the function `f(z)` is bounded under iteration. The Julia set can
    be visualized by plotting each point in the set in the complex plane.
    Julia sets are examples of fractals when plotted in the complex plane.

    ALGORITHM:

    Let `R_c = \bigl(1 + \sqrt{1 + 4|c|}\bigr)/2` if the polynomial is of the
    form `f(z) = z^2 + c`; otherwise, let `R_c = 2`.
    For every `p \in \mathbb{C}`, if `|f^{k}(p)| > R_c` for some `k \geq 0`,
    then `f^{n}(p) \to \infty`.  Let `N` be the maximum number of iterations.
    Compute the first `N` points on the orbit of `p` under `f`. If for
    any `k < N`, `|f^{k}(p)| > R_c`, we stop the iteration and assign a color
    to the point `p` based on how quickly `p` escaped to infinity under
    iteration of `f`. If `|f^{i}(p)| \leq R_c` for all `i \leq N`, we assume
    `p` is in the Julia set and assign the point `p` the color black.

    INPUT:

    - ``f`` -- input polynomial (optional - default: ``z^2 - 1``).

    - ``period`` -- list (optional - default: ``None``), returns the Julia set
      for a random `c` value with the given (formal) cycle structure.

    - ``mandelbrot`` -- boolean (optional - default: ``True``), when set to
      ``True``, an image of the Mandelbrot set is appended to the right of the
      Julia set.

    - ``point_color`` -- RGB color (optional - default: ``'tomato'``),
      color of the point `c` in the Mandelbrot set (any valid input for Color).

    - ``x_center`` -- double (optional - default: ``-1.0``), Real part
      of center point.

    - ``y_center`` -- double (optional - default: ``0.0``), Imaginary part
      of center point.

    - ``image_width`` -- double (optional - default: ``4.0``), width of image
      in the complex plane.

    - ``max_iteration`` -- long (optional - default: ``500``), maximum number
      of iterations the map `f(z)`.

    - ``pixel_count`` -- long (optional - default: ``500``), side length of
      image in number of pixels.

    - ``base_color`` -- hex color (optional - default: ``'steelblue'``), color
      used to determine the coloring of set (any valid input for Color).

    - ``level_sep`` -- long (optional - default: 1), number of iterations
      between each color level.

    - ``number_of_colors`` -- long (optional - default: 30), number of colors
      used to plot image.

    - ``interact`` -- boolean (optional - default: ``False``), controls whether
      plot will have interactive functionality.

    OUTPUT:

    24-bit RGB image of the Julia set in the complex plane.

    .. TODO::

        Implement the side-by-side Mandelbrot-Julia plots for general one-parameter families
        of polynomials.

    EXAMPLES:

    The default ``f`` is `z^2 - 1`::

        sage: julia_plot()
        1001x500px 24-bit RGB image

    To display only the Julia set, set ``mandelbrot`` to ``False``::

        sage: julia_plot(mandelbrot=False)
        500x500px 24-bit RGB image

    ::

        sage: R.<z> = CC[]
        sage: f = z^3 - z + 1
        sage: julia_plot(f)
        500x500px 24-bit RGB image

    To display an interactive plot of the Julia set in the Notebook,
    set ``interact`` to ``True``. (This is only implemented for polynomials of
    the form ``f = z^2 + c``)::

        sage: julia_plot(interact=True)
        interactive(children=(FloatSlider(value=-1.0, description=u'Real c'...

        ::

        sage: R.<z> = CC[]
        sage: f = z^2 + 1/2
        sage: julia_plot(f,interact=True)
        interactive(children=(FloatSlider(value=0.5, description=u'Real c'...

    To return the Julia set of a random `c` value with (formal) cycle structure
    `(2,3)`, set ``period = [2,3]``::

        sage: julia_plot(period=[2,3])
        1001x500px 24-bit RGB image

    To return all of the Julia sets of `c` values with (formal) cycle structure
    `(2,3)`::

        sage: period = [2,3] # not tested
        ....: R.<c> = QQ[]
        ....: P.<x,y> = ProjectiveSpace(R,1)
        ....: f = DynamicalSystem([x^2+c*y^2, y^2])
        ....: L = f.dynatomic_polynomial(period).subs({x:0,y:1}).roots(ring=CC)
        ....: c_values = [k[0] for k in L]
        ....: for c in c_values:
        ....:     julia_plot(c)

    Polynomial maps can be defined over a polynomial ring or a fraction field,
    so long as ``f`` is polynomial::

        sage: R.<z> = CC[]
        sage: f = z^2 - 1
        sage: julia_plot(f)
        1001x500px 24-bit RGB image

    ::

        sage: R.<z> = CC[]
        sage: K = R.fraction_field(); z = K.gen()
        sage: f = z^2-1
        sage: julia_plot(f)
        1001x500px 24-bit RGB image

    Interact functionality is not implemented if the polynomial is not of the
    form `f = z^2 + c`::

        sage: R.<z> = CC[]
        sage: f = z^3 + 1
        sage: julia_plot(f, interact=True)
        Traceback (most recent call last):
        ...
        NotImplementedError: The interactive plot is only implemented for ...
    """

    # extract keyword arguments
    period = kwds.pop("period", None)
    mandelbrot = kwds.pop("mandelbrot", True)
    point_color = kwds.pop("point_color", 'tomato')
    x_center = kwds.pop("x_center", 0.0)
    y_center = kwds.pop("y_center", 0.0)
    image_width = kwds.pop("image_width", 4.0)
    max_iteration = kwds.pop("max_iteration", 500)
    pixel_count = kwds.pop("pixel_count", 500)
    base_color = kwds.pop("base_color", 'steelblue')
    level_sep = kwds.pop("level_sep", 1)
    number_of_colors = kwds.pop("number_of_colors", 30)
    interacts = kwds.pop("interact", False)

    f_is_default_after_all = None

    if period:  # pick a random c with the specified period
        R = PolynomialRing(CC, 'c')
        c = R.gen()
        x, y = ProjectiveSpace(R, 1, 'x,y').gens()
        F = DynamicalSystem([x**2 + c * y**2, y**2])
        L = F.dynatomic_polynomial(period).subs({x: 0, y: 1}).roots(ring=CC)
        c = L[randint(0, len(L) - 1)][0]

    base_color = Color(base_color)
    point_color = Color(point_color)

    EPS = 0.00001

    if f is not None and period is None:  # f user-specified and no period given

        # try to coerce f to live in a polynomial ring
        S = PolynomialRing(CC, names='z')
        z = S.gen()
        try:
            f_poly = S(f)
        except TypeError:
            R = f.parent()
            if not (R.is_integral_domain() and
                    (CC.is_subring(R) or CDF.is_subring(R))):
                raise ValueError('Given `f` must be a complex polynomial.')
            else:
                raise NotImplementedError(
                    'Julia sets not implemented for rational functions.')

        if (f_poly - z * z) in CC:  # f is specified and of the form z^2 + c.
            f_is_default_after_all = True
            c = f_poly - z * z
        else:  # f is specified and not of the form z^2 + c
            if interacts:
                raise NotImplementedError(
                    "The interactive plot is only implemented for "
                    "polynomials of the form f = z^2 + c.")
            else:
                return general_julia(f_poly, x_center, y_center, image_width,
                                     max_iteration, pixel_count, level_sep,
                                     number_of_colors, base_color)

    # otherwise we can use fast_julia_plot for z^2 + c
    if f_is_default_after_all or f is None or period is not None:

        # specify default c = -1 value if f and period were not specified
        if not f_is_default_after_all and period is None:
            c = -1

        c = CC(c)
        c_real = c.real()
        c_imag = c.imag()

        if interacts:  # set widgets
            from ipywidgets.widgets import FloatSlider, IntSlider, \
                                           ColorPicker, interact
            widgets = dict(
                c_real=FloatSlider(min=-2.0,
                                   max=2.0,
                                   step=EPS,
                                   value=c_real,
                                   description="Real c"),
                c_imag=FloatSlider(min=-2.0,
                                   max=2.0,
                                   step=EPS,
                                   value=c_imag,
                                   description="Imag c"),
                x_center=FloatSlider(min=-1.0,
                                     max=1.0,
                                     step=EPS,
                                     value=x_center,
                                     description="Real center"),
                y_center=FloatSlider(min=-1.0,
                                     max=1.0,
                                     step=EPS,
                                     value=y_center,
                                     description="Imag center"),
                image_width=FloatSlider(min=EPS,
                                        max=4.0,
                                        step=EPS,
                                        value=image_width,
                                        description="Width"),
                max_iteration=IntSlider(min=0,
                                        max=1000,
                                        value=max_iteration,
                                        description="Iterations"),
                pixel_count=IntSlider(min=10,
                                      max=1000,
                                      value=pixel_count,
                                      description="Pixels"),
                level_sep=IntSlider(min=1,
                                    max=20,
                                    value=level_sep,
                                    description="Color sep"),
                color_num=IntSlider(min=1,
                                    max=100,
                                    value=number_of_colors,
                                    description="# Colors"),
                base_color=ColorPicker(value=base_color.html_color(),
                                       description="Base color"),
            )
            if mandelbrot:
                widgets["point_color"] = ColorPicker(
                    value=point_color.html_color(), description="Point color")
                return interact(**widgets).widget(julia_helper)
            else:
                return interact(**widgets).widget(fast_julia_plot)
        elif mandelbrot:  # non-interactive with mandelbrot
            return julia_helper(c_real, c_imag, x_center, y_center,
                                image_width, max_iteration, pixel_count,
                                level_sep, number_of_colors, base_color,
                                point_color)
        else:  # non-interactive without mandelbrot
            return fast_julia_plot(c_real, c_imag, x_center, y_center,
                                   image_width, max_iteration, pixel_count,
                                   level_sep, number_of_colors, base_color)
Beispiel #50
0
def test_finite_lattice(L):
    """
    Test several functions on a given finite lattice.

    The function contains tests of different kinds:

    - Implications of Boolean properties. Examples: a distributive lattice is modular,
      a dismantlable and distributive lattice is planar, a simple lattice can not be
      constructible by Day's doublings.
    - Dual and self-dual properties. Examples: Dual of a modular lattice is modular,
      dual of an atomic lattice is co-atomic.
    - Certificate tests. Example: certificate for a non-complemented lattice must be
      an element without a complement.
    - Verification of some property by known property or by a random test.
      Examples: A lattice is distributive iff join-primes are exactly
      join-irreducibles and an interval of a relatively complemented
      lattice is complemented.
    - Set inclusions. Example: Every co-atom must be meet-irreducible.
    - And several other tests. Example: The skeleton of a pseudocomplemented
      lattice must be Boolean.

    EXAMPLES::

        sage: from sage.tests.finite_poset import test_finite_lattice
        sage: L = posets.RandomLattice(10, 0.98)
        sage: test_finite_lattice(L) is None  # Long time
        True
    """
    from sage.combinat.posets.lattices import LatticePoset

    from sage.sets.set import Set
    from sage.combinat.subset import Subsets

    from sage.misc.prandom import randint
    from sage.misc.flatten import flatten
    from sage.misc.misc import attrcall

    from sage.misc.sageinspect import sage_getargspec

    if L.cardinality() < 4:
        # Special cases should be tested in specific TESTS-sections.
        return None

    all_props = set(list(implications) + flatten(implications.values()))
    P = {x: test_attrcall('is_' + x, L) for x in all_props}

    ### Relations between boolean-valued properties ###

    # Direct one-property implications
    for prop1 in implications:
        if P[prop1]:
            for prop2 in implications[prop1]:
                if not P[prop2]:
                    raise ValueError("error: %s should implicate %s" %
                                     (prop1, prop2))

    # Impossible combinations
    for p1, p2 in mutually_exclusive:
        if P[p1] and P[p2]:
            raise ValueError(
                "error: %s and %s should be impossible combination" % (p1, p2))

    # Two-property implications
    for p1, p2, p3 in two_to_one:
        if P[p1] and P[p2] and not P[p3]:
            raise ValueError("error: %s and %s, so should be %s" %
                             (p1, p2, p3))

    Ldual = L.dual()
    # Selfdual properties
    for p in selfdual_properties:
        if P[p] != test_attrcall('is_' + p, Ldual):
            raise ValueError("selfdual property %s error" % p)
    # Dual properties and elements
    for p1, p2 in dual_properties:
        if P[p1] != test_attrcall('is_' + p2, Ldual):
            raise ValueError("dual properties error %s" % p1)
    for e1, e2 in dual_elements:
        if set(attrcall(e1)(L)) != set(attrcall(e2)(Ldual)):
            raise ValueError("dual elements error %s" % e1)

    ### Certificates ###

    # Return value must be a pair with correct result as first element.
    for p_ in all_props:
        # Dirty fix first
        if p_[:9] == 'doubling_' or p_[:5] == 'uniq_': continue
        p = "is_" + p_
        if 'certificate' in sage_getargspec(getattr(L, p)).args:
            res = attrcall(p, certificate=True)(L)
            if type(res) != type((1, 2)) or len(res) != 2:
                raise ValueError(
                    "certificate-option does not return a pair in %s" % p)
            if P[p_] != res[0]:
                raise ValueError("certificate-option changes result in %s" % p)

    # Test for "yes"-certificates
    if P['supersolvable']:
        a = L.is_supersolvable(certificate=True)[1]
        S = Subsets(L).random_element()
        if L.is_chain_of_poset(S):
            if not L.sublattice(a + list(S)).is_distributive():
                raise ValueError("certificate error in is_supersolvable")
    if P['dismantlable']:
        elms = L.is_dismantlable(certificate=True)[1]
        if len(elms) != L.cardinality():
            raise ValueError("certificate error 1 in is_dismantlable")
        elms = elms[:randint(0, len(elms) - 1)]
        L_ = L.sublattice([x for x in L if x not in elms])
        if L_.cardinality() != L.cardinality() - len(elms):
            raise ValueError("certificate error 2 in is_dismantlable")
    if P['vertically_decomposable']:
        c = L.is_vertically_decomposable(certificate=True)[1]
        if c == L.bottom() or c == L.top():
            raise ValueError(
                "certificate error 1 in is_vertically_decomposable")
        e = L.random_element()
        if L.compare_elements(c, e) is None:
            raise ValueError(
                "certificate error 2 in is_vertically_decomposable")

    # Test for "no"-certificates
    if not P['atomic']:
        a = L.is_atomic(certificate=True)[1]
        if a in L.atoms() or a not in L.join_irreducibles():
            raise ValueError("certificate error in is_atomic")
    if not P['coatomic']:
        a = L.is_coatomic(certificate=True)[1]
        if a in L.coatoms() or a not in L.meet_irreducibles():
            raise ValueError("certificate error in is_coatomic")

    if not P['complemented']:
        a = L.is_complemented(certificate=True)[1]
        if L.complements(a) != []:
            raise ValueError("compl. error 1")
    if not P['sectionally_complemented']:
        a, b = L.is_sectionally_complemented(certificate=True)[1]
        L_ = L.sublattice(L.interval(L.bottom(), a))
        if L_.is_complemented():
            raise ValueError("sec. compl. error 1")
        if len(L_.complements(b)) > 0:
            raise ValueError("sec. compl. error 2")
    if not P['cosectionally_complemented']:
        a, b = L.is_cosectionally_complemented(certificate=True)[1]
        L_ = L.sublattice(L.interval(a, L.top()))
        if L_.is_complemented():
            raise ValueError("cosec. compl. error 1")
        if len(L_.complements(b)) > 0:
            raise ValueError("cosec. compl. error 2")
    if not P['relatively_complemented']:
        a, b, c = L.is_relatively_complemented(certificate=True)[1]
        I = L.interval(a, c)
        if len(I) != 3 or b not in I:
            raise ValueError("rel. compl. error 1")

    if not P['upper_semimodular']:
        a, b = L.is_upper_semimodular(certificate=True)[1]
        if not set(L.lower_covers(a)).intersection(set(
                L.lower_covers(b))) or set(L.upper_covers(a)).intersection(
                    set(L.upper_covers(b))):
            raise ValueError("certificate error in is_upper_semimodular")
    if not P['lower_semimodular']:
        a, b = L.is_lower_semimodular(certificate=True)[1]
        if set(L.lower_covers(a)).intersection(set(
                L.lower_covers(b))) or not set(L.upper_covers(a)).intersection(
                    set(L.upper_covers(b))):
            raise ValueError("certificate error in is_lower_semimodular")

    if not P['distributive']:
        x, y, z = L.is_distributive(certificate=True)[1]
        if L.meet(x, L.join(y, z)) == L.join(L.meet(x, y), L.meet(x, z)):
            raise ValueError("certificate error in is_distributive")
    if not P['modular']:
        x, a, b = L.is_modular(certificate=True)[1]
        if not L.is_less_than(x, b) or L.join(x, L.meet(a, b)) == L.meet(
                L.join(x, a), b):
            raise ValueError("certificate error in is_modular")

    if not P['pseudocomplemented']:
        a = L.is_pseudocomplemented(certificate=True)[1]
        L_ = L.subposet([e for e in L if L.meet(e, a) == L.bottom()])
        if L_.has_top():
            raise ValueError("certificate error in is_pseudocomplemented")
    if not P['join_pseudocomplemented']:
        a = L.is_join_pseudocomplemented(certificate=True)[1]
        L_ = L.subposet([e for e in L if L.join(e, a) == L.top()])
        if L_.has_bottom():
            raise ValueError("certificate error in is_join_pseudocomplemented")

    if not P['join_semidistributive']:
        e, x, y = L.is_join_semidistributive(certificate=True)[1]
        if L.join(e, x) != L.join(e, y) or L.join(e, x) == L.join(
                e, L.meet(x, y)):
            raise ValueError("certificate error in is_join_semidistributive")
    if not P['meet_semidistributive']:
        e, x, y = L.is_meet_semidistributive(certificate=True)[1]
        if L.meet(e, x) != L.meet(e, y) or L.meet(e, x) == L.meet(
                e, L.join(x, y)):
            raise ValueError("certificate error in is_meet_semidistributive")

    if not P['simple']:
        c = L.is_simple(certificate=True)[1]
        if len(L.congruence([c[randint(0, len(c) - 1)]])) == 1:
            raise ValueError("certificate error in is_simple")
    if not P['isoform']:
        c = L.is_isoform(certificate=True)[1]
        if len(c) == 1:
            raise ValueError("certificate error in is_isoform")
        if all(
                L.subposet(c[i]).is_isomorphic(L.subposet(c[i + 1]))
                for i in range(len(c) - 1)):
            raise ValueError("certificate error in is_isoform")
    if not P['uniform']:
        c = L.is_uniform(certificate=True)[1]
        if len(c) == 1:
            raise ValueError("certificate error in is_uniform")
        if all(len(c[i]) == len(c[i + 1]) for i in range(len(c) - 1)):
            raise ValueError("certificate error in is_uniform")
    if not P['regular']:
        c = L.is_regular(certificate=True)[1]
        if len(c[0]) == 1:
            raise ValueError("certificate error 1 in is_regular")
        if Set(c[1]) not in c[0]:
            raise ValueError("certificate error 2 in is_regular")
        if L.congruence([c[1]]) == c[0]:
            raise ValueError("certificate error 3 in is_regular")

    if not P['subdirectly_reducible']:
        x, y = L.is_subdirectly_reducible(certificate=True)[1]
        a = L.random_element()
        b = L.random_element()
        c = L.congruence([[a, b]])
        if len(c) != L.cardinality():
            for c_ in c:
                if x in c_:
                    if y not in c_:
                        raise ValueError(
                            "certificate error 1 in is_subdirectly_reducible")
                    break
            else:
                raise ValueError(
                    "certificate error 2 in is_subdirectly_reducible")

    if not P['join_distributive']:
        a = L.is_join_distributive(certificate=True)[1]
        L_ = L.sublattice(L.interval(a, L.join(L.upper_covers(a))))
        if L_.is_distributive():
            raise ValueError("certificate error in is_join_distributive")
    if not P['meet_distributive']:
        a = L.is_meet_distributive(certificate=True)[1]
        L_ = L.sublattice(L.interval(L.meet(L.lower_covers(a)), a))
        if L_.is_distributive():
            raise ValueError("certificate error in is_meet_distributive")

    ### Other ###

    # Other ways to recognize some boolean property
    if P['distributive'] != (set(L.join_primes()) == set(
            L.join_irreducibles())):
        raise ValueError(
            "every join-irreducible of a distributive lattice should be join-prime"
        )
    if P['distributive'] != (set(L.meet_primes()) == set(
            L.meet_irreducibles())):
        raise ValueError(
            "every meet-irreducible of a distributive lattice should be meet-prime"
        )
    if P['join_semidistributive'] != all(
            L.canonical_joinands(e) is not None for e in L):
        raise ValueError(
            "every element of join-semidistributive lattice should have canonical joinands"
        )
    if P['meet_semidistributive'] != all(
            L.canonical_meetands(e) is not None for e in L):
        raise ValueError(
            "every element of meet-semidistributive lattice should have canonical meetands"
        )

    # Random verification of a Boolean property
    if P['relatively_complemented']:
        a = L.random_element()
        b = L.random_element()
        if not L.sublattice(L.interval(a, b)).is_complemented():
            raise ValueError("rel. compl. error 3")
    if P['sectionally_complemented']:
        a = L.random_element()
        if not L.sublattice(L.interval(L.bottom(), a)).is_complemented():
            raise ValueError("sec. compl. error 3")
    if P['cosectionally_complemented']:
        a = L.random_element()
        if not L.sublattice(L.interval(a, L.top())).is_complemented():
            raise ValueError("cosec. compl. error 2")

    # Element set inclusions
    for s1, s2 in set_inclusions:
        if not set(attrcall(s1)(L)).issubset(set(attrcall(s2)(L))):
            raise ValueError("%s should be a subset of %s" % (s1, s2))

    # Sublattice-closed properties
    L_ = L.sublattice(Subsets(L).random_element())
    for p in sublattice_closed:
        if P[p] and not test_attrcall('is_' + p, L_):
            raise ValueError("property %s should apply to sublattices" % p)

    # Some sublattices
    L_ = L.center()  # Center is a Boolean lattice
    if not L_.is_atomic() or not L_.is_distributive():
        raise ValueError("error in center")
    if P['pseudocomplemented']:
        L_ = L.skeleton()  # Skeleton is a Boolean lattice
        if not L_.is_atomic() or not L_.is_distributive():
            raise ValueError("error in skeleton")
    L_ = L.frattini_sublattice()
    S = Subsets(L).random_element()
    if L.sublattice(S) == L and L.sublattice([e
                                              for e in S if e not in L_]) != L:
        raise ValueError("error in Frattini sublattice")
    L_ = L.maximal_sublattices()
    L_ = L_[randint(0, len(L_) - 1)]
    e = L.random_element()
    if e not in L_ and L.sublattice(list(L_) + [e]) != L:
        raise ValueError("error in maximal_sublattices")

    # Reverse functions: vertical composition and decomposition
    L_ = reduce(lambda a, b: a.vertical_composition(b),
                L.vertical_decomposition(), LatticePoset())
    if not L.is_isomorphic(L_):
        raise ValueError("error in vertical [de]composition")

    # Meet and join
    a = L.random_element()
    b = L.random_element()
    m = L.meet(a, b)
    j = L.join(a, b)
    m_ = L.subposet([
        e for e in L.principal_lower_set(a) if e in L.principal_lower_set(b)
    ]).top()
    j_ = L.subposet([
        e for e in L.principal_upper_set(a) if e in L.principal_upper_set(b)
    ]).bottom()
    if m != m_ or m != Ldual.join(a, b):
        raise ValueError("error in meet")
    if j != j_ or j != Ldual.meet(a, b):
        raise ValueError("error in join")

    # Misc misc
    e = L.neutral_elements()
    e = e[randint(0, len(e) - 1)]
    a = L.random_element()
    b = L.random_element()
    if not L.sublattice([e, a, b]).is_distributive():
        raise ValueError("error in neutral_elements")
    def Random(self,
               n=None,
               A=None,
               density_edges=None,
               density_finals=None,
               verb=False):
        """
        Generate a random DeterministicAutomaton.

        INPUT:

        - ``n`` - int (default: ``None``) -- the number of states 

        - ``A`` (default: ``None``) -- alphabet of the result

        - ``density_edges`` (default: ``None``) -- the density of the transitions among all possible transitions

        - ``density_finals`` (default: ``None``) -- the density of final states among all states

        - ``verb`` - bool (default: ``False``) -- print informations for debugging

        OUTPUT:

        A :class:`DeterministicAutomaton`

        EXAMPLES::

            sage: dag.Random()      # random
            DeterministicAutomaton with 401 states and an alphabet of 836 letters

            sage: dag.Random(3, ['a','b'])
            DeterministicAutomaton with 3 states and an alphabet of 2 letters

        """
        if density_edges is None:
            density_edges = random()
        if density_finals is None:
            density_finals = random()
        if n is None:
            n = randint(2, 1000)
        if A is None:
            if random() < .5:
                A = list('abcdefghijklmnopqrstuvwxyz')[:randint(0, 25)]
            else:
                A = range(1, randint(1, 1000))
        if verb:
            print(
                "Random automaton with %s states, density of leaving edges %s, density of final states %s and alphabet %s"
                % (n, density_edges, density_finals, A))
        L = []
        for i in range(n):
            for j in range(len(A)):
                if random() < density_edges:
                    L.append((i, randint(0, n - 1), A[j]))
        if verb:
            print(L)
        F = []
        for i in range(n):
            if random() < density_finals:
                F.append(i)
        if verb:
            print("final states %s" % F)
        return DeterministicAutomaton(L,
                                      A=A,
                                      S=range(n),
                                      i=randint(0, n - 1),
                                      final_states=F)
Beispiel #52
0
    def random_element(self, degree=2, monic=False, *args, **kwds):
        r"""
        Return a random skew polynomial in ``self``.

        INPUT:

        - ``degree`` -- (default: 2) integer with degree
          or a tuple of integers with minimum and maximum degrees

        - ``monic`` -- (default: ``False``) if ``True``, return a monic
          skew polynomial

        - ``*args, **kwds`` -- passed on to the ``random_element`` method
          for the base ring

        OUTPUT:

        Skew polynomial such that the coefficients of `x^i`, for `i` up
        to ``degree``, are random elements from the base ring, randomized
        subject to the arguments ``*args`` and ``**kwds``.

        EXAMPLES::

            sage: k.<t> = GF(5^3)
            sage: Frob = k.frobenius_endomorphism()
            sage: S.<x> = k['x', Frob]
            sage: S.random_element()  # random
            (2*t^2 + 3)*x^2 + (4*t^2 + t + 4)*x + 2*t^2 + 2
            sage: S.random_element(monic=True)  # random
            x^2 + (2*t^2 + t + 1)*x + 3*t^2 + 3*t + 2

        Use ``degree`` to obtain polynomials of higher degree

            sage: p = S.random_element(degree=5)   # random
            (t^2 + 3*t)*x^4 + (4*t + 4)*x^3 + (4*t^2 + 4*t)*x^2 + (2*t^2 + 1)*x + 3

        When ``monic`` is ``False``, the returned skew polynomial may have
        a degree less than ``degree`` (it happens when the random leading
        coefficient is zero). However, if ``monic`` is ``True``, this can't
        happen::

            sage: p = S.random_element(degree=4, monic=True)
            sage: p.leading_coefficient() == S.base_ring().one()
            True
            sage: p.degree() == 4
            True

        If a tuple of two integers is given for the degree argument, a random
        integer will be chosen between the first and second element of the
        tuple as the degree, both inclusive::

            sage: S.random_element(degree=(2,7))  # random
            (3*t^2 + 1)*x^4 + (4*t + 2)*x^3 + (4*t + 1)*x^2
             + (t^2 + 3*t + 3)*x + 3*t^2 + 2*t + 2

        If the first tuple element is greater than the second, a a
        ``ValueError`` is raised::

            sage: S.random_element(degree=(5,4))
            Traceback (most recent call last):
            ...
            ValueError: first degree argument must be less or equal to the second
        """
        R = self.base_ring()
        if isinstance(degree, (list, tuple)):
            if len(degree) != 2:
                raise ValueError(
                    "degree argument must be an integer or a tuple of 2 integers (min_degree, max_degree)"
                )
            if degree[0] > degree[1]:
                raise ValueError(
                    "first degree argument must be less or equal to the second"
                )
            degree = randint(*degree)
        if monic:
            return self(
                [R.random_element(*args, **kwds)
                 for _ in range(degree)] + [R.one()])
        else:
            return self(
                [R.random_element(*args, **kwds) for _ in range(degree + 1)])
Beispiel #53
0
    def _eigenvectors(self):
        r"""
        Find numerical approximations to simultaneous eigenvectors in
        self.modular_symbols() for all T_p in self._tp.

        EXAMPLES::

            sage: n = numerical_eigenforms(61)
            sage: n._eigenvectors() # random order
            [              1.0    0.289473640239    0.176788851952    0.336707726757  2.4182243084e-16]
            [                0  -0.0702748344418    0.491416161212    0.155925712173    0.707106781187]
            [                0    0.413171180356    0.141163094698   0.0923242547901    0.707106781187]
            [                0    0.826342360711    0.282326189397     0.18464850958 6.79812569682e-16]
            [                0      0.2402380858    0.792225196393    0.905370774276 4.70805946682e-16]

        TESTS:

        This tests if this routine selects only eigenvectors with
        multiplicity one.  Two of the eigenvalues are
        (roughly) -92.21 and -90.30 so if we set ``eps = 2.0``
        then they should compare as equal, causing both eigenvectors
        to be absent from the matrix returned.  The remaining eigenvalues
        (ostensibly unique) are visible in the test, which should be
        independent of which eigenvectors are returned, but it does presume
        an ordering of these eigenvectors for the test to succeed.
        This exercises a correction in :trac:`8018`. ::

            sage: n = numerical_eigenforms(61, eps=2.0)
            sage: evectors = n._eigenvectors()
            sage: evalues = diagonal_matrix(CDF, [-283.0, 108.522012456, 142.0])
            sage: diff = n._hecke_matrix*evectors - evectors*evalues
            sage: sum([abs(diff[i,j]) for i in range(5) for j in range(3)]) < 1.0e-9
            True
        """
        try:
            return self.__eigenvectors
        except AttributeError:
            pass
        verbose('Finding eigenvector basis')
        M = self.modular_symbols()

        tp = self._tp
        p = tp[0]
        t = M.T(p).matrix()
        for p in tp[1:]:
            t += randint(-50,50)*M.T(p).matrix()

        self._hecke_matrix = t

        global scipy
        if scipy is None:
            import scipy
        import scipy.linalg
        evals,eig = scipy.linalg.eig(self._hecke_matrix.numpy(), right=True, left=False)
        B = matrix(eig)
        v = [CDF(evals[i]) for i in range(len(evals))]

        # Determine the eigenvectors with eigenvalues of multiplicity
        # one, with equality controlled by the value of eps
        # Keep just these eigenvectors
        eps = self._eps
        w = []
        for i in range(len(v)):
            e = v[i]
            uniq = True
            for j in range(len(v)):
                if uniq and i != j and abs(e-v[j]) < eps:
                    uniq = False
            if uniq:
                w.append(i)
        self.__eigenvectors = B.matrix_from_columns(w)
        return self.__eigenvectors
Beispiel #54
0
def test_finite_poset(P):
    """
    Test several functions on a given finite poset.

    The function contains tests of different kinds, for example

    - Numerical properties jump number, dimension etc. can't be a bigger
      in a subposet with one element less.
    - "Dual tests", for example the dual of meet-semilattice must be a join-semilattice.
    - Random tries: for example if the dimension of a poset is `k`, then it can't be the
      intersection of `k-1` random linear extensions.

    EXAMPLES::

        sage: from sage.tests.finite_poset import test_finite_poset
        sage: P = posets.RandomPoset(10, 0.15)
        sage: test_finite_poset(P) is None  # Long time
        True
    """
    from sage.combinat.posets.posets import Poset
    from sage.combinat.subset import Subsets
    from sage.misc.prandom import shuffle

    from sage.misc.misc import attrcall

    e = P.random_element()
    P_one_less = P.subposet([x for x in P if x != e])

    # Cardinality
    if len(P) != P.cardinality():
        raise ValueError("error 1 in cardinality")
    if P.cardinality() - 1 != P_one_less.cardinality():
        raise ValueError("error 5 in cardinality")

    # Height
    h1 = P.height()
    h2, chain = P.height(certificate=True)
    if h1 != h2:
        raise ValueError("error 1 in height")
    if h1 != len(chain):
        raise ValueError("error 2 in height")
    if not P.is_chain_of_poset(chain):
        raise ValueError("error 3 in height")
    if len(P.random_maximal_chain()) > h1:
        raise ValueError("error 4 in height")
    if h1 - P_one_less.height() not in [0, 1]:
        raise ValueError("error 5 in height")

    # Width
    w1 = P.width()
    w2, antichain = P.width(certificate=True)
    if w1 != w2:
        raise ValueError("error 1 in width")
    if w1 != len(antichain):
        raise ValueError("error 2 in width")
    if not P.is_antichain_of_poset(antichain):
        raise ValueError("error 3 in width")
    if len(P.random_maximal_antichain()) > w1:
        raise ValueError("error 4 in width")
    if w1 - P_one_less.width() not in [0, 1]:
        raise ValueError("error 5 in width")

    # Dimension
    dim1 = P.dimension()
    dim2, linexts = P.dimension(certificate=True)
    if dim1 != dim2:
        raise ValueError("error 1 in dimension")
    if dim1 != len(linexts):
        raise ValueError("error 2 in dimension")
    P_ = Poset((P.list(), lambda a, b: all(
        linext.index(a) < linext.index(b) for linext in linexts)))
    if P_ != Poset(P.hasse_diagram()):
        raise ValueError("error 3 in dimension")
    x = [P.random_linear_extension() for _ in range(dim1 - 1)]
    P_ = Poset(
        (P.list(),
         lambda a, b: all(linext.index(a) < linext.index(b) for linext in x)))
    if P_ == Poset(P.hasse_diagram()):
        raise ValueError("error 4 in dimension")
    if dim1 - P_one_less.dimension() < 0:
        raise ValueError("error 5 in dimension")

    # Jump number
    j1 = P.jump_number()
    j2, linext = P.jump_number(certificate=True)
    if j1 != j2:
        raise ValueError("error 1 in jump number")
    if P.linear_extension(linext).jump_count() != j1:
        raise ValueError("error 2 in jump number")
    if not P.is_linear_extension(linext):
        raise ValueError("error 3 in jump number")
    if P.linear_extension(P.random_linear_extension()).jump_count() < j1:
        raise ValueError("error 4 in jump number")
    if j1 - P_one_less.jump_number() not in [0, 1]:
        raise ValueError("error 5 in jump number")

    P_dual = P.dual()
    selfdual_properties = [
        'chain', 'bounded', 'connected', 'graded', 'ranked', 'series_parallel',
        'slender', 'lattice'
    ]
    for prop in selfdual_properties:
        f = attrcall('is_' + prop)
        if f(P) != f(P_dual):
            raise ValueError("error in self-dual property %s" % prop)
    if P.is_graded():
        if P.is_bounded():
            if P.is_eulerian() != P_dual.is_eulerian():
                raise ValueError("error in self-dual property eulerian")
            if P.is_eulerian():
                P_ = P.star_product(P)
                if not P_.is_eulerian():
                    raise ("error in star product / eulerian")
        chain1 = P.random_maximal_chain()
        if len(chain1) != h1:
            raise ValueError("error in is_graded")
        if not P.is_ranked():
            raise ValueError("error in is_ranked / is_graded")

    if P.is_meet_semilattice() != P_dual.is_join_semilattice():
        raise ValueError("error in meet/join semilattice")

    if set(P.minimal_elements()) != set(P_dual.maximal_elements()):
        raise ValueError("error in min/max elements")
    if P.top() != P_dual.bottom():
        raise ValueError("error in top/bottom element")

    parts = P.connected_components()
    P_ = Poset()
    for part in parts:
        P_ = P_.disjoint_union(part)
    if not P.is_isomorphic(P_):
        raise ValueError("error in connected components / disjoint union")
    parts = P.ordinal_summands()
    P_ = Poset()
    for part in parts:
        P_ = P_.ordinal_sum(part)
    if not P.is_isomorphic(P_):
        raise ValueError("error in ordinal summands / ordinal sum")

    P_ = P.with_bounds().without_bounds()
    if not P.is_isomorphic(P_):
        raise ValueError("error in with bounds / without bounds")

    P_ = P.completion_by_cuts().irreducibles_poset()
    if not P.has_isomorphic_subposet(P_):
        raise ValueError("error in completion by cuts / irreducibles poset")

    P_ = P.subposet(Subsets(P).random_element())
    if not P_.is_induced_subposet(P):
        raise ValueError("error in subposet / is induced subposet")

    if not P.is_linear_extension(P.random_linear_extension()):
        raise ValueError("error in is linear extension")

    x = list(P)
    shuffle(x)
    if not P.is_linear_extension(P.sorted(x)):
        raise ValueError("error in sorted")

    dil = P.dilworth_decomposition()
    chain = dil[randint(0, len(dil) - 1)]
    if not P.is_chain_of_poset(chain):
        raise ValueError("error in Dilworth decomposition")
    lev = P.level_sets()
    level = lev[randint(0, len(lev) - 1)]
    if not P.is_antichain_of_poset(level):
        raise ValueError("error in level sets")

    # certificate=True must return a pair
    bool_with_cert = [
        'eulerian', 'greedy', 'join_semilattice', 'jump_critical',
        'meet_semilattice', 'slender'
    ]
    for p in bool_with_cert:
        try:  # some properties are not always defined for all posets
            res1 = attrcall('is_' + p)(P)
        except ValueError:
            continue
        res2 = attrcall('is_' + p, certificate=True)(P)
        if type(res2) != type((1, 2)) or len(res2) != 2:
            raise ValueError(
                "certificate-option does not return a pair in %s" % p)
        if res1 != res2[0]:
            raise ValueError("certificate-option changes result in %s" % p)
Beispiel #55
0
def julia_plot(c=-1, **kwds):
    r"""
    Plots the Julia set of a given complex `c` value. Users can specify whether
    they would like to display the Mandelbrot side by side with the Julia set.

    The Julia set of a given `c` value is the set of complex numbers for which
    the function `Q_c(z)=z^2+c` is bounded under iteration. The Julia set can
    be visualized by plotting each point in the set in the complex plane.
    Julia sets are examples of fractals when plotted in the complex plane.

    ALGORITHM:

    Define the map `Q_c(z) = z^2 + c` for some `c \in \mathbb{C}`. For every
    `p \in \mathbb{C}`, if `|Q_{c}^{k}(p)| > 2` for some `k \geq 0`,
    then `Q_{c}^{n}(p) \to \infty`. Let `N` be the maximum number of iterations.
    Compute the first `N` points on the orbit of `p` under `Q_c`. If for
    any `k < N`, `|Q_{c}^{k}(p)| > 2`, we stop the iteration and assign a color
    to the point `p` based on how quickly `p` escaped to infinity under
    iteration of `Q_c`. If `|Q_{c}^{i}(p)| \leq 2` for all `i \leq N`, we assume
    `p` is in the Julia set and assign the point `p` the color black.

    INPUT:

    - ``c`` -- complex (optional - default: ``-1``), complex point `c` that
      determines the Julia set.

    kwds:

    - ``period`` -- list (optional - default: ``None``), returns the Julia set
      for a random `c` value with the given (formal) cycle structure.

    - ``mandelbrot`` -- boolean (optional - default: ``True``), when set to
      ``True``, an image of the Mandelbrot set is appended to the right of the
      Julia set.

    - ``point_color`` -- RGB color (optional - default: ``[255, 0, 0]``),
      color of the point `c` in the Mandelbrot set.

    - ``x_center`` -- double (optional - default: ``-1.0``), Real part
      of center point.

    - ``y_center`` -- double (optional - default: ``0.0``), Imaginary part
      of center point.

    - ``image_width`` -- double (optional - default: ``4.0``), width of image
      in the complex plane.

    - ``max_iteration`` -- long (optional - default: ``500``), maximum number
      of iterations the map `Q_c(z)`.

    - ``pixel_count`` -- long (optional - default: ``500``), side length of
      image in number of pixels.

    - ``base_color`` -- RGB color (optional - default: ``[40, 40, 40]``), color
      used to determine the coloring of set.

    - ``iteration_level`` -- long (optional - default: 1), number of iterations
      between each color level.

    - ``number_of_colors`` -- long (optional - default: 30), number of colors
      used to plot image.

    - ``interact`` -- boolean (optional - default: ``False``), controls whether
      plot will have interactive functionality.

    OUTPUT:

    24-bit RGB image of the Julia set in the complex plane.

    EXAMPLES::

        sage: julia_plot()
        1001x500px 24-bit RGB image

    To display only the Julia set, set ``mandelbrot`` to ``False``::

        sage: julia_plot(mandelbrot=False)
        500x500px 24-bit RGB image

    To display an interactive plot of the Julia set in the Notebook,
    set ``interact`` to ``True``::

        sage: julia_plot(interact=True)
        <html>...</html>

    To return the Julia set of a random `c` value with (formal) cycle structure
    `(2,3)`, set ``period = [2,3]``::

        sage: julia_plot(period=[2,3])
        1001x500px 24-bit RGB image

    To return all of the Julia sets of `c` values with (formal) cycle structure
    `(2,3)`::

        sage: period = [2,3] # not tested
        ....: R.<c> = QQ[]
        ....: P.<x,y> = ProjectiveSpace(R,1)
        ....: f = DynamicalSystem([x^2+c*y^2, y^2])
        ....: L = f.dynatomic_polynomial(period).subs({x:0,y:1}).roots(ring=CC)
        ....: c_values = [k[0] for k in L]
        ....: for c in c_values:
        ....:     julia_plot(c)
    """

    x_center = kwds.pop("x_center", 0.0)
    y_center = kwds.pop("y_center", 0.0)
    image_width = kwds.pop("image_width", 4.0)
    max_iteration = kwds.pop("max_iteration", 500)
    pixel_count = kwds.pop("pixel_count", 500)
    base_color = kwds.pop("base_color", [50, 50, 50])
    iteration_level = kwds.pop("iteration_level", 1)
    number_of_colors = kwds.pop("number_of_colors", 50)
    point_color = kwds.pop("point_color", [255, 0, 0])
    interacts = kwds.pop("interact", False)
    mandelbrot = kwds.pop("mandelbrot", True)
    period = kwds.pop("period", None)

    if not period is None:
        R = PolynomialRing(QQ, 'c')
        c = R.gen()
        P = ProjectiveSpace(R, 1, 'x,y')
        x,y = P.gens()
        f = DynamicalSystem([x**2+c*y**2, y**2])
        L = f.dynatomic_polynomial(period).subs({x:0,y:1}).roots(ring=CC)
        c = L[randint(0,len(L)-1)][0]

    c_real = CC(c).real()
    c_imag = CC(c).imag()

    if interacts:
        @interact(layout={'bottom':[['real_center'], ['im_center'], ['width']],
         'top':[['iterations'], ['level_sep'], ['color_num'], ['mandel'],
         ['cx'], ['cy']], 'right':[['image_color'], ['pt_color']]})
        def _(cx = input_box(c_real, '$Re(c)$'),
            cy = input_box(c_imag, '$Im(c)$'),
            real_center=input_box(x_center, 'Real Center'),
            im_center=input_box(y_center, 'Imaginary Center'),
            width=input_box(image_width, 'Width of Image'),
            iterations=input_box(max_iteration, 'Max Number of Iterations'),
            level_sep=input_box(iteration_level, 'Iterations between Colors'),
            color_num=input_box(number_of_colors, 'Number of Colors'),
            image_color=color_selector(default=Color([j/255 for j in base_color]),
             label="Image Color", hide_box=True),
            pt_color=color_selector(default=Color([j/255 for j in point_color]),
             label="Point Color", hide_box=True),
            mandel=checkbox(mandelbrot, label='Mandelbrot set')):

            if mandel:
                return julia_helper(cx, cy, real_center, im_center,
                 width, iterations, pixel_count, level_sep, color_num,
                 image_color, pt_color).show()

            else:
                return fast_julia_plot(cx, cy, real_center, im_center,
                 width, iterations, pixel_count, level_sep, color_num,
                 image_color).show()

    else:
        if mandelbrot:
            return julia_helper(c_real, c_imag, x_center, y_center,
             image_width, max_iteration, pixel_count, iteration_level,
             number_of_colors, base_color, point_color)

        else:
            return fast_julia_plot(c_real, c_imag, x_center, y_center,
             image_width, max_iteration, pixel_count, iteration_level,
             number_of_colors, base_color)
Beispiel #56
0
    def __init__(self, n, q, D, secret_dist='uniform', m=None):
        """
        Construct an LWE oracle in dimension ``n`` over a ring of order
        ``q`` with noise distribution ``D``.

        INPUT:

        - ``n`` - dimension (integer > 0)
        - ``q`` - modulus typically > n (integer > 0)
        - ``D`` - an error distribution such as an instance of
          :class:`DiscreteGaussianSamplerRejection` or :class:`UniformSampler`
        - ``secret_dist`` - distribution of the secret (default: 'uniform'); one of

          - "uniform" - secret follows the uniform distribution in `\Zmod{q}`
          - "noise" - secret follows the noise distribution
          - ``(lb,ub)`` - the secret is chosen uniformly from ``[lb,...,ub]`` including both endpoints

        - ``m`` - number of allowed samples or ``None`` if no such limit exists
          (default: ``None``)

        EXAMPLE:

        First, we construct a noise distribution with standard deviation 3.0::

            sage: from sage.crypto.lwe import DiscreteGaussianSampler
            sage: D = DiscreteGaussianSampler(3.0)

        Next, we construct our oracle::

            sage: from sage.crypto.lwe import LWE
            sage: lwe = LWE(n=20, q=next_prime(400), D=D); lwe
            LWE(20, 401, DiscreteGaussianSamplerRejection(3.000000, 53, 4), 'uniform', None)

        and sample 1000 samples::

            sage: L = [lwe() for _ in range(1000)]

        To test the oracle, we use the internal secret to evaluate the samples
        in the secret::

            sage: S = [ZZ(a.dot_product(lwe._LWE__s) - c) for (a,c) in L]

        However, while Sage represents finite field elements between 0 and q-1
        we rely on a balanced representation of those elements here. Hence, we
        fix the representation and recover the correct standard deviation of the
        noise::

            sage: sqrt(variance([e if e <= 200 else e-401 for e in S]).n())
            3.0...

        If ``m`` is not ``None`` the number of available samples is restricted::

            sage: from sage.crypto.lwe import LWE
            sage: lwe = LWE(n=20, q=next_prime(400), D=D, m=30)
            sage: _ = [lwe() for _ in range(30)]
            sage: lwe() # 31
            Traceback (most recent call last):
            ...
            IndexError: Number of available samples exhausted.
        """
        self.n = ZZ(n)
        self.m = m
        self.__i = 0
        self.K = IntegerModRing(q)
        self.FM = FreeModule(self.K, n)
        self.D = D

        self.secret_dist = secret_dist
        if secret_dist == 'uniform':
            self.__s = random_vector(self.K, self.n)
        elif secret_dist == 'noise':
            self.__s = vector(self.K, self.n, [self.D() for _ in range(n)])
        else:
            try:
                lb, ub = map(ZZ, secret_dist)
                self.__s = vector(self.K, self.n,
                                  [randint(lb, ub) for _ in range(n)])
            except (IndexError, TypeError):
                raise TypeError("Parameter secret_dist=%s not understood." %
                                (secret_dist))
Beispiel #57
0
def RandomBicubicPlanar(n):
    """
    Return the graph of a random bipartite cubic map with `3 n` edges.

    INPUT:

    `n` -- an integer (at least `1`)

    OUTPUT:

    a graph with multiple edges (no embedding is provided)

    The algorithm used is described in [Schaeffer99]_. This samples
    a random rooted bipartite cubic map, chosen uniformly at random.

    First one creates a random binary tree with `n` vertices. Next one
    turns this into a blossoming tree (at random) and reads the
    contour word of this blossoming tree.

    Then one performs a rotation on this word so that this becomes a
    balanced word. There are three ways to do that, one is picked at
    random. Then a graph is build from the balanced word by iterated
    closure (adding edges).

    In the returned graph, the three edges incident to any given
    vertex are colored by the integers 0, 1 and 2.

    .. SEEALSO:: the auxiliary method :func:`blossoming_contour`

    EXAMPLES::

        sage: n = randint(200, 300)
        sage: G = graphs.RandomBicubicPlanar(n)
        sage: G.order() == 2*n
        True
        sage: G.size() == 3*n
        True
        sage: G.is_bipartite() and G.is_planar() and G.is_regular(3)
        True
        sage: dic = {'red':[v for v in G.vertices() if v[0] == 'n'],
        ....:        'blue': [v for v in G.vertices() if v[0] != 'n']}
        sage: G.plot(vertex_labels=False,vertex_size=20,vertex_colors=dic)
        Graphics object consisting of ... graphics primitives

    .. PLOT::
        :width: 300 px

        G = graphs.RandomBicubicPlanar(200)
        V0 = [v for v in G.vertices() if v[0] == 'n']
        V1 = [v for v in G.vertices() if v[0] != 'n']
        dic = {'red': V0, 'blue': V1}
        sphinx_plot(G.plot(vertex_labels=False,vertex_colors=dic))

    REFERENCES:

    .. [Schaeffer99] Gilles Schaeffer, *Random Sampling of Large Planar Maps and Convex Polyhedra*,
       Annual ACM Symposium on Theory of Computing (Atlanta, GA, 1999)
    """
    from sage.combinat.binary_tree import BinaryTrees
    from sage.rings.finite_rings.integer_mod_ring import Zmod
    if not n:
        raise ValueError("n must be at least 1")
    # first pick a random binary tree
    t = BinaryTrees(n).random_element()

    # next pick a random blossoming of this tree, compute its contour
    contour = blossoming_contour(t) + [('xb', )]  # adding the final xb

    # first step : rotate the contour word to one of 3 balanced
    N = len(contour)
    double_contour = contour + contour
    pile = []
    not_touched = [i for i in range(N) if contour[i][0] in ['x', 'xb']]
    for i, w in enumerate(double_contour):
        if w[0] == 'x' and i < N:
            pile.append(i)
        elif w[0] == 'xb' and (i % N) in not_touched:
            if pile:
                j = pile.pop()
                not_touched.remove(i % N)
                not_touched.remove(j)

    # random choice among 3 possibilities for a balanced word
    idx = not_touched[randint(0, 2)]
    w = contour[idx + 1:] + contour[:idx + 1]

    # second step : create the graph by closure from the balanced word
    G = Graph(multiedges=True)

    pile = []
    Z3 = Zmod(3)
    colour = Z3.zero()
    not_touched = [i for i, v in enumerate(w) if v[0] in ['x', 'xb']]
    for i, v in enumerate(w):
        # internal edges
        if v[0] == 'i':
            colour += 1
            if w[i + 1][0] == 'n':
                G.add_edge((w[i], w[i + 1], colour))
        elif v[0] == 'n':
            colour += 2
        elif v[0] == 'x':
            pile.append(i)
        elif v[0] == 'xb' and i in not_touched:
            if pile:
                j = pile.pop()
                G.add_edge((w[i + 1], w[j - 1], colour))
                not_touched.remove(i)
                not_touched.remove(j)

    # there remains to add three edges to elements of "not_touched"
    # from a new vertex labelled "n"
    for i in not_touched:
        taken_colours = [edge[2] for edge in G.edges_incident(w[i - 1])]
        colour = [u for u in Z3 if u not in taken_colours][0]
        G.add_edge((('n', -1), w[i - 1], colour))

    return G
Beispiel #58
0
def blossoming_contour(t, shift=0):
    """
    Return a random blossoming of a binary tree `t`, as a contour word.

    This is doing several things simultaneously:

    - complete the binary tree, by adding leaves labelled ``xb``,
    - add a vertex labelled ``n`` at the middle of every inner
      edge, with a leaf labelled ``x`` either on the left or on the
      right (at random),
    - number all vertices (but not leaves) by integers starting from `shift`,
    - compute the counter-clockwise contour word of the result.

    Initial vertices receive the label ``i``.

    This is an auxiliary function, used for the generation of random
    planar bicubic maps.

    INPUT:

    - `t` -- a binary tree (non-empty)

    - ``shift`` -- an integer (default `0`), used as a starting index

    OUTPUT:

    contour word of a random blossoming of `t`

    EXAMPLES::

        sage: from sage.graphs.generators.random import blossoming_contour
        sage: print(blossoming_contour(BinaryTrees(1).an_element()))
        [('i', 0), ('xb',), ('i', 0), ('xb',), ('i', 0)]

        sage: t = BinaryTrees(2).random_element()
        sage: print(blossoming_contour(t))  # random
        [('i', 0), ('xb',), ('i', 0), ('n', 2), ('i', 1), ('xb',), ('i', 1),
        ('xb',), ('i', 1), ('n', 2), ('x',), ('n', 2), ('i', 0)]

        sage: w = blossoming_contour(BinaryTrees(3).random_element()); len(w)
        21
        sage: w.count(('xb',))
        4
        sage: w.count(('x',))
        2

    TESTS::

        sage: from sage.graphs.generators.random import blossoming_contour
        sage: blossoming_contour(BinaryTrees(0).an_element())
        Traceback (most recent call last):
        ...
        ValueError: tree must be non-empty
    """
    if not t:
        raise ValueError('tree must be non-empty')
    t1, t2 = t
    leaf_xb = ('xb', )
    leaf_x = ('x', )
    n1 = t1.node_number()
    n = t.node_number()

    # adding buds on edges in t1
    if not t1:
        tt1 = [leaf_xb]
    elif randint(0, 1):
        label1 = ('n', shift)
        tt1 = [label1, leaf_x, label1] + blossoming_contour(t1, shift + 1)
        tt1 += [label1]
    else:
        label1 = ('n', shift + 2 * n1 - 1)
        tt1 = [label1] + blossoming_contour(t1, shift)
        tt1 += [label1, leaf_x, label1]

    # adding buds on edges in t2
    if not t2:
        tt2 = [leaf_xb]
    elif randint(0, 1):
        label2 = ('n', shift + 2 * n1 + 1)
        tt2 = [label2, leaf_x, label2]
        tt2 += blossoming_contour(t2, shift + 2 * n1 + 2) + [label2]
    else:
        label2 = ('n', shift + 2 * n - 2)
        tt2 = [label2] + blossoming_contour(t2, shift + 2 * n1 + 1)
        tt2 += [label2, leaf_x, label2]

    label = [('i', shift + 2 * n1)]
    return label + tt1 + label + tt2 + label
Beispiel #59
0
def RandomTree(n):
    """
    Returns a random tree on `n` nodes numbered `0` through `n-1`.

    By Cayley's theorem, there are `n^{n-2}` trees with vertex
    set `\{0,1,...,n-1\}`. This constructor chooses one of these uniformly
    at random.

    ALGORITHM:

    The algoritm works by generating an `(n-2)`-long
    random sequence of numbers chosen independently and uniformly
    from `\{0,1,\ldots,n-1\}` and then applies an inverse
    Prufer transformation.

    INPUT:

    -  ``n`` - number of vertices in the tree

    EXAMPLE::

        sage: G = graphs.RandomTree(10)
        sage: G.is_tree()
        True
        sage: G.show() # long

    TESTS:

    Ensuring that we encounter no unexpected surprise ::

        sage: all( graphs.RandomTree(10).is_tree()
        ...        for i in range(100) )
        True

    """
    from sage.misc.prandom import randint
    g = graph.Graph()

    # create random Prufer code
    code = [randint(0, n - 1) for i in xrange(n - 2)]

    # We count the number of symbols of each type.
    # count[k] is the no. of times k appears in code
    #
    # (count[k] is set to -1 when the corresponding vertex is not
    # available anymore)
    count = [0 for i in xrange(n)]
    for k in code:
        count[k] += 1

    g.add_vertices(range(n))

    for s in code:
        for x in range(n):
            if count[x] == 0:
                break

        count[x] = -1
        g.add_edge(x, s)
        count[s] -= 1

    # Adding as an edge the last two available vertices
    last_edge = [v for v in range(n) if count[v] != -1]
    g.add_edge(last_edge)

    return g
Beispiel #60
0
def _auxiliary_random_word(n):
    r"""
    Return a random word used to generate random triangulations.

    INPUT:

    n -- an integer

    OUTPUT:

    A binary sequence `w` of length `4n-2` with `n-1` ones, such that any proper
    prefix `u` of `w` satisfies `3|u|_1 - |u|_0 > -2` (where `|u|_1` and `|u|_0`
    are respectively the number of 1s and 0s in `u`). Those words are the
    expected input of :func:`_contour_and_graph_from_word`.

    ALGORITHM:

    A random word with these numbers of `0` and `1` is chosen. This
    word is then rotated in order to give an admissible code for a
    tree (as explained in Proposition 4.2, [PS2006]_). There are
    exactly two such rotations, one of which is chosen at random.

    Let us consider a word `w` satisfying the expected conditions. By
    drawing a step (1,3) for each 1 and a step (1,-1) for each 0 in
    `w`, one gets a path starting at height 0, ending at height -2 and
    staying above (or on) the horizontal line of height -1 except at the
    end point. By cutting the word at the first position of height -1,
    let us write `w=uv`. One can then see that `v` can only touch the line
    of height -1 at its initial point and just before its end point
    (these two points may be the same).

    Now consider a word `w'` obtained from `w` by any
    rotation. Because `vu` is another word satisfying the expected
    conditions, one can assume that `w'` is obtained from `w` by
    starting at some point in `u`. The algorithm must then recognize
    the end of `u` and the end of `v` inside `w'`. The end of `v` is
    the unique point of minimal height `h`. The end of `u` is the first
    point reaching the height `h+1`.

    EXAMPLES::

        sage: from sage.graphs.generators.random import _auxiliary_random_word
        sage: _auxiliary_random_word(4)  # random
        [1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]

        sage: def check(w):
        ....:     steps = {1: 3, 0: -1}
        ....:     return all(sum(steps[u] for u in w[:i]) >= -1 for i in range(len(w)))

        sage: for n in range(1, 10):
        ....:     w = _auxiliary_random_word(n)
        ....:     assert len(w) == 4 * n - 2
        ....:     assert w.count(0) == 3 * n - 1
        ....:     assert check(w)
    """
    from sage.misc.prandom import shuffle
    w = [0] * (3 * n - 1) + [1] * (n - 1)
    shuffle(w)

    # Finding the two admissible shifts.
    # The 'if height' is true at least once.
    # If it is true just once, then the word is admissible
    # and cuts = [0, first position of -1] (ok)
    # Otherwise, cuts will always contain
    # [first position of hmin, first position of hmin - 1] (ok)
    cuts = [0, 0]
    height = 0
    height_min = 0
    for i in range(4 * n - 3):
        if w[i] == 1:
            height += 3
        else:
            height -= 1
            if height < height_min:
                height_min = height
                cuts = cuts[1], i + 1

    # random choice of one of the two possible cuts
    idx = cuts[randint(0, 1)]
    return w[idx:] + w[:idx]