Ask Your Question
2

Add a personnal coercion rule

asked 14 years ago

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

Preview: (hide)

3 Answers

Sort by » oldest newest most voted
5

answered 14 years ago

DSM gravatar image

updated 14 years ago

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.

Preview: (hide)
link
0

answered 14 years ago

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

Laurent

Preview: (hide)
link
0

answered 14 years ago

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)
Preview: (hide)
link

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: 14 years ago

Seen: 594 times

Last updated: Jan 26 '11