refactoring symbolic functions

12 views
Skip to first unread message

Burcin Erocal

unread,
Sep 30, 2009, 5:38:12 PM9/30/09
to sage-devel, pynac...@googlegroups.com
Hi,

Here is the current state of my symbolic functions changes. I won't be
able to work on this much in the near future. I don't even expect to
have e-mail access in the next few days.

I would really like to hear comments and suggestions on the new design.
Below is a quick summary of some of the new stuff. I need to go pack,
and get some sleep before I leave tomorrow. :)


Here are the major changes:

* evalf now accepts a parent argument instead of a precision
This allows us to use the numeric evaluation framework in ginac for
evaluating things with RIF, CIF, instances as well, not just RR, or
CC with the given precision.

* python arguments passed to custom methods of sfunctions are not
wrapped in Expression objects any more. No need to call .pyobject()
to unwrap these.

* custom methods support calling methods on self.
This would be useful if you need access to other function of the
defining class, or store tables of data calculated on demand.

* __call__ method supports hold parameter
This works:
sage: exp(log(x))
x
sage: exp(log(x), hold=True)
e^log(x)

* Custom methods for symbolic functions (_eval_, _evalf_, _conjugate_,
_derivative_, etc. See [1] for a list of support functions.) can be
written in Cython for builtin functions (that are provided by the
Sage library)
The pickling code tries to pickle the custom functions as well, and
this is only supported for python functions. We don't need to store
the function code if it is already defined in the library though.

Some things that need thought:

* The new class structure

We have 4 different types of functions, those defined by
* ginac (sin, cos, ...),
* the Sage library (cot)
* the user (in a python file, subclassing the new
SymbolicFunction)
* the command line function_factory (by calling function('f') )

Things we need to do for these functions different for each of these,
perhaps similar for the last two. Normally initializing a function
means checking if it's already defined, if not, initializing a
structure from ginac called function_options, and registering this in
a table. There are also issues with pickling.

For ginac functions, we don't need any of this, since we can't change
it at python level. We only need to look up the serial number (the
indicator in the table) of the function. We don't need to do anything
to pickle or unpickle these either.

Pickling and unpickling library functions only needs an identifier
for the class to initialize it again if necessary.

User defined functions need to lookup if there is an existing
function in the table, since we should try to keep the table small.

The new hierarchy under sage.symbolic.function is:
Function
GinacFunction
CustomizableFunction
BuiltinFunction
SymbolicFunction

There is also a new function_factory in sage.symbolic.function_factory
(it needs to be in a python file) that creates NewSymbolicFunction
classes on the fly for the function() calls from the command line.

* We should think about unifying these functions with the
CallableSymbolicExpression's This might be an easy way to
support arithmetic with these functions.

* Or, any other way to make arithmetic with these work.


Some of the things that still need work:

* pickling for NewSymbolicFunctions created in function_factory
* removing calls to math.* functions
we can't guarantee precision of these, IMHO, even for floats we
should call mpfr or mpmath, and convert the result back to float

Note that this is work in progress, many things don't work yet, lot's
of doctest failures etc.

In order to get the changes you need the pynac package here:

http://sage.math.washington.edu/home/burcin/pynac/pynac-0.1.9.sf.spkg

and this patch:

http://sage.math.washington.edu/home/burcin/pynac/sfunction_refactor.0.patch

It touches 25 files, it should apply to a recent alpha, but expect
having to manually patch certain files.


I would greatly appreciate any comments/suggestions especially on the
new hierarchy, and possible way to make things simpler. If anybody has
time to finish this off that's even better. :)


Cheers,
Burcin

Robert Bradshaw

unread,
Oct 1, 2009, 3:39:14 AM10/1/09
to sage-...@googlegroups.com
On Sep 30, 2009, at 2:38 PM, Burcin Erocal wrote:

> Hi,
>
> Here is the current state of my symbolic functions changes. I won't be
> able to work on this much in the near future. I don't even expect to
> have e-mail access in the next few days.
>
> I would really like to hear comments and suggestions on the new
> design.
> Below is a quick summary of some of the new stuff. I need to go pack,
> and get some sleep before I leave tomorrow. :)
>
>
> Here are the major changes:
>
> * evalf now accepts a parent argument instead of a precision
> This allows us to use the numeric evaluation framework in ginac for
> evaluating things with RIF, CIF, instances as well, not just RR, or
> CC with the given precision.

+1

> * python arguments passed to custom methods of sfunctions are not
> wrapped in Expression objects any more. No need to call .pyobject()
> to unwrap these.

+1

> * custom methods support calling methods on self.
> This would be useful if you need access to other function of the
> defining class, or store tables of data calculated on demand.
>
> * __call__ method supports hold parameter
> This works:
> sage: exp(log(x))
> x
> sage: exp(log(x), hold=True)
> e^log(x)

+1. Now we should hook this up to a context, e.g.

with symbolic_hold(True): # name ???
exp(log(x)) + 2 + 2 # doesn't evaluate it at all, or at least
not the function calling part

> * Custom methods for symbolic functions (_eval_, _evalf_,
> _conjugate_,
> _derivative_, etc. See [1] for a list of support functions.) can be
> written in Cython for builtin functions (that are provided by the
> Sage library)

Excellent.

That sounds a lot nicer.

>
> There is also a new function_factory in
> sage.symbolic.function_factory
> (it needs to be in a python file) that creates NewSymbolicFunction
> classes on the fly for the function() calls from the command line.
>
> * We should think about unifying these functions with the
> CallableSymbolicExpression's This might be an easy way to
> support arithmetic with these functions.
>
> * Or, any other way to make arithmetic with these work.

Give them a Parent that coerces in to SR.

> Some of the things that still need work:
>
> * pickling for NewSymbolicFunctions created in function_factory
> * removing calls to math.* functions
> we can't guarantee precision of these, IMHO, even for floats we
> should call mpfr or mpmath, and convert the result back to float

I'm not so sure about this. IMHO, MPFR input -> MPFR output, double
input -> double output. We shouldn't be using these on non-float/RDF
inputs though.

All in all, it sounds like an welcome improvement.

- Robert

Reply all
Reply to author
Forward
0 new messages