|
Packit |
67cb25 |
\input texinfo @c -*-texinfo-*-
|
|
Packit |
67cb25 |
@c %**start of header
|
|
Packit |
67cb25 |
@setfilename gsl-design.info
|
|
Packit |
67cb25 |
@settitle GNU Scientific Library
|
|
Packit |
67cb25 |
@finalout
|
|
Packit |
67cb25 |
@c -@setchapternewpage odd
|
|
Packit |
67cb25 |
@c %**end of header
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@dircategory Scientific software
|
|
Packit |
67cb25 |
@direntry
|
|
Packit |
67cb25 |
* GSL-design: (GSL-design). GNU Scientific Library -- Design
|
|
Packit |
67cb25 |
@end direntry
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@comment @include version-design.texi
|
|
Packit |
67cb25 |
@set GSL @i{GNU Scientific Library}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@ifinfo
|
|
Packit |
67cb25 |
This file documents the @value{GSL}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2004 The GSL Project.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Permission is granted to copy, distribute and/or modify this document
|
|
Packit |
67cb25 |
under the terms of the GNU Free Documentation License, Version 1.2 or
|
|
Packit |
67cb25 |
any later version published by the Free Software Foundation; with no
|
|
Packit |
67cb25 |
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
|
|
Packit |
67cb25 |
copy of the license is included in the section entitled ``GNU Free
|
|
Packit |
67cb25 |
Documentation License''.
|
|
Packit |
67cb25 |
@end ifinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@titlepage
|
|
Packit |
67cb25 |
@title GNU Scientific Library -- Design document
|
|
Packit |
67cb25 |
@comment @subtitle Edition @value{EDITION}, for gsl Version @value{VERSION}
|
|
Packit |
67cb25 |
@comment @subtitle @value{UPDATED}
|
|
Packit |
67cb25 |
@author Mark Galassi
|
|
Packit |
67cb25 |
Los Alamos National Laboratory
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@author James Theiler
|
|
Packit |
67cb25 |
Astrophysics and Radiation Measurements Group, Los Alamos National Laboratory
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@author Brian Gough
|
|
Packit |
67cb25 |
Network Theory Limited
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@page
|
|
Packit |
67cb25 |
@vskip 0pt plus 1filll
|
|
Packit |
67cb25 |
Copyright @copyright{} 1996,1997,1998,1999,2000,2001,2004 The GSL Project.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Permission is granted to make and distribute verbatim copies of
|
|
Packit |
67cb25 |
this manual provided the copyright notice and this permission notice
|
|
Packit |
67cb25 |
are preserved on all copies.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Permission is granted to copy and distribute modified versions of this
|
|
Packit |
67cb25 |
manual under the conditions for verbatim copying, provided that the entire
|
|
Packit |
67cb25 |
resulting derived work is distributed under the terms of a permission
|
|
Packit |
67cb25 |
notice identical to this one.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Permission is granted to copy and distribute translations of this manual
|
|
Packit |
67cb25 |
into another language, under the above conditions for modified versions,
|
|
Packit |
67cb25 |
except that this permission notice may be stated in a translation approved
|
|
Packit |
67cb25 |
by the Foundation.
|
|
Packit |
67cb25 |
@end titlepage
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@contents
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Top, Motivation, (dir), (dir)
|
|
Packit |
67cb25 |
@top About GSL
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@ifinfo
|
|
Packit |
67cb25 |
This file documents the design of @value{GSL}, a collection of numerical
|
|
Packit |
67cb25 |
routines for scientific computing.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
More information about GSL can be found at the project homepage,
|
|
Packit |
67cb25 |
@uref{http://www.gnu.org/software/gsl/}.
|
|
Packit |
67cb25 |
@end ifinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The @value{GSL} is a library of scientific subroutines. It aims to
|
|
Packit |
67cb25 |
provide a convenient interface to routines that do standard (and not so
|
|
Packit |
67cb25 |
standard) tasks that arise in scientific research. More than that, it
|
|
Packit |
67cb25 |
also provides the source code. Users are welcome to alter, adjust,
|
|
Packit |
67cb25 |
modify, and improve the interfaces and/or implementations of whichever
|
|
Packit |
67cb25 |
routines might be needed for a particular purpose.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
GSL is intended to provide a free equivalent to existing proprietary
|
|
Packit |
67cb25 |
numerical libraries written in C or Fortran, such as NAG, IMSL's CNL,
|
|
Packit |
67cb25 |
IBM's ESSL, and SGI's SCSL.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The target platform is a low-end desktop workstation. The goal is to
|
|
Packit |
67cb25 |
provide something which is generally useful, and the library is aimed at
|
|
Packit |
67cb25 |
general users rather than specialists.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@menu
|
|
Packit |
67cb25 |
* Motivation::
|
|
Packit |
67cb25 |
* Contributing::
|
|
Packit |
67cb25 |
* Design::
|
|
Packit |
67cb25 |
* Bibliography::
|
|
Packit |
67cb25 |
* Copying::
|
|
Packit |
67cb25 |
* GNU Free Documentation License::
|
|
Packit |
67cb25 |
@end menu
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Motivation, Contributing, Top, Top
|
|
Packit |
67cb25 |
@chapter Motivation
|
|
Packit |
67cb25 |
@cindex numerical analysis
|
|
Packit |
67cb25 |
@cindex free software
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There is a need for scientists and engineers to have a numerical library
|
|
Packit |
67cb25 |
that:
|
|
Packit |
67cb25 |
@itemize @bullet
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
is free (in the sense of freedom, not in the sense of gratis; see the
|
|
Packit |
67cb25 |
GNU General Public License), so that people can use that library,
|
|
Packit |
67cb25 |
redistribute it, modify it @dots{}
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
is written in C using modern coding conventions, calling conventions,
|
|
Packit |
67cb25 |
scoping @dots{}
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
is clearly and pedagogically documented; preferably with TeXinfo, so as
|
|
Packit |
67cb25 |
to allow online info, WWW and TeX output.
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
uses top quality state-of-the-art algorithms.
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
is portable and configurable using @emph{autoconf} and @emph{automake}.
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
basically, is GNUlitically correct.
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There are strengths and weaknesses with existing libraries:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{Netlib} (http://www.netlib.org/) is probably the most advanced set
|
|
Packit |
67cb25 |
of numerical algorithms available on the net, maintained by AT&T.
|
|
Packit |
67cb25 |
Unfortunately most of the software is written in Fortran, with strange
|
|
Packit |
67cb25 |
calling conventions in many places. It is also not very well collected,
|
|
Packit |
67cb25 |
so it is a lot of work to get started with netlib.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{GAMS} (http://gams.nist.gov/) is an extremely well organized set
|
|
Packit |
67cb25 |
of pointers to scientific software, but like netlib, the individual
|
|
Packit |
67cb25 |
routines vary in their quality and their level of documentation.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{Numerical Recipes} (http://www.nr.com,
|
|
Packit |
67cb25 |
http://cfata2.harvard.edu/nr/) is an excellent book: it explains the
|
|
Packit |
67cb25 |
algorithms in a very clear way. Unfortunately the authors released the
|
|
Packit |
67cb25 |
source code under a license which allows you to use it, but prevents you
|
|
Packit |
67cb25 |
from re-distributing it. Thus Numerical Recipes is not @emph{free} in
|
|
Packit |
67cb25 |
the sense of @emph{freedom}. On top of that, the implementation suffers
|
|
Packit |
67cb25 |
from @emph{fortranitis} and other
|
|
Packit |
67cb25 |
limitations. [http://www.lysator.liu.se/c/num-recipes-in-c.html]
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{SLATEC} is a large public domain collection of numerical routines
|
|
Packit |
67cb25 |
in Fortran written under a Department of Energy program in the
|
|
Packit |
67cb25 |
1970's. The routines are well tested and have a reasonable overall
|
|
Packit |
67cb25 |
design (given the limitations of that era). GSL should aim to be a
|
|
Packit |
67cb25 |
modern version of SLATEC.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{NSWC} is the Naval Surface Warfare Center numerical library. It
|
|
Packit |
67cb25 |
is a large public-domain Fortran library, containing a lot of
|
|
Packit |
67cb25 |
high-quality code. Documentation for the library is hard to find, only
|
|
Packit |
67cb25 |
a few photocopies of the printed manual are still in circulation.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{NAG} and @emph{IMSL} both sell high-quality libraries which are
|
|
Packit |
67cb25 |
proprietary. The NAG library is more advanced and has wider scope than
|
|
Packit |
67cb25 |
IMSL. The IMSL library leans more towards ease-of-use and makes
|
|
Packit |
67cb25 |
extensive use of variable length argument lists to emulate "default
|
|
Packit |
67cb25 |
arguments".
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{ESSL} and @emph{SCSL} are proprietary libraries from IBM and SGI.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{Forth Scientific Library} [see the URL
|
|
Packit |
67cb25 |
http://www.taygeta.com/fsl/sciforth.html]. Mainly of interest to Forth
|
|
Packit |
67cb25 |
users.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{Numerical Algorithms with C} G. Engeln-Mullges, F. Uhlig. A nice
|
|
Packit |
67cb25 |
numerical library written in ANSI C with an accompanying
|
|
Packit |
67cb25 |
textbook. Source code is available but the library is not free software.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{NUMAL} A C version of the NUMAL library has been written by
|
|
Packit |
67cb25 |
H.T. Lau and is published as a book and disk with the title "A Numerical
|
|
Packit |
67cb25 |
Library in C for Scientists and Engineers". Source code is available but
|
|
Packit |
67cb25 |
the library is not free software.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{C Mathematical Function Handbook} by Louis Baker. A library of
|
|
Packit |
67cb25 |
function approximations and methods corresponding to those in the
|
|
Packit |
67cb25 |
"Handbook of Mathematical Functions" by Abramowitz and Stegun. Source
|
|
Packit |
67cb25 |
code is available but the library is not free software.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{CCMATH} by Daniel A. Atkinson. A C numerical library covering
|
|
Packit |
67cb25 |
similar areas to GSL. The code is quite terse. Earlier versions were
|
|
Packit |
67cb25 |
under the GPL but unfortunately it has changed to the LGPL in recent
|
|
Packit |
67cb25 |
versions.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{CEPHES} A useful collection of high-quality special functions
|
|
Packit |
67cb25 |
written in C. Not GPL'ed.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{WNLIB} A small collection of numerical routines written in C by
|
|
Packit |
67cb25 |
Will Naylor. Public domain.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{MESHACH} A comprehensive matrix-vector linear algebra library
|
|
Packit |
67cb25 |
written in C. Freely available but not GPL'ed (non-commercial license).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{CERNLIB} is a large high-quality Fortran library developed at CERN
|
|
Packit |
67cb25 |
over many years. It was originally non-free software but has recently
|
|
Packit |
67cb25 |
been released under the GPL.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@emph{COLT} is a free numerical library in Java developed at CERN by
|
|
Packit |
67cb25 |
Wolfgang Hoschek. It is under a BSD-style license.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The long-term goal will be to provide a framework to which the real
|
|
Packit |
67cb25 |
numerical experts (or their graduate students) will contribute.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Contributing, Design, Motivation, Top
|
|
Packit |
67cb25 |
@chapter Contributing
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This design document was originally written in 1996. As of 2004, GSL
|
|
Packit |
67cb25 |
itself is essentially feature complete, the developers are not actively
|
|
Packit |
67cb25 |
working on any major new functionality.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The main emphasis is now on ensuring the stability of the existing
|
|
Packit |
67cb25 |
functions, improving consistency, tidying up a few problem areas and
|
|
Packit |
67cb25 |
fixing any bugs that are reported. Potential contributors are
|
|
Packit |
67cb25 |
encouraged to gain familiarity with the library by investigating and
|
|
Packit |
67cb25 |
fixing known problems listed in the @file{BUGS} file in the CVS
|
|
Packit |
67cb25 |
repository.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Adding large amounts of new code is difficult because it leads to
|
|
Packit |
67cb25 |
differences in the maturity of different parts of the library. To
|
|
Packit |
67cb25 |
maintain stability, any new functionality is encouraged as
|
|
Packit |
67cb25 |
@dfn{packages}, built on top of GSL and maintained independently by the
|
|
Packit |
67cb25 |
author, as in other free software projects (such as the Perl CPAN
|
|
Packit |
67cb25 |
archive and TeX CTAN archive, etc).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@menu
|
|
Packit |
67cb25 |
* Packages::
|
|
Packit |
67cb25 |
@end menu
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Packages, , Contributing, Contributing
|
|
Packit |
67cb25 |
@section Packages
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The design of GSL permits extensions to be used alongside the existing
|
|
Packit |
67cb25 |
library easily by simple linking. For example, additional random number
|
|
Packit |
67cb25 |
generators can be provided in a separate library:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
$ tar xvfz rngextra-0.1.tar.gz
|
|
Packit |
67cb25 |
$ cd rngextra-0.1
|
|
Packit |
67cb25 |
$ ./configure; make; make check; make install
|
|
Packit |
67cb25 |
$ ...
|
|
Packit |
67cb25 |
$ gcc -Wall main.c -lrngextra -lgsl -lgslcblas -lm
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The points below summarise the package design guidelines. These are
|
|
Packit |
67cb25 |
intended to ensure that packages are consistent with GSL itself, to make
|
|
Packit |
67cb25 |
life easier for the end-user and make it possible to distribute popular
|
|
Packit |
67cb25 |
well-tested packages as part of the core GSL in future.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize @bullet
|
|
Packit |
67cb25 |
@item Follow the GSL and GNU coding standards described in this document
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This means using the standard GNU packaging tools, such as Automake,
|
|
Packit |
67cb25 |
providing documentation in Texinfo format, and a test suite. The test
|
|
Packit |
67cb25 |
suite should run using @samp{make check}, and use the test functions
|
|
Packit |
67cb25 |
provided in GSL to produce the output with @code{PASS:}/@code{FAIL:}
|
|
Packit |
67cb25 |
lines. It is not essential to use libtool since packages are likely to
|
|
Packit |
67cb25 |
be small, a static library is sufficient and simpler to build.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item Use a new unique prefix for the package (do not use @samp{gsl_} -- this is reserved for internal use).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For example, a package of additional random number generators might use
|
|
Packit |
67cb25 |
the prefix @code{rngextra}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
#include <rngextra.h>
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_rng * r = gsl_rng_alloc (rngextra_lsfr32);
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item Use a meaningful version number which reflects the state of development
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Generally, @code{0.x} are alpha versions, which provide no guarantees.
|
|
Packit |
67cb25 |
Following that, @code{0.9.x} are beta versions, which should be essentially
|
|
Packit |
67cb25 |
complete, subject only to minor changes and bug fixes. The first major
|
|
Packit |
67cb25 |
release is @code{1.0}. Any version number of @code{1.0} or higher
|
|
Packit |
67cb25 |
should be suitable for production use with a well-defined API.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The API must not change in a major release and should be
|
|
Packit |
67cb25 |
backwards-compatible in its behavior (excluding actual bug-fixes), so
|
|
Packit |
67cb25 |
that existing code do not have to be modified. Note that the API
|
|
Packit |
67cb25 |
includes all exported definitions, including data-structures defined
|
|
Packit |
67cb25 |
with @code{struct}. If you need to change the API in a package, it
|
|
Packit |
67cb25 |
requires a new major release (e.g. @code{2.0}).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item Use the GNU General Public License (GPL)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Follow the normal procedures of obtaining a copyright disclaimer if you
|
|
Packit |
67cb25 |
would like to have the package considered for inclusion in GSL itself in
|
|
Packit |
67cb25 |
the future (@pxref{Legal issues}).
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Post announcements of your package releases to
|
|
Packit |
67cb25 |
@email{gsl-discuss@@sourceware.org} so that information about them
|
|
Packit |
67cb25 |
can be added to the GSL webpages.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For security, sign your package with GPG (@code{gpg --detach-sign
|
|
Packit |
67cb25 |
@var{file}}).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
An example package @samp{rngextra} containing two additional random
|
|
Packit |
67cb25 |
number generators can be found at
|
|
Packit |
67cb25 |
@url{http://www.network-theory.co.uk/download/rngextra/}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Design, Bibliography, Contributing, Top
|
|
Packit |
67cb25 |
@chapter Design
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@menu
|
|
Packit |
67cb25 |
* Language for implementation::
|
|
Packit |
67cb25 |
* Interface to other languages::
|
|
Packit |
67cb25 |
* What routines are implemented::
|
|
Packit |
67cb25 |
* What routines are not implemented::
|
|
Packit |
67cb25 |
* Design of Numerical Libraries::
|
|
Packit |
67cb25 |
* Code Reuse::
|
|
Packit |
67cb25 |
* Standards and conventions::
|
|
Packit |
67cb25 |
* Background and Preparation::
|
|
Packit |
67cb25 |
* Choice of Algorithms::
|
|
Packit |
67cb25 |
* Documentation::
|
|
Packit |
67cb25 |
* Namespace::
|
|
Packit |
67cb25 |
* Header files::
|
|
Packit |
67cb25 |
* Target system::
|
|
Packit |
67cb25 |
* Function Names::
|
|
Packit |
67cb25 |
* Object-orientation::
|
|
Packit |
67cb25 |
* Comments::
|
|
Packit |
67cb25 |
* Minimal structs::
|
|
Packit |
67cb25 |
* Algorithm decomposition::
|
|
Packit |
67cb25 |
* Memory allocation and ownership::
|
|
Packit |
67cb25 |
* Memory layout::
|
|
Packit |
67cb25 |
* Linear Algebra Levels::
|
|
Packit |
67cb25 |
* Error estimates::
|
|
Packit |
67cb25 |
* Exceptions and Error handling::
|
|
Packit |
67cb25 |
* Persistence::
|
|
Packit |
67cb25 |
* Using Return Values::
|
|
Packit |
67cb25 |
* Variable Names::
|
|
Packit |
67cb25 |
* Datatype widths::
|
|
Packit |
67cb25 |
* size_t::
|
|
Packit |
67cb25 |
* Arrays vs Pointers::
|
|
Packit |
67cb25 |
* Pointers::
|
|
Packit |
67cb25 |
* Constness::
|
|
Packit |
67cb25 |
* Pseudo-templates::
|
|
Packit |
67cb25 |
* Arbitrary Constants::
|
|
Packit |
67cb25 |
* Test suites::
|
|
Packit |
67cb25 |
* Compilation::
|
|
Packit |
67cb25 |
* Thread-safety::
|
|
Packit |
67cb25 |
* Legal issues::
|
|
Packit |
67cb25 |
* Non-UNIX portability::
|
|
Packit |
67cb25 |
* Compatibility with other libraries::
|
|
Packit |
67cb25 |
* Parallelism::
|
|
Packit |
67cb25 |
* Precision::
|
|
Packit |
67cb25 |
* Miscellaneous::
|
|
Packit |
67cb25 |
@end menu
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Language for implementation, Interface to other languages, Design, Design
|
|
Packit |
67cb25 |
@section Language for implementation
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@strong{One language only (C)}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Advantages: simpler, compiler available and quite universal.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Interface to other languages, What routines are implemented, Language for implementation, Design
|
|
Packit |
67cb25 |
@section Interface to other languages
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Wrapper packages are supplied as "extra" packages; not as part of the
|
|
Packit |
67cb25 |
"core". They are maintained separately by independent contributors.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Use standard tools to make wrappers: swig, g-wrap
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node What routines are implemented, What routines are not implemented, Interface to other languages, Design
|
|
Packit |
67cb25 |
@section What routines are implemented
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Anything which is in any of the existing libraries. Obviously it makes
|
|
Packit |
67cb25 |
sense to prioritize and write code for the most important areas first.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @itemize @bullet
|
|
Packit |
67cb25 |
@c @item Random number generators
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c Includes both random number generators and routines to give various
|
|
Packit |
67cb25 |
@c interesting distributions.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Statistics
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Special Functions
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c What I (jt) envision for this section is a collection of routines for
|
|
Packit |
67cb25 |
@c reliable and accurate (but not necessarily fast or efficient) estimation
|
|
Packit |
67cb25 |
@c of values for special functions, explicitly using Taylor series, asymptotic
|
|
Packit |
67cb25 |
@c expansions, continued fraction expansions, etc. As well as these routines,
|
|
Packit |
67cb25 |
@c fast approximations will also be provided, primarily based on Chebyshev
|
|
Packit |
67cb25 |
@c polynomials and ratios of polynomials. In this vision, the approximations
|
|
Packit |
67cb25 |
@c will be the "standard" routines for the users, and the exact (so-called)
|
|
Packit |
67cb25 |
@c routines will be used for verification of the approximations. It may also
|
|
Packit |
67cb25 |
@c be useful to provide various identity-checking routines as part of the
|
|
Packit |
67cb25 |
@c verification suite.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Curve fitting
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c polynomial, special functions, spline
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Ordinary differential equations
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Partial differential equations
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Fourier Analysis
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Wavelets
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Matrix operations: linear equations
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Matrix operations: eigenvalues and spectral analysis
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Matrix operations: any others?
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Direct integration
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Monte Carlo methods
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Simulated annealing
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Genetic algorithms
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c We need to think about what kinds of algorithms are basic generally
|
|
Packit |
67cb25 |
@c useful numerical algorithms, and which ones are special purpose
|
|
Packit |
67cb25 |
@c research projects. We should concentrate on supplying the former.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @item Cellular automata
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node What routines are not implemented, Design of Numerical Libraries, What routines are implemented, Design
|
|
Packit |
67cb25 |
@section What routines are not implemented
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize @bullet
|
|
Packit |
67cb25 |
@item anything which already exists as a high-quality GPL'ed package.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item anything which is too big
|
|
Packit |
67cb25 |
-- i.e. an application in its own right rather than a subroutine
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For example, partial differential equation solvers are often huge and
|
|
Packit |
67cb25 |
very specialized applications (since there are so many types of PDEs,
|
|
Packit |
67cb25 |
types of solution, types of grid, etc). This sort of thing should
|
|
Packit |
67cb25 |
remain separate. It is better to point people to the good applications
|
|
Packit |
67cb25 |
which exist.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item anything which is independent and useful separately.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Arguably functions for manipulating date and time, or financial
|
|
Packit |
67cb25 |
functions might be included in a "scientific" library. However, these
|
|
Packit |
67cb25 |
sorts of modules could equally well be used independently in other
|
|
Packit |
67cb25 |
programs, so it makes sense for them to be separate libraries.
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Design of Numerical Libraries, Code Reuse, What routines are not implemented, Design
|
|
Packit |
67cb25 |
@section Design of Numerical Libraries
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
In writing a numerical library there is a unavoidable conflict between
|
|
Packit |
67cb25 |
completeness and simplicity. Completeness refers to the ability to
|
|
Packit |
67cb25 |
perform operations on different objects so that the group is
|
|
Packit |
67cb25 |
"closed". In mathematics objects can be combined and operated on in an
|
|
Packit |
67cb25 |
infinite number of ways. For example, I can take the derivative of a
|
|
Packit |
67cb25 |
scalar field with respect to a vector and the derivative of a vector
|
|
Packit |
67cb25 |
field wrt.@: a scalar (along a path).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There is a definite tendency to unconsciously try to reproduce all these
|
|
Packit |
67cb25 |
possibilities in a numerical library, by adding new features one by
|
|
Packit |
67cb25 |
one. After all, it is always easy enough to support just one more
|
|
Packit |
67cb25 |
feature @dots{} so why not?
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Looking at the big picture, no-one would start out by saying "I want to
|
|
Packit |
67cb25 |
be able to represent every possible mathematical object and operation
|
|
Packit |
67cb25 |
using C structs" -- this is a strategy which is doomed to fail. There
|
|
Packit |
67cb25 |
is a limited amount of complexity which can be represented in a
|
|
Packit |
67cb25 |
programming language like C. Attempts to reproduce the complexity of
|
|
Packit |
67cb25 |
mathematics within such a language would just lead to a morass of
|
|
Packit |
67cb25 |
unmaintainable code. However, it's easy to go down that road if you
|
|
Packit |
67cb25 |
don't think about it ahead of time.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
It is better to choose simplicity over completeness. In designing new
|
|
Packit |
67cb25 |
parts of the library keep modules independent where possible. If
|
|
Packit |
67cb25 |
interdependencies between modules are introduced be sure about where you
|
|
Packit |
67cb25 |
are going to draw the line.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Code Reuse, Standards and conventions, Design of Numerical Libraries, Design
|
|
Packit |
67cb25 |
@section Code Reuse
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
It is useful if people can grab a single source file and include it in
|
|
Packit |
67cb25 |
their own programs without needing the whole library. Try to allow
|
|
Packit |
67cb25 |
standalone files like this whenever it is reasonable. Obviously the
|
|
Packit |
67cb25 |
user might need to define a few macros, such as GSL_ERROR, to compile
|
|
Packit |
67cb25 |
the file but that is ok. Examples where this can be done: grabbing a
|
|
Packit |
67cb25 |
single random number generator.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Standards and conventions, Background and Preparation, Code Reuse, Design
|
|
Packit |
67cb25 |
@section Standards and conventions
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The people who kick off this project should set the coding standards and
|
|
Packit |
67cb25 |
conventions. In order of precedence the standards that we follow are,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize @bullet
|
|
Packit |
67cb25 |
@item We follow the GNU Coding Standards.
|
|
Packit |
67cb25 |
@item We follow the conventions of the ANSI Standard C Library.
|
|
Packit |
67cb25 |
@item We follow the conventions of the GNU C Library.
|
|
Packit |
67cb25 |
@item We follow the conventions of the glib GTK support Library.
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The references for these standards are the @cite{GNU Coding Standards}
|
|
Packit |
67cb25 |
document, Harbison and Steele @cite{C: A Reference Manual}, the
|
|
Packit |
67cb25 |
@cite{GNU C Library Manual} (version 2), and the Glib source code.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For mathematical formulas, always follow the conventions in Abramowitz &
|
|
Packit |
67cb25 |
Stegun, the @cite{Handbook of Mathematical Functions}, since it is the
|
|
Packit |
67cb25 |
definitive reference and also in the public domain.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If the project has a philosophy it is to "Think in C". Since we are
|
|
Packit |
67cb25 |
working in C we should only do what is natural in C, rather than trying
|
|
Packit |
67cb25 |
to simulate features of other languages. If there is something which is
|
|
Packit |
67cb25 |
unnatural in C and has to be simulated then we avoid using it. If this
|
|
Packit |
67cb25 |
means leaving something out of the library, or only offering a limited
|
|
Packit |
67cb25 |
version then so be it. It is not worthwhile making the library
|
|
Packit |
67cb25 |
over-complicated. There are numerical libraries in other languages, and
|
|
Packit |
67cb25 |
if people need the features of those languages it would be sensible for
|
|
Packit |
67cb25 |
them to use the corresponding libraries, rather than coercing a C
|
|
Packit |
67cb25 |
library into doing that job.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
It should be borne in mind at all time that C is a macro-assembler. If
|
|
Packit |
67cb25 |
you are in doubt about something being too complicated ask yourself the
|
|
Packit |
67cb25 |
question "Would I try to write this in macro-assembler?" If the answer
|
|
Packit |
67cb25 |
is obviously "No" then do not try to include it in GSL. [BJG]
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
It will be useful to read the following papers,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize @w{}
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
Kiem-Phong Vo, ``The Discipline and Method Architecture for Reusable
|
|
Packit |
67cb25 |
Libraries'', Software - Practice & Experience, v.30, pp.107-128, 2000.
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
It is available from
|
|
Packit |
67cb25 |
@uref{http://www.research.att.com/sw/tools/sfio/dm-spe.ps} or the earlier
|
|
Packit |
67cb25 |
technical report Kiem-Phong Vo, "An Architecture for Reusable Libraries"
|
|
Packit |
67cb25 |
@uref{http://citeseer.nj.nec.com/48973.html}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There are associated papers on Vmalloc, SFIO, and CDT which are also
|
|
Packit |
67cb25 |
relevant to the design of portable C libraries.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize @w{}
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
Kiem-Phong Vo, ``Vmalloc: A General and Efficient Memory
|
|
Packit |
67cb25 |
Allocator''. Software Practice & Experience, 26:1--18, 1996.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@uref{http://www.research.att.com/sw/tools/vmalloc/vmalloc.ps}
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
Kiem-Phong Vo. ``Cdt: A Container Data Type Library''. Soft. Prac. &
|
|
Packit |
67cb25 |
Exp., 27:1177--1197, 1997
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@uref{http://www.research.att.com/sw/tools/cdt/cdt.ps}
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
David G. Korn and Kiem-Phong Vo, ``Sfio: Safe/Fast String/File IO'',
|
|
Packit |
67cb25 |
Proceedings of the Summer '91 Usenix Conference, pp. 235-256, 1991.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@uref{http://citeseer.nj.nec.com/korn91sfio.html}
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Source code should be indented according to the GNU Coding Standards,
|
|
Packit |
67cb25 |
with spaces not tabs. For example, by using the @code{indent} command:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
indent -gnu -nut *.c *.h
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
The @code{-nut} option converts tabs into spaces.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Background and Preparation, Choice of Algorithms, Standards and conventions, Design
|
|
Packit |
67cb25 |
@section Background and Preparation
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Before implementing something be sure to research the subject
|
|
Packit |
67cb25 |
thoroughly! This will save a lot of time in the long-run. The two most
|
|
Packit |
67cb25 |
important steps are,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@enumerate
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
to determine whether there is already a free library (GPL or
|
|
Packit |
67cb25 |
GPL-compatible) which does the job. If so, there is no need to
|
|
Packit |
67cb25 |
reimplement it. Carry out a search on Netlib, GAMs, na-net,
|
|
Packit |
67cb25 |
sci.math.num-analysis and the web in general. This should also provide
|
|
Packit |
67cb25 |
you with a list of existing proprietary libraries which are relevant,
|
|
Packit |
67cb25 |
keep a note of these for future reference in step 2.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
make a comparative survey of existing implementations in the
|
|
Packit |
67cb25 |
commercial/free libraries. Examine the typical APIs, methods of
|
|
Packit |
67cb25 |
communication between program and subroutine, and classify them so that
|
|
Packit |
67cb25 |
you are familiar with the key concepts or features that an
|
|
Packit |
67cb25 |
implementation may or may not have, depending on the relevant tradeoffs
|
|
Packit |
67cb25 |
chosen. Be sure to review the documentation of existing libraries for
|
|
Packit |
67cb25 |
useful references.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
read up on the subject and determine the state-of-the-art. Find the
|
|
Packit |
67cb25 |
latest review papers. A search of the following journals should be
|
|
Packit |
67cb25 |
undertaken.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize @w{}
|
|
Packit |
67cb25 |
@item ACM Transactions on Mathematical Software
|
|
Packit |
67cb25 |
@item Numerische Mathematik
|
|
Packit |
67cb25 |
@item Journal of Computation and Applied Mathematics
|
|
Packit |
67cb25 |
@item Computer Physics Communications
|
|
Packit |
67cb25 |
@item SIAM Journal of Numerical Analysis
|
|
Packit |
67cb25 |
@item SIAM Journal of Scientific Computing
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
@end enumerate
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
Keep in mind that GSL is not a research project. Making a good
|
|
Packit |
67cb25 |
implementation is difficult enough, without also needing to invent new
|
|
Packit |
67cb25 |
algorithms. We want to implement existing algorithms whenever
|
|
Packit |
67cb25 |
possible. Making minor improvements is ok, but don't let it be a
|
|
Packit |
67cb25 |
time-sink.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Choice of Algorithms, Documentation, Background and Preparation, Design
|
|
Packit |
67cb25 |
@section Choice of Algorithms
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Whenever possible choose algorithms which scale well and always remember
|
|
Packit |
67cb25 |
to handle asymptotic cases. This is particularly relevant for functions
|
|
Packit |
67cb25 |
with integer arguments. It is tempting to implement these using the
|
|
Packit |
67cb25 |
simple @math{O(n)} algorithms used to define the functions, such as the
|
|
Packit |
67cb25 |
many recurrence relations found in Abramowitz and Stegun. While such
|
|
Packit |
67cb25 |
methods might be acceptable for @math{n=O(10-100)} they will not be
|
|
Packit |
67cb25 |
satisfactory for a user who needs to compute the same function for
|
|
Packit |
67cb25 |
@math{n=1000000}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Similarly, do not make the implicit assumption that multivariate data
|
|
Packit |
67cb25 |
has been scaled to have components of the same size or O(1). Algorithms
|
|
Packit |
67cb25 |
should take care of any necessary scaling or balancing internally, and
|
|
Packit |
67cb25 |
use appropriate norms (e.g. |Dx| where D is a diagonal scaling matrix,
|
|
Packit |
67cb25 |
rather than |x|).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Documentation, Namespace, Choice of Algorithms, Design
|
|
Packit |
67cb25 |
@section Documentation
|
|
Packit |
67cb25 |
Documentation: the project leaders should give examples of how things
|
|
Packit |
67cb25 |
are to be documented. High quality documentation is absolutely
|
|
Packit |
67cb25 |
mandatory, so documentation should introduce the topic, and give careful
|
|
Packit |
67cb25 |
reference for the provided functions. The priority is to provide
|
|
Packit |
67cb25 |
reference documentation for each function. It is not necessary to
|
|
Packit |
67cb25 |
provide tutorial documentation.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Use free software, such as GNU Plotutils, to produce the graphs in the
|
|
Packit |
67cb25 |
manual.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Some of the graphs have been made with gnuplot which is not truly free
|
|
Packit |
67cb25 |
(or GNU) software, and some have been made with proprietary
|
|
Packit |
67cb25 |
programs. These should be replaced with output from GNU plotutils.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
When citing references be sure to use the standard, definitive and
|
|
Packit |
67cb25 |
best reference books in the field, rather than lesser known text-books
|
|
Packit |
67cb25 |
or introductory books which happen to be available (e.g. from
|
|
Packit |
67cb25 |
undergraduate studies). For example, references concerning algorithms
|
|
Packit |
67cb25 |
should be to Knuth, references concerning statistics should be to
|
|
Packit |
67cb25 |
Kendall & Stuart, references concerning special functions should be to
|
|
Packit |
67cb25 |
Abramowitz & Stegun (Handbook of Mathematical Functions AMS-55), etc.
|
|
Packit |
67cb25 |
Wherever possible refer to Abramowitz & Stegun rather than other
|
|
Packit |
67cb25 |
reference books because it is a public domain work, so it is
|
|
Packit |
67cb25 |
inexpensive and freely redistributable.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The standard references have a better chance of being available in an
|
|
Packit |
67cb25 |
accessible library for the user. If they are not available and the user
|
|
Packit |
67cb25 |
decides to buy a copy in order to look up the reference then this also
|
|
Packit |
67cb25 |
gives them the best quality book which should also cover the largest
|
|
Packit |
67cb25 |
number of other references in the GSL Manual. If many different books
|
|
Packit |
67cb25 |
were to be referenced this would be an expensive and inefficient use of
|
|
Packit |
67cb25 |
resources for a user who needs to look up the details of the algorithms.
|
|
Packit |
67cb25 |
Reference books also stay in print much longer than text books, which
|
|
Packit |
67cb25 |
are often out-of-print after a few years.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Similarly, cite original papers wherever possible. Be sure to keep
|
|
Packit |
67cb25 |
copies of these for your own reference (e.g. when dealing with bug
|
|
Packit |
67cb25 |
reports) or to pass on to future maintainers.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If you need help in tracking down references, ask on the
|
|
Packit |
67cb25 |
@code{gsl-discuss} mailing list. There is a group of volunteers with
|
|
Packit |
67cb25 |
access to good libraries who have offered to help GSL developers get
|
|
Packit |
67cb25 |
copies of papers.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c [JT section: written by James Theiler
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c And we furthermore promise to try as hard as possible to document
|
|
Packit |
67cb25 |
@c the software: this will ideally involve discussion of why you might want
|
|
Packit |
67cb25 |
@c to use it, what precisely it does, how precisely to invoke it,
|
|
Packit |
67cb25 |
@c how more-or-less it works, and where we learned about the algorithm,
|
|
Packit |
67cb25 |
@c and (unless we wrote it from scratch) where we got the code.
|
|
Packit |
67cb25 |
@c We do not plan to write this entire package from scratch, but to cannibalize
|
|
Packit |
67cb25 |
@c existing mathematical freeware, just as we expect our own software to
|
|
Packit |
67cb25 |
@c be cannibalized.]
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
To write mathematics in the texinfo file you can use the @code{@@math}
|
|
Packit |
67cb25 |
command with @emph{simple} TeX commands. These are automatically
|
|
Packit |
67cb25 |
surrounded by @code{$...$} for math mode. For example,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
to calculate the coefficient @@math@{\alpha@} use the function...
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
will be correctly formatted in both online and TeX versions of the
|
|
Packit |
67cb25 |
documentation.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Note that you cannot use the special characters @{ and @}
|
|
Packit |
67cb25 |
inside the @code{@@math} command because these conflict between TeX
|
|
Packit |
67cb25 |
and Texinfo. This is a problem if you want to write something like
|
|
Packit |
67cb25 |
@code{\sqrt@{x+y@}}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
To work around it you can precede the math command with a special
|
|
Packit |
67cb25 |
macro @code{@@c} which contains the explicit TeX commands you want to
|
|
Packit |
67cb25 |
use (no restrictions), and put an ASCII approximation into the
|
|
Packit |
67cb25 |
@code{@@math} command (you can write @code{@@@{} and
|
|
Packit |
67cb25 |
@code{@@@}} there for the left and right braces). The explicit TeX
|
|
Packit |
67cb25 |
commands are used in the TeX output and the argument of @code{@@math}
|
|
Packit |
67cb25 |
in the plain info output.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Note that the @code{@@c@{@}} macro must go at the end of the
|
|
Packit |
67cb25 |
preceding line, because everything else after it is ignored---as far
|
|
Packit |
67cb25 |
as texinfo is concerned it's actually a 'comment'. The comment
|
|
Packit |
67cb25 |
command @@c has been modified to capture a TeX expression which is
|
|
Packit |
67cb25 |
output by the next @@math command. For ordinary comments use the @@comment
|
|
Packit |
67cb25 |
command.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For example,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
this is a test @@c@{$\sqrt@{x+y@}$@}
|
|
Packit |
67cb25 |
@@math@{\sqrt@@@{x+y@@@}@}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
is equivalent to @code{this is a test $\sqrt@{x+y@}$} in plain TeX
|
|
Packit |
67cb25 |
and @code{this is a test @@math@{\sqrt@@@{x+y@@@}@}} in Info.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
It looks nicer if some of the more cryptic TeX commands are given
|
|
Packit |
67cb25 |
a C-style ascii version, e.g.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
for @@c@{$x \ge y$@}
|
|
Packit |
67cb25 |
@@math@{x >= y@}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
will be appropriately displayed in both TeX and Info.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Namespace, Header files, Documentation, Design
|
|
Packit |
67cb25 |
@section Namespace
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Use @code{gsl_} as a prefix for all exported functions and variables.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Use @code{GSL_} as a prefix for all exported macros.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
All exported header files should have a filename with the prefix @code{gsl_}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
All installed libraries should have a name like libgslhistogram.a
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Any installed executables (utility programs etc) should have the prefix
|
|
Packit |
67cb25 |
@code{gsl-} (with a hyphen, not an underscore).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
All function names, variables, etc.@: should be in lower case. Macros and
|
|
Packit |
67cb25 |
preprocessor variables should be in upper case.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Some common conventions in variable and function names:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@table @code
|
|
Packit |
67cb25 |
@item p1
|
|
Packit |
67cb25 |
plus 1, e.g. function @code{log1p(x)} or a variable like @code{kp1}, @math{=k+1}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item m1
|
|
Packit |
67cb25 |
minus 1, e.g. function @code{expm1(x)} or a variable like @code{km1}, @math{=k-1}.
|
|
Packit |
67cb25 |
@end table
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Header files, Target system, Namespace, Design
|
|
Packit |
67cb25 |
@section Header files
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Installed header files should be idempotent, i.e. surround them by the
|
|
Packit |
67cb25 |
preprocessor conditionals like the following,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
#ifndef __GSL_HISTOGRAM_H__
|
|
Packit |
67cb25 |
#define __GSL_HISTOGRAM_H__
|
|
Packit |
67cb25 |
...
|
|
Packit |
67cb25 |
#endif /* __GSL_HISTOGRAM_H__ */
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Target system, Function Names, Header files, Design
|
|
Packit |
67cb25 |
@section Target system
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The target system is ANSI C, with a full Standard C Library, and IEEE
|
|
Packit |
67cb25 |
arithmetic.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Function Names, Object-orientation, Target system, Design
|
|
Packit |
67cb25 |
@section Function Names
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Each module has a name, which prefixes any function names in that
|
|
Packit |
67cb25 |
module, e.g. the module gsl_fft has function names like
|
|
Packit |
67cb25 |
gsl_fft_init. The modules correspond to subdirectories of the library
|
|
Packit |
67cb25 |
source tree.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Object-orientation, Comments, Function Names, Design
|
|
Packit |
67cb25 |
@section Object-orientation
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The algorithms should be object oriented, but only to the extent that is
|
|
Packit |
67cb25 |
easy in portable ANSI C. The use of casting or other tricks to simulate
|
|
Packit |
67cb25 |
inheritance is not desirable, and the user should not have to be aware
|
|
Packit |
67cb25 |
of anything like that. This means many types of patterns are ruled
|
|
Packit |
67cb25 |
out. However, this is not considered a problem -- they are too
|
|
Packit |
67cb25 |
complicated for the library.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Note: it is possible to define an abstract base class easily in C, using
|
|
Packit |
67cb25 |
function pointers. See the rng directory for an example.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
When reimplementing public domain Fortran code, please try to introduce
|
|
Packit |
67cb25 |
the appropriate object concepts as structs, rather than translating the
|
|
Packit |
67cb25 |
code literally in terms of arrays. The structs can be useful just
|
|
Packit |
67cb25 |
within the file, you don't need to export them to the user.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For example, if a Fortran program repeatedly uses a subroutine like,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
SUBROUTINE RESIZE (X, K, ND, K1)
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
where X(K,D) represents a grid to be resized to X(K1,D) you can make
|
|
Packit |
67cb25 |
this more readable by introducing a struct,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@smallexample
|
|
Packit |
67cb25 |
struct grid @{
|
|
Packit |
67cb25 |
int nd; /* number of dimensions */
|
|
Packit |
67cb25 |
int k; /* number of bins */
|
|
Packit |
67cb25 |
double * x; /* partition of axes, array of size x[k][nd] */
|
|
Packit |
67cb25 |
@}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
void
|
|
Packit |
67cb25 |
resize_grid (struct grid * g, int k_new)
|
|
Packit |
67cb25 |
@{
|
|
Packit |
67cb25 |
...
|
|
Packit |
67cb25 |
@}
|
|
Packit |
67cb25 |
@end smallexample
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
Similarly, if you have a frequently recurring code fragment within a
|
|
Packit |
67cb25 |
single file you can define a static or static inline function for it.
|
|
Packit |
67cb25 |
This is typesafe and saves writing out everything in full.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Comments, Minimal structs, Object-orientation, Design
|
|
Packit |
67cb25 |
@section Comments
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Follow the GNU Coding Standards. A relevant quote is,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
``Please write complete sentences and capitalize the first word. If a
|
|
Packit |
67cb25 |
lower-case identifier comes at the beginning of a sentence, don't
|
|
Packit |
67cb25 |
capitalize it! Changing the spelling makes it a different identifier.
|
|
Packit |
67cb25 |
If you don't like starting a sentence with a lower case letter, write
|
|
Packit |
67cb25 |
the sentence differently (e.g., "The identifier lower-case is ...").''
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Minimal structs, Algorithm decomposition, Comments, Design
|
|
Packit |
67cb25 |
@section Minimal structs
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
We prefer to make structs which are @dfn{minimal}. For example, if a
|
|
Packit |
67cb25 |
certain type of problem can be solved by several classes of algorithm
|
|
Packit |
67cb25 |
(e.g. with and without derivative information) it is better to make
|
|
Packit |
67cb25 |
separate types of struct to handle those cases. i.e. run time type
|
|
Packit |
67cb25 |
identification is not desirable.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Algorithm decomposition, Memory allocation and ownership, Minimal structs, Design
|
|
Packit |
67cb25 |
@section Algorithm decomposition
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Iterative algorithms should be decomposed into an INITIALIZE, ITERATE,
|
|
Packit |
67cb25 |
TEST form, so that the user can control the progress of the iteration
|
|
Packit |
67cb25 |
and print out intermediate results. This is better than using
|
|
Packit |
67cb25 |
call-backs or using flags to control whether the function prints out
|
|
Packit |
67cb25 |
intermediate results. In fact, call-backs should not be used -- if they
|
|
Packit |
67cb25 |
seem necessary then it's a sign that the algorithm should be broken down
|
|
Packit |
67cb25 |
further into individual components so that the user has complete control
|
|
Packit |
67cb25 |
over them.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For example, when solving a differential equation the user may need to
|
|
Packit |
67cb25 |
be able to advance the solution by individual steps, while tracking a
|
|
Packit |
67cb25 |
realtime process. This is only possible if the algorithm is broken down
|
|
Packit |
67cb25 |
into step-level components. Higher level decompositions would not give
|
|
Packit |
67cb25 |
sufficient flexibility.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Memory allocation and ownership, Memory layout, Algorithm decomposition, Design
|
|
Packit |
67cb25 |
@section Memory allocation and ownership
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Functions which allocate memory on the heap should end in _alloc
|
|
Packit |
67cb25 |
(e.g. gsl_foo_alloc) and be deallocated by a corresponding _free function
|
|
Packit |
67cb25 |
(gsl_foo_free).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Be sure to free any memory allocated by your function if you have to
|
|
Packit |
67cb25 |
return an error in a partially initialized object.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Don't allocate memory 'temporarily' inside a function and then free it
|
|
Packit |
67cb25 |
before the function returns. This prevents the user from controlling
|
|
Packit |
67cb25 |
memory allocation. All memory should be allocated and freed through
|
|
Packit |
67cb25 |
separate functions and passed around as a "workspace" argument. This
|
|
Packit |
67cb25 |
allows memory allocation to be factored out of tight loops.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
To avoid confusion over ownership, workspaces should not own each
|
|
Packit |
67cb25 |
other or contain other workspaces. For clarity and ease of use in
|
|
Packit |
67cb25 |
different contexts, they should be allocated from integer arguments
|
|
Packit |
67cb25 |
rather than derived from other structs.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Memory layout, Linear Algebra Levels, Memory allocation and ownership, Design
|
|
Packit |
67cb25 |
@section Memory layout
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
We use flat blocks of memory to store matrices and vectors, not C-style
|
|
Packit |
67cb25 |
pointer-to-pointer arrays. The matrices are stored in row-major order
|
|
Packit |
67cb25 |
-- i.e. the column index (second index) moves continuously through memory.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Linear Algebra Levels, Error estimates, Memory layout, Design
|
|
Packit |
67cb25 |
@section Linear Algebra Levels
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Functions using linear algebra are divided into two levels:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For purely "1d" functions we use the C-style arguments (double *,
|
|
Packit |
67cb25 |
stride, size) so that it is simpler to use the functions in a normal C
|
|
Packit |
67cb25 |
program, without needing to invoke all the gsl_vector machinery.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The philosophy here is to minimize the learning curve. If someone only
|
|
Packit |
67cb25 |
needs to use one function, like an fft, they can do so without having
|
|
Packit |
67cb25 |
to learn about gsl_vector.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This leads to the question of why we don't do the same for matrices.
|
|
Packit |
67cb25 |
In that case the argument list gets too long and confusing, with
|
|
Packit |
67cb25 |
(size1, size2, tda) for each matrix and potential ambiguities over row
|
|
Packit |
67cb25 |
vs column ordering. In this case, it makes sense to use gsl_vector and
|
|
Packit |
67cb25 |
gsl_matrix, which take care of this for the user.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
So really the library has two levels -- a lower level based on C types
|
|
Packit |
67cb25 |
for 1d operations, and a higher level based on gsl_matrix and
|
|
Packit |
67cb25 |
gsl_vector for general linear algebra.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Of course, it would be possible to define a vector version of the
|
|
Packit |
67cb25 |
lower level functions too. So far we have not done that because it was
|
|
Packit |
67cb25 |
not essential -- it could be done but it is easy enough to get by
|
|
Packit |
67cb25 |
using the C arguments, by typing v->data, v->stride, v->size instead.
|
|
Packit |
67cb25 |
A gsl_vector version of low-level functions would mainly be a
|
|
Packit |
67cb25 |
convenience.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Please use BLAS routines internally within the library whenever possible
|
|
Packit |
67cb25 |
for efficiency.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Error estimates, Exceptions and Error handling, Linear Algebra Levels, Design
|
|
Packit |
67cb25 |
@section Error estimates
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
In the special functions error bounds are given as twice the expected
|
|
Packit |
67cb25 |
``Gaussian'' error, i.e.@: 2-sigma, so the result is inside the error
|
|
Packit |
67cb25 |
98% of the time. People expect the true value to be within +/- the
|
|
Packit |
67cb25 |
quoted error (this wouldn't be the case 32% of the time for 1 sigma).
|
|
Packit |
67cb25 |
Obviously the errors are not Gaussian but a factor of two works well
|
|
Packit |
67cb25 |
in practice.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Exceptions and Error handling, Persistence, Error estimates, Design
|
|
Packit |
67cb25 |
@section Exceptions and Error handling
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The basic error handling procedure is the return code (see gsl_errno.h
|
|
Packit |
67cb25 |
for a list of allowed values). Use the GSL_ERROR macro to mark an
|
|
Packit |
67cb25 |
error. The current definition of this macro is not ideal but it can be
|
|
Packit |
67cb25 |
changed at compile time.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
You should always use the GSL_ERROR macro to indicate an error, rather
|
|
Packit |
67cb25 |
than just returning an error code. The macro allows the user to trap
|
|
Packit |
67cb25 |
errors using the debugger (by setting a breakpoint on the function
|
|
Packit |
67cb25 |
gsl_error).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The only circumstances where GSL_ERROR should not be used are where the
|
|
Packit |
67cb25 |
return value is "indicative" rather than an error -- for example, the
|
|
Packit |
67cb25 |
iterative routines use the return code to indicate the success or
|
|
Packit |
67cb25 |
failure of an iteration. By the nature of an iterative algorithm
|
|
Packit |
67cb25 |
"failure" (a return code of GSL_CONTINUE) is a normal occurrence and
|
|
Packit |
67cb25 |
there is no need to use GSL_ERROR there.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Be sure to free any memory allocated by your function if you return an
|
|
Packit |
67cb25 |
error (in particular for errors in partially initialized objects).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Persistence, Using Return Values, Exceptions and Error handling, Design
|
|
Packit |
67cb25 |
@section Persistence
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If you make an object foo which uses blocks of memory (e.g. vector,
|
|
Packit |
67cb25 |
matrix, histogram) you can provide functions for reading and writing
|
|
Packit |
67cb25 |
those blocks,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@smallexample
|
|
Packit |
67cb25 |
int gsl_foo_fread (FILE * stream, gsl_foo * v);
|
|
Packit |
67cb25 |
int gsl_foo_fwrite (FILE * stream, const gsl_foo * v);
|
|
Packit |
67cb25 |
int gsl_foo_fscanf (FILE * stream, gsl_foo * v);
|
|
Packit |
67cb25 |
int gsl_foo_fprintf (FILE * stream, const gsl_foo * v, const char *format);
|
|
Packit |
67cb25 |
@end smallexample
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
Only dump out the blocks of memory, not any associated parameters such
|
|
Packit |
67cb25 |
as lengths. The idea is for the user to build higher level input/output
|
|
Packit |
67cb25 |
facilities using the functions the library provides. The fprintf/fscanf
|
|
Packit |
67cb25 |
versions should be portable between architectures, while the binary
|
|
Packit |
67cb25 |
versions should be the "raw" version of the data. Use the functions
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@smallexample
|
|
Packit |
67cb25 |
int gsl_block_fread (FILE * stream, gsl_block * b);
|
|
Packit |
67cb25 |
int gsl_block_fwrite (FILE * stream, const gsl_block * b);
|
|
Packit |
67cb25 |
int gsl_block_fscanf (FILE * stream, gsl_block * b);
|
|
Packit |
67cb25 |
int gsl_block_fprintf (FILE * stream, const gsl_block * b, const char *format);
|
|
Packit |
67cb25 |
@end smallexample
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
or
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@smallexample
|
|
Packit |
67cb25 |
int gsl_block_raw_fread (FILE * stream, double * b, size_t n, size_t stride);
|
|
Packit |
67cb25 |
int gsl_block_raw_fwrite (FILE * stream, const double * b, size_t n, size_t stri
|
|
Packit |
67cb25 |
de);
|
|
Packit |
67cb25 |
int gsl_block_raw_fscanf (FILE * stream, double * b, size_t n, size_t stride);
|
|
Packit |
67cb25 |
int gsl_block_raw_fprintf (FILE * stream, const double * b, size_t n, size_t str
|
|
Packit |
67cb25 |
ide, const char *format);
|
|
Packit |
67cb25 |
@end smallexample
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
to do the actual reading and writing.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Using Return Values, Variable Names, Persistence, Design
|
|
Packit |
67cb25 |
@section Using Return Values
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Always assign a return value to a variable before using it. This allows
|
|
Packit |
67cb25 |
easier debugging of the function, and inspection and modification of the
|
|
Packit |
67cb25 |
return value. If the variable is only needed temporarily then enclose
|
|
Packit |
67cb25 |
it in a suitable scope.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For example, instead of writing,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
a = f(g(h(x,y)))
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
use temporary variables to store the intermediate values,
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
@{
|
|
Packit |
67cb25 |
double u = h(x,y);
|
|
Packit |
67cb25 |
double v = g(u);
|
|
Packit |
67cb25 |
a = f(v);
|
|
Packit |
67cb25 |
@}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
These can then be inspected more easily in the debugger, and breakpoints
|
|
Packit |
67cb25 |
can be placed more precisely. The compiler will eliminate the temporary
|
|
Packit |
67cb25 |
variables automatically when the program is compiled with optimization.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Variable Names, Datatype widths, Using Return Values, Design
|
|
Packit |
67cb25 |
@section Variable Names
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Try to follow existing conventions for variable names,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@table @code
|
|
Packit |
67cb25 |
@item dim
|
|
Packit |
67cb25 |
number of dimensions
|
|
Packit |
67cb25 |
@item w
|
|
Packit |
67cb25 |
pointer to workspace
|
|
Packit |
67cb25 |
@item state
|
|
Packit |
67cb25 |
pointer to state variable (use @code{s} if you need to save characters)
|
|
Packit |
67cb25 |
@item result
|
|
Packit |
67cb25 |
pointer to result (output variable)
|
|
Packit |
67cb25 |
@item abserr
|
|
Packit |
67cb25 |
absolute error
|
|
Packit |
67cb25 |
@item relerr
|
|
Packit |
67cb25 |
relative error
|
|
Packit |
67cb25 |
@item epsabs
|
|
Packit |
67cb25 |
absolute tolerance
|
|
Packit |
67cb25 |
@item epsrel
|
|
Packit |
67cb25 |
relative tolerance
|
|
Packit |
67cb25 |
@item size
|
|
Packit |
67cb25 |
the size of an array or vector e.g. double array[size]
|
|
Packit |
67cb25 |
@item stride
|
|
Packit |
67cb25 |
the stride of a vector
|
|
Packit |
67cb25 |
@item size1
|
|
Packit |
67cb25 |
the number of rows in a matrix
|
|
Packit |
67cb25 |
@item size2
|
|
Packit |
67cb25 |
the number of columns in a matrix
|
|
Packit |
67cb25 |
@item n
|
|
Packit |
67cb25 |
general integer number, e.g. number of elements of array, in fft, etc
|
|
Packit |
67cb25 |
@item r
|
|
Packit |
67cb25 |
random number generator (gsl_rng)
|
|
Packit |
67cb25 |
@end table
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Datatype widths, size_t, Variable Names, Design
|
|
Packit |
67cb25 |
@section Datatype widths
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Be aware that in ANSI C the type @code{int} is only guaranteed to
|
|
Packit |
67cb25 |
provide 16-bits. It may provide more, but is not guaranteed to.
|
|
Packit |
67cb25 |
Therefore if you require 32 bits you must use @code{long int}, which
|
|
Packit |
67cb25 |
will have 32 bits or more. Of course, on many platforms the type
|
|
Packit |
67cb25 |
@code{int} does have 32 bits instead of 16 bits but we have to code to
|
|
Packit |
67cb25 |
the ANSI standard rather than a specific platform.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node size_t, Arrays vs Pointers, Datatype widths, Design
|
|
Packit |
67cb25 |
@section size_t
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
All objects (blocks of memory, etc) should be measured in terms of a
|
|
Packit |
67cb25 |
@code{size_t} type. Therefore any iterations (e.g. @code{for(i=0; i
|
|
Packit |
67cb25 |
i++)}) should also use an index of type @code{size_t}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Don't mix @code{int} and @code{size_t}. They are @emph{not}
|
|
Packit |
67cb25 |
interchangeable.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If you need to write a descending loop you have to be careful because
|
|
Packit |
67cb25 |
@code{size_t} is unsigned, so instead of
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
for (i = N - 1; i >= 0; i--) @{ ... @} /* DOESN'T WORK */
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
use something like
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
for (i = N; i-- > 0;) @{ ... @}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
to avoid problems with wrap-around at @code{i=0}. Note that the
|
|
Packit |
67cb25 |
post-decrement ensures that the loop variable is tested before it
|
|
Packit |
67cb25 |
reaches zero. Beware that @code{i} will wraparound on exit from the
|
|
Packit |
67cb25 |
loop. (This could also be written as @code{for (i = N; i--;)} since
|
|
Packit |
67cb25 |
the test for @code{i>0} is equivalent to @code{i!=0} for an unsigned
|
|
Packit |
67cb25 |
integer)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If you really want to avoid confusion use a separate variable to invert
|
|
Packit |
67cb25 |
the loop order,
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
for (i = 0; i < N; i++) @{ j = N - i; ... @}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Note (BJG). Originally, I suggested using
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
for (i = N; i > 0 && i--;) @{ ... @}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
which makes the test for @code{i>0} explicit and leaves @code{i=0} on
|
|
Packit |
67cb25 |
exit from the loop. However, it is slower as there is an additional
|
|
Packit |
67cb25 |
branch which prevents unrolling. Thanks to J. Seward for pointing
|
|
Packit |
67cb25 |
this out.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Note: As a matter of style, please use post-increment (@code{i++}) and
|
|
Packit |
67cb25 |
post-decrement (@code{i--}) operators by default and only use
|
|
Packit |
67cb25 |
pre-increment (@code{++i}) and pre-decrement (@code{--i}) operators
|
|
Packit |
67cb25 |
where specifically needed.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Arrays vs Pointers, Pointers, size_t, Design
|
|
Packit |
67cb25 |
@section Arrays vs Pointers
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
A function can be declared with either pointer arguments or array
|
|
Packit |
67cb25 |
arguments. The C standard considers these to be equivalent. However, it
|
|
Packit |
67cb25 |
is useful to distinguish between the case of a pointer, representing a
|
|
Packit |
67cb25 |
single object which is being modified, and an array which represents a
|
|
Packit |
67cb25 |
set of objects with unit stride (that are modified or not depending on
|
|
Packit |
67cb25 |
the presence of @code{const}). For vectors, where the stride is not
|
|
Packit |
67cb25 |
required to be unity, the pointer form is preferred.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@smallexample
|
|
Packit |
67cb25 |
/* real value, set on output */
|
|
Packit |
67cb25 |
int foo (double * x);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* real vector, modified */
|
|
Packit |
67cb25 |
int foo (double * x, size_t stride, size_t n);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* constant real vector */
|
|
Packit |
67cb25 |
int foo (const double * x, size_t stride, size_t n);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* real array, modified */
|
|
Packit |
67cb25 |
int bar (double x[], size_t n);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* real array, not modified */
|
|
Packit |
67cb25 |
int baz (const double x[], size_t n);
|
|
Packit |
67cb25 |
@end smallexample
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Pointers, Constness, Arrays vs Pointers, Design
|
|
Packit |
67cb25 |
@section Pointers
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Avoid dereferencing pointers on the right-hand side of an expression where
|
|
Packit |
67cb25 |
possible. It's better to introduce a temporary variable. This is
|
|
Packit |
67cb25 |
easier for the compiler to optimise and also more readable since it
|
|
Packit |
67cb25 |
avoids confusion between the use of @code{*} for multiplication and
|
|
Packit |
67cb25 |
dereferencing.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
while (fabs (f) < 0.5)
|
|
Packit |
67cb25 |
@{
|
|
Packit |
67cb25 |
*e = *e - 1;
|
|
Packit |
67cb25 |
f *= 2;
|
|
Packit |
67cb25 |
@}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
is better written as,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
@{
|
|
Packit |
67cb25 |
int p = *e;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
while (fabs(f) < 0.5)
|
|
Packit |
67cb25 |
@{
|
|
Packit |
67cb25 |
p--;
|
|
Packit |
67cb25 |
f *= 2;
|
|
Packit |
67cb25 |
@}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
*e = p;
|
|
Packit |
67cb25 |
@}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Constness, Pseudo-templates, Pointers, Design
|
|
Packit |
67cb25 |
@section Constness
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Use @code{const} in function prototypes wherever an object pointed to by
|
|
Packit |
67cb25 |
a pointer is constant (obviously). For variables which are meaningfully
|
|
Packit |
67cb25 |
constant within a function/scope use @code{const} also. This prevents
|
|
Packit |
67cb25 |
you from accidentally modifying a variable which should be constant
|
|
Packit |
67cb25 |
(e.g. length of an array, etc). It can also help the compiler do
|
|
Packit |
67cb25 |
optimization. These comments also apply to arguments passed by value
|
|
Packit |
67cb25 |
which should be made @code{const} when that is meaningful.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Pseudo-templates, Arbitrary Constants, Constness, Design
|
|
Packit |
67cb25 |
@section Pseudo-templates
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There are some pseudo-template macros available in @file{templates_on.h}
|
|
Packit |
67cb25 |
and @file{templates_off.h}. See a directory link @file{block} for
|
|
Packit |
67cb25 |
details on how to use them. Use sparingly, they are a bit of a
|
|
Packit |
67cb25 |
nightmare, but unavoidable in places.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
In particular, the convention is: templates are used for operations on
|
|
Packit |
67cb25 |
"data" only (vectors, matrices, statistics, sorting). This is intended
|
|
Packit |
67cb25 |
to cover the case where the program must interface with an external
|
|
Packit |
67cb25 |
data-source which produces a fixed type. e.g. a big array of char's
|
|
Packit |
67cb25 |
produced by an 8-bit counter.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
All other functions can use double, for floating point, or the
|
|
Packit |
67cb25 |
appropriate integer type for integers (e.g. unsigned long int for random
|
|
Packit |
67cb25 |
numbers). It is not the intention to provide a fully templated version
|
|
Packit |
67cb25 |
of the library.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
That would be "putting a quart into a pint pot". To summarize, almost
|
|
Packit |
67cb25 |
everything should be in a "natural type" which is appropriate for
|
|
Packit |
67cb25 |
typical usage, and templates are there to handle a few cases where it is
|
|
Packit |
67cb25 |
unavoidable that other data-types will be encountered.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For floating point work "double" is considered a "natural type". This
|
|
Packit |
67cb25 |
sort of idea is a part of the C language.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Arbitrary Constants, Test suites, Pseudo-templates, Design
|
|
Packit |
67cb25 |
@section Arbitrary Constants
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Avoid arbitrary constants.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For example, don't hard code "small" values like '1e-30', '1e-100' or
|
|
Packit |
67cb25 |
@code{10*GSL_DBL_EPSILON} into the routines. This is not appropriate
|
|
Packit |
67cb25 |
for a general purpose library.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Compute values accurately using IEEE arithmetic. If errors are
|
|
Packit |
67cb25 |
potentially significant then error terms should be estimated reliably
|
|
Packit |
67cb25 |
and returned to the user, by analytically deriving an error propagation
|
|
Packit |
67cb25 |
formula, not using guesswork.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
A careful consideration of the algorithm usually shows that arbitrary
|
|
Packit |
67cb25 |
constants are unnecessary, and represent an important parameter which
|
|
Packit |
67cb25 |
should be accessible to the user.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For example, consider the following code:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
if (residual < 1e-30) @{
|
|
Packit |
67cb25 |
return 0.0; /* residual is zero within round-off error */
|
|
Packit |
67cb25 |
@}
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
This should be rewritten as,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@example
|
|
Packit |
67cb25 |
return residual;
|
|
Packit |
67cb25 |
@end example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
in order to allow the user to determine whether the residual is
|
|
Packit |
67cb25 |
significant or not.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The only place where it is acceptable to use constants like
|
|
Packit |
67cb25 |
@code{GSL_DBL_EPSILON} is in function approximations, (e.g.@: Taylor
|
|
Packit |
67cb25 |
series, asymptotic expansions, etc). In these cases it is not an
|
|
Packit |
67cb25 |
arbitrary constant, but an inherent part of the algorithm.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Test suites, Compilation, Arbitrary Constants, Design
|
|
Packit |
67cb25 |
@section Test suites
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The implementor of each module should provide a reasonable test suite
|
|
Packit |
67cb25 |
for the routines.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The test suite should be a program that uses the library and checks the
|
|
Packit |
67cb25 |
result against known results, or invokes the library several times and
|
|
Packit |
67cb25 |
does a statistical analysis on the results (for example in the case of
|
|
Packit |
67cb25 |
random number generators).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Ideally the one test program per directory should aim for 100% path
|
|
Packit |
67cb25 |
coverage of the code. Obviously it would be a lot of work to really
|
|
Packit |
67cb25 |
achieve this, so prioritize testing on the critical parts and use
|
|
Packit |
67cb25 |
inspection for the rest. Test all the error conditions by explicitly
|
|
Packit |
67cb25 |
provoking them, because we consider it a serious defect if the function
|
|
Packit |
67cb25 |
does not return an error for an invalid parameter. N.B. Don't bother to
|
|
Packit |
67cb25 |
test for null pointers -- it's sufficient for the library to segfault if
|
|
Packit |
67cb25 |
the user provides an invalid pointer.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The tests should be deterministic. Use the @code{gsl_test} functions
|
|
Packit |
67cb25 |
provided to perform separate tests for each feature with a separate
|
|
Packit |
67cb25 |
output PASS/FAIL line, so that any failure can be uniquely identified.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Use realistic test cases with 'high entropy'. Tests on simple values
|
|
Packit |
67cb25 |
such as 1 or 0 may not reveal bugs. For example, a test using a value
|
|
Packit |
67cb25 |
of @math{x=1} will not pick up a missing factor of @math{x} in the code.
|
|
Packit |
67cb25 |
Similarly, a test using a value of @math{x=0} will not pick any missing
|
|
Packit |
67cb25 |
terms involving @math{x} in the code. Use values like @math{2.385} to
|
|
Packit |
67cb25 |
avoid silent failures.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If your test uses multiple values make sure there are no simple
|
|
Packit |
67cb25 |
relations between them that could allow bugs to be missed through silent
|
|
Packit |
67cb25 |
cancellations.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If you need some random floats to put in the test programs use @code{od -f
|
|
Packit |
67cb25 |
/dev/random} as a source of inspiration.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Don't use @code{sprintf} to create output strings in the tests. It can
|
|
Packit |
67cb25 |
cause hard to find bugs in the test programs themselves. The functions
|
|
Packit |
67cb25 |
@code{gsl_test_...} support format string arguments so use these
|
|
Packit |
67cb25 |
instead.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Compilation, Thread-safety, Test suites, Design
|
|
Packit |
67cb25 |
@section Compilation
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Make sure everything compiles cleanly. Use the strict compilation
|
|
Packit |
67cb25 |
options for extra checking.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@smallexample
|
|
Packit |
67cb25 |
make CFLAGS="-ansi -pedantic -Werror -W -Wall -Wtraditional -Wconversion
|
|
Packit |
67cb25 |
-Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings
|
|
Packit |
67cb25 |
-Wstrict-prototypes -fshort-enums -fno-common -Wmissing-prototypes
|
|
Packit |
67cb25 |
-Wnested-externs -Dinline= -g -O4"
|
|
Packit |
67cb25 |
@end smallexample
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@noindent
|
|
Packit |
67cb25 |
Also use @code{checkergcc} to check for memory problems on the stack and
|
|
Packit |
67cb25 |
the heap. It's the best memory checking tool. If checkergcc isn't
|
|
Packit |
67cb25 |
available then Electric Fence will check the heap, which is better than
|
|
Packit |
67cb25 |
no checking.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There is a new tool @code{valgrind} for checking memory access. Test
|
|
Packit |
67cb25 |
the code with this as well.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Make sure that the library will also compile with C++ compilers
|
|
Packit |
67cb25 |
(g++). This should not be too much of a problem if you have been writing
|
|
Packit |
67cb25 |
in ANSI C.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Thread-safety, Legal issues, Compilation, Design
|
|
Packit |
67cb25 |
@section Thread-safety
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The library should be usable in thread-safe programs. All the functions
|
|
Packit |
67cb25 |
should be thread-safe, in the sense that they shouldn't use static
|
|
Packit |
67cb25 |
variables.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
We don't require everything to be completely thread safe, but anything
|
|
Packit |
67cb25 |
that isn't should be obvious. For example, some global variables are
|
|
Packit |
67cb25 |
used to control the overall behavior of the library (range-checking
|
|
Packit |
67cb25 |
on/off, function to call on fatal error, etc). Since these are accessed
|
|
Packit |
67cb25 |
directly by the user it is obvious to the multi-threaded programmer that
|
|
Packit |
67cb25 |
they shouldn't be modified by different threads.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There is no need to provide any explicit support for threads
|
|
Packit |
67cb25 |
(e.g. locking mechanisms etc), just to avoid anything which would make
|
|
Packit |
67cb25 |
it impossible for someone to call a GSL routine from a multithreaded
|
|
Packit |
67cb25 |
program.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Legal issues, Non-UNIX portability, Thread-safety, Design
|
|
Packit |
67cb25 |
@section Legal issues
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize @bullet
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
Each contributor must make sure her code is under the GNU General Public
|
|
Packit |
67cb25 |
License (GPL). This means getting a disclaimer from your employer.
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
We must clearly understand ownership of existing code and algorithms.
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
Each contributor can retain ownership of their code, or sign it over to
|
|
Packit |
67cb25 |
FSF as they prefer.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There is a standard disclaimer in the GPL (take a look at it). The more
|
|
Packit |
67cb25 |
specific you make your disclaimer the more likely it is that it will be
|
|
Packit |
67cb25 |
accepted by an employer. For example,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@smallexample
|
|
Packit |
67cb25 |
Yoyodyne, Inc., hereby disclaims all copyright interest in the software
|
|
Packit |
67cb25 |
`GNU Scientific Library - Legendre Functions' (routines for computing
|
|
Packit |
67cb25 |
Legendre functions numerically in C) written by James Hacker.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
<signature of Ty Coon>, 1 April 1989
|
|
Packit |
67cb25 |
Ty Coon, President of Vice
|
|
Packit |
67cb25 |
@end smallexample
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
Obviously: don't use or translate non-free code.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
In particular don't copy or translate code from @cite{Numerical Recipes}
|
|
Packit |
67cb25 |
or @cite{ACM TOMS}.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Numerical Recipes is under a strict license and is not free software.
|
|
Packit |
67cb25 |
The publishers Cambridge University Press claim copyright on all aspects
|
|
Packit |
67cb25 |
of the book and the code, including function names, variable names and
|
|
Packit |
67cb25 |
ordering of mathematical subexpressions. Routines in GSL should not
|
|
Packit |
67cb25 |
refer to Numerical Recipes or be based on it in any way.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The ACM algorithms published in TOMS (Transactions on Mathematical
|
|
Packit |
67cb25 |
Software) are not public domain, even though they are distributed on the
|
|
Packit |
67cb25 |
internet -- the ACM uses a special non-commercial license which is not
|
|
Packit |
67cb25 |
compatible with the GPL. The details of this license can be found on the
|
|
Packit |
67cb25 |
cover page of ACM Transactions on Mathematical Software or on the ACM
|
|
Packit |
67cb25 |
Website.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Only use code which is explicitly under a free license: GPL or Public
|
|
Packit |
67cb25 |
Domain. If there is no license on the code then this does not mean it
|
|
Packit |
67cb25 |
is public domain -- an explicit statement is required. If in doubt check
|
|
Packit |
67cb25 |
with the author.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
I @strong{think} one can reference algorithms from classic books on
|
|
Packit |
67cb25 |
numerical analysis (BJG: yes, provided the code is an independent
|
|
Packit |
67cb25 |
implementation and not copied from any existing software. For
|
|
Packit |
67cb25 |
example, it would be ok to read the papers in ACM TOMS and make an
|
|
Packit |
67cb25 |
independent implementation from their description).
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Non-UNIX portability, Compatibility with other libraries, Legal issues, Design
|
|
Packit |
67cb25 |
@section Non-UNIX portability
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There is good reason to make this library work on non-UNIX systems. It
|
|
Packit |
67cb25 |
is probably safe to ignore DOS and only worry about windows95/windowsNT
|
|
Packit |
67cb25 |
portability (so filenames can be long, I think).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
On the other hand, nobody should be forced to use non-UNIX systems for
|
|
Packit |
67cb25 |
development.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The best solution is probably to issue guidelines for portability, like
|
|
Packit |
67cb25 |
saying "don't use XYZ unless you absolutely have to". Then the Windows
|
|
Packit |
67cb25 |
people will be able to do their porting.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Compatibility with other libraries, Parallelism, Non-UNIX portability, Design
|
|
Packit |
67cb25 |
@section Compatibility with other libraries
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
We do not regard compatibility with other numerical libraries as a
|
|
Packit |
67cb25 |
priority.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
However, other libraries, such as Numerical Recipes, are widely used.
|
|
Packit |
67cb25 |
If somebody writes the code to allow drop-in replacement of these
|
|
Packit |
67cb25 |
libraries it would be useful to people. If it is done, it would be as a
|
|
Packit |
67cb25 |
separate wrapper that can be maintained and shipped separately.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
There is a separate issue of system libraries, such as BSD math library
|
|
Packit |
67cb25 |
and functions like @code{expm1}, @code{log1p}, @code{hypot}. The
|
|
Packit |
67cb25 |
functions in this library are available on nearly every platform (but
|
|
Packit |
67cb25 |
not all).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
In this case, it is best to write code in terms of these native
|
|
Packit |
67cb25 |
functions to take advantage of the vendor-supplied system library (for
|
|
Packit |
67cb25 |
example log1p is a machine instruction on the Intel x86). The library
|
|
Packit |
67cb25 |
also provides portable implementations e.g. @code{gsl_hypot} which are
|
|
Packit |
67cb25 |
used as an automatic fall back via autoconf when necessary. See the
|
|
Packit |
67cb25 |
usage of @code{hypot} in @file{gsl/complex/math.c}, the implementation
|
|
Packit |
67cb25 |
of @code{gsl_hypot} and the corresponding parts of files
|
|
Packit |
67cb25 |
@file{configure.in} and @file{config.h.in} as an example.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Parallelism, Precision, Compatibility with other libraries, Design
|
|
Packit |
67cb25 |
@section Parallelism
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
We don't intend to provide support for parallelism within the library
|
|
Packit |
67cb25 |
itself. A parallel library would require a completely different design
|
|
Packit |
67cb25 |
and would carry overhead that other applications do not need.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Precision, Miscellaneous, Parallelism, Design
|
|
Packit |
67cb25 |
@section Precision
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For algorithms which use cutoffs or other precision-related terms please
|
|
Packit |
67cb25 |
express these in terms of @code{GSL_DBL_EPSILON} and @code{GSL_DBL_MIN}, or powers or
|
|
Packit |
67cb25 |
combinations of these. This makes it easier to port the routines to
|
|
Packit |
67cb25 |
different precisions.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Miscellaneous, , Precision, Design
|
|
Packit |
67cb25 |
@section Miscellaneous
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Don't use the letter @code{l} as a variable name --- it is difficult to
|
|
Packit |
67cb25 |
distinguish from the number @code{1}. (This seems to be a favorite in
|
|
Packit |
67cb25 |
old Fortran programs).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Final tip: one perfect routine is better than any number of routines
|
|
Packit |
67cb25 |
containing errors.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Bibliography, Copying, Design, Top
|
|
Packit |
67cb25 |
@chapter Bibliography
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@section General numerics
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Numerical Computation} (2 Volumes) by C.W. Ueberhuber,
|
|
Packit |
67cb25 |
Springer 1997, ISBN 3540620583 (Vol 1) and ISBN 3540620575 (Vol 2).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Accuracy and Stability of Numerical Algorithms} by N.J. Higham,
|
|
Packit |
67cb25 |
SIAM, ISBN 0898715210.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Sources and Development of Mathematical Software} edited by W.R. Cowell,
|
|
Packit |
67cb25 |
Prentice Hall, ISBN 0138235015.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{A Survey of Numerical Mathematics (2 vols)} by D.M. Young and R.T. Gregory,
|
|
Packit |
67cb25 |
ISBN 0486656918, ISBN 0486656926.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Methods and Programs for Mathematical Functions} by Stephen L. Moshier,
|
|
Packit |
67cb25 |
Hard to find (ISBN 13578980X or 0135789982, possibly others).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Numerical Methods That Work} by Forman S. Acton,
|
|
Packit |
67cb25 |
ISBN 0883854503.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Real Computing Made Real: Preventing Errors in Scientific and Engineering Calculations} by Forman S. Acton,
|
|
Packit |
67cb25 |
ISBN 0486442217.
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@section Reference
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Handbook of Mathematical Functions} edited by Abramowitz & Stegun,
|
|
Packit |
67cb25 |
Dover, ISBN 0486612724.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{The Art of Computer Programming} (3rd Edition, 3 Volumes) by D. Knuth,
|
|
Packit |
67cb25 |
Addison Wesley, ISBN 0201485419.
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@section Subject specific
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@itemize
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Matrix Computations} (3rd Ed) by G.H. Golub, C.F. Van Loan,
|
|
Packit |
67cb25 |
Johns Hopkins University Press 1996, ISBN 0801854148.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{LAPACK Users' Guide} (3rd Edition),
|
|
Packit |
67cb25 |
SIAM 1999, ISBN 0898714478.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Treatise on the Theory of Bessel Functions 2ND Edition} by G N Watson,
|
|
Packit |
67cb25 |
ISBN 0521483913.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@item
|
|
Packit |
67cb25 |
@cite{Higher Transcendental Functions satisfying nonhomogeneous linear differential equations} by A W Babister,
|
|
Packit |
67cb25 |
ISBN 1114401773.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@end itemize
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node Copying, GNU Free Documentation License, Bibliography, Top
|
|
Packit |
67cb25 |
@unnumbered Copying
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The subroutines and source code in the @value{GSL} package are "free";
|
|
Packit |
67cb25 |
this means that everyone is free to use them and free to redistribute
|
|
Packit |
67cb25 |
them on a free basis. The @value{GSL}-related programs are not in the
|
|
Packit |
67cb25 |
public domain; they are copyrighted and there are restrictions on their
|
|
Packit |
67cb25 |
distribution, but these restrictions are designed to permit everything
|
|
Packit |
67cb25 |
that a good cooperating citizen would want to do. What is not allowed
|
|
Packit |
67cb25 |
is to try to prevent others from further sharing any version of these
|
|
Packit |
67cb25 |
programs that they might get from you.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Specifically, we want to make sure that you have the right to give
|
|
Packit |
67cb25 |
away copies of the programs that relate to @value{GSL}, that you receive
|
|
Packit |
67cb25 |
source code or else can get it if you want it, that you can change these
|
|
Packit |
67cb25 |
programs or use pieces of them in new free programs, and that you know
|
|
Packit |
67cb25 |
you can do these things.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
To make sure that everyone has such rights, we have to forbid you to
|
|
Packit |
67cb25 |
deprive anyone else of these rights. For example, if you distribute
|
|
Packit |
67cb25 |
copies of the @value{GSL}-related code, you must give the recipients all
|
|
Packit |
67cb25 |
the rights that you have. You must make sure that they, too, receive or
|
|
Packit |
67cb25 |
can get the source code. And you must tell them their rights.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Also, for our own protection, we must make certain that everyone
|
|
Packit |
67cb25 |
finds out that there is no warranty for the programs that relate to
|
|
Packit |
67cb25 |
@value{GSL}. If these programs are modified by someone else and passed
|
|
Packit |
67cb25 |
on, we want their recipients to know that what they have is not what we
|
|
Packit |
67cb25 |
distributed, so that any problems introduced by others will not reflect
|
|
Packit |
67cb25 |
on our reputation.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The precise conditions of the licenses for the programs currently
|
|
Packit |
67cb25 |
being distributed that relate to @value{GSL} are found in the General
|
|
Packit |
67cb25 |
Public Licenses that accompany them.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@node GNU Free Documentation License, , Copying, Top
|
|
Packit |
67cb25 |
@unnumbered GNU Free Documentation License
|
|
Packit |
67cb25 |
@include fdl.texi
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @printindex cp
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @node Function Index
|
|
Packit |
67cb25 |
@c @unnumbered Function Index
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @printindex fn
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @node Variable Index
|
|
Packit |
67cb25 |
@c @unnumbered Variable Index
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @printindex vr
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @node Type Index
|
|
Packit |
67cb25 |
@c @unnumbered Type Index
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@c @printindex tp
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
@bye
|