Skip to content
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

Added prev_prime(x) #284

Merged
merged 7 commits into from
Sep 11, 2023
Merged

Added prev_prime(x) #284

merged 7 commits into from
Sep 11, 2023

Conversation

sethtroisi
Copy link
Contributor

@sethtroisi sethtroisi commented Nov 21, 2020

I authored mpz_prevprime and finally got it upstreamed. I'd love if gmpy2 would also support this (as I mostly call gmp via your wonderful wrapper).

Couple of notes

  • I throw Py_RETURN_NOTIMPLEMENTED if __GNU_MP_VERSION < 6.3
    I'm not sure when gmp 6.3 release will happen but this is the safest option. I/you/others can always remove this line (or change it to 6.2) when using development version of the repo which uses build version 6.2.99.
  • mpz_prevprime has an int return (0 when no previous prime (arg < 2), definite prime, probable prime) I can return a two element tuple but IMHO it's better to just return the previous_prime (or 2).

@casevh
Copy link
Collaborator

casevh commented Nov 22, 2020

Hi Seth,

Congratulations for getting prev_prime() accepted. I will merge this in a few days.

@sethtroisi
Copy link
Contributor Author

I inverted the #if which fixes compilation. Tests are still broken because libgmp-dev is version 6.2
Maybe I should comment out the tests and leave a note to enable them in 6months/1year when 6.3 is released?

@casevh
Copy link
Collaborator

casevh commented Nov 24, 2020 via email

@sethtroisi
Copy link
Contributor Author

sethtroisi commented Jul 19, 2022

libgmp could have contained prevprime in 6.2.1, but it didn't.
I fixed the merge conflict. Guess I'll wait another 2 years for a gmp release.

@sethtroisi sethtroisi force-pushed the master branch 2 times, most recently from e2ac363 to e2f956b Compare July 20, 2022 04:57
@casevh
Copy link
Collaborator

casevh commented Jul 23, 2022

I've generally used conditional compilation to only include a new function if the underlying library provides it. But I may have another option for including new features. Don't update your PR just yet.

@skirpichev
Copy link
Contributor

@casevh, I think it's time to review this (gmp-6.3.0 is available).

@sethtroisi, could you, please, fix merge conflicts? Documentation structure was changed, let me know if you will need some help.

@sethtroisi
Copy link
Contributor Author

I think I'm testing the correct thing by using

python setup.py build_ext --inplace
pip install .
python test/runtests.py 

I have some test failures but they are certainly related to mpc e.g. mpc('nan+nanj') does not match mpc('nannanj').

Let me know if you want any changes.

@sethtroisi
Copy link
Contributor Author

I think CI requires than #425 is merged. Currently GMP 6.3 isn't downloaded which results in PrevPrime returning NotImplemented in the tests.

static PyObject *
GMPy_MPZ_Function_PrevPrime(PyObject *self, PyObject *other)
{
#if (__GNU_MP_VERSION > 6) || (__GNU_MP_VERSION == 6 && __GNU_MP_VERSION_MINOR >= 3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given f8878b6 (and 39a9e48), I would guess, that you should surround the whole function by #if's.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to only include functions that are supported by the GMP/MPFR/MPC version. I think it causes less confusion than raising NonImpemented. The documentation can include prev_prime with a note "Only present when compiled with GMP 6.3.0 or later."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the documentation is in the build artifacts and I'll check that it contains that note which I added to PyDoc_STRVAR(GMPy_doc_mpz_function_prev_prime.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the documentation is in the build artifacts

No. The documentation build will fail, unless you exclude new function for GMP < 6.3.0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OR (perhaps, it's better), you can include the prev_prive (a copy of the docstring) to the sphinx docs with the function directive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got sphinx running locally and verified that the prev_prime is included (conditional on has_prev_prime which is hardcoded in conf.py as mp_version() >= "GMP 6.3.0")

Comment on lines 660 to 680
Test prev_prime
---------------
>>> gmpy2.prev_prime('a')
Traceback (most recent call last):
...
TypeError:
>>> gmpy2.prev_prime(2)
mpz(2)
>>> gmpy2.prev_prime(mpz(3))
mpz(2)
>>> gmpy2.prev_prime(3)
mpz(2)
>>> gmpy2.prev_prime(1000004)
mpz(1000003)
>>> gmpy2.prev_prime(1000033)
mpz(1000003)
>>> gmpy2.prev_prime(-100)
mpz(2)
>>> gmpy2.prev_prime(1)
mpz(2)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per #377, you shouldn't use test/*.txt files for new tests.

These tests could be moved to the test_mpz.py, I think. And you could use the pytest's skipif fixture to skip them if the GMP library is too old.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some *.txt are there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left one additional test for next_prime(1000000) which I think is a nice test I can remove if you don't want it added here.

docs/mpz.rst Outdated
@@ -105,6 +105,7 @@ mpz Functions
.. autofunction:: powmod_exp_list
.. autofunction:: powmod_base_list
.. autofunction:: powmod_sec
.. autofunction:: prev_prime
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should include this function to the sphinx docs.

But if so, you should do this conditionally, probably with the "only" directive of the sphinx. Also, I think that in this case we should mention in the prev_prime docstring, that this function is available only for certain conditions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.. autofunction:: prev_prime
.. function:: prev_prime(x, /) -> mpz
Return the previous *probable* prime number < x.
Only present when compiled with GMP 6.3.0 or later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a few days but I made a conditional tag and got this working with the only directive (thanks for pointing me at it).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with your solution is that this function will not be displayed on the https://gmpy2.readthedocs.io/en/latest/ for a long time. That's why I did this suggestion.

Copy link
Contributor Author

@sethtroisi sethtroisi Sep 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep you were perspective in a way I had to learn by making the mistake. Should be fixed now. I tried to run build, tests, and sphinx, with and without gmp 6.3.0.

return NULL;
}
else {
if (!mpz_prevprime(result->z, result->z)) {
Copy link
Contributor

@skirpichev skirpichev Sep 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs says in this case the rop is unchanged. Maybe you should return result without any tests?

Or we could raise a ValueError. Silent, undocumented default - looks odd for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to ValueError.

@skirpichev
Copy link
Contributor

I think I'm testing the correct thing by using

pip install .
python test/runtests.py

Should be enough.

I have some test failures but they are certainly related to mpc e.g. mpc('nan+nanj') does not match mpc('nannanj').

Probably related to #422. If you did a rebase wrt the current master - there should be no failures.

I think CI requires than #425 is merged. Currently GMP 6.3 isn't downloaded which results in PrevPrime returning NotImplemented in the tests.

Yes, #425 is required. But tests should pass in any case.

src/gmpy2.c Show resolved Hide resolved
@codecov-commenter
Copy link

codecov-commenter commented Sep 10, 2023

Codecov Report

Merging #284 (3277ae3) into master (eb56a3d) will not change coverage.
Report is 9 commits behind head on master.
The diff coverage is 100.00%.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

@@           Coverage Diff           @@
##           master     #284   +/-   ##
=======================================
  Coverage   83.63%   83.63%           
=======================================
  Files          49       49           
  Lines       11715    11715           
  Branches     2190     2190           
=======================================
  Hits         9798     9798           
  Misses       1917     1917           
Files Changed Coverage Δ
src/gmpy2.c 100.00% <ø> (ø)
src/gmpy2_mpz_misc.c 100.00% <100.00%> (ø)

... and 1 file with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Co-authored-by: Sergey B Kirpichev <[email protected]>
@casevh casevh merged commit 7f09f58 into aleaxit:master Sep 11, 2023
@casevh
Copy link
Collaborator

casevh commented Sep 11, 2023

Thanks.

@sethtroisi
Copy link
Contributor Author

Here I was writing a long question about if anything more was needed. :) Thanks for pulling I'm glad to have gotten this included!

@skirpichev
Copy link
Contributor

Here I was writing a long question about if anything more was needed. :)

@sethtroisi, as I said above - you could just use "function" directive without any checks. Else the sphinx docs on the https://gmpy2.readthedocs.io/en/latest/ or in the build artifact will not include the prev_prime() function. @casevh, probably we want to include this unconditionally (with a warning), right?

@skirpichev
Copy link
Contributor

See #430

@sethtroisi sethtroisi deleted the master branch September 11, 2023 04:39
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.

4 participants