Skip to content

Commit ada4a4a

Browse files
mmaterarocky
andauthored
RealAbs and RealSign (#885)
This PR implements two new builtins. Also, its low-level implementation is used to simplify some of the low-level eval functions in arithmetic and testing expressions. --------- Co-authored-by: rocky <[email protected]>
1 parent 8a75f8f commit ada4a4a

File tree

8 files changed

+612
-178
lines changed

8 files changed

+612
-178
lines changed

CHANGES.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ New Builtins
99

1010

1111
* `Elements`
12-
12+
* `RealAbs` and `RealSign`
1313

1414
Compatibility
1515
-------------
@@ -24,7 +24,7 @@ Internals
2424
* ``eval_abs`` and ``eval_sign`` extracted from ``Abs`` and ``Sign`` and added to ``mathics.eval.arithmetic``.
2525
* Maximum number of digits allowed in a string set to 7000 and can be adjusted using environment variable
2626
``MATHICS_MAX_STR_DIGITS`` on Python versions that don't adjust automatically (like pyston).
27-
27+
* Real number comparisons implemented is based now in the internal implementation of `RealSign`.
2828

2929
Bugs
3030
----

SYMBOLS_MANIFEST.txt

+2
Original file line numberDiff line numberDiff line change
@@ -824,8 +824,10 @@ System`Read
824824
System`ReadList
825825
System`ReadProtected
826826
System`Real
827+
System`RealAbs
827828
System`RealDigits
828829
System`RealNumberQ
830+
System`RealSign
829831
System`Reals
830832
System`Reap
831833
System`Record

mathics/builtin/arithmetic.py

+99-3
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,13 @@
7777
SymbolTable,
7878
SymbolUndefined,
7979
)
80-
from mathics.eval.arithmetic import eval_Abs, eval_mpmath_function, eval_Sign
80+
from mathics.eval.arithmetic import (
81+
eval_Abs,
82+
eval_mpmath_function,
83+
eval_negate_number,
84+
eval_RealSign,
85+
eval_Sign,
86+
)
8187
from mathics.eval.nevaluator import eval_N
8288
from mathics.eval.numerify import numerify
8389

@@ -823,7 +829,9 @@ def evaluate(self, evaluation: Evaluation):
823829

824830
class Im(SympyFunction):
825831
"""
826-
<url>:WMA link:https://reference.wolfram.com/language/ref/Im.html</url>
832+
<url>
833+
:WMA link:
834+
https://reference.wolfram.com/language/ref/Im.html</url>
827835
828836
<dl>
829837
<dt>'Im[$z$]'
@@ -1207,6 +1215,49 @@ class Real_(Builtin):
12071215
name = "Real"
12081216

12091217

1218+
class RealAbs(Builtin):
1219+
"""
1220+
<url>
1221+
:Abs (Real):
1222+
https://en.wikipedia.org/wiki/Absolute_value</url> (<url>
1223+
:WMA link:
1224+
https://reference.wolfram.com/language/ref/RealAbs.html
1225+
</url>)
1226+
1227+
<dl>
1228+
<dt>'RealAbs[$x$]'
1229+
<dd>returns the absolute value of a real number $x$.
1230+
</dl>
1231+
'RealAbs' is also known as modulus. It is evaluated if $x$ can be compared \
1232+
with $0$.
1233+
1234+
>> RealAbs[-3.]
1235+
= 3.
1236+
'RealAbs[$z$]' is left unevaluated for complex $z$:
1237+
>> RealAbs[2. + 3. I]
1238+
= RealAbs[2. + 3. I]
1239+
>> D[RealAbs[x ^ 2], x]
1240+
= 2 x ^ 3 / RealAbs[x ^ 2]
1241+
"""
1242+
1243+
attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED
1244+
rules = {
1245+
"D[RealAbs[x_],x_]": "x/RealAbs[x]",
1246+
"Integrate[RealAbs[x_],x_]": "1/2 x RealAbs[x]",
1247+
"Integrate[RealAbs[u_],{u_,a_,b_}]": "1/2 b RealAbs[b]-1/2 a RealAbs[a]",
1248+
}
1249+
summary_text = "real absolute value"
1250+
1251+
def eval(self, x: BaseElement, evaluation: Evaluation):
1252+
"""RealAbs[x_]"""
1253+
real_sign = eval_RealSign(x)
1254+
if real_sign is IntegerM1:
1255+
return eval_negate_number(x)
1256+
if real_sign is None:
1257+
return
1258+
return x
1259+
1260+
12101261
class RealNumberQ(Test):
12111262
"""
12121263
## Not found in WMA
@@ -1237,9 +1288,54 @@ def test(self, expr) -> bool:
12371288
return isinstance(expr, (Integer, Rational, Real))
12381289

12391290

1291+
class RealSign(Builtin):
1292+
"""
1293+
<url>
1294+
:Signum:
1295+
https://en.wikipedia.org/wiki/Sign_function</url> (<url>
1296+
:WMA link:
1297+
https://reference.wolfram.com/language/ref/RealSign.html
1298+
</url>)
1299+
<dl>
1300+
<dt>'RealSign[$x$]'
1301+
<dd>returns $-1$, $0$ or $1$ depending on whether $x$ is negative,
1302+
zero or positive.
1303+
</dl>
1304+
'RealSign' is also known as $sgn$ or $signum$ function.
1305+
1306+
>> RealSign[-3.]
1307+
= -1
1308+
'RealSign[$z$]' is left unevaluated for complex $z$:
1309+
>> RealSign[2. + 3. I]
1310+
= RealSign[2. + 3. I]
1311+
1312+
>> D[RealSign[x^2],x]
1313+
= 2 x Piecewise[{{0, x ^ 2 != 0}}, Indeterminate]
1314+
>> Integrate[RealSign[u],{u,0,x}]
1315+
= RealAbs[x]
1316+
"""
1317+
1318+
attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED
1319+
rules = {
1320+
"D[RealSign[x_],x_]": "Piecewise[{{0, x!=0}}, Indeterminate]",
1321+
"Integrate[RealSign[x_],x_]": "RealAbs[x]",
1322+
"Integrate[RealSign[u_],{u_, a_, b_}]": "RealAbs[b]-RealSign[a]",
1323+
}
1324+
summary_text = "real sign"
1325+
1326+
def eval(self, x: Number, evaluation: Evaluation) -> Optional[Integer]:
1327+
"""RealSign[x_]"""
1328+
return eval_RealSign(x)
1329+
1330+
12401331
class Sign(SympyFunction):
12411332
"""
1242-
<url>:WMA link:https://reference.wolfram.com/language/ref/Sign.html</url>
1333+
<url>
1334+
:Sign:
1335+
https://en.wikipedia.org/wiki/Sign_function</url> (<url>
1336+
:WMA link:
1337+
https://reference.wolfram.com/language/ref/Sign.html
1338+
</url>)
12431339
12441340
<dl>
12451341
<dt>'Sign[$x$]'

mathics/builtin/testing_expressions/equality_inequality.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ def numerify_args(items, evaluation) -> list:
6969
n_items = []
7070
for item in items:
7171
if not isinstance(item, Number):
72-
# TODO: use $MaxExtraPrecision insterad of hard-coded 50
73-
item = eval_N(item, evaluation, SymbolMaxPrecision)
72+
item = eval_N(item, evaluation, SymbolMaxExtraPrecision)
7473
n_items.append(item)
7574
items = n_items
7675
else:

mathics/core/systemsymbols.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,9 @@
200200
SymbolRational = Symbol("System`Rational")
201201
SymbolRe = Symbol("System`Re")
202202
SymbolReal = Symbol("System`Real")
203+
SymbolRealAbs = Symbol("System`RealAbs")
203204
SymbolRealDigits = Symbol("System`RealDigits")
205+
SymbolRealSign = Symbol("System`RealSign")
204206
SymbolRepeated = Symbol("System`Repeated")
205207
SymbolRepeatedNull = Symbol("System`RepeatedNull")
206208
SymbolReturn = Symbol("System`Return")
@@ -223,7 +225,7 @@
223225
SymbolSlot = Symbol("System`Slot")
224226
SymbolSparseArray = Symbol("System`SparseArray")
225227
SymbolSplit = Symbol("System`Split")
226-
SymbolSqrt = Symbol("System'Sqrt")
228+
SymbolSqrt = Symbol("System`Sqrt")
227229
SymbolSqrtBox = Symbol("System`SqrtBox")
228230
SymbolStandardDeviation = Symbol("System`StandardDeviation")
229231
SymbolStandardForm = Symbol("System`StandardForm")

0 commit comments

Comments
 (0)