Ask Your Question
2

Add a personnal coercion rule

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

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.

SAGE

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

from sage.all import *

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

x=MyAngle(pi/2)
cos(x)

ERROR

Traceback (most recent call last):
File "./sagess.py", line 11, in <module>
    cos(x)
  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),

cos(x)

means

cos(x.value)

I found that, but I didn't helped me so much. http://www.sagemath.org/doc/developer...

Thanks for help ! have a good night Laurent

edit retag flag offensive close merge delete

3 answers

Sort by ยป oldest newest most voted
4

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

DSM gravatar image

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

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
1/2*pi
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
0

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

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

Laurent

edit flag offensive delete link more
0

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

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):
        self.value=value
    def cos(self):
        return(n(cos(self.value)))
x=MyAngle(4/2)
cos(x)
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

Stats

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

Seen: 197 times

Last updated: Jan 25 '11