| 1 | # These are shared inline functions. |
|---|
| 2 | |
|---|
| 3 | ################################################################################# |
|---|
| 4 | # fast tests to verify no coersion is needed |
|---|
| 5 | ################################################################################# |
|---|
| 6 | |
|---|
| 7 | cdef 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 | |
|---|
| 23 | cdef 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. |
|---|
| 26 | Both x (=%s) and y (=%s) are supposed to have identical parents but they don't. |
|---|
| 27 | In fact, x has parent '%s' |
|---|
| 28 | whereas y has parent '%s'"""%(x,y,parent_c(x),parent_c(y)) |
|---|
| 29 | return x, y |
|---|
| 30 | |
|---|
| 31 | cdef inline bint have_same_base(Element x, Element y): |
|---|
| 32 | return x._parent._base is y._parent._base |
|---|
| 33 | |
|---|
| 34 | ################################################################################# |
|---|
| 35 | # parent |
|---|
| 36 | ################################################################################# |
|---|
| 37 | cdef 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 | |
|---|
| 45 | def parent(x): |
|---|
| 46 | return parent_c(x) |
|---|
| 47 | |
|---|
| 48 | ################################################################################# |
|---|
| 49 | # operators |
|---|
| 50 | ################################################################################# |
|---|
| 51 | |
|---|
| 52 | cdef add, sub, mul, div, iadd, isub, imul, idiv |
|---|
| 53 | from operator import add, sub, mul, div, iadd, isub, imul, idiv |
|---|
| 54 | |
|---|
| 55 | cdef inline inplace_op(op): |
|---|
| 56 | return operator.__dict__['i'+op.__name__] |
|---|
| 57 | |
|---|
| 58 | cdef inline no_inplace_op(op): |
|---|
| 59 | return operator.__dict__[op.__name__[1:]] |
|---|
| 60 | |
|---|
| 61 | ################################################################################# |
|---|
| 62 | # errors |
|---|
| 63 | ################################################################################# |
|---|
| 64 | cdef D = {'mul':'*', 'add':'+', 'sub':'-', 'div':'/', 'imul': '*', 'iadd': '+', 'isub':'-', 'idiv':'/'} |
|---|
| 65 | |
|---|
| 66 | cdef 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 | |
|---|
| 77 | cdef 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 | |
|---|
| 83 | cdef 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 | |
|---|
| 89 | cdef 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 | |
|---|
| 95 | cdef 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 |
|---|
| 102 | cdef 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 |
|---|
| 109 | cdef 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 |
|---|
| 116 | cdef 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 | |
|---|
| 122 | cdef 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 | |
|---|
| 128 | cdef 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 | |
|---|
| 134 | cdef 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 | |
|---|
| 140 | cdef 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 | |
|---|
| 146 | cdef enum: |
|---|
| 147 | # 3 references: handle, scope container, and arithmatic call stack |
|---|
| 148 | inplace_threshold = 3 |
|---|
| 149 | |
|---|
| 150 | |
|---|