Ask Your Question
1

Coercion not commutative

asked 2021-09-01 12:50:04 +0200

philipp7 gravatar image

I implemented a new algebraic structure A, derived from CommutativeAlgebra (over the rationals QQ) with element class Aelement derived from CommutativeAlgebraElement. The method A._element_constructor_ can, in particular, coerce an element from QQ into an element Aelement and this works fine if done explicitly. Also if I multiply an element from A with an element from QQ from the right-hand side everything works and the rational number is properly coerced to A. However, if I multiply an element from QQ with an element from A I get an error and the coercion does not work:

sage: A(QQ(2)) # works
sage: C.has_coerce_map_from(QQ)
True
sage: A.an_element()*QQ(2) # works
sage: ZZ(2)*A.an_element() # works
sage: QQ(2)*A.an_element() # does not work

The last call yields the error:

~/sage-9.2/local/lib/python3.8/site-packages/sage/rings/rational.pyx in sage.rings.rational.Rational.__mul__ (build/cythonized/sage/rings/rational.c:20912)()
   2399             return x
   2400 
-> 2401         return coercion_model.bin_op(left, right, operator.mul)
   2402 
   2403     cpdef _mul_(self, right):

~/sage-9.2/local/lib/python3.8/site-packages/sage/structure/coerce.pyx in sage.structure.coerce.CoercionModel.bin_op (build/cythonized/sage/structure/coerce.c:11304)()
   1246         # We should really include the underlying error.
   1247         # This causes so much headache.
-> 1248         raise bin_op_exception(op, x, y)
   1249 
   1250     cpdef canonical_coercion(self, x, y):

TypeError: unsupported operand parent(s) for *: 'Rational Field' and 'A'

Does someone know what the problem could be? If no one has an idea, I will try to provide a minimal example which exhibits the error. Thank you!

edit retag flag offensive close merge delete

Comments

Could you please provide the whole code so that we can reproduce ?

tmonteil gravatar imagetmonteil ( 2021-09-01 15:53:51 +0200 )edit

I will try to provide a minimal example which shows the error tomorrow.

philipp7 gravatar imagephilipp7 ( 2021-09-01 16:23:34 +0200 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2021-09-02 13:17:49 +0200

philipp7 gravatar image

The mistake was quite stupid: The structure A is defined over some base ring. For checking equality of the algebraic structures I used:

def __eq__(self, right):
    try:
        return self.base_ring() == right.base_ring()
    except:
        return False

However, since QQ.base_ring() is QQ, this meant that A over QQ and QQ itself were considered equal. Hence, sage thought there is also a coercion from A to QQ (and not only from QQ to A). Therefore, for QQ(2)*A.an_element() sage tried to convert A.an_element() to a rational which failed. On the other hand, A.an_element()*QQ(2) worked because QQ(2) could indeed be converted to an element of A. My fix was to simply change the equality function to something like

def __eq__(self, right):
    if not isinstance(right, A) :
        return False
    try:
        return self.base_ring() == right.base_ring()
    except:
        return False
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2021-09-01 12:50:04 +0200

Seen: 44 times

Last updated: Sep 02