Skip to content

Commit

Permalink
Merge pull request #553 from Mathics3/accuracy-and-precision-doc
Browse files Browse the repository at this point in the history
Go over docs for Accuracy and Precision
  • Loading branch information
rocky authored Sep 15, 2022
2 parents 4302237 + 9be4fc5 commit a0f456b
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 48 deletions.
62 changes: 37 additions & 25 deletions mathics/builtin/atomic/numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,20 +148,20 @@ def convert_float(x, base, exponents):

class Accuracy(Builtin):
"""
<url>:Accuracy: https://en.wikipedia.org/wiki/Accuracy_and_precision</url> (WMA <url>:Accuracy: https://reference.wolfram.com/language/ref/Accuracy.html</url>)
<dl>
<dt>'Accuracy[$x$]'
<dd>examines the number of significant digits of $expr$ after the decimal point in the number x.
</dl>
This is rather a proof-of-concept than a full implementation.
<i>This is rather a proof-of-concept than a full implementation.</i>
Accuracy of a real number is estimated from its value and its precision:
>> Accuracy[3.1416`2]
= 1.50298
Notice that the value is not exactly equal to the obtained in WMA: This is due to the different way in which
Precision is handled in SymPy.
Notice that the value is not exactly equal to the obtained in WMA: This is due to the different way in which 'Precision' is handled in SymPy.
Accuracy for exact atoms is $Infinity$:
>> Accuracy[1]
Expand All @@ -176,9 +176,20 @@ class Accuracy(Builtin):
Accuracy of expressions is given by the minimum accuracy of its elements:
>> Accuracy[F[1, Pi, A]]
= Infinity
>> Accuracy[F[1.3, Pi, A]]
= 14.8861
'Accuracy' for the value 0 is a fixed-precision Real number:
>> 0``2
= 0.00
In compound expressions, the 'Accuracy' is fixed by the number with
the lowest 'Accuracy':
>> Accuracy[{{1, 1.`},{1.``5, 1.``10}}]
= 5.
See also <url>:'Precision': /doc/reference-of-built-in-symbols/atomic-elements-of-expressions/representation-of-numbers/precision/</url>.
"""

summary_text = "find the accuracy of a number"
Expand Down Expand Up @@ -954,40 +965,41 @@ def apply(self, expr, evaluation):

class Precision(Builtin):
"""
<url>:Precision: https://en.wikipedia.org/wiki/Accuracy_and_precision</url> (WMA <url>:Precision: https://reference.wolfram.com/language/ref/Precision.html</url>)
<dl>
<dt>'Precision[$expr$]'
<dd>examines the number of significant digits of $expr$.
</dl>
This is rather a proof-of-concept than a full implementation.
Precision of compound expression is not supported yet.
<i>This is rather a proof-of-concept than a full implementation.</i>
The precision of an exact number, e.g. an Integer, is 'Infinity':
>> Precision[1]
= Infinity
A fraction is an exact number too, so its Precision is 'Infinity':
>> Precision[1/2]
= Infinity
>> Precision[0.5]
= MachinePrecision
#> Precision[0.0]
= MachinePrecision
#> Precision[0.000000000000000000000000000000000000]
= 0.
#> Precision[-0.0]
= MachinePrecision
#> Precision[-0.000000000000000000000000000000000000]
= 0.
Numbers entered in the form $digits$`$p$ are taken to have precision $p$:
#> 1.0000000000000000 // Precision
= MachinePrecision
#> 1.00000000000000000 // Precision
= 17.
>> Precision[1.23`10]
= 10.
#> 0.4 + 2.4 I // Precision
Precision of a machine‐precision number is 'MachinePrecision':
>> Precision[0.5]
= MachinePrecision
#> Precision[2 + 3 I]
= Infinity
#> Precision["abc"]
= Infinity
In compound expressions, the 'Precision' is fixed by the number with
the lowest 'Precision':
>> Precision[{{1, 1.`},{1.`5, 1.`10}}]
= 5.
See also <url>:'Accuracy': /doc/reference-of-built-in-symbols/atomic-elements-of-expressions/representation-of-numbers/accuracy/</url>.
"""

rules = {
Expand Down
42 changes: 19 additions & 23 deletions mathics/doc/documentation/1-Manual.mdoc
Original file line number Diff line number Diff line change
Expand Up @@ -196,50 +196,46 @@ The result of the previous query to \Mathics can be accessed by '%':

<section title="Precision and Accuracy">

\Mathics handles relative ('Precision') and absolute ('Accuracy') uncertanties in numerical quantities. 'Precision' is set by adding a single reversed quote $`$
and the numerical value of the precision right after the last digit of the mantissa. For example,
\Mathics handles relative and absolute uncertanties in numerical quantities. The <em>precision</em> or relative accuracy, is set by adding a RawBackquote character ('`') and the number of digits of precision in the mantissa. For example:

>> a = 3.1416`3
>> 3.1416`3
= 3.14

set $a$ with a number having a relative uncertainty of $10^{-3}$, in a way that this number is numerically equivalent to $3.1413`4$:
Above, two decimal places are shown in output after the decimal point, but three places of precision are stored.

>> a == 3.1413`4
The relative uncertainty of '3.1416`3' is 10^-3. It is numerically equivalent, in three places after the decimal point, to 3.1413`4:

>> 3.1416`3 == 3.1413`4
= True

We can recover the precision of the number by using 'Precision'
We can get the precision of the number by using the \Mathics <url>:'Precision': /doc/reference-of-built-in-symbols/atomic-elements-of-expressions/representation-of-numbers/precision/</url> function:

>> Precision[a]
= 3.
>> Precision[3.1413`4]
= 4.

Up to the precision, $a$ is equivalent to $\pi$, so
While 3.1419 not the closest approximation to Pi in 4 digits after the decimal point (or with precision 4), for 3 digits of precision it is:

>> Pi - a
= 0.
>> Pi == a
>> Pi == 3.141987654321`3
= True

In a similar way, 'Accuracy' is set by adding a double reversed quote $``$
and the numerical value of the accuracy right after the last digit of the mantissa. For example,
<url>The absolute accuracy of a number, is set by adding a two RawBackquotes '``' and the number digits.

For example:

>> a = 13.1416``4
>> 13.1416``4
= 13.142

set $a$ with a number having a absolute uncertainty of $10^{-4}$, in a way that this number is numerically equivalent to $13.1413``4$:
is a number having a absolute uncertainty of 10^-4. This number is numerically equivalent to '13.1413``4':

>> a == 13.1413``4
>> 13.1416``4 == 13.1413``4
= True

For $0$, 'Precision' is ignored, since corresponds to a zero uncertainty:

>> 0`4
= 0

while 'Accuracy' is taken into account by storing the value as a fixed precision Real number:
The absolute accuracy for the value 0 is a fixed-precision Real number:

>> 0``4
= 0.0000

See also <url>:Accuracy and precision: https://en.wikipedia.org/wiki/Accuracy_and_precision</url>.
</section>


Expand Down
42 changes: 42 additions & 0 deletions test/builtin/atomic/test_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,45 @@ def test_n():
("N[1.01234567890123456789`, 2] // Precision", "MachinePrecision"),
):
check_evaluation(str_expr, str_expected)


def test_accuracy():
for str_expr, str_expected in (
("0`4", "0"),
("Accuracy[0.0]", "15."),
("Accuracy[0.000000000000000000000000000000000000]", "36."),
("Accuracy[-0.0]", "15."),
# In WMA, this gives 36. Seems to be a rounding issue
# ("Accuracy[-0.000000000000000000000000000000000000]", "36."),
("1.0000000000000000 // Accuracy", "15."),
("1.00000000000000000 // Accuracy", "17."),
# Returns the accuracy of ```2.4```
(" 0.4 + 2.4 I // Accuracy", "14.6198"),
("Accuracy[2 + 3 I]", "Infinity"),
('Accuracy["abc"]', "Infinity"),
# Returns the accuracy of ``` 3.2`3 ```
('Accuracy[F["a", 2, 3.2`3]]', "2.49482"),
('Accuracy[{{a, 2, 3.2`},{2.1`5, 3.2`3, "a"}}]', "2.49482"),
# Another case of issues with rounding. In Mathics, this returns
# 2.67776
# ('Accuracy[{{a, 2, 3.2`},{2.1``3, 3.2``5, "a"}}]', '3.'),
):
check_evaluation(str_expr, str_expected)


def test_precision():
for str_expr, str_expected in (
("0`4", "0"),
("Precision[0.0]", "MachinePrecision"),
("Precision[0.000000000000000000000000000000000000]", "0."),
("Precision[-0.0]", "MachinePrecision"),
("Precision[-0.000000000000000000000000000000000000]", "0."),
("1.0000000000000000 // Precision", "MachinePrecision"),
("1.00000000000000000 // Precision", "17."),
(" 0.4 + 2.4 I // Precision", "MachinePrecision"),
("Precision[2 + 3 I]", "Infinity"),
('Precision["abc"]', "Infinity"),
('Precision[F["a", 2, 3.2`3]]', "3."),
('Precision[{{a,2,3.2`},{2.1`5, 2.`3, "a"}}]', "3."),
):
check_evaluation(str_expr, str_expected)

0 comments on commit a0f456b

Please sign in to comment.