On Wed, 20 Jul 2011 17:02:49 -0700 (PDT)
Steven Pollack <stevenlawr...@gmail.com> wrote:
> I noticed that a thread was developed for this sort of thing (http://
> groups.google.com/group/sage-support/browse_thread/thread/
> d50dc3bc2bdbeab0/34798c0585fc034f?lnk=gst&q=nicolas&fwc=1#), but I'm a
> newbie, and a lot of it went over my head.
>
> Is there a simple to create a subclass of
> sage.symbolic.expression.Expression?
The main problem with subclassing Expression is that the result
returned from arithmetic is hardcoded to be an Expression again.
I quickly did a search and replace in the sage/symbolics directory to
pass the new class as an argument to the fast expression constructor
new_Expression_from_GEx. Here is the patch:
http://sage.math.washington.edu/home/burcin/subclass_expression.patch
After applying the patch the following works:
sage: class new_exp(Expression):
....: pass
....:
sage: t = new_exp(SR, x)
sage: t
x
sage: type(t)
<class '__main__.new_exp'>
sage: u = t*t
sage: type(u)
<class '__main__.new_exp'>
sage: u
x^2
Hope this helps.
Burcin
Note that many of the low-level classes, such as Integers and perhaps
Expressions, were not designed with sublcassing in mind. YMMV, but
this is often a problem of OOP in general.
> The main problem with subclassing Expression is that the result
> returned from arithmetic is hardcoded to be an Expression again.
>
> I quickly did a search and replace in the sage/symbolics directory to
> pass the new class as an argument to the fast expression constructor
> new_Expression_from_GEx. Here is the patch:
>
> http://sage.math.washington.edu/home/burcin/subclass_expression.patch
>
> After applying the patch the following works:
>
> sage: class new_exp(Expression):
> ....: pass
> ....:
> sage: t = new_exp(SR, x)
> sage: t
> x
> sage: type(t)
> <class '__main__.new_exp'>
> sage: u = t*t
> sage: type(u)
> <class '__main__.new_exp'>
> sage: u
> x^2
Any performance cost?
- Robert
I'm curious; could you write a sentence or two more about why this is
often a problem of OOP in general? I would have thought it would be a
strength of OOP in general.
Jason
Without the patch:
sage: %timeit v = [-pi,-pi+1/100000..,pi]
5 loops, best of 3: 1.4 s per loop
With the patch:
sage: %timeit v = [-pi,-pi+1/100000..,pi]
5 loops, best of 3: 1.62 s per loop
Cheers,
Burcin
> Is the syntax for this class
>
> t = new_exp(SR, symbolic_expression)?
>
> So that sage: t returns symbolic_expression?
t is an instance of new_exp, which inherits from Expression. The value
of the internal GiNaC object stored in both is determined by the second
argument.
You could define other member functions or store attributes in your
class. Though you need to take care what happens to the attributes
when you do any arithmetic.
sage: class new_exp(Expression):
def __init__(self, parent, value, attribute):
self.attr = attribute
super(self.__class__, self).__init__(parent, value)
....:
sage: t = new_exp(SR, x, 2)
sage: t
x
sage: t.attr
2
sage: t.new_method(5)
x - 5
sage: u = t+t
sage: u.new_method(5)
2*x - 5
sage: u.attr
<snip>
AttributeError: 'new_exp' object has no attribute 'attr'
sage: type(u)
<class '__main__.new_exp'>
sage: u
2*x
sage: v = u/2
sage: v.new_method(5)
x - 5
sage: v.attr
<snip>
AttributeError: 'new_exp' object has no attribute 'attr'
> Second, I'm not entirely sure I understand how this patch was made,
> let alone how to install it. I skimmed over
> http://www.sagemath.org/doc/developer/patching_spkgs.html and
> http://www.sagemath.org/doc/developer/producing_spkgs.html#chapter-spkg
> but found the whole thing to be a bit over my head (I'm a newbie,
> sorry).
>
> Is there a series of instructions you could provide me for the
> installation of your patch? I'm sure you're very busy, so I really do
> appreciate the effort.
You need to look at a different section of the guide:
http://sagemath.org/doc/developer/walk_through.html
Here is a quick summary:
- Go to your SAGE_ROOT, the base directory of your sage installation
- Go to the directory with the sage library sources
cd devel/sage
- import the patch into a patch queue
hg qimport <URL_of_patch>
- apply the patch
hg qpush
- go back to SAGE_ROOT
cd ../..
- build the library with changes
./sage -b
- start Sage and enjoy
./sage
Cheers,
Burcin