Ejemplo n.º 1
0
def asintotas(f):
    # Igual usar singularities mejor: asintotas, verticales, horizontales y oblícuas (a,b) en oo y -oo
    asint = []
    asintex = r'Asíntotas:\\'
    asint.append([
        (i, limit(f, x, i))
        for i in list(S.Reals - continuous_domain(f, x, domain=S.Reals))
    ])
    asintex += ', '.join(
        r'A.V. $x=' + str(i) + r'$\\'
        for i in list(S.Reals - continuous_domain(f, x, domain=S.Reals)))
    if abs(limit(f, x, oo)) != oo:
        asintex += r'A.H. $y=' + latex(limit(f, x, oo)) + r'$\\'
    if abs(limit(f, x, -oo)) != oo:
        asintex += r'A.H. $y=' + latex(limit(f, x, -oo)) + r'$\\'

    asint.append([(oo, limit(f, x, oo)), (-oo, limit(f, x, -oo))])
    oblicuas = []
    if abs(limit(f / x, x, oo)) != oo:
        oblicuas.append((oo, limit(f / x, x, oo) * x +
                         limit(f - limit(f / x, x, oo) * x, x, oo)))
        #display(latex(limit(f/x,x,oo)*x+limit(f-limit(f/x,x,oo)*x,x,oo)))
        asintex += r'A.O. $y=' + latex(
            limit(f / x, x, oo) * x +
            limit(f - limit(f / x, x, oo) * x, x, oo)) + r'$ \\'
    if abs(limit(f / x, x, -oo)) != oo:
        oblicuas.append((-oo, limit(f / x, x, -oo) * x +
                         limit(f - limit(f / x, x, -oo) * x, x, -oo)))
        asintex += r'A.O. $y=' + latex(
            limit(f / x, x, -oo) * x +
            limit(f - limit(f / x, x, -oo) * x, x, -oo)) + r'$ \\'
    asint.append(oblicuas)
    return asint, asintex
Ejemplo n.º 2
0
def test_continuous_domain():
    x = Symbol('x')
    assert continuous_domain(sin(x), x, Interval(0, 2*pi)) == Interval(0, 2*pi)
    assert continuous_domain(tan(x), x, Interval(0, 2*pi)) == \
        Union(Interval(0, pi/2, False, True), Interval(pi/2, 3*pi/2, True, True),
              Interval(3*pi/2, 2*pi, True, False))
    assert continuous_domain((x - 1)/((x - 1)**2), x, S.Reals) == \
        Union(Interval(-oo, 1, True, True), Interval(1, oo, True, True))
    assert continuous_domain(log(x) + log(4*x - 1), x, S.Reals) == \
        Interval(1/4, oo, True, True)
    assert continuous_domain(1/sqrt(x - 3), x, S.Reals) == Interval(3, oo, True, True)
Ejemplo n.º 3
0
def test_continuous_domain():
    x = Symbol('x')
    assert continuous_domain(sin(x), x,
                             Interval(0, 2 * pi)) == Interval(0, 2 * pi)
    assert continuous_domain(tan(x), x, Interval(0, 2*pi)) == \
        Union(Interval(0, pi/2, False, True), Interval(pi/2, 3*pi/2, True, True),
              Interval(3*pi/2, 2*pi, True, False))
    assert continuous_domain((x - 1)/((x - 1)**2), x, S.Reals) == \
        Union(Interval(-oo, 1, True, True), Interval(1, oo, True, True))
    assert continuous_domain(log(x) + log(4*x - 1), x, S.Reals) == \
        Interval(1/4, oo, True, True)
    assert continuous_domain(1 / sqrt(x - 3), x,
                             S.Reals) == Interval(3, oo, True, True)
Ejemplo n.º 4
0
    def construct(self):
        expr2 = self.expr.subs(e, math.e)
        f = lambdify(x, expr2, 'numpy')

        domains = continuous_domain(self.expr, x,
                                    Interval(self.x_min, self.x_max))

        if type(domains) is Union:
            domains = domains.args
        else:
            domains = [domains]

        self.setup_axes(animate=True)

        func_graph = VGroup()

        for domain in domains:
            graph = self.get_graph(f, self.function_color,
                                   get_left_bound(domain),
                                   get_right_bound(domain))
            func_graph.add(graph)

        graph_lab = self.get_graph_label(func_graph[0], label=latex(self.expr))
        self.play(ShowCreation(func_graph, run_time=3))
        self.play(ShowCreation(graph_lab))
        self.wait(5)
Ejemplo n.º 5
0
def test_continuous_domain():
    x = Symbol('x')
    assert continuous_domain(sin(x), x, Interval(0, 2*pi)) == Interval(0, 2*pi)
    assert continuous_domain(tan(x), x, Interval(0, 2*pi)) == \
        Union(Interval(0, pi/2, False, True), Interval(pi/2, pi*Rational(3, 2), True, True),
              Interval(pi*Rational(3, 2), 2*pi, True, False))
    assert continuous_domain((x - 1)/((x - 1)**2), x, S.Reals) == \
        Union(Interval(-oo, 1, True, True), Interval(1, oo, True, True))
    assert continuous_domain(log(x) + log(4*x - 1), x, S.Reals) == \
        Interval(Rational(1, 4), oo, True, True)
    assert continuous_domain(1/sqrt(x - 3), x, S.Reals) == Interval(3, oo, True, True)
    assert continuous_domain(1/x - 2, x, S.Reals) == \
        Union(Interval.open(-oo, 0), Interval.open(0, oo))
    assert continuous_domain(1/(x**2 - 4) + 2, x, S.Reals) == \
        Union(Interval.open(-oo, -2), Interval.open(-2, 2), Interval.open(2, oo))
    domain = continuous_domain(log(tan(x)**2 + 1), x, S.Reals)
    assert not domain.contains(3*pi/2)
    assert domain.contains(5)
    d = Symbol('d', even=True, zero=False)
    assert continuous_domain(x**(1/d), x, S.Reals) == Interval(0, oo)
def find_real_domain(f, symbol):
    from sympy import symbols
    try:
        # We first need to make sure all variables are registered as being real, before
        # we pass into continuous_domain, as the Sage conversion doesn't preserved Reals.
        for sym in f.free_symbols.difference({symbol}):
            f = f.subs(sym, symbols(str(sym), real=True))

        new_symbol = symbols(str(symbol), real=True)
        f = f.subs(symbol, new_symbol)
        symbol = new_symbol

        return continuous_domain(f, symbol, S.Reals)
    except Exception as e:
        warnings.warn(
            "Failed to find the domain of: " + str(f) + "\n" + str(e),
            RuntimeWarning)
        return S.Reals
Ejemplo n.º 7
0
def estudio(f):
    # Estudio en una función a trozos

    set = S.Reals
    conj_singular = S.EmptySet
    for j, t in enumerate(f.args):
        #display(singularities(t[0],x))
        #conj_singular = Union(conj_singular,singularities(t[0],x))
        #display(Union(conj_singular,singularities(t[0],x)))
        #conj_singular = Union(conj_singular,Complement(S.Reals,continuous_domain(t[0],x,S.Reals)))
        #conj_singular = Union(conj_singular,Intersection(t[1].as_set(),Complement(S.Reals,continuous_domain(t[0],x,S.Reals))))
        set2 = Intersection(set, t[1].as_set())
        conj_singular = Union(
            conj_singular,
            Intersection(
                set2, Complement(S.Reals, continuous_domain(t[0], x,
                                                            S.Reals))))
        set = Complement(S.Reals, t[1].as_set())

    sol = r"Singularidades de las expresiones analíticas: $" + latex(
        conj_singular) + "$"
    sol += r".\\ Posibles discontinuidades en los extremos de los trozos:"

    xs = []
    estudio = []

    for j, t in enumerate(trozos(f)):
        xs.append(str(t[0]))
        if (t[1] == t[2]):
            estudio.append(
                r"\\En {} es continua ya que hay límite y $\lim = f({})={}$".
                format(t[0], t[0], t[3]))
            display(r"En $x_0={}$ hay límite y f({})={}".format(
                t[0], t[0], t[3]))
        else:
            estudio.append(
                r"\\En {} no es continua porque no existe límite. Límites laterales: ${}$ y ${}$"
                .format(t[0], latex(t[1]), latex(t[2])))
            display(
                r"En {} no existe límite. Límites laterales: {} y  {}".format(
                    t[0], t[1], t[2]))

    sol += ', '.join(xs) + r"." + '. '.join(estudio)
    return (sol)
Ejemplo n.º 8
0
    def __init__(self, function):  
        self.function = Explorer.get_sym(function)
        self.derivative = self.function.diff(x)
        self.derived_second = self.derivative.diff(x)
        self.domain = [continuous_domain(self.function, x, S.Reals)]
        self.y_point_of_intersection = (0, self.function.subs(x, 0))
        self.x_point_of_intersections = []        
        self.extremums = []
        self.inflection_points = []
        self.vertical_asymptote = []
        self.horizontal_asymptotes = []
        self.place_ud_ = []
        self.place_pn_ = []

        self.x_point_of_intersection()
        self.get_extremum()
        self.get_inflection_point()
        self.find_vertical_asymptote()
        self.find_horizontal_asymptote()
        # למשתנה שבשורה הבאה נוספו ערכי נקודת פיתול מכיוון שיכול להיות שהממוצע יצא אחד מהם
        self.list_of_changes = sorted([-oo, oo] + [xy[0] for m,xy in self.extremums] + self.vertical_asymptote + [xy[0] for un, xy, nu in self.inflection_points] + [xy[0] for xy in self.x_point_of_intersections])
        self.place_pn()
        self.place_ud()
Ejemplo n.º 9
0
def test_continuous_domain():
    x = Symbol("x")
    assert continuous_domain(sin(x), x,
                             Interval(0, 2 * pi)) == Interval(0, 2 * pi)
    assert continuous_domain(tan(x), x, Interval(0, 2 * pi)) == Union(
        Interval(0, pi / 2, False, True),
        Interval(pi / 2, pi * Rational(3, 2), True, True),
        Interval(pi * Rational(3, 2), 2 * pi, True, False),
    )
    assert continuous_domain((x - 1) / ((x - 1)**2), x,
                             S.Reals) == Union(Interval(-oo, 1, True, True),
                                               Interval(1, oo, True, True))
    assert continuous_domain(log(x) + log(4 * x - 1), x,
                             S.Reals) == Interval(Rational(1, 4), oo, True,
                                                  True)
    assert continuous_domain(1 / sqrt(x - 3), x,
                             S.Reals) == Interval(3, oo, True, True)
    assert continuous_domain(1 / x - 2, x,
                             S.Reals) == Union(Interval.open(-oo, 0),
                                               Interval.open(0, oo))
    assert continuous_domain(1 / (x**2 - 4) + 2, x,
                             S.Reals) == Union(Interval.open(-oo, -2),
                                               Interval.open(-2, 2),
                                               Interval.open(2, oo))
Ejemplo n.º 10
0
Archivo: plots.py Proyecto: seab1/WDA
from sympy import Symbol, Interval, Range
from sympy.calculus.util import continuous_domain
import numpy as np
import math
import matplotlib.pyplot as plt

x = Symbol("x")
y = input("Wprowadź wzór funkcji: f(x) = ")
y = eval(y)
x1 = float(input("Podaj początek przedziału: "))
x2 = float(input("Podaj koniec przedziału: "))
domain = continuous_domain(y, x, Interval(x1, x2))
view_range = np.arange(x1, x2 + 0.1, 0.01)
index = 0

for i in view_range:
    view_range[index] = round(view_range[index], 2)
    if i not in domain:
        np.delete(view_range, index)
        index -= 1
    index += 1
#end for

x = view_range
y = eval(str(y))

plt.plot(x, y)
plt.show()
Ejemplo n.º 11
0
def solve_univariate_inequality(expr, gen, relational=True, domain=S.Reals, continuous=False):
    """Solves a real univariate inequality.

    Parameters
    ==========

    expr : Relational
        The target inequality
    gen : Symbol
        The variable for which the inequality is solved
    relational : bool
        A Relational type output is expected or not
    domain : Set
        The domain over which the equation is solved
    continuous: bool
        True if expr is known to be continuous over the given domain
        (and so continuous_domain() doesn't need to be called on it)

    Raises
    ======

    NotImplementedError
        The solution of the inequality cannot be determined due to limitation
        in `solvify`.

    Notes
    =====

    Currently, we cannot solve all the inequalities due to limitations in
    `solvify`. Also, the solution returned for trigonometric inequalities
    are restricted in its periodic interval.

    See Also
    ========

    solvify: solver returning solveset solutions with solve's output API

    Examples
    ========

    >>> from sympy.solvers.inequalities import solve_univariate_inequality
    >>> from sympy import Symbol, sin, Interval, S
    >>> x = Symbol('x')

    >>> solve_univariate_inequality(x**2 >= 4, x)
    ((2 <= x) & (x < oo)) | ((x <= -2) & (-oo < x))

    >>> solve_univariate_inequality(x**2 >= 4, x, relational=False)
    Union(Interval(-oo, -2), Interval(2, oo))

    >>> domain = Interval(0, S.Infinity)
    >>> solve_univariate_inequality(x**2 >= 4, x, False, domain)
    Interval(2, oo)

    >>> solve_univariate_inequality(sin(x) > 0, x, relational=False)
    Interval.open(0, pi)

    """
    from sympy import im
    from sympy.calculus.util import (continuous_domain, periodicity,
        function_range)
    from sympy.solvers.solvers import denoms
    from sympy.solvers.solveset import solveset_real, solvify, solveset
    from sympy.solvers.solvers import solve

    # This keeps the function independent of the assumptions about `gen`.
    # `solveset` makes sure this function is called only when the domain is
    # real.
    _gen = gen
    _domain = domain
    if gen.is_real is False:
        rv = S.EmptySet
        return rv if not relational else rv.as_relational(_gen)
    elif gen.is_real is None:
        gen = Dummy('gen', real=True)
        try:
            expr = expr.xreplace({_gen: gen})
        except TypeError:
            raise TypeError(filldedent('''
When gen is real, the relational has a complex part
which leads to an invalid comparison like I < 0.
            '''))

    rv = None

    if expr is S.true:
        rv = domain

    elif expr is S.false:
        rv = S.EmptySet

    else:
        e = expr.lhs - expr.rhs
        period = periodicity(e, gen)
        if period is not None:
            frange = function_range(e, gen, domain)

            rel = expr.rel_op
            if rel == '<' or rel == '<=':
                if expr.func(frange.sup, 0):
                    rv = domain
                elif not expr.func(frange.inf, 0):
                    rv = S.EmptySet

            elif rel == '>' or rel == '>=':
                if expr.func(frange.inf, 0):
                    rv = domain
                elif not expr.func(frange.sup, 0):
                    rv = S.EmptySet

            inf, sup = domain.inf, domain.sup
            if sup - inf is S.Infinity:
                domain = Interval(0, period, False, True)

        if rv is None:
            n, d = e.as_numer_denom()
            try:
                if gen not in n.free_symbols and len(e.free_symbols) > 1:
                    raise ValueError
                # this might raise ValueError on its own
                # or it might give None...
                solns = solvify(e, gen, domain)
                if solns is None:
                    # in which case we raise ValueError
                    raise ValueError
            except (ValueError, NotImplementedError):
                raise NotImplementedError(filldedent('''
The inequality cannot be solved using solve_univariate_inequality.
                        '''))

            expanded_e = expand_mul(e)
            def valid(x):
                # this is used to see if gen=x satisfies the
                # relational by substituting it into the
                # expanded form and testing against 0, e.g.
                # if expr = x*(x + 1) < 2 then e = x*(x + 1) - 2
                # and expanded_e = x**2 + x - 2; the test is
                # whether a given value of x satisfies
                # x**2 + x - 2 < 0
                #
                # expanded_e, expr and gen used from enclosing scope
                v = expanded_e.subs(gen, x)
                try:
                    r = expr.func(v, 0)
                except TypeError:
                    r = S.false
                if r in (S.true, S.false):
                    return r
                if v.is_real is False:
                    return S.false
                else:
                    v = v.n(2)
                    if v.is_comparable:
                        return expr.func(v, 0)
                    # not comparable or couldn't be evaluated
                    raise NotImplementedError(
                        'relationship did not evaluate: %s' % r)

            singularities = []
            for d in denoms(expr, gen):
                singularities.extend(solvify(d, gen, domain))
            if not continuous:
                domain = continuous_domain(e, gen, domain)

            include_x = '=' in expr.rel_op and expr.rel_op != '!='

            try:
                discontinuities = set(domain.boundary -
                    FiniteSet(domain.inf, domain.sup))
                # remove points that are not between inf and sup of domain
                critical_points = FiniteSet(*(solns + singularities + list(
                    discontinuities))).intersection(
                    Interval(domain.inf, domain.sup,
                    domain.inf not in domain, domain.sup not in domain))
                if all(r.is_number for r in critical_points):
                    reals = _nsort(critical_points, separated=True)[0]
                else:
                    from sympy.utilities.iterables import sift
                    sifted = sift(critical_points, lambda x: x.is_real)
                    if sifted[None]:
                        # there were some roots that weren't known
                        # to be real
                        raise NotImplementedError
                    try:
                        reals = sifted[True]
                        if len(reals) > 1:
                            reals = list(sorted(reals))
                    except TypeError:
                        raise NotImplementedError
            except NotImplementedError:
                raise NotImplementedError('sorting of these roots is not supported')

            #If expr contains imaginary coefficients
            #Only real values of x for which the imaginary part is 0 are taken
            make_real = S.Reals
            if im(expanded_e) != S.Zero:
                check = True
                im_sol = FiniteSet()
                try:
                    a = solveset(im(expanded_e), gen, domain)
                    if not isinstance(a, Interval):
                        for z in a:
                            if z not in singularities and valid(z) and z.is_real:
                                im_sol += FiniteSet(z)
                    else:
                        start, end = a.inf, a.sup
                        for z in _nsort(critical_points + FiniteSet(end)):
                            valid_start = valid(start)
                            if start != end:
                                valid_z = valid(z)
                                pt = _pt(start, z)
                                if pt not in singularities and pt.is_real and valid(pt):
                                    if valid_start and valid_z:
                                        im_sol += Interval(start, z)
                                    elif valid_start:
                                        im_sol += Interval.Ropen(start, z)
                                    elif valid_z:
                                        im_sol += Interval.Lopen(start, z)
                                    else:
                                        im_sol += Interval.open(start, z)
                            start = z
                        for s in singularities:
                            im_sol -= FiniteSet(s)
                except (TypeError):
                    im_sol = S.Reals
                    check = False

                if isinstance(im_sol, EmptySet):
                    raise ValueError(filldedent('''
%s contains imaginary parts which cannot be made 0 for any value of %s
satisfying the inequality, leading to relations like I < 0.
                '''  % (expr.subs(gen, _gen), _gen)))

                make_real = make_real.intersect(im_sol)

            empty = sol_sets = [S.EmptySet]

            start = domain.inf
            if valid(start) and start.is_finite:
                sol_sets.append(FiniteSet(start))

            for x in reals:
                end = x

                if valid(_pt(start, end)):
                    sol_sets.append(Interval(start, end, True, True))

                if x in singularities:
                    singularities.remove(x)
                else:
                    if x in discontinuities:
                        discontinuities.remove(x)
                        _valid = valid(x)
                    else:  # it's a solution
                        _valid = include_x
                    if _valid:
                        sol_sets.append(FiniteSet(x))

                start = end

            end = domain.sup
            if valid(end) and end.is_finite:
                sol_sets.append(FiniteSet(end))

            if valid(_pt(start, end)):
                sol_sets.append(Interval.open(start, end))

            if im(expanded_e) != S.Zero and check:
                rv = (make_real).intersect(_domain)
            else:
                rv = Intersection(
                    (Union(*sol_sets)), make_real, _domain).subs(gen, _gen)

    return rv if not relational else rv.as_relational(_gen)
Ejemplo n.º 12
0
from sympy import *
from fractions import *
from sympy import Symbol, S
from sympy.calculus.util import continuous_domain
import math

x = Symbol("x")
f = 1 / x - 2
z = continuous_domain(f, x, S.Reals)


def dominio_rango(R):
    x = []
    y = []
    for a, b in R:
        x.append(a)
        y.append(b)
    return "El dominio es: ", sorted(
        set(x), key=x.index), " El rango es: ", sorted(set(y), key=y.index)


print(
    "En caso de ingresar una relación el dominio y rango estarán definidos por sus ejes X y Y"
)
print("Relación ingresada")
print("[(1,1), (1,2), (2,3), (4,2)]")
print(dominio_rango([(1, 1), (1, 2), (2, 3), (4, 2)]))
Ejemplo n.º 13
0
def solve_univariate_inequality(expr,
                                gen,
                                relational=True,
                                domain=S.Reals,
                                continuous=False):
    """Solves a real univariate inequality.

    Parameters
    ==========

    expr : Relational
        The target inequality
    gen : Symbol
        The variable for which the inequality is solved
    relational : bool
        A Relational type output is expected or not
    domain : Set
        The domain over which the equation is solved
    continuous: bool
        True if expr is known to be continuous over the given domain
        (and so continuous_domain() doesn't need to be called on it)

    Raises
    ======

    NotImplementedError
        The solution of the inequality cannot be determined due to limitation
        in `solvify`.

    Notes
    =====

    Currently, we cannot solve all the inequalities due to limitations in
    `solvify`. Also, the solution returned for trigonometric inequalities
    are restricted in its periodic interval.

    See Also
    ========

    solvify: solver returning solveset solutions with solve's output API

    Examples
    ========

    >>> from sympy.solvers.inequalities import solve_univariate_inequality
    >>> from sympy import Symbol, sin, Interval, S
    >>> x = Symbol('x')

    >>> solve_univariate_inequality(x**2 >= 4, x)
    ((2 <= x) & (x < oo)) | ((x <= -2) & (-oo < x))

    >>> solve_univariate_inequality(x**2 >= 4, x, relational=False)
    (-oo, -2] U [2, oo)

    >>> domain = Interval(0, S.Infinity)
    >>> solve_univariate_inequality(x**2 >= 4, x, False, domain)
    [2, oo)

    >>> solve_univariate_inequality(sin(x) > 0, x, relational=False)
    (0, pi)

    """
    from sympy.calculus.util import (continuous_domain, periodicity,
                                     function_range)
    from sympy.solvers.solvers import denoms
    from sympy.solvers.solveset import solveset_real, solvify

    # This keeps the function independent of the assumptions about `gen`.
    # `solveset` makes sure this function is called only when the domain is
    # real.
    d = Dummy(real=True)
    expr = expr.subs(gen, d)
    _gen = gen
    gen = d
    rv = None

    if expr is S.true:
        rv = domain

    elif expr is S.false:
        rv = S.EmptySet

    else:
        e = expr.lhs - expr.rhs
        period = periodicity(e, gen)
        if period is not None:
            frange = function_range(e, gen, domain)

            rel = expr.rel_op
            if rel == '<' or rel == '<=':
                if expr.func(frange.sup, 0):
                    rv = domain
                elif not expr.func(frange.inf, 0):
                    rv = S.EmptySet

            elif rel == '>' or rel == '>=':
                if expr.func(frange.inf, 0):
                    rv = domain
                elif not expr.func(frange.sup, 0):
                    rv = S.EmptySet

            inf, sup = domain.inf, domain.sup
            if sup - inf is S.Infinity:
                domain = Interval(0, period, False, True)

        if rv is None:
            singularities = []
            for d in denoms(e):
                singularities.extend(solvify(d, gen, domain))
            if not continuous:
                domain = continuous_domain(e, gen, domain)
            solns = solvify(e, gen, domain)

            if solns is None:
                raise NotImplementedError(
                    filldedent('''The inequality cannot be
                    solved using solve_univariate_inequality.'''))

            include_x = expr.func(0, 0)

            def valid(x):
                v = e.subs(gen, x)
                try:
                    r = expr.func(v, 0)
                except TypeError:
                    r = S.false
                if r in (S.true, S.false):
                    return r
                if v.is_real is False:
                    return S.false
                else:
                    v = v.n(2)
                    if v.is_comparable:
                        return expr.func(v, 0)
                    return S.false

            start = domain.inf
            sol_sets = [S.EmptySet]
            try:
                discontinuities = domain.boundary - FiniteSet(
                    domain.inf, domain.sup)
                critical_points = set(solns + singularities +
                                      list(discontinuities))
                reals = _nsort(critical_points, separated=True)[0]

            except NotImplementedError:
                raise NotImplementedError(
                    'sorting of these roots is not supported')

            if valid(start) and start.is_finite:
                sol_sets.append(FiniteSet(start))

            for x in reals:
                end = x

                if end in [S.NegativeInfinity, S.Infinity]:
                    if valid(S(0)):
                        sol_sets.append(Interval(start, S.Infinity, True,
                                                 True))
                        break

                pt = ((start + end) / 2 if start is not S.NegativeInfinity else
                      (end / 2 if end.is_positive else
                       (2 * end if end.is_negative else end - 1)))
                if valid(pt):
                    sol_sets.append(Interval(start, end, True, True))

                if x in singularities:
                    singularities.remove(x)
                elif include_x:
                    sol_sets.append(FiniteSet(x))

                start = end

            end = domain.sup

            # in case start == -oo then there were no solutions so we just
            # check a point between -oo and oo (e.g. 0) else pick a point
            # past the last solution (which is start after the end of the
            # for-loop above
            pt = (0 if start is S.NegativeInfinity else
                  (start / 2 if start.is_negative else
                   (2 * start if start.is_positive else start + 1)))

            if pt >= end:
                pt = (start + end) / 2

            if valid(pt):
                sol_sets.append(Interval(start, end, True, True))

            rv = Union(*sol_sets).subs(gen, _gen)

    return rv if not relational else rv.as_relational(_gen)
Ejemplo n.º 14
0
def solve_univariate_inequality(expr, gen, relational=True, domain=S.Reals, continuous=False):
    """Solves a real univariate inequality.

    Parameters
    ==========

    expr : Relational
        The target inequality
    gen : Symbol
        The variable for which the inequality is solved
    relational : bool
        A Relational type output is expected or not
    domain : Set
        The domain over which the equation is solved
    continuous: bool
        True if expr is known to be continuous over the given domain
        (and so continuous_domain() doesn't need to be called on it)

    Raises
    ======

    NotImplementedError
        The solution of the inequality cannot be determined due to limitation
        in `solvify`.

    Notes
    =====

    Currently, we cannot solve all the inequalities due to limitations in
    `solvify`. Also, the solution returned for trigonometric inequalities
    are restricted in its periodic interval.

    See Also
    ========

    solvify: solver returning solveset solutions with solve's output API

    Examples
    ========

    >>> from sympy.solvers.inequalities import solve_univariate_inequality
    >>> from sympy import Symbol, sin, Interval, S
    >>> x = Symbol('x')

    >>> solve_univariate_inequality(x**2 >= 4, x)
    ((2 <= x) & (x < oo)) | ((x <= -2) & (-oo < x))

    >>> solve_univariate_inequality(x**2 >= 4, x, relational=False)
    (-oo, -2] U [2, oo)

    >>> domain = Interval(0, S.Infinity)
    >>> solve_univariate_inequality(x**2 >= 4, x, False, domain)
    [2, oo)

    >>> solve_univariate_inequality(sin(x) > 0, x, relational=False)
    (0, pi)

    """
    from sympy.calculus.util import (continuous_domain, periodicity,
        function_range)
    from sympy.solvers.solvers import denoms
    from sympy.solvers.solveset import solveset_real, solvify

    # This keeps the function independent of the assumptions about `gen`.
    # `solveset` makes sure this function is called only when the domain is
    # real.
    d = Dummy(real=True)
    expr = expr.subs(gen, d)
    _gen = gen
    gen = d
    rv = None

    if expr is S.true:
        rv = domain

    elif expr is S.false:
        rv = S.EmptySet

    else:
        e = expr.lhs - expr.rhs
        period = periodicity(e, gen)
        if period is not None:
            frange = function_range(e, gen, domain)

            rel = expr.rel_op
            if rel == '<' or rel == '<=':
                if expr.func(frange.sup, 0):
                    rv = domain
                elif not expr.func(frange.inf, 0):
                    rv = S.EmptySet

            elif rel == '>' or rel == '>=':
                if expr.func(frange.inf, 0):
                    rv = domain
                elif not expr.func(frange.sup, 0):
                    rv = S.EmptySet

            inf, sup = domain.inf, domain.sup
            if sup - inf is S.Infinity:
                domain = Interval(0, period, False, True)

        if rv is None:
            singularities = []
            for d in denoms(e):
                singularities.extend(solvify(d, gen, domain))
            if not continuous:
                domain = continuous_domain(e, gen, domain)
            solns = solvify(e, gen, domain)

            if solns is None:
                raise NotImplementedError(filldedent('''The inequality cannot be
                    solved using solve_univariate_inequality.'''))

            include_x = expr.func(0, 0)

            def valid(x):
                v = e.subs(gen, x)
                try:
                    r = expr.func(v, 0)
                except TypeError:
                    r = S.false
                if r in (S.true, S.false):
                    return r
                if v.is_real is False:
                    return S.false
                else:
                    v = v.n(2)
                    if v.is_comparable:
                        return expr.func(v, 0)
                    return S.false

            start = domain.inf
            sol_sets = [S.EmptySet]
            try:
                discontinuities = domain.boundary - FiniteSet(domain.inf, domain.sup)
                critical_points = set(solns + singularities + list(discontinuities))
                reals = _nsort(critical_points, separated=True)[0]

            except NotImplementedError:
                raise NotImplementedError('sorting of these roots is not supported')

            if valid(start) and start.is_finite:
                sol_sets.append(FiniteSet(start))

            for x in reals:
                end = x

                if end in [S.NegativeInfinity, S.Infinity]:
                    if valid(S(0)):
                        sol_sets.append(Interval(start, S.Infinity, True, True))
                        break

                pt = ((start + end)/2 if start is not S.NegativeInfinity else
                    (end/2 if end.is_positive else
                    (2*end if end.is_negative else
                    end - 1)))
                if valid(pt):
                    sol_sets.append(Interval(start, end, True, True))

                if x in singularities:
                    singularities.remove(x)
                elif include_x:
                    sol_sets.append(FiniteSet(x))

                start = end

            end = domain.sup

            # in case start == -oo then there were no solutions so we just
            # check a point between -oo and oo (e.g. 0) else pick a point
            # past the last solution (which is start after the end of the
            # for-loop above
            pt = (0 if start is S.NegativeInfinity else
                (start/2 if start.is_negative else
                (2*start if start.is_positive else
                start + 1)))

            if pt >= end:
                pt = (start + end)/2

            if valid(pt):
                sol_sets.append(Interval(start, end, True, True))

            rv = Union(*sol_sets).subs(gen, _gen)

    return rv if not relational else rv.as_relational(_gen)
 def compute_admissible_domain(self, sym_function):
     """Deprecated, as continuos_domain is superslow"""
     x = self.symbol
     res = continuous_domain(sym_function, self.symbol, S.Reals)
     return res
Ejemplo n.º 16
0
def solve_univariate_inequality(expr,
                                gen,
                                relational=True,
                                domain=S.Reals,
                                continuous=False):
    """Solves a real univariate inequality.

    Parameters
    ==========

    expr : Relational
        The target inequality
    gen : Symbol
        The variable for which the inequality is solved
    relational : bool
        A Relational type output is expected or not
    domain : Set
        The domain over which the equation is solved
    continuous: bool
        True if expr is known to be continuous over the given domain
        (and so continuous_domain() doesn't need to be called on it)

    Raises
    ======

    NotImplementedError
        The solution of the inequality cannot be determined due to limitation
        in `solvify`.

    Notes
    =====

    Currently, we cannot solve all the inequalities due to limitations in
    `solvify`. Also, the solution returned for trigonometric inequalities
    are restricted in its periodic interval.

    See Also
    ========

    solvify: solver returning solveset solutions with solve's output API

    Examples
    ========

    >>> from sympy.solvers.inequalities import solve_univariate_inequality
    >>> from sympy import Symbol, sin, Interval, S
    >>> x = Symbol('x')

    >>> solve_univariate_inequality(x**2 >= 4, x)
    ((2 <= x) & (x < oo)) | ((x <= -2) & (-oo < x))

    >>> solve_univariate_inequality(x**2 >= 4, x, relational=False)
    Union(Interval(-oo, -2), Interval(2, oo))

    >>> domain = Interval(0, S.Infinity)
    >>> solve_univariate_inequality(x**2 >= 4, x, False, domain)
    Interval(2, oo)

    >>> solve_univariate_inequality(sin(x) > 0, x, relational=False)
    Interval.open(0, pi)

    """
    from sympy import im
    from sympy.calculus.util import (continuous_domain, periodicity,
                                     function_range)
    from sympy.solvers.solvers import denoms
    from sympy.solvers.solveset import solveset_real, solvify, solveset
    from sympy.solvers.solvers import solve

    # This keeps the function independent of the assumptions about `gen`.
    # `solveset` makes sure this function is called only when the domain is
    # real.
    _gen = gen
    _domain = domain
    if gen.is_real is False:
        rv = S.EmptySet
        return rv if not relational else rv.as_relational(_gen)
    elif gen.is_real is None:
        gen = Dummy('gen', real=True)
        try:
            expr = expr.xreplace({_gen: gen})
        except TypeError:
            raise TypeError(
                filldedent('''
                When gen is real, the relational has a complex part
                which leads to an invalid comparison like I < 0.
                '''))

    rv = None

    if expr is S.true:
        rv = domain

    elif expr is S.false:
        rv = S.EmptySet

    else:
        e = expr.lhs - expr.rhs
        period = periodicity(e, gen)
        if period is S.Zero:
            e = expand_mul(e)
            const = expr.func(e, 0)
            if const is S.true:
                rv = domain
            elif const is S.false:
                rv = S.EmptySet
        elif period is not None:
            frange = function_range(e, gen, domain)

            rel = expr.rel_op
            if rel == '<' or rel == '<=':
                if expr.func(frange.sup, 0):
                    rv = domain
                elif not expr.func(frange.inf, 0):
                    rv = S.EmptySet

            elif rel == '>' or rel == '>=':
                if expr.func(frange.inf, 0):
                    rv = domain
                elif not expr.func(frange.sup, 0):
                    rv = S.EmptySet

            inf, sup = domain.inf, domain.sup
            if sup - inf is S.Infinity:
                domain = Interval(0, period, False, True)

        if rv is None:
            n, d = e.as_numer_denom()
            try:
                if gen not in n.free_symbols and len(e.free_symbols) > 1:
                    raise ValueError
                # this might raise ValueError on its own
                # or it might give None...
                solns = solvify(e, gen, domain)
                if solns is None:
                    # in which case we raise ValueError
                    raise ValueError
            except (ValueError, NotImplementedError):
                # replace gen with generic x since it's
                # univariate anyway
                raise NotImplementedError(
                    filldedent('''
                    The inequality, %s, cannot be solved using
                    solve_univariate_inequality.
                    ''' % expr.subs(gen, Symbol('x'))))

            expanded_e = expand_mul(e)

            def valid(x):
                # this is used to see if gen=x satisfies the
                # relational by substituting it into the
                # expanded form and testing against 0, e.g.
                # if expr = x*(x + 1) < 2 then e = x*(x + 1) - 2
                # and expanded_e = x**2 + x - 2; the test is
                # whether a given value of x satisfies
                # x**2 + x - 2 < 0
                #
                # expanded_e, expr and gen used from enclosing scope
                v = expanded_e.subs(gen, expand_mul(x))
                try:
                    r = expr.func(v, 0)
                except TypeError:
                    r = S.false
                if r in (S.true, S.false):
                    return r
                if v.is_real is False:
                    return S.false
                else:
                    v = v.n(2)
                    if v.is_comparable:
                        return expr.func(v, 0)
                    # not comparable or couldn't be evaluated
                    raise NotImplementedError(
                        'relationship did not evaluate: %s' % r)

            singularities = []
            for d in denoms(expr, gen):
                singularities.extend(solvify(d, gen, domain))
            if not continuous:
                domain = continuous_domain(expanded_e, gen, domain)

            include_x = '=' in expr.rel_op and expr.rel_op != '!='

            try:
                discontinuities = set(domain.boundary -
                                      FiniteSet(domain.inf, domain.sup))
                # remove points that are not between inf and sup of domain
                critical_points = FiniteSet(
                    *(solns + singularities +
                      list(discontinuities))).intersection(
                          Interval(domain.inf, domain.sup, domain.inf
                                   not in domain, domain.sup not in domain))
                if all(r.is_number for r in critical_points):
                    reals = _nsort(critical_points, separated=True)[0]
                else:
                    from sympy.utilities.iterables import sift
                    sifted = sift(critical_points, lambda x: x.is_real)
                    if sifted[None]:
                        # there were some roots that weren't known
                        # to be real
                        raise NotImplementedError
                    try:
                        reals = sifted[True]
                        if len(reals) > 1:
                            reals = list(sorted(reals))
                    except TypeError:
                        raise NotImplementedError
            except NotImplementedError:
                raise NotImplementedError(
                    'sorting of these roots is not supported')

            # If expr contains imaginary coefficients, only take real
            # values of x for which the imaginary part is 0
            make_real = S.Reals
            if im(expanded_e) != S.Zero:
                check = True
                im_sol = FiniteSet()
                try:
                    a = solveset(im(expanded_e), gen, domain)
                    if not isinstance(a, Interval):
                        for z in a:
                            if z not in singularities and valid(
                                    z) and z.is_real:
                                im_sol += FiniteSet(z)
                    else:
                        start, end = a.inf, a.sup
                        for z in _nsort(critical_points + FiniteSet(end)):
                            valid_start = valid(start)
                            if start != end:
                                valid_z = valid(z)
                                pt = _pt(start, z)
                                if pt not in singularities and pt.is_real and valid(
                                        pt):
                                    if valid_start and valid_z:
                                        im_sol += Interval(start, z)
                                    elif valid_start:
                                        im_sol += Interval.Ropen(start, z)
                                    elif valid_z:
                                        im_sol += Interval.Lopen(start, z)
                                    else:
                                        im_sol += Interval.open(start, z)
                            start = z
                        for s in singularities:
                            im_sol -= FiniteSet(s)
                except (TypeError):
                    im_sol = S.Reals
                    check = False

                if isinstance(im_sol, EmptySet):
                    raise ValueError(
                        filldedent('''
                        %s contains imaginary parts which cannot be
                        made 0 for any value of %s satisfying the
                        inequality, leading to relations like I < 0.
                        ''' % (expr.subs(gen, _gen), _gen)))

                make_real = make_real.intersect(im_sol)

            empty = sol_sets = [S.EmptySet]

            start = domain.inf
            if valid(start) and start.is_finite:
                sol_sets.append(FiniteSet(start))

            for x in reals:
                end = x

                if valid(_pt(start, end)):
                    sol_sets.append(Interval(start, end, True, True))

                if x in singularities:
                    singularities.remove(x)
                else:
                    if x in discontinuities:
                        discontinuities.remove(x)
                        _valid = valid(x)
                    else:  # it's a solution
                        _valid = include_x
                    if _valid:
                        sol_sets.append(FiniteSet(x))

                start = end

            end = domain.sup
            if valid(end) and end.is_finite:
                sol_sets.append(FiniteSet(end))

            if valid(_pt(start, end)):
                sol_sets.append(Interval.open(start, end))

            if im(expanded_e) != S.Zero and check:
                rv = (make_real).intersect(_domain)
            else:
                rv = Intersection((Union(*sol_sets)), make_real,
                                  _domain).subs(gen, _gen)

    return rv if not relational else rv.as_relational(_gen)
Ejemplo n.º 17
0
def nminmax(func, x, warningctx=None):
    # Find minimum and maximum at [0,1].
    try:
        return [
            minimum(func, x, Interval(0, 1)),
            maximum(func, x, Interval(0, 1))
        ]
    except:
        pw = piecewise_fold(func.rewrite(Piecewise))
        if isinstance(pw, Piecewise):
            try:
                return pwminmax(pw, x, Interval(0, 1))
            except:
                pass
        print("WARNING: Resorting to numerical optimization: %s" % (func),
              file=sys.stderr)
        if warningctx:
            warningctx["warning"] = True
    cv = [0, 1]
    df = diff(func)
    mmh = isinstance(func, Min) or isinstance(func, Max) or isinstance(
        func, Heaviside)
    n = 40 if mmh else 20
    for i in range(n):
        try:
            ns = nsolve(df, x, (S(i) / n, S(i + 1) / n), solver="bisect")
            cv.append(lowerbound(ns))
            cv.append(upperbound(ns))
        except:
            ss = S(i) / n
            se = S(i + 1) / n
            for k in range(1 + 1):
                cv.append(ss + (se - ss) * S(k) / 10)
    # Evaluate at critical points, and
    # remove incomparable values
    cv2 = []
    # print(func.__class__)
    iscont = continuous_domain(func, x, Interval(0, 1)) == Interval(0, 1)
    # print([func.__class__,iscont])
    # print(func)
    for c in cv:
        c2s = [func.subs(x, c)]
        # Finding limits for Min, Max, and Heaviside can be
        # extremely slow.  Also check whether function is continuous
        # to avoid unnecessary limit computation
        if (not iscont) and (not mmh):
            try:
                c2s.append(funclimit(func, x, c, "+"))
            except:
                pass
            # XXX: Disabling because it can be extremely slow in some
            # cases, especially when Heaviside is involved
            # try:
            #  c2s.append(funclimit(func, x, c, "-"))
            # except:
            #  pass
        for c2 in c2s:
            # Change complex infinity to infinity
            if c2 == zoo:
                c2 = oo
            try:
                Min(c2)
                cv2.append(c2)
            except:
                pass
    cv = cv2
    return [lowerbound(Min(*cv)), upperbound(Max(*cv))]