source: sage/structure/element.pyx @ 1999:4111e2c8c6ad

Revision 1999:4111e2c8c6ad, 59.5 KB checked in by William Stein <wstein@…>, 7 years ago (diff)

Rewrite Dirichlet characters to be vastly faster. Also fixed some related issues along the way.

Line 
1r"""
2Elements
3
4AUTHORS:
5   -- David Harvey (2006-10-16): changed CommutativeAlgebraElement to derive
6   from CommutativeRingElement instead of AlgebraElement
7   -- David Harvey (2006-10-29): implementation and documentation of new
8   arithmetic architecture
9   -- William Stein (2006-11): arithmetic architecture -- pushing it through to completion.
10
11
12\subsection{The Abstract Element Class Heierarchy}
13This is the abstract class heierchary, i.e., these are all
14abstract base classes.
15\begin{verbatim}
16SageObject
17    Element
18        ModuleElement
19            AdditiveGroupElement
20
21        MonoidElement
22            MultiplicativeGroupElement
23
24        RingElement
25            CommutativeRingElement
26                IntegralDomainElement
27                    DedekindDomainElement
28                        PrincipalIdealDomainElement
29                            EuclideanDomainElement
30            FieldElement
31                FiniteFieldElement
32            AlgebraElement   (note -- can't derive from module, since no multiple inheritence)
33                CommutativeAlgebraElement
34            InfinityElement
35\end{verbatim}
36
37\subsection{How to Define a New Element Class}
38Elements typically define a method \code{_new_c}, e.g.,
39\begin{verbatim}
40    cdef _new_c(self, defining data):
41        cdef FreeModuleElement_generic_dense x
42        x = PY_NEW(FreeModuleElement_generic_dense)
43        x._parent = self._parent
44        x._entries = v
45\end{verbatim}
46that creates a new sibling very quickly from defining data
47with assumed properties. 
48
49SAGE has a special system in place for handling arithmetic operations
50for all Element subclasses. There are various rules that must be
51followed by both arithmetic implementors and callers.
52
53A quick summary for the impatient:
54\begin{itemize}
55 \item DO NOT OVERRIDE _add_c. EVER. THANKS.
56 \item DO NOT CALL _add_c_impl DIRECTLY.
57 \item To implement addition for a python class, override def _add_().
58 \item To implement addition for a pyrex class, override cdef _add_c_impl().
59 \item If you want to add x and y, whose parents you know are IDENTICAL,
60   you may call _add_(x, y) (from python or pyrex) or _add_c(x, y) (from
61   pyrex -- this will be faster). This will be the fastest way to guarantee
62   that the correct implementation gets called. Of course you can still
63   always use "x + y".
64\end{itemize}
65
66Now in more detail. The aims of this system are to provide (1) an efficient
67calling protocol from both python and pyrex, (2) uniform coercion semantics
68across SAGE, (3) ease of use, (4) readability of code.
69
70We will take addition of RingElements as an example; all other operators
71and classes are similar. There are four relevant functions.
72
73{\bf def RingElement.__add__}
74
75   This function is called by python or pyrex when the binary "+" operator
76   is encountered. It ASSUMES that at least one of its arguments is a
77   RingElement; only a really twisted programmer would violate this
78   condition. It has a fast pathway to deal with the most common case
79   where the arguments have the same parent. Otherwise, it uses the coercion
80   module to work out how to make them have the same parent. After any
81   necessary coercions have been performed, it calls _add_c to dispatch to
82   the correct underlying addition implementation.
83
84   Note that although this function is declared as def, it doesn't have the
85   usual overheads associated with python functions (either for the caller
86   or for __add__ itself). This is because python has optimised calling
87   protocols for such special functions.
88
89{\bf cdef RingElement._add_c}
90
91   DO ***NOT*** OVERRIDE THIS FUNCTION.
92
93   The two arguments to this function MUST have the SAME PARENT.
94   Its return value MUST have the SAME PARENT as its arguments.
95
96   If you want to add two objects from pyrex, and you know that their
97   parents are the same object, you are encouraged to call this function
98   directly, instead of using "x + y".
99
100   This function dispatches to either _add_ or _add_c_impl as appropriate.
101   It takes necessary steps to decide whether a pyrex implementation of
102   _add_c_impl has been overridden by some python implementation of _add_.
103   The code is optimised in favour of reaching _add_c_impl as soon as
104   possible.
105
106{\bf def RingElement._add_}
107
108   This is the function you should override to implement addition in a
109   python subclass of RingElement.
110
111   WARNING: if you override this in a *pyrex* class, it won't get called.
112   You should override _add_c_impl instead. It is especially important to
113   keep this in mind whenever you move a class down from python to pyrex.
114
115   The two arguments to this function are guaranteed to have the
116   SAME PARENT. Its return value MUST have the SAME PARENT as its
117   arguments.
118
119   If you want to add two objects from python, and you know that their
120   parents are the same object, you are encouraged to call this function
121   directly, instead of using "x + y".
122
123   The default implementation of this function is to call _add_c_impl,
124   so if no-one has defined a python implementation, the correct pyrex
125   implementation will get called.
126
127{\bf cdef RingElement._add_c_impl}
128
129   This is the function you should override to implement addition in a
130   pyrex subclass of RingElement.
131
132   The two arguments to this function are guaranteed to have the
133   SAME PARENT. Its return value MUST have the SAME PARENT as its
134   arguments.
135
136   DO ***NOT*** CALL THIS FUNCTION DIRECTLY.
137
138   (Exception: you know EXACTLY what you are doing, and you know exactly
139   which implementation you are trying to call; i.e. you're not trying to
140   write generic code. In particular, if you call this directly, your code
141   will not work correctly if you run it on a python class derived from
142   a pyrex class where someone has redefined _add_ in python.)
143
144   The default implementation of this function is to raise a
145   NotImplementedError, which will happen if no-one has supplied
146   implementations of either _add_ or _add_c_impl.
147
148"""
149
150
151##################################################################
152# Generic element, so all this functionality must be defined
153# by any element.  Derived class must call __init__
154##################################################################
155
156include "../ext/cdefs.pxi"
157include "../ext/stdsage.pxi"
158include "../ext/python.pxi"
159
160import operator
161
162from sage.structure.parent      cimport Parent
163from sage.structure.parent_base cimport ParentWithBase
164
165# This classes uses element.pxd.  To add data members, you
166# must change that file.
167
168def make_element(_class, _dict, parent):
169    """
170    Used for unpickling Element objects (and subclasses).
171
172    This should work for any Python class deriving from Element, as long
173    as it doesn't implement some screwy __new__() method.
174
175    See also Element.__reduce__().
176    """
177    new_object = _class.__new__(_class)
178    new_object._set_parent(parent)
179    new_object.__dict__ = _dict
180    return new_object
181
182
183   
184def is_Element(x):
185    """
186    Return True if x is of type Element.
187   
188    EXAMPLES:
189        sage: is_Element(2/3)
190        True
191        sage: is_Element(QQ^3)
192        False
193    """
194    return IS_INSTANCE(x, Element)
195
196cdef class Element(sage_object.SageObject):
197    """
198    Generic element of a structure. All other types of elements
199    (RingElement, ModuleElement, etc) derive from this type.
200
201    Subtypes must either call __init__() to set _parent, or may
202    set _parent themselves if that would be more efficient.
203    """
204   
205    def __init__(self, parent):
206        r"""
207        INPUT:
208            parent -- a SageObject
209        """
210        #if parent is None:
211        #    raise RuntimeError, "bug -- can't set parent to None"
212        self._parent = parent
213   
214    def _set_parent(self, parent):
215        r"""
216        INPUT:
217            parent -- a SageObject
218        """
219        self._parent = parent
220
221    cdef _set_parent_c(self, ParentWithBase parent):
222        self._parent = parent
223   
224    def _repr_(self):
225        return "Generic element of a structure"
226
227    def __reduce__(self):
228        return (make_element, (self.__class__, self.__dict__, self._parent))
229
230    def __hash__(self):
231        return hash(str(self))
232
233    def _im_gens_(self, codomain, im_gens):
234        """
235        Return the image of self in codomain under the map that sends
236        the images of the generators of the parent of self to the
237        tuple of elements of im_gens.
238        """
239        raise NotImplementedError
240           
241    cdef base_extend_c(self, ParentWithBase R):
242        if HAS_DICTIONARY(self):
243            return self.base_extend(R)
244        else:
245            return self.base_extend_c_impl(R)
246       
247    cdef base_extend_c_impl(self, ParentWithBase R):
248        cdef ParentWithBase V
249        V = self._parent.base_extend(R)
250        return (<Parent>V)._coerce_c(self)
251
252    def base_extend(self, R):
253        return self.base_extend_c_impl(R)
254
255    def base_ring(self):
256        """
257        Returns the base ring of this element's parent (if that makes sense).
258        """
259        return self._parent.base_ring()
260
261    def category(self):
262        from sage.categories.category import Elements
263        return Elements(self._parent)
264
265    def parent(self, x=None):
266        """
267        Returns parent of this element; or, if the optional argument x is
268        supplied, the result of coercing x into the parent of this element.
269        """
270        if x is None:
271            return self._parent
272        else:
273            return self._parent(x)
274
275    def __xor__(self, right):
276        raise RuntimeError, "Use ** for exponentiation, not '^', which means xor\n"+\
277              "in Python, and has the wrong precedence."
278
279    def _coeff_repr(self, no_space=True):
280        if self._is_atomic():
281            s = str(self)
282        else:
283            s = "(%s)"%self
284        if no_space:
285            return s.replace(' ','')
286        return s
287
288    def _latex_coeff_repr(self):
289        try:
290            s = self._latex_()
291        except AttributeError:
292            s = str(self)
293        if self._is_atomic():
294            return s
295        else:
296            return "\\left(%s\\right)"%s
297   
298    def _is_atomic(self):
299        if self._parent.is_atomic_repr():
300            return True
301        s = str(self)
302        return PyBool_FromLong(s.find("+") == -1 and s.find("-") == -1 and s.find(" ") == -1)
303
304    def is_zero(self):
305        return PyBool_FromLong(self == self._parent(0))
306
307    def _richcmp_(left, right, op):
308        return left._richcmp(right, op)
309
310    cdef _richcmp(left, right, int op):
311        """
312        Compare left and right.
313        """
314        cdef int r
315        if not have_same_parent(left, right):
316            try:
317                _left, _right = canonical_coercion_c(left, right)
318                r = cmp(_left, _right)
319            except TypeError:
320                r = cmp(type(left), type(right))
321                if r == 0:
322                    r = -1
323        else:
324            if HAS_DICTIONARY(left):   # fast check
325                r = left.__cmp__(right)
326            else:
327                r = left._cmp_c_impl(right)
328
329        return left._rich_to_bool(op, r)
330
331    cdef _rich_to_bool(self, int op, int r):
332        if op == 0:  #<
333            return PyBool_FromLong(r  < 0)
334        elif op == 2: #==
335            return PyBool_FromLong(r == 0)
336        elif op == 4: #>
337            return PyBool_FromLong(r  > 0)
338        elif op == 1: #<=
339            return PyBool_FromLong(r <= 0)
340        elif op == 3: #!=
341            return PyBool_FromLong(r != 0)
342        elif op == 5: #>=
343            return PyBool_FromLong(r >= 0)
344
345    ####################################################################
346    # For a derived Pyrex class, you **must** put the following in
347    # your subclasses, in order for it to take advantage of the
348    # above generic comparison code.  You must also define
349    # _cmp_c_impl.
350    # This is simply how Python works.
351    #
352    # For a *Python* class just define __cmp__ as always.
353    # But note that when this get called you can assume that
354    # both inputs have identical parents.
355    ####################################################################
356    def __richcmp__(left, right, int op):
357        return (<Element>left)._richcmp(right, op)
358   
359    cdef int _cmp_c_impl(left, Element right) except -2:
360        ### For derived SAGEX code, you *MUST* ALSO COPY the __richcmp__ above
361        ### into your class!!!  For Python code just use __cmp__.
362        raise NotImplementedError, "BUG: sort algorithm for elements of type %s not implemented"%(type(left))
363
364    def __cmp__(left, right):
365        return left._cmp_c_impl(right)   # default
366
367def is_ModuleElement(x):
368    """
369    Return True if x is of type ModuleElement.
370   
371    This is even faster than using isinstance inline.
372
373    EXAMPLES:
374        sage: is_ModuleElement(2/3)
375        True
376        sage: is_ModuleElement((QQ^3).0)
377        True
378        sage: is_ModuleElement('a')
379        False
380    """
381    return IS_INSTANCE(x, ModuleElement)
382
383
384cdef class ModuleElement(Element):
385    """
386    Generic element of a module.
387    """
388    ##################################################   
389    def is_zero(self):
390        return PyBool_FromLong(self == self._parent(0))
391
392    ##################################################
393    # Addition
394    ##################################################   
395    def __add__(left, right):
396        """
397        Top-level addition operator for ModuleElements.
398
399        See extensive documentation at the top of element.pyx.
400        """
401
402        # Try fast pathway if they are both ModuleElements and the parents
403        # match.
404
405        # (We know at least one of the arguments is a ModuleElement. So if
406        # their types are *equal* (fast to check) then they are both
407        # ModuleElements. Otherwise use the slower test via PY_TYPE_CHECK.)
408        if have_same_parent(left, right):
409            return (<ModuleElement>left)._add_c(<ModuleElement>right)
410        return bin_op_c(left, right, operator.add)
411
412    cdef ModuleElement _add_c(left, ModuleElement right):
413        """
414        Addition dispatcher for ModuleElements.
415
416        DO NOT OVERRIDE THIS FUNCTION.
417
418        See extensive documentation at the top of element.pyx.
419        """
420        if HAS_DICTIONARY(left):   # fast check
421            # TODO: this bit will be unnecessarily slow if someone derives
422            # from the pyrex class *without* overriding _add_, since then
423            # we'll be making an unnecessary python call to _add_, which will
424            # end up in _add_c_impl anyway. There must be a simple way to
425            # distinguish this situation. It's complicated because someone
426            # can even override it at the instance level (without overriding
427            # it in the class.)
428            return left._add_(right)
429        else:
430            # Must be a pure Pyrex class.
431            return left._add_c_impl(right)
432
433
434    cdef ModuleElement _add_c_impl(left, ModuleElement right):
435        """
436        Pyrex classes should override this function to implement addition.
437        DO NOT CALL THIS FUNCTION DIRECTLY.
438        See extensive documentation at the top of element.pyx.
439        """
440        raise TypeError, arith_error_message(left, right, operator.add)
441       
442
443    def _add_(ModuleElement left, ModuleElement right):
444        """
445        Python classes should override this function to implement addition.
446
447        See extensive documentation at the top of element.pyx.
448        """
449        return left._add_c_impl(right)
450
451    ##################################################
452    # Subtraction
453    ##################################################   
454
455    def __sub__(left, right):
456        """
457        Top-level subtraction operator for ModuleElements.
458        See extensive documentation at the top of element.pyx.
459        """
460        if have_same_parent(left, right):
461            return (<ModuleElement>left)._sub_c(<ModuleElement>right)
462        return bin_op_c(left, right, operator.sub)
463
464    cdef ModuleElement _sub_c(left, ModuleElement right):
465        """
466        Subtraction dispatcher for ModuleElements.
467
468        DO NOT OVERRIDE THIS FUNCTION.
469
470        See extensive documentation at the top of element.pyx.
471        """
472       
473        if HAS_DICTIONARY(left):   # fast check
474            return left._sub_(right)
475        else:
476            # Must be a pure Pyrex class.
477            return left._sub_c_impl(right)
478
479
480    cdef ModuleElement _sub_c_impl(left, ModuleElement right):
481        """
482        Pyrex classes should override this function to implement subtraction.
483
484        DO NOT CALL THIS FUNCTION DIRECTLY.
485
486        See extensive documentation at the top of element.pyx.
487        """
488        # default implementation is to use the negation and addition
489        # dispatchers:
490        return left._add_c(right._neg_c())
491       
492
493    def _sub_(ModuleElement left, ModuleElement right):
494        """
495        Python classes should override this function to implement subtraction.
496
497        See extensive documentation at the top of element.pyx.
498        """
499        return left._sub_c_impl(right)
500       
501    ##################################################
502    # Negation
503    ##################################################   
504
505    def __neg__(self):
506        """
507        Top-level negation operator for ModuleElements.
508        See extensive documentation at the top of element.pyx.
509        """
510        # We ASSUME that self is a ModuleElement. No type checks.
511        return (<ModuleElement>self)._neg_c()
512
513
514    cdef ModuleElement _neg_c(self):
515        """
516        Negation dispatcher for ModuleElements.
517        DO NOT OVERRIDE THIS FUNCTION.
518        See extensive documentation at the top of element.pyx.
519        """
520       
521        if HAS_DICTIONARY(self):   # fast check
522            return self._neg_()
523        else:
524            # Must be a pure Pyrex class.
525            return self._neg_c_impl()
526
527
528    cdef ModuleElement _neg_c_impl(self):
529        """
530        Pyrex classes should override this function to implement negation.
531        DO NOT CALL THIS FUNCTION DIRECTLY.
532        See extensive documentation at the top of element.pyx.
533        """
534        # default implementation is to try multiplying by -1.
535        return bin_op_c(-1, self, operator.mul)
536       
537
538    def _neg_(ModuleElement self):
539        """
540        Python classes should override this function to implement negation.
541
542        See extensive documentation at the top of element.pyx.
543        """
544        return self._neg_c_impl()
545
546    ##################################################
547    # Module element multiplication (scalars, etc.)
548    ##################################################
549    def __mul__(left, right):
550        return module_element_generic_multiply_c(left, right)
551   
552    cdef ModuleElement _multiply_by_scalar(self, right):
553        # self * right,  where right need not be a ring element in the base ring
554        # This does type checking and canonical coercion then calls _lmul_c_impl.
555        if PY_TYPE_CHECK(right, Element) and (<Element>right)._parent is self._parent._base:
556            # No coercion needed
557            return self._lmul_c(right)
558        else:
559            # Otherwise we do an explicit canonical coercion.
560            try:
561                return self._lmul_c( self._parent._base._coerce_c(right) )
562            except TypeError:
563                # that failed -- try to base extend right then do the multiply:
564                self = self.base_extend((<RingElement>right)._parent)
565                return (<ModuleElement>self)._lmul_c(right)
566
567    cdef ModuleElement _rmultiply_by_scalar(self, left):
568        # left * self, where left need not be a ring element in the base ring
569        # This does type checking and canonical coercion then calls _rmul_c_impl.
570        if PY_TYPE_CHECK(left, Element) and (<Element>self)._parent is self._parent._base:
571            # No coercion needed
572            return self._rmul_c(right)
573        else:
574            # Otherwise we do an explicit canonical coercion.
575            try:
576                return self._rmul_c(self._parent._base._coerce_c(left))
577            except TypeError:
578                # that failed -- try to base extend self then do the multiply:
579                self = self.base_extend((<RingElement>left)._parent)
580                return (<ModuleElement>self)._rmul_c(left)
581
582    cdef ModuleElement _lmul_nonscalar_c(left, right):
583        # Compute the product left * right, where right is assumed to be a nonscalar (so no coercion)
584        # This is a last resort.
585        if HAS_DICTIONARY(left):
586            return left._lmul_nonscalar(right)
587        else:
588            return left._lmul_nonscalar_c_impl(right)
589       
590    cdef ModuleElement _lmul_nonscalar_c_impl(left, right):
591        raise TypeError
592
593    def _lmul_nonscalar(left, right):
594        return left._lmul_nonscalar_c_impl(right)
595   
596    cdef ModuleElement _rmul_nonscalar_c(right, left):
597        if HAS_DICTIONARY(right):
598            return right._rmul_nonscalar(left)
599        else:
600            return right._rmul_nonscalar_c_impl(left)
601       
602    cdef ModuleElement _rmul_nonscalar_c_impl(right, left):
603        raise TypeError
604
605    def _rmul_nonscalar(right, left):
606        return right._rmul_nonscalar_c_impl(left)
607       
608
609    # rmul -- left * self
610    cdef ModuleElement _rmul_c(self, RingElement left):
611        """
612        DO NOT OVERRIDE THIS FUNCTION.  OK to call.
613        """
614        if HAS_DICTIONARY(self):
615            return self._rmul_(left)
616        else:
617            return self._rmul_c_impl(left)
618
619    cdef ModuleElement _rmul_c_impl(self, RingElement left):
620        """
621        Default module left scalar multiplication, which is to try to
622        canonically coerce the scalar to the integers and do that
623        multiplication, which is always defined.
624        """
625        from sage.rings.all import ZZ
626        n = (<Parent>ZZ)._coerce_c(left)
627        a = self
628        if n < 0:
629            a = -a
630            n = -n
631        prod = self._parent(0)
632        aprod = a
633        while True:
634            if n&1 > 0: prod = prod + aprod
635            n = n >> 1
636            if n != 0:
637                aprod = aprod + aprod
638            else:
639                break
640        return prod
641
642    def _rmul_(self, left):
643        return self._rmul_c_impl(left)
644
645
646    # lmul -- self * right
647       
648    cdef ModuleElement _lmul_c(self, RingElement right):
649        """
650        DO NOT OVERRIDE THIS FUNCTION.
651        """
652        if HAS_DICTIONARY(self):
653            return self._lmul_(right)
654        else:
655            return self._lmul_c_impl(right)
656       
657    cdef ModuleElement _lmul_c_impl(self, RingElement right):
658        """
659        Default module right scalar multiplication, which is to try to
660        canonically coerce the scalar to the integers and do that
661        multiplication, which is always defined.
662        """
663        return self._rmul_c(right)
664
665    def _lmul_(self, right):
666        return self._lmul_c_impl(right)
667   
668   
669    cdef RingElement coerce_to_base_ring(self, x):
670        if PY_TYPE_CHECK(x, Element) and (<Element>x)._parent is self._parent._base:
671            return x
672        try:
673            return self._parent._base._coerce_c(x)
674        except AttributeError:
675            return self._parent._base(x)
676
677    ##################################################
678    # Other properties
679    ##################################################
680    def order(self):              ### DO NOT OVERRIDE THIS!!! Instead, override additive_order.
681        """
682        Return the additive order of self.
683        """
684        return self.additive_order()   
685
686    def additive_order(self):
687        """
688        Return the additive order of self.
689        """
690        raise NotImplementedError
691   
692def module_element_generic_multiply(left, right):
693    return module_element_generic_multiply_c(left, right)
694
695cdef module_element_generic_multiply_c(left, right):
696    cdef int is_element
697    if PY_TYPE_CHECK(right, ModuleElement) and not PY_TYPE_CHECK(right, RingElement):
698        # do left * (a module element right)
699        is_element = PY_TYPE_CHECK(left, Element)
700        if is_element  and  (<Element>left)._parent is (<ModuleElement>right)._parent._base:
701            # No coercion needed
702            return (<ModuleElement>right)._rmul_c(left)
703        else:
704            try:
705                return (<ModuleElement>right)._rmul_nonscalar_c(left)
706            except TypeError:
707                pass
708            # Otherwise we have to do an explicit canonical coercion.
709            try:
710                return (<ModuleElement>right)._rmul_c(
711                    (<Parent>(<ModuleElement>right)._parent._base)._coerce_c(left))
712            except TypeError:
713                if is_element:
714                    # that failed -- try to base extend right then do the multiply:
715                    right = right.base_extend((<RingElement>left)._parent)
716                    return (<ModuleElement>right)._rmul_c(left)
717    else:
718        # do (module element left) * right
719        # This is the symmetric case of above.
720        is_element = PY_TYPE_CHECK(right, Element)
721        if is_element  and  (<Element>right)._parent is (<ModuleElement>left)._parent._base:
722            # No coercion needed
723            return (<ModuleElement>left)._lmul_c(right)
724        else:
725            try:
726                return (<ModuleElement>left)._lmul_nonscalar_c(right)
727            except TypeError:
728                pass
729            # Otherwise we have to do an explicit canonical coercion.
730            try:
731                return (<ModuleElement>left)._lmul_c(
732                    (<Parent>(<ModuleElement>left)._parent._base)._coerce_c(right))
733            except TypeError:
734                if is_element:
735                    # that failed -- try to base extend right then do the multiply:
736                    left = left.base_extend((<RingElement>right)._parent)
737                    return (<ModuleElement>left)._rmul_c(right)
738    raise TypeError
739
740########################################################################
741# Monoid
742########################################################################
743
744def is_MonoidElement(x):
745    """
746    Return True if x is of type MonoidElement.
747    """
748    return IS_INSTANCE(x, MonoidElement)
749
750cdef class MonoidElement(Element):
751    """
752    Generic element of a monoid.
753    """
754
755    #############################################################
756    # Multiplication
757    #############################################################
758    def __mul__(left, right):
759        """
760        Top-level multiplication operator for ring elements.
761        See extensive documentation at the top of element.pyx.
762        """
763        if have_same_parent(left, right):
764            return (<MonoidElement>left)._mul_c(<MonoidElement>right)
765        return bin_op_c(left, right, operator.mul)
766           
767
768    cdef MonoidElement _mul_c(left, MonoidElement right):
769        """
770        Multiplication dispatcher for RingElements.
771        DO NOT OVERRIDE THIS FUNCTION.
772        See extensive documentation at the top of element.pyx.
773        """       
774        if HAS_DICTIONARY(left):   # fast check
775            return left._mul_(right)
776        else:
777            return left._mul_c_impl(right)
778       
779       
780    cdef MonoidElement _mul_c_impl(left, MonoidElement right):
781        """
782        Pyrex classes should override this function to implement multiplication.
783        DO NOT CALL THIS FUNCTION DIRECTLY.
784        See extensive documentation at the top of element.pyx.
785        """
786        raise TypeError
787
788    def _mul_(left, right):
789        return left._mul_c_impl(right)
790
791    #############################################################
792    # Other generic functions that should be available to
793    # any monoid element.
794    #############################################################
795    def order(self):
796        """
797        Return the multiplicative order of self.
798        """
799        return self.multiplicative_order()
800
801    def multiplicative_order(self):
802        """
803        Return the multiplicative order of self.
804        """
805        raise NotImplementedError
806   
807    def __pow__(self, n, dummy):
808        cdef int i
809
810        if PyFloat_Check(n):
811            raise TypeError, "raising %s to the power of the float %s not defined"%(self, n)
812
813        n = int(n)
814
815        a = self
816        power = self.parent()(1)
817        if n < 0:
818            n = -n
819            a = ~self
820        elif n == 0:
821            return power
822
823        power = (<Element>self)._parent(1)
824        apow = a
825        while True:
826            if n&1 > 0: power = power*apow
827            n = n >> 1
828            if n != 0:
829                apow = apow*apow
830            else:
831                break
832           
833        return power
834
835
836def is_AdditiveGroupElement(x):
837    """
838    Return True if x is of type AdditiveGroupElement.
839    """
840    return IS_INSTANCE(x, AdditiveGroupElement)
841
842cdef class AdditiveGroupElement(ModuleElement):
843    """
844    Generic element of an additive group.
845    """
846    def order(self):
847        """
848        Return additive order of element
849        """
850        return self.additive_order()
851
852    def __invert__(self):
853        raise NotImplementedError, "multiplicative inverse not defined for additive group elements"
854   
855    cdef ModuleElement _rmul_c_impl(self, RingElement left):
856        return self._lmul_c_impl(left)
857       
858    cdef ModuleElement _lmul_c_impl(self, RingElement right):
859        cdef int m
860        m = int(right)  # a little worrisome.
861        if m<0:
862            return (-self)*(-m)
863        if m==1:
864            return self
865        P = self.scheme()(0)
866        if m==0:
867            return P
868        power = P
869        i = 0
870        apow2 = self
871        while ((m>>i) > 0):
872            if((m>>i) & 1):
873                power = power + apow2
874            apow2 = apow2 + apow2
875            i = i + 1
876        return power
877
878
879def is_MultiplicativeGroupElement(x):
880    """
881    Return True if x is of type MultiplicativeGroupElement.
882    """
883    return IS_INSTANCE(x, MultiplicativeGroupElement)
884
885cdef class MultiplicativeGroupElement(MonoidElement):
886    """
887    Generic element of a multiplicative group.
888    """
889    def order(self):
890        """
891        Return the multiplicative order of self.
892        """
893        return self.multiplicative_order()
894
895    def _add_(self, x):
896        raise ArithmeticError, "addition not defined in a multiplicative group"
897
898    def __div__(left, right):
899        if have_same_parents(left, right):
900            return left._div_(right)
901        return bin_op_c(left, right, operator.div)
902   
903    cdef MultiplicativeGroupElement _div_c(self, MultiplicativeGroupElement right):
904        """
905        Multiplication dispatcher for MultiplicativeGroupElements.
906        DO NOT OVERRIDE THIS FUNCTION.
907        See extensive documentation at the top of element.pyx.
908        """
909        if HAS_DICTIONARY(self):   # fast check
910            return self._div_(right)
911        else:
912            return self._div_c_impl(right)
913
914    cdef MultiplicativeGroupElement _div_c_impl(self, MultiplicativeGroupElement right):
915        """
916        Pyrex classes should override this function to implement division.
917        DO NOT CALL THIS FUNCTION DIRECTLY.
918        See extensive documentation at the top of element.pyx.
919        """
920        return self._parent.fraction_field()(self, right)
921
922    def _div_(MultiplicativeGroupElement self, MultiplicativeGroupElement right):
923        """
924        Python classes should override this function to implement division.
925        """
926        return self._div_c_impl(right)
927   
928
929    def __invert__(self):
930        return 1/self
931
932
933def is_RingElement(x):
934    """
935    Return True if x is of type RingElement.
936    """
937    return IS_INSTANCE(x, RingElement)
938
939cdef class RingElement(ModuleElement):
940    ##################################################
941    def is_zero(self):
942        return PyBool_FromLong(self == self.parent()(0))
943
944    def is_one(self):
945        return PyBool_FromLong(self == self.parent()(1))
946
947    ##################################
948    # Multiplication
949    ##################################   
950   
951    def __mul__(self, right):
952        """
953        Top-level multiplication operator for ring elements.
954        See extensive documentation at the top of element.pyx.
955        """
956        # Try fast pathway if they are both RingElements and the parents match.
957        # (We know at least one of the arguments is a RingElement. So if their
958        # types are *equal* (fast to check) then they are both RingElements.
959        # Otherwise use the slower test via PY_TYPE_CHECK.)
960        if have_same_parent(self, right):
961            return (<RingElement>self)._mul_c(<RingElement>right)
962
963        # VERY important special case:
964        # (ring element) * (module element that is not a ring element)
965        # We don't have to do the other direction, since it is
966        # done in module element __mul__.
967        if PY_TYPE_CHECK(right, ModuleElement) and not PY_TYPE_CHECK(right, RingElement):
968            # Now self must be a ring element:
969            # If the parent is the same as the base ring, good
970            if (<RingElement>self)._parent is (<ModuleElement>right)._parent._base:
971                return (<ModuleElement>right)._rmul_c(self)
972            else:
973                # Otherwise we have to do an explicit canonical coercion.
974                try:
975                    return (<ModuleElement>right)._rmul_c(
976                        (<Parent>(<ModuleElement>right)._parent._base)._coerce_c(self))
977                except TypeError:
978                    # that failed -- try to base extend right then do the multiply:
979                    right = right.base_extend((<RingElement>self)._parent)
980                    return (<ModuleElement>right)._rmul_c(self)
981       
982        # General case.
983        return bin_op_c(self, right, operator.mul)
984
985    cdef RingElement _mul_c(self, RingElement right):
986        """
987        Multiplication dispatcher for RingElements.
988        DO NOT OVERRIDE THIS FUNCTION.
989        See extensive documentation at the top of element.pyx.
990        """       
991        if HAS_DICTIONARY(self):   # fast check
992            return self._mul_(right)
993        else:
994            return self._mul_c_impl(right)
995
996    cdef RingElement _mul_c_impl(self, RingElement right):
997        """
998        Pyrex classes should override this function to implement multiplication.
999        DO NOT CALL THIS FUNCTION DIRECTLY.
1000        See extensive documentation at the top of element.pyx.
1001        """
1002        raise TypeError, arith_error_message(self, right, operator.mul)
1003
1004    def _mul_(RingElement self, RingElement right):
1005        """
1006        Python classes should override this function to implement multiplication.
1007        See extensive documentation at the top of element.pyx.       
1008        """
1009        return self._mul_c_impl(right)
1010
1011
1012    ##################################
1013    # Division
1014    ##################################   
1015   
1016    def __truediv__(self, right):
1017        # in sage all divs are true
1018        if not PY_TYPE_CHECK(self, Element):
1019            return bin_op_c(self, right, operator.div)
1020        return self.__div__(right)
1021
1022    def __div__(self, right):
1023        """
1024        Top-level multiplication operator for ring elements.
1025        See extensive documentation at the top of element.pyx.
1026        """
1027        if have_same_parent(self, right):
1028            return (<RingElement>self)._div_c(<RingElement>right)
1029        return bin_op_c(self, right, operator.div)
1030
1031           
1032
1033    cdef RingElement _div_c(self, RingElement right):
1034        """
1035        Multiplication dispatcher for RingElements.
1036        DO NOT OVERRIDE THIS FUNCTION.
1037        See extensive documentation at the top of element.pyx.
1038        """
1039        if HAS_DICTIONARY(self):   # fast check
1040            return self._div_(right)
1041        else:
1042            return self._div_c_impl(right)
1043
1044    cdef RingElement _div_c_impl(self, RingElement right):
1045        """
1046        Pyrex classes should override this function to implement division.
1047        DO NOT CALL THIS FUNCTION DIRECTLY.
1048        See extensive documentation at the top of element.pyx.
1049        """
1050        try:
1051            return self._parent.fraction_field()(self, right)
1052        except AttributeError:
1053            raise TypeError, arith_error_message(self, right, operator.div)
1054
1055    def _div_(RingElement self, RingElement right):
1056        """
1057        Python classes should override this function to implement division.
1058        """
1059        return self._div_c_impl(right)
1060
1061    def __pos__(self):
1062        return self
1063
1064    def __invert__(self):
1065        return 1/self
1066
1067    ##################################################
1068
1069    def order(self):
1070        """
1071        Return the additive order of self.
1072        """
1073        return self.additive_order()
1074
1075    def additive_order(self):
1076        """
1077        Return the additive order of self.
1078        """
1079        raise NotImplementedError
1080
1081    def multiplicative_order(self):
1082        r"""
1083        Return the multiplicative order of self, if self is a unit, or raise
1084        \code{ArithmeticError} otherwise.
1085        """
1086        if not self.is_unit():
1087            raise ArithmeticError, "self (=%s) must be a unit to have a multiplicative order."
1088        raise NotImplementedError
1089
1090    def is_unit(self):
1091        if self == 1 or self == -1:
1092            return True
1093        raise NotImplementedError
1094
1095    def is_nilpotent(self):
1096        """
1097        Return True if self is nilpotent, i.e., some power of self
1098        is 0.
1099        """
1100        if self.is_unit():
1101            return False
1102        if self.is_zero():
1103            return True
1104        raise NotImplementedError
1105   
1106    def __pow__(self, n, dummy):
1107        cdef int i
1108        if PyFloat_Check(n):
1109            raise TypeError, "raising %s to the power of the float %s not defined"%(self, n)
1110
1111        n = int(n)
1112        try:
1113            return self._pow(n)
1114        except AttributeError:
1115            pass
1116
1117        a = self
1118        power = self.parent()(1)
1119        if n < 0:
1120            n = -n
1121            a = ~self
1122        elif n == 0:
1123            return power
1124        i = 0
1125        apow2 = a
1126        while (n>>i) > 0:
1127            if (n>>i) & 1:
1128                power = power * apow2
1129            if n == 0: break   # to not waste time doing an extra multiplication/increment
1130            apow2 = apow2 * apow2
1131            i = i+1
1132        return power
1133
1134
1135
1136
1137def is_CommutativeRingElement(x):
1138    """
1139    Return True if x is of type CommutativeRingElement.
1140    """
1141    return IS_INSTANCE(x, CommutativeRingElement)
1142
1143cdef class CommutativeRingElement(RingElement):
1144    def _im_gens_(self, codomain, im_gens):
1145        if len(im_gens) == 1 and self.parent().gen(0) == 1:
1146            return codomain(self)
1147        raise NotImplementedError
1148   
1149    def inverse_mod(self, I):
1150        r"""
1151        Return an inverse of self modulo the ideal $I$, if defined,
1152        i.e., if $I$ and self together generate the unit ideal.
1153        """
1154        raise NotImplementedError
1155   
1156    def mod(self, I):
1157        r"""
1158        Return a representative for self modulo the ideal I (or the ideal
1159        generated by the elements of I if I is not an ideal.)
1160
1161        EXAMPLE:  Integers
1162        Reduction of 5 modulo an ideal:
1163            sage: n = 5
1164            sage: n.mod(3*ZZ)
1165            2
1166
1167        Reduction of 5 modulo the ideal generated by 3.
1168            sage: n.mod(3)
1169            2
1170
1171        Reduction of 5 modulo the ideal generated by 15 and 6, which is $(3)$.           
1172            sage: n.mod([15,6])
1173            2
1174
1175
1176        EXAMPLE: Univiate polynomials
1177            sage: R.<x> = PolynomialRing(QQ)
1178            sage: f = x^3 + x + 1
1179            sage: f.mod(x + 1)
1180            -1
1181
1182        When little is implemented about a given ring, then mod may
1183        return simply return $f$.  For example, reduction is not
1184        implemented for $\Z[x]$ yet. (TODO!)
1185       
1186            sage: R.<x> = PolynomialRing(ZZ)
1187            sage: f = x^3 + x + 1
1188            sage: f.mod(x + 1)
1189            x^3 + x + 1
1190           
1191       
1192
1193        EXAMPLE: Multivariate polynomials
1194        We reduce a polynomial in two variables modulo a polynomial
1195        and an ideal:
1196            sage: R.<x,y,z> = PolynomialRing(QQ, 3)
1197            sage: (x^2 + y^2 + z^2).mod(x+y+z)
1198            2*z^2 + 2*y*z + 2*y^2
1199
1200        Notice above that $x$ is eliminated.  In the next example,
1201        both $y$ and $z$ are eliminated.
1202           
1203            sage: (x^2 + y^2 + z^2).mod( (x - y, y - z) )
1204            3*z^2
1205            sage: f = (x^2 + y^2 + z^2)^2; f
1206            z^4 + 2*y^2*z^2 + y^4 + 2*x^2*z^2 + 2*x^2*y^2 + x^4
1207            sage: f.mod( (x - y, y - z) )
1208            9*z^4
1209
1210        In this example $y$ is eliminated.
1211            sage: (x^2 + y^2 + z^2).mod( (x^3, y - z) )
1212            2*z^2 + x^2
1213        """
1214        from sage.rings.all import is_Ideal
1215        if not is_Ideal(I) or not I.ring() is self.parent():
1216            I = self.parent().ideal(I)
1217            #raise TypeError, "I = %s must be an ideal in %s"%(I, self.parent())
1218        return I.reduce(self)
1219
1220cdef class Vector(ModuleElement):
1221    def __mul__(left, right):
1222        if PY_TYPE_CHECK(left, Vector):
1223            # left is the vector
1224            # Possibilities:
1225            #     left * matrix
1226            if PY_TYPE_CHECK(right, Matrix):
1227                return (<Matrix>right)._vector_times_matrix_c(<Vector>left)
1228            #     left * vector
1229            if PY_TYPE_CHECK(right, Vector):
1230                return (<Vector>left)._vector_times_vector_c(<Vector>right)
1231            #     left * scalar
1232            return (<ModuleElement>left)._multiply_by_scalar(right)
1233           
1234        else:
1235            # right is the vector
1236            # Possibilities:
1237            #     matrix * right
1238            if PY_TYPE_CHECK(left, Matrix):
1239                return (<Matrix>left)._matrix_times_vector_c(<Vector>right)
1240            #     vector * right
1241            if PY_TYPE_CHECK(left, Vector):
1242                return (<Vector>left)._vector_times_vector_c(<Vector>right)
1243            #     scalar * right
1244            return (<ModuleElement>right)._rmultiply_by_scalar(left)
1245
1246    cdef Vector _vector_times_vector_c(Vector left, Vector right):
1247        if left._degree != right._degree:
1248            raise TypeError, "incompatible degrees"
1249        left, right = canonical_base_coercion_c(left, right)
1250        if HAS_DICTIONARY(left):
1251            return left._vector_times_vector(right)
1252        else:
1253            return left._vector_times_vector_c_impl(right)
1254    cdef Vector _vector_times_vector_c_impl(Vector left, Vector right):
1255        raise TypeError,arith_error_message(left, right, operator.mul)
1256   
1257    def  _vector_times_vector(left, right):
1258        return self.vector_time_vector_c_impl(right)
1259
1260    def __div__(self, right):
1261        if PY_TYPE_CHECK(self, Vector):
1262            right = (<Vector>self)._parent._base._coerce_c(right)
1263            return (<Vector>self)._lmul_c(~right)
1264        raise TypeError, arith_error_message(self, right, operator.div)
1265       
1266
1267cdef have_same_base(Element x, Element y):
1268    return x._parent._base is y._parent._base
1269
1270
1271def is_Vector(x):
1272    return IS_INSTANCE(x, Vector)
1273
1274cdef class Matrix(ModuleElement):
1275    cdef int is_sparse_c(self):
1276        raise NotImplementedError
1277   
1278    cdef int is_dense_c(self):
1279        raise NotImplementedError
1280   
1281    def __mul__(left, right):
1282        if PY_TYPE_CHECK(left, Matrix):
1283            # left is the matrix
1284            # Possibilities:
1285            #     left * matrix
1286            if PY_TYPE_CHECK(right, Matrix):
1287                return (<Matrix>left)._matrix_times_matrix_c(<Vector>right)
1288            #     left * vector
1289            if PY_TYPE_CHECK(right, Vector):
1290                return (<Matrix>left)._matrix_times_vector_c(<Vector>right)
1291            #     left * scalar
1292            return (<Matrix>left)._multiply_by_scalar(right)
1293           
1294        else:
1295            # right is the matrix
1296            # Possibilities:
1297            #     matrix * right
1298            if PY_TYPE_CHECK(left, Matrix):
1299                return (<Matrix>left)._matrix_times_matrix_c(<Matrix>right)
1300            #     vector * right
1301            if PY_TYPE_CHECK(left, Vector):
1302                return (<Matrix>right)._vector_times_matrix_c(<Vector>left)
1303            #     scalar * right
1304            return (<Matrix>right)._rmultiply_by_scalar(left)
1305       
1306    cdef Vector _vector_times_matrix_c(matrix_right, Vector vector_left):
1307        if vector_left._degree != matrix_right._nrows:
1308            raise TypeError, "incompatible dimensions"
1309        matrix_right, vector_left = canonical_base_coercion_c(matrix_right, vector_left)
1310        if HAS_DICTIONARY(matrix_right):
1311            return matrix_right._vector_times_matrix(vector_left)           
1312        else:
1313            return matrix_right._vector_times_matrix_c_impl(vector_left)
1314       
1315    cdef Vector _vector_times_matrix_c_impl(matrix_right, Vector vector_left):
1316        raise TypeError
1317   
1318    def _vector_times_matrix(matrix_right, vector_left):
1319        return matrix_right._vector_times_matrix_c_impl(vector_left)
1320
1321       
1322    cdef Vector _matrix_times_vector_c(matrix_left, Vector vector_right):
1323        if matrix_left._ncols != vector_right._degree:
1324            raise TypeError, "incompatible dimensions"
1325        matrix_left, vector_right = canonical_base_coercion_c(matrix_left, vector_right)
1326        if HAS_DICTIONARY(matrix_left):
1327            return matrix_left._matrix_times_vector(vector_right)
1328        else:
1329            return matrix_left._matrix_times_vector_c_impl(vector_right)
1330           
1331    cdef Vector _matrix_times_vector_c_impl(matrix_left, Vector vector_right):
1332        raise TypeError
1333    def _matrix_times_vector(matrix_left, vector_right):
1334        return matrix_left._matrix_times_vector_c_impl(vector_right)
1335
1336       
1337    cdef Matrix _matrix_times_matrix_c(left, Matrix right):
1338        cdef int sl, sr
1339        if left._ncols != right._nrows:
1340            raise TypeError, "incompatible dimensions"
1341        left, right = canonical_base_coercion_c(left, right)
1342        sl = left.is_sparse_c(); sr = right.is_sparse_c()
1343        if sl != sr:  # is dense and one is sparse
1344            if sr:  # left is dense
1345                right = right.dense_matrix()
1346            else:
1347                left = left.dense_matrix()
1348        if HAS_DICTIONARY(left):
1349            return left._matrix_times_matrix(right)
1350        else:
1351            return left._matrix_times_matrix_c_impl(right)
1352       
1353    cdef Matrix _matrix_times_matrix_c_impl(left, Matrix right):
1354        raise TypeError
1355    def _matrix_time_matrix(left, right):
1356        return left._matrix_times_matrix_c_impl(right)
1357   
1358
1359def is_Matrix(x):
1360    return IS_INSTANCE(x, Matrix)
1361
1362def is_IntegralDomainElement(x):
1363    """
1364    Return True if x is of type IntegralDomainElement.
1365    """
1366    return IS_INSTANCE(x, IntegralDomainElement)
1367
1368cdef class IntegralDomainElement(CommutativeRingElement):
1369    def is_nilpotent(self):
1370        return self.is_zero()
1371
1372
1373def is_DedekindDomainElement(x):
1374    """
1375    Return True if x is of type DedekindDomainElement.
1376    """
1377    return IS_INSTANCE(x, DedekindDomainElement)
1378
1379cdef class DedekindDomainElement(IntegralDomainElement):
1380    pass
1381       
1382def is_PrincipalIdealDomainElement(x):
1383    """
1384    Return True if x is of type PrincipalIdealDomainElement.
1385    """
1386    return IS_INSTANCE(x, PrincipalIdealDomainElement)
1387
1388cdef class PrincipalIdealDomainElement(DedekindDomainElement):
1389    def lcm(self, right):
1390        """
1391        Returns the least common multiple of self and right.
1392        """
1393        if not PY_TYPE_CHECK(right, Element) or not ((<Element>right)._parent is self._parent):
1394            return bin_op_c(self, right, lcm)
1395        return self._lcm(right)
1396
1397    def gcd(self, right):
1398        """
1399        Returns the gcd of self and right, or 0 if both are 0.
1400        """
1401        if not PY_TYPE_CHECK(right, Element) or not ((<Element>right)._parent is self._parent):
1402            return bin_op_c(self, right, gcd)
1403        return self._gcd(right)
1404
1405    def xgcd(self, right):
1406        r"""
1407        Return the extended gcd of self and other, i.e., elements $r, s, t$ such that
1408        $$
1409           r = s \cdot self + t \cdot other.
1410        $$
1411        """
1412        if not PY_TYPE_CHECK(right, Element) or not ((<Element>right)._parent is self._parent):
1413            return bin_op_c(self, right, xgcd)
1414        return self._xgcd(right)
1415
1416
1417# This is pretty nasty low level stuff. The idea is to speed up construction
1418# of EuclideanDomainElements (in particular Integers) by skipping some tp_new
1419# calls up the inheritance tree.
1420PY_SET_TP_NEW(EuclideanDomainElement, Element)
1421
1422def is_EuclideanDomainElement(x):
1423    """
1424    Return True if x is of type EuclideanDomainElement.
1425    """
1426    return IS_INSTANCE(x, EuclideanDomainElement)
1427
1428cdef class EuclideanDomainElement(PrincipalIdealDomainElement):
1429
1430    def degree(self):
1431        raise NotImplementedError
1432
1433    def _gcd(self, other):
1434        """
1435        Return the greatest common divisor of self and other.
1436
1437        Algorithm 3.2.1 in Cohen, GTM 138.
1438        """
1439        A = self
1440        B = other
1441        while not B.is_zero():
1442            Q, R = A.quo_rem(B)
1443            A = B
1444            B = R
1445        return A
1446
1447    def leading_coefficient(self):
1448        raise NotImplementedError
1449
1450    def quo_rem(self, other):
1451        raise NotImplementedError
1452
1453    def __floordiv__(self,right):
1454        """
1455        Quotient of division of self by other.  This is denoted //.
1456        """
1457        Q, _ = self.quo_rem(right)
1458        return Q
1459       
1460    def __mod__(self, other):
1461        """
1462        Remainder of division of self by other.
1463       
1464        EXAMPLES:
1465            sage: R.<x> = ZZ[]
1466            sage: x % (x+1)
1467            -1
1468            sage: (x**3 + x - 1) % (x**2 - 1)
1469            2*x - 1
1470        """
1471        _, R = self.quo_rem(other)
1472        return R
1473       
1474def is_FieldElement(x):
1475    """
1476    Return True if x is of type FieldElement.
1477    """
1478    return IS_INSTANCE(x, FieldElement)
1479
1480cdef class FieldElement(CommutativeRingElement):
1481
1482    def is_unit(self):
1483        """
1484        Return True if self is a unit in its parent ring.
1485       
1486        EXAMPLES:
1487            sage: a = 2/3; a.is_unit()
1488            True
1489
1490        On the other hand, 2 is not a unit, since its parent is ZZ.
1491            sage: a = 2; a.is_unit()
1492            False
1493            sage: parent(a)
1494            Integer Ring
1495
1496        However, a is a unit when viewed as an element of QQ:
1497            sage: a = QQ(2); a.is_unit()
1498            True
1499        """
1500        return PyBool_FromLong(not self.is_zero())
1501   
1502    def _gcd(self, FieldElement other):
1503        """
1504        Return the greatest common divisor of self and other.
1505        """
1506        if self.is_zero() and other.is_zero():
1507            return self
1508        else:
1509            return self.parent()(1)
1510
1511    def _lcm(self, FieldElement other):
1512        """
1513        Return the least common multiple of self and other.
1514        """
1515        if self.is_zero() and other.is_zero():
1516            return self
1517        else:
1518            return self.parent()(1)
1519
1520    def _xgcd(self, FieldElement other):
1521        R = self.parent()
1522        if not self.is_zero():
1523            return R(1), ~self, R(0)
1524        elif not other.is_zero():
1525            return R(1), R(0), ~self
1526        else: # both are 0
1527            return self, self, self
1528       
1529
1530    def quo_rem(self, right):
1531        if not isinstance(right, FieldElement) or not (right.parent() is self.parent()):
1532            right = self.parent()(right)
1533        return self/right, 0
1534
1535def is_FiniteFieldElement(x):
1536    """
1537    Return True if x is of type FiniteFieldElement.
1538    """
1539    return IS_INSTANCE(x, FiniteFieldElement)
1540
1541cdef class FiniteFieldElement(FieldElement):
1542    pass
1543   
1544def is_AlgebraElement(x):
1545    """
1546    Return True if x is of type AlgebraElement.
1547    """
1548    return IS_INSTANCE(x, AlgebraElement)
1549
1550cdef class AlgebraElement(RingElement):
1551    pass
1552
1553def is_CommutativeAlgebraElement(x):
1554    """
1555    Return True if x is of type CommutativeAlgebraElement.
1556    """
1557    return IS_INSTANCE(x, CommutativeAlgebraElement)
1558
1559cdef class CommutativeAlgebraElement(CommutativeRingElement):
1560    pass   
1561
1562def is_InfinityElement(x):
1563    """
1564    Return True if x is of type InfinityElement.
1565    """
1566    return IS_INSTANCE(x, InfinityElement)
1567
1568cdef class InfinityElement(RingElement):
1569    pass
1570
1571
1572cdef int have_same_parent(left, right):
1573    """
1574    Return nonzero true value if and only if left and right are
1575    elements and have the same parent.
1576    """
1577    # (We know at least one of the arguments is an Element. So if
1578    # their types are *equal* (fast to check) then they are both
1579    # Elements.  Otherwise use the slower test via PY_TYPE_CHECK.)
1580    if PY_TYPE(left) is PY_TYPE(right):
1581        return (<Element>left)._parent is (<Element>right)._parent
1582   
1583    if PY_TYPE_CHECK(right, Element) and PY_TYPE_CHECK(left, Element):
1584        return (<Element>left)._parent is (<Element>right)._parent
1585
1586    return 0
1587           
1588
1589
1590
1591
1592
1593#################################################################################
1594#
1595#  Coercion of elements
1596#
1597#################################################################################
1598import __builtin__
1599import operator
1600
1601cimport sage.modules.module
1602import  sage.modules.module
1603
1604#################################################################################
1605# parent
1606#################################################################################
1607cdef parent_c(x):
1608    if PY_TYPE_CHECK(x,Element):
1609        return (<Element>x)._parent
1610    return <object>PY_TYPE(x)
1611
1612def parent(x):
1613    return parent_c(x)
1614
1615#################################################################################
1616# coerce
1617#################################################################################
1618def coerce(Parent p, x):
1619    try:
1620        return p._coerce_c(x)
1621    except AttributeError:
1622        return p(x)
1623
1624           
1625#################################################################################
1626# canonical coercion of two ring elements into one of their parents.
1627#################################################################################
1628cdef _verify_canonical_coercion_c(x, y):
1629    if not have_same_parent(x,y):
1630        raise RuntimeError, """There is a bug in the coercion code in SAGE.
1631Both x (=%s) and y (=%s) are supposed to have identical parents but they don't.
1632In fact, x has parent '%s'
1633whereas y has parent '%s'"""%(x,y,parent_c(x),parent_c(y))
1634    return x, y
1635
1636def canonical_coercion(x, y):
1637    return canonical_coercion_c(x,y)
1638
1639cdef canonical_coercion_c(x, y):
1640    cdef int i
1641    xp = parent_c(x)
1642    yp = parent_c(y)
1643    if xp is yp:
1644        return x, y
1645
1646    if PY_IS_NUMERIC(x):
1647        try:
1648            x = yp(x)
1649        except TypeError:
1650            y = x.__class__(y)
1651            return x, y
1652        # Calling this every time incurs overhead -- however, if a mistake
1653        # gets through then one can get infinite loops in C code hence core
1654        # dumps.  And users define _coerce_ and __call__ for rings, which
1655        # can easily have bugs in it, i.e., not really make the element
1656        # have the correct parent.  Thus this check is *crucial*.
1657        return _verify_canonical_coercion_c(x,y)
1658   
1659    elif PY_IS_NUMERIC(y):
1660        try:
1661            y = xp(y)
1662        except TypeError:
1663            x = y.__class__(x)
1664            return x, y           
1665        return _verify_canonical_coercion_c(x,y)
1666
1667    try:
1668        if xp.has_coerce_map_from(yp):
1669            y = (<Parent>xp)._coerce_c(y)
1670            return _verify_canonical_coercion_c(x,y)
1671    except AttributeError:
1672        pass
1673    try:
1674        if yp.has_coerce_map_from(xp):
1675            x = (<Parent>yp)._coerce_c(x)
1676            return _verify_canonical_coercion_c(x,y)
1677    except AttributeError:
1678        pass
1679    raise TypeError, "no common canonical parent for objects with parents: '%s' and '%s'"%(xp, yp)
1680
1681cdef canonical_base_coercion_c(Element x, Element y):
1682    if not have_same_base(x, y):
1683        if (<Parent> x._parent._base).has_coerce_map_from_c(y._parent._base):
1684            # coerce all elements of y to the base ring of x
1685            y = y.base_extend_c(x._parent._base)
1686        elif (<Parent> y._parent._base).has_coerce_map_from_c(x._parent._base):
1687            # coerce x to have elements in the base ring of y
1688            x = x.base_extend_c(y._parent._base)
1689    return x,y
1690
1691def canonical_base_coercion(x, y):
1692    try:
1693        xb = x.base_ring()
1694    except AttributeError:
1695        #raise TypeError, "unable to find base ring for %s (parent: %s)"%(x,x.parent())
1696        raise TypeError, "unable to find base ring"
1697    try:
1698        yb = y.base_ring()
1699    except AttributeError:
1700        raise TypeError, "unable to find base ring"
1701        #raise TypeError, "unable to find base ring for %s (parent: %s)"%(y,y.parent())
1702    try:
1703        b = canonical_coercion_c(xb(0),yb(0))[0].parent()
1704    except TypeError:
1705        raise TypeError, "unable to find base ring"
1706        #raise TypeError, "unable to find a common base ring for %s (base ring: %s) and %s (base ring %s)"%(x,xb,y,yb)
1707    return x.change_ring(b), y.change_ring(b)
1708
1709
1710D = {'mul':'*', 'add':'+', 'sub':'-', 'div':'/'}
1711cdef arith_error_message(x, y, op):
1712    try:
1713        n = D[op.__name__]
1714    except KeyError:
1715        n = op.__name__
1716    return "unsupported operand parent(s) for '%s': '%s' and '%s'"%(n, parent_c(x), parent_c(y))
1717   
1718def bin_op(x, y, op):
1719    return bin_op_c(x,y,op)
1720
1721cdef bin_op_c(x, y, op):
1722    """
1723    Compute x op y, where coercion of x and y works according to
1724    SAGE's coercion rules.
1725    """
1726    # Try canonical element coercion.
1727    try:
1728        x1, y1 = canonical_coercion_c(x, y)
1729        return op(x1,y1)       
1730    except TypeError, msg:
1731        if not op is operator.mul:
1732            raise TypeError, arith_error_message(x,y,op)
1733
1734    # If the op is multiplication, then some other algebra multiplications
1735    # may be defined
1736   
1737    # 2. Try scalar multiplication.
1738    # No way to multiply x and y using the ``coerce into a canonical
1739    # parent'' rule.
1740    # The next rule to try is scalar multiplication by coercing
1741    # into the base ring.
1742    cdef int x_is_modelt, y_is_modelt
1743
1744    y_is_modelt = PY_TYPE_CHECK(y, ModuleElement)
1745    if y_is_modelt:
1746        # First try to coerce x into the base ring of y if y is an element.
1747        try:
1748            R = (<ModuleElement> y)._parent._base
1749            if R is None:
1750                raise RuntimeError, "base of '%s' must be set to a ring (but it is None)!"%((<ModuleElement> y)._parent)
1751            x = (<Parent>R)._coerce_c(x)
1752            return (<ModuleElement> y)._rmul_c(x)     # the product x * y
1753        except TypeError, msg:
1754            pass
1755
1756    x_is_modelt = PY_TYPE_CHECK(x, ModuleElement)
1757    if x_is_modelt:
1758        # That did not work.  Try to coerce y into the base ring of x.
1759        try:
1760            R = (<ModuleElement> x)._parent._base
1761            if R is None:
1762                raise RuntimeError, "base of '%s' must be set to a ring (but it is None)!"%((<ModuleElement> x)._parent)           
1763            y = (<Parent> R)._coerce_c(y)
1764            return (<ModuleElement> x)._lmul_c(y)    # the product x * y
1765        except TypeError:
1766            pass
1767
1768    if y_is_modelt and x_is_modelt:
1769        # 3. Both canonical coercion failed, but both are module elements.
1770        # Try base extending the right object by the parent of the left
1771
1772        ## TODO -- WORRY -- only unambiguous if one succeeds!
1773        if  PY_TYPE_CHECK(x, RingElement):
1774            try:
1775                return x * y.base_extend((<RingElement>x)._parent)
1776            except (TypeError, AttributeError), msg:
1777                pass
1778        # Also try to base extending the left object by the parent of the right
1779        if  PY_TYPE_CHECK(y, RingElement):
1780            try:
1781                return y * x.base_extend((<Element>y)._parent)
1782            except (TypeError, AttributeError), msg:
1783                pass
1784
1785    # 4. Try _l_action or _r_action.
1786    # Test to see if an _r_action or _l_action is
1787    # defined on either side.
1788    try:
1789        return x._l_action(y)
1790    except (AttributeError, TypeError):   
1791        pass
1792    try:
1793        return y._r_action(x)
1794    except (AttributeError, TypeError):
1795        pass
1796
1797    raise TypeError, arith_error_message(x,y,op)
1798
1799def coerce_cmp(x,y): 
1800    cdef int c
1801    try:
1802        x, y = canonical_coercion_c(x, y)
1803        return cmp(x,y)       
1804    except TypeError:
1805        c = cmp(type(x), type(y))
1806        if c == 0: c = -1
1807        return c
1808
1809
1810
1811###############################################################################
1812
1813def lcm(x,y):
1814    from sage.rings.arith import lcm
1815    return lcm(x,y)
1816
1817def gcd(x,y):
1818    from sage.rings.arith import gcd
1819    return gcd(x,y)
1820
1821def xgcd(x,y):
1822    from sage.rings.arith import xgcd
1823    return xgcd(x,y)
1824
Note: See TracBrowser for help on using the repository browser.