Inheritance from sage.symbolic.expression.Expression

15 views
Skip to first unread message

Nicolas

unread,
Jun 11, 2009, 10:07:50 AM6/11/09
to sage-support
Hi all,

I am trying, in sage 4.0, to write a class that inherits from the new
sage.symbolic.expression.Expression class. I have not found any
precise signature for the __init__ method of that class so I suppose I
am doing something wrong : things seem to work, except for the
substitute stuff.

Here is an example of what I mean :

______________________________________
class test(Expression):
def __init__(self,eq):
Expression.__init__(self,SR,eq)

f=function("f")
g=function("g")
a=f(x)
b=test(f(x))
testa=a.substitute_function(f,g)
testb=b.substitute_function(f,g)
______________________________________
sage: testa
g(x)
sage: testb
f(x)
sage:

Anyone to help me out ?

Thanks to all

Burcin Erocal

unread,
Jun 11, 2009, 11:12:57 AM6/11/09
to sage-s...@googlegroups.com
Hi Nicolas,

I don't think the __init__ function in Expression is usable as it is.
Here is the code:

def __init__(self, SR, x=0):
cdef GEx exp
GEx_construct_pyobject(exp, x)
GEx_construct_ex(&self._gobj, exp)
self._parent = SR

The line with GEx_construct_pyobject() coerces the symbolic expression
you give it to a constant numeric object. Then, in your construction, b
becomes a constant.

sage: b.operator() # this returns None since it's a constant
sage: t.operator()
f


After applying the patch below, the following works:

----------------------------------------------------------------------
| Sage Version 4.0.1, Release Date: 2009-06-06 |
| Type notebook() for the GUI, and license() for information. |
----------------------------------------------------------------------
Loading Sage library. Current Mercurial branch is: la
sage: from sage.symbolic.expression import Expression
sage: class esub(Expression):
....: def __init__(self, parent, val):
....: Expression.__init__(self, parent, val)
....:
sage: f = function('f')
sage: g = function('g')
sage: t = f(x)
sage: b = esub(SR, t)
sage: b.substitute_function(f, g)
g(x)


This still doesn't solve your problem though, most methods of
Expression will return Expression objects.

sage: type(b.substitute_function(f, g))
<type 'sage.symbolic.expression.Expression'>


Can you explain your application a little?

Cheers,
Burcin

diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
--- a/sage/symbolic/expression.pyx
+++ b/sage/symbolic/expression.pyx
@@ -212,9 +212,8 @@
sage: sage.symbolic.expression.Expression(SR, 5)
5
"""
- cdef GEx exp
- GEx_construct_pyobject(exp, x)
- GEx_construct_ex(&self._gobj, exp)
+ cdef Expression exp = self.coerce_in(x)
+ GEx_construct_ex(&self._gobj, exp._gobj)
self._parent = SR

def __dealloc__(self):

Nicolas

unread,
Jun 11, 2009, 11:38:07 AM6/11/09
to sage-support
Hi Burcin

I am still in sage-4.0... The 4.0.1 is currently building.
I am writing a piece of software whose purpose is to analyse a set of
given equations to transform them into Cellular Automata to solve
differential problems right from the formal expression. You can get
details there : http://intercell.metz.supelec.fr and there :
http://intercell.metz.supelec.fr/depot/InterCell/escapade2.handout.pdf

I have written in sage.3.4 a class that inherited from
SymbolicArithmetic (and used the __init__ as follows) :
_____________________
if is_SymbolicExpression(eq):
eq=(eq==0)
# SymbolicArithmetic.__init__(self,[eq,
0],operator.add)
SymbolicArithmetic.__init__(self,[eq.lhs
(),eq.rhs()],operator.sub)
elif is_SymbolicEquation(eq):
SymbolicArithmetic.__init__(self,[eq.lhs
(),eq.rhs()],operator.sub)
elif ((eq==0)|(type(eq)==bool)):# a special treatment
for the 0==0 equation
SymbolicArithmetic.__init__(self,
[x,x],operator.sub)
else:
print('arguments must be SymbolicExpression or
SymbolicEquation')
____________________

As you see, I have used a few dirty tricks to work around a few bugs
but it worked.

My purpose is to add to this inherited class a few methods that will
analyse this equation (count the functions in, determine their
arguments, translate them...), but I definitely need to use the base
functions of symbolic arithmetic. I must thus find a way to correctly
init a subclass of Expression.

By the way, I also found a few other things that did not work with
this __init__ method, see :
________________________
sage: a=(x==1)
sage: b=(x==2)
sage: a+b
2*x == 3
sage: a=test(x==1)
sage: b=test(x==2)
sage: a+b
2*x == 3
sage: a=(x==1)
sage: b=test(x==2)
sage: a+b
x == (x + 1 == 3)
________________________

strange, huh ?

I will try out your patch. Why do you say that does not solve my
problem ?

Thanks

Nicolas

Nicolas

unread,
Jun 12, 2009, 5:09:08 AM6/12/09
to sage-support
Dear Burcin,

Just one quick question about patches, I have just changed the
expression.pyx file and ran another make (which took not so much
time). But it does not seem to work. Is this simple way of applying
patch enough or do I have to go through the mercurial system ?

Thanks !

On 11 juin, 17:12, Burcin Erocal <bur...@erocal.org> wrote:
Message has been deleted

Mike Hansen

unread,
Jun 12, 2009, 5:21:47 AM6/12/09
to sage-s...@googlegroups.com
Hello,

On Fri, Jun 12, 2009 at 2:09 AM, Nicolas<nicolas.f...@gmail.com> wrote:
>
> Dear Burcin,
>
> Just one quick question about patches, I have just changed the
> expression.pyx file and ran another make (which took not so much
> time).

After you make the change to the file, just run "sage -br" (for build
and run) to compile your changes and make them active.

--Mike

Burcin Erocal

unread,
Jun 12, 2009, 5:22:27 AM6/12/09
to sage-s...@googlegroups.com
Hi Nicolas,

On Fri, 12 Jun 2009 02:09:08 -0700 (PDT)
Nicolas <nicolas.f...@gmail.com> wrote:

> Just one quick question about patches, I have just changed the
> expression.pyx file and ran another make (which took not so much
> time). But it does not seem to work. Is this simple way of applying
> patch enough or do I have to go through the mercurial system ?

You need to do

./sage -br


From your other message:


> I will try out your patch. Why do you say that does not solve my
> problem ?

You'll see that whenever you perform arithmetic on the new objects,
you'll end up with Expression's again.

< assuming the class esub was defined as in my previous message >
sage: var('x,y,z')
(x, y, z)
sage: t = x * y^z
sage: u = esub(SR, t)
sage: u
y^z*x
sage: type(u)
<class '__main__.esub'>
sage: type(u*u)
<type 'sage.symbolic.expression.Expression'>


Let's see how far you get with the patch. I'll try to see if there is
a simple fix to make Expression behave well w.r.t. object oriented
design.


Cheers,
Burcin

Nicolas

unread,
Jun 15, 2009, 10:06:13 AM6/15/09
to sage-support
Dear Burcin

Thanks for all
It seems the patch works fine for my application, at least this is
what the first tests says !

I will get back to here if I see issues

Nicolas

On 12 juin, 11:22, Burcin Erocal <bur...@erocal.org> wrote:
> Hi Nicolas,
>
> On Fri, 12 Jun 2009 02:09:08 -0700 (PDT)
>

Nicolas

unread,
Jun 18, 2009, 3:12:34 PM6/18/09
to sage-support
Dear Burcin,

After thorough tests, your patch works pretty well !
I have just encountered a problem with pickling (and thus the save
function).
There is a workaround by using the __repr__ function for file saving
but this requires parsing after loading.

Here is the behavior of save in sage.4.0.1 with the patch applied :

----------------------------------------------------------------------
| Sage Version 4.0.1, Release Date: 2009-06-06 |
| Type notebook() for the GUI, and license() for information. |
----------------------------------------------------------------------
sage: class esub(Expression):
....: def __init__(self, parent, val):
....: Expression.__init__(self, parent, val)
....:
sage: a=esub(SR,x)
sage: a
x
sage: save(x,"file")
sage: save(a,"file")
---------------------------------------------------------------------------
PicklingError Traceback (most recent call
last)

/home/fresseng/.sage/temp/nix.sciences.univ_metz.fr/24993/
_home_fresseng__sage_init_sage_0.py in <module>()

/usr/local/src/sage-4.0.1/local/lib/python2.5/site-packages/sage/
structure/sage_object.so in sage.structure.sage_object.save (sage/
structure/sage_object.c:6832)()

/usr/local/src/sage-4.0.1/local/lib/python2.5/site-packages/sage/
structure/sage_object.so in sage.structure.sage_object.SageObject.save
(sage/structure/sage_object.c:1866)()

/usr/local/src/sage-4.0.1/local/lib/python2.5/site-packages/sage/
structure/sage_object.so in
sage.structure.sage_object.SageObject.dumps (sage/structure/
sage_object.c:2080)()

PicklingError: Can't pickle <class '__main__.esub'>: attribute lookup
__main__.esub failed


In my opinion, this should work. Am I wrong ? Is there a special
method to implement in the extension class esub ?

Thanks for your help !

Nicolas

On 12 juin, 11:22, Burcin Erocal <bur...@erocal.org> wrote:
> Hi Nicolas,
>
> On Fri, 12 Jun 2009 02:09:08 -0700 (PDT)
>
Reply all
Reply to author
Forward
0 new messages