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.You are not allowed to attach a file to this page.