Ask Your Question

Add a personnal coercion rule

asked 2011-01-24 05:53:09 -0600

Hi all !

For some reasons I have to use a class MyAngle which basically describes an angle, but with some personal methods.

Obviously, sage's cos function cannot take an instance of my class as argument.


#! /usr/bin/sage -python
# -*- coding: utf8 -*-

from sage.all import *

class MyAngle(object):
    def __init__(self,value):



Traceback (most recent call last):
  File "function.pyx", line 733, in sage.symbolic.function.GinacFunction.__call__   (sage/symbolic/function.cpp:6572)
  File "function.pyx", line 417, in sage.symbolic.function.Function.__call__ (sage/symbolic    /function.cpp:4336)
TypeError: cannot coerce arguments: no canonical coercion from <class '__main__.MyAngle'> to Symbolic Ring

What do I have to add to my class to make Sage's cosine understand that when x=MyAngle(pi/2),




I found that, but I didn't helped me so much.

Thanks for help ! have a good night Laurent

edit retag flag offensive close merge delete

3 answers

Sort by » oldest newest most voted

answered 2011-01-25 20:09:21 -0600

Thanks for the idea of subclassing Expression. I'll dig in that direction.


edit flag offensive delete link more

answered 2011-01-24 16:31:53 -0600

DSM gravatar image

updated 2011-01-24 18:08:09 -0600

You only mention cos, but presumably there are other things you're going to want to do with your angles: sin, tan, add them, subtract them, convert them to floats, possibly simplify them, and so on. That's a lot of hassle to implement, so instead let's subclass the built-in Expression class and let it do most of the work.

class FixedValue(Expression):
    def __init__(self, value):
        Expression.__init__(self, SR, value)
    def new_method(self, *args):
        print self, args

sage: x = FixedValue(pi/2)
sage: x
sage: cos(x), sin(x), tan(x), float(x), complex(x)
(0, 1, Infinity, 1.5707963267948966, (1.5707963267948966+0j))
sage: x+x, x*3, simplify(exp(x*I))
(pi, 3/2*pi, I)
sage: x.new_method(99, 'fred')
1/2*pi (99, 'fred')

Note that the above doesn't store a copy of its value in ".value"; you can simply refer to the object itself. If you do store a copy you have to worry about them getting out of sync. Also note that while the above makes it easy to operate on these objects, the result of an operation won't be an instance of the class (e.g. x*1 is an Expression, not a FixedValue), but you can easily coerce back, or we can work around it if necessary.

edit flag offensive delete link more

answered 2011-01-24 06:47:19 -0600

Shashank gravatar image

Cos is defined for float only. So you can use the following code.

from sage.all import *

class MyAngle(object):
    def __init__(self,value):
    def cos(self):
edit flag offensive delete link more

Your Answer


Add Answer

Question Tools


Asked: 2011-01-24 05:53:09 -0600

Seen: 246 times

Last updated: Jan 25 '11