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

Fix factory keys for finite fields to avoid repeated construction #16934

Closed
jdemeyer opened this issue Sep 4, 2014 · 40 comments
Closed

Fix factory keys for finite fields to avoid repeated construction #16934

jdemeyer opened this issue Sep 4, 2014 · 40 comments

Comments

@jdemeyer
Copy link

jdemeyer commented Sep 4, 2014

The following sequence of commands somehow breaks the coercion framework. This is on vanilla Sage 6.4.beta1. The problem only occurs if impl="pari_ffelt" is explicitly given, even though that is the default:

sage: k1.<a> = GF(17^14, impl="pari_ffelt")
sage: _ = PolynomialRing(k1, 'x')(a/2)
sage: k2.<a> = GF(17^14, impl="pari_ffelt")
sage: _ = PolynomialRing(k2, 'x')(a/2)
Traceback (most recent call last):
...
TypeError: no coercion defined

The underlying reason is:

sage: k1 is k2
False

This double construction of the same finite field is caused by slightly different UniqueFactory keys arising during the construction of a common parent (for the computation of a/2) by the coercion system.

Related: #16855

Depends on #16930

Component: finite rings

Author: Peter Bruin

Branch/Commit: 9cbdcde

Reviewer: Jeroen Demeyer

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

@jdemeyer jdemeyer added this to the sage-6.4 milestone Sep 4, 2014
@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@pjbruin
Copy link
Contributor

pjbruin commented Sep 4, 2014

comment:9

I don't claim to know what is going on, but it may be caused by equality and identity not being the same for finite fields; #16855 seems to fix this bug.

@pjbruin
Copy link
Contributor

pjbruin commented Sep 4, 2014

comment:10

This guess is corroborated by the fact that the following change also appears to fix the bug:

--- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx
+++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx
@@ -202,7 +202,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):
         cdef Integer xi

         if isinstance(x, FiniteFieldElement_pari_ffelt):
-            if self._parent is (<FiniteFieldElement_pari_ffelt>x)._parent:
+            if self._parent == (<FiniteFieldElement_pari_ffelt>x)._parent:
                 pari_catch_sig_on()
                 self.construct((<FiniteFieldElement_pari_ffelt>x).val)
             else:

After #16855, this change effectively does nothing.

@jdemeyer
Copy link
Author

jdemeyer commented Sep 4, 2014

comment:11

Replying to @pjbruin:

--- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx
+++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx
@@ -202,7 +202,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement):
         cdef Integer xi

         if isinstance(x, FiniteFieldElement_pari_ffelt):
-            if self._parent is (<FiniteFieldElement_pari_ffelt>x)._parent:
+            if self._parent == (<FiniteFieldElement_pari_ffelt>x)._parent:
                 pari_catch_sig_on()
                 self.construct((<FiniteFieldElement_pari_ffelt>x).val)
             else:

Would you propose to make the above change, or simply to close as ticket as dupe of #16855?

@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@pjbruin
Copy link
Contributor

pjbruin commented Sep 5, 2014

comment:14

Replying to @jdemeyer:

Would you propose to make the above change, or simply to close as ticket as dupe of #16855?

I would say either we close this as a duplicate of #16855, or we try to fix the other bug (#16855 comment:11) here:

sage: k1.<a> = GF(17^14, impl="pari_ffelt")
sage: _ = a/2
sage: k2.<a> = GF(17^14, impl="pari_ffelt")
sage: k1 is k2
False

@jdemeyer
Copy link
Author

jdemeyer commented Sep 5, 2014

comment:15

OK, let's wait and see what happens with #16855 then...

@pjbruin
Copy link
Contributor

pjbruin commented Sep 5, 2014

comment:16

The construction of the non-identical k1 and k2 appears to be due to a subtlety involving the FiniteFieldFactory.other_keys() method and an intermediate construction of another finite field (defined by the same data but with impl=None) during the construction of a common parent for the computation of a/2. The keys returned by other_keys() only differ in the impl keyword. I think the best solution is to always set the impl keyword when constructing the key (as opposed to allowing it to be None). Then the use of this other_keys() method, which feels to me somewhat like a hack, can be avoided.

@pjbruin
Copy link
Contributor

pjbruin commented Sep 5, 2014

comment:17

This branch depends on #16930 to avoid merge conflicts. It merges with, and works independently of, #16855.

@pjbruin
Copy link
Contributor

pjbruin commented Sep 5, 2014

@pjbruin
Copy link
Contributor

pjbruin commented Sep 5, 2014

Dependencies: #16930

@pjbruin
Copy link
Contributor

pjbruin commented Sep 5, 2014

Commit: c33a718

@pjbruin

This comment has been minimized.

@pjbruin
Copy link
Contributor

pjbruin commented Sep 5, 2014

Author: Peter Bruin

@pjbruin pjbruin changed the title Finite fields coercion bug Fix factory keys for finite fields to avoid repeated construction Sep 5, 2014
@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 5, 2014

Changed commit from c33a718 to ffb74fa

@pjbruin
Copy link
Contributor

pjbruin commented Sep 5, 2014

comment:19

Diff for easier reviewing: sagemath/sagetrac-mirror@8cdbd79...ffb74fa

@jdemeyer
Copy link
Author

@jdemeyer
Copy link
Author

comment:21

Please restore the warning

warn("the 'modulus' argument is ignored when constructing prime finite fields")

for all prime finite field implementations because the modulus really is ignored:

sage: x = polygen(GF(7)); GF(7, modulus=x-2, impl="givaro").modulus()
x + 6

Of course we could change that behaviour (perhaps we should), but let's do that on a new ticket.


New commits:

33c86efMerge remote-tracking branch 'origin/develop' into ticket/16934

@jdemeyer
Copy link
Author

Changed commit from ffb74fa to 33c86ef

@pjbruin
Copy link
Contributor

pjbruin commented Sep 12, 2014

Changed commit from 33c86ef to bf36ec1

@pjbruin
Copy link
Contributor

pjbruin commented Sep 12, 2014

@pjbruin
Copy link
Contributor

pjbruin commented Sep 12, 2014

comment:22

This commit adds back the warning. Alternatively, it could have been put outside the if impl == 'modn', but in this way it is easier to remove again for non-modn implementations.

@jdemeyer
Copy link
Author

comment:23
sage: GF(7, impl="givaro", modulus="primitive")
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-2-c6a1d2461111> in <module>()
----> 1 GF(Integer(7), impl="givaro", modulus="primitive")

/usr/local/src/sage-git/local/lib/python2.7/site-packages/sage/structure/factory.so in sage.structure.factory.UniqueFactory.__call__ (build/cythonized/sage/structure/factory.c:1160)()
                                                                                                                                                                        
/usr/local/src/sage-git/local/lib/python2.7/site-packages/sage/rings/finite_rings/constructor.pyc in create_key_and_extra_args(self, order, name, modulus, names, impl, proof, check_irreducible, **kwds)                                                                                                                                       
    521                 if not modulus.is_irreducible():                                                                                                                
    522                     raise ValueError("finite field modulus must be irreducible but it is not.")
--> 523             if modulus is not None and modulus.degree() != n:
    524                 raise ValueError("the degree of the modulus does not equal the degree of the field.")
    525 

AttributeError: 'str' object has no attribute 'degree'

@jdemeyer
Copy link
Author

comment:24

Replying to @pjbruin:

This commit adds back the warning. Alternatively, it could have been put outside the if impl == 'modn', but in this way it is easier to remove again for non-modn implementations.

I would prefer to have the warning in one place. If we ever allow a custom modulus, we should allow it for all implementations.

My vision for this "modulus" argument is that the following should assign to a a primitive root:

sage: K.<a> = GF(7, modulus='primitive')

so perhaps we should expand the warning to say

warn("currently, the 'modulus' argument is ignored when constructing prime finite fields. This might change in the future and this will probably also change the output of the .gen() and .modulus() methods on the finite field.\nSee http://trac.sagemath.org/16930 for details.")

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 12, 2014

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

9cbdcdeTrac 16934: fix warning about ignored 'modulus' argument

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 12, 2014

Changed commit from bf36ec1 to 9cbdcde

@jdemeyer
Copy link
Author

Reviewer: Jeroen Demeyer

@nbruin
Copy link
Contributor

nbruin commented Sep 15, 2014

comment:28

Replying to @jdemeyer:

Replying to @pjbruin:

This commit adds back the warning. Alternatively, it could have been put outside the if impl == 'modn', but in this way it is easier to remove again for non-modn implementations.

I would prefer to have the warning in one place. If we ever allow a custom modulus, we should allow it for all implementations.

My vision for this "modulus" argument is that the following should assign to a a primitive root:

sage: K.<a> = GF(7, modulus='primitive')

The word "modulus" here is definitely wrong. If anything is a modulus for GF(7), it is 7, because the natural way to construct GF(7) as quotient of ZZ by 7ZZ.

In general, even for field extensions, the word modulus is confusing. That only applies if you're making the field as a quotient of a polynomial ring. For the purpose proposed, generator would cover the notion much better. I see from the doc that we have legacy against us on this one.

@jdemeyer
Copy link
Author

comment:29

Replying to @nbruin:

Replying to @jdemeyer:

My vision for this "modulus" argument is that the following should assign to a a primitive root:

sage: K.<a> = GF(7, modulus='primitive')

The word "modulus" here is definitely wrong. If anything is a modulus for GF(7), it is 7, because the natural way to construct GF(7) as quotient of ZZ by 7ZZ.

Depends on how you look at it. For me, there is a big philosophical difference between IntegerModRing(p) and GF(p). I see IntegerModRing(m) as ZZ/(m), while GF(p^n) is IntegerModRing(p)[x]/(f(x)) for an irreducible polynomial f(x) of degree n.

For fields GF(p^n) (n > 1), the word "modulus" for f(x) is certainly more standard than "generator". For me, the "generator" is the image of x in GF(p^n) = IntegerModRing(p)[x]/(f(x)), which is returned by the gen() method.

@jdemeyer
Copy link
Author

comment:30

Replying to @jdemeyer:

My vision for this "modulus" argument is that the following should assign to a a primitive root:

sage: K.<a> = GF(7, modulus='primitive')

By the way, this is now implemented at #16983.

@vbraun
Copy link
Member

vbraun commented Sep 16, 2014

Changed branch from u/pbruin/16934-FiniteField_factory_key to 9cbdcde

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