Skip to content

Commit

Permalink
split to_sympy from BaseElement
Browse files Browse the repository at this point in the history
  • Loading branch information
mmatera committed Jul 22, 2023
1 parent 7ced55a commit b323f1e
Show file tree
Hide file tree
Showing 33 changed files with 231 additions and 206 deletions.
10 changes: 5 additions & 5 deletions mathics/builtin/arithfns/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
A_READ_PROTECTED,
)
from mathics.core.convert.expression import to_expression
from mathics.core.convert.sympy import from_sympy
from mathics.core.convert.sympy import from_sympy, to_sympy
from mathics.core.expression import Expression
from mathics.core.list import ListExpression
from mathics.core.symbols import (
Expand Down Expand Up @@ -347,16 +347,16 @@ def negate(item): # -> Expression (see FIXME below)
else:
return Expression(SymbolTimes, IntegerM1, *item.elements)
elif isinstance(item, Number):
return from_sympy(-item.to_sympy())
return from_sympy(to_sympy(-item))
else:
return Expression(SymbolTimes, IntegerM1, item)

def is_negative(value) -> bool:
if isinstance(value, Complex):
real, imag = value.to_sympy().as_real_imag()
real, imag = to_sympy(value).as_real_imag()
if real <= 0 and imag <= 0:
return True
elif isinstance(value, Number) and value.to_sympy() < 0:
elif isinstance(value, Number) and to_sympy(value) < 0:
return True
return False

Expand Down Expand Up @@ -786,7 +786,7 @@ def inverse(item):
if (
item.has_form("Power", 2)
and isinstance(item.elements[1], (Integer, Rational, Real))
and item.elements[1].to_sympy() < 0
and to_sympy(item.elements[1]) < 0
): # nopep8

negative.append(inverse(item))
Expand Down
47 changes: 26 additions & 21 deletions mathics/builtin/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@
A_PROTECTED,
)
from mathics.core.convert.expression import to_expression
from mathics.core.convert.sympy import SympyExpression, from_sympy, sympy_symbol_prefix
from mathics.core.convert.sympy import (
SympyExpression,
from_sympy,
sympy_symbol_prefix,
to_sympy,
)
from mathics.core.element import BaseElement
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
Expand Down Expand Up @@ -128,7 +133,7 @@ def eval(self, z, evaluation: Evaluation):

# if no arguments are inexact attempt to use sympy
if all(not x.is_inexact() for x in args):
result = to_expression(self.get_name(), *args).to_sympy()
result = to_sympy(to_expression(self.get_name(), *args))
result = self.prepare_mathics(result)
result = from_sympy(result)
# evaluate elements to convert e.g. Plus[2, I] -> Complex[2, 1]
Expand Down Expand Up @@ -467,7 +472,7 @@ def eval(self, r, i, evaluation: Evaluation):
"Complex[r_?NumberQ, i_?NumberQ]"

if isinstance(r, Complex) or isinstance(i, Complex):
sym_form = r.to_sympy() + sympy.I * i.to_sympy()
sym_form = to_sympy(r) + sympy.I * to_sympy(i)
r, i = sym_form.simplify().as_real_imag()
r, i = from_sympy(r), from_sympy(i)
return Complex(r, i)
Expand Down Expand Up @@ -548,12 +553,12 @@ def to_sympy(self, expr, **kwargs):
elif cond is SymbolFalse:
sympy_cond = False
if sympy_cond is None:
sympy_cond = cond.to_sympy(**kwargs)
sympy_cond = to_sympy(cond, **kwargs)
if not (sympy_cond.is_Relational or sympy_cond.is_Boolean):
return

sympy_cases = (
(expr.to_sympy(**kwargs), sympy_cond),
(to_sympy(expr, **kwargs), sympy_cond),
(sympy.Symbol(sympy_symbol_prefix + "System`Undefined"), True),
)
return sympy.Piecewise(*sympy_cases)
Expand Down Expand Up @@ -719,7 +724,7 @@ def to_sympy(self, expr, **kwargs):
elif dir == -1:
return -sympy.oo
else:
return sympy.Mul((expr.elements[0].to_sympy()), sympy.zoo)
return sympy.Mul((to_sympy(expr.elements[0])), sympy.zoo)
else:
return sympy.zoo

Expand Down Expand Up @@ -866,7 +871,7 @@ def eval_number(self, number, evaluation: Evaluation):
def eval(self, number, evaluation: Evaluation):
"Im[number_]"

return from_sympy(sympy.im(number.to_sympy().expand(complex=True)))
return from_sympy(sympy.im(to_sympy(number).expand(complex=True)))


class Integer_(Builtin):
Expand Down Expand Up @@ -965,16 +970,16 @@ def to_sympy(self, expr, **kwargs):
elif cond is SymbolFalse:
sympy_cond = False
if sympy_cond is None:
sympy_cond = cond.to_sympy(**kwargs)
sympy_cond = to_sympy(cond, **kwargs)
if not (sympy_cond.is_Relational or sympy_cond.is_Boolean):
return

sympy_cases.append((then.to_sympy(**kwargs), sympy_cond))
sympy_cases.append((to_sympy(then, **kwargs), sympy_cond))

if len(elements) == 2: # default case
sympy_cases.append((elements[1].to_sympy(**kwargs), True))
sympy_cases.append((to_sympy(elements[1], **kwargs), True))
else:
sympy_cases.append((Integer0.to_sympy(**kwargs), True))
sympy_cases.append((to_sympy(Integer0, **kwargs), True))

return sympy.Piecewise(*sympy_cases)

Expand Down Expand Up @@ -1056,10 +1061,10 @@ def to_sympy(self, expr, **kwargs):
try:
e_kwargs = kwargs.copy()
e_kwargs["convert_all_global_functions"] = True
e = expr.elements[0].to_sympy(**e_kwargs)
i = index.elements[0].to_sympy(**kwargs)
start = index.elements[1].to_sympy(**kwargs)
stop = index.elements[2].to_sympy(**kwargs)
e = to_sympy(expr.elements[0], **e_kwargs)
i = to_sympy(index.elements[0], **kwargs)
start = to_sympy(index.elements[1], **kwargs)
stop = to_sympy(index.elements[2], **kwargs)

return sympy.product(e, (i, start, stop))
except ZeroDivisionError:
Expand Down Expand Up @@ -1136,7 +1141,7 @@ def eval_number(self, number, evaluation: Evaluation):

def eval(self, number, evaluation: Evaluation):
"Re[number_]"
return from_sympy(sympy.re(number.to_sympy().expand(complex=True)))
return from_sympy(sympy.re(to_sympy(number).expand(complex=True)))


class Real_(Builtin):
Expand Down Expand Up @@ -1384,7 +1389,7 @@ def eval(self, x, evaluation: Evaluation):
return result
# return None

sympy_x = x.to_sympy()
sympy_x = to_sympy(x)
if sympy_x is None:
return None
# Unhandled cases. Use sympy
Expand Down Expand Up @@ -1505,23 +1510,23 @@ def to_sympy(self, expr, **kwargs) -> Optional[SympyExpression]:
index = expr.elements[1]
arg_kwargs = kwargs.copy()
arg_kwargs["convert_all_global_functions"] = True
f_sympy = expr.elements[0].to_sympy(**arg_kwargs)
f_sympy = to_sympy(expr.elements[0], **arg_kwargs)
if f_sympy is None:
return

evaluation = kwargs.get("evaluation", None)

# Handle summation parameters: variable, min, max
var_min_max = index.elements[:3]
bounds = [expr.to_sympy(**kwargs) for expr in var_min_max]
bounds = [to_sympy(expr, **kwargs) for expr in var_min_max]

if evaluation:
# Min and max might be Mathics expressions. If so, evaluate them.
for i in (1, 2):
min_max_expr = var_min_max[i]
if not isinstance(expr, Symbol):
min_max_expr_eval = min_max_expr.evaluate(evaluation)
value = min_max_expr_eval.to_sympy(**kwargs)
value = to_sympy(min_max_expr_eval, **kwargs)
bounds[i] = value

# FIXME: The below tests on SympyExpression, but really the
Expand All @@ -1546,7 +1551,7 @@ def to_sympy(self, expr, **kwargs) -> Optional[SympyExpression]:
)
ret = self.get_result(values.elements).evaluate(evaluation)
# Make sure to convert the result back to sympy.
return ret.to_sympy()
return to_sympy(ret)

if None not in bounds:
return sympy.summation(f_sympy, bounds)
6 changes: 3 additions & 3 deletions mathics/builtin/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from mathics.core.convert.expression import to_expression
from mathics.core.convert.op import ascii_operator_to_symbol
from mathics.core.convert.python import from_bool
from mathics.core.convert.sympy import from_sympy, to_numeric_sympy_args
from mathics.core.convert.sympy import from_sympy, to_numeric_sympy_args, to_sympy
from mathics.core.definitions import Definition
from mathics.core.evaluation import Evaluation
from mathics.core.exceptions import MessageException
Expand Down Expand Up @@ -691,7 +691,7 @@ def eval_iter(self, expr, i, imin, imax, di, evaluation):
whole_expr = to_expression(
self.get_name(), expr, ListExpression(i, imin, imax)
)
sympy_expr = whole_expr.to_sympy(evaluation=evaluation)
sympy_expr = to_sympy(whole_expr, evaluation=evaluation)
if sympy_expr is None:
return None

Expand Down Expand Up @@ -964,7 +964,7 @@ def to_sympy(self, expr, **kwargs):
try:
if self.sympy_name:
elements = self.prepare_sympy(expr.elements)
sympy_args = [element.to_sympy(**kwargs) for element in elements]
sympy_args = [to_sympy(element, **kwargs) for element in elements]
if None in sympy_args:
return None
sympy_function = self.get_sympy_function(elements)
Expand Down
7 changes: 4 additions & 3 deletions mathics/builtin/forms/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
String,
StringFromPython,
)
from mathics.core.convert.sympy import to_sympy
from mathics.core.evaluation import Evaluation
from mathics.core.expression import BoxError, Expression
from mathics.core.list import ListExpression
Expand Down Expand Up @@ -124,7 +125,7 @@ def eval_makeboxes(self, expr, n, f, evaluation: Evaluation):
return None

if isinstance(expr, PrecisionReal):
x = expr.to_sympy()
x = to_sympy(expr)
p = int(ceil(expr.get_precision() / LOG2_10) + 1)
elif isinstance(expr, MachineReal):
x = expr.value
Expand Down Expand Up @@ -796,7 +797,7 @@ def eval_python(self, expr, evaluation) -> Expression:

def build_python_form(expr):
if isinstance(expr, Symbol):
return expr.to_sympy()
return to_sympy(expr)
return expr.to_python()

try:
Expand Down Expand Up @@ -832,7 +833,7 @@ def eval_sympy(self, expr, evaluation) -> Optional[Expression]:
"MakeBoxes[expr_, SympyForm]"

try:
sympy_equivalent = expr.to_sympy()
sympy_equivalent = to_sympy(expr)
except Exception:
return
return StringFromPython(sympy_equivalent)
Expand Down
8 changes: 4 additions & 4 deletions mathics/builtin/list/constructing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from mathics.core.atoms import Integer, is_integer_rational_or_real
from mathics.core.attributes import A_HOLD_FIRST, A_LISTABLE, A_LOCKED, A_PROTECTED
from mathics.core.convert.expression import to_expression
from mathics.core.convert.sympy import from_sympy
from mathics.core.convert.sympy import from_sympy, to_sympy
from mathics.core.element import ElementsProperties
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression, structure
Expand Down Expand Up @@ -263,9 +263,9 @@ def eval(self, imin, imax, di, evaluation: Evaluation):
*result, elements_properties=range_list_elements_properties
)

imin = imin.to_sympy()
imax = imax.to_sympy()
di = di.to_sympy()
imin = to_sympy(imin)
imax = to_sympy(imax)
di = to_sympy(di)
index = imin
result = []
while index <= imax:
Expand Down
Loading

0 comments on commit b323f1e

Please sign in to comment.