Exemplo n.º 1
0
 def _pgroup_of_double(polyh, ordered_faces, pgroup):
     n = len(ordered_faces[0])
     # the vertices of the double which sits inside a give polyhedron
     # can be found by tracking the faces of the outer polyhedron.
     # A map between face and the vertex of the double is made so that
     # after rotation the position of the vertices can be located
     fmap = dict(zip(ordered_faces,
                     range(len(ordered_faces))))
     flat_faces = flatten(ordered_faces)
     new_pgroup = []
     for i, p in enumerate(pgroup):
         h = polyh.copy()
         h.rotate(p)
         c = h.corners
         # reorder corners in the order they should appear when
         # enumerating the faces
         reorder = unflatten([c[j] for j in flat_faces], n)
         # make them canonical
         reorder = [tuple(map(as_int,
                    minlex(f, directed=False, is_set=True)))
                    for f in reorder]
         # map face to vertex: the resulting list of vertices are the
         # permutation that we seek for the double
         new_pgroup.append(Perm([fmap[f] for f in reorder]))
     return new_pgroup
Exemplo n.º 2
0
def test_flatten():
    assert flatten((1, (1, ))) == [1, 1]
    assert flatten((x, (x, ))) == [x, x]

    ls = [[(-2, -1), (1, 2)], [(0, 0)]]

    assert flatten(ls, levels=0) == ls
    assert flatten(ls, levels=1) == [(-2, -1), (1, 2), (0, 0)]
    assert flatten(ls, levels=2) == [-2, -1, 1, 2, 0, 0]
    assert flatten(ls, levels=3) == [-2, -1, 1, 2, 0, 0]

    pytest.raises(ValueError, lambda: flatten(ls, levels=-1))

    class MyOp(Basic):
        pass

    assert flatten([MyOp(x, y), z]) == [MyOp(x, y), z]
    assert flatten([MyOp(x, y), z], cls=MyOp) == [x, y, z]

    assert flatten({1, 11, 2}) == list({1, 11, 2})
Exemplo n.º 3
0
def test_flatten():
    assert flatten((1, (1,))) == [1, 1]
    assert flatten((x, (x,))) == [x, x]

    ls = [[(-2, -1), (1, 2)], [(0, 0)]]

    assert flatten(ls, levels=0) == ls
    assert flatten(ls, levels=1) == [(-2, -1), (1, 2), (0, 0)]
    assert flatten(ls, levels=2) == [-2, -1, 1, 2, 0, 0]
    assert flatten(ls, levels=3) == [-2, -1, 1, 2, 0, 0]

    pytest.raises(ValueError, lambda: flatten(ls, levels=-1))

    class MyOp(Basic):
        pass

    assert flatten([MyOp(x, y), z]) == [MyOp(x, y), z]
    assert flatten([MyOp(x, y), z], cls=MyOp) == [x, y, z]

    assert flatten({1, 11, 2}) == list({1, 11, 2})
Exemplo n.º 4
0
    def __new__(cls, *args, **kw_args):
        """The constructor for the Prufer object.

        Examples
        ========

        >>> from diofant.combinatorics.prufer import Prufer

        A Prufer object can be constructed from a list of edges:

        >>> a = Prufer([[0, 1], [0, 2], [0, 3]])
        >>> a.prufer_repr
        [0, 0]

        If the number of nodes is given, no checking of the nodes will
        be performed; it will be assumed that nodes 0 through n - 1 are
        present:

        >>> Prufer([[0, 1], [0, 2], [0, 3]], 4)
        Prufer([[0, 1], [0, 2], [0, 3]], 4)

        A Prufer object can be constructed from a Prufer sequence:

        >>> b = Prufer([1, 3])
        >>> b.tree_repr
        [[0, 1], [1, 3], [2, 3]]

        """
        ret_obj = Basic.__new__(cls, *args, **kw_args)
        args = [list(args[0])]
        if args[0] and iterable(args[0][0]):
            if not args[0][0]:
                raise ValueError(
                    'Prufer expects at least one edge in the tree.')
            if len(args) > 1:
                nnodes = args[1]
            else:
                nodes = set(flatten(args[0]))
                nnodes = max(nodes) + 1
                if nnodes != len(nodes):
                    missing = set(range(nnodes)) - nodes
                    if len(missing) == 1:
                        msg = 'Node %s is missing.' % missing.pop()
                    else:
                        msg = 'Nodes %s are missing.' % list(sorted(missing))
                    raise ValueError(msg)
            ret_obj._tree_repr = [list(i) for i in args[0]]
            ret_obj._nodes = nnodes
        else:
            ret_obj._prufer_repr = args[0]
            ret_obj._nodes = len(ret_obj._prufer_repr) + 2
        return ret_obj
Exemplo n.º 5
0
def random_integer_partition(n, seed=None):
    """
    Generates a random integer partition summing to ``n`` as a list
    of reverse-sorted integers.

    Examples
    ========

    >>> from diofant.combinatorics.partitions import random_integer_partition

    For the following, a seed is given so a known value can be shown; in
    practice, the seed would not be given.

    >>> random_integer_partition(100, seed=[1, 1, 12, 1, 2, 1, 85, 1])
    [85, 12, 2, 1]
    >>> random_integer_partition(10, seed=[1, 2, 3, 1, 5, 1])
    [5, 3, 1, 1]
    >>> random_integer_partition(1)
    [1]
    """
    from diofant.utilities.randtest import _randint

    n = as_int(n)
    if n < 1:
        raise ValueError('n must be a positive integer')

    randint = _randint(seed)

    partition = []
    while (n > 0):
        k = randint(1, n)
        mult = randint(1, n//k)
        partition.append((k, mult))
        n -= k*mult
    partition.sort(reverse=True)
    partition = flatten([[k]*m for k, m in partition])
    return partition
Exemplo n.º 6
0
def plot_implicit(expr, x_var=None, y_var=None, **kwargs):
    """A plot function to plot implicit equations / inequalities.

    Parameters
    ==========

    ``expr`` : Expr
        The equation / inequality that is to be plotted.
    ``x_var`` : symbol or tuple, optional
        symbol to plot on x-axis or tuple giving symbol and range
        as ``(symbol, xmin, xmax)``
    ``y_var`` : symbol or tuple, optional
        symbol to plot on y-axis or tuple giving symbol and range
        as ``(symbol, ymin, ymax)``

    If neither ``x_var`` nor ``y_var`` are given then the free symbols in the
    expression will be assigned in the order they are sorted.

    The following keyword arguments can also be used:

    ``adaptive`` : Boolean, optional
        The default value is set to True. It has to be
        set to False if you want to use a mesh grid.

    ``depth`` : integer
        The depth of recursion for adaptive mesh grid.
        Default value is 0. Takes value in the range (0, 4).

    ``points`` : integer
        The number of points if adaptive mesh grid is not
        used. Default value is 200.

    ``title`` : str
        The title for the plot.

    ``xlabel`` : str
        The label for the x-axis

    ``ylabel`` : string
        The label for the y-axis

    Aesthetics options:

    ``line_color`` : float or str
        Specifies the color for the plot.  See ``Plot`` to see how to
        set color for the plots.

    plot_implicit, by default, uses interval arithmetic to plot functions. If
    the expression cannot be plotted using interval arithmetic, it defaults to
    a generating a contour using a mesh grid of fixed number of points. By
    setting adaptive to False, you can force plot_implicit to use the mesh
    grid. The mesh grid method can be effective when adaptive plotting using
    interval arithmetic, fails to plot with small line width.

    Examples
    ========

    Plot expressions:

    >>> from diofant import plot_implicit, cos, sin, symbols, Eq, And
    >>> x, y = symbols('x y')

    Without any ranges for the symbols in the expression

    >>> p1 = plot_implicit(Eq(x**2 + y**2, 5))

    With the range for the symbols

    >>> p2 = plot_implicit(Eq(x**2 + y**2, 3),
    ...         (x, -3, 3), (y, -3, 3))

    With depth of recursion as argument.

    >>> p3 = plot_implicit(Eq(x**2 + y**2, 5),
    ...         (x, -4, 4), (y, -4, 4), depth = 2)

    Using mesh grid and not using adaptive meshing.

    >>> p4 = plot_implicit(Eq(x**2 + y**2, 5),
    ...         (x, -5, 5), (y, -2, 2), adaptive=False)

    Using mesh grid with number of points as input.

    >>> p5 = plot_implicit(Eq(x**2 + y**2, 5),
    ...         (x, -5, 5), (y, -2, 2),
    ...         adaptive=False, points=400)

    Plotting regions.

    >>> p6 = plot_implicit(y > x**2)

    Plotting Using boolean conjunctions.

    >>> p7 = plot_implicit(And(y > x, y > -x))

    When plotting an expression with a single variable (y - 1, for example),
    specify the x or the y variable explicitly:

    >>> p8 = plot_implicit(y - 1, y_var=y)
    >>> p9 = plot_implicit(x - 1, x_var=x)

    """

    # Represents whether the expression contains an Equality,
    # GreaterThan or LessThan
    has_equality = False

    def arg_expand(bool_expr):
        """
        Recursively expands the arguments of an Boolean Function
        """
        for arg in bool_expr.args:
            if isinstance(arg, BooleanFunction):
                arg_expand(arg)
            elif isinstance(arg, Relational):
                arg_list.append(arg)

    arg_list = []
    if isinstance(expr, BooleanFunction):
        arg_expand(expr)

        # Check whether there is an equality in the expression provided.
        if any(
                isinstance(e, (Equality, GreaterThan, LessThan))
                for e in arg_list):
            has_equality = True

    elif not isinstance(expr, Relational):
        expr = Eq(expr, 0)
        has_equality = True
    elif isinstance(expr, (Equality, GreaterThan, LessThan)):
        has_equality = True

    xyvar = [i for i in (x_var, y_var) if i is not None]
    free_symbols = expr.free_symbols
    range_symbols = Tuple(*flatten(xyvar)).free_symbols
    undeclared = free_symbols - range_symbols
    if len(free_symbols & range_symbols) > 2:
        raise NotImplementedError("Implicit plotting is not implemented for "
                                  "more than 2 variables")

    # Create default ranges if the range is not provided.
    default_range = Tuple(-5, 5)

    def _range_tuple(s):
        if isinstance(s, (Dummy, Symbol)):
            return Tuple(s) + default_range
        if len(s) == 3:
            return Tuple(*s)
        raise ValueError('symbol or `(symbol, min, max)` expected but got %s' %
                         s)

    if len(xyvar) == 0:
        xyvar = list(_sort_gens(free_symbols))
    var_start_end_x = _range_tuple(xyvar[0])
    x = var_start_end_x[0]
    if len(xyvar) != 2:
        if x in undeclared or not undeclared:
            xyvar.append(Dummy('f(%s)' % x.name))
        else:
            xyvar.append(undeclared.pop())
    var_start_end_y = _range_tuple(xyvar[1])

    use_interval = kwargs.pop('adaptive', True)
    nb_of_points = kwargs.pop('points', 300)
    depth = kwargs.pop('depth', 0)
    line_color = kwargs.pop('line_color', "blue")
    # Check whether the depth is greater than 4 or less than 0.
    if depth > 4:
        depth = 4
    elif depth < 0:
        depth = 0

    series_argument = ImplicitSeries(expr, var_start_end_x, var_start_end_y,
                                     has_equality, use_interval, depth,
                                     nb_of_points, line_color)
    show = kwargs.pop('show', True)

    # set the x and y limits
    kwargs['xlim'] = tuple(float(x) for x in var_start_end_x[1:])
    kwargs['ylim'] = tuple(float(y) for y in var_start_end_y[1:])
    # set the x and y labels
    kwargs.setdefault('xlabel', var_start_end_x[0].name)
    kwargs.setdefault('ylabel', var_start_end_y[0].name)
    p = Plot(series_argument, **kwargs)
    if show:
        p.show()
    return p