Initialisation du repository de Beta
This commit is contained in:
commit
14985f6dbb
9469 changed files with 1903273 additions and 0 deletions
|
|
@ -0,0 +1,440 @@
|
|||
"""
|
||||
Handlers related to order relations: positive, negative, etc.
|
||||
"""
|
||||
|
||||
from sympy.assumptions import Q, ask
|
||||
from sympy.core import Add, Basic, Expr, Mul, Pow, S
|
||||
from sympy.core.logic import fuzzy_not, fuzzy_and, fuzzy_or
|
||||
from sympy.core.numbers import E, ImaginaryUnit, NaN, I, pi
|
||||
from sympy.functions import Abs, acos, acot, asin, atan, exp, factorial, log
|
||||
from sympy.matrices import Determinant, Trace
|
||||
from sympy.matrices.expressions.matexpr import MatrixElement
|
||||
|
||||
from sympy.multipledispatch import MDNotImplementedError
|
||||
|
||||
from ..predicates.order import (NegativePredicate, NonNegativePredicate,
|
||||
NonZeroPredicate, ZeroPredicate, NonPositivePredicate, PositivePredicate,
|
||||
ExtendedNegativePredicate, ExtendedNonNegativePredicate,
|
||||
ExtendedNonPositivePredicate, ExtendedNonZeroPredicate,
|
||||
ExtendedPositivePredicate,)
|
||||
|
||||
|
||||
# NegativePredicate
|
||||
|
||||
def _NegativePredicate_number(expr, assumptions):
|
||||
r, i = expr.as_real_imag()
|
||||
|
||||
if r == S.NaN or i == S.NaN:
|
||||
return None
|
||||
|
||||
# If the imaginary part can symbolically be shown to be zero then
|
||||
# we just evaluate the real part; otherwise we evaluate the imaginary
|
||||
# part to see if it actually evaluates to zero and if it does then
|
||||
# we make the comparison between the real part and zero.
|
||||
if not i:
|
||||
r = r.evalf(2)
|
||||
if r._prec != 1:
|
||||
return r < 0
|
||||
else:
|
||||
i = i.evalf(2)
|
||||
if i._prec != 1:
|
||||
if i != 0:
|
||||
return False
|
||||
r = r.evalf(2)
|
||||
if r._prec != 1:
|
||||
return r < 0
|
||||
|
||||
@NegativePredicate.register(Basic)
|
||||
def _(expr, assumptions):
|
||||
if expr.is_number:
|
||||
return _NegativePredicate_number(expr, assumptions)
|
||||
|
||||
@NegativePredicate.register(Expr)
|
||||
def _(expr, assumptions):
|
||||
ret = expr.is_negative
|
||||
if ret is None:
|
||||
raise MDNotImplementedError
|
||||
return ret
|
||||
|
||||
@NegativePredicate.register(Add)
|
||||
def _(expr, assumptions):
|
||||
"""
|
||||
Positive + Positive -> Positive,
|
||||
Negative + Negative -> Negative
|
||||
"""
|
||||
if expr.is_number:
|
||||
return _NegativePredicate_number(expr, assumptions)
|
||||
|
||||
r = ask(Q.real(expr), assumptions)
|
||||
if r is not True:
|
||||
return r
|
||||
|
||||
nonpos = 0
|
||||
for arg in expr.args:
|
||||
if ask(Q.negative(arg), assumptions) is not True:
|
||||
if ask(Q.positive(arg), assumptions) is False:
|
||||
nonpos += 1
|
||||
else:
|
||||
break
|
||||
else:
|
||||
if nonpos < len(expr.args):
|
||||
return True
|
||||
|
||||
@NegativePredicate.register(Mul)
|
||||
def _(expr, assumptions):
|
||||
if expr.is_number:
|
||||
return _NegativePredicate_number(expr, assumptions)
|
||||
result = None
|
||||
for arg in expr.args:
|
||||
if result is None:
|
||||
result = False
|
||||
if ask(Q.negative(arg), assumptions):
|
||||
result = not result
|
||||
elif ask(Q.positive(arg), assumptions):
|
||||
pass
|
||||
else:
|
||||
return
|
||||
return result
|
||||
|
||||
@NegativePredicate.register(Pow)
|
||||
def _(expr, assumptions):
|
||||
"""
|
||||
Real ** Even -> NonNegative
|
||||
Real ** Odd -> same_as_base
|
||||
NonNegative ** Positive -> NonNegative
|
||||
"""
|
||||
if expr.base == E:
|
||||
# Exponential is always positive:
|
||||
if ask(Q.real(expr.exp), assumptions):
|
||||
return False
|
||||
return
|
||||
|
||||
if expr.is_number:
|
||||
return _NegativePredicate_number(expr, assumptions)
|
||||
if ask(Q.real(expr.base), assumptions):
|
||||
if ask(Q.positive(expr.base), assumptions):
|
||||
if ask(Q.real(expr.exp), assumptions):
|
||||
return False
|
||||
if ask(Q.even(expr.exp), assumptions):
|
||||
return False
|
||||
if ask(Q.odd(expr.exp), assumptions):
|
||||
return ask(Q.negative(expr.base), assumptions)
|
||||
|
||||
@NegativePredicate.register_many(Abs, ImaginaryUnit)
|
||||
def _(expr, assumptions):
|
||||
return False
|
||||
|
||||
@NegativePredicate.register(exp)
|
||||
def _(expr, assumptions):
|
||||
if ask(Q.real(expr.exp), assumptions):
|
||||
return False
|
||||
raise MDNotImplementedError
|
||||
|
||||
|
||||
# NonNegativePredicate
|
||||
|
||||
@NonNegativePredicate.register(Basic)
|
||||
def _(expr, assumptions):
|
||||
if expr.is_number:
|
||||
notnegative = fuzzy_not(_NegativePredicate_number(expr, assumptions))
|
||||
if notnegative:
|
||||
return ask(Q.real(expr), assumptions)
|
||||
else:
|
||||
return notnegative
|
||||
|
||||
@NonNegativePredicate.register(Expr)
|
||||
def _(expr, assumptions):
|
||||
ret = expr.is_nonnegative
|
||||
if ret is None:
|
||||
raise MDNotImplementedError
|
||||
return ret
|
||||
|
||||
|
||||
# NonZeroPredicate
|
||||
|
||||
@NonZeroPredicate.register(Expr)
|
||||
def _(expr, assumptions):
|
||||
ret = expr.is_nonzero
|
||||
if ret is None:
|
||||
raise MDNotImplementedError
|
||||
return ret
|
||||
|
||||
@NonZeroPredicate.register(Basic)
|
||||
def _(expr, assumptions):
|
||||
if ask(Q.real(expr)) is False:
|
||||
return False
|
||||
if expr.is_number:
|
||||
# if there are no symbols just evalf
|
||||
i = expr.evalf(2)
|
||||
def nonz(i):
|
||||
if i._prec != 1:
|
||||
return i != 0
|
||||
return fuzzy_or(nonz(i) for i in i.as_real_imag())
|
||||
|
||||
@NonZeroPredicate.register(Add)
|
||||
def _(expr, assumptions):
|
||||
if all(ask(Q.positive(x), assumptions) for x in expr.args) \
|
||||
or all(ask(Q.negative(x), assumptions) for x in expr.args):
|
||||
return True
|
||||
|
||||
@NonZeroPredicate.register(Mul)
|
||||
def _(expr, assumptions):
|
||||
for arg in expr.args:
|
||||
result = ask(Q.nonzero(arg), assumptions)
|
||||
if result:
|
||||
continue
|
||||
return result
|
||||
return True
|
||||
|
||||
@NonZeroPredicate.register(Pow)
|
||||
def _(expr, assumptions):
|
||||
return ask(Q.nonzero(expr.base), assumptions)
|
||||
|
||||
@NonZeroPredicate.register(Abs)
|
||||
def _(expr, assumptions):
|
||||
return ask(Q.nonzero(expr.args[0]), assumptions)
|
||||
|
||||
@NonZeroPredicate.register(NaN)
|
||||
def _(expr, assumptions):
|
||||
return None
|
||||
|
||||
|
||||
# ZeroPredicate
|
||||
|
||||
@ZeroPredicate.register(Expr)
|
||||
def _(expr, assumptions):
|
||||
ret = expr.is_zero
|
||||
if ret is None:
|
||||
raise MDNotImplementedError
|
||||
return ret
|
||||
|
||||
@ZeroPredicate.register(Basic)
|
||||
def _(expr, assumptions):
|
||||
return fuzzy_and([fuzzy_not(ask(Q.nonzero(expr), assumptions)),
|
||||
ask(Q.real(expr), assumptions)])
|
||||
|
||||
@ZeroPredicate.register(Mul)
|
||||
def _(expr, assumptions):
|
||||
# TODO: This should be deducible from the nonzero handler
|
||||
return fuzzy_or(ask(Q.zero(arg), assumptions) for arg in expr.args)
|
||||
|
||||
|
||||
# NonPositivePredicate
|
||||
|
||||
@NonPositivePredicate.register(Expr)
|
||||
def _(expr, assumptions):
|
||||
ret = expr.is_nonpositive
|
||||
if ret is None:
|
||||
raise MDNotImplementedError
|
||||
return ret
|
||||
|
||||
@NonPositivePredicate.register(Basic)
|
||||
def _(expr, assumptions):
|
||||
if expr.is_number:
|
||||
notpositive = fuzzy_not(_PositivePredicate_number(expr, assumptions))
|
||||
if notpositive:
|
||||
return ask(Q.real(expr), assumptions)
|
||||
else:
|
||||
return notpositive
|
||||
|
||||
|
||||
# PositivePredicate
|
||||
|
||||
def _PositivePredicate_number(expr, assumptions):
|
||||
r, i = expr.as_real_imag()
|
||||
# If the imaginary part can symbolically be shown to be zero then
|
||||
# we just evaluate the real part; otherwise we evaluate the imaginary
|
||||
# part to see if it actually evaluates to zero and if it does then
|
||||
# we make the comparison between the real part and zero.
|
||||
if not i:
|
||||
r = r.evalf(2)
|
||||
if r._prec != 1:
|
||||
return r > 0
|
||||
else:
|
||||
i = i.evalf(2)
|
||||
if i._prec != 1:
|
||||
if i != 0:
|
||||
return False
|
||||
r = r.evalf(2)
|
||||
if r._prec != 1:
|
||||
return r > 0
|
||||
|
||||
@PositivePredicate.register(Expr)
|
||||
def _(expr, assumptions):
|
||||
ret = expr.is_positive
|
||||
if ret is None:
|
||||
raise MDNotImplementedError
|
||||
return ret
|
||||
|
||||
@PositivePredicate.register(Basic)
|
||||
def _(expr, assumptions):
|
||||
if expr.is_number:
|
||||
return _PositivePredicate_number(expr, assumptions)
|
||||
|
||||
@PositivePredicate.register(Mul)
|
||||
def _(expr, assumptions):
|
||||
if expr.is_number:
|
||||
return _PositivePredicate_number(expr, assumptions)
|
||||
result = True
|
||||
for arg in expr.args:
|
||||
if ask(Q.positive(arg), assumptions):
|
||||
continue
|
||||
elif ask(Q.negative(arg), assumptions):
|
||||
result = result ^ True
|
||||
else:
|
||||
return
|
||||
return result
|
||||
|
||||
@PositivePredicate.register(Add)
|
||||
def _(expr, assumptions):
|
||||
if expr.is_number:
|
||||
return _PositivePredicate_number(expr, assumptions)
|
||||
|
||||
r = ask(Q.real(expr), assumptions)
|
||||
if r is not True:
|
||||
return r
|
||||
|
||||
nonneg = 0
|
||||
for arg in expr.args:
|
||||
if ask(Q.positive(arg), assumptions) is not True:
|
||||
if ask(Q.negative(arg), assumptions) is False:
|
||||
nonneg += 1
|
||||
else:
|
||||
break
|
||||
else:
|
||||
if nonneg < len(expr.args):
|
||||
return True
|
||||
|
||||
@PositivePredicate.register(Pow)
|
||||
def _(expr, assumptions):
|
||||
if expr.base == E:
|
||||
if ask(Q.real(expr.exp), assumptions):
|
||||
return True
|
||||
if ask(Q.imaginary(expr.exp), assumptions):
|
||||
return ask(Q.even(expr.exp/(I*pi)), assumptions)
|
||||
return
|
||||
|
||||
if expr.is_number:
|
||||
return _PositivePredicate_number(expr, assumptions)
|
||||
if ask(Q.positive(expr.base), assumptions):
|
||||
if ask(Q.real(expr.exp), assumptions):
|
||||
return True
|
||||
if ask(Q.negative(expr.base), assumptions):
|
||||
if ask(Q.even(expr.exp), assumptions):
|
||||
return True
|
||||
if ask(Q.odd(expr.exp), assumptions):
|
||||
return False
|
||||
|
||||
@PositivePredicate.register(exp)
|
||||
def _(expr, assumptions):
|
||||
if ask(Q.real(expr.exp), assumptions):
|
||||
return True
|
||||
if ask(Q.imaginary(expr.exp), assumptions):
|
||||
return ask(Q.even(expr.exp/(I*pi)), assumptions)
|
||||
|
||||
@PositivePredicate.register(log)
|
||||
def _(expr, assumptions):
|
||||
r = ask(Q.real(expr.args[0]), assumptions)
|
||||
if r is not True:
|
||||
return r
|
||||
if ask(Q.positive(expr.args[0] - 1), assumptions):
|
||||
return True
|
||||
if ask(Q.negative(expr.args[0] - 1), assumptions):
|
||||
return False
|
||||
|
||||
@PositivePredicate.register(factorial)
|
||||
def _(expr, assumptions):
|
||||
x = expr.args[0]
|
||||
if ask(Q.integer(x) & Q.positive(x), assumptions):
|
||||
return True
|
||||
|
||||
@PositivePredicate.register(ImaginaryUnit)
|
||||
def _(expr, assumptions):
|
||||
return False
|
||||
|
||||
@PositivePredicate.register(Abs)
|
||||
def _(expr, assumptions):
|
||||
return ask(Q.nonzero(expr), assumptions)
|
||||
|
||||
@PositivePredicate.register(Trace)
|
||||
def _(expr, assumptions):
|
||||
if ask(Q.positive_definite(expr.arg), assumptions):
|
||||
return True
|
||||
|
||||
@PositivePredicate.register(Determinant)
|
||||
def _(expr, assumptions):
|
||||
if ask(Q.positive_definite(expr.arg), assumptions):
|
||||
return True
|
||||
|
||||
@PositivePredicate.register(MatrixElement)
|
||||
def _(expr, assumptions):
|
||||
if (expr.i == expr.j
|
||||
and ask(Q.positive_definite(expr.parent), assumptions)):
|
||||
return True
|
||||
|
||||
@PositivePredicate.register(atan)
|
||||
def _(expr, assumptions):
|
||||
return ask(Q.positive(expr.args[0]), assumptions)
|
||||
|
||||
@PositivePredicate.register(asin)
|
||||
def _(expr, assumptions):
|
||||
x = expr.args[0]
|
||||
if ask(Q.positive(x) & Q.nonpositive(x - 1), assumptions):
|
||||
return True
|
||||
if ask(Q.negative(x) & Q.nonnegative(x + 1), assumptions):
|
||||
return False
|
||||
|
||||
@PositivePredicate.register(acos)
|
||||
def _(expr, assumptions):
|
||||
x = expr.args[0]
|
||||
if ask(Q.nonpositive(x - 1) & Q.nonnegative(x + 1), assumptions):
|
||||
return True
|
||||
|
||||
@PositivePredicate.register(acot)
|
||||
def _(expr, assumptions):
|
||||
return ask(Q.real(expr.args[0]), assumptions)
|
||||
|
||||
@PositivePredicate.register(NaN)
|
||||
def _(expr, assumptions):
|
||||
return None
|
||||
|
||||
|
||||
# ExtendedNegativePredicate
|
||||
|
||||
@ExtendedNegativePredicate.register(object)
|
||||
def _(expr, assumptions):
|
||||
return ask(Q.negative(expr) | Q.negative_infinite(expr), assumptions)
|
||||
|
||||
|
||||
# ExtendedPositivePredicate
|
||||
|
||||
@ExtendedPositivePredicate.register(object)
|
||||
def _(expr, assumptions):
|
||||
return ask(Q.positive(expr) | Q.positive_infinite(expr), assumptions)
|
||||
|
||||
|
||||
# ExtendedNonZeroPredicate
|
||||
|
||||
@ExtendedNonZeroPredicate.register(object)
|
||||
def _(expr, assumptions):
|
||||
return ask(
|
||||
Q.negative_infinite(expr) | Q.negative(expr) | Q.positive(expr) | Q.positive_infinite(expr),
|
||||
assumptions)
|
||||
|
||||
|
||||
# ExtendedNonPositivePredicate
|
||||
|
||||
@ExtendedNonPositivePredicate.register(object)
|
||||
def _(expr, assumptions):
|
||||
return ask(
|
||||
Q.negative_infinite(expr) | Q.negative(expr) | Q.zero(expr),
|
||||
assumptions)
|
||||
|
||||
|
||||
# ExtendedNonNegativePredicate
|
||||
|
||||
@ExtendedNonNegativePredicate.register(object)
|
||||
def _(expr, assumptions):
|
||||
return ask(
|
||||
Q.zero(expr) | Q.positive(expr) | Q.positive_infinite(expr),
|
||||
assumptions)
|
||||
Loading…
Add table
Add a link
Reference in a new issue