Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More on sympy #890

Draft
wants to merge 4 commits into
base: split_to_sympy
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 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, to_sympy
from mathics.core.convert.sympy import eval_sympy, 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,7 +347,7 @@ def negate(item): # -> Expression (see FIXME below)
else:
return Expression(SymbolTimes, IntegerM1, *item.elements)
elif isinstance(item, Number):
return from_sympy(to_sympy(-item))
return eval_sympy(-item)
else:
return Expression(SymbolTimes, IntegerM1, item)

Expand Down Expand Up @@ -384,6 +384,7 @@ def is_negative(value) -> bool:
def eval(self, items, evaluation):
"Plus[items___]"
items_tuple = numerify(items, evaluation).get_sequence()

return eval_Plus(*items_tuple)


Expand Down Expand Up @@ -838,5 +839,6 @@ def format_outputform(self, items, evaluation):

def eval(self, items, evaluation):
"Times[items___]"
items = numerify(items, evaluation).get_sequence()
return eval_Times(*items)
items_tuple = numerify(items, evaluation).get_sequence()

return eval_Times(*items_tuple)
23 changes: 12 additions & 11 deletions mathics/builtin/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
from_sympy,
sympy_symbol_prefix,
to_sympy,
to_sympy_with_kwargs,
)
from mathics.core.element import BaseElement
from mathics.core.evaluation import Evaluation
Expand Down Expand Up @@ -970,16 +971,16 @@ def to_sympy(self, expr, **kwargs):
elif cond is SymbolFalse:
sympy_cond = False
if sympy_cond is None:
sympy_cond = to_sympy(cond, **kwargs)
sympy_cond = to_sympy_with_kwargs(cond, **kwargs)
if not (sympy_cond.is_Relational or sympy_cond.is_Boolean):
return

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

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

return sympy.Piecewise(*sympy_cases)

Expand Down Expand Up @@ -1061,10 +1062,10 @@ def to_sympy(self, expr, **kwargs):
try:
e_kwargs = kwargs.copy()
e_kwargs["convert_all_global_functions"] = True
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)
e = to_sympy_with_kwargs(expr.elements[0], **e_kwargs)
i = to_sympy_with_kwargs(index.elements[0], **kwargs)
start = to_sympy_with_kwargs(index.elements[1], **kwargs)
stop = to_sympy_with_kwargs(index.elements[2], **kwargs)

return sympy.product(e, (i, start, stop))
except ZeroDivisionError:
Expand Down Expand Up @@ -1510,23 +1511,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 = to_sympy(expr.elements[0], **arg_kwargs)
f_sympy = to_sympy_with_kwargs(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 = [to_sympy(expr, **kwargs) for expr in var_min_max]
bounds = [to_sympy_with_kwargs(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 = to_sympy(min_max_expr_eval, **kwargs)
value = to_sympy_with_kwargs(min_max_expr_eval, **kwargs)
bounds[i] = value

# FIXME: The below tests on SympyExpression, but really the
Expand Down
13 changes: 10 additions & 3 deletions mathics/builtin/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@
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, to_sympy
from mathics.core.convert.sympy import (
from_sympy,
to_numeric_sympy_args,
to_sympy,
to_sympy_with_kwargs,
)
from mathics.core.definitions import Definition
from mathics.core.evaluation import Evaluation
from mathics.core.exceptions import MessageException
Expand Down Expand Up @@ -691,7 +696,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 = to_sympy(whole_expr, evaluation=evaluation)
sympy_expr = to_sympy_with_kwargs(whole_expr, evaluation=evaluation)
if sympy_expr is None:
return None

Expand Down Expand Up @@ -964,7 +969,9 @@ def to_sympy(self, expr, **kwargs):
try:
if self.sympy_name:
elements = self.prepare_sympy(expr.elements)
sympy_args = [to_sympy(element, **kwargs) for element in elements]
sympy_args = [
to_sympy_with_kwargs(element, **kwargs) for element in elements
]
if None in sympy_args:
return None
sympy_function = self.get_sympy_function(elements)
Expand Down
3 changes: 2 additions & 1 deletion mathics/builtin/numbers/calculus.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
from_sympy,
sympy_symbol_prefix,
to_sympy,
to_sympy_with_kwargs,
)
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
Expand Down Expand Up @@ -562,7 +563,7 @@ class DiscreteLimit(Builtin):
def eval(self, f, n, n0, evaluation: Evaluation, options: dict = {}):
"DiscreteLimit[f_, n_->n0_, OptionsPattern[DiscreteLimit]]"

f = to_sympy(f, convert_all_global_functions=True)
f = to_sympy_with_kwargs(f, convert_all_global_functions=True)
n = to_sympy(n)
n0 = to_sympy(n0)

Expand Down
6 changes: 3 additions & 3 deletions mathics/builtin/numbers/diffeqns.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sympy

from mathics.builtin.base import Builtin
from mathics.core.convert.sympy import from_sympy, to_sympy
from mathics.core.convert.sympy import from_sympy, to_sympy_with_kwargs
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
from mathics.core.list import ListExpression
Expand Down Expand Up @@ -153,8 +153,8 @@ def eval(self, eqn, y, x, evaluation: Evaluation):
f_name = func.get_head_name()

conversion_args = {"converted_functions": set([f_name])}
sym_func = to_sympy(func, **conversion_args)
sym_eq = to_sympy(eqn, **conversion_args)
sym_func = to_sympy_with_kwargs(func, **conversion_args)
sym_eq = to_sympy_with_kwargs(eqn, **conversion_args)

# XXX when sympy adds support for higher-order PDE we will have to
# change this to a tuple of solvefuns
Expand Down
9 changes: 7 additions & 2 deletions mathics/builtin/numbers/numbertheory.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
)
from mathics.core.convert.expression import to_mathics_list
from mathics.core.convert.python import from_bool, from_python
from mathics.core.convert.sympy import SympyPrime, from_sympy, to_sympy
from mathics.core.convert.sympy import (
SympyPrime,
from_sympy,
to_sympy,
to_sympy_with_kwargs,
)
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
from mathics.core.list import ListExpression
Expand Down Expand Up @@ -612,7 +617,7 @@ def eval(self, n, evaluation: Evaluation):

def to_sympy(self, expr, **kwargs):
if expr.has_form("Prime", 1):
return SympyPrime(to_sympy(expr.elements[0], **kwargs))
return SympyPrime(to_sympy_with_kwargs(expr.elements[0], **kwargs))


class PrimePi(SympyFunction):
Expand Down
4 changes: 2 additions & 2 deletions mathics/builtin/optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from mathics.core.atoms import IntegerM1
from mathics.core.attributes import A_CONSTANT, A_PROTECTED, A_READ_PROTECTED
from mathics.core.convert.python import from_python
from mathics.core.convert.sympy import from_sympy, to_sympy
from mathics.core.convert.sympy import eval_sympy, from_sympy, to_sympy
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
from mathics.core.list import ListExpression
Expand Down Expand Up @@ -79,7 +79,7 @@ def eval_constraints(self, f, vars, evaluation: Evaluation):
"Maximize[f_List, vars_]"

constraints = [function for function in f.elements]
constraints[0] = from_sympy(to_sympy(constraints[0]) * IntegerM1)
constraints[0] = eval_sympy(constraints[0] * IntegerM1)

dual_solutions = (
Expression(SymbolMinimize, constraints, vars).evaluate(evaluation).elements
Expand Down
11 changes: 9 additions & 2 deletions mathics/builtin/recurrence.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
from mathics.builtin.base import Builtin
from mathics.core.atoms import IntegerM1
from mathics.core.attributes import A_CONSTANT
from mathics.core.convert.sympy import from_sympy, sympy_symbol_prefix, to_sympy
from mathics.core.convert.sympy import (
from_sympy,
sympy_symbol_prefix,
to_sympy,
to_sympy_with_kwargs,
)
from mathics.core.evaluation import Evaluation
from mathics.core.expression import Expression
from mathics.core.list import ListExpression
Expand Down Expand Up @@ -138,7 +143,9 @@ def is_relation(eqn):
SymbolPlus, left, Expression(SymbolTimes, IntegerM1, right)
).evaluate(evaluation)

sym_eq = to_sympy(relation, converted_functions={func.get_head_name()})
sym_eq = to_sympy_with_kwargs(
relation, converted_functions={func.get_head_name()}
)
if sym_eq is None:
return
sym_n = sympy.core.symbols(str(sympy_symbol_prefix + n.name))
Expand Down
6 changes: 3 additions & 3 deletions mathics/builtin/testing_expressions/equality_inequality.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
A_PROTECTED,
)
from mathics.core.convert.expression import to_expression, to_numeric_args
from mathics.core.convert.sympy import to_sympy
from mathics.core.convert.sympy import to_sympy, to_sympy_with_kwargs
from mathics.core.expression import Expression
from mathics.core.expression_predefined import (
MATHICS3_COMPLEX_INFINITY,
Expand Down Expand Up @@ -155,8 +155,8 @@ def infty_equal(self, lhs, rhs, max_extra_prec=None) -> Optional[bool]:

def sympy_equal(self, lhs, rhs, max_extra_prec=None) -> Optional[bool]:
try:
lhs_sympy = to_sympy(lhs, evaluate=True, prec=COMPARE_PREC)
rhs_sympy = to_sympy(rhs, evaluate=True, prec=COMPARE_PREC)
lhs_sympy = to_sympy_with_kwargs(lhs, evaluate=True, prec=COMPARE_PREC)
rhs_sympy = to_sympy_with_kwargs(rhs, evaluate=True, prec=COMPARE_PREC)
except NotImplementedError:
return None

Expand Down
Loading