diff --git a/mathics/builtin/atomic/numbers.py b/mathics/builtin/atomic/numbers.py index 9ad9e4add..0808fabbb 100644 --- a/mathics/builtin/atomic/numbers.py +++ b/mathics/builtin/atomic/numbers.py @@ -148,20 +148,20 @@ def convert_float(x, base, exponents): class Accuracy(Builtin): """ + :Accuracy: https://en.wikipedia.org/wiki/Accuracy_and_precision (WMA :Accuracy: https://reference.wolfram.com/language/ref/Accuracy.html) +
'Accuracy[$x$]'
examines the number of significant digits of $expr$ after the decimal point in the number x.
- This is rather a proof-of-concept than a full implementation. - + This is rather a proof-of-concept than a full implementation. 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] @@ -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 :'Precision': /doc/reference-of-built-in-symbols/atomic-elements-of-expressions/representation-of-numbers/precision/. """ summary_text = "find the accuracy of a number" @@ -954,40 +965,41 @@ def apply(self, expr, evaluation): class Precision(Builtin): """ + :Precision: https://en.wikipedia.org/wiki/Accuracy_and_precision (WMA :Precision: https://reference.wolfram.com/language/ref/Precision.html) +
'Precision[$expr$]'
examines the number of significant digits of $expr$.
- This is rather a proof-of-concept than a full implementation. - Precision of compound expression is not supported yet. + + This is rather a proof-of-concept than a full implementation. + + 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 :'Accuracy': /doc/reference-of-built-in-symbols/atomic-elements-of-expressions/representation-of-numbers/accuracy/. """ rules = { diff --git a/mathics/doc/documentation/1-Manual.mdoc b/mathics/doc/documentation/1-Manual.mdoc index 269cb5c96..5f7ab6a67 100644 --- a/mathics/doc/documentation/1-Manual.mdoc +++ b/mathics/doc/documentation/1-Manual.mdoc @@ -196,50 +196,46 @@ The result of the previous query to \Mathics can be accessed by '%':
-\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 precision 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 :'Precision': /doc/reference-of-built-in-symbols/atomic-elements-of-expressions/representation-of-numbers/precision/ 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, +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 :Accuracy and precision: https://en.wikipedia.org/wiki/Accuracy_and_precision.
diff --git a/test/builtin/atomic/test_numbers.py b/test/builtin/atomic/test_numbers.py index 124988659..9039abc63 100644 --- a/test/builtin/atomic/test_numbers.py +++ b/test/builtin/atomic/test_numbers.py @@ -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)