Changeset 6660:333f153e3474
- Timestamp:
- 09/05/07 20:04:21 (6 years ago)
- Branch:
- default
- Location:
- sage/structure
- Files:
-
- 4 edited
-
coerce.pxi (modified) (2 diffs)
-
coerce.pyx (modified) (1 diff)
-
element.pxd (modified) (3 diffs)
-
element.pyx (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
sage/structure/coerce.pxi
r6655 r6660 58 58 return "unsupported operand parent(s) for '%s': '%s' and '%s'"%(n, parent_c(x), parent_c(y)) 59 59 60 ################################################################################# 61 # Inline arithmatic dispatchers for ModuleElements and RingElements 62 ################################################################################# 63 60 64 cdef inline ModuleElement _add_c(ModuleElement left, ModuleElement right): 61 65 if HAS_DICTIONARY(left): … … 69 73 else: 70 74 return left._iadd_c_impl(right) 75 76 cdef inline ModuleElement _sub_c(ModuleElement left, ModuleElement right): 77 if HAS_DICTIONARY(left): 78 return left._sub_(right) 79 else: 80 return left._sub_c_impl(right) 81 82 cdef inline ModuleElement _isub_c(ModuleElement left, ModuleElement right): 83 if HAS_DICTIONARY(left): 84 return left._isub_(right) 85 else: 86 return left._isub_c_impl(right) 87 88 # rmul -- left * self 89 cdef inline ModuleElement _rmul_c(ModuleElement right, RingElement left): 90 if HAS_DICTIONARY(right): 91 return right._rmul_(left) 92 else: 93 return right._rmul_c_impl(left) 94 95 # lmul -- self * right 96 cdef inline ModuleElement _lmul_c(ModuleElement left, RingElement right): 97 if HAS_DICTIONARY(left): 98 return left._lmul_(right) 99 else: 100 return left._lmul_c_impl(right) 101 102 # ilmul -- inplace self * right 103 cdef inline ModuleElement _ilmul_c(ModuleElement self, RingElement right): 104 if HAS_DICTIONARY(self): 105 return self._ilmul_(right) 106 else: 107 return self._ilmul_c_impl(right) 108 109 cdef inline RingElement _mul_c(RingElement left, RingElement right): 110 if HAS_DICTIONARY(left): 111 return left._mul_(right) 112 else: 113 return left._mul_c_impl(right) 114 115 cdef inline RingElement _imul_c(RingElement left, RingElement right): 116 if HAS_DICTIONARY(left): 117 return left._imul_(right) 118 else: 119 return left._imul_c_impl(right) 120 121 cdef inline RingElement _div_c(RingElement left, RingElement right): 122 if HAS_DICTIONARY(left): 123 return left._div_(right) 124 else: 125 return left._div_c_impl(right) 126 127 cdef inline RingElement _idiv_c(RingElement left, RingElement right): 128 if HAS_DICTIONARY(left): 129 return left._idiv_(right) 130 else: 131 return left._idiv_c_impl(right) 132 133 cdef enum: 134 # 3 references: handle, scope container, and arithmatic call stack 135 inplace_threshold = 0 -
sage/structure/coerce.pyx
r6659 r6660 243 243 244 244 cdef bin_op_c(self, x, y, op): 245 246 if (op is not op_add) and (op is not op_sub) and (op is not op_iadd) and not (op is not op_isub): 245 if (op is not op_add) and (op is not op_sub) and (op is not op_iadd) and (op is not op_isub): 247 246 # Actions take preference over common-parent coercions. 248 247 xp = parent_c(x) -
sage/structure/element.pxd
r6655 r6660 36 36 cdef class ModuleElement(Element): 37 37 cdef ModuleElement _add_c(self, ModuleElement right) # do *NOT* override, but OK to call directly 38 cdef ModuleElement _iadd_c(self, ModuleElement right) # do *NOT* override, but OK to call directly39 38 cdef ModuleElement _sub_c(self, ModuleElement right) # do *NOT* override, but OK to call directly 40 39 cdef ModuleElement _neg_c(self) # do *NOT* override, but OK to call directly … … 45 44 46 45 cdef ModuleElement _add_c_impl(self, ModuleElement right) # OK to override, but do NOT call 47 cdef ModuleElement _iadd_c_impl(self, ModuleElement right) # OK to override, but do NOT call48 46 cdef ModuleElement _sub_c_impl(self, ModuleElement right) # OK to override, but do NOT call 49 47 cdef ModuleElement _neg_c_impl(self) # OK to override, but do *NOT* call directly 50 48 cdef ModuleElement _lmul_c_impl(self, RingElement right) # OK to override, but do *NOT* call directly 51 49 cdef ModuleElement _rmul_c_impl(self, RingElement left) # OK to override, but do *NOT* call directly 50 51 # Inplace operations, override, do *NOT* call directly 52 cdef ModuleElement _iadd_c_impl(self, ModuleElement right) 53 cdef ModuleElement _isub_c_impl(self, ModuleElement right) 54 cdef ModuleElement _ilmul_c_impl(self, RingElement right) 52 55 53 56 # Coerce x to the base ring of self and return the result. … … 86 89 cdef RingElement _div_c_impl(self, RingElement right) # OK to override, but do *NOT* call directly 87 90 91 # Inplace operations, override, do *NOT* call directly 92 cdef RingElement _imul_c_impl(self, RingElement right) 93 cdef RingElement _idiv_c_impl(self, RingElement right) 94 88 95 cdef class CommutativeRingElement(RingElement): 89 96 pass -
sage/structure/element.pyx
r6655 r6660 152 152 implementations of either _add_ or _add_c_impl. 153 153 154 155 For speed, there are also {\bf inplace} version of the arithmatic commands. 156 DD NOT call them directly, they may mutate the object and will be called 157 when and only when it has been determined that the old object will no longer 158 be accessible from the calling function after this operation. 159 160 {\bf def RingElement._iadd_} 161 162 This is the function you should override to inplace implement addition 163 in a python subclass of RingElement. 164 165 WARNING: if you override this in a *pyrex* class, it won't get called. 166 You should override _iadd_c_impl instead. It is especially important to 167 keep this in mind whenever you move a class down from python to pyrex. 168 169 The two arguments to this function are guaranteed to have the 170 SAME PARENT. Its return value MUST have the SAME PARENT as its 171 arguments. 172 173 The default implementation of this function is to call _add_c_impl, 174 so if no-one has defined a python implementation, the correct pyrex 175 implementation will get called. 176 177 {\bf cdef RingElement._iadd_c_impl} 178 179 This is the function you should override to inplace implement addition 180 in a pyrex subclass of RingElement. 181 182 The two arguments to this function are guaranteed to have the 183 SAME PARENT. Its return value MUST have the SAME PARENT as its 184 arguments. 185 186 The default implementation of this function is to call _add_c 187 154 188 """ 155 189 … … 648 682 # ModuleElements. Otherwise use the slower test via PY_TYPE_CHECK.) 649 683 if have_same_parent(left, right): 650 if (<RefPyObject *>left).ob_refcnt <= 2: 651 # This is a temporary variable (incref due to calling, and at the top of this fn). 652 return (<ModuleElement>left)._iadd_c(<ModuleElement>right) 684 # If we hold the only references to this object, we can 685 # safely mutate it. NOTE the threshold is different by one 686 # for __add__ and __iadd__. 687 if (<RefPyObject *>left).ob_refcnt < inplace_threshold: 688 return _iadd_c(<ModuleElement>left, <ModuleElement>right) 653 689 else: 654 return (<ModuleElement>left)._add_c(<ModuleElement>right)690 return _add_c(<ModuleElement>left, <ModuleElement>right) 655 691 global coercion_model 656 692 return coercion_model.bin_op_c(left, right, operator.add) 657 693 658 def __iadd__(ModuleElement self, right):659 if have_same_parent(self, right):660 if (<RefPyObject *>self).ob_refcnt <= 3:661 return self._iadd_c(<ModuleElement>right)662 else:663 return self._add_c(right)664 else:665 global coercion_model666 return coercion_model.bin_op_c(self, right, operator.iadd)667 668 cdef ModuleElement _iadd_c(self, ModuleElement right):669 if HAS_DICTIONARY(self):670 return self._iadd_(right)671 else:672 return self._iadd_c_impl(right)673 674 def _iadd_(self, right):675 return self._iadd_c_impl(right)676 677 cdef ModuleElement _iadd_c_impl(self, ModuleElement right):678 return self._add_c(right)679 680 681 694 cdef ModuleElement _add_c(left, ModuleElement right): 682 695 """ … … 718 731 return left._add_c_impl(right) 719 732 733 def __iadd__(ModuleElement self, right): 734 if have_same_parent(self, right): 735 if (<RefPyObject *>self).ob_refcnt <= inplace_threshold: 736 return _iadd_c(<ModuleElement>self, <ModuleElement>right) 737 else: 738 return _add_c(<ModuleElement>self, <ModuleElement>right) 739 else: 740 global coercion_model 741 return coercion_model.bin_op_c(self, right, operator.iadd) 742 743 def _iadd_(self, right): 744 return self._iadd_c_impl(right) 745 746 cdef ModuleElement _iadd_c_impl(self, ModuleElement right): 747 return self._add_c(right) 748 720 749 ################################################## 721 750 # Subtraction … … 728 757 """ 729 758 if have_same_parent(left, right): 730 return (<ModuleElement>left)._sub_c(<ModuleElement>right) 759 if (<RefPyObject *>left).ob_refcnt < inplace_threshold: 760 return _isub_c(<ModuleElement>left, <ModuleElement>right) 761 else: 762 return _sub_c(<ModuleElement>left, <ModuleElement>right) 731 763 global coercion_model 732 764 return coercion_model.bin_op_c(left, right, operator.sub) … … 769 801 return left._sub_c_impl(right) 770 802 803 804 def __isub__(ModuleElement self, right): 805 if have_same_parent(self, right): 806 if (<RefPyObject *>self).ob_refcnt <= inplace_threshold: 807 return _isub_c(<ModuleElement>self, <ModuleElement>right) 808 else: 809 return _sub_c(<ModuleElement>self, <ModuleElement>right) 810 else: 811 global coercion_model 812 return coercion_model.bin_op_c(self, right, operator.isub) 813 814 def _isub_(self, right): 815 return self._isub_c_impl(right) 816 817 cdef ModuleElement _isub_c_impl(self, ModuleElement right): 818 return self._sub_c(right) 819 771 820 ################################################## 772 821 # Negation … … 959 1008 return self._lmul_c_impl(right) 960 1009 1010 cdef ModuleElement _ilmul_c_impl(self, RingElement right): 1011 return _lmul_c(self, right) 1012 961 1013 cdef RingElement coerce_to_base_ring(self, x): 962 1014 if PY_TYPE_CHECK(x, Element) and (<Element>x)._parent is self._parent._base: … … 1246 1298 ################################## 1247 1299 1248 # The default behavior for scalars is just to coerce into the parent ring.1249 1300 cdef ModuleElement _lmul_c_impl(self, RingElement right): 1301 # We raise an error to invoke the default action of coercing into self 1250 1302 raise NotImplementedError, "parents %s %s %s" % (parent_c(self), parent_c(right), parent_c(self) is parent_c(right)) 1251 # return self._mul_c(<RingElement>(self._parent._coerce_c(right)))1252 1303 1253 1304 cdef ModuleElement _rmul_c_impl(self, RingElement left): 1305 # We raise an error to invoke the default action of coercing into self 1254 1306 raise NotImplementedError 1255 # return (<RingElement>(self._parent._coerce_c(left)))._mul_c(self) 1256 1307 1257 1308 def __mul__(self, right): 1258 1309 """ … … 1365 1416 1366 1417 """ 1367 global coercion_model1368 1418 # Try fast pathway if they are both RingElements and the parents match. 1369 1419 # (We know at least one of the arguments is a RingElement. So if their … … 1371 1421 # Otherwise use the slower test via PY_TYPE_CHECK.) 1372 1422 if have_same_parent(self, right): 1373 return (<RingElement>self)._mul_c(<RingElement>right) 1374 1375 if not (PY_TYPE_CHECK(self, Element) and PY_TYPE_CHECK(right, Element)): 1376 # one of self or right is not even an Element. 1377 return coercion_model.bin_op_c(self, right, operator.mul) 1378 1423 if (<RefPyObject *>self).ob_refcnt < inplace_threshold: 1424 return _imul_c(<RingElement>self, <RingElement>right) 1425 else: 1426 return _mul_c(<RingElement>self, <RingElement>right) 1427 1379 1428 # Always do this 1429 global coercion_model 1380 1430 return coercion_model.bin_op_c(self, right, operator.mul) 1381 1431 … … 1450 1500 return self._mul_c_impl(right) 1451 1501 1502 def __imul__x(left, right): 1503 if have_same_parent(left, right): 1504 if (<RefPyObject *>left).ob_refcnt <= inplace_threshold: 1505 return _imul_c(<RingElement>left, <RingElement>right) 1506 else: 1507 return _mul_c(<RingElement>left, <RingElement>right) 1508 1509 global coercion_model 1510 return coercion_model.bin_op_c(left, right, operator.imul) 1511 1512 def _imul_(self, right): 1513 return self._imul_c_impl(right) 1514 1515 cdef RingElement _imul_c_impl(RingElement self, RingElement right): 1516 return _mul_c(self, right) 1517 1452 1518 def __pow__(self, n, dummy): 1453 1519 """ … … 1503 1569 """ 1504 1570 if have_same_parent(self, right): 1505 return (<RingElement>self)._div_c(<RingElement>right) 1571 if (<RefPyObject *>self).ob_refcnt < inplace_threshold: 1572 return _idiv_c(<RingElement>self, <RingElement>right) 1573 else: 1574 return _div_c(<RingElement>self, <RingElement>right) 1575 global coercion_model 1506 1576 return coercion_model.bin_op_c(self, right, operator.div) 1507 1508 1577 1509 1578 … … 1539 1608 return self._div_c_impl(right) 1540 1609 1610 def __idiv__(self, right): 1611 """ 1612 Top-level multiplication operator for ring elements. 1613 See extensive documentation at the top of element.pyx. 1614 """ 1615 if have_same_parent(self, right): 1616 if (<RefPyObject *>self).ob_refcnt <= inplace_threshold: 1617 return _idiv_c(<RingElement>self, <RingElement>right) 1618 else: 1619 return _div_c(<RingElement>self, <RingElement>right) 1620 global coercion_model 1621 return coercion_model.bin_op_c(self, right, operator.idiv) 1622 1623 def _idiv_(self, right): 1624 return self._idiv_c_impl(right) 1625 1626 cdef RingElement _idiv_c_impl(RingElement self, RingElement right): 1627 return _div_c(self, right) 1628 1541 1629 def __pos__(self): 1542 1630 return self
Note: See TracChangeset
for help on using the changeset viewer.
