8000 Simplify __invert__ for polynomial quotient ring element by user202729 · Pull Request #39402 · sagemath/sage · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Simplify __invert__ for polynomial quotient ring element #39402

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 10, 2025

Conversation

user202729
Copy link
Contributor
@user202729 user202729 commented Jan 28, 2025

Previously __invert__ uses xgcd, while the method inverse_mod already exists, it's duplication of code. Besides, while simplifying this some missing features in inverse_mod is uncovered.

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

⌛ Dependencies

Copy link
github-actions bot commented Jan 28, 2025

Documentation preview for this PR (built with commit 9f0b2c3; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@user202729 user202729 marked this pull request as draft January 28, 2025 14:01
@user202729 user202729 marked this pull request as ready for review January 29, 2025 03:57
@vincentmacri
Copy link
Contributor

@user202729 I'm curious if this change has any performance impact. Would you mind posting a before/after timeit result?

@user202729
Copy link
Contributor Author

That's a good question… on the other hand we can argue inverse_mod should be exactly equivalent to quotient ring element __invert__, otherwise one can be optimized in term of the other.

On the other hand, what happened previously is that they both have different supported/unsupported cases (e.g. previously inverse_mod doesn't fallback to inverse_of_unit, while __invert__ does). When they're merged, it seems best to try to support as many cases as possible, this necessarily slows down the operator because more cases need to be checked.

There's the caveat of what to do with inexact rings… we have to adopt one option or the other either way.

@vincentmacri
Copy link
Contributor

From my reading of this you added some extra checking in polynomial_element.pyx, and changed __invert__ in polynomial_quotient_ring_element.py to call the function in polynomial_element.pyx? I expect that from this change the performance hit in polynomial_element.pyx would be negligible, and __invert__ in polynomial_quotient_ring_element.py will be sped up since it's not calling a function written in Cython.

I would like to see before/after timeit results of the two functions before approving this, just in case the reason for the two different implementations was because it had some performance benefits.

Additionally, your PR description mentions that you fixed a few bugs with this PR. Please add tests covering those bugs if you haven't yet, and add a pointer to this PR in the explanation of those tests (i.e. "See :issue:39402").

@vincentmacri
Copy link
Contributor
* [x]  I have linked a relevant issue or discussion.

There is no linked issue or discussion in your PR description. Not sure if you meant to link something or if you accidentally checked the box out of habit.

@user202729
Copy link
Contributor Author
user202729 commented Jan 31, 2025

Not exactly bug, just missing feature — that previously inverse_mod didn't fallback to inverse_of_unit, but it now does (see the newly added doctest).

Also, I don't think there's runtime overhead of passing between the Python–Cython boundary, except for what is already there in Python interpreter.

Timing result:

Setup code:

sage: R.<x> = GF(5)[]
....: S = R.quotient(x^3+1)
sage: s_element = S(x+2)
....: r_element = x+2
....: modulus = x^3+1

Before the PR:

sage: %timeit ~s_element
11.9 μs ± 341 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
sage: %timeit r_element.inverse_mod(modulus)
4.73 μs ± 185 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

After the PR:

sage: %timeit ~s_element
9.72 μs ± 261 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
sage: %timeit r_element.inverse_mod(modulus)
4.81 μs ± 267 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

So… __invert__ got sped up, and inverse_mod gets slightly slowed down (understandable because the additional check to fallback to inverse_of_unit is needed)

Reasonable explanation why __invert__ got sped up: now inverse_of_unit is only attempted when xgcd fails, previously it is unconditionally attempted.

@vincentmacri
Copy link
Contributor
8000 vincentmacri commented Jan 31, 2025

Great! Looks good to me. The inverse_mod slowdown looks like it's probably within the range of measurement error anyway.

vbraun pushed a commit to vbraun/sage that referenced this pull request Feb 3, 2025
sagemathgh-39402: Simplify __invert__ for polynomial quotient ring element
    
Previously `__invert__` uses `xgcd`, while the method `inverse_mod`
already exists, it's duplication of code. Besides, while simplifying
this some missing features in `inverse_mod` is uncovered.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#39402
Reported by: user202729
Reviewer(s):
vbraun pushed a commit to vbraun/sage that referenced this pull request Feb 4, 2025
sagemathgh-39402: Simplify __invert__ for polynomial quotient ring element
    
Previously `__invert__` uses `xgcd`, while the method `inverse_mod`
already exists, it's duplication of code. Besides, while simplifying
this some missing features in `inverse_mod` is uncovered.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#39402
Reported by: user202729
Reviewer(s):
vbraun pushed a commit to vbraun/sage that referenced this pull request Feb 9, 2025
sagemathgh-39402: Simplify __invert__ for polynomial quotient ring element
    
Previously `__invert__` uses `xgcd`, while the method `inverse_mod`
already exists, it's duplication of code. Besides, while simplifying
this some missing features in `inverse_mod` is uncovered.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#39402
Reported by: user202729
Reviewer(s):
vbraun pushed a commit to vbraun/sage that referenced this pull request Feb 9, 2025
sagemathgh-39402: Simplify __invert__ for polynomial quotient ring element
    
Previously `__invert__` uses `xgcd`, while the method `inverse_mod`
already exists, it's duplication of code. Besides, while simplifying
this some missing features in `inverse_mod` is uncovered.

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#39402
Reported by: user202729
Reviewer(s):
@vbraun vbraun merged commit 4e338c6 into sagemath:develop Feb 10, 2025
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0