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

_nth_root_naive fails for integer mod #32084

Closed
kliem opened this issue Jun 29, 2021 · 32 comments
Closed

_nth_root_naive fails for integer mod #32084

kliem opened this issue Jun 29, 2021 · 32 comments

Comments

@kliem
Copy link
Contributor

kliem commented Jun 29, 2021

sage -t --long --random-seed=3 src/sage/rings/finite_rings/integer_mod.pyx
**********************************************************************
File "src/sage/rings/finite_rings/integer_mod.pyx", line 1525, in sage.rings.finite_rings.integer_mod.IntegerMod_abstract._nth_root_naive
Failed example:
    for n in range(2,100): # long time
        K = Integers(n)
        elist = list(range(1,min(2*n+2,100)))
        for e in random_sublist(elist, 5/len(elist)):
            for a in random_sublist(range(1,n), min((n+2)//2,10)/(n-1)):
                b = K(a)
                try:
                    L = b.nth_root(e, all=True)
                    if L:
                        c = b.nth_root(e)
                except Exception:
                    L = [-1]
                M = b._nth_root_naive(e)
                if sorted(L) != M:
                    print("mod(%s, %s).nth_root(%s,all=True), mod(%s, %s)._nth_root_naive(%s)" % (a,n,e,a,n,e))
                if L and (c not in L):
                    print("mod(%s, %s).nth_root(%s), mod(%s, %s).nth_root(%s,all=True)" % (a,n,e,a,n,e))
Expected nothing
Got:
    mod(43, 75).nth_root(75), mod(43, 75).nth_root(75,all=True)

Component: algebra

Keywords: ring, mod, root

Author: Dave Morris

Branch/Commit: 226fe84

Reviewer: Travis Scrimshaw

Issue created by migration from https://trac.sagemath.org/ticket/32084

@kliem kliem added this to the sage-9.4 milestone Jun 29, 2021
@DaveWitteMorris
Copy link
Member

comment:1

The problem seems to be that mod(a, n).nth_root(k) sometimes returns a value that is not actually a kth root of mod(a, n):

sage: for n in range(100):
....:     for k in range(2*n):
....:         kth_powers = set(x^k % n for x in range(n))
....:         bad = set( (a, mod(a, n).nth_root(k), mod(a, n).nth_root(k)^k) for a in kth_powers
....:             if mod(a, n).nth_root(k)^k % n != a)
....:         if bad:
....:             print(n, k, bad)
50 50 {(49, 49, 1), (24, 24, 26)}
50 75 {(7, 7, 43), (43, 43, 7), (32, 32, 18), (18, 18, 32)}
75 50 {(49, 74, 1), (24, 24, 51)}
75 75 {(7, 7, 43), (18, 18, 57), (68, 68, 32), (57, 57, 18), (32, 32, 68), (43, 43, 7)}
98 98 {(79, 79, 67), (30, 30, 18), (67, 67, 79), (18, 18, 30)}

In the above examples, the erroneous kth root of a is always a itself, but there are larger examples where this is not the case. For example:

sage: n = 147
sage: a = 67
sage: k = 98
sage: mod(a, n).nth_root(k)
116
sage: (116^k) % n
79

@DaveWitteMorris
Copy link
Member

Branch: public/32084

@DaveWitteMorris
Copy link
Member

comment:3

When n is a prime power, mod(a,n).nth_root(k) returned self in certain cases where self happened to be a (p - 1)th root of unity, but it needs to return a kth root of self. This PR should fix the problem.


New commits:

e593b0atrac 32084 fix nth root

@DaveWitteMorris
Copy link
Member

Commit: e593b0a

@DaveWitteMorris
Copy link
Member

Author: Dave Morris

@kliem
Copy link
Contributor Author

kliem commented Jun 30, 2021

Work Issues: #29979 -- rebase one ticket on the other (#29979 marks this as a bug)

@DaveWitteMorris
Copy link
Member

Changed branch from public/32084 to public/32084r1

@DaveWitteMorris
Copy link
Member

Changed work issues from #29979 -- rebase one ticket on the other (#29979 marks this as a bug) to none

@DaveWitteMorris
Copy link
Member

Changed commit from e593b0a to 6158236

@DaveWitteMorris
Copy link
Member

Dependencies: #29979

@DaveWitteMorris
Copy link
Member

comment:6

Rebased on #29979, and removed "known bug" tag. Only the last 2 commits are from this ticket ('trac 32084 fix nth root' and 'remove "known bug" tag').


New commits:

a03aebbmake some files of rings fuzz ready
e92d0a6some changes to make rings fuzz ready
8d93480make rings ready for fuzzed doctests
f008269add ticket numbers to `not tested`
540413efix various remaining doctests in rings
2a3eebba few more doctests
5c027a7get a random nonzero element
bf9dee1trac 32084 fix nth root
6158236remove "known bug" tag

@kliem
Copy link
Contributor Author

kliem commented Jul 1, 2021

comment:7

The first value in the line above is quasi K(modp.lift(), but here we pick K(modp). Why?

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Jul 1, 2021

Changed commit from 6158236 to 779691a

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Jul 1, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

779691ause explicit lift()

@DaveWitteMorris
Copy link
Member

comment:9

Thanks for the comment. Using lift() may be a bit safer, because we know exactly what K(modp.lift()) will do (lift modp to an integer, and then pass to Z/(p^k Z) in the obvious way), but it may not be so obvious what the constructor K(modp) will do. So I made the change. We are in the situation where every lift of modp to an element of Z/(p^k Z) is an nth root, so it does not matter how we get the lift.

@tscrim
Copy link
Collaborator

tscrim commented Jul 2, 2021

comment:10

Can we reverse the dependency with #29979? I think this has a much higher chance of getting reviewed first.

@kliem
Copy link
Contributor Author

kliem commented Jul 2, 2021

comment:11

The work issue was really meant as a note that one of the tickets needs to be rebased. I think the order should be whichever ticket is ready to be merged first.

Btw, it would be great to add one of the failing examples as a doctest.

@DaveWitteMorris
Copy link
Member

Changed commit from 779691a to e593b0a

@DaveWitteMorris
Copy link
Member

New commits:

e593b0atrac 32084 fix nth root

@DaveWitteMorris
Copy link
Member

Work Issues: #29979 -- rebase one ticket on the other (#29979 marks this as a bug)

@DaveWitteMorris
Copy link
Member

Changed branch from public/32084r1 to public/32084

@DaveWitteMorris
Copy link
Member

Changed branch from public/32084 to public/32084r2

@DaveWitteMorris
Copy link
Member

Changed commit from e593b0a to 226fe84

@DaveWitteMorris
Copy link
Member

comment:14

Sorry for the confusion. I think I put this back the way it was (including the work issue), except that I rebased on 9.4b4 and added a doctest.


New commits:

0994f0ftrac 32084 fix nth root
226fe84trac 32084 fix nth root

@DaveWitteMorris
Copy link
Member

Changed dependencies from #29979 to none

@tscrim
Copy link
Collaborator

tscrim commented Jul 3, 2021

Reviewer: Travis Scrimshaw

@tscrim
Copy link
Collaborator

tscrim commented Jul 3, 2021

comment:16

Thank you. LGTM.

@tscrim
Copy link
Collaborator

tscrim commented Jul 3, 2021

Changed work issues from #29979 -- rebase one ticket on the other (#29979 marks this as a bug) to none

@DaveWitteMorris
Copy link
Member

comment:17

Thanks!

@kliem
Copy link
Contributor Author

kliem commented Jul 3, 2021

comment:18

I moved the work issue now to #29979. (I hoped that this is what a reviewer would do when setting it on positive review, I caught on to this so things are fine.)

@tscrim
Copy link
Collaborator

tscrim commented Jul 4, 2021

comment:19

Replying to @kliem:

I moved the work issue now to #29979. (I hoped that this is what a reviewer would do when setting it on positive review, I caught on to this so things are fine.)

Sorry, I should have done that.

@vbraun
Copy link
Member

vbraun commented Jul 23, 2021

Changed branch from public/32084r2 to 226fe84

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants