On 4/3/07, Martin Albrecht <[EMAIL PROTECTED]> wrote:
> On Monday 02 April 2007 22:53, Kate Minola wrote:
> > Would a kind person explain to me why element 1 and element 2
> > are not equal?  And what I need to do to test if element 1 is zero
> > in K?

It's a bug.

> > # setup
> > f = conway_polynomial(2,63)
> > K.<a> = GF(2**63, name='a', modulus=f)
> > n = f.degree()
> > m = 3;
> > e = (2^n - 1) / (2^m - 1)
> > c = a^e
> > conway = conway_polynomial(2,m)
> >
> > # element 1
> > print conway(c)   # says 0
> > print type(c)
> > print parent(c)
> > print c in K          # says True
> >
> > # element 2
> > print K(0)      # says 0
> > print type(K(0))
> > print parent(K(0))
> >
> > print conway(c) == K(0)    # says False???
>
> This seems to be a bug in the pari.gen.gen class:
>
> sage: e1 = conway(c)
> sage: e2 = K(0)
>
> When compare is called on them, their pari values are compared, these differ
> in their representation.
>
> sage: e1._FiniteField_ext_pariElement__value
> 0
>
> sage: e2._FiniteField_ext_pariElement__value
>
> Mod(Mod(0, 2), Mod(1, 2)*a^63 + Mod(1, 2)*a^24 + Mod(1, 2)*a^23 + Mod(1,
> 2)*a^22 + Mod(1, 2)*a^17 + Mod(1, 2)*a^16 + Mod(1, 2)*a^15 + Mod(1, 2)*a^11 +
> Mod(1, 2)*a^9 + Mod(1, 2)*a^8 + Mod(1, 2)*a^4 + Mod(1, 2)*a^3 + Mod(1, 2)*a^2
> + Mod(1, 2)*a + Mod(1, 2))
>
> Their comparison fails as follows:
>
> e2._FiniteField_ext_pariElement__value._cmp(e1._FiniteField_ext_pariElement__value
>   )
> ---------------------------------------------------------------------------
> <class 'gen.PariError'>                   Traceback (most recent call last)
>
> /home/malb/<ipython console> in <module>()
>
> /home/malb/gen.pyx in gen._pari_trap()
>
> <class 'gen.PariError'>: incorrect type (20)
>
> I openend a ticket on Trac for this.

I've attached a fix.   Could you close your trac ticket, since this fix will
be in sage-2.8.1.

William

--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sage-support
URLs: http://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/
-~----------~----~----~----~------~----~------~--~---

# HG changeset patch
# User William Stein <[EMAIL PROTECTED]>
# Date 1187051524 25200
# Node ID c39ca352e774bc61d46e93c63ef159b87cb74b65
# Parent  22fee559b081bc246faa8de71cb08fa0f7d37cdd
Fix a bug in large finite field arithmetic (construction of 0 element wrong in some cases).  Also (very slightly!) optimized some arithmetic in finite fields.

diff -r 22fee559b081 -r c39ca352e774 sage/rings/finite_field_element.py
--- a/sage/rings/finite_field_element.py	Sun Aug 12 18:14:42 2007 -0700
+++ b/sage/rings/finite_field_element.py	Mon Aug 13 17:32:04 2007 -0700
@@ -7,6 +7,18 @@ EXAMPLES:
     sage: w = V([0,1,2])
     sage: K(1)*w
     (0, 1, 0)
+
+We do some arithmetic involving a bigger field and a Conway polynomial,
+i.e., we verify compatibility condition.
+    sage: f = conway_polynomial(2,63)
+    sage: K.<a> = GF(2**63, name='a', modulus=f)
+    sage: n = f.degree()
+    sage: m = 3;
+    sage: e = (2^n - 1) / (2^m - 1)
+    sage: c = a^e
+    sage: conway = conway_polynomial(2,m)
+    sage: conway(c) == 0
+    True
 """
 
 
@@ -59,7 +71,7 @@ class FiniteField_ext_pariElement(Finite
         sage: loads(a.dumps()) == a
         True
     """
-    def __init__(self, parent, value):
+    def __init__(self, parent, value, check=True):
         """
         Create element of a finite field.
 
@@ -75,15 +87,33 @@ class FiniteField_ext_pariElement(Finite
         self.__parent = parent
         if isinstance(value, str):
             raise TypeError, "value must not be a string"
+        if not check:
+            if not value:  # see comment below about this workaround
+                self.__value = pari(0).Mod(parent._pari_modulus())*parent._pari_one()
+            else:
+                self.__value = value
+            return
         try:
             if isinstance(value, pari_gen):
-                if value.type()[-3:] == "MOD" :
-                    self.__value = value
-                else:
-                    try:
+                try:
+                    # In some cases we get two different versions of
+                    # the 0 element of a finite field.  This has to do
+                    # with how PARI's Mod function works -- it treats
+                    # 0 differently.  In particular, if value is a a
+                    # pari t_POLMOD that is 0, modding it simply
+                    # doesn't work correctly.  We fix this by changing
+                    # the value in the 0 case to the standard pari 0,
+                    # which works correctly.  Note -- probably all
+                    # this code should be replaced by much faster
+                    # finite field arithmetic programmed against NTL.
+                    if not value:
+                        value = pari(0)
+                    if value.type() == "t_POLMOD":
+                        self.__value = value * parent._pari_one()
+                    else:
                         self.__value = value.Mod(parent._pari_modulus())*parent._pari_one()
-                    except RuntimeError:
-                        raise TypeError, "no possible coercion implemented"
+                except RuntimeError:
+                    raise TypeError, "no possible coercion implemented"
                 return
             elif isinstance(value, FiniteField_ext_pariElement):
                 if parent != value.parent():
@@ -271,7 +301,7 @@ class FiniteField_ext_pariElement(Finite
             sage: a is a
             True
         """
-        return FiniteField_ext_pariElement(self.__parent, self.__value)
+        return FiniteField_ext_pariElement(self.__parent, self.__value, check=False)
 
     def _pari_(self, var=None):
         """
@@ -489,18 +519,18 @@ class FiniteField_ext_pariElement(Finite
             raise TypeError, "Parents of finite field elements must be equal."
         
     def _add_(self, right):
-        return FiniteField_ext_pariElement(self.__parent, self.__value + right.__value)
+        return FiniteField_ext_pariElement(self.__parent, self.__value + right.__value, check=False)
     
     def _sub_(self, right):
-        return FiniteField_ext_pariElement(self.__parent, self.__value - right.__value)
+        return FiniteField_ext_pariElement(self.__parent, self.__value - right.__value, check=False)
     
     def _mul_(self, right):
-        return FiniteField_ext_pariElement(self.__parent, self.__value * right.__value)
+        return FiniteField_ext_pariElement(self.__parent, self.__value * right.__value, check=False)
 
     def _div_(self, right):
         if right.__value == 0:
             raise ZeroDivisionError
-        return FiniteField_ext_pariElement(self.__parent, self.__value / right.__value)
+        return FiniteField_ext_pariElement(self.__parent, self.__value / right.__value, check=False)
 
     def __int__(self):
         try:
@@ -531,10 +561,10 @@ class FiniteField_ext_pariElement(Finite
     #    right = int(_right)
     #    if right != _right:
     #         raise ValueError
-    #    return FiniteField_ext_pariElement(self.__parent, self.__value**right)
+    #    return FiniteField_ext_pariElement(self.__parent, self.__value**right, check=False)
 
     def __neg__(self):
-        return FiniteField_ext_pariElement(self.__parent, -self.__value)
+        return FiniteField_ext_pariElement(self.__parent, -self.__value, check=False)
     
     def __pos__(self):
         return self
@@ -555,7 +585,7 @@ class FiniteField_ext_pariElement(Finite
 
         if self.__value == 0:
             raise ZeroDivisionError, "Cannot invert 0"
-        return FiniteField_ext_pariElement(self.__parent, ~self.__value)
+        return FiniteField_ext_pariElement(self.__parent, ~self.__value, check=False)
     
     def lift(self):
         """

Reply via email to