def solveset_real(f, symbol): """ Solves a real valued equation. Parameters ========== f : Expr The target equation symbol : Symbol The variable for which the equation is solved Returns ======= Set A set of values for `symbol` for which `f` is equal to zero. An `EmptySet` is returned if no solution is found. A `ConditionSet` is returned as unsolved object if algorithms to evaluate complete solutions are not yet implemented. `solveset_real` claims to be complete in the set of the solution it returns. Raises ====== NotImplementedError Algorithms to solve inequalities in complex domain are not yet implemented. ValueError The input is not valid. RuntimeError It is a bug, please report to the github issue tracker. See Also ======= solveset_complex : solver for complex domain Examples ======== >>> from sympy import Symbol, exp, sin, sqrt, I >>> from sympy.solvers.solveset import solveset_real >>> x = Symbol('x', real=True) >>> a = Symbol('a', real=True, finite=True, positive=True) >>> solveset_real(x**2 - 1, x) {-1, 1} >>> solveset_real(sqrt(5*x + 6) - 2 - x, x) {-1, 2} >>> solveset_real(x - I, x) EmptySet() >>> solveset_real(x - a, x) {a} >>> solveset_real(exp(x) - a, x) {log(a)} * In case the equation has infinitely many solutions an infinitely indexed `ImageSet` is returned. >>> solveset_real(sin(x) - 1, x) ImageSet(Lambda(_n, 2*_n*pi + pi/2), Integers()) * If the equation is true for any arbitrary value of the symbol a `S.Reals` set is returned. >>> solveset_real(x - x, x) (-oo, oo) """ if not symbol.is_Symbol: raise ValueError(" %s is not a symbol" % (symbol)) f = sympify(f) if not isinstance(f, (Expr, Number)): raise ValueError(" %s is not a valid sympy expression" % (f)) original_eq = f f = together(f) # In this, unlike in solveset_complex, expression should only # be expanded when fraction(f)[1] does not contain the symbol # for which we are solving if not symbol in fraction(f)[1].free_symbols and f.is_rational_function(): f = expand(f) if f.has(Piecewise): f = piecewise_fold(f) result = EmptySet() if f.expand().is_zero: return S.Reals elif not f.has(symbol): return EmptySet() elif f.is_Mul and all([_is_finite_with_finite_vars(m) for m in f.args]): # if f(x) and g(x) are both finite we can say that the solution of # f(x)*g(x) == 0 is same as Union(f(x) == 0, g(x) == 0) is not true in # general. g(x) can grow to infinitely large for the values where # f(x) == 0. To be sure that we are not silently allowing any # wrong solutions we are using this technique only if both f and g are # finite for a finite input. result = Union(*[solveset_real(m, symbol) for m in f.args]) elif _is_function_class_equation(TrigonometricFunction, f, symbol) or \ _is_function_class_equation(HyperbolicFunction, f, symbol): result = _solve_real_trig(f, symbol) elif f.is_Piecewise: result = EmptySet() expr_set_pairs = f.as_expr_set_pairs() for (expr, in_set) in expr_set_pairs: solns = solveset_real(expr, symbol).intersect(in_set) result = result + solns else: lhs, rhs_s = invert_real(f, 0, symbol) if lhs == symbol: result = rhs_s elif isinstance(rhs_s, FiniteSet): equations = [lhs - rhs for rhs in rhs_s] for equation in equations: if equation == f: if any( _has_rational_power(g, symbol)[0] for g in equation.args): result += _solve_radical(equation, symbol, solveset_real) elif equation.has(Abs): result += _solve_abs(f, symbol) else: result += _solve_as_rational( equation, symbol, solveset_solver=solveset_real, as_poly_solver=_solve_as_poly_real) else: result += solveset_real(equation, symbol) else: result = ConditionSet(symbol, Eq(f, 0), S.Reals) if isinstance(result, FiniteSet): result = [ s for s in result if isinstance(s, RootOf) or domain_check(original_eq, symbol, s) ] return FiniteSet(*result).intersect(S.Reals) else: return result.intersect(S.Reals)
def solveset_real(f, symbol): """ Solves a real valued equation. Parameters ========== f : Expr The target equation symbol : Symbol The variable for which the equation is solved Returns ======= Set A set of values for `symbol` for which `f` is equal to zero. An `EmptySet` is returned if no solution is found. `solveset_real` claims to be complete in the set of the solution it returns. Raises ====== NotImplementedError The algorithms for to find the solution of the given equation are not yet implemented. ValueError The input is not valid. RuntimeError It is a bug, please report to the github issue tracker. See Also ======= solveset_complex : solver for complex domain Examples ======== >>> from sympy import Symbol, exp, sin, sqrt, I >>> from sympy.solvers.solveset import solveset_real >>> x = Symbol('x', real=True) >>> a = Symbol('a', real=True, finite=True, positive=True) >>> solveset_real(x**2 - 1, x) {-1, 1} >>> solveset_real(sqrt(5*x + 6) - 2 - x, x) {-1, 2} >>> solveset_real(x - I, x) EmptySet() >>> solveset_real(x - a, x) {a} >>> solveset_real(exp(x) - a, x) {log(a)} In case the equation has infinitely many solutions an infinitely indexed `ImageSet` is returned. >>> solveset_real(sin(x) - 1, x) ImageSet(Lambda(_n, 2*_n*pi + pi/2), Integers()) If the equation is true for any arbitrary value of the symbol a `S.Reals` set is returned. >>> solveset_real(x - x, x) (-oo, oo) """ if not symbol.is_Symbol: raise ValueError(" %s is not a symbol" % (symbol)) f = sympify(f) if not isinstance(f, (Expr, Number)): raise ValueError(" %s is not a valid sympy expression" % (f)) original_eq = f f = together(f) if f.has(Piecewise): f = piecewise_fold(f) result = EmptySet() if f.expand().is_zero: return S.Reals elif not f.has(symbol): return EmptySet() elif f.is_Mul and all([_is_finite_with_finite_vars(m) for m in f.args]): # if f(x) and g(x) are both finite we can say that the solution of # f(x)*g(x) == 0 is same as Union(f(x) == 0, g(x) == 0) is not true in # general. g(x) can grow to infinitely large for the values where # f(x) == 0. To be sure that we not are silently allowing any # wrong solutions we are using this technique only if both f and g and # finite for a finite input. result = Union(*[solveset_real(m, symbol) for m in f.args]) elif _is_function_class_equation(C.TrigonometricFunction, f, symbol) or \ _is_function_class_equation(C.HyperbolicFunction, f, symbol): result = _solve_real_trig(f, symbol) elif f.is_Piecewise: result = EmptySet() expr_set_pairs = f.as_expr_set_pairs() for (expr, in_set) in expr_set_pairs: solns = solveset_real(expr, symbol).intersect(in_set) result = result + solns else: lhs, rhs_s = invert_real(f, 0, symbol) if lhs == symbol: result = rhs_s elif isinstance(rhs_s, FiniteSet): equations = [lhs - rhs for rhs in rhs_s] for equation in equations: if equation == f: if any(_has_rational_power(g, symbol)[0] for g in equation.args): result += _solve_radical(equation, symbol, solveset_real) elif equation.has(Abs): result += _solve_abs(f, symbol) else: result += _solve_as_rational(equation, symbol, solveset_solver=solveset_real, as_poly_solver=_solve_as_poly_real) else: result += solveset_real(equation, symbol) else: raise NotImplementedError if isinstance(result, FiniteSet): result = [s for s in result if isinstance(s, RootOf) or domain_check(original_eq, symbol, s)] return FiniteSet(*result).intersect(S.Reals) else: return result.intersect(S.Reals)