Skip to content

Commit

Permalink
remove duplicated
Browse files Browse the repository at this point in the history
  • Loading branch information
mmatera committed Jul 21, 2023
1 parent 261ba42 commit c16e3bc
Showing 1 changed file with 0 additions and 295 deletions.
295 changes: 0 additions & 295 deletions mathics/eval/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,301 +463,6 @@ def append_last():
elements_properties=ElementsProperties(False, False, True),
)

elements.sort()
return Expression(
SymbolPlus,
*elements,
elements_properties=ElementsProperties(False, False, True),
)


def eval_Power_number(base: Number, exp: Number) -> Optional[Number]:
"""
Eval base^exp for `base` and `exp` two numbers. If the expression
remains the same, return None.
"""
# If both base and exponent are exact quantities,
# use sympy.
# If base or exp are inexact quantities, use
# the inexact routine.
if base.is_inexact() or exp.is_inexact():
return eval_Power_inexact(base, exp)

# Trivial special cases
if exp is Integer1:
return base
if exp is Integer0:
return Integer1
if base is Integer1:
return Integer1

def eval_Power_sympy() -> Optional[Number]:
"""
Tries to compute x^p using sympy rules.
If the answer is again x^p, return None.
"""
# This function is called just if useful native rules
# are available.
result = from_sympy(sympy.Pow(base.to_sympy(), exp.to_sympy()))
if result.has_form("Power", 2):
# If the expression didn´t change, return None
if result.elements[0].sameQ(base):
return None
return result

# Rational exponent
if isinstance(exp, Rational):
exp_p, exp_q = exp.value.as_numer_denom()
if abs(exp_p) > exp_q:
exp_int, exp_num = divmod(exp_p, exp_q)
exp_rem = Rational(exp_num, exp_q)
factor_1 = eval_Power_number(base, Integer(exp_int))
factor_2 = eval_Power_number(base, exp_rem) or Expression(
SymbolPower, base, exp_rem
)
if factor_1 is Integer1:
return factor_2
return Expression(SymbolTimes, factor_1, factor_2)

# Integer base
if isinstance(base, Integer):
base_value = base.value
if base_value == -1:
if isinstance(exp, Rational):
if exp.sameQ(RationalOneHalf):
return SymbolI
return None
return eval_Power_sympy()
elif base_value < 0:
neg_base = eval_negate_number(base)
candidate = eval_Power_number(neg_base, exp)
if candidate is None:
return None
sign_factor = eval_Power_number(IntegerM1, exp)
if candidate is Integer1:
return sign_factor
return Expression(SymbolTimes, candidate, sign_factor)

# Rational base
if isinstance(base, Rational):
# If the exponent is an Integer or Rational negative value
# restate as a positive power
if (
isinstance(exp, Integer)
and exp.value < 0
or isinstance(exp, Rational)
and exp.value.p < 0
):
base, exp = eval_inverse_number(base), eval_negate_number(exp)
return eval_Power_number(base, exp) or Expression(SymbolPower, base, exp)

p, q = (Integer(u) for u in base.value.as_numer_denom())
p_eval, q_eval = (eval_Power_number(u, exp) for u in (p, q))
# If neither p^exp or q^exp produced a new result,
# leave it alone
if q_eval is None and p_eval is None:
return None
# if q^exp == 1: return p_eval
# (should not happen)
if q_eval is Integer1:
return p_eval
if isinstance(q_eval, Integer):
if isinstance(p_eval, Integer):
return Rational(p_eval.value, q_eval.value)

if p_eval is None:
p_eval = Expression(SymbolPower, p, exp)

if q_eval is None:
q_eval = Expression(SymbolPower, q, exp)
return Expression(
SymbolTimes, p_eval, Expression(SymbolPower, q_eval, IntegerM1)
)
# Pure imaginary base case
elif isinstance(base, Complex) and base.real.is_zero:
base = base.imag
if base.value < 0:
base = eval_negate_number(base)
phase = Expression(
SymbolPower,
IntegerM1,
eval_multiply_numbers(IntegerM1, RationalOneHalf, exp),
)
else:
phase = Expression(
SymbolPower, IntegerM1, eval_multiply_numbers(RationalOneHalf, exp)
)
real_factor = eval_Power_number(base, exp)

if real_factor is None:
return None
return Expression(SymbolTimes, real_factor, phase)

# Generic case
return eval_Power_sympy()


def eval_Power_inexact(base: Number, exp: Number) -> BaseElement:
"""
Eval base^exp for `base` and `exp` inexact numbers
"""
# If both base and exponent are exact quantities,
# use sympy.
prec = min_prec(base, exp)
if prec is not None:
is_machine_precision = base.is_machine_precision() or exp.is_machine_precision()
if is_machine_precision:
number = mpmath.power(base.to_mpmath(), exp.to_mpmath())
return from_mpmath(number)
else:
with mpmath.workprec(prec):
number = mpmath.power(base.to_mpmath(), exp.to_mpmath())
return from_mpmath(number, prec)


def eval_Power_number(base: Number, exp: Number) -> Optional[Number]:
"""
Eval base^exp for `base` and `exp` two numbers. If the expression
remains the same, return None.
"""
# If both base and exponent are exact quantities,
# use sympy.
# If base or exp are inexact quantities, use
# the inexact routine.
if base.is_inexact() or exp.is_inexact():
return eval_Power_inexact(base, exp)

# Trivial special cases
if exp is Integer1:
return base
if exp is Integer0:
return Integer1
if base is Integer1:
return Integer1

def eval_Power_sympy() -> Optional[Number]:
"""
Tries to compute x^p using sympy rules.
If the answer is again x^p, return None.
"""
# This function is called just if useful native rules
# are available.
result = from_sympy(sympy.Pow(base.to_sympy(), exp.to_sympy()))
if result.has_form("Power", 2):
# If the expression didn´t change, return None
if result.elements[0].sameQ(base):
return None
return result

# Rational exponent
if isinstance(exp, Rational):
exp_p, exp_q = exp.value.as_numer_denom()
if abs(exp_p) > exp_q:
exp_int, exp_num = divmod(exp_p, exp_q)
exp_rem = Rational(exp_num, exp_q)
factor_1 = eval_Power_number(base, Integer(exp_int))
factor_2 = eval_Power_number(base, exp_rem) or Expression(
SymbolPower, base, exp_rem
)
if factor_1 is Integer1:
return factor_2
return Expression(SymbolTimes, factor_1, factor_2)

# Integer base
if isinstance(base, Integer):
base_value = base.value
if base_value == -1:
if isinstance(exp, Rational):
if exp.sameQ(RationalOneHalf):
return SymbolI
return None
return eval_Power_sympy()
elif base_value < 0:
neg_base = eval_negate_number(base)
candidate = eval_Power_number(neg_base, exp)
if candidate is None:
return None
sign_factor = eval_Power_number(IntegerM1, exp)
if candidate is Integer1:
return sign_factor
return Expression(SymbolTimes, candidate, sign_factor)

# Rational base
if isinstance(base, Rational):
# If the exponent is an Integer or Rational negative value
# restate as a positive power
if (
isinstance(exp, Integer)
and exp.value < 0
or isinstance(exp, Rational)
and exp.value.p < 0
):
base, exp = eval_inverse_number(base), eval_negate_number(exp)
return eval_Power_number(base, exp) or Expression(SymbolPower, base, exp)

p, q = (Integer(u) for u in base.value.as_numer_denom())
p_eval, q_eval = (eval_Power_number(u, exp) for u in (p, q))
# If neither p^exp or q^exp produced a new result,
# leave it alone
if q_eval is None and p_eval is None:
return None
# if q^exp == 1: return p_eval
# (should not happen)
if q_eval is Integer1:
return p_eval
if isinstance(q_eval, Integer):
if isinstance(p_eval, Integer):
return Rational(p_eval.value, q_eval.value)

if p_eval is None:
p_eval = Expression(SymbolPower, p, exp)

if q_eval is None:
q_eval = Expression(SymbolPower, q, exp)
return Expression(
SymbolTimes, p_eval, Expression(SymbolPower, q_eval, IntegerM1)
)
# Pure imaginary base case
elif isinstance(base, Complex) and base.real.is_zero:
base = base.imag
if base.value < 0:
base = eval_negate_number(base)
phase = Expression(
SymbolPower,
IntegerM1,
eval_multiply_numbers(IntegerM1, RationalOneHalf, exp),
)
else:
phase = Expression(
SymbolPower, IntegerM1, eval_multiply_numbers(RationalOneHalf, exp)
)
real_factor = eval_Power_number(base, exp)

if real_factor is None:
return None
return Expression(SymbolTimes, real_factor, phase)

# Generic case
return eval_Power_sympy()


def eval_Power_inexact(base: Number, exp: Number) -> BaseElement:
"""
Eval base^exp for `base` and `exp` inexact numbers
"""
# If both base and exponent are exact quantities,
# use sympy.
prec = min_prec(base, exp)
if prec is not None:
is_machine_precision = base.is_machine_precision() or exp.is_machine_precision()
if is_machine_precision:
number = mpmath.power(base.to_mpmath(), exp.to_mpmath())
return from_mpmath(number)
else:
with mpmath.workprec(prec):
number = mpmath.power(base.to_mpmath(), exp.to_mpmath())
return from_mpmath(number, prec)


def eval_Power_number(base: Number, exp: Number) -> Optional[Number]:
"""
Expand Down

0 comments on commit c16e3bc

Please sign in to comment.