# HG changeset patch
# User Martin Albrecht
# Date 1219531586 3600
# Node ID 4bf9056066e8e0b85be0f485dbea99b11fa6ec87
# Parent 9e8605f19c12ab9371c60f976207d3b76a503e42
my comments on Trac > a patch
diff r 9e8605f19c12 r 4bf9056066e8 prog/prog.tex
 a/prog/prog.tex Tue Aug 19 19:25:47 2008 0700
+++ b/prog/prog.tex Sat Aug 23 23:46:26 2008 +0100
@@ 6,7 +6,6 @@
\documentclass{manual}
\usepackage{textcomp}

\include{macrosnew}
% a hack to get around another hack.
\ifpdf
@@ 17,8 +16,9 @@
%\newcommand{\todo}[1]{\footnote{1}}
\newcommand{\todo}[1]{}
\newcommand{\swlist}{GAP, GSL, Matplotlib, Maxima, MWRANK, NetworkX,
 NTL, Numpy, PARI and Singular\xspace}
+\newcommand{\swlist}{Flint, FpLLL, GAP, GSL, IML, LinBox, M4RI, Matplotlib,
+Maxima, MWRank, ECLib, NetworkX, NTL, Numpy, PARI/GP, PolyBoRi, R
+Scipy, Singular, Sympy\xspace}
\usepackage{color}
\definecolor{hue}{rgb}{.202, .602, .58}
@@ 28,8 +28,6 @@
\definecolor{orange}{rgb}{.902, .502, .08}
\definecolor{black}{rgb}{0,0, 1}


\input{boilerplate}
\makeindex
@@ 39,7 +37,7 @@
\title{\SAGE Developer's Guide}
\author{William Stein and David Joyner}
+\author{The Sage Group}
\maketitle
@@ 53,8 +51,9 @@
\noindent
\SAGE is a free mathematics software system. It is implemented using
Python, Cython, and C++, and uses \swlist. It is free and open
source, and is available under the terms of the GNU Public License.
+Python, Cython, and C++, uses \swlist and many specialized smaller systems
+and libraries. It is free and open source, and is available under the terms of
+the GNU Public License. Some parts are available under compatible licenses.
Everybody who uses \SAGE should contribute something
back to \SAGE at some point. Implement a new function, add examples
@@ 84,7 +83,10 @@
\item Implement it in C/C++ and make the result accessible
to \SAGE using Cython,
\item Implement it using Cython,
\item Implement it using one or more of the following: \swlist.
+\item Implement it using one or more of the following: \swlist or any of the
+other libraries included with \SAGE~\footnote{See
+\url{http://www.sagemath.org/linkscomponents.html} for a full list of packages
+shipped with every copy of \SAGE}
\item or {\em any combination} of the above.
\end{enumerate}
@@ 99,7 +101,8 @@
contains sophisticated, optimized number theory algorithms. Notably
absent from this triad is a good system for exact linear algebra
(something MAGMA does extremely well), but this gap is being filled by
code written for \SAGE.
+code written for \SAGE or covered by specialized C/C++ libraries like LinBox,
+IML and M4RI.
\todo{Say something about GSL, Matplotlib, Maxima, MWRANK, NetworkX,
NTL, Numpy}
@@ 110,10 +113,8 @@
semantics of objects, the definitions, etc., are informed by how the
corresponding objects are used in everyday mathematics.
This document was authored by William Stein, David Joyner and others
with the editorial help of Iftikhar Burhanuddin.


+This document was authored by William Stein, David Joyner, John Palmieri
+and others with the editorial help of Iftikhar Burhanuddin and Martin Albrecht.
\chapter{Conventions for Coding in \SAGE}\label{ch:conventions}
@@ 147,6 +148,9 @@
objects, e.g., \code{PolynomialRing}.
\end{itemize}
+Note however that some functions do have uppercase letters where it makes sense.
+For instance, the function for lattice reduction by the LLL algorithm is called
+\code{Matrix_integer_dense.LLL}.
\section{File and Directory Names}
@@ 156,6 +160,8 @@
file \code{polynomial\_ring.py} might still contain definitions of
several different types of polynomial rings.
+%malb: I'm not sure about the encouragement of TXT files. It seems to be hardly
+% used and gets old quickly.
\note{You are encouraged
to include miscellaneous notes, emails, design
discussions, etc., in your package. Make these
@@ 196,75 +202,118 @@
\end{verbatim}
The following is the top of the file
\code{SAGE_ROOT/devel/sage/sage/modular/ssmmod/ssmod.py}, which
contains the Supersingular Module code.
+\code{SAGE_ROOT/devel/sage/sage/rings/integer.pyx}, which
+contains the implementation for $\Z$.
{\small
\begin{verbatim}
"""
Module of Supersingular Points
+r"""
+Elements of the ring $\Z$ of integers
AUTHORS:
  William Stein
  David Kohel
  Iftikhar Burhanuddin
+  William Stein (2005): initial version
+  Gonzalo Tornaria (20060302): vastly improved python/GMP
+ conversion; hashing
+  Didier Deshommes (20060306): numerous
+ examples and docstrings
+  William Stein (20060331): changes to reflect GMP bug fixes
+  William Stein (20060414): added GMP factorial method (since it's
+ now very fast).
+  David Harvey (20060915): added nth_root, exact_log
+  David Harvey (20060916): attempt to optimise Integer constructor
+  Rishikesh (20070225): changed quo_rem so that the rem is positive
+  David Harvey, Martin Albrecht, Robert Bradshaw (20070301):
+ optimized Integer constructor and
+ pool
+  Pablo De Napoli (20070401): multiplicative_order should
+ return +infinity for non zero
+ numbers
+  Robert Bradshaw (20070412): is_perfect_power, Jacobi symbol
+ (with Kronecker extension). Convert
+ some methods to use GMP directly
+ rather than pari, Integer() >
+ PY_NEW(Integer)
+  David Roe (20070321): sped up valuation and is_square, added
+ val_unit, is_power, is_power_of and
+ divide_knowing_divisible_by
+  Robert Bradshaw (20080326): gamma function, multifactorials
EXAMPLES:
 sage: x = SupersingularModule(389)
 sage: m = x.T(2).matrix()
 sage: a = m.change_ring(GF(97))
 sage: D = a.decomposition()
 sage: D[:3]
 [
 (Vector space of degree 33 and dimension 1 over Finite Field of size 97
 Basis matrix:
 [ 0 0 0 1 96 96 1 96 96 0 2 96 96 0 1 0 1 2 95 0 1 1 0 1 0 95 0 96 95 1 96 0 2], True),
 (Vector space of degree 33 and dimension 1 over Finite Field of size 97
 Basis matrix:
 [ 0 1 96 75 16 81 22 17 17 0 0 80 80 1 16 40 74 0 0 96 81 23 57 74 0 0 0 24 0 23 73 0 0], True),
 (Vector space of degree 33 and dimension 1 over Finite Field of size 97
 Basis matrix:
 [ 0 1 96 90 90 7 7 6 91 0 0 91 6 13 7 0 91 0 0 84 90 6 0 6 0 0 0 90 0 91 7 0 0], True)
 ]
 sage: len(D)
 9
+ Add 2 integers:
+ sage: a = Integer(3) ; b = Integer(4)
+ sage: a + b == 7
+ True
We compute a Hecker operator on a space of huge dimension!
 sage: X = SupersingularModule(next_prime(100000))
 sage: t = X.T(2).matrix() # long time (but still less than a minute!)
 sage: t.nrows() # long time
 8334
+ Add an integer and a real number:
+ sage: a + 4.0
+ 7.00000000000000
TESTS:
 sage: X = SupersingularModule(389)
 sage: T = X.T(2).matrix().change_ring(QQ)
 sage: d = T.decomposition()
 sage: len(d)
 6
 sage: [a[0].dimension() for a in d]
 [1, 1, 2, 3, 6, 20]
 sage: loads(dumps(X)) == X
+ Add an integer and a rational number:
+ sage: a + Rational(2)/5
+ 17/5
+
+ Add an integer and a complex number:
+ sage: b = ComplexField().0 + 1.5
+ sage: loads((a+b).dumps()) == a+b
+ True
+
+ sage: z = 32
+ sage: z
+ 32
+ sage: z = 0; z
+ 0
+ sage: z = 0; z
+ 0
+ sage: z = 1; z
+ 1
+
+Multiplication:
+ sage: a = Integer(3) ; b = Integer(4)
+ sage: a * b == 12
True
 sage: loads(dumps(d)) == d
+ sage: loads((a * 4.0).dumps()) == a*b
True
+ sage: a * Rational(2)/5
+ 6/5
+
+ sage: list([2,3]) * 4
+ [2, 3, 2, 3, 2, 3, 2, 3]
+
+ sage: 'sage'*Integer(3)
+ 'sagesagesage'
+
+COERCIONS:
+ Returns version of this integer in the multiprecision floating
+ real field R.
+
+ sage: n = 9390823
+ sage: RR = RealField(200)
+ sage: RR(n)
+ 9.3908230000000000000000000000000000000000000000000000000000e6
+
"""

#*****************************************************************************
# Copyright (C) 2004,2006 William Stein
# Copyright (C) 2006 David Kohel
# Copyright (C) 2006 Iftikhar Burhanuddin
+# Copyright (C) 2006 Gonzalo Tornaria
+# Copyright (C) 2006 Didier Deshommes
+# Copyright (C) 2007 David Harvey
+# Copyright (C) 2007 Martin Albrecht
+# Copyright (C) 2007,2008 Robert Bradshaw
+# Copyright (C) 2007 David Roe
+#
# Distributed under the terms of the GNU General Public License (GPL)
...
+# http://www.gnu.org/licenses/
+#*****************************************************************************
\end{verbatim}
}%small
All code included with \sage must be licensed under the GPL or a less
restrictive license (e.g., the BSD license).
It is {\em very
 important} that you include your name in the AUTHOR log, since
everybody who submits code to \sage to receive proper credit. (If
+All code included with \sage must be licensed under the GPLv2+ or a
+less restrictive license (e.g., the BSD license).
+It is {\em very important} that you include your name in the AUTHOR log, since
+everybody who submits code to \sage to receive proper credit\footnote{See
+\url{http://www.sagemath.org/developmentmap.html}}. (If
ever you feel you are not receiving proper credit for anything you
submit to \sage, please let the development team know!)
@@ 279,9 +328,13 @@
have to represent the exact \SAGE/Python types. For example, use
``integer'' for anything that behaves like an integer; you do not
have to put a precise type name such as \code{int}.
\item An EXAMPLES block for examples. This is {\em not} optional.
+\item An EXAMPLES block for examples. This is {\em not} optional. These
+examples are used for automatic testing before each release and new functions
+without these doctests will not be accepted for inclusion with \SAGE.
+\item An ALGORITHM block (optional) which indicates what software and/or what
+algorithm is used. For example \code{ALGORITHM: Uses Pari}.
\item A NOTES block for special notes (optional). Include information
 such as algorithm used, references, etc.
+ such as references, purpose etc.
\item An AUTHORS block (optional, but encouraged for important
functions, so users can see from the docstring who wrote it and
therefore whom to contact if they have questions).
@@ 295,7 +348,6 @@
This function returns the point $(x^5,y)$.
INPUT:
 self  anything special about self
x  integer (default: 1) the ...
y  integer (default: 2) the ...
@@ 336,8 +388,7 @@
You are {\em strongly encouraged} to:
\begin{itemize}
\item Use nice \Latex formating everywhere but in the
 \code{INPUT/OUTPUT} blocks. If you use backslashes, either use
+\item Use nice \Latex formating everywhere. If you use backslashes, either use
double backslashes or place an {\tt r} right before the first triple
opening quote. For example,
%skip
@@ 371,7 +422,8 @@
regular basis, and are crucial for the quality and adaptability of
\sage. Without such examples, small changes to one part of \sage
that break something else might not go seen until much later when
 someone uses the system, which is unacceptable.
+ someone uses the system, which is unacceptable. Note that no new functions
+ without will be accepted for inclusion in \SAGE.
\end{itemize}
The code in the examples should pass automatic testing. This means
@@ 423,6 +475,10 @@
sage: c._hash #random
1335416675971793195
\end{verbatim}
+ However, most functions generating pseudorandom output do not need this tag
+ since the doctesting framework guarantees the state of the
+pseudo random number generators (PRNGs) used in \SAGE for a given doctest. See
+\ref{ch:random} for details on this framework.
\item If a line contains the text \code{long time} then that line is
not tested unless the {\code long} option is given, e.g.,
@@ 459,10 +515,12 @@
class \code{EllipticCurve_finite_field} from the
\code{SAGE_ROOT/devel/sage/sage/schemes/elliptic_curves/ell_finite_field.py}
contains
+{\small
\begin{verbatim}
 sage: EllipticCurve(GF(41),[2,5])._magma_init_() # optional  requires Magma
+ sage: E = EllipticCurve(GF(41),[2,5])
+ sage: E._magma_init_() # optional  requires Magma
'EllipticCurve([_sage_[1]GF(41)!0,GF(41)!0,GF(41)!0,GF(41)!2,GF(41)!5])'
\end{verbatim}
+\end{verbatim}}
\item If the entire documentation string contains all three words
\code{optional}, \code{package}, and \code{installed}, then
@@ 478,6 +536,441 @@
implemented}, one can use the results of such a search to direct
further development on \sage.
+\section{Random Numbers}\label{ch:random}
+
+(This section was originally written by Carl Witty)
+
+The \code{sage.misc.randstate} module manages all the available pseudorandom
+number generators
+in \Sage. (For the rest of the documentation, we will drop the ``pseudo''.)
+
+The goal is to allow algorithms using random numbers to be reproducible from one
+run of \sage to the next, and (to the extent possible) from one machine to the
+next (even across different operating systems and architectures).
+
+There are two parts to the API. First we will describe the
+commandlineoriented API, for setting random number generator seeds.
+Then we will describe the library API, for people writing \sage library code
+that uses random numbers.
+
+We'll start with the simplest usage: setting fixed random number seeds
+and showing that these lead to reproducible results.
+
+\begin{verbatim}
+sage: K. = QQ[]
+sage: G = PermutationGroup([[(1,2,3),(4,5)], [(1,2)]])
+sage: rgp = Gp()
+sage: def gap_randstring(n):
+... current_randstate().set_seed_gap()
+... return gap(n).SCRRandomString()
+sage: def rtest():
+... current_randstate().set_seed_gp(rgp)
+... return (ZZ.random_element(1000), RR.random_element(),
+... K.random_element(), G.random_element(),
+... gap_randstring(5),
+... rgp.random(), ntl.ZZ_random(99999),
+... random())
+\end{verbatim}
+
+The above test shows the results of six different random number generators, in
+three different processes. The random elements from \code{ZZ}, \code{RR}, and
+\code{K} all derive from a single GMPbased random number generator. The random
+element from \code{G} comes from a GAP subprocess. The random ``string''
+(5element binary list) is also from a GAP subprocess, using the ``classical''
+GAP random generator. The random number from \code{rgp} is from a Pari/gp
+subprocess. NTL's \code{ZZ_random} uses a separate NTL random number generator
+in the main \sage process. And \code{random()} is from a Python
+\class{random.Random} object.
+
+Here we see that setting the random number seed really does make the
+results of these random number generators reproducible.
+
+\begin{verbatim}
+sage: set_random_seed(0)
+sage: rtest()
+(303, 0.187141682737491, 1/2*x^2  1/95*x  1/2, (1,2), [ 0, 0, 0, 0, 1 ],
+1698070399, 8045, 0.96619117347084138)
+sage: set_random_seed(1)
+sage: rtest()
+(978, 0.184109262667515, 3*x^2  1/12, (2,3), [ 0, 1, 1, 0, 0 ], 1046254370,
+60359, 0.83350776541997362)
+sage: set_random_seed(2)
+sage: rtest()
+(207, 0.505364206568040, 4*x^2 + 1/2, (1,2)(4,5), [ 0, 0, 1, 0, 1 ], 2137873234,
+27695, 0.19982565117278328)
+sage: set_random_seed(0)
+sage: rtest()
+(303, 0.187141682737491, 1/2*x^2  1/95*x  1/2, (1,2), [ 0, 0, 0, 0, 1 ],
+1698070399, 8045, 0.96619117347084138)
+sage: set_random_seed(1)
+sage: rtest()
+(978, 0.184109262667515, 3*x^2  1/12, (2,3), [ 0, 1, 1, 0, 0 ], 1046254370,
+60359, 0.83350776541997362)
+sage: set_random_seed(2)
+sage: rtest()
+(207, 0.505364206568040, 4*x^2 + 1/2, (1,2)(4,5), [ 0, 0, 1, 0, 1 ], 2137873234,
+27695, 0.19982565117278328)
+\end{verbatim}
+
+Once we've set the random number seed, we can check what seed was used.
+(This is not the current random number state; it does not change when
+random numbers are generated.)
+
+\begin{verbatim}
+sage: set_random_seed(12345)
+sage: initial_seed()
+12345L
+sage: rtest()
+(720, 0.0216737401150802, x^2  x, (), [ 1, 0, 0, 0, 0 ], 1506569166, 14005,
+0.92053315995181839)
+sage: initial_seed()
+12345L
+\end{verbatim}
+
+If \code{set_random_seed()} is called with no argument, then a new
+seed is automatically selected. On operating systems that support it,
+the new seed comes from \function{os.urandom}; this is intended to be
+a truly random (not pseudorandom), cryptographically secure number.
+(Whether it is actually cryptographically secure depends on operating
+system details that are outside the control of \sage.)
+
+If \function{os.urandom} is not supported, then the new seed comes
+from the current time, which is definitely not cryptographically
+secure.
+
+\begin{verbatim}
+sage: set_random_seed()
+sage: r = rtest()
+sage: r # random
+(909, 0.407373370020575, 6/7*x^2 + 1, (1,2,3)(4,5), 985329107, 21461,
+0.30047071049504859)
+\end{verbatim}
+
+After setting a new random number seed with \code{set_random_seed()},
+we can use \function{initial_seed} to see what seed was automatically
+selected, and call \function{set_random_seed} to restart the same
+random number sequence.
+
+\begin{verbatim}
+sage: s = initial_seed()
+sage: s # random
+336237747258024892084418842839280045662L
+sage: set_random_seed(s)
+sage: r2 = rtest()
+sage: r == r2
+True
+\end{verbatim}
+
+Whenever \sage starts, \code{set_random_seed()} is called just before
+command line interaction starts; so every \sage run starts with a
+different random number seed. This seed can be recovered with
+\code{initial_seed()} (as long as the user has not set a different
+seed with \function{set_random_seed}), so that the results of this run
+can be reproduced in another run; or this automatically selected seed
+can be overridden with, for instance, \code{set_random_seed(0)}.
+
+We can demonstrate this startup behavior by running a new instance of
+\sage as a subprocess.
+
+\begin{verbatim}
+sage: subsage = Sage()
+sage: s = ZZ(subsage('initial_seed()'))
+sage: r = ZZ(subsage('ZZ.random_element(2^200)'))
+sage: s # random
+161165040149656168853863459174502758403
+sage: r # random
+1273828861620427462924151488498075119241254209468761367941442
+sage: set_random_seed(s)
+sage: r == ZZ.random_element(2^200)
+True
+\end{verbatim}
+
+Note that wrappers of all the random number generation methods from
+Python's \module{random} module are available at the \sage command
+line, and these wrappers are properly affected by set_random_seed().
+
+\begin{verbatim}
+sage: set_random_seed(0)
+sage: random(), getrandbits(20), uniform(5.0, 10.0), normalvariate(0, 1)
+(0.111439293741037, 539332L, 8.26785106378383, 1.3893337539828183)
+sage: set_random_seed(1)
+sage: random(), getrandbits(20), uniform(5.0, 10.0), normalvariate(0, 1)
+(0.82940228518742587, 624859L, 5.77894484361117, 0.42013668263087578)
+sage: set_random_seed(0)
+sage: random(), getrandbits(20), uniform(5.0, 10.0), normalvariate(0, 1)
+(0.111439293741037, 539332L, 8.26785106378383, 1.3893337539828183)
+\end{verbatim}
+
+That pretty much covers what you need to know for commandline use of
+this module. Now let's move to what authors of \sage library code
+need to know about the module.
+
+First, we'll cover doctesting. Every docstring now has an implicit
+\code{set_random_seed(0)} prepended. Any uses of \code{# random} that
+are based on random numbers under the control of this module should be
+removed, and the reproducible answers inserted instead.
+
+This practice has two potential drawbacks. First, it increases the work
+of maintaining doctests; for instance, in a long docstring that has
+many doctests that depend on random numbers, a change near the beginning
+(for instance, adding a new doctest) may invalidate all later doctests
+in the docstring. To reduce this downside, you may add calls to
+\code{set_random_seed(0)} throughout the docstring (in the extreme case,
+before every doctest).
+
+Second, the \code{# random} in the doctest served as a signal to the
+reader of the docstring that the result was unpredictable and that it
+would not be surprising to get a different result when trying out the
+examples in the doctest. If a doctest specifically refers to
+\code{ZZ.random_element()} (for instance), this is presumably enough
+of a signal to render this function of \code{# random} unnecessary.
+However, some doctests are not obviously (from the name) random, but
+do depend on random numbers internally, such as the
+\method{composition_series} method of a \class{PermutationGroup}. In
+these cases, the convention is to insert the following text at the
+beginning of the EXAMPLES section.
+
+\begin{verbatim}
+ These computations use pseudorandom numbers, so we set the
+ seed for reproducible testing.
+ sage: set_random_seed(0)
+\end{verbatim}
+
+Note that this call to \code{set_random_seed(0)} is redundant, since
+\code{set_random_seed(0)} is automatically inserted at the beginning
+of every docstring; but it makes the example reproducible for somebody
+who just types the lines from the doctest and doesn't know about the
+automatic \code{set_random_seed(0)}.
+
+Next, let's cover setting the random seed from library code. The
+first rule is that library code should never call
+\function{set_random_seed}; this function is only for commandline
+use. Instead, if the library code wants to use a different random
+seed, it should use \code{with seed(s):}; this will use the new seed
+within the scope of the \code{with}, but will revert to the previous seed
+once the \code{with} is completed. (Or the library can use
+\code{with seed():} to get a seed automatically selected using
+\code{os.urandom()} or the current time, in the same way as described for
+\code{set_random_seed()} above.)
+
+Ideally, using \code{with seed(s):} should not affect the outer random
+number sequence at all; we will call this property ``isolation.'' We
+achieve isolation for most, but not all, of the random number generators
+in \sage (we fail for generators, such as NTL, that do not provide an API
+to retrieve the current random number state).
+
+We'll demonstrate isolation. First, we show the sequence of random numbers
+that you get without intervening \code{with seed}.
+
+\begin{verbatim}
+sage: set_random_seed(0)
+sage: r1 = rtest(); r1
+(303, 0.187141682737491, 1/2*x^2  1/95*x  1/2, (1,2), [ 0, 0, 0, 0, 1 ],
+1698070399, 8045, 0.96619117347084138)
+sage: r2 = rtest(); r2
+(105, 0.581229341007821, x^2  x  6, (1,3,2)(4,5), [ 1, 0, 0, 1, 1 ],
+697338742, 1271, 0.001767155077382232)
+\end{verbatim}
+
+We get slightly different results with an intervening \code{with seed}.
+
+\begin{verbatim}
+sage: set_random_seed(0)
+sage: r1 == rtest()
+True
+sage: with seed(1): rtest()
+(978, 0.184109262667515, 3*x^2  1/12, (2,3), [ 0, 1, 1, 0, 0 ], 1046254370,
+60359, 0.83350776541997362)
+sage: r2m = rtest(); r2m
+(105, 0.581229341007821, x^2  x  6, (1,3,2)(4,5), [ 1, 0, 0, 1, 1 ],
+697338742, 19769, 0.001767155077382232)
+sage: r2m == r2
+False
+\end{verbatim}
+
+We can see that \var{r2} and \var{r2m} are the same except for the
+call to \function{ntl.ZZ_random}, which produces different results
+with and without the \code{with seed}.
+
+However, we do still get a partial form of isolation, even in this
+case, as we see in this example:
+
+\begin{verbatim}
+sage: set_random_seed(0)
+sage: r1 == rtest()
+True
+sage: with seed(1): (rtest(), rtest())
+((978, 0.184109262667515, 3*x^2  1/12, (2,3), [ 0, 1, 1, 0, 0 ], 1046254370,
+60359, 0.83350776541997362), (138, 0.247578366457583, 2*x  24, (), [ 1, 1, 1,
+0, 1 ], 1077419109, 10234, 0.0033332230808060803))
+sage: r2m == rtest()
+True
+\end{verbatim}
+
+The NTL results after the \code{with seed} don't depend on how many
+NTL random numbers were generated inside the \code{with seed}.
+
+Unfortunately, Cython does not yet support the \code{with} statement.
+Instead, you must use the equivalent \code{try}/\code{finally} statement:
+
+\begin{verbatim}
+sage: set_random_seed(0)
+sage: r1 == rtest()
+True
+sage: ctx = seed(1)
+sage: try:
+... ctx.__enter__()
+... rtest()
+... finally:
+... ctx.__exit__(None, None, None)
+
+(978, 0.184109262667515, 3*x^2  1/12, (2,3), [ 0, 1, 1, 0, 0 ], 1046254370,
+60359, 0.83350776541997362)
+False
+sage: r2m == rtest()
+True
+\end{verbatim}
+
+(In general, the above code is not exactly equivalent to the \code{with}
+statement, because if an exception happens in the body, the real
+\code{with} statement will pass the exception information as parameters to
+the \method{__exit__} method. However, our \method{__exit__} method
+ignores the exception information anyway, so the above is equivalent in
+our case.)
+
+Now we come to the last part of the documentation: actually generating
+random numbers in library code. First, the easy case: if you generate
+random numbers only by calling other \sage library code (such as
+\method{random_element} methods on parents), you don't need to do
+anything special; the other code presumably already interacts with
+this module correctly.
+
+Otherwise, it depends on what random number generator you want to use.
+
+\begin{description}
+\item[gmp_randstate_t] If you want to use some random number generator
+that takes a \code{gmp_randstate_t} (like \code{mpz_urandomm} or
+\code{mpfr_urandomb}), then use code like the following:
+\begin{verbatim}
+from sage.misc.randstate cimport randstate, current_randstate
+...
+
+ cdef randstate rstate = current_randstate()
+\end{verbatim}
+then a \code{gmp_randstate_t} is available as \code{rstate.gmp_state}.
+
+Fetch the current \class{randstate} with \code{current_randstate()} in
+every function that wants to use it; don't cache it globally or
+in a class. (Such caching would break \method{set_random_seed}).
+
+\item[Python] If you want to use the random number generators from the
+\module{random} module, you have two choices. The slightly easier choice
+is to import functions from \module{sage.misc.prandom}; for instance,
+you can simply replace \code{from random import randrange} with
+\code{from sage.misc.prandom import randrange}. However, this is
+slighly less efficient, because the wrappers in \module{sage.misc.prandom}
+look up the current \class{randstate} on each call. If you're generating
+many random numbers in a row, it's faster to instead do
+\begin{verbatim}
+from sage.misc.randstate import current_randstate
+...
+
+ randrange = current_randstate().python_random().randrange
+\end{verbatim}
+
+Fetch the current \class{randstate} with \code{current_randstate()} in
+every function that wants to use it; don't cache the
+\class{randstate}, the \class{Random} object returned by
+\method{python_random}, or the bound methods on that \class{Random}
+object globally or in a class. (Such caching would break
+\method{set_random_seed}).
+
+\item[GAP] If you are calling code in GAP that uses random numbers,
+call \method{set_seed_gap} at the beginning of your function, like this:
+\begin{verbatim}
+from sage.misc.randstate import current_randstate
+...
+
+ current_randstate().set_seed_gap()
+\end{verbatim}
+
+Fetch the current \class{randstate} with \code{current_randstate()} in
+every function that wants to use it; don't cache it globally or
+in a class. (Such caching would break \method{set_random_seed}).
+
+\item[Pari] If you are calling code in the Pari library that uses
+random numbers, call \method{set_seed_pari} at the beginning of your
+function, like this:
+\begin{verbatim}
+from sage.misc.randstate import current_randstate
+...
+
+ current_randstate().set_seed_pari()
+\end{verbatim}
+
+Fetch the current \class{randstate} with \code{current_randstate()} in
+every function that wants to use it; don't cache it globally or
+in a class. (Such caching would break \method{set_random_seed}).
+
+\item[Pari/gp] If you are calling code in a Pari/gp subprocess that
+uses random numbers, call \method{set_seed_gp} at the beginning of
+your function, like this:
+\begin{verbatim}
+from sage.misc.randstate import current_randstate
+...
+
+ current_randstate().set_seed_gp()
+\end{verbatim}
+This will set the seed in the gp process in sage.interfaces.gp.gp.
+If you have a different gp process, say in the variable \var{my_gp}, then
+call \code{set_seed_gp(my_gp)} instead.
+
+Fetch the current \class{randstate} with \code{current_randstate()} in
+every function that wants to use it; don't cache it globally or
+in a class. (Such caching would break \method{set_random_seed}).
+
+\item[NTL] If you are calling code in the NTL library that uses
+random numbers, call \method{set_seed_ntl} at the beginning of your
+function, like this:
+\begin{verbatim}
+from sage.misc.randstate import current_randstate
+...
+
+ current_randstate().set_seed_ntl(False)
+\end{verbatim}
+
+Fetch the current \class{randstate} with \code{current_randstate()} in
+every function that wants to use it; don't cache it globally or
+in a class. (Such caching would break \method{set_random_seed}).
+
+\item[libc] If you are writing code that calls the libc function
+\code{random()}: don't! The \code{random()} function does not give
+reproducible results across different operating systems, so we can't
+make portable doctests for the results. Instead, do:
+\begin{verbatim}
+from sage.misc.randstate cimport random
+\end{verbatim}
+The \function{random} function in \module{sage.misc.randstate} gives a
+31bit random number (the same range as the \function{random} in libc,
+on all systems I'm familiar with), but it uses the \code{gmp_randstate_t}
+in the current \class{randstate}, so it is portable.
+
+However, you may still need to set the libc random number state; for
+instance, if you are wrapping a library that uses \code{random()}
+internally and you don't want to change the library. In that case,
+call \method{set_seed_libc} at the beginning of your function, like this:
+\begin{verbatim}
+from sage.misc.randstate import current_randstate
+...
+
+ current_randstate().set_seed_libc(False)
+\end{verbatim}
+
+Fetch the current \class{randstate} with \code{current_randstate()} in
+every function that wants to use it; don't cache it globally or
+in a class. (Such caching would break \method{set_random_seed}).
+
+\end{description}
\section{Automated Testing}\label{ch:testing}
@@ 521,11 +1014,12 @@
on \code{.doctest_foo.py}.
\end{enumerate}
\note{{\em Note that line numbers in the errors
you might see apply to the file \code{.doctest_foo.py}, not
to the original file \code{foo.py}!} If you get errors,
feel free to inspect \code{.doctest_foo.py}; it is never
automatically deleted by \sage.}
+% malb: I think these numbers are correct.
+% \note{{\em Note that line numbers in the errors
+% you might see apply to the file \code{.doctest_foo.py}, not
+% to the original file \code{foo.py}!} If you get errors,
+% feel free to inspect \code{.doctest_foo.py}; it is never
+% automatically deleted by \sage.}
Your file passes these tests if the code in it will run when entered
at the \code{sage:} prompt with no special imports. Thus users are
@@ 575,6 +1069,7 @@
\section{Randomized Testing}
\label{ch:randomtesting}
+%malb: do we run randomized tests regulary?
In addition to all the examples in your docstrings, which serve as
both demonstrations and tests of your code, you should consider creating a
@@ 654,7 +1149,8 @@
\item Define a method \code{_latex_(self)} that returns a
\Latex representation of your object. It should be something that
 can be typeset correctly within math mode.
+ can be typeset correctly within math mode. Do not include opening and closing
+ \$'s.
\item Often objects are built up out of other \sage objects, and these
components should be typeset using the \code{latex} function.
@@ 680,7 +1176,7 @@
class X:
...
def _latex_(self):
 """
+ r"""
Return \Latex representation of X.
EXAMPLES:
@@ 701,9 +1197,10 @@
The standard Python printing method is \code{__repr__(self)}. In
\sage, that is for objects that derive from \code{SageObject} (which
is everything in \sage), instead define \code{_repr_(self)}.
% This is preferable because if you only define \code{_repr_(self)} and
% not \code{__repr__(self)}, then users can rename your object to print
% however they like.
+This is preferable because if you only define \code{_repr_(self)} and
+not \code{__repr__(self)}, then users can rename your object to print
+however they like. Also, some objects should print differently depending on the
+context.
Here is an example of the \code{_latex_} and \code{_repr_} functions
for the Pi class. It is from the file
@@ 748,8 +1245,6 @@
def adjacency_matrix(self, sparse=None, boundary_first=False):
...

 am = adjacency_matrix # shorter call makes life easier
\end{verbatim}
Similarly,
@@ 823,17 +1318,18 @@
\end{verbatim}
\item Raw literals can be very useful in certain cases. For instance,
 Python integers are typically much more efficient than \SAGE integers
+ Python integers can be more efficient than \SAGE integers
when they are very small; large \SAGE integers are much more
efficient than Python integers, since they are implemented using the
 GMP C library. For example, the first of these commands may be somewhat
 slower than the second:
\begin{verbatim}
 sage: v = [ 2*i for i in range(10000)]
 sage: v = [ 2r*i for i in range(10000r)]
\end{verbatim}
because the first uses \sage integers, while the second uses raw
Python integers.
+ GMP C library.
+% For example, the first of these commands may be somewhat
+% slower than the second:
+% \begin{verbatim}
+% sage: v = [ 2*i for i in range(10000)]
+% sage: v = [ 2r*i for i in range(10000r)]
+% \end{verbatim}
+% because the first uses \sage integers, while the second uses raw
+% Python integers.
\end{itemize}
@@ 1092,7 +1588,8 @@
If you don't have any exceptions explicitly listed (as a tuple), your
code will catch absolutely anything, including \code{ctrlC} and alarms,
and this will lead to confusion.
+and this will lead to confusion. Also, this might catch real errors which
+should be propagated to the user.
\section{Importing}
@@ 1120,9 +1617,11 @@
With this setup, running \sage will produce an error:
%skip
\begin{verbatim}
Exception exceptions.ImportError: 'cannot import name SteenrodAlgebra' in 'sage.rings.polynomial.polynomial_element.Polynomial_generic_dense.__normalize' ignored

ImportError Traceback (most recent call last)
+Exception exceptions.ImportError: 'cannot import name SteenrodAlgebra' \
+in 'sage.rings.polynomial.polynomial_element.\
+Polynomial_generic_dense.__normalize' ignored
+
+ImportError Traceback (most recent call last)
...
ImportError: cannot import name SteenrodAlgebra
@@ 1147,6 +1646,7 @@
as possible, since this is what dominates the \SAGE startup time, and
controlling the toplevel imports helps to do this.
+% malb: Describe late_import trick hereish.
\section{Using Optional Packages}
@@ 1154,7 +1654,8 @@
perhaps using a \code{try} and \code{except} block  when the optional
package is not available, and should give a hint about how to install
it. For example, typing \code{sage optional} gives a list of all
optional packages, so it might suggest to the user that they type that.
+optional packages, so it might suggest to the user that they type that. The
+command \code{optional_packages()} from within \SAGE also returns this list.
@@ 1163,8 +1664,9 @@
When writing code for \sage, use Python for the basic structure and
interface. For speed, efficiency, or convenience, you can implement
parts of the code using any of the following languages:
Cython, C/C++, Fortran 95, GAP, Singular, and GP/PARI. You can also
use the mwrank, GSL, NTL, and PARI C/C++ libraries. (And if you are
+Cython, C/C++, Fortran 95, GAP, Common Lisp, Singular, and GP/PARI. You can
+also use all C/C++ libraries included with \SAGE~\footnote{See \url{
+http://www.sagemath.org/linkscomponents.html} for a list}. (And if you are
okay with your code depending on optional \sage packages, you can use
Octave, or even Magma, Mathematica, or Maple.)
@@ 1173,14 +1675,13 @@
written in Cython. Later sections discuss the interfaces between
\sage and PARI, GAP, and Singular.


\section{Cython}
Cython is a compiled version of Python; it is based on Pyrex
(\url{http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/}). To
a large degree, Cython has changed based on what \sage's developers
needed: Cython has been developed in concert with \sage.
+needed: Cython has been developed in concert with \sage. However, it is an
+independent project now which is used beyond the scope of \SAGE.
As such, it is a young, but developing, language, with young, but
developing, documentation. See its web page,
@@ 1225,9 +1726,32 @@
['sage/graphs/chrompoly.pyx']
), \
\end{verbatim}
in \code{setup.py}. Then type \code{sage ba} to build \sage with the
new code.
+in \code{setup.py}. Also, the module  in this example \code{sage.graphs.ch
+rompoly}  needs to be added to the \code{packages} list in \code{setup.py}
+. Then type \code{sage b} to build \sage with the new code.
\end{enumerate}
+
+\subsection{Special Pragmas}
+%malb: needs flashing out, example
+If Cython code is either attached or loaded as a \verb.spyx file or loaded
+from the notebook as a \code{\%cython} block, the follow pragmas are available:
+
+\begin{description}
+\item[clang] may be either c or c++ indicating whether a C or
+ C++ compiler should be used
+\item[clib] additional libraries to be linked in, the space
+ separated list is split and passed to distutils.
+\item[cinclude] additional directories to search for header
+ files. The space separated list is split and
+ passed to distutils.
+\end{description}
+
+For example:
+\begin{verbatim}
+#clang C++
+#clib givaro
+#cinclude /usr/local/include/
+\end{verbatim}
\subsection{Attaching or Loading {\tt .spyx} Files}
@@ 1264,12 +1788,14 @@
\begin{verbatim}
sage: attach "power2.spyx"
\end{verbatim}
Cython is used for its speed. Here is a timed test on a 2.4 GHz iMac:
+Cython is used for its speed. Here is a timed test on a 2.6 GHz Opteron:
%skip
\begin{verbatim}
sage: time [n for n in range(10^5) if is2pow(n)]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536]
CPU time: 0.06 s, Wall time: 0.06 s
+[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
+65536]
+CPU times: user 0.60 s, sys: 0.00 s, total: 0.60 s
+Wall time: 0.60 s
\end{verbatim}
Now, the code in the file \code{power2.spyx} is valid Python, and if
we copy this to a file \code{powerslow.py} and load that, we get the
@@ 1279,11 +1805,12 @@
sage: load "powerslow.py"
sage: time [n for n in range(10^5) if is2pow(n)]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536]
CPU time: 1.80 s, Wall time: 1.84 s
+CPU times: user 1.01 s, sys: 0.04 s, total: 1.05 s
+Wall time: 1.05 s
\end{verbatim}
By the way, we could gain even a little more speed  cutting it down
to 0.03 s  with the Cython version with a type declaration, by
changing \code{def is2pow(n):} to \code{def is2pow(unsigned int n):}.
+By the way, we could gain even a little more speed with the Cython version with
+a type declaration, by changing \code{def is2pow(n):} to \code{def
+is2pow(unsigned int n):}.
@@ 1301,10 +1828,12 @@
(This chapter was written by Martin Albrecht.)
+%malb: explain why we didn't add matfrobenius to some decl.pxi
+
Here is the stepbystep guide to adding a new PARI functions to \SAGE.
We use the Frobenius form of a matrix as an example.
The heavy lifting for matrices over integers is implemented using the
+Some heavy lifting for matrices over integers is implemented using the
PARI library. To compute the Frobenius form in PARI the
\code{matfrobenius} function is used.
@@ 1325,8 +1854,9 @@
\code{SAGE_ROOT/devel/sage/sage/libs/pari/gen.pyx}, and this is where we add
the method \code{matfrobenius}:
+%malb: that docstring isn't up to Sage's standards, change it in the code and
+% then update it here.
\begin{verbatim}

def matfrobenius(self, flag=0):
"""
matfrobenius(M,{flag}): Return the Frobenius form of the
@@ 1340,8 +1870,11 @@
\end{verbatim}
The \code{_sig_on} statement is some magic to prevent SIGSEGVs from the PARI C
library to crash the \SAGE interpreter by catching these signals. The
\code{self.new_gen()} call constructs a new SAGEpythongen object from a given
+library to crash the \SAGE interpreter by catching these signals. Note that
+\code{self.new_gen()} calls a closing \code{_sig_off} macro. These two
+\emph{must always} come in pairs, i.e. every \code{_sig_on} must be matched by
+a closing \code{_sig_off}. The \code{self.new_gen()} call constructs a new
+SAGEpythongen object from a given
pariCgen where the pariCgen is stored as the SAGEpythongen.g attribute.
The \code{matfrobenius} call is just a call to the PARI C library function
\code{matfrobenius} with the appropriate parameters.
@@ 1364,6 +1897,8 @@
so we can do
\code{matfrobenius()} as well as
\code{.matfrobenius()}:
+
+%malb: no docstring!
\begin{verbatim}
def matfrobenius(self): return pari(self).matfrobenius()
\end{verbatim}
@@ 1372,6 +1907,8 @@
\code{matrix_integer} class where we call the \code{matfrobenius()}
method on the PARI object associated to the matrix after doing some
sanity checking. Then we convert output from PARI to \SAGE objects:
+
+%malb: this docstring isn't up to Sage's standards.
\begin{verbatim}
def frobenius(self,flag=0):
"""
@@ 1404,7 +1941,8 @@
[ 0 2/15 1/15])
"""
if self.nrows()!=self.ncols():
 raise ArithmeticError, "frobenius matrix of nonsquare matrix not defined."
+ raise ArithmeticError, \
+ "frobenius matrix of nonsquare matrix not defined."
v = self._pari_().matfrobenius(flag)
if flag==0:
return self.matrix_space()(v.python())
@@ 1540,7 +2078,7 @@
A ``hard'' example is left as an exercise! Here are a few ideas.
\begin{itemize}

+%malb: are these examples still valid.
\item Write a wrapper for GAP's \code{FreeLieAlgebra} function (or,
more generally, all the finitely presented Lie algebra fuunctions in
GAP). This would require creating new Python objects.
@@ 1556,6 +2094,9 @@
\end{itemize}
\section{Singular}
+
+%malb: this section needs heavy updating, it is outdated, needs libSingular,
+%suggests uglyish hacks
(The first version of this chapter was written by David Joyner.)
@@ 1780,9 +2321,9 @@
% }
From looking at the output, notice that our wrapper program will need to
+From looking at the output, notice that our wrapper function will need to
parse the string represented by $L$ above, so
let us write a separate program to do just that. This requires figuring out how
+let us write a separate function to do just that. This requires figuring out how
to determine where the coordinates of the points are placed in the string L.
Python has some very useful string manipulation commands to do just that.
@@ 1790,7 +2331,7 @@
\begin{verbatim}
def points_parser(string_points,F):
"""
 This program will parse a string of points
+ This function will parse a string of points
of X over a finite field F returned by Singular's NSplaces
command into a Python list of points with entries from F.
EXAMPLE
@@ 2116,7 +2657,7 @@
\begin{itemize}
\item The \sage tutorial:
\code{SAGE_ROOT/devel/doc/tut/tut.tex}
\item The \sage programming guide:
+\item The \sage developer's guide:
\code{SAGE_ROOT/devel/doc/prog/prog.tex}
\item Constructions in \sage:
\code{SAGE_ROOT/devel/doc/const/const.tex}
@@ 2145,16 +2686,17 @@
\begin{itemize}
\item the Google group \code{sagesupport}, at
\url{http://groups.google.com/group/sagesupport}. According to the
group's official description, ``This group gives help and support to
those who have problems with \sage (installation, syntax, etc).''
+\url{http://groups.google.com/group/sagesupport}. This group gives help and
+support to those who have problems with \sage (installation, syntax, etc).
+The IRC channel \#sagesupport on freenode serves the same purpose.
\item the Google group \code{sagedevel}, at
\url{http://groups.google.com/group/sagedevel}. According to the
group's description, ``This list is for \sage development and is about
programming, design and technical issues.'' This is a great place to
post questions about whether certain behavior is a bug, or whether a
certain feature ought to be implemented (or how it ought to be
implemented), or similar issues.
+\url{http://groups.google.com/group/sagedevel}. This list is for \sage
+development and is about programming, design and technical issues. This is a
+great place to post questions about whether certain behavior is a bug, or
+whether a certain feature ought to be implemented (or how it ought to be
+implemented), or similar issues. Also implementation issues are discussed here
+and the general direction of the project. The matching IRC channel is
+\#sagedevel on freenode.
\item Mercurial: this is the source control system that is included
with \SAGE. Use this to produce patches for \sage. See
Chapter~\ref{ch:mercurial} for a full discussion of Mercurial.
@@ 2166,9 +2708,9 @@
\section{Inclusion Procedure for New \sage Code}
+\section{Inclusion Procedure for New Packages}
For code to become part of \sage's core, it must meet the
+For a package to become part of \sage's standard distribution, it must meet the
following requirements:
\begin{itemize}
@@ 2229,7 +2771,7 @@
for doing development is available in your copy of \SAGE.
Before using Mercurial,
make sure to define your username and password so the
+make sure to define your username so the
patches you make are identified as yours. Make a
file \verb+~/.hgrc+ in your home directory like this one:
%skip
@@ 2307,7 +2849,9 @@
Note that you can also start a very nice web server that allows you to
navigate your repository with a web browser, or pull patches from it
remotely, by typing \code{hg_sage.serve()}.
+remotely, by typing \code{hg_sage.serve()}. Then open your webbrowser and point
+it to \url{http://localhost:8000} which is the default listening address for
+Mecurial.
Finally, if you want to apply a patch file (perhaps you've downloaded
a patch from the trac server for review), use the command
@@ 2383,7 +2927,38 @@
Put your files in that directory.
\item[(c)]
Create an executable shell script \code{mypackage0.1/spkginstall}.
+Create an executable shell script \code{mypackage0.1/spkginstall} following
+the skeleton given below.
+\begin{verbatim}
+ #!/usr/bin/env bash
+
+if [ "$SAGE_LOCAL" = "" ]; then
+ echo "SAGE_LOCAL undefined ... exiting";
+ echo "Maybe run 'sage sh'?"
+ exit 1
+fi
+
+cd src
+
+./configure prefix="$SAGE_LOCAL"
+if [ $? ne 0 ]; then
+ echo "Error configuring PACKAGE_NAME."
+ exit 1
+fi
+
+make
+if [ $? ne 0 ]; then
+ echo "Error building PACKAGE_NAME."
+ exit 1
+fi
+
+make install
+if [ $? ne 0 ]; then
+ echo "Error installing PACKAGE_NAME."
+ exit 1
+fi
+\end{verbatim}
+
\item[(d)]
The script \code{spkginstall} is run during installation
@@ 2424,21 +2999,20 @@
automatically install it by typing \code{sage i mypackageversion.spkg}.
\end{itemize}
If your package depends on another package, say GAP, then you should
check that this other package has been installed. In the case of GAP,
it is installed into the directory \code{SAGE_ROOT/local/lib/gap4.4.10/}
and your \code{spkginstall} script should check that this exists,
with the code like the following:
+If your package depends on another package, say boehm_gc, then you should
+check that this other package has been installed. Your \code{spkginstall}
+script should check that it exists, with the code like the following:
%skip
\begin{verbatim}
if [ ! d $SAGE_ROOT/local/lib/gap4.4.10 ]; then
 echo "This package requires that GAP 4.4.10 is installed."
+BOEHM_GC=`cd $SAGE_ROOT/spkg/standard/; ./newest_version boehm_gc`
+if [ $? ne 0 ]; then
+ echo "Failed to find boehm_gc. Please install the boehm_gc spkg"
exit 1
fi
\end{verbatim}
\emph{Caveat}: Do {\em not} just
copy to \code{SAGE_ROOT/local/lib/gap*/} since that will copy
+copy to e.g. \code{SAGE_ROOT/local/lib/gap*/} since that will copy
your package to the lib directory of the {\em old} version of GAP if
GAP is upgraded.
@@ 2448,77 +3022,77 @@
that's where you'd put it. You'd also want to have relevant Python code
to make the Magma code easily usable.
\textbf{Example}:
These instructions provide directions for creating a particular
\sage package.

\begin{itemize}
\item
Download \code{guava3.6.tar.gz} (the tarball for GUAVA, the
GAP errorcorrecting codes package) from
\url{http://www.gapsystem.org/Packages/guava.html}.

\item
Suppose you have a directory \code{sagefiles}.
Within that, create a subdirectory \code{guava3.6}.
Extract the tarball into the directory \code{guava3.6}.

\item
Create a file \code{guava3.6/spkginstall} with the following
contents:
%skip
\begin{verbatim}
#!/bin/sh

if [ ! d $SAGE_ROOT/local/lib/gap4.4.10 ]; then
 echo "This package requires that GAP 4.4.10 is installed."
 exit 1
fi

cp pr guava3.6 $SAGE_ROOT/local/lib/gap4.4.10/pkg/

cd $SAGE_ROOT/local/lib/gap4.4.10/pkg/guava3.6
./configure ../..
make
\end{verbatim}

Make it executable with \code{chmod +x spkginstall}.

\item
In the directory \code{sagefiles},
issue the command

%skip
\begin{verbatim}
 sage pkg guava3.6
\end{verbatim}
This will do some checks, run tar/bz2, and create the spkg file,
\code{guava3.6.spkg}, in the
directory \code{sagefiles},
\end{itemize}

To test this, within the \code{sagefiles} directory, type
%skip
\begin{verbatim}
 sage i guava3.6.spkg
\end{verbatim}
It should install and compile the guava program in sage.
To test its functionality, one could do the following:

\begin{verbatim}
sage: gap(`LoadPackage("guava")') # requires optional package
true
sage: gap(`HammingCode(3,3)') # requires optional package
a linear [13,10,3]1 Hamming (3,3) code over GF(3)
\end{verbatim}

To build it again if you've already installed the package, use
%skip
\begin{verbatim}
 sage f guava3.6.spkg
\end{verbatim}


+% \textbf{Example}:
+% These instructions provide directions for creating a particular
+% \sage package.
+%
+% \begin{itemize}
+% \item
+% Download \code{guava3.6.tar.gz} (the tarball for GUAVA, the
+% GAP errorcorrecting codes package) from
+% \url{http://www.gapsystem.org/Packages/guava.html}.
+%
+% \item
+% Suppose you have a directory \code{sagefiles}.
+% Within that, create a subdirectory \code{guava3.6}.
+% Extract the tarball into the directory \code{guava3.6}.
+%
+% \item
+% Create a file \code{guava3.6/spkginstall} with the following
+% contents:
+% %skip
+% \begin{verbatim}
+% #!/bin/sh
+%
+% if [ ! d $SAGE_ROOT/local/lib/gap4.4.10 ]; then
+% echo "This package requires that GAP 4.4.10 is installed."
+% exit 1
+% fi
+%
+% cp pr guava3.6 $SAGE_ROOT/local/lib/gap4.4.10/pkg/
+%
+% cd $SAGE_ROOT/local/lib/gap4.4.10/pkg/guava3.6
+% ./configure ../..
+% make
+% \end{verbatim}
+%
+% Make it executable with \code{chmod +x spkginstall}.
+%
+% \item
+% In the directory \code{sagefiles},
+% issue the command
+%
+% %skip
+% \begin{verbatim}
+% sage pkg guava3.6
+% \end{verbatim}
+% This will do some checks, run tar/bz2, and create the spkg file,
+% \code{guava3.6.spkg}, in the
+% directory \code{sagefiles},
+% \end{itemize}
+%
+% To test this, within the \code{sagefiles} directory, type
+% %skip
+% \begin{verbatim}
+% sage i guava3.6.spkg
+% \end{verbatim}
+% It should install and compile the guava program in sage.
+% To test its functionality, one could do the following:
+%
+% \begin{verbatim}
+% sage: gap(`LoadPackage("guava")') # requires optional package
+% true
+% sage: gap(`HammingCode(3,3)') # requires optional package
+% a linear [13,10,3]1 Hamming (3,3) code over GF(3)
+% \end{verbatim}
+%
+% To build it again if you've already installed the package, use
+% %skip
+% \begin{verbatim}
+% sage f guava3.6.spkg
+% \end{verbatim}
+%
+%
\chapter{The \sage Trac Server: Submitting Patches and Packages}
@@ 2646,8 +3220,7 @@
Download it (from the window displaying the patch, see the
``Download'' option at the bottom of the page). Apply it (using
\code{hg_sage.patch('filename')}, for example) to your copy of \sage,
and build \sage with the new code by typing \code{sage b} (for
patches to .py files) or \code{sage ba} (for patches to .pyx files).
+and build \sage with the new code by typing \code{sage b}.
Now ask yourself questions like these:
\begin{itemize}
@@ 2687,7 +3260,7 @@
\section{Closing Tickets}
Don't close tickets. That is the job of the \sage administrators. If
+Don't close tickets. That is the job of the acting \sage release manager. If
you feel strongly that a ticket should be closed or deleted, send
email to the current release manager explaining the situation.