예제 #1
0
def test_Tuple():
    t = (1, 2, 3, 4)
    st = Tuple(*t)
    assert set(sympify(t)) == set(st)
    assert len(t) == len(st)
    assert set(sympify(t[:2])) == set(st[:2])
    assert isinstance(st[:], Tuple)
    assert st == Tuple(1, 2, 3, 4)
    assert st.func(*st.args) == st
    p, q, r, s = symbols('p q r s')
    t2 = (p, q, r, s)
    st2 = Tuple(*t2)
    assert st2.atoms() == set(t2)
    assert st == st2.subs({p: 1, q: 2, r: 3, s: 4})
    # issue 5505
    assert all(isinstance(arg, Basic) for arg in st.args)
    assert Tuple(p, 1).subs(p, 0) == Tuple(0, 1)
    assert Tuple(p, Tuple(p, 1)).subs(p, 0) == Tuple(0, Tuple(0, 1))

    assert Tuple(t2) == Tuple(Tuple(*t2))
    assert Tuple.fromiter(t2) == Tuple(*t2)
    assert Tuple.fromiter(x for x in range(4)) == Tuple(0, 1, 2, 3)
    assert st2.fromiter(st2.args) == st2
예제 #2
0
 def __radd__(self, other):
     return Tuple.__radd__(self, other + other)
예제 #3
0
def test_AlgebraicNumber():
    minpoly, root = x**2 - 2, sqrt(2)

    a = AlgebraicNumber(root, gen=x)

    assert a.rep == DMP([QQ(1), QQ(0)], QQ)
    assert a.root == root
    assert a.alias is None
    assert a.minpoly == minpoly
    assert a.is_number

    assert a.is_aliased is False

    assert a.coeffs() == [S(1), S(0)]
    assert a.native_coeffs() == [QQ(1), QQ(0)]

    a = AlgebraicNumber(root, gen=x, alias='y')

    assert a.rep == DMP([QQ(1), QQ(0)], QQ)
    assert a.root == root
    assert a.alias == Symbol('y')
    assert a.minpoly == minpoly
    assert a.is_number

    assert a.is_aliased is True

    a = AlgebraicNumber(root, gen=x, alias=Symbol('y'))

    assert a.rep == DMP([QQ(1), QQ(0)], QQ)
    assert a.root == root
    assert a.alias == Symbol('y')
    assert a.minpoly == minpoly
    assert a.is_number

    assert a.is_aliased is True

    assert AlgebraicNumber(sqrt(2), []).rep == DMP([], QQ)
    assert AlgebraicNumber(sqrt(2), ()).rep == DMP([], QQ)
    assert AlgebraicNumber(sqrt(2), (0, 0)).rep == DMP([], QQ)

    assert AlgebraicNumber(sqrt(2), [8]).rep == DMP([QQ(8)], QQ)
    assert AlgebraicNumber(sqrt(2), [S(8) / 3]).rep == DMP([QQ(8, 3)], QQ)

    assert AlgebraicNumber(sqrt(2), [7, 3]).rep == DMP([QQ(7), QQ(3)], QQ)
    assert AlgebraicNumber(sqrt(2), [S(7) / 9, S(3) / 2]).rep == DMP(
        [QQ(7, 9), QQ(3, 2)], QQ)

    assert AlgebraicNumber(sqrt(2), [1, 2, 3]).rep == DMP([QQ(2), QQ(5)], QQ)

    a = AlgebraicNumber(AlgebraicNumber(root, gen=x), [1, 2])

    assert a.rep == DMP([QQ(1), QQ(2)], QQ)
    assert a.root == root
    assert a.alias is None
    assert a.minpoly == minpoly
    assert a.is_number

    assert a.is_aliased is False

    assert a.coeffs() == [S(1), S(2)]
    assert a.native_coeffs() == [QQ(1), QQ(2)]

    a = AlgebraicNumber((minpoly, root), [1, 2])

    assert a.rep == DMP([QQ(1), QQ(2)], QQ)
    assert a.root == root
    assert a.alias is None
    assert a.minpoly == minpoly
    assert a.is_number

    assert a.is_aliased is False

    a = AlgebraicNumber((Poly(minpoly), root), [1, 2])

    assert a.rep == DMP([QQ(1), QQ(2)], QQ)
    assert a.root == root
    assert a.alias is None
    assert a.minpoly == minpoly
    assert a.is_number

    assert a.is_aliased is False

    assert AlgebraicNumber(sqrt(3)).rep == DMP([QQ(1), QQ(0)], QQ)
    assert AlgebraicNumber(-sqrt(3)).rep == DMP([QQ(1), QQ(0)], QQ)

    a = AlgebraicNumber(sqrt(2))
    b = AlgebraicNumber(sqrt(2))

    assert a == b

    c = AlgebraicNumber(sqrt(2), gen=x)
    d = AlgebraicNumber(sqrt(2), gen=x)

    assert a == b
    assert a == c

    a = AlgebraicNumber(sqrt(2), [1, 2])
    b = AlgebraicNumber(sqrt(2), [1, 3])

    assert a != b and a != sqrt(2) + 3

    assert (a == x) is False and (a != x) is True

    a = AlgebraicNumber(sqrt(2), [1, 0])
    b = AlgebraicNumber(sqrt(2), [1, 0], alias=y)

    assert a.as_poly(x) == Poly(x)
    assert b.as_poly() == Poly(y)

    assert a.as_expr() == sqrt(2)
    assert a.as_expr(x) == x
    assert b.as_expr() == sqrt(2)
    assert b.as_expr(x) == x

    a = AlgebraicNumber(sqrt(2), [2, 3])
    b = AlgebraicNumber(sqrt(2), [2, 3], alias=y)

    p = a.as_poly()

    assert p == Poly(2 * p.gen + 3)

    assert a.as_poly(x) == Poly(2 * x + 3)
    assert b.as_poly() == Poly(2 * y + 3)

    assert a.as_expr() == 2 * sqrt(2) + 3
    assert a.as_expr(x) == 2 * x + 3
    assert b.as_expr() == 2 * sqrt(2) + 3
    assert b.as_expr(x) == 2 * x + 3

    a = AlgebraicNumber(sqrt(2))
    b = to_number_field(sqrt(2))
    assert a.args == b.args == (sqrt(2), Tuple(1, 0))
    b = AlgebraicNumber(sqrt(2), alias='alpha')
    assert b.args == (sqrt(2), Tuple(1, 0), Symbol('alpha'))

    a = AlgebraicNumber(sqrt(2), [1, 2, 3])
    assert a.args == (sqrt(2), Tuple(1, 2, 3))
예제 #4
0
파일: rv.py 프로젝트: nvquang/gotit_sympy
def given(expr, condition=None, **kwargs):
    """ Conditional Random Expression
    From a random expression and a condition on that expression creates a new
    probability space from the condition and returns the same expression on that
    conditional probability space.

    Examples
    ========

    >>> from sympy.stats import given, density, Die
    >>> X = Die('X', 6)
    >>> Y = given(X, X > 3)
    >>> density(Y).dict
    {4: 1/3, 5: 1/3, 6: 1/3}

    Following convention, if the condition is a random symbol then that symbol
    is considered fixed.

    >>> from sympy.stats import Normal
    >>> from sympy import pprint
    >>> from sympy.abc import z

    >>> X = Normal('X', 0, 1)
    >>> Y = Normal('Y', 0, 1)
    >>> pprint(density(X + Y, Y)(z), use_unicode=False)
                    2
           -(-Y + z)
           -----------
      ___       2
    \/ 2 *e
    ------------------
             ____
         2*\/ pi
    """

    if not random_symbols(condition) or pspace_independent(expr, condition):
        return expr

    if isinstance(condition, RandomSymbol):
        condition = Eq(condition, condition.symbol)

    condsymbols = random_symbols(condition)
    if (isinstance(condition, Equality) and len(condsymbols) == 1
            and not isinstance(pspace(expr).domain, ConditionalDomain)):
        rv = tuple(condsymbols)[0]

        results = solveset(condition, rv)
        if isinstance(results, Intersection) and S.Reals in results.args:
            results = list(results.args[1])

        return sum(expr.subs(rv, res) for res in results)

    # Get full probability space of both the expression and the condition
    fullspace = pspace(Tuple(expr, condition))
    # Build new space given the condition
    space = fullspace.conditional_space(condition, **kwargs)
    # Dictionary to swap out RandomSymbols in expr with new RandomSymbols
    # That point to the new conditional space
    swapdict = rs_swap(fullspace.values, space.values)
    # Swap random variables in the expression
    expr = expr.xreplace(swapdict)
    return expr
예제 #5
0
def plot_implicit(expr, x_var=None, y_var=None, adaptive=True, depth=0,
                  points=300, line_color="blue", show=True, **kwargs):
    """A plot function to plot implicit equations / inequalities.

    Arguments
    =========

    - ``expr`` : The equation / inequality that is to be plotted.
    - ``x_var`` (optional) : symbol to plot on x-axis or tuple giving symbol
      and range as ``(symbol, xmin, xmax)``
    - ``y_var`` (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. 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 300.

    - ``show`` Boolean. Default value is True. If set to False, the plot will
        not be shown. See ``Plot`` for further information.

    - ``title`` string. The title for the plot.

    - ``xlabel`` string. The label for the x-axis

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

    Aesthetics options:

    - ``line_color``: float or string. Specifies the color for the plot.
        See ``Plot`` to see how to set color for the plots.
        Default value is "Blue"

    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:

    .. plot::
        :context: reset
        :format: doctest
        :include-source: True

        >>> from sympy import plot_implicit, symbols, Eq, And
        >>> x, y = symbols('x y')

    Without any ranges for the symbols in the expression:

    .. plot::
        :context: close-figs
        :format: doctest
        :include-source: True

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

    With the range for the symbols:

    .. plot::
        :context: close-figs
        :format: doctest
        :include-source: True

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

    With depth of recursion as argument:

    .. plot::
        :context: close-figs
        :format: doctest
        :include-source: True

        >>> 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:

    .. plot::
        :context: close-figs
        :format: doctest
        :include-source: True

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

    Using mesh grid without using adaptive meshing with number of points
    specified:

    .. plot::
        :context: close-figs
        :format: doctest
        :include-source: True

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

    Plotting regions:

    .. plot::
        :context: close-figs
        :format: doctest
        :include-source: True

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

    Plotting Using boolean conjunctions:

    .. plot::
        :context: close-figs
        :format: doctest
        :include-source: True

        >>> 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:

    .. plot::
        :context: close-figs
        :format: doctest
        :include-source: True

        >>> p8 = plot_implicit(y - 1, y_var=y)
        >>> p9 = plot_implicit(x - 1, x_var=x)
    """
    has_equality = False  # Represents whether the expression contains an Equality,
                     #GreaterThan or LessThan

    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, 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])

    #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, adaptive, depth,
                                    points, line_color)

    #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
예제 #6
0
def eval_sum_symbolic(f, limits):
    from sympy.functions import harmonic, bernoulli

    f_orig = f
    (i, a, b) = limits
    if not f.has(i):
        return f * (b - a + 1)

    # Linearity
    if f.is_Mul:
        # Try factor out everything not including i
        without_i, with_i = f.as_independent(i)
        if without_i != 1:
            s = eval_sum_symbolic(with_i, (i, a, b))
            if s:
                r = without_i * s
                if r is not S.NaN:
                    return r
        else:
            # Try term by term
            L, R = f.as_two_terms()

            if not L.has(i):
                sR = eval_sum_symbolic(R, (i, a, b))
                if sR:
                    return L * sR

            if not R.has(i):
                sL = eval_sum_symbolic(L, (i, a, b))
                if sL:
                    return sL * R
        try:
            f = apart(f, i)  # see if it becomes an Add
        except PolynomialError:
            pass

    if f.is_Add:
        L, R = f.as_two_terms()
        lrsum = telescopic(L, R, (i, a, b))

        if lrsum:
            return lrsum

        # Try factor out everything not including i
        without_i, with_i = f.as_independent(i)
        if without_i != 0:
            s = eval_sum_symbolic(with_i, (i, a, b))
            if s:
                r = without_i * (b - a + 1) + s
                if r is not S.NaN:
                    return r
        else:
            # Try term by term
            lsum = eval_sum_symbolic(L, (i, a, b))
            rsum = eval_sum_symbolic(R, (i, a, b))

            if None not in (lsum, rsum):
                r = lsum + rsum
                if r is not S.NaN:
                    return r

    # Polynomial terms with Faulhaber's formula
    n = Wild('n')
    result = f.match(i**n)

    if result is not None:
        n = result[n]

        if n.is_Integer:
            if n >= 0:
                if (b is S.Infinity and not a is S.NegativeInfinity) or \
                   (a is S.NegativeInfinity and not b is S.Infinity):
                    return S.Infinity
                return ((bernoulli(n + 1, b + 1) - bernoulli(n + 1, a)) /
                        (n + 1)).expand()
            elif a.is_Integer and a >= 1:
                if n == -1:
                    return harmonic(b) - harmonic(a - 1)
                else:
                    return harmonic(b, abs(n)) - harmonic(a - 1, abs(n))

    if not (a.has(S.Infinity, S.NegativeInfinity)
            or b.has(S.Infinity, S.NegativeInfinity)):
        # Geometric terms
        c1 = Wild('c1', exclude=[i])
        c2 = Wild('c2', exclude=[i])
        c3 = Wild('c3', exclude=[i])
        wexp = Wild('wexp')

        # Here we first attempt powsimp on f for easier matching with the
        # exponential pattern, and attempt expansion on the exponent for easier
        # matching with the linear pattern.
        e = f.powsimp().match(c1**wexp)
        if e is not None:
            e_exp = e.pop(wexp).expand().match(c2 * i + c3)
            if e_exp is not None:
                e.update(e_exp)

        if e is not None:
            p = (c1**c3).subs(e)
            q = (c1**c2).subs(e)

            r = p * (q**a - q**(b + 1)) / (1 - q)
            l = p * (b - a + 1)

            return Piecewise((l, Eq(q, S.One)), (r, True))

        r = gosper_sum(f, (i, a, b))

        if isinstance(r, (Mul, Add)):
            from sympy import ordered, Tuple
            non_limit = r.free_symbols - Tuple(*limits[1:]).free_symbols
            den = denom(together(r))
            den_sym = non_limit & den.free_symbols
            args = []
            for v in ordered(den_sym):
                try:
                    s = solve(den, v)
                    m = Eq(v, s[0]) if s else S.false
                    if m != False:
                        args.append((Sum(f_orig.subs(*m.args),
                                         limits).doit(), m))
                    break
                except NotImplementedError:
                    continue

            args.append((r, True))
            return Piecewise(*args)

        if not r in (None, S.NaN):
            return r

    h = eval_sum_hyper(f_orig, (i, a, b))
    if h is not None:
        return h

    factored = f_orig.factor()
    if factored != f_orig:
        return eval_sum_symbolic(factored, (i, a, b))
예제 #7
0
def plot_implicit(expr, *args, **kwargs):
    """A plot function to plot implicit equations / inequalities.

    Arguments
    =========

    - ``expr`` : The equation / inequality that is to be plotted.
    - ``(x, xmin, xmax)`` optional, 3-tuple denoting the range of symbol
      ``x``
    - ``(y, ymin, ymax)`` optional, 3-tuple denoting the range of symbol
      ``y``

    The following arguments can be passed as named parameters.

    - ``adaptive``. Boolean. 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`` string .The title for the plot.

    - ``xlabel`` string. The label for the x - axis

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

    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 sympy import plot_implicit, cos, sin, symbols, Eq
    >>> x, y = symbols('x y')

    Without any ranges for the symbols in the expression

    >>> p1 = plot_implicit(Eq(x**2 + y**2, 5)) #doctest: +SKIP

    With the range for the symbols

    >>> p2 = plot_implicit(Eq(x**2 + y**2, 3), (x, -3, 3), (y, -3, 3)) #doctest: +SKIP

    With depth of recursion as argument.

    >>> p3 = plot_implicit(Eq(x**2 + y**2, 5), (x, -4, 4), (y, -4, 4), depth = 2) #doctest: +SKIP

    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) #doctest: +SKIP

    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) #doctest: +SKIP

    Plotting regions.

    >>> p6 = plot_implicit(y > x**2) #doctest: +SKIP

    Plotting Using boolean conjunctions.

    >>> p7 = plot_implicit(And(y > x, y > -x)) #doctest: +SKIP
    """

    assert isinstance(expr, Expr)
    has_equality = False #Represents whether the expression contains an Equality,
                     #GreaterThan or LessThan

    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

    free_symbols = set(expr.free_symbols)
    range_symbols = set([t[0] for t in args])
    symbols = set_union(free_symbols, range_symbols)
    if len(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)
    if len(args) == 2:
        var_start_end_x = args[0]
        var_start_end_y = args[1]
    elif len(args) == 1:
        if len(free_symbols) == 2:
            var_start_end_x = args[0]
            var_start_end_y, = (Tuple(e) + default_range
                                for e in (free_symbols - range_symbols))
        else:
            var_start_end_x, = (Tuple(e) + default_range for e in free_symbols)
            #Create a random symbol
            var_start_end_y = Tuple(Dummy()) + default_range

    elif len(args) == 0:
        if len(free_symbols) == 1:
            var_start_end_x, = (Tuple(e) + default_range for e in free_symbols)
            #create a random symbol
            var_start_end_y = Tuple(Dummy()) + default_range
        else:
            var_start_end_x, var_start_end_y = (Tuple(e) + default_range
                                                for e in free_symbols)

    use_interval = kwargs.pop('adaptive', True)
    nb_of_points = kwargs.pop('points', 300)
    depth = kwargs.pop('depth', 0)
    #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)
    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:])
    p = Plot(series_argument, **kwargs)
    if show:
        p.show()
    return p
예제 #8
0
def test_divmod():
    assert divmod(S(12), S(8)) == Tuple(1, 4)
    assert divmod(-S(12), S(8)) == Tuple(-2, 4)
    assert divmod(S(0), S(1)) == Tuple(0, 0)
    raises(ZeroDivisionError, lambda: divmod(S(0), S(0)))
    raises(ZeroDivisionError, lambda: divmod(S(1), S(0)))
    assert divmod(S(12), 8) == Tuple(1, 4)
    assert divmod(12, S(8)) == Tuple(1, 4)

    assert divmod(S("2"), S("3/2")) == Tuple(S("1"), S("1/2"))
    assert divmod(S("3/2"), S("2")) == Tuple(S("0"), S("3/2"))
    assert divmod(S("2"), S("3.5")) == Tuple(S("0"), S("2"))
    assert divmod(S("3.5"), S("2")) == Tuple(S("1"), S("1.5"))
    assert divmod(S("2"), S("1/3")) == Tuple(S("6"), S("0"))
    assert divmod(S("1/3"), S("2")) == Tuple(S("0"), S("1/3"))
    assert divmod(S("2"), S("0.1")) == Tuple(S("20"), S("0"))
    assert divmod(S("0.1"), S("2")) == Tuple(S("0"), S("0.1"))
    assert divmod(S("2"), 2) == Tuple(S("1"), S("0"))
    assert divmod(2, S("2")) == Tuple(S("1"), S("0"))
    assert divmod(S("2"), 1.5) == Tuple(S("1"), S("0.5"))
    assert divmod(1.5, S("2")) == Tuple(S("0"), S("1.5"))
    assert divmod(0.3, S("2")) == Tuple(S("0"), S("0.3"))
    assert divmod(S("3/2"), S("3.5")) == Tuple(S("0"), S("3/2"))
    assert divmod(S("3.5"), S("3/2")) == Tuple(S("2"), S("0.5"))
    assert divmod(S("3/2"), S("1/3")) == Tuple(S("4"), Float("1/6"))
    assert divmod(S("1/3"), S("3/2")) == Tuple(S("0"), S("1/3"))
    assert divmod(S("3/2"), S("0.1")) == Tuple(S("15"), S("0"))
    assert divmod(S("0.1"), S("3/2")) == Tuple(S("0"), S("0.1"))
    assert divmod(S("3/2"), 2) == Tuple(S("0"), S("3/2"))
    assert divmod(2, S("3/2")) == Tuple(S("1"), S("0.5"))
    assert divmod(S("3/2"), 1.5) == Tuple(S("1"), S("0"))
    assert divmod(1.5, S("3/2")) == Tuple(S("1"), S("0"))
    assert divmod(S("3/2"), 0.3) == Tuple(S("5"), S("0"))
    assert divmod(0.3, S("3/2")) == Tuple(S("0"), S("0.3"))
    assert divmod(S("1/3"), S("3.5")) == Tuple(S("0"), S("1/3"))
    assert divmod(S("3.5"), S("0.1")) == Tuple(S("35"), S("0"))
    assert divmod(S("0.1"), S("3.5")) == Tuple(S("0"), S("0.1"))
    assert divmod(S("3.5"), 2) == Tuple(S("1"), S("1.5"))
    assert divmod(2, S("3.5")) == Tuple(S("0"), S("2"))
    assert divmod(S("3.5"), 1.5) == Tuple(S("2"), S("0.5"))
    assert divmod(1.5, S("3.5")) == Tuple(S("0"), S("1.5"))
    assert divmod(0.3, S("3.5")) == Tuple(S("0"), S("0.3"))
    assert divmod(S("0.1"), S("1/3")) == Tuple(S("0"), S("0.1"))
    assert divmod(S("1/3"), 2) == Tuple(S("0"), S("1/3"))
    assert divmod(2, S("1/3")) == Tuple(S("6"), S("0"))
    assert divmod(S("1/3"), 1.5) == Tuple(S("0"), S("1/3"))
    assert divmod(0.3, S("1/3")) == Tuple(S("0"), S("0.3"))
    assert divmod(S("0.1"), 2) == Tuple(S("0"), S("0.1"))
    assert divmod(2, S("0.1")) == Tuple(S("20"), S("0"))
    assert divmod(S("0.1"), 1.5) == Tuple(S("0"), S("0.1"))
    assert divmod(1.5, S("0.1")) == Tuple(S("15"), S("0"))
    assert divmod(S("0.1"), 0.3) == Tuple(S("0"), S("0.1"))

    assert str(divmod(S("2"), 0.3)) == '(6, 0.2)'
    assert str(divmod(S("3.5"), S("1/3"))) == '(10, 0.166666666666667)'
    assert str(divmod(S("3.5"), 0.3)) == '(11, 0.2)'
    assert str(divmod(S("1/3"), S("0.1"))) == '(3, 0.0333333333333333)'
    assert str(divmod(1.5, S("1/3"))) == '(4, 0.166666666666667)'
    assert str(divmod(S("1/3"), 0.3)) == '(1, 0.0333333333333333)'
    assert str(divmod(0.3, S("0.1"))) == '(2, 0.1)'

    assert divmod(-3, S(2)) == (-2, 1)
    assert divmod(S(-3), S(2)) == (-2, 1)
    assert divmod(S(-3), 2) == (-2, 1)
예제 #9
0
def linear_factors(expr, *syms):
    """Reduce a Matrix Expression to a sum of linear factors

    Given symbols and a matrix expression linear in those symbols return a
    dict mapping symbol to the linear factor

    >>> from sympy import MatrixSymbol, linear_factors, symbols
    >>> n, m, l = symbols('n m l')
    >>> A = MatrixSymbol('A', n, m)
    >>> B = MatrixSymbol('B', m, l)
    >>> C = MatrixSymbol('C', n, l)
    >>> linear_factors(2*A*B + C, B, C)
    {B: 2*A, C: I}
    """

    expr = matrixify(expand(expr))
    d = {}
    if expr.is_Matrix and expr.is_Symbol:
        if expr in syms:
            d[expr] = Identity(expr.rows)

    if expr.is_Add:
        for sym in syms:
            total_factor = 0
            for arg in expr.args:
                factor = arg.coeff(sym)
                if not factor:
                    # .coeff fails when powers are in the expression
                    if sym in arg.free_symbols:
                        raise ValueError("Expression not linear in symbols")
                    else:
                        factor = 0
                factor = sympify(factor)
                if not factor.is_Matrix:
                    if factor.is_zero:
                        factor = ZeroMatrix(expr.rows, sym.rows)
                        if not sym.cols == expr.cols:
                            raise ShapeError(
                            "%s not compatible as factor of %s"%(sym, expr))
                    else:
                        factor = Identity(sym.rows)*factor
                total_factor += factor
            d[sym] = total_factor
    elif expr.is_Mul:
        for sym in syms:
            factor = expr.coeff(sym)
            if not factor:
                # .coeff fails when powers are in the expression
                if sym in expr.free_symbols:
                    raise ValueError("Expression not linear in symbols")
                else:
                    factor = 0
            factor = sympify(factor)
            if not factor.is_Matrix:
                if factor.is_zero:
                    factor = ZeroMatrix(expr.rows, sym.rows)
                    if not sym.cols == expr.cols:
                        raise ShapeError("%s not compatible as factor of %s"%
                                (sym, expr))
                else:
                    factor = Identity(sym.rows)*factor
            d[sym] = factor

    if any(sym in matrix_symbols(Tuple(*d.values())) for sym in syms):
        raise ValueError("Expression not linear in symbols")

    return d
예제 #10
0
 def _eval_subs(self, old, new):
     # only do substitutions in shape
     shape = Tuple(*self.shape)._subs(old, new)
     return MatrixSymbol(self.name, *shape)
예제 #11
0
파일: plot.py 프로젝트: vperic/sympy
    def add_variables_and_ranges(plot):
        """make sure all limits are in the form (symbol, a, b)"""

        # find where the limits begin and expressions end
        for i in range(len(plot)):
            if isinstance(plot[i], Tuple):
                break
        else:
            i = len(plot) + 1
        exprs = list(plot[:i])
        assert all(isinstance(e, Expr) for e in exprs)
        assert all(isinstance(t, Tuple) for t in plot[i:])

        ranges = set([i for i in plot[i:] if isinstance(i, Tuple) and len(i) > 1])
        range_variables = set([t[0] for t in ranges if len(t) == 3])
        expr_free = set_union(*[e.free_symbols for e in exprs if isinstance(e, Expr)])

        default_range = Tuple(-10, 10)

        # unambiguous cases for limits
        #   no ranges
        if not ranges:
            plot = exprs + [Tuple(e) + default_range for e in expr_free or [Dummy()]]

        #   all limits of length 3
        elif all(len(i) == 3 for i in ranges):
            pass

        #   all ranges the same
        elif len(ranges) == 1:
            range1 = ranges.pop()
            if len(range1) == 2:
                plot = exprs + [Tuple(x) + range1 for x in expr_free]

        #   ranges cover free variables of expression
        elif expr_free < range_variables:
            plot = exprs + [i if len(i) == 3 else Tuple(Dummy()) + i for i in ranges]

        #   ranges cover all but 1 free variable
        elif len(expr_free - range_variables) == 1:
            x = (expr_free - range_variables).pop()
            ranges = list(ranges)
            for i, ri in enumerate(ranges):
                if len(ri) == 2:
                    ranges[i] = Tuple(x) + ri
                    break
            else:
                ranges.append(Tuple(x) + default_range)
            for i, ri in enumerate(ranges):
                if len(ri) == 2:
                    ranges[i] = Tuple(Dummy()) + ri
            plot = exprs + ranges

        #   all implicit ranges
        elif all(len(i) == 2 for i in ranges):
            more = len(ranges) - len(expr_free)
            all_free = list(expr_free) + [Dummy() for i in range(more)]
            ranges = list(ranges)
            ranges.extend(-more*[default_range])
            plot = exprs + [Tuple(all_free[i]) + ri for i, ri in enumerate(ranges)]

        else:
            raise ValueError('erroneous or unanticipated range input')

        return plot
예제 #12
0
파일: plot.py 프로젝트: vperic/sympy
def plot(*args, **kwargs):
    """A plot function for interactive use.

    It implements many heuristics in order to guess what the user wants on
    incomplete input.

    There is also the 'show' argument that defaults to True (immediately
    showing the plot).

    The input arguments can be:
      - lists with coordinates for ploting a line in 2D or 3D
      - the expressions and variable lists with ranges in order to plot any of
        the following: 2d line, 2d parametric line, 3d parametric line,
        surface, parametric surface
         - if the variable lists do not provide ranges a default range is used
         - if the variables are not provided, the free variables are
           automatically supplied in the order they are sorted (e.g. x, y, z)
         - if neither variables nor ranges are provided, both are guessed
         - if multiple expressions are provided in a list all of them are
           plotted
      - an instance of BaseSeries() subclass
      - another Plot() instance
      - tuples containing any of the above mentioned options, for plotting them
        together

    In the case of 2D line and parametric plots, an adaptive sampling algorithm
    is used. The adaptive sampling algorithm recursively selects a random point
    in between two previously sampled points, which might lead to slightly
    different plots being rendered each time.

    Examples:
    ---------

    Plot expressions:
    >>> from sympy import plot, cos, sin, symbols
    >>> x,y,u,v = symbols('x y u v')
    >>> p1 = plot(x**2, show=False) # with default [-10,+10] range
    >>> p2 = plot(x**2, (0, 5), show=False) # it finds the free variable itself
    >>> p3 = plot(x**2, (x, 0, 5), show=False) # fully explicit

    Fully implicit examples (finding the free variable and using default
    range). For the explicit versions just add the tuples with ranges:
    >>> p4 = plot(x**2, show=False) # cartesian line
    >>> p5 = plot(cos(u), sin(u), show=False) # parametric line
    >>> p6 = plot(cos(u), sin(u), u, show=False) # parametric line in 3d
    >>> p7 = plot(x**2 + y**2, show=False) # cartesian surface
    >>> p8 = plot(u, v, u+v, show=False) # parametric surface

    Multiple plots per figure:
    >>> p9 = plot((x**2, ), (cos(u), sin(u)), show=False) # cartesian and parametric lines

    Set title or other options:
    >>> p10 = plot(x**2, title='second order polynomial', show=False)

    Plot a list of expressions:
    >>> p11 = plot([x, x**2, x**3], show=False)
    >>> p12 = plot([x, x**2, x**3], (0,2), show=False) # explicit range
    >>> p13 = plot([x*y, -x*y], show=False) # list of surfaces

    And you can even plot a Plot or a Series object:
    >>> a = plot(x, show=False)
    >>> p14 = plot(a, show=False) # plotting a plot object
    >>> p15 = plot(a[0], show=False) # plotting a series object

    """

    plot_arguments = [p for p in args if isinstance(p, Plot)]
    series_arguments = [p for p in args if isinstance(p, BaseSeries)]
    args = sympify([np for np in args if not isinstance(np, (Plot, BaseSeries))])


    # Are the arguments for only one plot or are they tuples with arguments
    # for many plots. If it is the latter make the Tuples into list so they are
    # mutable.
    # args = (x, (x, 10, 20)) vs args = ((x, (x, 10, 20)), (y, (y, 20, 30)))
    if all([isinstance(a, Tuple) for a in args]):
        list_of_plots = map(list, args)
    else:
        list_of_plots = [list(args), ]

    # Check for arguments containing lists of expressions for the same ranges.
    # args = (x**2, (x, 10, 20)) vs args = ([x**3, x**2], (x, 10, 20))
    list_arguments = [p for p in list_of_plots
                              if any(isinstance(a, list) for a in p)]
    list_of_plots = [p for p in list_of_plots
                             if not any(isinstance(a, list) for a in p)]

    def expand(plot):
        """
        >> expand(([1,2,3],(1,2),(4,5)))
        [[1, (1, 2), (4, 5)], [2, (1, 2), (4, 5)], [3, (1, 2), (4, 5)]]
        """
        lists = [i for i in plot if isinstance(i, list)]
        not_lists = [i for i in plot if not isinstance(i, list)]
        return [list(l) + not_lists for l in zip(*lists)]

    for a in list_arguments:
        list_of_plots.extend(expand(a))

    def add_variables_and_ranges(plot):
        """make sure all limits are in the form (symbol, a, b)"""

        # find where the limits begin and expressions end
        for i in range(len(plot)):
            if isinstance(plot[i], Tuple):
                break
        else:
            i = len(plot) + 1
        exprs = list(plot[:i])
        assert all(isinstance(e, Expr) for e in exprs)
        assert all(isinstance(t, Tuple) for t in plot[i:])

        ranges = set([i for i in plot[i:] if isinstance(i, Tuple) and len(i) > 1])
        range_variables = set([t[0] for t in ranges if len(t) == 3])
        expr_free = set_union(*[e.free_symbols for e in exprs if isinstance(e, Expr)])

        default_range = Tuple(-10, 10)

        # unambiguous cases for limits
        #   no ranges
        if not ranges:
            plot = exprs + [Tuple(e) + default_range for e in expr_free or [Dummy()]]

        #   all limits of length 3
        elif all(len(i) == 3 for i in ranges):
            pass

        #   all ranges the same
        elif len(ranges) == 1:
            range1 = ranges.pop()
            if len(range1) == 2:
                plot = exprs + [Tuple(x) + range1 for x in expr_free]

        #   ranges cover free variables of expression
        elif expr_free < range_variables:
            plot = exprs + [i if len(i) == 3 else Tuple(Dummy()) + i for i in ranges]

        #   ranges cover all but 1 free variable
        elif len(expr_free - range_variables) == 1:
            x = (expr_free - range_variables).pop()
            ranges = list(ranges)
            for i, ri in enumerate(ranges):
                if len(ri) == 2:
                    ranges[i] = Tuple(x) + ri
                    break
            else:
                ranges.append(Tuple(x) + default_range)
            for i, ri in enumerate(ranges):
                if len(ri) == 2:
                    ranges[i] = Tuple(Dummy()) + ri
            plot = exprs + ranges

        #   all implicit ranges
        elif all(len(i) == 2 for i in ranges):
            more = len(ranges) - len(expr_free)
            all_free = list(expr_free) + [Dummy() for i in range(more)]
            ranges = list(ranges)
            ranges.extend(-more*[default_range])
            plot = exprs + [Tuple(all_free[i]) + ri for i, ri in enumerate(ranges)]

        else:
            raise ValueError('erroneous or unanticipated range input')

        return plot

    list_of_plots = [Tuple(*add_variables_and_ranges(pl)) for pl in list_of_plots]

    series_arguments.extend([OverloadedSeriesFactory(*pl) for pl in list_of_plots])

    show = kwargs.pop('show', True)
    p = Plot(*series_arguments, **kwargs)
    for plot_argument in plot_arguments:
        p.extend(plot_argument)
    if show:
        p.show()
    return p
예제 #13
0
    def eval(cls, expr):

        types = (VectorFunction, ScalarFunction, DifferentialOperator)

        if isinstance(expr, _logical_partial_derivatives):
            atom    = get_atom_logical_derivatives(expr)
            indices = get_index_logical_derivatives(expr)

            if cls in _logical_partial_derivatives:
                indices[cls.coordinate] += 1

            for i,n in enumerate(list(indices.values())[::-1]):
                d = _logical_partial_derivatives[-i-1]
                for _ in range(n):
                    atom = d(atom, evaluate=False)

            if cls in _partial_derivatives:
                atom = cls(atom, evaluate=False)
            elif cls not in _logical_partial_derivatives:
                raise NotImplementedError('TODO')

            return atom

        if isinstance(expr, VectorFunction):
            n = expr.shape[0]
            args = [cls(expr[i], evaluate=False) for i in range(0, n)]
            args = Tuple(*args)
            return Matrix([args])
        elif isinstance(expr, (list, tuple, Tuple)):
            args = [cls(i, evaluate=True) for i in expr]
            args = Tuple(*args)
            return Matrix([args])
        elif isinstance(expr, (Matrix, ImmutableDenseMatrix)):
            newexpr = Matrix.zeros(*expr.shape)
            for i in range(expr.shape[0]):
                for j in range(expr.shape[1]):
                    newexpr[i,j] = cls(expr[i,j], evaluate=True)
            return type(expr)(newexpr)
        elif isinstance(expr, (IndexedVectorFunction, DifferentialOperator)):
            return cls(expr, evaluate=False)

        elif isinstance(expr, ScalarFunction):
            return cls(expr, evaluate=False)

        elif isinstance(expr, (minus, plus)):
            return cls(expr, evaluate=False)

        elif isinstance(expr, Indexed) and isinstance(expr.base, BasicMapping):
            return cls(expr, evaluate=False)
        elif not has(expr, types):
            if expr.is_number:
                return S.Zero

            elif isinstance(expr, Expr):
                x = Symbol(cls.coordinate)
                if cls.logical:
                    M = expr.atoms(Mapping)
                    if len(M)>0:
                        M = list(M)[0]
                        expr_primes = [diff(expr, M[i]) for i in range(M.pdim)]
                        Jj = Jacobian(M)[:,cls.grad_index]
                        expr_prime = sum([ei*Jji for ei,Jji in zip(expr_primes, Jj)])
                        return expr_prime + diff(expr, x)
                return diff(expr, x)


        if isinstance(expr, Add):
            args = [cls(a, evaluate=True) for a in expr.args]
            v    = Add(*args)
            return v

        elif isinstance(expr, Mul):
            coeffs  = [a for a in expr.args if isinstance(a, _coeffs_registery)]
            vectors = [a for a in expr.args if not(a in coeffs)]

            c = S.One
            if coeffs:
                c = Mul(*coeffs)

            V = S.Zero
            if vectors:
                if len(vectors) == 1:
                    # do we need to use Mul?
                    V = cls(vectors[0], evaluate=True)

                elif len(vectors) == 2:
                    a = vectors[0]
                    b = vectors[1]

                    fa = cls(a, evaluate=True)
                    fb = cls(b, evaluate=True)

                    V = a * fb + fa * b

                else:
                    a = vectors[0]
                    b = Mul(*vectors[1:])

                    fa = cls(a, evaluate=True)
                    fb = cls(b, evaluate=True)

                    V = a * fb + fa * b

            v = Mul(c, V)
            return v

        elif isinstance(expr, Pow):
            b = expr.base
            e = expr.exp
            v = (log(b)*cls(e, evaluate=True) + e*cls(b, evaluate=True)/b) * b**e
            return v

        else:
            msg = '{expr} of type {type}'.format(expr=expr, type=type(expr))
            raise NotImplementedError(msg)
예제 #14
0
def test_Tuple_tuple_count():
    assert Tuple(0, 1, 2, 3).tuple_count(4) == 0
    assert Tuple(0, 4, 1, 2, 3).tuple_count(4) == 1
    assert Tuple(0, 4, 1, 4, 2, 3).tuple_count(4) == 2
    assert Tuple(0, 4, 1, 4, 2, 4, 3).tuple_count(4) == 3
예제 #15
0
def test_Tuple_comparision():
    assert (Tuple(1, 3) >= Tuple(-10, 30)) is True
    assert (Tuple(1, 3) <= Tuple(-10, 30)) is False
    assert (Tuple(1, 3) >= Tuple(1, 3)) is True
    assert (Tuple(1, 3) <= Tuple(1, 3)) is True
예제 #16
0
def test_Tuple():
    t = (1, 2, 3, 4)
    st = Tuple(*t)
    assert set(sympify(t)) == set(st)
    assert len(t) == len(st)
    assert set(sympify(t[:2])) == set(st[:2])
    assert isinstance(st[:], Tuple)
    assert st == Tuple(1, 2, 3, 4)
    assert st.func(*st.args) == st
    p, q, r, s = symbols('p q r s')
    t2 = (p, q, r, s)
    st2 = Tuple(*t2)
    assert st2.atoms() == set(t2)
    assert st == st2.subs({p: 1, q: 2, r: 3, s: 4})
    # issue 2406
    assert all(isinstance(arg, Basic) for arg in st.args)
    assert Tuple(p, 1).subs(p, 0) == Tuple(0, 1)
    assert Tuple(p, Tuple(p, 1)).subs(p, 0) == Tuple(0, Tuple(0, 1))

    assert Tuple(t2) == Tuple(Tuple(*t2))
    assert Tuple.fromiter(t2) == Tuple(*t2)
    assert Tuple.fromiter(x for x in range(4)) == Tuple(0, 1, 2, 3)
    assert st2.fromiter(st2.args) == st2
예제 #17
0
def _sort_contraction_indices(pairing_indices):
    pairing_indices = [Tuple(*sorted(i)) for i in pairing_indices]
    pairing_indices.sort(key=lambda x: min(x))
    return pairing_indices
예제 #18
0
 def _construct_template_types(args):
     return Tuple(*args)
예제 #19
0
def test_as_Basic():
    assert as_Basic(1) is S.One
    assert as_Basic(()) == Tuple()
    raises(TypeError, lambda: as_Basic([]))
예제 #20
0
파일: bind_c.py 프로젝트: noushi/pyccel
def as_static_function(func, name=None):

    assert(isinstance(func, FunctionDef))

    args    = list(func.arguments)
    results = list(func.results)
    body    = func.body
    arguments_inout = func.arguments_inout
    functions = func.functions
    _results = []
    interfaces = func.interfaces

    # Convert array results to inout arguments
    for r in results:
        if r.rank > 0 and r not in args:
            args += [r]
            arguments_inout += [False]
        elif r.rank == 0:
            _results += [r]

    if name is None:
        name = 'bind_c_{}'.format(func.name).lower()

    # ...
    results_names = [i.name for i in _results]
    _args = []
    _arguments_inout = []

    for i_a, a in enumerate(args):
        if not isinstance(a, (Variable, FunctionAddress)):
            raise TypeError('Expecting a Variable or FunctionAddress type for {}'.format(a))
        if not isinstance(a, FunctionAddress) and a.rank > 0:
            # ...
            additional_args = []
            for i in range(a.rank):
                n_name = 'n{i}_{name}'.format(name=str(a.name), i=i)
                n_arg  = Variable('int', n_name, precision=4)

                additional_args += [n_arg]

            shape_new = Tuple(*additional_args, sympify=False)
            # ...

            _args += additional_args
            _arguments_inout += [False] * len(additional_args)

            a_new = Variable( a.dtype, a.name,
                              allocatable = a.allocatable,
                              is_pointer  = a.is_pointer,
                              is_target   = a.is_target,
                              is_optional = a.is_optional,
                              shape       = shape_new,
                              rank        = a.rank,
                              order       = a.order,
                              precision   = a.precision)

            if not( a.name in results_names ):
                _args += [a_new]

            else:
                _results += [a_new]

        else:
            _args += [a]

        intent = arguments_inout[i_a]
        _arguments_inout += [intent]
    args = _args
    results = _results
    arguments_inout = _arguments_inout
    # ...
    return BindCFunctionDef( name, list(args), results, body,
                        local_vars = func.local_vars,
                        is_static = True,
                        arguments_inout = arguments_inout,
                        functions = functions,
                        interfaces = interfaces,
                        imports = func.imports,
                        original_function = func,
                        doc_string = func.doc_string,
                        )
예제 #21
0
def test_issue_3982():
    a = [3, 2.0]
    assert sympify(a) == [Integer(3), Float(2.0)]
    assert sympify(tuple(a)) == Tuple(Integer(3), Float(2.0))
    assert sympify(set(a)) == set([Integer(3), Float(2.0)])
예제 #22
0
    def __new__(cls, name, transformation=None, parent=None, location=None,
                rotation_matrix=None, vector_names=None, variable_names=None):
        """
        The orientation/location parameters are necessary if this system
        is being defined at a certain orientation or location wrt another.

        Parameters
        ==========

        name : str
            The name of the new CoordSys3D instance.

        transformation : Lambda, Tuple, str
            Transformation defined by transformation equations or choosen
            from predefined ones.

        location : Vector
            The position vector of the new system's origin wrt the parent
            instance.

        rotation_matrix : SymPy ImmutableMatrix
            The rotation matrix of the new coordinate system with respect
            to the parent. In other words, the output of
            new_system.rotation_matrix(parent).

        parent : CoordSys3D
            The coordinate system wrt which the orientation/location
            (or both) is being defined.

        vector_names, variable_names : iterable(optional)
            Iterables of 3 strings each, with custom names for base
            vectors and base scalars of the new system respectively.
            Used for simple str printing.

        """

        name = str(name)
        Vector = sympy.vector.Vector
        BaseVector = sympy.vector.BaseVector
        Point = sympy.vector.Point

        if not isinstance(name, string_types):
            raise TypeError("name should be a string")

        if transformation is not None:
            if (location is not None) or (rotation_matrix is not None):
                raise ValueError("specify either `transformation` or "
                                 "`location`/`rotation_matrix`")
            if isinstance(transformation, (Tuple, tuple, list)):
                if isinstance(transformation[0], MatrixBase):
                    rotation_matrix = transformation[0]
                    location = transformation[1]
                else:
                    transformation = Lambda(transformation[0],
                                            transformation[1])
            elif isinstance(transformation, collections.Callable):
                x1, x2, x3 = symbols('x1 x2 x3', cls=Dummy)
                transformation = Lambda((x1, x2, x3),
                                        transformation(x1, x2, x3))
            elif isinstance(transformation, string_types):
                transformation = Symbol(transformation)
            elif isinstance(transformation, (Symbol, Lambda)):
                pass
            else:
                raise TypeError("transformation: "
                                "wrong type {0}".format(type(transformation)))

        # If orientation information has been provided, store
        # the rotation matrix accordingly
        if rotation_matrix is None:
            rotation_matrix = ImmutableDenseMatrix(eye(3))
        else:
            if not isinstance(rotation_matrix, MatrixBase):
                raise TypeError("rotation_matrix should be an Immutable" +
                                "Matrix instance")
            rotation_matrix = rotation_matrix.as_immutable()

        # If location information is not given, adjust the default
        # location as Vector.zero
        if parent is not None:
            if not isinstance(parent, CoordSys3D):
                raise TypeError("parent should be a " +
                                "CoordSys3D/None")
            if location is None:
                location = Vector.zero
            else:
                if not isinstance(location, Vector):
                    raise TypeError("location should be a Vector")
                # Check that location does not contain base
                # scalars
                for x in location.free_symbols:
                    if isinstance(x, BaseScalar):
                        raise ValueError("location should not contain" +
                                         " BaseScalars")
            origin = parent.origin.locate_new(name + '.origin',
                                              location)
        else:
            location = Vector.zero
            origin = Point(name + '.origin')

        if transformation is None:
            transformation = Tuple(rotation_matrix, location)

        if isinstance(transformation, Tuple):
            lambda_transformation = CoordSys3D._compose_rotation_and_translation(
                transformation[0],
                transformation[1],
                parent
            )
            r, l = transformation
            l = l._projections
            lambda_lame = CoordSys3D._get_lame_coeff('cartesian')
            lambda_inverse = lambda x, y, z: r.inv()*Matrix(
                [x-l[0], y-l[1], z-l[2]])
        elif isinstance(transformation, Symbol):
            trname = transformation.name
            lambda_transformation = CoordSys3D._get_transformation_lambdas(trname)
            if parent is not None:
                if parent.lame_coefficients() != (S(1), S(1), S(1)):
                    raise ValueError('Parent for pre-defined coordinate '
                                 'system should be Cartesian.')
            lambda_lame = CoordSys3D._get_lame_coeff(trname)
            lambda_inverse = CoordSys3D._set_inv_trans_equations(trname)
        elif isinstance(transformation, Lambda):
            if not CoordSys3D._check_orthogonality(transformation):
                raise ValueError("The transformation equation does not "
                                 "create orthogonal coordinate system")
            lambda_transformation = transformation
            lambda_lame = CoordSys3D._calculate_lame_coeff(lambda_transformation)
            lambda_inverse = None
        else:
            lambda_transformation = lambda x, y, z: transformation(x, y, z)
            lambda_lame = CoordSys3D._get_lame_coeff(transformation)
            lambda_inverse = None

        if variable_names is None:
            if isinstance(transformation, Lambda):
                variable_names = ["x1", "x2", "x3"]
            elif isinstance(transformation, Symbol):
                if transformation.name is 'spherical':
                    variable_names = ["r", "theta", "phi"]
                elif transformation.name is 'cylindrical':
                    variable_names = ["r", "theta", "z"]
                else:
                    variable_names = ["x", "y", "z"]
            else:
                variable_names = ["x", "y", "z"]
        if vector_names is None:
            vector_names = ["i", "j", "k"]

        # All systems that are defined as 'roots' are unequal, unless
        # they have the same name.
        # Systems defined at same orientation/position wrt the same
        # 'parent' are equal, irrespective of the name.
        # This is true even if the same orientation is provided via
        # different methods like Axis/Body/Space/Quaternion.
        # However, coincident systems may be seen as unequal if
        # positioned/oriented wrt different parents, even though
        # they may actually be 'coincident' wrt the root system.
        if parent is not None:
            obj = super(CoordSys3D, cls).__new__(
                cls, Symbol(name), transformation, parent)
        else:
            obj = super(CoordSys3D, cls).__new__(
                cls, Symbol(name), transformation)
        obj._name = name
        # Initialize the base vectors

        _check_strings('vector_names', vector_names)
        vector_names = list(vector_names)
        latex_vects = [(r'\mathbf{\hat{%s}_{%s}}' % (x, name)) for
                           x in vector_names]
        pretty_vects = [(name + '_' + x) for x in vector_names]

        obj._vector_names = vector_names

        v1 = BaseVector(0, obj, pretty_vects[0], latex_vects[0])
        v2 = BaseVector(1, obj, pretty_vects[1], latex_vects[1])
        v3 = BaseVector(2, obj, pretty_vects[2], latex_vects[2])

        obj._base_vectors = (v1, v2, v3)

        # Initialize the base scalars

        _check_strings('variable_names', vector_names)
        variable_names = list(variable_names)
        latex_scalars = [(r"\mathbf{{%s}_{%s}}" % (x, name)) for
                         x in variable_names]
        pretty_scalars = [(name + '_' + x) for x in variable_names]

        obj._variable_names = variable_names
        obj._vector_names = vector_names

        x1 = BaseScalar(0, obj, pretty_scalars[0], latex_scalars[0])
        x2 = BaseScalar(1, obj, pretty_scalars[1], latex_scalars[1])
        x3 = BaseScalar(2, obj, pretty_scalars[2], latex_scalars[2])

        obj._base_scalars = (x1, x2, x3)

        obj._transformation = transformation
        obj._transformation_lambda = lambda_transformation
        obj._lame_coefficients = lambda_lame(x1, x2, x3)
        obj._transformation_from_parent_lambda = lambda_inverse

        setattr(obj, variable_names[0], x1)
        setattr(obj, variable_names[1], x2)
        setattr(obj, variable_names[2], x3)

        setattr(obj, vector_names[0], v1)
        setattr(obj, vector_names[1], v2)
        setattr(obj, vector_names[2], v3)

        # Assign params
        obj._parent = parent
        if obj._parent is not None:
            obj._root = obj._parent._root
        else:
            obj._root = obj

        obj._parent_rotation_matrix = rotation_matrix
        obj._origin = origin

        # Return the instance
        return obj
예제 #23
0
def test_ImageSet():
    raises(ValueError, lambda: ImageSet(x, S.Integers))
    assert ImageSet(Lambda(x, 1), S.Integers) == FiniteSet(1)
    assert ImageSet(Lambda(x, y), S.Integers) == {y}
    assert ImageSet(Lambda(x, 1), S.EmptySet) == S.EmptySet
    empty = Intersection(FiniteSet(log(2) / pi), S.Integers)
    assert unchanged(ImageSet, Lambda(x, 1), empty)  # issue #17471
    squares = ImageSet(Lambda(x, x**2), S.Naturals)
    assert 4 in squares
    assert 5 not in squares
    assert FiniteSet(*range(10)).intersect(squares) == FiniteSet(1, 4, 9)

    assert 16 not in squares.intersect(Interval(0, 10))

    si = iter(squares)
    a, b, c, d = next(si), next(si), next(si), next(si)
    assert (a, b, c, d) == (1, 4, 9, 16)

    harmonics = ImageSet(Lambda(x, 1 / x), S.Naturals)
    assert Rational(1, 5) in harmonics
    assert Rational(.25) in harmonics
    assert 0.25 not in harmonics
    assert Rational(.3) not in harmonics
    assert (1, 2) not in harmonics

    assert harmonics.is_iterable

    assert imageset(x, -x, Interval(0, 1)) == Interval(-1, 0)

    assert ImageSet(Lambda(x, x**2), Interval(0, 2)).doit() == Interval(0, 4)
    assert ImageSet(Lambda((x, y), 2 * x), {4}, {3}).doit() == FiniteSet(8)
    assert (ImageSet(Lambda((x, y), x + y), {1, 2, 3},
                     {10, 20, 30}).doit() == FiniteSet(11, 12, 13, 21, 22, 23,
                                                       31, 32, 33))

    c = Interval(1, 3) * Interval(1, 3)
    assert Tuple(2, 6) in ImageSet(Lambda(((x, y), ), (x, 2 * y)), c)
    assert Tuple(2, S.Half) in ImageSet(Lambda(((x, y), ), (x, 1 / y)), c)
    assert Tuple(2, -2) not in ImageSet(Lambda(((x, y), ), (x, y**2)), c)
    assert Tuple(2, -2) in ImageSet(Lambda(((x, y), ), (x, -2)), c)
    c3 = ProductSet(Interval(3, 7), Interval(8, 11), Interval(5, 9))
    assert Tuple(8, 3, 9) in ImageSet(Lambda(((t, y, x), ), (y, t, x)), c3)
    assert Tuple(Rational(1, 8), 3,
                 9) in ImageSet(Lambda(((t, y, x), ), (1 / y, t, x)), c3)
    assert 2 / pi not in ImageSet(Lambda(((x, y), ), 2 / x), c)
    assert 2 / S(100) not in ImageSet(Lambda(((x, y), ), 2 / x), c)
    assert Rational(2, 3) in ImageSet(Lambda(((x, y), ), 2 / x), c)

    S1 = imageset(lambda x, y: x + y, S.Integers, S.Naturals)
    assert S1.base_pset == ProductSet(S.Integers, S.Naturals)
    assert S1.base_sets == (S.Integers, S.Naturals)

    # Passing a set instead of a FiniteSet shouldn't raise
    assert unchanged(ImageSet, Lambda(x, x**2), {1, 2, 3})

    S2 = ImageSet(Lambda(((x, y), ), x + y), {(1, 2), (3, 4)})
    assert 3 in S2.doit()
    # FIXME: This doesn't yet work:
    #assert 3 in S2
    assert S2._contains(3) is None

    raises(TypeError, lambda: ImageSet(Lambda(x, x**2), 1))
예제 #24
0
def test_CodeBlock():
    c = CodeBlock(Assignment(x, 1), Assignment(y, x + 1))
    assert c.func(*c.args) == c

    assert c.left_hand_sides == Tuple(x, y)
    assert c.right_hand_sides == Tuple(1, x + 1)
예제 #25
0
 def _range_tuple(s):
     if isinstance(s, 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)
예제 #26
0
def test_deriv1():
    # These all requre derivatives evaluated at a point (issue 4719) to work.
    # See issue 4624
    assert f(
        2 * x).diff(x) == 2 * Subs(Derivative(f(x), x), Tuple(x), Tuple(2 * x))
    assert (f(x)**3).diff(x) == 3 * f(x)**2 * f(x).diff(x)
    assert (f(2 * x)**3).diff(x) == 6 * f(2 * x)**2 * Subs(
        Derivative(f(x), x), Tuple(x), Tuple(2 * x))

    assert f(2 + x).diff(x) == Subs(Derivative(f(x), x), Tuple(x),
                                    Tuple(x + 2))
    assert f(2 + 3 * x).diff(x) == 3 * Subs(Derivative(f(x), x), Tuple(x),
                                            Tuple(3 * x + 2))
    assert f(3 * sin(x)).diff(x) == 3 * cos(x) * Subs(Derivative(
        f(x), x), Tuple(x), Tuple(3 * sin(x)))

    # See issue 8510
    assert f(x, x + z).diff(x) == Subs(Derivative(f(y, x + z), y), Tuple(y), Tuple(x)) \
            + Subs(Derivative(f(x, y), y), Tuple(y), Tuple(x + z))
    assert f(x, x**2).diff(x) == Subs(Derivative(f(y, x**2), y), Tuple(y), Tuple(x)) \
            + 2*x*Subs(Derivative(f(x, y), y), Tuple(y), Tuple(x**2))
예제 #27
0
    def __new__(cls,
                base_dims,
                derived_dims=[],
                dimensional_dependencies={},
                name=None,
                descr=None):
        dimensional_dependencies = dict(dimensional_dependencies)

        if (name is not None) or (descr is not None):
            SymPyDeprecationWarning(
                deprecated_since_version="1.2",
                issue=13336,
                useinstead="do not define a `name` or `descr`",
            ).warn()

        def parse_dim(dim):
            if isinstance(dim, string_types):
                dim = Dimension(Symbol(dim))
            elif isinstance(dim, Dimension):
                pass
            elif isinstance(dim, Symbol):
                dim = Dimension(dim)
            else:
                raise TypeError("%s wrong type" % dim)
            return dim

        base_dims = [parse_dim(i) for i in base_dims]
        derived_dims = [parse_dim(i) for i in derived_dims]

        for dim in base_dims:
            dim = dim.name
            if (dim in dimensional_dependencies and
                (len(dimensional_dependencies[dim]) != 1
                 or dimensional_dependencies[dim].get(dim, None) != 1)):
                raise IndexError("Repeated value in base dimensions")
            dimensional_dependencies[dim] = Dict({dim: 1})

        def parse_dim_name(dim):
            if isinstance(dim, Dimension):
                return dim.name
            elif isinstance(dim, string_types):
                return Symbol(dim)
            elif isinstance(dim, Symbol):
                return dim
            else:
                raise TypeError("unrecognized type %s for %s" %
                                (type(dim), dim))

        for dim in dimensional_dependencies.keys():
            dim = parse_dim(dim)
            if (dim not in derived_dims) and (dim not in base_dims):
                derived_dims.append(dim)

        def parse_dict(d):
            return Dict({parse_dim_name(i): j for i, j in d.items()})

        # Make sure everything is a SymPy type:
        dimensional_dependencies = {
            parse_dim_name(i): parse_dict(j)
            for i, j in dimensional_dependencies.items()
        }

        for dim in derived_dims:
            if dim in base_dims:
                raise ValueError("Dimension %s both in base and derived" % dim)
            if dim.name not in dimensional_dependencies:
                # TODO: should this raise a warning?
                dimensional_dependencies[dim] = Dict({dim.name: 1})

        base_dims.sort(key=default_sort_key)
        derived_dims.sort(key=default_sort_key)

        base_dims = Tuple(*base_dims)
        derived_dims = Tuple(*derived_dims)
        dimensional_dependencies = Dict(
            {i: Dict(j)
             for i, j in dimensional_dependencies.items()})
        obj = Basic.__new__(cls, base_dims, derived_dims,
                            dimensional_dependencies)
        return obj
예제 #28
0
파일: rv.py 프로젝트: max-yue/sympy
def sample_iter(expr,
                condition=None,
                size=(1, ),
                library='scipy',
                numsamples=S.Infinity,
                **kwargs):
    """
    Returns an iterator of realizations from the expression given a condition

    Parameters
    ==========

    expr: Expr
        Random expression to be realized
    condition: Expr, optional
        A conditional expression
    size : int, tuple
        Represents size of each sample in numsamples
    numsamples: integer, optional
        Length of the iterator (defaults to infinity)

    Examples
    ========

    >>> from sympy.stats import Normal, sample_iter
    >>> X = Normal('X', 0, 1)
    >>> expr = X*X + 3
    >>> iterator = sample_iter(expr, numsamples=3) # doctest: +SKIP
    >>> list(iterator) # doctest: +SKIP
    [12, 4, 7]

    Returns
    =======

    sample_iter: iterator object
        iterator object containing the sample/samples of given expr

    See Also
    ========

    sample
    sampling_P
    sampling_E

    """
    if not import_module(library):
        raise ValueError("Failed to import %s" % library)

    if condition is not None:
        ps = pspace(Tuple(expr, condition))
    else:
        ps = pspace(expr)

    rvs = list(ps.values)
    if library == 'pymc3':
        # Currently unable to lambdify in pymc3
        # TODO : Remove 'pymc3' when lambdify accepts 'pymc3' as module
        fn = lambdify(rvs, expr, **kwargs)
    else:
        fn = lambdify(rvs, expr, modules=library, **kwargs)
    if condition is not None:
        given_fn = lambdify(rvs, condition, **kwargs)

    def return_generator():
        count = 0
        while count < numsamples:
            d = ps.sample(
                size=size,
                library=library)  # a dictionary that maps RVs to values
            args = [d[rv] for rv in rvs]

            if condition is not None:  # Check that these values satisfy the condition
                gd = given_fn(*args)
                if gd != True and gd != False:
                    raise ValueError(
                        "Conditions must not contain free symbols")
                if not gd:  # If the values don't satisfy then try again
                    continue

            yield fn(*args)
            count += 1

    return return_generator()
예제 #29
0
def balance_stoichiometry(reactants, products, substances=None,
                          substance_factory=Substance.from_formula,
                          parametric_symbols=None, underdetermined=True, allow_duplicates=False):
    """ Balances stoichiometric coefficients of a reaction

    Parameters
    ----------
    reactants : iterable of reactant keys
    products : iterable of product keys
    substances : OrderedDict or string or None
        Mapping reactant/product keys to instances of :class:`Substance`.
    substance_factory : callback
    parametric_symbols : generator of symbols
        Used to generate symbols for parametric solution for
        under-determined system of equations. Default is numbered "x-symbols" starting
        from 1.
    underdetermined : bool
        Allows to find a non-unique solution (in addition to a constant factor
        across all terms). Set to ``False`` to disallow (raise ValueError) on
        e.g. "C + O2 -> CO + CO2". Set to ``None`` if you want the symbols replaced
        so that the coefficients are the smallest possible positive (non-zero) integers.
    allow_duplicates : bool
        If False: raises an excpetion if keys appear in both ``reactants`` and ``products``.

    Examples
    --------
    >>> ref = {'C2H2': 2, 'O2': 3}, {'CO': 4, 'H2O': 2}
    >>> balance_stoichiometry({'C2H2', 'O2'}, {'CO', 'H2O'}) == ref
    True
    >>> ref2 = {'H2': 1, 'O2': 1}, {'H2O2': 1}
    >>> balance_stoichiometry('H2 O2'.split(), ['H2O2'], 'H2 O2 H2O2') == ref2
    True
    >>> reac, prod = 'CuSCN KIO3 HCl'.split(), 'CuSO4 KCl HCN ICl H2O'.split()
    >>> Reaction(*balance_stoichiometry(reac, prod)).string()
    '4 CuSCN + 7 KIO3 + 14 HCl -> 4 CuSO4 + 7 KCl + 4 HCN + 7 ICl + 5 H2O'
    >>> balance_stoichiometry({'Fe', 'O2'}, {'FeO', 'Fe2O3'}, underdetermined=False)
    Traceback (most recent call last):
        ...
    ValueError: The system was under-determined
    >>> r, p = balance_stoichiometry({'Fe', 'O2'}, {'FeO', 'Fe2O3'})
    >>> list(set.union(*[v.free_symbols for v in r.values()]))
    [x1]
    >>> b = balance_stoichiometry({'Fe', 'O2'}, {'FeO', 'Fe2O3'}, underdetermined=None)
    >>> b == ({'Fe': 3, 'O2': 2}, {'FeO': 1, 'Fe2O3': 1})
    True
    >>> d = balance_stoichiometry({'C', 'CO'}, {'C', 'CO', 'CO2'}, underdetermined=None, allow_duplicates=True)
    >>> d == ({'CO': 2}, {'C': 1, 'CO2': 1})
    True

    Returns
    -------
    balanced reactants : dict
    balanced products : dict

    """
    import sympy
    from sympy import (
        MutableDenseMatrix, gcd, zeros, linsolve, numbered_symbols, Wild, Symbol,
        Integer, Tuple, preorder_traversal as pre
    )

    _intersect = sorted(set.intersection(*map(set, (reactants, products))))
    if _intersect:
        if allow_duplicates:
            if underdetermined is not None:
                raise NotImplementedError("allow_duplicates currently requires underdetermined=None")
            if set(reactants) == set(products):
                raise ValueError("cannot balance: reactants and products identical")

            # For each duplicate, try to drop it completely:
            for dupl in _intersect:
                try:
                    result = balance_stoichiometry(
                        [sp for sp in reactants if sp != dupl],
                        [sp for sp in products if sp != dupl],
                        substances=substances, substance_factory=substance_factory,
                        underdetermined=underdetermined, allow_duplicates=True)
                except Exception:
                    continue
                else:
                    return result
            for perm in product(*[(False, True)]*len(_intersect)):  # brute force (naive)
                r = set(reactants)
                p = set(products)
                for remove_reac, dupl in zip(perm, _intersect):
                    if remove_reac:
                        r.remove(dupl)
                    else:
                        p.remove(dupl)
                try:
                    result = balance_stoichiometry(
                        r, p, substances=substances, substance_factory=substance_factory,
                        parametric_symbols=parametric_symbols, underdetermined=underdetermined,
                        allow_duplicates=False)
                except ValueError:
                    continue
                else:
                    return result
            else:
                raise ValueError("Failed to remove duplicate keys: %s" % _intersect)
        else:
            raise ValueError("Substances on both sides: %s" % str(_intersect))
    if substances is None:
        substances = OrderedDict([(k, substance_factory(k)) for k in chain(reactants, products)])
    if isinstance(substances, str):
        substances = OrderedDict([(k, substance_factory(k)) for k in substances.split()])
    if type(reactants) == set:  # we don't want isinstance since it might be "OrderedSet"
        reactants = sorted(reactants)
    if type(products) == set:
        products = sorted(products)
    subst_keys = list(reactants) + list(products)

    cks = Substance.composition_keys(substances.values())

    if parametric_symbols is None:
        parametric_symbols = numbered_symbols('x', start=1, integer=True, positive=True)

    # ?C2H2 + ?O2 -> ?CO + ?H2O
    # Ax = 0
    #   A:                    x:
    #
    #   C2H2   O2  CO  H2O
    # C -2     0    1   0      x0    =   0
    # H -2     0    0   2      x1        0
    # O  0    -2    1   1      x2        0
    #                          x3

    def _get(ck, sk):
        return substances[sk].composition.get(ck, 0) * (-1 if sk in reactants else 1)

    for ck in cks:  # check that all components are present on reactant & product sides
        for rk in reactants:
            if substances[rk].composition.get(ck, 0) != 0:
                break
        else:
            any_pos = any(substances[pk].composition.get(ck, 0) > 0 for pk in products)
            any_neg = any(substances[pk].composition.get(ck, 0) < 0 for pk in products)
            if any_pos and any_neg:
                pass  # negative and positive parts among products, no worries
            else:
                raise ValueError("Component '%s' not among reactants" % ck)

        for pk in products:
            if substances[pk].composition.get(ck, 0) != 0:
                break
        else:
            any_pos = any(substances[pk].composition.get(ck, 0) > 0 for pk in reactants)
            any_neg = any(substances[pk].composition.get(ck, 0) < 0 for pk in reactants)
            if any_pos and any_neg:
                pass  # negative and positive parts among reactants, no worries
            else:
                raise ValueError("Component '%s' not among products" % ck)

    A = MutableDenseMatrix([[_get(ck, sk) for sk in subst_keys] for ck in cks])
    symbs = list(reversed([next(parametric_symbols) for _ in range(len(subst_keys))]))
    sol, = linsolve((A, zeros(len(cks), 1)), symbs)
    wi = Wild('wi', properties=[lambda k: not k.has(Symbol)])
    cd = reduce(gcd, [1] + [1/m[wi] for m in map(
        lambda n: n.match(symbs[-1]/wi), pre(sol)) if m is not None])
    sol = sol.func(*[arg/cd for arg in sol.args])

    def remove(cont, symb, remaining):
        subsd = dict(zip(remaining/symb, remaining))
        cont = cont.func(*[(arg/symb).expand().subs(subsd) for arg in cont.args])
        if cont.has(symb):
            raise ValueError("Bug, please report an issue at https://github.com/bjodah/chempy")
        return cont

    done = False
    for idx, symb in enumerate(symbs):
        for expr in sol:
            iterable = expr.args if expr.is_Add else [expr]
            for term in iterable:
                if term.is_number:
                    done = True
                    break
            if done:
                break
        if done:
            break
        for expr in sol:
            if (expr/symb).is_number:
                sol = remove(sol, symb, MutableDenseMatrix(symbs[idx+1:]))
                break
    for symb in symbs:
        cd = 1
        for expr in sol:
            iterable = expr.args if expr.is_Add else [expr]
            for term in iterable:
                if term.is_Mul and term.args[0].is_number and term.args[1] == symb:
                    cd = gcd(cd, term.args[0])
        if cd != 1:
            sol = sol.func(*[arg.subs(symb, symb/cd) for arg in sol.args])
    integer_one = 1  # need 'is' check, SyntaxWarning when checking against literal
    if underdetermined is integer_one:
        from ._release import __version__
        if int(__version__.split('.')[1]) > 6:
            warnings.warn(  # deprecated because comparison with ``1`` problematic (True==1)
                ("Pass underdetermined == None instead of ``1`` (depreacted since 0.7.0,"
                 " will_be_missing_in='0.9.0')"), ChemPyDeprecationWarning)
        underdetermined = None
    if underdetermined is None:
        sol = Tuple(*[Integer(x) for x in _solve_balancing_ilp_pulp(A)])

    fact = gcd(sol)
    sol = MutableDenseMatrix([e/fact for e in sol]).reshape(len(sol), 1)
    sol /= reduce(gcd, sol)
    if 0 in sol:
        raise ValueError("Superfluous species given.")
    if underdetermined:
        if any(x == sympy.nan for x in sol):
            raise ValueError("Failed to balance reaction")
    else:
        for x in sol:
            if len(x.free_symbols) != 0:
                raise ValueError("The system was under-determined")
        if not all(residual == 0 for residual in A * sol):
            raise ValueError("Failed to balance reaction")

    def _x(k):
        coeff = sol[subst_keys.index(k)]
        return int(coeff) if underdetermined is None else coeff

    return (
        OrderedDict([(k, _x(k)) for k in reactants]),
        OrderedDict([(k, _x(k)) for k in products])
    )
예제 #30
0
파일: rv.py 프로젝트: max-yue/sympy
def given(expr, condition=None, **kwargs):
    r""" Conditional Random Expression
    From a random expression and a condition on that expression creates a new
    probability space from the condition and returns the same expression on that
    conditional probability space.

    Examples
    ========

    >>> from sympy.stats import given, density, Die
    >>> X = Die('X', 6)
    >>> Y = given(X, X > 3)
    >>> density(Y).dict
    {4: 1/3, 5: 1/3, 6: 1/3}

    Following convention, if the condition is a random symbol then that symbol
    is considered fixed.

    >>> from sympy.stats import Normal
    >>> from sympy import pprint
    >>> from sympy.abc import z

    >>> X = Normal('X', 0, 1)
    >>> Y = Normal('Y', 0, 1)
    >>> pprint(density(X + Y, Y)(z), use_unicode=False)
                    2
           -(-Y + z)
           -----------
      ___       2
    \/ 2 *e
    ------------------
             ____
         2*\/ pi
    """

    if not is_random(condition) or pspace_independent(expr, condition):
        return expr

    if isinstance(condition, RandomSymbol):
        condition = Eq(condition, condition.symbol)

    condsymbols = random_symbols(condition)
    if (isinstance(condition, Equality) and len(condsymbols) == 1
            and not isinstance(pspace(expr).domain, ConditionalDomain)):
        rv = tuple(condsymbols)[0]

        results = solveset(condition, rv)
        if isinstance(results, Intersection) and S.Reals in results.args:
            results = list(results.args[1])

        sums = 0
        for res in results:
            temp = expr.subs(rv, res)
            if temp == True:
                return True
            if temp != False:
                # XXX: This seems nonsensical but preserves existing behaviour
                # after the change that Relational is no longer a subclass of
                # Expr. Here expr is sometimes Relational and sometimes Expr
                # but we are trying to add them with +=. This needs to be
                # fixed somehow.
                if sums == 0 and isinstance(expr, Relational):
                    sums = expr.subs(rv, res)
                else:
                    sums += expr.subs(rv, res)
        if sums == 0:
            return False
        return sums

    # Get full probability space of both the expression and the condition
    fullspace = pspace(Tuple(expr, condition))
    # Build new space given the condition
    space = fullspace.conditional_space(condition, **kwargs)
    # Dictionary to swap out RandomSymbols in expr with new RandomSymbols
    # That point to the new conditional space
    swapdict = rs_swap(fullspace.values, space.values)
    # Swap random variables in the expression
    expr = expr.xreplace(swapdict)
    return expr
예제 #31
0
def test_sympyify_iterables():
    ans = [Rational(3, 10), Rational(1, 5)]
    assert sympify(['.3', '.2'], rational=True) == ans
    assert sympify(tuple(['.3', '.2']), rational=True) == Tuple(*ans)
    assert sympify(dict(x=0, y=1)) == {x: 0, y: 1}
    assert sympify(['1', '2', ['3', '4']]) == [S(1), S(2), [S(3), S(4)]]
예제 #32
0
def test_Tuple_equality():
    assert Tuple(1, 2) is not (1, 2)
    assert (Tuple(1, 2) == (1, 2)) is True
    assert (Tuple(1, 2) != (1, 2)) is False
    assert (Tuple(1, 2) == (1, 3)) is False
    assert (Tuple(1, 2) != (1, 3)) is True
    assert (Tuple(1, 2) == Tuple(1, 2)) is True
    assert (Tuple(1, 2) != Tuple(1, 2)) is False
    assert (Tuple(1, 2) == Tuple(1, 3)) is False
    assert (Tuple(1, 2) != Tuple(1, 3)) is True