Skip to content

Commit cc30f32

Browse files
authored
Merge pull request #1191 from mathics/simplify-sympy-fns
Try simplying SympyFunction builtins
2 parents 88046a0 + b94894d commit cc30f32

5 files changed

Lines changed: 122 additions & 111 deletions

File tree

mathics/Makefile

Lines changed: 0 additions & 20 deletions
This file was deleted.

mathics/builtin/arithmetic.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,7 @@ class Re(SympyFunction):
10951095
"""
10961096

10971097
attributes = ("Listable", "NumericFunction")
1098+
sympy_name = "re"
10981099

10991100
def apply_complex(self, number, evaluation):
11001101
"Re[number_Complex]"
@@ -1209,7 +1210,7 @@ class Abs(_MPMathFunction):
12091210
mpmath_name = "fabs" # mpmath actually uses python abs(x) / x.__abs__()
12101211

12111212

1212-
class Sign(Builtin):
1213+
class Sign(SympyFunction):
12131214
"""
12141215
<dl>
12151216
<dt>'Sign[$x$]'
@@ -1237,8 +1238,7 @@ class Sign(Builtin):
12371238
= Sign[20]
12381239
"""
12391240

1240-
# Sympy and mpmath do not give the desired form of complex number
1241-
# sympy_name = 'sign'
1241+
sympy_name = "sign"
12421242
# mpmath_name = 'sign'
12431243

12441244
attributes = ("Listable", "NumericFunction")
@@ -1248,14 +1248,15 @@ class Sign(Builtin):
12481248
}
12491249

12501250
def apply(self, x, evaluation):
1251-
"Sign[x_]"
1251+
"%(name)s[x_]"
1252+
# Sympy and mpmath do not give the desired form of complex number
12521253
if isinstance(x, Complex):
12531254
return Expression("Times", x, Expression("Power", Expression("Abs", x), -1))
12541255

12551256
sympy_x = x.to_sympy()
12561257
if sympy_x is None:
12571258
return None
1258-
return from_sympy(sympy.sign(sympy_x))
1259+
return super().apply(x)
12591260

12601261
def apply_error(self, x, seqs, evaluation):
12611262
"Sign[x_, seqs__]"
@@ -1591,7 +1592,7 @@ class Rational_(Builtin):
15911592
name = "Rational"
15921593

15931594
def apply(self, n, m, evaluation):
1594-
"Rational[n_Integer, m_Integer]"
1595+
"%(name)s[n_Integer, m_Integer]"
15951596

15961597
if m.to_sympy() == 1:
15971598
return Integer(n.to_sympy())
@@ -1658,7 +1659,7 @@ class Complex_(Builtin):
16581659
name = "Complex"
16591660

16601661
def apply(self, r, i, evaluation):
1661-
"Complex[r_?NumberQ, i_?NumberQ]"
1662+
"%(name)s[r_?NumberQ, i_?NumberQ]"
16621663

16631664
if isinstance(r, Complex) or isinstance(i, Complex):
16641665
sym_form = r.to_sympy() + sympy.I * i.to_sympy()
@@ -2063,7 +2064,7 @@ class Piecewise(SympyFunction):
20632064
attributes = ("HoldAll",)
20642065

20652066
def apply(self, items, evaluation):
2066-
"Piecewise[items__]"
2067+
"%(name)s[items__]"
20672068
result = self.to_sympy(Expression("Piecewise", *items.get_sequence()))
20682069
if result is None:
20692070
return
@@ -2129,7 +2130,7 @@ class Boole(Builtin):
21292130
attributes = ("Listable",)
21302131

21312132
def apply(self, expr, evaluation):
2132-
"Boole[expr_]"
2133+
"%(name)s[expr_]"
21332134
if isinstance(expr, Symbol):
21342135
if expr == SymbolTrue:
21352136
return Integer(1)

mathics/builtin/base.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import re
44
import sympy
5-
65
from functools import total_ordering
76
import importlib
87
from itertools import chain
@@ -11,6 +10,7 @@
1110

1211
from mathics.version import __version__ # noqa used in loading to check consistency.
1312

13+
from mathics.core.convert import from_sympy
1414
from mathics.core.definitions import Definition
1515
from mathics.core.parser.util import SystemDefinitions, PyMathicsDefinitions
1616
from mathics.core.rules import Rule, BuiltinRule, Pattern
@@ -444,7 +444,6 @@ def get_sympy_names(self) -> typing.List[str]:
444444
return [self.sympy_name]
445445
return []
446446

447-
448447
class UnaryOperator(Operator):
449448
def __init__(self, format_function, *args, **kwargs):
450449
super().__init__(*args, **kwargs)
@@ -532,6 +531,17 @@ def apply(self, expr, evaluation) -> Symbol:
532531

533532

534533
class SympyFunction(SympyObject):
534+
535+
def apply(self, *args):
536+
"""
537+
Generic apply method that uses the class sympy_name.
538+
to call the corresponding sympy function. Arguments are
539+
converted to python and the result is converted from sympy
540+
"""
541+
sympy_args = [a.to_sympy() for a in args]
542+
sympy_fn = getattr(sympy, self.sympy_name)
543+
return from_sympy(sympy_fn(*sympy_args))
544+
535545
def get_constant(self, precision, evaluation, have_mpmath=False):
536546
try:
537547
d = get_precision(precision, evaluation)
@@ -572,6 +582,8 @@ def prepare_mathics(self, sympy_expr):
572582
return sympy_expr
573583

574584

585+
586+
575587
class InvalidLevelspecError(Exception):
576588
pass
577589

mathics/builtin/numbertheory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class ContinuedFraction(SympyFunction):
3939

4040
def apply_1(self, x, evaluation):
4141
"%(name)s[x_]"
42-
return from_python(sympy.continued_fraction(x.to_sympy()))
42+
return super().apply(x)
4343

4444
def apply_2(self, x, n, evaluation):
4545
"%(name)s[x_, n_Integer]"
@@ -686,7 +686,7 @@ class PartitionsP(SympyFunction):
686686

687687
def apply(self, n, evaluation):
688688
"PartitionsP[n_Integer]"
689-
return from_sympy(sympy.npartitions(n.to_sympy()))
689+
return super().apply(n)
690690

691691

692692
class PowerMod(Builtin):

0 commit comments

Comments
 (0)