substitution in and integration of piecewise functions

76 views
Skip to first unread message

Ondrej Certik

unread,
Nov 24, 2008, 6:19:55 AM11/24/08
to sage-support
Hi,

when I use regular expressions, I can use .subs():

sage: e = x+y
sage: e.subs(x=y)
2*y

but not with Piecewise:

sage: var("h H x y")
(h, H, x, y)
sage: u = Piecewise([((0, h), x/h), ((h, H), 1)])
sage: u.subs(x=y)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)

/home/ondra/ext/sage-3.1.2-debian32-intel-i686-Linux/<ipython console>
in <module>()

AttributeError: PiecewisePolynomial instance has no attribute 'subs'


Ok. Now I'd like to integrate that:

sage: u.integral()
TypeError: Computation failed since Maxima requested additional
constraints (use assume):
Is h positive, negative, or zero?

sage: assume(h>0)
sage: u.integral()
TypeError: Computation failed since Maxima requested additional
constraints (use assume):
Is ?h+h positive, negative, or zero?


What does "?h+h" mean?

sage: u.integral(x)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)

/home/ondra/ext/sage-3.1.2-debian32-intel-i686-Linux/<ipython console>
in <module>()

/home/ondra/ext/sage-3.1.2-debian32-intel-i686-Linux/local/lib/python2.5/site-packages/sage/functions/piecewise.py
in integral(self, x)
647 invs = self.intervals()
648 n = len(funcs)
--> 649 return sum([funcs[i].integral(x,invs[i][0],invs[i][1])
for i in range(n)])
650
651 def convolution(self,other):

AttributeError: 'sage.rings.integer.Integer' object has no attribute 'integral'

Am I doing something wrong, or is it just not implemented yet? What is
the plan of implementing this in pynac?

For comparison, in sympy you can do this:

In [1]: var("h")
Out[1]: h

In [2]: u = Piecewise( (0, x<=0), (1, x>=h), (x/h, True))

In [3]: integrate(u, x)
Out[3]:
⎧ 0 for x ≤ 0

⎪ x for h ≤ x

⎨ 2
⎪ x
⎪─── otherwise
⎪2⋅h


Substitution works like this:

In [4]: e = (u-u.subs(x, y))**2/(x-y)**2

In [5]: e
Out[5]:
2
⎛- ⎧0 for y ≤ 0 + ⎧0 for x ≤ 0⎞
⎜ ⎪ ⎪ ⎟
⎜ ⎪1 for h ≤ y ⎪1 for h ≤ x⎟
⎜ ⎨ ⎨ ⎟
⎜ ⎪y ⎪x ⎟
⎜ ⎪─ otherwise ⎪─ otherwise⎟
⎝ ⎩h ⎩h ⎠
──────────────────────────────────
2
(x - y)


Now I'd like to integrate the resulting expression and that doesn't
yet work in sympy:

http://code.google.com/p/sympy/issues/detail?id=1214

so I was curious what is Sage's strategy to handle Piecewise functions
in a regular symbolic expression.


Ondrej

Burcin Erocal

unread,
Nov 24, 2008, 7:07:18 AM11/24/08
to sage-s...@googlegroups.com
On Mon, 24 Nov 2008 12:19:55 +0100
"Ondrej Certik" <ond...@certik.cz> wrote:

> Hi,
>
> when I use regular expressions, I can use .subs():
>
> sage: e = x+y
> sage: e.subs(x=y)
> 2*y
>
> but not with Piecewise:
>
> sage: var("h H x y")
> (h, H, x, y)
> sage: u = Piecewise([((0, h), x/h), ((h, H), 1)])
> sage: u.subs(x=y)
> ---------------------------------------------------------------------------
> AttributeError Traceback (most recent call
> last)
>
> /home/ondra/ext/sage-3.1.2-debian32-intel-i686-Linux/<ipython console>
> in <module>()
>
> AttributeError: PiecewisePolynomial instance has no attribute 'subs'

This means that substitution is simply not implemented for piecewise
functions. I suppose no one needed this until now.

<snip>


> Am I doing something wrong, or is it just not implemented yet? What is
> the plan of implementing this in pynac?

I don't see how pynac is relevant here. Pynac will only provide a
different internal format for representing symbolic expressions, the
piecewise class will still be the same.

You can open a trac ticket if you need this functionality. It is safe
to change piecewise.py, and add a .subs() method. Since the user
interface for the pynac expressions will be almost the same as the
current ones, it should still work when the underlying representation
changes.


Cheers,

Burcin

David Joyner

unread,
Nov 24, 2008, 7:25:41 AM11/24/08
to sage-s...@googlegroups.com
On Mon, Nov 24, 2008 at 6:19 AM, Ondrej Certik <ond...@certik.cz> wrote:
> Hi,
>
> when I use regular expressions, I can use .subs():
>
> sage: e = x+y
> sage: e.subs(x=y)
> 2*y
>
> but not with Piecewise:
>
> sage: var("h H x y")
> (h, H, x, y)
> sage: u = Piecewise([((0, h), x/h), ((h, H), 1)])


I don't think variable endpoints are implemented in Sage's Piecewise.
Maybe one could add a method="sympy" option to use sympy's
Piecewise in place of the Maxima interface?

Ondrej Certik

unread,
Nov 24, 2008, 8:04:53 AM11/24/08
to sage-s...@googlegroups.com
On Mon, Nov 24, 2008 at 1:25 PM, David Joyner <wdjo...@gmail.com> wrote:
> On Mon, Nov 24, 2008 at 6:19 AM, Ondrej Certik <ond...@certik.cz> wrote:
>> Hi,
>>
>> when I use regular expressions, I can use .subs():
>>
>> sage: e = x+y
>> sage: e.subs(x=y)
>> 2*y
>>
>> but not with Piecewise:
>>
>> sage: var("h H x y")
>> (h, H, x, y)
>> sage: u = Piecewise([((0, h), x/h), ((h, H), 1)])
>
>
> I don't think variable endpoints are implemented in Sage's Piecewise.
> Maybe one could add a method="sympy" option to use sympy's
> Piecewise in place of the Maxima interface?

Well, even fixed endpoints doesn't seem to work properly:

sage: u = Piecewise([((0, 1), x/h), ((1, 2), 1)])
sage: u**2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)

/home/ondra/ext/sage-3.1.4-debian32-IntelXeon-x86-i686-Linux/<ipython
console> in <module>()

/home/ondra/ext/sage/local/lib/python2.5/site-packages/sage/rings/integer.so
in sage.rings.integer.Integer.__pow__ (sage/rings/integer.c:9379)()

TypeError: unsupported operand type(s) for ** or pow(): 'instance' and 'int'


> I don't see how pynac is relevant here. Pynac will only provide a
> different internal format for representing symbolic expressions, the
> piecewise class will still be the same.

Well, if you want to do stuff like u**2, where u is piecewise, or use
the .subs() that is implemented in the symbolic engine, you can either
implement everything by hand (e.g. implement .subs(), implement
__pow__, ...), but that's imho not the way, or, you can integrate it
inside the symbolic engine, so that you can manipulate with it like
with any other function -- that's the approach we took with sympy.

>
> You can open a trac ticket if you need this functionality. It is safe
> to change piecewise.py, and add a .subs() method. Since the user
> interface for the pynac expressions will be almost the same as the
> current ones, it should still work when the underlying representation
> changes.

I think it should be discussed more first. My vision is that the
symbolic engine should treat everything as first class citizens ---
e.g. if you make series expansion, it does the right thing.

Well, I just found series expansion of piecewise functions doesn't
work in sympy. :)

http://code.google.com/p/sympy/issues/detail?id=1216

But you see the pattern --- we just override the
Piecewise._eval_nseries() and it will start working.

btw. it doesn't work in Sage either:

sage: taylor(u, x, 0.5)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)

/home/ondra/ext/sage-3.1.4-debian32-IntelXeon-x86-i686-Linux/<ipython
console> in <module>()

TypeError: taylor() takes exactly 4 arguments (3 given)
sage: taylor(u, x, 0.5, 4)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)

/home/ondra/ext/sage-3.1.4-debian32-IntelXeon-x86-i686-Linux/<ipython
console> in <module>()

/home/ondra/ext/sage/local/lib/python2.5/site-packages/sage/calculus/functional.pyc
in taylor(f, v, a, n)
332 """
333 if not isinstance(f, SymbolicExpression):
--> 334 f = SR(f)
335 return f.taylor(v=v,a=a,n=n)
336

/home/ondra/ext/sage/local/lib/python2.5/site-packages/sage/calculus/calculus.pyc
in __call__(self, x)
452 msg, s, pos = err.args
453 raise TypeError, "%s: %s !!! %s" % (msg,
s[:pos], s[pos:])
--> 454 return self._coerce_impl(x)
455
456 def _coerce_impl(self, x):

/home/ondra/ext/sage/local/lib/python2.5/site-packages/sage/calculus/calculus.pyc
in _coerce_impl(self, x)
508 return self(x._sage_())
509 else:
--> 510 raise TypeError, "cannot coerce type '%s' into a
SymbolicExpression."%type(x)
511
512 def _repr_(self):

TypeError: cannot coerce type '<type 'instance'>' into a SymbolicExpression.

So imho it is related to pynac, because if you use ginac's series
expansion, it should be able to handle Piecewise. If you choose to
implement series expansion yourself (that's what we did in sympy), you
need to integrate Piecewise in somehow.


Ondrej

David Joyner

unread,
Nov 24, 2008, 8:15:15 AM11/24/08
to sage-s...@googlegroups.com
On Mon, Nov 24, 2008 at 7:25 AM, David Joyner <wdjo...@gmail.com> wrote:
> On Mon, Nov 24, 2008 at 6:19 AM, Ondrej Certik <ond...@certik.cz> wrote:
>> Hi,
>>
>> when I use regular expressions, I can use .subs():
>>
>> sage: e = x+y
>> sage: e.subs(x=y)
>> 2*y
>>
>> but not with Piecewise:
>>
>> sage: var("h H x y")
>> (h, H, x, y)
>> sage: u = Piecewise([((0, h), x/h), ((h, H), 1)])
>
>
> I don't think variable endpoints are implemented in Sage's Piecewise.
> Maybe one could add a method="sympy" option to use sympy's
> Piecewise in place of the Maxima interface?
>

Replying to my own post:
I am happy to copy my code over to sympy's piecewise class
(or have someone else do it). In other words, even though it is
GPL'd I'm happy to relicense it under BSD for sympy, if there is
any interest. I might have time for that over the winter break.

Ondrej Certik

unread,
Nov 24, 2008, 8:27:04 AM11/24/08
to sage-s...@googlegroups.com
On Mon, Nov 24, 2008 at 2:15 PM, David Joyner <wdjo...@gmail.com> wrote:
> On Mon, Nov 24, 2008 at 7:25 AM, David Joyner <wdjo...@gmail.com> wrote:
>> On Mon, Nov 24, 2008 at 6:19 AM, Ondrej Certik <ond...@certik.cz> wrote:
>>> Hi,
>>>
>>> when I use regular expressions, I can use .subs():
>>>
>>> sage: e = x+y
>>> sage: e.subs(x=y)
>>> 2*y
>>>
>>> but not with Piecewise:
>>>
>>> sage: var("h H x y")
>>> (h, H, x, y)
>>> sage: u = Piecewise([((0, h), x/h), ((h, H), 1)])
>>
>>
>> I don't think variable endpoints are implemented in Sage's Piecewise.
>> Maybe one could add a method="sympy" option to use sympy's
>> Piecewise in place of the Maxima interface?
>>
>
> Replying to my own post:
> I am happy to copy my code over to sympy's piecewise class
> (or have someone else do it). In other words, even though it is
> GPL'd I'm happy to relicense it under BSD for sympy, if there is
> any interest. I might have time for that over the winter break.

Thanks! Btw, feel free to take any code from sympy as well and
incorporate it in Sage. But it's a design issue --- I want to work on
these things with Sage together, because clearly currently we have
two, incompatible Piecewise functions implementations, and neither in
Sage nor in sympy it works 100%.

Ondrej

Burcin Erocal

unread,
Nov 24, 2008, 9:08:01 AM11/24/08
to sage-s...@googlegroups.com

Again, this is not implemented, patches are welcome.

> > I don't see how pynac is relevant here. Pynac will only provide a
> > different internal format for representing symbolic expressions, the
> > piecewise class will still be the same.
>
> Well, if you want to do stuff like u**2, where u is piecewise, or use
> the .subs() that is implemented in the symbolic engine, you can either
> implement everything by hand (e.g. implement .subs(), implement
> __pow__, ...), but that's imho not the way, or, you can integrate it
> inside the symbolic engine, so that you can manipulate with it like
> with any other function -- that's the approach we took with sympy.

Are you saying that your class which represents a piecewise function
doesn't implement it's .subs() method, which in turn calls the .subs()
methods of each of the pieces (and the endpoints in your case)?
Similarly for the __pow__ method.

Can you explain your design a little?

> >
> > You can open a trac ticket if you need this functionality. It is
> > safe to change piecewise.py, and add a .subs() method. Since the
> > user interface for the pynac expressions will be almost the same as
> > the current ones, it should still work when the underlying
> > representation changes.
>
> I think it should be discussed more first. My vision is that the
> symbolic engine should treat everything as first class citizens ---
> e.g. if you make series expansion, it does the right thing.

Note that in the design of GiNaC, which AFAIK, you also follow in SymPy,
these methods, e.g., arithmetic, substitution, etc. are implemented in
each class of the hierarchy.

I don't see why building on this hierarchy using python after a certain
point is a problem.

> Well, I just found series expansion of piecewise functions doesn't
> work in sympy. :)
>
> http://code.google.com/p/sympy/issues/detail?id=1216
>
> But you see the pattern --- we just override the
> Piecewise._eval_nseries() and it will start working.

Same in Sage. I don't see your point.

> btw. it doesn't work in Sage either:
>
> sage: taylor(u, x, 0.5)
> ---------------------------------------------------------------------------
> TypeError Traceback (most recent call
> last)

<...>


> TypeError: cannot coerce type '<type 'instance'>' into a
> SymbolicExpression.

Can you open a ticket and list these things you found that don't work
with piecewise functions. I.e.,

- substitutions
- __pow__
- series expansion

> So imho it is related to pynac, because if you use ginac's series
> expansion, it should be able to handle Piecewise. If you choose to
> implement series expansion yourself (that's what we did in sympy), you
> need to integrate Piecewise in somehow.

Pynac will only provide the basic operations one needs from
symbolic expressions as a library. This is quite similar to your
efforts of implementing a sympy core in Cython.

http://groups.google.com/group/sympy/browse_thread/thread/aa3f4263bc3f7e23

The road plan for SymPy says this will be included in version 0.7:

http://wiki.sympy.org/wiki/Plan_for_SymPy_1.0

So I really don't see what you mean above.


From another message:


On Mon, 24 Nov 2008 14:27:04 +0100
"Ondrej Certik" <ond...@certik.cz> wrote:
>
> Thanks! Btw, feel free to take any code from sympy as well and
> incorporate it in Sage. But it's a design issue --- I want to work on
> these things with Sage together, because clearly currently we have
> two, incompatible Piecewise functions implementations, and neither in
> Sage nor in sympy it works 100%.
>

Piecewise functions are a great example of a way SymPy and Sage can work
together. Since the interfaces to the underlying symbolic expressions
are the same, the same python implementation can be used for both the
projects. If SymPy had a stable and fast core at the moment, I don't
see why Sage couldn't use that as the basis for symbolics either.

Unfortunately, I don't think it is possible to share all symbolics
code between SymPy and Sage. Since for more advanced algorithms, such
as summation and integration (I don't mean just pattern matching, or
table lookups), you also need fast polynomials, gcd's, linear algebra,
etc. I don't see how SymPy can provide the same performance for these,
using pure python, or it's own cython implementations.


Cheers,

Burcin

P.S. At the moment, I am writing a wrapper for FLINT's zmod_poly_t
polynomials for Sage, which I need for an algorithm to compute kernels
of matrices over Q(x), which I need for my summation code.

Ondrej Certik

unread,
Nov 24, 2008, 11:06:58 AM11/24/08
to sage-s...@googlegroups.com

No, it does implement exactly that.

Actually, because of docstrings (and possibly changing the interface
of things to the end user), we have one .subs() method implemented in
Basic, with a nice docstring and the subclasses (including Piecewise)
just implement _eval_subs(). The user is supposed to just call
.subs(). But that's minor.

But in pynac, so do you call ginac's subs method, or do you implement
it on your own? I know you can pass Sage objects inside ginac, thanks
to cython. I just want to clarify this is what you do.

> Similarly for the __pow__ method.

We only implement __pow__ in Basic by default. The subclasses can
override it for efficiency reasons, but don't have to.

>
> Can you explain your design a little?

Yes -- please ask if more clarification is needed besides the above.

>
>> >
>> > You can open a trac ticket if you need this functionality. It is
>> > safe to change piecewise.py, and add a .subs() method. Since the
>> > user interface for the pynac expressions will be almost the same as
>> > the current ones, it should still work when the underlying
>> > representation changes.
>>
>> I think it should be discussed more first. My vision is that the
>> symbolic engine should treat everything as first class citizens ---
>> e.g. if you make series expansion, it does the right thing.
>
> Note that in the design of GiNaC, which AFAIK, you also follow in SymPy,
> these methods, e.g., arithmetic, substitution, etc. are implemented in
> each class of the hierarchy.

Some of, yes.

>
> I don't see why building on this hierarchy using python after a certain
> point is a problem.

It is not a problem, I am only curious if this is your plan.

Yes, that's the plan. Or, if we figure out how, I'd also be able to
use pynac. Even though from engineering point of view, every new
optional part of sympy adds a lot more work to test everything. So I
prefer to just have one core and stick to it.

>
> So I really don't see what you mean above.
>
>
> From another message:
> On Mon, 24 Nov 2008 14:27:04 +0100
> "Ondrej Certik" <ond...@certik.cz> wrote:
>>
>> Thanks! Btw, feel free to take any code from sympy as well and
>> incorporate it in Sage. But it's a design issue --- I want to work on
>> these things with Sage together, because clearly currently we have
>> two, incompatible Piecewise functions implementations, and neither in
>> Sage nor in sympy it works 100%.
>>
>
> Piecewise functions are a great example of a way SymPy and Sage can work
> together. Since the interfaces to the underlying symbolic expressions
> are the same, the same python implementation can be used for both the

Well, I don't think it could easily. So imagine you want to calculate
the series expansion of u**2, where u is a Piecewise function. How
will you do that technically with pynac/Sage?

> projects. If SymPy had a stable and fast core at the moment, I don't
> see why Sage couldn't use that as the basis for symbolics either.
>
> Unfortunately, I don't think it is possible to share all symbolics
> code between SymPy and Sage. Since for more advanced algorithms, such
> as summation and integration (I don't mean just pattern matching, or
> table lookups), you also need fast polynomials, gcd's, linear algebra,
> etc. I don't see how SymPy can provide the same performance for these,
> using pure python, or it's own cython implementations.

Right, so far we have all of this in pure Python. By using Cython in a
few critical places (polynomials, gcd, ...), I am sure we'll get
competitive performance. My view has always been it's better to get
some performance, than no performance. I am not against using a better
library optinally and we do use gmp optionally. In fact, our pi
calculating algorithm for a milion digits is 3x faster than in Sage
(unless you fixed that recently).

But I know what you mean --- in Sage you always use the best tool for
the job that is available out there right now and thus get the best
possible performance. The price for it is that then you depend on
everything.

> Cheers,
>
> Burcin
>
> P.S. At the moment, I am writing a wrapper for FLINT's zmod_poly_t
> polynomials for Sage, which I need for an algorithm to compute kernels
> of matrices over Q(x), which I need for my summation code.

Thanks for the long explanation. Well, but then the symbolics in Sage
couldn't be used without Sage. I do consider summation algorithms part
of the symbolic engine. As well as integration.

I am not saying it's bad -- I only want to better understand where
each approach is heading, and what advantages and disadvantages it
brings.

Thanks,
Ondrej

Robert Bradshaw

unread,
Nov 25, 2008, 5:41:43 AM11/25/08
to sage-s...@googlegroups.com

+1

>
>>
>> You can open a trac ticket if you need this functionality. It is safe
>> to change piecewise.py, and add a .subs() method. Since the user
>> interface for the pynac expressions will be almost the same as the
>> current ones, it should still work when the underlying representation
>> changes.
>
> I think it should be discussed more first. My vision is that the
> symbolic engine should treat everything as first class citizens ---
> e.g. if you make series expansion, it does the right thing.

One of the issues right now is that sage's piecewise is a completely
separate class then the rest of the calculus library. I think it
should descend from symbolic expression and be on the same level as,
e.g. sin and addition (and probably even have a pynac counterpart).
Letting the operands be the conditions (as symbolic equations, giving
much more flexibility then we now have) and the corresponding
expressions (as symbolic equations) would allow it to fit into the
symbolic ring nicely. This would have the advantage that one could
leverage all the generic SR functionality like subs, pow,
composition, etc. without having to re-implement it for every method
that's missing.

- Robert

Ondrej Certik

unread,
Nov 25, 2008, 6:15:41 AM11/25/08
to sage-s...@googlegroups.com
> One of the issues right now is that sage's piecewise is a completely
> separate class then the rest of the calculus library. I think it
> should descend from symbolic expression and be on the same level as,
> e.g. sin and addition (and probably even have a pynac counterpart).
> Letting the operands be the conditions (as symbolic equations, giving
> much more flexibility then we now have) and the corresponding
> expressions (as symbolic equations) would allow it to fit into the
> symbolic ring nicely. This would have the advantage that one could
> leverage all the generic SR functionality like subs, pow,
> composition, etc. without having to re-implement it for every method
> that's missing.

Exactly. In fact, that is how Piecewise works in sympy. So I think
pynac has to know how to properly dispatch stuff like .subs(),
.series() and other things into the Piecewise class (after it is
integrated into the calculus). And I know it is possible to do that
with Cython. Btw, how about pattern matching? Will you extend the C++
code in ginac to handle Piecewise functions?

The other option is to reimplement the .subs(), .series() and pattern
matching in Python. Burcin, please don't take my comments as sarcastic
--- I am really interested how to handle this and how to cooperate as
much as possible. Also, how will you approach to fix the bug in pynac
series I reported here:

http://groups.google.com/group/sage-devel/msg/a59f3c5d0586766b

E.g. will you fix ginac, or rather reimplement it in Cython/Python?
You can actually still use Maxima for that, so that's not a problem in
fact. And later just reimplement it in Python/Cython.

Ondrej

William Stein

unread,
Nov 25, 2008, 3:13:11 PM11/25/08
to sage-s...@googlegroups.com
On Tue, Nov 25, 2008 at 3:15 AM, Ondrej Certik <ond...@certik.cz> wrote:
>
>> One of the issues right now is that sage's piecewise is a completely
>> separate class then the rest of the calculus library. I think it

Just for the record, this is because Piecewise was implemented long
long ago by David Joyner, probably a year before any of the rest of
the calculus library was implemented. It definitely needs to be
somehow integrated better with the
calculus code as explained here.
--
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

David Joyner

unread,
Nov 25, 2008, 3:16:45 PM11/25/08
to sage-s...@googlegroups.com
On Tue, Nov 25, 2008 at 3:13 PM, William Stein <wst...@gmail.com> wrote:
>
> On Tue, Nov 25, 2008 at 3:15 AM, Ondrej Certik <ond...@certik.cz> wrote:
>>
>>> One of the issues right now is that sage's piecewise is a completely
>>> separate class then the rest of the calculus library. I think it
>
> Just for the record, this is because Piecewise was implemented long
> long ago by David Joyner, probably a year before any of the rest of
> the calculus library was implemented. It definitely needs to be
> somehow integrated better with the
> calculus code as explained here.


I'll try working on this some over the winter break, ie, in 2-3 weeks.

Burcin Erocal

unread,
Nov 25, 2008, 5:00:18 PM11/25/08
to sage-s...@googlegroups.com
On Tue, 25 Nov 2008 12:15:41 +0100
"Ondrej Certik" <ond...@certik.cz> wrote:

>
> > One of the issues right now is that sage's piecewise is a completely
> > separate class then the rest of the calculus library. I think it
> > should descend from symbolic expression and be on the same level as,
> > e.g. sin and addition (and probably even have a pynac counterpart).
> > Letting the operands be the conditions (as symbolic equations,
> > giving much more flexibility then we now have) and the corresponding
> > expressions (as symbolic equations) would allow it to fit into the
> > symbolic ring nicely. This would have the advantage that one could
> > leverage all the generic SR functionality like subs, pow,
> > composition, etc. without having to re-implement it for every method
> > that's missing.
>
> Exactly. In fact, that is how Piecewise works in sympy. So I think
> pynac has to know how to properly dispatch stuff like .subs(),
> .series() and other things into the Piecewise class (after it is
> integrated into the calculus). And I know it is possible to do that
> with Cython. Btw, how about pattern matching? Will you extend the C++
> code in ginac to handle Piecewise functions?

Ok. Now I see what you mean, first let me explain why I failed to
understand you before.

Sage treats piecewise functions as functions, and in Sage, once you
have a function, it remains a function even when you do arithmetic with
it, unless you apply it to values and get an expression. E.g.,

sage: var('x,y,z,n')
(x, y, z, n)
sage: f(x) = 2*x^n
sage: f
x |--> 2*x^n
sage: g = f + y; g
x |--> y + 2*x^n
sage: g.subs(x=z)
2*z^n + y
sage: e = g(x,z); e
y + 2*x^n
sage: type(e)
<class 'sage.calculus.calculus.SymbolicArithmetic'>

So, when we were talking about piecewise functions, I thought that
would also stay as a piecewise function object all along. No matter
what arithmetic you do with it.

When you start having piecewise (or conditional?) expressions, things
do get complicated as you have been trying to point out all this
time. :)


Note that we already call python functions from c++ in pynac. Just look
at the sage.symbolic.function.SFunction class. You can specify python
functions for evaluation, derivation, conjugation, etc. just as ginac
lets you do this with c++ functions.

sage: from sage.symbolic.function import function as nfunction
sage: var('x,y',ns=1)
(x, y)
sage: def npow(x, power_param=None): return x*power_param

sage: foo = nfunction("foo", 1, power_func=npow)
sage: foo(y)^(x+y)
(x + y)*y

sage: def nseries(*args, **kwds): return sum(args[0]^i for i in
range(kwds['order']))

sage: foo = nfunction("foo", 1, series_func=nseries)
sage: foo(y).series(y, 5)
y^4 + y^3 + y^2 + y + 1

Once a couple more glitches are fixed, this should allow people to
implement new special functions using only python.

It should be straightforward to add a new class to ginac, which also
dispatches substitution and pattern matching to custom functions as
well. I'll have to think more about the best way to do this.

As you might have noticed from the lack of progress on the pynac front,
I don't have much time to spend on pynac these days. I will have at
least a week to work on this in december, than more january. I hope to
have most of the lower level stuff sorted out by then, so we can start
moving things over to pynac.

> The other option is to reimplement the .subs(), .series() and pattern
> matching in Python. Burcin, please don't take my comments as sarcastic
> --- I am really interested how to handle this and how to cooperate as
> much as possible.

Thanks for pointing these out. I don't use symbolics much, and was
stuck with the idea of piecewise functions for some reason. I
guess I hadn't looked at your initial example carefully. So piecewise
functions are on my todo list now:

http://wiki.sagemath.org/symbolics/pynac_todo

Please suggest anything else that you think should be in there. I don't
use symbolics enough to know about different use cases and common
problems. Your experience here is definitely needed.


> Also, how will you approach to fix the bug in pynac
> series I reported here:
>
> http://groups.google.com/group/sage-devel/msg/a59f3c5d0586766b
>
> E.g. will you fix ginac, or rather reimplement it in Cython/Python?

This was already on my todo list, see item "1/gamma(-1) = 0" in the
above link. I will fix ginac, as this annoys me too. This is also on
the ginac todo list (see the 4th item):

http://www.ginac.de/ToDo.html

> You can actually still use Maxima for that, so that's not a problem in
> fact. And later just reimplement it in Python/Cython.

I would like to use pynac as much as possible and avoid calling maxima.
I don't think I need to reimplement anything in cython to fix this
specific problem though. I just need to go around and modify a few eval
functions to take infinity into account. Covering all the possible
cases might take a couple of days, but it's definitely within reach. In
fact, I already did something similar to get around ginac's shortcuts in
arithmetic when handling modular coefficients.


Thanks.

Burcin

Ondrej Certik

unread,
Nov 25, 2008, 6:14:13 PM11/25/08
to sage-s...@googlegroups.com

I only wanted to do stuff in this issue:

http://code.google.com/p/sympy/issues/detail?id=1214

e.g. substitue in the Piecewise function and then integrate it. Since
the integration failed in sympy, I was curious how far Sage is on this
front, and it is not far either. So the aim is that one should be able
to do everything in the issue.

>
>
>> Also, how will you approach to fix the bug in pynac
>> series I reported here:
>>
>> http://groups.google.com/group/sage-devel/msg/a59f3c5d0586766b
>>
>> E.g. will you fix ginac, or rather reimplement it in Cython/Python?
>
> This was already on my todo list, see item "1/gamma(-1) = 0" in the
> above link. I will fix ginac, as this annoys me too. This is also on
> the ginac todo list (see the 4th item):
>
> http://www.ginac.de/ToDo.html
>
>> You can actually still use Maxima for that, so that's not a problem in
>> fact. And later just reimplement it in Python/Cython.
>
> I would like to use pynac as much as possible and avoid calling maxima.
> I don't think I need to reimplement anything in cython to fix this
> specific problem though. I just need to go around and modify a few eval
> functions to take infinity into account. Covering all the possible
> cases might take a couple of days, but it's definitely within reach. In
> fact, I already did something similar to get around ginac's shortcuts in
> arithmetic when handling modular coefficients.

Thanks for pointing everything out. Now I can see where it's heading.
Btw, the last big problem are assumptions ---- I just told Michael on
irc, when we get this implemented, I could finally sleep well at
night, because then all the necessary pieces will be there.

Ondrej

Reply all
Reply to author
Forward
0 new messages