Skip to content

Commit

Permalink
Merge branch 'master' into reinstate-pymathics-doc
Browse files Browse the repository at this point in the history
  • Loading branch information
rocky authored Feb 5, 2023
2 parents 2904c28 + df2882d commit 6289259
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 10 deletions.
9 changes: 5 additions & 4 deletions mathics/builtin/atomic/numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,11 @@ class Accuracy(Builtin):
>> Accuracy[A]
= Infinity
# For Complex numbers, the accuracy is the smaller of the accuracies of its \
# real and imaginary parts:
# >> Accuracy[1.00`2 + 2.00`2 I]
# = 1.
For Complex numbers, the accuracy is estimated as (minus) the base-10 log
of the square root of the squares of the errors on the real and complex parts:
>> z=Complex[3.00``2, 4..00``2];
>> Accuracy[z] == -Log[10, Sqrt[10^(-2 Accuracy[Re[z]]) + 10^(-2 Accuracy[Im[z]])]]
= True
Accuracy of expressions is given by the minimum accuracy of its elements:
>> Accuracy[F[1, Pi, A]]
Expand Down
6 changes: 4 additions & 2 deletions mathics/core/atoms.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,11 @@ class Real(Number):

# __new__ rather than __init__ is used here because the kind of
# object created differs based on contents of "value".
def __new__(cls, value, p=None) -> "Real":
def __new__(cls, value, p: int = None) -> "Real":
"""
Return either a MachineReal or a PrecisionReal object.
Or raise a TypeError
Or raise a TypeError.
p is the number of binary digits of precision.
"""
if isinstance(value, str):
value = str(value)
Expand All @@ -325,6 +326,7 @@ def __new__(cls, value, p=None) -> "Real":
if p is None or p == FP_MANTISA_BINARY_DIGITS:
return MachineReal.__new__(MachineReal, value)
else:
# TODO: check where p is set in value:
return PrecisionReal.__new__(PrecisionReal, value)

def __eq__(self, other) -> bool:
Expand Down
12 changes: 9 additions & 3 deletions mathics/eval/numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ def eval_Accuracy(z: BaseElement) -> Optional[float]:
return acc_imag
if acc_imag is None:
return acc_real
return min(acc_real, acc_imag)

return -mpmath.log(10 ** (-2 * acc_real) + 10 ** (-2 * acc_imag), 10.0) * 0.5

if isinstance(z, Expression):
elem_accuracies = (eval_Accuracy(z_elem) for z_elem in z.elements)
Expand Down Expand Up @@ -91,11 +92,16 @@ def eval_Precision(z: BaseElement) -> Optional[float]:
if isinstance(z, Complex):
prec_real = eval_Precision(z.real)
prec_imag = eval_Precision(z.imag)
if prec_real is None:
if prec_real is None or prec_imag == prec_real:
return prec_imag
if prec_imag is None:
return prec_real
return min(prec_real, prec_imag)
# both numbers have different precision.
# Evaluate the accuracy and add the log of
# the module.
acc = eval_Accuracy(z)
abs_sq = z.real.value**2 + z.imag.value**2
return acc + mpmath.log(abs_sq, 10.0) * 0.5

if isinstance(z, Expression):
elem_prec = (eval_Precision(z_elem) for z_elem in z.elements)
Expand Down
2 changes: 1 addition & 1 deletion test/builtin/atomic/test_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ def test_n():
# For some reason, the following test
# would fail in WMA
("1. I", "Accuracy[1.]"),
(" 0.4 + 2.4 I", "Accuracy[2.4]"),
(" 0.4 + 2.4 I", "$MachinePrecision-Log[10, Abs[.4+2.4 I]]"),
("2 + 3 I", "Infinity"),
('"abc"', "Infinity"),
# Returns the accuracy of ``` 3.2`3 ```
Expand Down

0 comments on commit 6289259

Please sign in to comment.