On March 28, 2007 7:42 AM Ondrej Certik wrote:
> ...
> Expression tree (Add, Mul,...) are very low level types, and
> you have many algorithms, that work with high level types like
> Polynomial, Fraction, ODE, DAE, PDE, etc. I understand that.
>
I think that there may be two problems with this discussion so
far.
I think the first problem is that Axiom developers and Python
programmers may not appreciate just how similar SPAD (or Aldor)
and Python really is. Although Python is dynamically typed
while Axiom is statically typed, both Python classes and Axiom
domains support object-oriented programming in similar ways.
I have been promising myself for some time now to take the time
to write a more accessible introduction. So here is at least a
start at this.
A draft containing the examples below is available on the Axiom
wiki as:
http://wiki.axiom-developer.org/SandBoxSPADForPython
For example, in Python we might define a simple class implementing
complex numbers something like the following:
### file: complex.py
class Complex:
"Example to demonstrate SPAD equivalent of Python Classes"
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
def real(self):
return self.r
def imag(self):
return self.i
def __str__(self):
if self.i<0:
return "%g - i %g"%(self.real(),-self.imag())
else:
return "%g + i %g"%(self.real(),self.imag())
def __coerce__(self,b):
if isinstance(b,Complex):
return(self,b)
else:
return(self,Complex(b,0))
def __add__(self,b):
return Complex(self.real()+b.real(), self.imag()+b.imag())
def __mul__(self,b):
return Complex(self.real()*b.real() - self.imag()*b.imag(),
self.real()*b.imag() + self.imag()*b.real())
###
>>> x = Complex(3.0, -4.5)
>>> y = Complex(-2.0, 5.4)
>>> print x
3.0 - i 4.5
>>> print x+y
1 + i 0.9
>>> print x*y
18.3 + i 25.2
>>> print x+1.0
4 - i 4.5
------
You can find details of how operator overloading in Python is done
by using special names like __op__ explained here:
http://docs.python.org/ref/customization.html
In SPAD a domain equivalent to this Python class would be:
--- file: complex.spad
)abbrev domain CMPLXS ComplexSpad
+++ Example of SPAD equivalent of Python Class
ComplexSpad(): with
new: (Float,Float) -> % ++ __init__ in Python
coerce: Float -> % ++ __coerce__ in Python
real: % -> Float ++ real in Python
imag: % -> Float ++ imag in Python
_+: (%,%) -> % ++ __add__ in Python
_*: (%,%) -> % ++ __mul__ in Python
coerce: % -> OutputForm ++ __str__ in Python
== add
Rep ==> Record(r:Float,i:Float)
import Rep, OutputForm, Symbol
new(realpart:Float,imagpart:Float):% == [realpart,imagpart] pretend %
coerce(x:Float):% == new(x,0)
real(x:%):Float == (x pretend Rep).r
imag(x:%):Float == (x pretend Rep).i
_+(x:%, y:%):% ==
new(real(x)+real(y), imag(x)+imag(y))
_*(x:%, y:%):% ==
new(real(x)*real(y) - imag(x)*imag(y),
real(x)*imag(y) + imag(x)*real(y))
coerce(x:%):OutputForm ==
if imag(x)<0 then
real(x)::OutputForm - outputForm("i"::Symbol) *
(-imag(x))::OutputForm
else
real(x)::OutputForm + outputForm("i"::Symbol) * imag(x)::OutputForm
---
I have indicated the equivalent Python function by the ++
comment in each export.
This would be compiled in Axiom using the command:
(1) -> )compile complex.spad
Compiling AXIOM source code from file
C:/Documents and Settings/Administrator.ASUS/My Documents/complex.spad
using old system compiler.
CMPLXS abbreviates domain ComplexSpad
...
Then we may use this new domain like this:
(1) -> x := new(3.0, -4.5)$ComplexSpad
(1) 3.0 - i 4.5
Type: ComplexSpad
(2) -> y := new(-2.0, 5.4)$ComplexSpad
(2) - 2.0 + i 5.4
Type: ComplexSpad
(3) -> x+y
(3) 1.0 + i 0.9
Type: ComplexSpad
(4) -> x*y
(4) 18.3 + i 25.2
Type: ComplexSpad
(5) -> x+1.0
(5) 4.0 - i 4.5
Type: ComplexSpad
There are a lot of good references to Python classes on the web
and in numerous books. Although the emphasis is on numerical
applications of Python I think a good introduction for Axiom
developers might be the following book:
Python Scripting for Computational Science
by Langtangen, Hans Petter
2nd ed., 2006, XXIV, 736 p., 33 illus., Hardcover
ISBN: 978-3-540-29415-3
http://www.springer.com/sgw/cda/frontpage/0,11855,1-40109-22-83511316-0,00.h
tml
See especially section 8.6 on Classes.
Or for a more detailed and technical description of Python
classes with a C++ flavour you could try:
http://docs.python.org/tut/node11.html
For Python programmers the best introduction to domains and
categories in Axiom is probably the Axiom book:
http://wiki.axiom-developer.org/public/book2.pdf#page=940
You might want to consult the Aldor user's guide:
http://www.aldor.org/docs/HTML/index.html
Most of what is written here about Aldor also applies to the SPAD
programming language in Axiom. See especially chapter 7 on Types:
http://www.aldor.org/docs/HTML/chap7.html
Unfortunately this document might be overly technical as an
introduction and uses terms that might not be very familiar to
Python programmers.
> The question is - how the Axiom converts from the low level
> representation to the high level?
>
Now this question suggests to me the second problem. What we are
missing here is the distinction between symbolic computation and
computer algebra that has been discussed by Steven Watt (the
developer of Aldor) in several recent papers. See especially his
paper:
Making Computer Algebra More Symbolic
http://www.csd.uwo.ca/~watt/pub/reprints/2006-tc-sympoly.pdf
Abstract
This paper is a step to bring closer together two views of computing
with mathematical objects: the view of "symbolic computation" and
the view of "computer algebra". Symbolic computation may be seen as
working with expression trees representing mathematical formulae
and applying various rules to transform them. Computer algebra may
be seen as developing constructive algorithms to compute algebraic
quantities in various arithmetic domains, possibly involving
indeterminates. Symbolic computation allows a wider range of
expression, while computer algebra admits greater algorithmic
precision. ...
-----
So what Axiom does is basically "computer algebra" in the above
sense while what many other so called computer algebra systems
are doing is really better described at "symbolic computation".
What makes things a little fuzzy here is that Axiom also has an
algebraic domain called Expression which has many (but not all!)
of the characteristics as symbolic computation in these other
systems.
But from this point of view what Axiom is doing is fundamentally
different than what I think SymPy is doing. SymPy is doing
symbolic computation using a set of Python domains that implement
an Expression tree structure. But what Axiom is doing with it's
Expression domain is trying to define a mathematical object
starting with rational functions (Fraction Polynomial) and adding
a large number of special functions.
> A place that occurs to me to do it is just right after the
> evaluation to the canonical form:
>
> like Add(x,x) automatically converts to Mul(2,x) and here, at
> this place, the CAS would check the expression and says: hey -
> the Mul(2,x) is a polynomial, let's return a Polynomial class
> instead.
>
> This would make sense to me, and we could do it in SymPy as well.
>
I think what Axiom is doing is very different.
Regards,
Bill Page.