Skip to content

Commit

Permalink
gh-35485: New comparison mode to lazy series and better undefined check
Browse files Browse the repository at this point in the history
    
<!-- Please provide a concise, informative and self-explanatory title.
-->
<!-- Don't put issue numbers in the title. Put it in the Description
below. -->
<!-- For example, instead of "Fixes #12345", use "Add a new method to
multiply two integers" -->

### 📚 Description

<!-- Describe your changes here in detail. -->
<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes #12345". -->
<!-- If your change requires a documentation PR, please link it
appropriately. -->

This fixes #35071 by:

1. providing a method to streams to see if they are unitinalized
2. includes a new mode for comparisons in the lazy series ring based on
the proposal in #35429.

The new comparison mode `secure` simply returns `False` when it cannot
verify that `f == g` and makes sure that `(f == g) == not (f != g)`, and
this will become the new default. In particular, it will return `True`
for `f != g` both when it cannot show that `f == g` and when they are
genuinely different. In order to verify when the comparison is unknown,
we expose the `is_nonzero()` that only returns `True` when the series is
_known_ to be nonzero. Thus, we verify by `(f - g).is_nonzero()`.

When a finite halting precision is given, then that takes priority.

For the infinite halting precision in the "old" version (`secure =
True`), it will raise a `ValueError` when it cannot verify the result.

**NOTE:** `f.is_zero()` is still the default `not f` for speed and the
assumption these are in agreement elsewhere in Sage.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x
]`. -->

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- #12345: short description why this is a dependency
- #34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: #35485
Reported by: Travis Scrimshaw
Reviewer(s): Martin Rubey, Travis Scrimshaw
  • Loading branch information
Release Manager committed Sep 15, 2023
2 parents 21a624a + 1ad7352 commit d412568
Show file tree
Hide file tree
Showing 4 changed files with 770 additions and 266 deletions.
15 changes: 12 additions & 3 deletions src/sage/combinat/species/recursive_species.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def _gs(self, series_ring, base_ring):
sage: F = CombinatorialSpecies()
sage: F.generating_series()
Uninitialized Lazy Laurent Series
Uninitialized Lazy Series
"""
if base_ring not in self._generating_series:
self._generating_series[base_ring] = series_ring.undefined(valuation=(0 if self._min is None else self._min))
Expand All @@ -247,7 +247,7 @@ def _itgs(self, series_ring, base_ring):
sage: F = CombinatorialSpecies()
sage: F.isotype_generating_series()
Uninitialized Lazy Laurent Series
Uninitialized Lazy Series
"""
if base_ring not in self._isotype_generating_series:
self._isotype_generating_series[base_ring] = series_ring.undefined(valuation=(0 if self._min is None else self._min))
Expand All @@ -264,7 +264,7 @@ def _cis(self, series_ring, base_ring):
sage: F = CombinatorialSpecies()
sage: F.cycle_index_series()
Uninitialized Lazy Laurent Series
Uninitialized Lazy Series
"""
if base_ring not in self._cycle_index_series:
self._cycle_index_series[base_ring] = series_ring.undefined(valuation=(0 if self._min is None else self._min))
Expand Down Expand Up @@ -401,6 +401,15 @@ def define(self, x):
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
sage: F.isotype_generating_series()[0:10]
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Check that :issue:`35071` is fixed::
sage: X = species.SingletonSpecies()
sage: E = species.SetSpecies(max=3)
sage: B = species.CombinatorialSpecies(min=1)
sage: B.define(X*E(B))
sage: B.generating_series()
z + z^2 + 3/2*z^3 + 5/2*z^4 + 9/2*z^5 + 17/2*z^6 + 133/8*z^7 + O(z^8)
"""
if not isinstance(x, GenericCombinatorialSpecies):
raise TypeError("x must be a combinatorial species")
Expand Down
Loading

0 comments on commit d412568

Please sign in to comment.