Skip to content

Commit

Permalink
RealAbs and RealSign (#885)
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
mmatera and rocky authored Jul 21, 2023
1 parent 8a75f8f commit ada4a4a
Show file tree
Hide file tree
Showing 8 changed files with 612 additions and 178 deletions.
4 changes: 2 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ New Builtins


* `Elements`

* `RealAbs` and `RealSign`

Compatibility
-------------
Expand All @@ -24,7 +24,7 @@ Internals
* ``eval_abs`` and ``eval_sign`` extracted from ``Abs`` and ``Sign`` and added to ``mathics.eval.arithmetic``.
* Maximum number of digits allowed in a string set to 7000 and can be adjusted using environment variable
``MATHICS_MAX_STR_DIGITS`` on Python versions that don't adjust automatically (like pyston).

* Real number comparisons implemented is based now in the internal implementation of `RealSign`.

Bugs
----
Expand Down
2 changes: 2 additions & 0 deletions SYMBOLS_MANIFEST.txt
Original file line number Diff line number Diff line change
Expand Up @@ -824,8 +824,10 @@ System`Read
System`ReadList
System`ReadProtected
System`Real
System`RealAbs
System`RealDigits
System`RealNumberQ
System`RealSign
System`Reals
System`Reap
System`Record
Expand Down
102 changes: 99 additions & 3 deletions mathics/builtin/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,13 @@
SymbolTable,
SymbolUndefined,
)
from mathics.eval.arithmetic import eval_Abs, eval_mpmath_function, eval_Sign
from mathics.eval.arithmetic import (
eval_Abs,
eval_mpmath_function,
eval_negate_number,
eval_RealSign,
eval_Sign,
)
from mathics.eval.nevaluator import eval_N
from mathics.eval.numerify import numerify

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

class Im(SympyFunction):
"""
<url>:WMA link:https://reference.wolfram.com/language/ref/Im.html</url>
<url>
:WMA link:
https://reference.wolfram.com/language/ref/Im.html</url>
<dl>
<dt>'Im[$z$]'
Expand Down Expand Up @@ -1207,6 +1215,49 @@ class Real_(Builtin):
name = "Real"


class RealAbs(Builtin):
"""
<url>
:Abs (Real):
https://en.wikipedia.org/wiki/Absolute_value</url> (<url>
:WMA link:
https://reference.wolfram.com/language/ref/RealAbs.html
</url>)
<dl>
<dt>'RealAbs[$x$]'
<dd>returns the absolute value of a real number $x$.
</dl>
'RealAbs' is also known as modulus. It is evaluated if $x$ can be compared \
with $0$.
>> RealAbs[-3.]
= 3.
'RealAbs[$z$]' is left unevaluated for complex $z$:
>> RealAbs[2. + 3. I]
= RealAbs[2. + 3. I]
>> D[RealAbs[x ^ 2], x]
= 2 x ^ 3 / RealAbs[x ^ 2]
"""

attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED
rules = {
"D[RealAbs[x_],x_]": "x/RealAbs[x]",
"Integrate[RealAbs[x_],x_]": "1/2 x RealAbs[x]",
"Integrate[RealAbs[u_],{u_,a_,b_}]": "1/2 b RealAbs[b]-1/2 a RealAbs[a]",
}
summary_text = "real absolute value"

def eval(self, x: BaseElement, evaluation: Evaluation):
"""RealAbs[x_]"""
real_sign = eval_RealSign(x)
if real_sign is IntegerM1:
return eval_negate_number(x)
if real_sign is None:
return
return x


class RealNumberQ(Test):
"""
## Not found in WMA
Expand Down Expand Up @@ -1237,9 +1288,54 @@ def test(self, expr) -> bool:
return isinstance(expr, (Integer, Rational, Real))


class RealSign(Builtin):
"""
<url>
:Signum:
https://en.wikipedia.org/wiki/Sign_function</url> (<url>
:WMA link:
https://reference.wolfram.com/language/ref/RealSign.html
</url>)
<dl>
<dt>'RealSign[$x$]'
<dd>returns $-1$, $0$ or $1$ depending on whether $x$ is negative,
zero or positive.
</dl>
'RealSign' is also known as $sgn$ or $signum$ function.
>> RealSign[-3.]
= -1
'RealSign[$z$]' is left unevaluated for complex $z$:
>> RealSign[2. + 3. I]
= RealSign[2. + 3. I]
>> D[RealSign[x^2],x]
= 2 x Piecewise[{{0, x ^ 2 != 0}}, Indeterminate]
>> Integrate[RealSign[u],{u,0,x}]
= RealAbs[x]
"""

attributes = A_LISTABLE | A_NUMERIC_FUNCTION | A_PROTECTED
rules = {
"D[RealSign[x_],x_]": "Piecewise[{{0, x!=0}}, Indeterminate]",
"Integrate[RealSign[x_],x_]": "RealAbs[x]",
"Integrate[RealSign[u_],{u_, a_, b_}]": "RealAbs[b]-RealSign[a]",
}
summary_text = "real sign"

def eval(self, x: Number, evaluation: Evaluation) -> Optional[Integer]:
"""RealSign[x_]"""
return eval_RealSign(x)


class Sign(SympyFunction):
"""
<url>:WMA link:https://reference.wolfram.com/language/ref/Sign.html</url>
<url>
:Sign:
https://en.wikipedia.org/wiki/Sign_function</url> (<url>
:WMA link:
https://reference.wolfram.com/language/ref/Sign.html
</url>)
<dl>
<dt>'Sign[$x$]'
Expand Down
3 changes: 1 addition & 2 deletions mathics/builtin/testing_expressions/equality_inequality.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ def numerify_args(items, evaluation) -> list:
n_items = []
for item in items:
if not isinstance(item, Number):
# TODO: use $MaxExtraPrecision insterad of hard-coded 50
item = eval_N(item, evaluation, SymbolMaxPrecision)
item = eval_N(item, evaluation, SymbolMaxExtraPrecision)
n_items.append(item)
items = n_items
else:
Expand Down
4 changes: 3 additions & 1 deletion mathics/core/systemsymbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@
SymbolRational = Symbol("System`Rational")
SymbolRe = Symbol("System`Re")
SymbolReal = Symbol("System`Real")
SymbolRealAbs = Symbol("System`RealAbs")
SymbolRealDigits = Symbol("System`RealDigits")
SymbolRealSign = Symbol("System`RealSign")
SymbolRepeated = Symbol("System`Repeated")
SymbolRepeatedNull = Symbol("System`RepeatedNull")
SymbolReturn = Symbol("System`Return")
Expand All @@ -223,7 +225,7 @@
SymbolSlot = Symbol("System`Slot")
SymbolSparseArray = Symbol("System`SparseArray")
SymbolSplit = Symbol("System`Split")
SymbolSqrt = Symbol("System'Sqrt")
SymbolSqrt = Symbol("System`Sqrt")
SymbolSqrtBox = Symbol("System`SqrtBox")
SymbolStandardDeviation = Symbol("System`StandardDeviation")
SymbolStandardForm = Symbol("System`StandardForm")
Expand Down
Loading

0 comments on commit ada4a4a

Please sign in to comment.