Skip to content

Commit fd13a27

Browse files
committed
Try simplying SympyFunction builtins
Would have expected to catch/DRY more items here. But I am optimistic that by starting this as we add more Sympy functions we will be making more use of this. I think it is better to have one way that is used regularly than open-code this a number of places.
1 parent 88046a0 commit fd13a27

4 files changed

Lines changed: 117 additions & 86 deletions

File tree

mathics/builtin/arithmetic.py

Lines changed: 5 additions & 4 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")
@@ -1249,13 +1249,14 @@ class Sign(Builtin):
12491249

12501250
def apply(self, x, evaluation):
12511251
"Sign[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__]"

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)