login  home  contents  what's new  discussion  bug reports help  links  subscribe  changes  refresh  edit

# Edit detail for SandBox SPAD for Python 2 revision 1 of 1

 1 Editor: Time: 2007/11/18 18:34:07 GMT-8 Note: added a note

changed:
-
Aldor and SPAD allow domains to have parameters. For example
let's generalize the previous Complex domain to form complex
numbers over any ring.

First define a simple category MyRing and two domains that satisfy
this category.
\begin{aldor}[myring]
#pile
#include "axiom.as"
define MyRing: Category == with
0: %
-: % -> %
-: (%,%) -> %
+: (%,%) -> %
*: (%,%) -> %
coerce: % -> OutputForm

MyInteger: MyRing with
coerce: Integer -> %
== Integer add
coerce(i: Integer): % == i pretend %

MyFloat: MyRing with
coerce: Float -> %
== Float add
coerce(i: Float): % == i pretend %
\end{aldor}

Now we can define the domain Complex2 which takes a ring as
parameter. Such a domain is sometimes called a 'functor' since
it behaves as a function mapping a category into a category.

\begin{aldor}
#pile
#include "axiom.as"
#library myring "myring.ao";
import from myring

Complex2(R: MyRing): MyRing with
new: (R,R) -> %
coerce: R -> %
real: % -> R
imag: % -> R
== add
Rep == Record(r:R,i:R)
import from Rep, R, OutputForm, Symbol
new(realpart:R,imagpart:R):% == per [realpart,imagpart]
0: % == new(0,0)
coerce(x:R):% == new(x,0)
real(x:%):R == rep(x).r
imag(x:%):R == rep(x).i
(x:%) + (y:%):% == new(real(x)+real(y), imag(x)+imag(y))
(x:%) - (y:%):% == new(real(x)-real(y), imag(x)-imag(y))
-(x:%):% == new(-real(x), -imag(x))
(x:%) * (y:%):% == new(real(x)*real(y) - imag(x)*imag(y),
real(x)*imag(y) + imag(x)*real(y))
local i: OutputForm == outputForm("i"::Symbol)
macro OUT == OutputForm
coerce(x:%):OUT ==
if R has with {<: (%,%) -> Boolean} then
import from R
if imag x < 0 then
[real(x)::OUT - (-imag(x))::OUT * i]
else
[real(x)::OUT + imag(x)::OUT * i]
else
[real(x)::OUT + (imag(x)::OUT) * i]
\end{aldor}

\begin{axiom}
macro CI == Complex2 MyInteger;
a: CI := new(2, 1)
b: CI := new(0, 3)
c: CI := a + b
\end{axiom}
Note that the inner and the outer appearance of the imaginary i are treated as different entities with similar properties.
\begin{axiom}
macro CCI == Complex2 CI;
a: CI := new(2, 1)
b: CI := new(0, 3)
c: CI := a + b
u: CCI := new(a, b)
v: CCI := new(a, c)
u - v
u * v
\end{axiom}
\begin{axiom}
ii: CI := new(0,1)
innerI: CCI := new(ii, 0)
outerI: CCI := new(0, 1)
innerI * outerI
\end{axiom}
Obviously 'Complex2 Complex2 MyInteger' rather behaves like
quaternions, but not exactly, since::

innerI*outerI = outerI*innerI

\begin{axiom}
macro CF == Complex2 MyFloat;
macro CCF == Complex2 CF
new(new(1.0,2.0)$CF,new(3.0,-4.0)$CF)$CCF \end{axiom} So now how would we do this in Python? First of all, notice that since Python in dynamically typed, i.e. it is the values that carry the types, not the variables, so it is not necessary to specify any type parameter to the class. In the original code we only *implicitly* required that the values passed to the '__init__' parameters, realpart and imagpart support certain methods, namely: -, +, *, < and 0. So if we wish to write:: Complex2(Complex2(1.0,2.0),Complex2(3.0,-4.0)) then all we need to do is add operators for -, take care of the case where we may not have a < operator and call __str__ directly to get the printed form. \begin{sageblock} class Complex2: "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 '__cmp__' in dir(self.i): if self.i<0: return "[%s - %s i]"%(self.r.__str__(),(-self.i).__str__()) else: return "[%s + %s i]"%(self.r.__str__(),self.i.__str__()) else: return "[%s + %s i]"%(self.r.__str__(),self.i.__str__()) def __coerce__(self,b): if isinstance(b,Complex2): return(self,b) else: return(self,Complex2(b,0)) def __add__(self,b): return Complex2(self.r+b.r, self.i+b.i) def __sub__(self,b): return Complex2(self.r-b.r, self.i-b.i) def __mul__(self,b): return Complex2(self.r*b.r - self.i*b.i, self.r*b.i + self.i*b.r) \end{sageblock} "Reference":http://docs.python.org/ref/customization.html Now we can write: \begin{verbatim} Complex2(Complex2(1.0,-2.0),Complex2(3.0,-4.0)) \end{verbatim} $$\sage{Complex2(Complex2(1.0,2.0),Complex2(3.0,-4.0))}$$ Compare the following to the output from Axiom above: \begin{sageblock} ii = Complex2(0,1) \end{sageblock} \begin{verbatim} print ii \end{verbatim} $$\sage{ii}$$ \begin{sageblock} innerI = Complex2(ii, 0) \end{sageblock} \begin{verbatim} print innerI \end{verbatim} $$\sage{innerI}$$ \begin{sageblock} outerI = Complex2(0, 1) \end{sageblock} \begin{verbatim} print outerI \end{verbatim} $$\sage{outerI}$$ \begin{verbatim} print innerI * outerI \end{verbatim} $$\sage{innerI * outerI}$$ This Python code seems to do the same thing as the Aldor code but without the "complication" of categories! Ondrej: The __cmp__ in dir(..) is ugly, but that's because you are using the python integers and stuff. In SymPy, we have our own class for Numbers and for Mul and str(x-y) prints the + and - correctly (the Mul and Add takes care of it). But in this simple example, the __cmp__ in dir(..) is the easiest solution.  Aldor and SPAD allow domains to have parameters. For example let's generalize the previous Complex domain to form complex numbers over any ring. First define a simple category MyRing and two domains that satisfy this category. \begin{aldor}[myring] #pile #include "axiom.as" define MyRing: Category == with 0: % -: % -> % -: (%,%) -> % +: (%,%) -> % *: (%,%) -> % coerce: % -> OutputForm MyInteger: MyRing with coerce: Integer -> % == Integer add coerce(i: Integer): % == i pretend % MyFloat: MyRing with coerce: Float -> % == Float add coerce(i: Float): % == i pretend % \end{aldor} Now we can define the domain Complex2 which takes a ring as parameter. Such a domain is sometimes called a functor since it behaves as a function mapping a category into a category. \begin{aldor} #pile #include "axiom.as" #library myring "myring.ao"; import from myring Complex2(R: MyRing): MyRing with new: (R,R) -> % coerce: R -> % real: % -> R imag: % -> R == add Rep == Record(r:R,i:R) import from Rep, R, OutputForm, Symbol new(realpart:R,imagpart:R):% == per [realpart,imagpart] 0: % == new(0,0) coerce(x:R):% == new(x,0) real(x:%):R == rep(x).r imag(x:%):R == rep(x).i (x:%) + (y:%):% == new(real(x)+real(y), imag(x)+imag(y)) (x:%) - (y:%):% == new(real(x)-real(y), imag(x)-imag(y)) -(x:%):% == new(-real(x), -imag(x)) (x:%) (y:%):% == new(real(x)real(y) - imag(x)imag(y), real(x)imag(y) + imag(x)*real(y)) local i: OutputForm == outputForm(i) macro OUT == OutputForm coerce(x:%):OUT == if R has with {<: (%,%) -> Boolean} then import from R if imag x < 0 then [real(x)::OUT - (-imag(x))::OUT * i] else [real(x)::OUT + imag(x)::OUT * i] else [real(x)::OUT + (imag(x)::OUT) * i] \end{aldor} \begin{axiom} macro CI == Complex2 MyInteger; a: CI := new(2, 1) b: CI := new(0, 3) c: CI := a + b \end{axiom} Note that the inner and the outer appearance of the imaginary i are treated as different entities with similar properties. \begin{axiom} macro CCI == Complex2 CI; a: CI := new(2, 1) b: CI := new(0, 3) c: CI := a + b u: CCI := new(a, b) v: CCI := new(a, c) u - v u v \end{axiom} \begin{axiom} ii: CI := new(0,1) innerI: CCI := new(ii, 0) outerI: CCI := new(0, 1) innerI outerI \end{axiom} Obviously Complex2 Complex2 MyInteger rather behaves like quaternions, but not exactly, since: innerI*outerI = outerI*innerI \begin{axiom} macro CF == Complex2 MyFloat?; macro CCF == Complex2 CF new(new(1.0,2.0)$CF,new(3.0,-4.0)$CF)$CCF
\end{axiom}
So now how would we do this in Python?
First of all, notice that since Python in dynamically typed,
i.e. it is the values that carry the types, not the variables,
so it is not necessary to specify any type parameter to the
class. In the original code we only implicitly required that
the values passed to the __init__ parameters, realpart and
imagpart support certain methods, namely: -, +, *, < and 0.
So if we wish to write:
Complex2(Complex2(1.0,2.0),Complex2(3.0,-4.0))

then all we need to do is add operators for -, take care of
the case where we may not have a < operator and call __str__
directly to get the printed form.
\begin{sageblock}
class Complex2:
"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 __cmp__ in dir(self.i):
if self.i<0:
return "[%s - %s i]"%(self.r.__str__(),(-self.i).__str__())
else:
return "[%s + %s i]"%(self.r.__str__(),self.i.__str__())
else:
return "[%s + %s i]"%(self.r.__str__(),self.i.__str__())
def __coerce__(self,b):
if isinstance(b,Complex2):
return(self,b)
else:
return(self,Complex2(b,0))
def __add__(self,b):
return Complex2(self.r+b.r, self.i+b.i)
def __sub__(self,b):
return Complex2(self.r-b.r, self.i-b.i)
def __mul__(self,b):
return Complex2(self.rb.r - self.ib.i,
self.rb.i + self.ib.r)
\end{sageblock}
Reference
Now we can write:
\begin{verbatim}
Complex2(Complex2(1.0,-2.0),Complex2(3.0,-4.0))
\end{verbatim}
\begin{equation}
\label{eq1}
\sage{Complex2(Complex2(1.0,2.0),Complex2(3.0,-4.0))}
\end{equation}
Compare the following to the output from Axiom above:
\begin{sageblock}
ii = Complex2(0,1)
\end{sageblock}
\begin{verbatim}
print ii
\end{verbatim}
\begin{equation}
\label{eq2}
\sage{ii}
\end{equation}
\begin{sageblock}
innerI = Complex2(ii, 0)
\end{sageblock}
\begin{verbatim}
print innerI
\end{verbatim}
\begin{equation}
\label{eq3}
\sage{innerI}
\end{equation}
\begin{sageblock}
outerI = Complex2(0, 1)
\end{sageblock}
\begin{verbatim}
print outerI
\end{verbatim}
\begin{equation}
\label{eq4}
\sage{outerI}
\end{equation}
\begin{verbatim}
print innerI * outerI
\end{verbatim}
\begin{equation}
\label{eq5}
\sage{innerI  outerI}
\end{equation*}
This Python code seems to do the same thing as the Aldor code
but without the "complication" of categories!
Ondrej: The __cmp__ in dir(..) is ugly, but that's because you are using the python integers and stuff. In SymPy?, we have our own class for Numbers and for Mul and str(x-y) prints the + and - correctly (the Mul and Add takes care of it). But in this simple example, the __cmp__ in dir(..) is the easiest solution.

Some or all expressions may not have rendered properly,
because Axiom returned the following error:Error: export AXIOM=/usr/local/lib/open-axiom/x86_64-unknown-linux/1.2.0-2008-05-25; export ALDORROOT=/usr/local/aldor/linux/1.1.0; export PATH=$ALDORROOT/bin:$PATH; export HOME=/var/zope2/var/LatexWiki; ulimit -t 600; export LD_LIBRARY_PATH=/usr/local/lib/open-axiom/x86_64-unknown-linux/1.2.0-2008-05-25/lib; LANG=en_US.UTF-8 \$AXIOM/bin/AXIOMsys < /var/zope2/var/LatexWiki/2461718240468875932-25px.axm
/bin/sh: /usr/local/lib/open-axiom/x86_64-unknown-linux/1.2.0-2008-05-25/bin/AXIOMsys: not found


Some or all expressions may not have rendered properly, because Latex returned the following error:
This is pdfTeXk, Version 3.141592-1.40.3 (Web2C 7.5.6)
\write18 enabled.
%&-line parsing enabled.
entering extended mode
(./2704029797281049257-16.0px.tex
LaTeX2e <2005/12/01>
Babel <v3.8h> and hyphenation patterns for english, usenglishmax, dumylang, noh
yphenation, arabic, farsi, croatian, ukrainian, russian, bulgarian, czech, slov
ak, danish, dutch, finnish, basque, french, german, ngerman, ibycus, greek, mon
ogreek, ancientgreek, hungarian, italian, latin, mongolian, norsk, icelandic, i
nterlingua, turkish, coptic, romanian, welsh, serbian, slovenian, estonian, esp
eranto, uppersorbian, indonesian, polish, portuguese, spanish, catalan, galicia
n, swedish, ukenglish, pinyin, loaded.
(/usr/share/texmf-texlive/tex/latex/base/article.cls
Document Class: article 2005/09/16 v1.4f Standard LaTeX document class
(/usr/share/texmf-texlive/tex/latex/base/size12.clo))
(/usr/share/texmf-texlive/tex/latex/ucs/ucs.sty
(/usr/share/texmf-texlive/tex/latex/ucs/data/uni-global.def))
(/usr/share/texmf-texlive/tex/latex/base/inputenc.sty
(/usr/share/texmf-texlive/tex/latex/ucs/utf8x.def))
(/usr/share/texmf-texlive/tex/latex/bbm/bbm.sty)
(/usr/share/texmf-texlive/tex/latex/jknapltx/mathrsfs.sty)
(/usr/share/texmf-texlive/tex/latex/base/fontenc.sty
(/usr/share/texmf-texlive/tex/latex/base/t1enc.def))
(/usr/share/texmf-texlive/tex/latex/pstricks/pstricks.sty
(/usr/share/texmf-texlive/tex/generic/pstricks/pstricks.tex
PSTricks' v1.15  <2006/12/22> (tvz)
(/usr/share/texmf-texlive/tex/generic/pstricks/pstricks.con))
(/usr/share/texmf/tex/latex/xcolor/xcolor.sty
(/etc/texmf/tex/latex/config/color.cfg)
(/usr/share/texmf-texlive/tex/latex/graphics/dvips.def)
(/usr/share/texmf-texlive/tex/latex/graphics/dvipsnam.def)))
(/usr/share/texmf-texlive/tex/latex/graphics/epsfig.sty
(/usr/share/texmf-texlive/tex/latex/graphics/graphicx.sty
(/usr/share/texmf-texlive/tex/latex/graphics/keyval.sty)
(/usr/share/texmf-texlive/tex/latex/graphics/graphics.sty
(/usr/share/texmf-texlive/tex/latex/graphics/trig.sty)
(/etc/texmf/tex/latex/config/graphics.cfg))))
(/usr/share/texmf-texlive/tex/latex/pst-grad/pst-grad.sty
(/usr/share/texmf-texlive/tex/generic/pst-grad/pst-grad.tex
(/usr/share/texmf-texlive/tex/latex/xkeyval/pst-xkey.tex
(/usr/share/texmf-texlive/tex/latex/xkeyval/xkeyval.sty
(/usr/share/texmf-texlive/tex/latex/xkeyval/xkeyval.tex)))
pst-plot' v1.05, 2006/11/04 (tvz,dg,hv)))
(/usr/share/texmf-texlive/tex/latex/pstricks/pst-plot.sty
(/usr/share/texmf-texlive/tex/generic/pstricks/pst-plot.tex
v97 patch 2, 1999/12/12
(/usr/share/texmf-texlive/tex/generic/multido/multido.tex
v1.41, 2004/05/18 <tvz>))) (/usr/share/texmf-texlive/tex/generic/xypic/xy.sty
(/usr/share/texmf-texlive/tex/generic/xypic/xy.tex Bootstrap'ing: catcodes,
docmode, (/usr/share/texmf-texlive/tex/generic/xypic/xyrecat.tex)
(/usr/share/texmf-texlive/tex/generic/xypic/xyidioms.tex) Xy-pic version 3.7 <1999/02/16>
Copyright (c) 1991-1998 by Kristoffer H. Rose <krisrose@ens-lyon.fr>
Xy-pic is free software: see the User's Guide for details.

Loading kernel: messages; fonts; allocations: state, direction,
utility macros; pictures: \xy, positions, objects, decorations;
kernel objects: directionals, circles, text; options; algorithms: directions,
edges, connections;  Xy-pic loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xyall.tex
Xy-pic option: All features v.3.3
(/usr/share/texmf-texlive/tex/generic/xypic/xycurve.tex
Xy-pic option: Curve and Spline extension v.3.7 curve, circles, loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xyframe.tex
Xy-pic option: Frame and Bracket extension v.3.7 loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xycmtip.tex
Xy-pic option: Computer Modern tip extension v.3.3
(/usr/share/texmf-texlive/tex/generic/xypic/xytips.tex
Xy-pic option: More Tips extension v.3.3 loaded) loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xyline.tex
Xy-pic option: Line styles extension v.3.6 loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xyrotate.tex
Xy-pic option: Rotate and Scale extension v.3.3 loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xycolor.tex
Xy-pic option: Colour extension v.3.3 loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xymatrix.tex
Xy-pic option: Matrix feature v.3.4 loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xyarrow.tex
Xy-pic option: Arrow and Path feature v.3.5 path, \ar, loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xygraph.tex
Xy-pic option: Graph feature v.3.7 loaded) loaded)
(/usr/share/texmf-texlive/tex/generic/xypic/xyknot.tex
Xy-pic option: Knots and Links feature v.3.4 knots and links, loaded))
(/usr/share/texmf-texlive/tex/generic/xypic/xyarc.tex
Xy-pic option: Circle, Ellipse, Arc feature v.3.4 circles, ellipses,
elliptical arcs, loaded)
(/usr/share/texmf-texlive/tex/latex/geometry/geometry.sty
(/usr/share/texmf-texlive/tex/xelatex/xetexconfig/geometry.cfg)
Package geometry Warning: lmargin' and rmargin' result in NEGATIVE (-108.405p
t).
width' should be shortened in length.
) (/usr/share/texmf-texlive/tex/latex/amsmath/amsmath.sty
For additional information on amsmath, use the ? option.
(/usr/share/texmf-texlive/tex/latex/amsmath/amstext.sty
(/usr/share/texmf-texlive/tex/latex/amsmath/amsgen.sty))
(/usr/share/texmf-texlive/tex/latex/amsmath/amsbsy.sty)
(/usr/share/texmf-texlive/tex/latex/amsmath/amsopn.sty))
(/usr/share/texmf-texlive/tex/latex/amsfonts/amsfonts.sty)
(/usr/share/texmf-texlive/tex/latex/amsfonts/amssymb.sty)
(/usr/share/texmf-texlive/tex/latex/amscls/amsthm.sty)
(/usr/share/texmf-texlive/tex/latex/setspace/setspace.sty
Package: setspace 6.7 <2000/12/01>
) (/usr/share/texmf-texlive/tex/latex/tools/verbatim.sty)
(/usr/share/texmf/tex/latex/graphviz/graphviz.sty
(/usr/share/texmf-texlive/tex/latex/psfrag/psfrag.sty))
(/usr/share/texmf/tex/latex/sagetex.sty
Writing sage input file 2704029797281049257-16.0px.sage
(./2704029797281049257-16.0px.sout))
(/usr/share/texmf-texlive/tex/latex/gnuplottex/gnuplottex.sty
(/usr/share/texmf-texlive/tex/latex/base/latexsym.sty)
(/usr/share/texmf-texlive/tex/latex/moreverb/moreverb.sty)
(/usr/share/texmf-texlive/tex/latex/base/ifthen.sty))
(./2704029797281049257-16.0px.aux)
(/usr/share/texmf-texlive/tex/latex/ucs/ucsencs.def)
You can't use macro parameter character #' in horizontal mode.
l.123 #
pile
You can't use macro parameter character #' in horizontal mode.
l.124 #
include "axiom.as"
[1]
You can't use macro parameter character #' in vertical mode.
l.144 #
pile
You can't use macro parameter character #' in horizontal mode.
l.145 #
include "axiom.as"
You can't use macro parameter character #' in horizontal mode.
l.146 #
library myring "myring.ao";
Missing } inserted.
<inserted text>
}
l.178 \end{aldor}
\newpage
[2] (/usr/share/texmf-texlive/tex/latex/base/t1cmtt.fd)
LaTeX Warning: Characters dropped after \end{axiom}' on input line 184.
LaTeX Warning: Characters dropped after \end{axiom}' on input line 194.
LaTeX Warning: Characters dropped after \end{axiom}' on input line 200.
LaTeX Warning: Characters dropped after \end{axiom}' on input line 205.
LaTeX Warning: Characters dropped after \end{sageblock}' on input line 236.
LaTeX Warning: Characters dropped after \end{verbatim}' on input line 239.
(/usr/share/texmf-texlive/tex/latex/jknapltx/ursfs.fd)
(/usr/share/texmf-texlive/tex/latex/amsfonts/umsa.fd)
(/usr/share/texmf-texlive/tex/latex/amsfonts/umsb.fd)
(/usr/share/texmf-texlive/tex/latex/base/ulasy.fd) [3]
LaTeX Warning: Characters dropped after \end{sageblock}' on input line 246.
LaTeX Warning: Characters dropped after \end{verbatim}' on input line 249.
[4]
LaTeX Warning: Characters dropped after \end{sageblock}' on input line 256.
LaTeX Warning: Characters dropped after \end{verbatim}' on input line 259.
[5]
LaTeX Warning: Characters dropped after \end{sageblock}' on input line 266.
LaTeX Warning: Characters dropped after \end{verbatim}' on input line 269.
[6]
LaTeX Warning: Characters dropped after \end{verbatim}' on input line 276.
[7] [8] (./2704029797281049257-16.0px.aux) )
(see the transcript file for additional information)
Output written on 2704029797281049257-16.0px.dvi (8 pages, 4108 bytes).
Transcript written on 2704029797281049257-16.0px.log.
`