source: sage/structure/coerce.pxi @ 6677:9c883622ea09

Revision 6677:9c883622ea09, 5.1 KB checked in by Robert Bradshaw <robertwb@…>, 6 years ago (diff)

Inplace operations for various rings

Line 
1# These are shared inline functions.
2
3#################################################################################
4# fast tests to verify no coersion is needed
5#################################################################################
6
7cdef inline bint have_same_parent(left, right):
8    """
9    Return nonzero true value if and only if left and right are
10    elements and have the same parent.
11    """
12    # (We know at least one of the arguments is an Element. So if
13    # their types are *equal* (fast to check) then they are both
14    # Elements.  Otherwise use the slower test via PY_TYPE_CHECK.)
15    if PY_TYPE(left) is PY_TYPE(right):
16        return (<Element>left)._parent is (<Element>right)._parent
17       
18    if PY_TYPE_CHECK(right, Element) and PY_TYPE_CHECK(left, Element):
19        return (<Element>left)._parent is (<Element>right)._parent
20
21    return 0
22
23cdef inline _verify_canonical_coercion_c(x, y):
24    if not have_same_parent(x,y):
25        raise RuntimeError, """There is a bug in the coercion code in SAGE.
26Both x (=%s) and y (=%s) are supposed to have identical parents but they don't.
27In fact, x has parent '%s'
28whereas y has parent '%s'"""%(x,y,parent_c(x),parent_c(y))
29    return x, y
30
31cdef inline bint have_same_base(Element x, Element y):
32    return x._parent._base is y._parent._base
33           
34#################################################################################
35# parent
36#################################################################################
37cdef inline parent_c(x):
38    if PY_TYPE_CHECK(x,Element):
39        return (<Element>x)._parent
40    elif hasattr(x, 'parent'):
41        return x.parent()
42    else:
43        return <object>PY_TYPE(x)
44
45def parent(x):
46    return parent_c(x)
47   
48#################################################################################
49# operators
50#################################################################################
51
52cdef add, sub, mul, div, iadd, isub, imul, idiv
53from operator import add, sub, mul, div, iadd, isub, imul, idiv
54
55cdef inline inplace_op(op):
56    return operator.__dict__['i'+op.__name__]
57
58cdef inline no_inplace_op(op):
59    return operator.__dict__[op.__name__[1:]]
60
61#################################################################################
62# errors
63#################################################################################
64cdef D = {'mul':'*', 'add':'+', 'sub':'-', 'div':'/', 'imul': '*', 'iadd': '+', 'isub':'-', 'idiv':'/'}
65
66cdef inline arith_error_message(x, y, op):
67        try:
68            n = D[op.__name__]
69        except KeyError:
70            n = op.__name__
71        return "unsupported operand parent(s) for '%s': '%s' and '%s'"%(n, parent_c(x), parent_c(y))
72
73#################################################################################
74# Inline arithmatic dispatchers for ModuleElements and RingElements
75#################################################################################
76
77cdef inline ModuleElement _add_c(ModuleElement left, ModuleElement right):
78    if HAS_DICTIONARY(left):
79        return left._add_(right)
80    else:
81        return left._add_c_impl(right)
82       
83cdef inline ModuleElement _iadd_c(ModuleElement left, ModuleElement right):
84    if HAS_DICTIONARY(left):
85        return left._iadd_(right)
86    else:
87        return left._iadd_c_impl(right)
88
89cdef inline ModuleElement _sub_c(ModuleElement left, ModuleElement right):
90    if HAS_DICTIONARY(left):
91        return left._sub_(right)
92    else:
93        return left._sub_c_impl(right)
94       
95cdef inline ModuleElement _isub_c(ModuleElement left, ModuleElement right):
96    if HAS_DICTIONARY(left):
97        return left._isub_(right)
98    else:
99        return left._isub_c_impl(right)
100
101# rmul -- left * self
102cdef inline ModuleElement _rmul_c(ModuleElement right, RingElement left):
103    if HAS_DICTIONARY(right):
104        return right._rmul_(left)
105    else:
106        return right._rmul_c_impl(left)
107
108# lmul -- self * right
109cdef inline ModuleElement _lmul_c(ModuleElement left, RingElement right):
110    if HAS_DICTIONARY(left):
111        return left._lmul_(right)
112    else:
113        return left._lmul_c_impl(right)
114
115# ilmul -- inplace self * right
116cdef inline ModuleElement _ilmul_c(ModuleElement self, RingElement right):
117    if HAS_DICTIONARY(self):
118        return self._ilmul_(right)
119    else:
120        return self._ilmul_c_impl(right)
121
122cdef inline RingElement _mul_c(RingElement left, RingElement right):
123    if HAS_DICTIONARY(left):
124        return left._mul_(right)
125    else:
126        return left._mul_c_impl(right)
127       
128cdef inline RingElement _imul_c(RingElement left, RingElement right):
129    if HAS_DICTIONARY(left):
130        return left._imul_(right)
131    else:
132        return left._imul_c_impl(right)
133
134cdef inline RingElement _div_c(RingElement left, RingElement right):
135    if HAS_DICTIONARY(left):
136        return left._div_(right)
137    else:
138        return left._div_c_impl(right)
139       
140cdef inline RingElement _idiv_c(RingElement left, RingElement right):
141    if HAS_DICTIONARY(left):
142        return left._idiv_(right)
143    else:
144        return left._idiv_c_impl(right)
145
146cdef enum:
147    # 3 references: handle, scope container, and arithmatic call stack
148    inplace_threshold = 3
149   
150
Note: See TracBrowser for help on using the repository browser.