Attachment 'coerce-free-module.patch'

Download

   1 # HG changeset patch
   2 # User Robert Bradshaw <[email protected]>
   3 # Date 1203667060 28800
   4 # Node ID 0c9522cc2ff7390fcb60e4146bafcff4d17a904b
   5 # Parent  0020f994146cac2d9c4d075822ed768639a0da29
   6 Free module coercion
   7 
   8 diff -r 0020f994146c -r 0c9522cc2ff7 sage/modules/free_module.py
   9 --- a/sage/modules/free_module.py	Thu Feb 14 14:13:45 2008 -0800
  10 +++ b/sage/modules/free_module.py	Thu Feb 21 23:57:40 2008 -0800
  11 @@ -144,6 +144,9 @@ from sage.structure.sequence import Sequ
  12  from sage.structure.sequence import Sequence
  13  
  14  from sage.structure.parent_gens import ParentWithGens
  15 +
  16 +from sage.categories.morphism import Morphism
  17 +import sage.categories.homset as homset
  18  
  19  ###############################################################################
  20  #
  21 @@ -378,14 +381,15 @@ class FreeModule_generic(module.Module):
  22          if degree < 0:
  23              raise ValueError, "degree (=%s) must be nonnegative"%degree
  24          
  25 -        ParentWithGens.__init__(self, base_ring)     # names aren't used anywhere.
  26 +        ParentWithGens.__init__(self, base_ring, element_class=self.__class__.element_constructor)     # names aren't used anywhere.
  27          self.__uses_ambient_inner_product = True
  28          self.__rank = rank
  29          self.__degree = degree
  30          self.__is_sparse = sparse
  31          self._inner_product_matrix = inner_product_matrix
  32          self._gram_matrix = None
  33 -        self.element_class()
  34 +        self._real_element_class = element_class(base_ring, sparse)
  35 +        self._populate_coercion_lists_(convert_method_name='vector')
  36          
  37      def construction(self):
  38          from sage.categories.pushout import VectorFunctor
  39 @@ -483,15 +487,30 @@ class FreeModule_generic(module.Module):
  40          return self(0)
  41  
  42      def element_class(self):
  43 -        try:
  44 -            return self._element_class
  45 -        except AttributeError:
  46 -            pass
  47 -        C = element_class(self.base_ring(), self.is_sparse())        
  48 -        self._element_class = C
  49 -        return C
  50 -    
  51 -    def __call__(self, x, coerce=True, copy=True, check=True):
  52 +        return self._real_element_class
  53 +        
  54 +    def element_constructor(self, x, coerce=True, copy=True, check=True):
  55 +        """
  56 +        This used to be in the __call__ method. We use this rather than setting element_class
  57 +        directly because we want to preserve pre-processing and post-processing without having
  58 +        to modify every element class. 
  59 +        
  60 +        EXAMPLE:
  61 +            sage: V = QQ^3
  62 +            sage: V([1,2,3])
  63 +            (1, 2, 3)
  64 +            sage: V([1,2,3.5])
  65 +            (1, 2, 7/2)
  66 +            sage: V(0)
  67 +            (0, 0, 0)
  68 +            sage: V((ZZ^3)([3,5,7]))
  69 +            (3, 5, 7)
  70 +        
  71 +            sage: k.<a> = GF(3^4)
  72 +            sage: VS = k.vector_space()
  73 +            sage: VS(a)
  74 +            (0, 1, 0, 0)
  75 +        """
  76          if isinstance(x, (int, long, sage.rings.integer.Integer)) and x==0:
  77              return self.zero_vector()
  78          elif isinstance(x, free_module_element.FreeModuleElement):
  79 @@ -501,7 +520,7 @@ class FreeModule_generic(module.Module):
  80                  else:
  81                      return x
  82              x = x.list()
  83 -        w = self._element_class(self, x, coerce, copy)
  84 +        w = self._real_element_class(self, x, coerce, copy)
  85          if check:
  86              if isinstance(self, FreeModule_ambient):
  87                  return w
  88 @@ -536,42 +555,22 @@ class FreeModule_generic(module.Module):
  89              if not (b in other):
  90                  return False
  91          return True
  92 -
  93 -
  94 -    def _has_coerce_map_from_space(self, V):
  95 +        
  96 +    def _has_coerce_map_from_(self, V):
  97          """
  98 -        Return True if V canonically coerces to self.
  99 +        EXAMPLES: 
 100 +            sage: FreeModule(QQ, 3).has_coerce_map_from(FreeModule(ZZ, 3))
 101 +            True
 102 +            sage: FreeModule(QQ, 3).has_coerce_map_from(FreeModule(ZZ['x'], 3))
 103 +            False
 104          """
 105 -        try:
 106 -            return self.__has_coerce_map_from_space[V]
 107 -        except AttributeError:
 108 -            self.__has_coerce_map_from_space = {}
 109 -        except KeyError:
 110 -            pass
 111 -        if self.base_ring() is V.base_ring():
 112 -            h = V.is_submodule(self)
 113 -        elif not self.base_ring().has_coerce_map_from(V.base_ring()):
 114 -            self.__has_coerce_map_from_space[V] = False
 115 -            return False
 116 -        else:
 117 -            h = V.base_extend(self.base_ring()).is_submodule(self)
 118 -        self.__has_coerce_map_from_space[V] = h
 119 -        return h
 120 -
 121 -    def _coerce_impl(self, x):
 122 -        """
 123 -        Canonical coercion of x into this free module.
 124 -            (0, 4/3, 8/3, 4, 16/3)        
 125 -        """
 126 -        if isinstance(x, (int, long, sage.rings.integer.Integer)) and x==0:
 127 -            return self.zero_vector()
 128 -        if isinstance(x, free_module_element.FreeModuleElement):
 129 -            # determining if the map exists is expensive the first time,
 130 -            # so we cache it.
 131 -            if self._has_coerce_map_from_space(x.parent()):
 132 -                return self(x)
 133 -        raise TypeError
 134 -
 135 +        if isinstance(V, FreeModule_generic) and V.degree() == self.degree(): 
 136 +            if self.base_ring() is V.base_ring():
 137 +                return V.is_submodule(self)
 138 +            elif self.base_ring().has_coerce_map_from(V.base_ring()):
 139 +                return V.base_extend(self.base_ring()).is_submodule(self)
 140 +        return False
 141 +            
 142      def __cmp__(self, right):
 143          raise NotImplementedError
 144  
 145 @@ -1290,7 +1289,7 @@ class FreeModule_generic(module.Module):
 146          # Do *not* cache this -- it must be computed fresh each time, since
 147          # it is is used by __call__ to make a new copy of the 0 element. 
 148          
 149 -        return self._element_class(self, 0)
 150 +        return self._real_element_class(self, 0)
 151  
 152  class FreeModule_generic_pid(FreeModule_generic):
 153      """
 154 @@ -2981,24 +2980,6 @@ class FreeModule_ambient_field(FreeModul
 155          """
 156          return self.base_ring()
 157  
 158 -    def __call__(self, e, coerce=True, copy=True, check=True):
 159 -        """
 160 -
 161 -        EXAMPLE:
 162 -            sage: k.<a> = GF(3^4)
 163 -            sage: VS = k.vector_space()
 164 -            sage: VS(a)
 165 -            (0, 1, 0, 0)
 166 -            
 167 -        """
 168 -        try:
 169 -            k = e.parent()
 170 -            if finite_field.is_FiniteField(k) and k.base_ring() == self.base_ring() and k.degree() == self.degree():
 171 -                return self(e.vector())
 172 -        except AttributeError:
 173 -            pass
 174 -        return FreeModule_generic_field.__call__(self,e)
 175 -
 176  
 177  
 178  ###############################################################################
 179 @@ -3993,3 +3974,4 @@ def element_class(R, is_sparse):
 180          else:
 181              return free_module_element.FreeModuleElement_generic_dense
 182      raise NotImplementedError
 183 +
 184 diff -r 0020f994146c -r 0c9522cc2ff7 sage/modules/module.pyx
 185 --- a/sage/modules/module.pyx	Thu Feb 14 14:13:45 2008 -0800
 186 +++ b/sage/modules/module.pyx	Thu Feb 21 23:57:40 2008 -0800
 187 @@ -23,12 +23,6 @@ cdef class Module(sage.structure.parent_
 188      """
 189      Generic module class.
 190      """
 191 -    def __call__(self, x):
 192 -        """
 193 -        Coerce x into the ring.
 194 -        """
 195 -        raise NotImplementedError
 196 -
 197      def category(self):
 198          """
 199          Return the category to which this module belongs.
 200 diff -r 0020f994146c -r 0c9522cc2ff7 sage/rings/finite_field.py
 201 --- a/sage/rings/finite_field.py	Thu Feb 14 14:13:45 2008 -0800
 202 +++ b/sage/rings/finite_field.py	Thu Feb 21 23:57:40 2008 -0800
 203 @@ -88,6 +88,7 @@ from sage.structure.parent_gens import n
 204  
 205  import sage.interfaces.gap
 206  import sage.databases.conway
 207 +
 208  
 209  cache = {}
 210  
 211 @@ -346,9 +347,9 @@ class FiniteField_prime_modn(FiniteField
 212          p = integer.Integer(p)
 213          if not arith.is_prime(p):
 214              raise ArithmeticError, "p must be prime"
 215 -        integer_mod_ring.IntegerModRing_generic.__init__(self, p)
 216          self._kwargs = {}
 217          self.__char = p
 218 +        integer_mod_ring.IntegerModRing_generic.__init__(self, p)
 219          self.__gen = self(1)  # self(int(pari.pari(p).znprimroot().lift()))
 220          ParentWithGens.__init__(self, self, ('x',), normalize=False)
 221  
 222 diff -r 0020f994146c -r 0c9522cc2ff7 sage/structure/coerce_maps.pyx
 223 --- a/sage/structure/coerce_maps.pyx	Thu Feb 14 14:13:45 2008 -0800
 224 +++ b/sage/structure/coerce_maps.pyx	Thu Feb 21 23:57:40 2008 -0800
 225 @@ -25,7 +25,7 @@ cdef class DefaultConvertMorphism(Conver
 226          self.args = args
 227          self.kwds = kwds
 228  
 229 -    cpdef Element _call_(self, x):            
 230 +    cpdef Element _call_(self, x):
 231          if self.args is None:
 232              if self.kwds is None:
 233                  return self._codomain._element_class(self._codomain, x)
 234 @@ -91,7 +91,14 @@ cdef class NamedConvertMorphism(ConvertM
 235      
 236      cpdef Element _call_(self, x):
 237          method = getattr(x, self.method_name)
 238 -        return method(self._codomain)
 239 +        cdef Morphism m
 240 +        cdef Element e = method(self._codomain)
 241 +        if e._parent is not self._codomain:
 242 +            m = self._codomain.convert_map_from(e._parent)
 243 +            if m is None or m is self:
 244 +                raise TypeError 
 245 +            e = m._call_(e)
 246 +        return e
 247  
 248      def _repr_type(self):
 249          return "Conversion via %s" % self.method_name

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2008-02-22 08:02:17, 9.1 KB) [[attachment:coerce-free-module.patch]]
  • [get | view] (2008-06-14 07:28:06, 1.1 KB) [[attachment:fix-random.patch]]
  • [get | view] (2008-04-16 03:14:59, 1.8 KB) [[attachment:list_parents.sage]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.