Skip to content

Log: a zero value gets the error of x, as in WMA - #2067

Merged
rocky merged 1 commit into
masterfrom
log-zero-precision
Oct 26, 2026
Merged

rocky merged 1 commit into
masterfrom
log-zero-precision

Conversation

@tombouctou

Copy link
Copy Markdown
Collaborator

Stacked on #2066 (base complex-precision), which already reworks Log. Once #2066 merges, this PR's base moves to master.

In WMA, when the value of a function is 0, its error is the change of f within the error of each argument, with the other arguments held fixed, and these changes are summed. So Log[1.`20] is 020., and Log[b, 1.20]`` has accuracy P + Log10[Abs[Log[b]]]: ``Log[2, 1.20]is019.84 and Log10[1.`20] is 020.36. The error of the base does not change a zero value: Log[2.20, 1.25]`` has accuracy 24.8408.

  • The change within an error is now the leading Taylor term c δ^p at the size of the error, as in WMA. The step is measured at δ 2^-40 and at half of that, and p is rounded to a multiple of 1/2. Before this PR the change was measured at the error itself, which is wrong at low precision. This fixes other functions too: Sin[01.5]now has accuracy 1.5 (it was 1.50007),Cos[02] 4.30103, ArcCos[1.`3] 1.34949 and Log[1.`3] 3. The test value for Accuracy[ArcCos[1.`5]] changes from 2.34948 to 2.34949, which is what WMA gives.
  • Special points of Log. Before this PR, Log[1.`20, 1.`20] raised ZeroDivisionError inside mpmath, on master as well. Now, as in WMA:
    • an inexact 0 in either argument gives Indeterminate;
    • a base that is 1, or whose error covers 1 (machine 1. included), gives ComplexInfinity, or Indeterminate when x is or covers 1 too;
    • an exact x = 1 with any other base gives an exact 0: Log[2.`20, 1] is 0.
  • MPMathFunction.special_point_value takes over the old indeterminate_at check, so a function can name its own special values; Log overrides it.

Tests are in test_log_zero_precision, next to test_real_valued_precision, and all the values come from WMA 15.

Left for later, as before this PR:

  • complex cases such as Log[1.`20 + 020 I]andLog[-1.20, 1.20]``;
  • Log[2.`20, 1.00000000000000000001`20], because the parser stores slightly different bits than WMA;
  • Log[1.`0.5], because of the shared precision < 1 guard;
  • Power of an inexact zero (Log[2, 1.`20]^2, Sqrt[03]``).

Locally, test_numbers.py, test/builtin/numbers, test/eval and the special-function tests give 1180 passed and 1 xfailed. black, isort and mypy report nothing.

🤖 Generated with Claude Code

Base automatically changed from complex-precision to master October 26, 2026 00:54
@rocky

rocky commented Oct 26, 2026

Copy link
Copy Markdown
Member

@tombouctou: I'd be grateful if you would handle the merge conflicts. Thanks!

MATH-258. Log[1.`20] is 0``20. and Log[b, 1.`20] is 0 with the accuracy
of x plus Log10[Abs[Log[b]]], as in WMA: the change of f within the
error of each argument, the others held fixed, added up. The base does
not change a zero, so Log[2.`20, 1.`25] is 0``24.84.

- A base that is 1, or whose error covers 1, gives ComplexInfinity, and
  Indeterminate when x is or covers 1 too; these raised
  ZeroDivisionError. An inexact 0 gives Indeterminate, and Log[b, 1]
  with an exact 1 is an exact 0.
- The change within an error is the leading term c delta^p of f, as in
  WMA, so Log[1.`3] is 0``3. and Sin[0``1.5] is 0``1.5 rather than
  showing the next terms.
- MPMathFunction.special_point_value takes the Indeterminate check of
  indeterminate_at, and Log adds its own points there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rocky

rocky commented Oct 26, 2026

Copy link
Copy Markdown
Member

LGTM

@rocky
rocky merged commit a438da1 into master Oct 26, 2026
15 checks passed
@rocky
rocky deleted the log-zero-precision branch October 26, 2026 12:14
@rocky

rocky commented Oct 28, 2026

Copy link
Copy Markdown
Member

@tombouctou and @mmatera : There is a lot of very, very useful information contained in the PRs regarding precision and accuracy.

This information should be collected and promoted somewhere to make this information more easily accessible.

One possibility is

<section title="Precision and Accuracy">

Another possibility is the developer's guide: https://mathics-development-guide.readthedocs.io/en/latest/

Thoughts?

@rocky

rocky commented Oct 28, 2026

Copy link
Copy Markdown
Member

And another possibility might be to create a Jupyter notebook with this kind of information.

And the same thing for matching rule and element order precedence

@tombouctou

Copy link
Copy Markdown
Collaborator Author

Thanks, good idea. I'd split it by reader:

  • User-facing behavior goes in the Manual's "Precision and Accuracy" section, as you suggest. There every example is a doctest, so it stays checked against the code. That's Manual: how precision and accuracy carry through computations #2069: errors in sums and products, the condition number for functions, zero values and poles, complex numbers, machine numbers, N with $MaxExtraPrecision, SetPrecision/SetAccuracy. All values are from WMA 15.
  • Internals (PrecisionReal's stored precision and 64-bit value, condition_numbers, special_point_value, the second pass of N) go in the developer's guide, in a separate PR there.

Rule matching and element order precedence would follow the same way, as a separate PR.

A notebook is a nice idea, but it isn't checked by CI, so I'd start with these two.

tombouctou added a commit to tombouctou/mathics-core that referenced this pull request Oct 28, 2026
Collect what the precision PRs (Mathics3#2050-Mathics3#2067) established into the
"Precision and Accuracy" section of the tutorial: errors in sums and
products, the condition number for functions, zero values and poles,
complex numbers, machine numbers, N with $MaxExtraPrecision, and
SetPrecision/SetAccuracy. Every example is a doctest, and every value
matches WMA 15.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
rocky added a commit that referenced this pull request Oct 28, 2026
Following the suggestion in #2067: this collects what the precision PRs
(#2050–#2067) established into the "Precision and Accuracy" section of
the Manual's tutorial.

The section keeps its introduction and gets six subsections:

- **Errors in Sums and Products**: absolute errors add up in a sum,
relative errors in a product; exact constants add no error;
cancellation, inexact zeros, and `0` times an inexact number.
- **Errors in Functions**: precision from the condition number `Abs[x
f'[x] / f[x]]`; a zero value (``Log[1.`20]``), an inexact zero argument,
and `Indeterminate` where the error covers a pole.
- **Complex Numbers**: the parts keep their own errors.
- **Machine Numbers**: a machine number anywhere gives
`MachinePrecision`.
- **Numerical Evaluation with N**: `N[expr, p]` with
`$MaxExtraPrecision`, and `N[expr, {p, a}]`.
- **Setting the Precision**: `SetPrecision` and `SetAccuracy`.

Every example is a doctest, so the text is checked along with the code.
Each value was checked against WMA 15. The internals (`PrecisionReal`'s
stored precision and 64-bit value, `condition_numbers`,
`special_point_value`, the second pass of `N`) belong in the developer's
guide, which is a separate repository; that will be a separate PR.

`docpipeline.py -s "Precision and Accuracy"`: 39 tests, all pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: R. Bernstein <rocky@users.noreply.github.com>
rocky added a commit that referenced this pull request Oct 28, 2026
Following the suggestion in #2067 ("the same thing for matching rule and
element order precedence"). This adds a new tutorial section to the
Manual, "Order of Rules and of Elements", right after "Functions and
Patterns".

- **Which Rule Is Tried First**: the more specific rule is used. A value
such as `f[1]` comes before `f[x_]`, `x_Integer` before `x_`, `_` before
`__` before `___`, a conditional rule before the same rule without a
condition, and `{x_}` before `x_List` before `x_`. A rule with the same
left-hand side replaces the old one.
- **Canonical Order**: what `Sort`, `Order` and `Orderless` use. Numbers
come first, then strings, then symbols, then other expressions. Strings
and symbols are ordered without regard to case, with lower case first.
Monomials are ordered as the terms of a polynomial, and general
expressions by head, then by length, then element by element.

Every example is a doctest, and every result was checked against WMA 15.
I left out the cases where Mathics3 and WMA differ:

- Rules that cannot be compared, such as `f[x_?EvenQ]` and
`f[x_?PrimeQ]`: WMA tries them in the order of definition. That is
#1978, and the draft #1989 addresses it.
- `Optional` and repeated pattern names.
- The place of sums in the canonical order.

These are listed, with WMA 15 values, in the companion developer's guide
page, Mathics3/Mathics3-development-guide#51.

`docpipeline.py -c "Language Tutorial"`: all pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: R. Bernstein <rocky@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants