From 81202466fdccd470fd0a45923817e7fbb74f59da Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 17 Jul 2017 15:30:05 +0200 Subject: [PATCH] Various Cython fixes --- src/sage/algebras/free_algebra_element.py | 34 +++---- .../lie_algebras/lie_algebra_element.pxd | 4 + .../lie_algebras/lie_algebra_element.pyx | 9 +- .../modules/with_basis/indexed_element.pxd | 11 +-- .../modules/with_basis/indexed_element.pyx | 90 ++++++++++++------- 5 files changed, 86 insertions(+), 62 deletions(-) diff --git a/src/sage/algebras/free_algebra_element.py b/src/sage/algebras/free_algebra_element.py index 9aaa39fa91a..40f3370e29f 100644 --- a/src/sage/algebras/free_algebra_element.py +++ b/src/sage/algebras/free_algebra_element.py @@ -40,7 +40,6 @@ from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement from sage.combinat.free_module import CombinatorialFreeModule from sage.structure.element import AlgebraElement -from sage.structure.richcmp import richcmp import six @@ -49,6 +48,18 @@ class FreeAlgebraElement(IndexedFreeModuleElement, AlgebraElement): """ A free algebra element. + + TESTS: + + The ordering is inherited from ``IndexedFreeModuleElement``:: + + sage: R. = FreeAlgebra(QQ,2) + sage: x < y + True + sage: x * y < y * x + True + sage: y * x < x * y + False """ def __init__(self, A, x): """ @@ -172,27 +183,6 @@ def extract_from(kwds,g): return self.parent()(0) return result - def _richcmp_(left, right, op): - """ - Compare two free algebra elements with the same parents. - - The ordering is the one on the underlying sorted list of - (monomial,coefficients) pairs. - - EXAMPLES:: - - sage: R. = FreeAlgebra(QQ,2) - sage: x < y - True - sage: x * y < y * x - True - sage: y * x < x * y - False - """ - v = sorted(left._monomial_coefficients.items()) - w = sorted(right._monomial_coefficients.items()) - return richcmp(v, w, op) - def _mul_(self, y): """ Return the product of ``self`` and ``y`` (another free algebra diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pxd b/src/sage/algebras/lie_algebras/lie_algebra_element.pxd index c9a6484ea63..5c7305aaf60 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pxd +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pxd @@ -21,6 +21,10 @@ cdef class UntwistedAffineLieAlgebraElement(Element): cdef _d_coeff cdef long _hash + cpdef _add_(self, other) + cpdef _sub_(self, other) + cpdef _neg_(self) + cpdef dict t_dict(self) cpdef c_coefficient(self) cpdef d_coefficient(self) diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx index 7f7a0ecc102..261af36856e 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx @@ -560,6 +560,7 @@ cdef class StructureCoefficientsElement(LieAlgebraMatrixWrapper): """ return self.value[self._parent._indices.index(i)] + cdef class UntwistedAffineLieAlgebraElement(Element): """ An element of an untwisted affine Lie algebra. @@ -798,9 +799,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): """ return bool(self._t_dict) or bool(self._c_coeff) or bool(self._d_coeff) - __bool__ = __nonzero__ - - cdef _add_(self, other): + cpdef _add_(self, other): """ Add ``self`` and ``other``. @@ -816,7 +815,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): self._c_coeff + rt._c_coeff, self._d_coeff + rt._d_coeff) - cdef _sub_(self, other): + cpdef _sub_(self, other): """ Subtract ``self`` and ``other``. @@ -838,7 +837,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): self._c_coeff - rt._c_coeff, self._d_coeff - rt._d_coeff) - cdef _neg_(self): + cpdef _neg_(self): """ Negate ``self``. diff --git a/src/sage/modules/with_basis/indexed_element.pxd b/src/sage/modules/with_basis/indexed_element.pxd index e4825c8ab22..b2f4988fcc3 100644 --- a/src/sage/modules/with_basis/indexed_element.pxd +++ b/src/sage/modules/with_basis/indexed_element.pxd @@ -1,12 +1,13 @@ -from sage.structure.element cimport Element, RingElement +from sage.structure.element cimport Element, ModuleElement -cdef class IndexedFreeModuleElement(Element): +cdef class IndexedFreeModuleElement(ModuleElement): cdef public dict _monomial_coefficients cdef long _hash cdef bint _hash_set + cpdef _add_(self, other) + cpdef _sub_(self, other) + cpdef _neg_(self) + cpdef dict monomial_coefficients(self, bint copy=*) cpdef _coefficient_fast(self, m) - cpdef _lmul_(self, Element right) - cpdef _rmul_(self, Element left) - diff --git a/src/sage/modules/with_basis/indexed_element.pyx b/src/sage/modules/with_basis/indexed_element.pyx index 7152fad7da2..1dcf6689fd1 100644 --- a/src/sage/modules/with_basis/indexed_element.pyx +++ b/src/sage/modules/with_basis/indexed_element.pyx @@ -17,12 +17,10 @@ AUTHORS: # http://www.gnu.org/licenses/ #***************************************************************************** -from __future__ import print_function - -from six import iteritems +from __future__ import absolute_import, division, print_function from sage.structure.element cimport parent -from sage.structure.richcmp cimport richcmp, richcmp_not_equal, rich_to_bool +from sage.structure.richcmp cimport richcmp, rich_to_bool from cpython.object cimport Py_NE, Py_EQ from sage.misc.misc import repr_lincomb @@ -33,7 +31,7 @@ from sage.typeset.unicode_art import UnicodeArt, empty_unicode_art from sage.categories.all import Category, Sets, ModulesWithBasis from sage.data_structures.blas_dict cimport add, negate, scal, axpy -cdef class IndexedFreeModuleElement(Element): +cdef class IndexedFreeModuleElement(ModuleElement): def __init__(self, M, x): """ Create a combinatorial module element. This should never be @@ -49,7 +47,7 @@ cdef class IndexedFreeModuleElement(Element): sage: f == loads(dumps(f)) True """ - Element.__init__(self, M) + ModuleElement.__init__(self, M) self._monomial_coefficients = x self._hash_set = False @@ -131,7 +129,7 @@ cdef class IndexedFreeModuleElement(Element): hash value of the parent. See :trac:`15959`. """ if not self._hash_set: - self._hash = hash(frozenset(self._monomial_coefficients.items())) + self._hash = hash(frozenset(self._monomial_coefficients.iteritems())) self._hash_set = True return self._hash @@ -180,7 +178,7 @@ cdef class IndexedFreeModuleElement(Element): 2*B['x'] + 2*B['y'] """ self._set_parent(state[0]) - for k, v in iteritems(state[1]): + for k, v in state[1].iteritems(): setattr(self, k, v) cpdef dict monomial_coefficients(self, bint copy=True): @@ -250,7 +248,7 @@ cdef class IndexedFreeModuleElement(Element): .. SEEALSO:: :meth:`_repr_`, :meth:`_latex_`, :meth:`print_options` """ print_options = self._parent.print_options() - v = self._monomial_coefficients.items() + v = list(self._monomial_coefficients.iteritems()) try: v.sort(key=lambda monomial_coeff: print_options['sorting_key'](monomial_coeff[0]), @@ -556,17 +554,21 @@ cdef class IndexedFreeModuleElement(Element): sage: TestSuite(F).run() """ cdef IndexedFreeModuleElement elt = other - if op in [Py_EQ, Py_NE]: - return richcmp(self._monomial_coefficients, elt._monomial_coefficients, op) if self._monomial_coefficients == elt._monomial_coefficients: return rich_to_bool(op, 0) - v = sorted(self._monomial_coefficients.items()) - w = sorted(elt._monomial_coefficients.items()) - return richcmp_not_equal(v, w, op) + # Not equal + if op == Py_EQ: + return False + if op == Py_NE: + return True + + v = sorted(self._monomial_coefficients.iteritems()) + w = sorted(elt._monomial_coefficients.iteritems()) + return richcmp(v, w, op) - cdef _add_(self, other): + cpdef _add_(self, other): """ EXAMPLES:: @@ -588,7 +590,7 @@ cdef class IndexedFreeModuleElement(Element): add(self._monomial_coefficients, (other)._monomial_coefficients)) - cdef _neg_(self): + cpdef _neg_(self): """ EXAMPLES:: @@ -606,7 +608,7 @@ cdef class IndexedFreeModuleElement(Element): """ return type(self)(self._parent, negate(self._monomial_coefficients)) - cdef _sub_(self, other): + cpdef _sub_(self, other): """ EXAMPLES:: @@ -771,11 +773,11 @@ cdef class IndexedFreeModuleElement(Element): TESTS:: sage: F.get_action(QQ, operator.mul, True) - Right action by Rational Field on Free module generated by {'a', 'b', 'c'} over Rational Field + Right scalar multiplication by Rational Field on Free module generated by {'a', 'b', 'c'} over Rational Field sage: F.get_action(QQ, operator.mul, False) - Left action by Rational Field on Free module generated by {'a', 'b', 'c'} over Rational Field + Left scalar multiplication by Rational Field on Free module generated by {'a', 'b', 'c'} over Rational Field sage: F.get_action(ZZ, operator.mul, True) - Right action by Integer Ring on Free module generated by {'a', 'b', 'c'} over Rational Field + Right scalar multiplication by Integer Ring on Free module generated by {'a', 'b', 'c'} over Rational Field sage: F.get_action(F, operator.mul, True) sage: F.get_action(F, operator.mul, False) @@ -840,7 +842,7 @@ cdef class IndexedFreeModuleElement(Element): """ return self._acted_upon_(left, False) - def __truediv__(self, x): + def __truediv__(left, x): """ Division by coefficients. @@ -848,7 +850,8 @@ cdef class IndexedFreeModuleElement(Element): sage: F = CombinatorialFreeModule(QQ, [1,2,3]) sage: x = F._from_dict({1:2, 2:3}) - sage: x/2 + sage: from operator import truediv + sage: truediv(x, 2) B[1] + 3/2*B[2] :: @@ -856,20 +859,47 @@ cdef class IndexedFreeModuleElement(Element): sage: F = CombinatorialFreeModule(QQ, [1,2,3]) sage: B = F.basis() sage: f = 2*B[2] + 4*B[3] - sage: f/2 + sage: truediv(f, 2) B[2] + 2*B[3] + + TESTS:: + + sage: truediv(x, x) + Traceback (most recent call last): + ... + TypeError: unable to convert 2*B[1] + 3*B[2] to a rational + sage: truediv("hello", x) + Traceback (most recent call last): + ... + TypeError: unsupported operand type(s) for /: 'str' and 'CombinatorialFreeModule_with_category.element_class' """ - F = parent(self) - if not self.base_ring().is_field(): - return type(self)(F, {k: c._divide_if_possible(x) - for k,c in self._monomial_coefficients.iteritems()}) + if not isinstance(left, IndexedFreeModuleElement): + return NotImplemented - x = self.base_ring()( x ) - x_inv = x ** -1 + cdef IndexedFreeModuleElement self = left + F = self._parent + B = self.base_ring() D = self._monomial_coefficients + if not B.is_field(): + return type(self)(F, {k: c._divide_if_possible(x) + for k, c in D.iteritems()}) + + x_inv = B(x) ** -1 return type(self)(F, scal(x_inv, D)) - __div__ = __truediv__ + def __div__(left, right): + """ + Forward old-style division to true division. + + EXAMPLES:: + + sage: F = CombinatorialFreeModule(QQ, [1,2,3]) + sage: x = F._from_dict({1:2, 2:3}) + sage: x/2 + B[1] + 3/2*B[2] + """ + return left / right + def _unpickle_element(C, d): """