This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: Math/Round,  Next: Math/SO3,  Prev: Math/Random,  Up: Module List

Perl extension for rounding numbers
***********************************

NAME
====

   Math::Round - Perl extension for rounding numbers

SYNOPSIS
========

     use Math::Round qw(...those desired... or :all);

     $rounded = round($scalar);
     @rounded = round(LIST...);
     $rounded = nearest($target, $scalar);
     @rounded = nearest($target, LIST...);

     # and other functions as described below

DESCRIPTION
===========

   *Math::Round* supplies functions that will round numbers in different
ways.  The functions round and nearest are exported by default; others are
available as described below.  "use ... qw(:all)" exports all functions.

FUNCTIONS
=========

round LIST
     Rounds the number(s) to the nearest integer.  In scalar context,
     returns a single value; in list context, returns a list of values.
     Numbers that are halfway between two integers are rounded "to
     infinity"; i.e., positive values are rounded up (e.g., 2.5 becomes 3)
     and negative values down (e.g., -2.5 becomes -3).

round_even LIST
     Rounds the number(s) to the nearest integer.  In scalar context,
     returns a single value; in list context, returns a list of values.
     Numbers that are halfway between two integers are rounded to the
     nearest even number; e.g., 2.5 becomes 2, 3.5 becomes 4, and -2.5
     becomes -2.

round_odd LIST
     Rounds the number(s) to the nearest integer.  In scalar context,
     returns a single value; in list context, returns a list of values.
     Numbers that are halfway between two integers are rounded to the
     nearest odd number; e.g., 3.5 becomes 3, 4.5 becomes 5, and -3.5
     becomes -3.

round_rand LIST
     Rounds the number(s) to the nearest integer.  In scalar context,
     returns a single value; in list context, returns a list of values.
     Numbers that are halfway between two integers are rounded up or down
     in a random fashion.  For example, in a large number of trials, 2.5
     will become 2 half the time and 3 half the time.

nearest TARGET, LIST
     Rounds the number(s) to the nearest multiple of the target value.
     TARGET must be positive.  In scalar context, returns a single value;
     in list context, returns a list of values.  Numbers that are halfway
     between two multiples of the target will be rounded to infinity.  For
     example:

          nearest(10, 44)    yields  40
          nearest(10, 46)            50
          nearest(10, 45)            50
          nearest(25, 328)          325
          nearest(.1, 4.567)          4.6
          nearest(10, -45)          -50

nearest_rand TARGET, LIST
     Rounds the number(s) to the nearest multiple of the target value.
     TARGET must be positive.  In scalar context, returns a single value;
     in list context, returns a list of values.  Numbers that are halfway
     between two multiples of the target will be rounded up or down in a
     random fashion.  For example, in a large number of trials,
     nearest(10, 45) will yield 40 half the time and 50 half the time.

STANDARD FLOATING-POINT DISCLAIMER
==================================

   If the numbers to be rounded are stored as floating-point, they will be
subject, as usual, to the mercies of your hardware, your C compiler, etc.
Thus, numbers that are supposed to be halfway between two others may be
stored in a slightly different way and thus behave surprisingly.

AUTHOR
======

   Math::Round was written by Geoffrey Rommel <GROMMEL@cpan.org> in
October 2000.


File: pm.info,  Node: Math/SO3,  Next: Math/SigFigs,  Prev: Math/Round,  Up: Module List

Perl extension for SO3 rotations
********************************

NAME
====

   Math::SO3 - Perl extension for SO3 rotations

   (Useful for: implementing orientation in 3d scenes. One major nice
feature of this package is to prevent numerical drift that makes rotation
matrices nonorthogonal when combining lots of them. And no, this is a
direct implementation, of SO3 it does not use quaternions and SU2->SO3
homomorphism.)

SYNOPSIS
========

     use Math::SO3;

     $rotation=Math::SO3->new("zr" => 3.14159/2,
     			   "xr" => 3.14159/4,
     			   "zr" => 3.14159/8);

     $rotation=Math::SO3->new("zd" => 90,
     			   "xd" => 90,
     			   "zr" => 3.14159/6);

     $rotation->invert();

     $rotation->turn("zr" => 3.14159/2, "xr" => 3.14159/4);

     $rotation->turn_round_axis((pack "d3", 1,1,1), 30, "degrees");

     $rotation->combine($rotation_after);

     $rotation->translate_vectors($vec1, $vec2,
                                  $vec3, $vec4, @more_vectors);

     $rotation->inv_translate_vectors($vec1, $vec2, $vec3,
     				   $vec4, @more_vectors);

     ($angle, $dir)=$rotation->turning_angle_and_dir("d");

     ($phi, $theta, $psi)=$rotation->euler_angles_zxz("d");

     ($heading, $pitch, $roll)=$rotation->euler_angles_yxz("d");

     $rotation->format_matrix();
     $rotation->format_matrix("%16.8f");

     $rotation->format_eigenvector();
     $rotation->format_eigenvector("%16.8f");

     $rotation->format_euler_zxz();
     $rotation->format_euler_zxz("%16.8f");

     $rotation->format_euler_yxz();
     $rotation->format_euler_yxz("%16.8f");

DESCRIPTION
===========

     Internal representation: SO3s are blessed refs to strings
     of size 3*3*sizeof(double) which contain the rotation
     matrix elements in standard C order. THIS IS PART OF THE
     OFFICIAL INTERFACE, so you may use this information, if
     you want. (It simply doesn't make much sense to
     inherit from purely mathematical data types like this one,
     so this doesn't hurt.)

     Note: whenever the text below says "d" is used for angles
     in degrees, any string starting with a lowercase "d" will
     work. Same goes for "r" for rad. If you entirely leave it
     away, default is "r". So you have much freedom in choosing
     those terms which are most descriptive and most readable.

     Note: some textbooks on Mechanics (like the very good and
     very influential one by Goldstein) follow the convention

     (e1')    (   ) (e1)
     (e2')  = ( M ) (e2)
     (e3')    (   ) (e3)

     This is not very fortunate, since it introduces some nasty
     ambiguity: it's easy to misinterpret the "vector-rotation
     matrix" M as the coefficient-rotation matrix, which,
     however, is just M^T.

     Matrix/vector calculus is exploited best if one agrees to
     write coefficient vectors as column vectors and the "array
     of base vectors" as a row vector (e1 e2 e3). Just look here:

     (a1)
       a1*e1 + a2*e2 + a3*e3 = (e1 e2 e3) (a2)
     (a3)

     Therefore, WE use the convention

     (a1')    (   ) (a1)
     (a2')  = ( M ) (a2)
     (a3')    (   ) (a3)

     (   )
       (e1 e2 e3) = (e1' e2' e3') ( M )
     (   )

     For details, see e.g. "Misner, Thorne, Wheeler:
     Gravitation". Unfortunately, the "wrong way" is rather
     widespread. Even OpenGL seems to want us to think this
     way. Please try not to get too confused about this; or
     better, if you are confused: yes, it's not entirely
     trivial what's going on here. Our three-dimensional space
     *is* a bit complicated.  But there is a recipe to master
     it: practice. Once you can think of one constellation in
     two different coordinate systems, you have won.

     In rigid body mechanics, it's best to think of this M as
     the matrix, which, when multiplied-right with a column
     space-coordinate vector (cscv) gives the corresponding
     column body-coordinate vector (cbcv).

     $rotation=Math::SO3->new("zr" => 3.14159/2,
     			   "xr" => 3.14159/4,
     			   "zr" => 3.14159/8);

     Create a new SO3-rotation matrix. You may specify an
     arbitrary number of rotations performed on the identity
     matrix. In the above case, if you think of $rotation as
     the matrix translating column-space-coordinate-vectors
     to column-body-coordinate-vectors (from here on called
     cscv->cbcv), these rotations you specify here will be
     applied to the body, rotating the body round one of its
     body axes. Important: Leftmost rotation will be applied
     first.  "zr" means rotate round z-axis, angle is in rad
     (full turn= 2pi rad); "xd" would mean: rotate round
     x-axis, angle is in degrees (full turn=360 degrees). Can
     be mixed.

     May also act as a copying constructor, as in:
      $copy=$rotation->new().

     $rotation->invert();

     Invert a rotation.

     $rotation->turn("zr" => 3.14159/2, "xr" => 3.14159/4);

     Just as you can specify rotations at SO3 creation,
     you may add a few more later on. Although "numerical drift" can
     build up, it is not possible for the rotation to get noticeably
     non-orthogonal.

     $rotation->turn_round_axis((pack "d3", 1,1,1), 30, "degrees");

     Turn the body round the axis given in space coordinates.

     $rotation->combine($rotation_after);

     left-multiplies with $rotation_after, that is, executes
     $rotation_after after $rotation, in the sense defined
     above.

     $rotation->translate_vectors($vec1, $vec2,
                                  $vec3, $vec4, @other_vectors);

     Destructively replace each single one of a list of
     cscv's by the corresponding cbcv's. Note that vectors
     must be packed-double-strings:
     $vec=pack("d3",$xcoord,$ycoord,$zcoord);

     Note: if vectors are "longer", say, like pack("d4", 5,8,10,1),
     only the first three coordinates will be replaced.
     This is very useful when working with homogenous coordinates.

     $rotation->inv_translate_vectors($vec1, $vec2,
                                      $vec3, $vec4, @other_vectors);

     Just the other way round, going cbcv -> cscv.

     ($angle, $dir)=$rotation->turning_angle_and_dir("d");

     Euler's theorem states that in three dimensions, every
     combination of rotations may be expressed as a single
     rotation round a given direction.  This determines angle
     and direction Say "d" if you want degrees, "r" for rad.

     FIXME code for this function is a bit weird and really
     should be reviewed. So please, you NASA guys, don't use
     it to compute RTG-satellite trajectories.

     ($phi, $theta, $psi)=$rotation->euler_angles_zxz("d");

     Returns just the famous Euler angles corresponding to a
     rotation. Specify "d" if you want degrees, "r" for rad.

     Note: this is designed for speed, and may, for a very
     small fraction of all possible angles, give bad results
     due to division by a small quantity.

     ($heading, $pitch, $roll)=$rotation->euler_angles_yxz("d");

     Standard zxz euler angles have one problem: if theta
     is very small, phi and psi rotations nearly go in
     the same direction, therefore, it's a bit difficult
     to see from coordinates if two rotations are very
     similar or are absolutely not. This is an alternative
     angle specification which is very common in aeronautics.
     Probably just the thing you need if you want to build
     a flight simulator.

     Note: accuracy see above.

     $rotation->format_matrix();
     $rotation->format_matrix("%16.8f");

     Computes a string
     "[[m00 m01 m02][m10 m11 m12][m20 m21 m22]]"
     displaying the matrix elements. Optionally, a sprintf
     format-string may be specified for the matrix
     elements. Default is "%10.5f".

     $rotation->format_eigenvector();
     $rotation->format_eigenvector("%16.8f");

     Similarly, computes a string like
     "<rotate   92.06153 deg round [   0.88972    0.07784   -0.44982]>"

     $rotation->format_euler_zxz();
     $rotation->format_euler_zxz("%16.8f");

     Similarly, computes a string like
     "<D_z(psi= 330.00000 deg) D_x(theta=  80.00000 deg) D_z(phi= 340.00000 deg)>"

     $rotation->format_euler_yxz();
     $rotation->format_euler_yxz("%16.8f");

     Just the same, but string is like
     "<D_z(heading= 338.30608 deg) D_x(pitch= -24.51349 deg) D_z(roll= 348.25034 deg)>"

     Basically, these functions were added as a quick way to
     get debugging info.  Therefore, all angles are given in
     degrees, since these are more readable.

AUTHOR AND LICENSE
==================

   Copyright 1999 Thomas Fischbacher

   (tf@cip.physik.uni-muenchen.de)

   License: GNU Lesser General Public License (aka GNU LGPL) Copy of the
LGPL not included, since it should come with your copy of perl. You may
find it at

   http://www.gnu.org/copyleft/lesser.html

SEE ALSO
========

   perl(1).


File: pm.info,  Node: Math/SigFigs,  Next: Math/Spline,  Prev: Math/SO3,  Up: Module List

do math with correct handling of significant figures
****************************************************

NAME
====

   Math::SigFigs - do math with correct handling of significant figures

SYNOPSIS
========

   If you only need to use CountSigFigs and FormatSigFigs, use the first
form.  If you are going to be doing arithmetic, use the second line.

     use Math::SigFigs;
     use Math::SigFigs qw(:all);

   The following routines do simple counting/formatting:

     $n=&CountSigFigs($num);
     $num=&FormatSigFigs($num,$n);

   Use the following routines to do arithmetic operations.

     $num=&addSF($n1,$n2);
     $num=&subSF($n1,$n2);
     $num=&multSF($n1,$n2);
     $num=&divSF($n1,$n2);

DESCRIPTION
===========

   In many scientific applications, it is often useful to be able to format
numbers with a given number of significant figures, or to do math in such
a way as to maintain the correct number of significant figures.  The rules
for significant figures are too complicated to be handled solely using the
sprintf function (unless you happen to be Randal Schwartz :-).

   These routines allow you to correctly handle significan figures.

   It can count the number of significan figures, format a number to a
given number of significant figures, and do basic arithmetic.

ROUTINES
========

CountSigFigs
          $n=&CountSigFigs($N);

     This returns the number of significant figures in a number.  It
     returns () if $N is not a number.

          $N      $n
          -----   --
          240     2
          240.    3
          241     3
          0240    2
          0.03    1
          0       0
          0.0     0

FormatSigFigs
          $str=&FormatSigFigs($N,$n)

     This returns a string containing $N formatted to $n significant
     figures.  This will work for all cases except something like "2400"
     formatted to 3 significant figures.

          $N     $n   $str
          ------ --   -------
          2400    1   2000
          2400    2   2400
          2400    3   2400
          2400    4   2400.
          2400    5   2400.0

          141     3   141.
          141     2   140

          0.039   1   0.04
          0.039   2   0.039

          9.9     1   10
          9.9     2   9.9
          9.9     3   9.90

addSF, subSF, multSF, divSF
     These routines add/subtract/multiply/divide two numbers while
     maintaining the proper number of significant figures.

KNOWN PROBLEMS
==============

   These routines do not work with scientific notation (exponents).  As a
result, it is impossible to unambiguously format some numbers.  For
example,

     $str=&FormatSigFigs("2400",3);

   will by necessity return the string "2400" which does NOT have 3
significant figures.  This is not a bug.  It is simply a fundamental
problem with working with significant figures when not using scientific
notation.

AUTHOR
======

   Sullivan Beck (sbeck@cise.ufl.edu)


File: pm.info,  Node: Math/Spline,  Next: Math/Trig,  Prev: Math/SigFigs,  Up: Module List

SYNOPSIS          require Math::Spline;     $spline=new Math::Spline(\@x,\@y)     $y_interp=$spline->evaluate($x);
==================================================================================================================

     use Math::Spline qw(spline linsearch binsearch);
     use Math::Derivative qw(Derivative2);
     @y2=Derivative2(\@x,\@y);
     $index=binsearch(\@x,$x);
     $index=linsearch(\@x,$x,$index);
     $y_interp=spline(\@x,\@y,\@y2,$index,$x);

DESCRIPTION
===========

   This package provides cubic spline interpolation of numeric data. The
data is passed as references to two arrays containing the x and y
ordinates. It may be used as an exporter of the numerical functions or,
more easily as a class module.

   The *Math::Spline* class constructor new takes references to the arrays
of x and y ordinates of the data. An interpolation is performed using the
evaluate method, which, when given an x ordinate returns the interpolate y
ordinate at that value.

   The *spline* function takes as arguments references to the x and y
ordinate array, a reference to the 2nd derivatives (calculated using
*Derivative2*, the low index of the interval in which to interpolate and
the x ordinate in that interval. Returned is the interpolated y ordinate.
Two functions are provided to look up the appropriate index in the array
of x data. For random calls *binsearch* can be used - give a reference to
the x ordinates and the x loopup value it returns the low index of the
interval in the data in which the value lies. Where the lookups are
strictly in ascending sequence (e.g. if interpolating to produce a higher
resolution data set to draw a curve) the *linsearch* function may more
efficiently be used. It performs like *binsearch*, but requires a third
argument being the previous index value, which is incremented if necessary.

NOTE
====

   requires Math::Derivative module

EXAMPLE
=======

     require Math::Spline;
     my @x=(1,3,8,10);
     my @y=(1,2,3,4);
     $spline=new Math::Spline(\@x,\@y);
     print $spline->evaluate(5)."\n";

   produces the output

   2.44

HISTORY
=======

   $Log: Spline.pm,v $ Revision 1.1  1995/12/26 17:28:17  willijar Initial
revision

BUGS
====

   Bug reports or constructive comments are welcome.

AUTHOR
======

   John A.R. Williams <J.A.R.Williams@aston.ac.uk>

SEE ALSO
========

   "Numerical Recipies: The Art of Scientific Computing" W.H. Press, B.P.
Flannery, S.A. Teukolsky, W.T. Vetterling.  Cambridge University Press.
ISBN 0 521 30811 9.


File: pm.info,  Node: Math/Trig,  Next: Math/TrulyRandom,  Prev: Math/Spline,  Up: Module List

trigonometric functions
***********************

NAME
====

   Math::Trig - trigonometric functions

SYNOPSIS
========

     use Math::Trig;

     $x = tan(0.9);
     $y = acos(3.7);
     $z = asin(2.4);

     $halfpi = pi/2;

     $rad = deg2rad(120);

DESCRIPTION
===========

   Math::Trig defines many trigonometric functions not defined by the core
Perl which defines only the `sin()' and `cos()'.  The constant pi is also
defined as are a few convenience functions for angle conversions.

TRIGONOMETRIC FUNCTIONS
=======================

   The tangent

tan
   The cofunctions of the sine, cosine, and tangent (cosec/csc and
cotan/cot are aliases)

   *csc*, *cosec*, sec, sec, *cot*, *cotan*

   The arcus (also known as the inverse) functions of the sine, cosine,
and tangent

   asin, acos, atan

   The principal value of the arc tangent of y/x

   atan2(y, x)

   The arcus cofunctions of the sine, cosine, and tangent (acosec/acsc and
acotan/acot are aliases)

   *acsc*, *acosec*, *asec*, *acot*, *acotan*

   The hyperbolic sine, cosine, and tangent

   sinh, cosh, tanh

   The cofunctions of the hyperbolic sine, cosine, and tangent (cosech/csch
and cotanh/coth are aliases)

   *csch*, *cosech*, *sech*, *coth*, *cotanh*

   The arcus (also known as the inverse) functions of the hyperbolic sine,
cosine, and tangent

   asinh, acosh, atanh

   The arcus cofunctions of the hyperbolic sine, cosine, and tangent
(acsch/acosech and acoth/acotanh are aliases)

   *acsch*, *acosech*, *asech*, *acoth*, *acotanh*

   The trigonometric constant pi is also defined.

   $pi2 = 2 * pi;

ERRORS DUE TO DIVISION BY ZERO
------------------------------

   The following functions

     acoth
     acsc
     acsch
     asec
     asech
     atanh
     cot
     coth
     csc
     csch
     sec
     sech
     tan
     tanh

   cannot be computed for all arguments because that would mean dividing
by zero or taking logarithm of zero. These situations cause fatal runtime
errors looking like this

     cot(0): Division by zero.
     (Because in the definition of cot(0), the divisor sin(0) is 0)
     Died at ...

   or

     atanh(-1): Logarithm of zero.
     Died at...

   For the `csc', `cot', `asec', `acsc', `acot', `csch', `coth', `asech',
`acsch', the argument cannot be 0 (zero).  For the atanh, `acoth', the
argument cannot be 1 (one).  For the atanh, `acoth', the argument cannot
be `-1' (minus one).  For the tan, sec, tanh, `sech', the argument cannot
be *pi/2 + k * pi*, where k is any integer.

SIMPLE (REAL) ARGUMENTS, COMPLEX RESULTS
----------------------------------------

   Please note that some of the trigonometric functions can break out from
the *real axis* into the *complex plane*. For example `asin(2)' has no
definition for plain real numbers but it has definition for complex
numbers.

   In Perl terms this means that supplying the usual Perl numbers (also
known as scalars, please see *Note Perldata: (perl.info)perldata,) as
input for the trigonometric functions might produce as output results that
no more are simple real numbers: instead they are complex numbers.

   The Math::Trig handles this by using the Math::Complex package which
knows how to handle complex numbers, please see *Note Math/Complex:
Math/Complex, for more information. In practice you need not to worry
about getting complex numbers as results because the Math::Complex takes
care of details like for example how to display complex numbers. For
example:

     print asin(2), "\n";

   should produce something like this (take or leave few last decimals):

     1.5707963267949-1.31695789692482i

   That is, a complex number with the real part of approximately `1.571'
and the imaginary part of approximately `-1.317'.

PLANE ANGLE CONVERSIONS
=======================

   (Plane, 2-dimensional) angles may be converted with the following
functions.

     $radians  = deg2rad($degrees);
     $radians  = grad2rad($gradians);

     $degrees  = rad2deg($radians);
     $degrees  = grad2deg($gradians);

     $gradians = deg2grad($degrees);
     $gradians = rad2grad($radians);

   The full circle is 2 pi radians or *360* degrees or *400* gradians.

RADIAL COORDINATE CONVERSIONS
=============================

   *Radial coordinate systems* are the *spherical* and the *cylindrical*
systems, explained shortly in more detail.

   You can import radial coordinate conversion functions by using the
`:radial' tag:

     use Math::Trig ':radial';

     ($rho, $theta, $z)     = cartesian_to_cylindrical($x, $y, $z);
     ($rho, $theta, $phi)   = cartesian_to_spherical($x, $y, $z);
     ($x, $y, $z)           = cylindrical_to_cartesian($rho, $theta, $z);
     ($rho_s, $theta, $phi) = cylindrical_to_spherical($rho_c, $theta, $z);
     ($x, $y, $z)           = spherical_to_cartesian($rho, $theta, $phi);
     ($rho_c, $theta, $z)   = spherical_to_cylindrical($rho_s, $theta, $phi);

   *All angles are in radians*.

COORDINATE SYSTEMS
------------------

   *Cartesian* coordinates are the usual rectangular *(x, y,
z)*-coordinates.

   Spherical coordinates, *(rho, theta, pi)*, are three-dimensional
coordinates which define a point in three-dimensional space.  They are
based on a sphere surface.  The radius of the sphere is *rho*, also known
as the *radial* coordinate.  The angle in the *xy*-plane (around the
z-axis) is *theta*, also known as the *azimuthal* coordinate.  The angle
from the z-axis is *phi*, also known as the *polar* coordinate.  The
`North Pole' is therefore *0, 0, rho*, and the `Bay of Guinea' (think of
the missing big chunk of Africa) *0, pi/2, rho*.  In geographical terms
*phi* is latitude (northward positive, southward negative) and *theta* is
longitude (eastward positive, westward negative).

   *BEWARE*: some texts define *theta* and *phi* the other way round, some
texts define the *phi* to start from the horizontal plane, some texts use
r in place of *rho*.

   Cylindrical coordinates, *(rho, theta, z)*, are three-dimensional
coordinates which define a point in three-dimensional space.  They are
based on a cylinder surface.  The radius of the cylinder is *rho*, also
known as the *radial* coordinate.  The angle in the *xy*-plane (around the
z-axis) is *theta*, also known as the *azimuthal* coordinate.  The third
coordinate is the z, pointing up from the *theta*-plane.

3-D ANGLE CONVERSIONS
---------------------

   Conversions to and from spherical and cylindrical coordinates are
available.  Please notice that the conversions are not necessarily
reversible because of the equalities like pi angles being equal to *-pi*
angles.

cartesian_to_cylindrical
          ($rho, $theta, $z) = cartesian_to_cylindrical($x, $y, $z);

cartesian_to_spherical
          ($rho, $theta, $phi) = cartesian_to_spherical($x, $y, $z);

cylindrical_to_cartesian
          ($x, $y, $z) = cylindrical_to_cartesian($rho, $theta, $z);

cylindrical_to_spherical
          ($rho_s, $theta, $phi) = cylindrical_to_spherical($rho_c, $theta, $z);

     Notice that when `$z' is not 0 `$rho_s' is not equal to `$rho_c'.

spherical_to_cartesian
          ($x, $y, $z) = spherical_to_cartesian($rho, $theta, $phi);

spherical_to_cylindrical
          ($rho_c, $theta, $z) = spherical_to_cylindrical($rho_s, $theta, $phi);

     Notice that when `$z' is not 0 `$rho_c' is not equal to `$rho_s'.

GREAT CIRCLE DISTANCES
======================

   You can compute spherical distances, called *great circle distances*,
by importing the `great_circle_distance' function:

     use Math::Trig 'great_circle_distance'

     $distance = great_circle_distance($theta0, $phi0, $theta1, $phi1, [, $rho]);

   The *great circle distance* is the shortest distance between two points
on a sphere.  The distance is in `$rho' units.  The `$rho' is optional, it
defaults to 1 (the unit sphere), therefore the distance defaults to
radians.

   If you think geographically the *theta* are longitudes: zero at the
Greenwhich meridian, eastward positive, westward negative-and the *phi*
are latitudes: zero at the North Pole, northward positive, southward
negative.  NOTE: this formula thinks in mathematics, not geographically:
the *phi* zero is at the North Pole, not at the Equator on the west coast
of Africa (Bay of Guinea).  You need to subtract your geographical
coordinates from *pi/2* (also known as 90 degrees).

     $distance = great_circle_distance($lon0, pi/2 - $lat0,
                                       $lon1, pi/2 - $lat1, $rho);

EXAMPLES
========

   To calculate the distance between London (51.3N 0.5W) and Tokyo (35.7N
139.8E) in kilometers:

     use Math::Trig qw(great_circle_distance deg2rad);

     # Notice the 90 - latitude: phi zero is at the North Pole.
     	@L = (deg2rad(-0.5), deg2rad(90 - 51.3));
     @T = (deg2rad(139.8),deg2rad(90 - 35.7));

     $km = great_circle_distance(@L, @T, 6378);

   The answer may be off by few percentages because of the irregular
(slightly aspherical) form of the Earth.  The used formula

     lat0 = 90 degrees - phi0
     lat1 = 90 degrees - phi1
     d = R * arccos(cos(lat0) * cos(lat1) * cos(lon1 - lon01) +
                            sin(lat0) * sin(lat1))

   is also somewhat unreliable for small distances (for locations
separated less than about five degrees) because it uses arc cosine which
is rather ill-conditioned for values close to zero.

BUGS
====

   Saying `use Math::Trig;' exports many mathematical routines in the
caller environment and even overrides some (sin, cos).  This is construed
as a feature by the Authors, actually... ;-)

   The code is not optimized for speed, especially because we use
Math::Complex and thus go quite near complex numbers while doing the
computations even when the arguments are not. This, however, cannot be
completely avoided if we want things like `asin(2)' to give an answer
instead of giving a fatal runtime error.

AUTHORS
=======

   Jarkko Hietaniemi <`jhi@iki.fi'> and Raphael Manfredi
<`Raphael_Manfredi@pobox.com'>.


File: pm.info,  Node: Math/TrulyRandom,  Next: Math/Units,  Prev: Math/Trig,  Up: Module List

Perl interface to a truly random number generator function
**********************************************************

NAME
====

   TrulyRandom - Perl interface to a truly random number generator function

SYNOPSIS
========

     use Math::TrulyRandom;
     
     $random = truly_random_value();

DESCRIPTION
===========

   The *TrulyRandom* module provides an ability to generate truly random
numbers from within Perl programs.  The source of the randomness is from
interrupt timing discrepancies.

EXAMPLE
=======

     $random = truly_random_value();

BUGS
====

   The random numbers take a long time (in computer terms) to generate, so
are only really useful for seeding pseudo random sequence generators.

COPYRIGHT
=========

   This implementation derives from the truly random number generator
function developed by Matt Blaze and Don Mitchell, and is copyright of
AT&T.  Other parts of this perl extension are copyright of Systemics Ltd (
http://www.systemics.com/ ).


File: pm.info,  Node: Math/Units,  Next: Math/VecStat,  Prev: Math/TrulyRandom,  Up: Module List

Unit conversion
***************

NAME
====

   Math::Units - Unit conversion

SYNOPSIS
========

   use Math::Units qw(convert);

   my $out_value = convert($in_value, 'in unit', 'out unit');

DESCRIPTION
===========

   The Math::Units module converts a numeric value in one unit of
measurement to some other unit.  The units must be compatible, i.e. length
can not be converted to volume.  If a conversion can not be made an
exception is thrown.

   A combination chaining and reduction algorithm is used to perform the
most direct unit conversion possible.  Units may be written in several
different styles.  An abbreviation table is used to convert from common
long-form unit names to the (more or less) standard abbreviations that the
units module uses internally.  All multiplicative unit conversions are
cached so that future conversions can be performed very quickly.

   Too many units, prefixes and abbreviations are supported to list here.
See the source code for a complete listing.

EXAMPLES
========

   print "5 mm == ", convert(5, 'mm', 'in'), " inches\n"; print "72
degrees Farenheit == ", convert(72, 'F', 'C'), " degrees Celsius\n"; print
"1 gallon == ", convert(1, 'gallon', 'cm^3'), " cubic centimeters\n";
print "4500 rpm == ", convert(4500, 'rpm', 'Hz'), " Hertz\n";


File: pm.info,  Node: Math/VecStat,  Next: Mcrypt,  Prev: Math/Units,  Up: Module List

Some basic numeric stats on vectors
***********************************

NAME
====

     Math::VecStat - Some basic numeric stats on vectors

SYNOPSIS
========

     use Math::VecStat qw(max min maxabs minabs sum average);
     $max=max(@vector);
     $max=max(\@vector);
     ($max,$imax)=max(@vector);
     ($max,$imax)=max(\@vector);
     $min=min(@vector);
     $min=min(\@vector);
     ($max,$imin)=min(@vector);
     ($max,$imin)=min(\@vector);
     $max=maxabs(@vector);
     $max=maxabs(\@vector);
     ($max,$imax)=maxabs(@vector);
     ($max,$imax)=maxabs(\@vector);
     $min=minabs(@vector);
     $min=minabs(\@vector);
     ($max,$imin)=minabs(@vector);
     ($max,$imin)=minabs(\@vector);
     $sum=sum($v1,$v2,...);
     $sum=sum(@vector);
     $sum=sum(\@vector);
     $average=average($v1,$v2,...);
     $av=average(@vector);
     $av=average(\@vector);
     $ref=vecprod($scalar,\@vector);
     $ok=ordered(@vector);
     $ok=ordered(\@vector);
     $ref=sumbyelement(\@vector1,\@vector2);
     $ref=diffbyelement(\@vector1,\@vector2);
     $ok=allequal(\@vector1,\@vector2);
     $ref=convolute(\@vector1,\@vector2);

DESCRIPTION
===========

   This package provides some basic statistics on numerical vectors. All
the subroutines can take a reference to the vector to be operated on. In
some cases a copy of the vector is acceptable, but is not recommended for
efficiency.

max(@vector), max(\@vector)
     return the maximum value of given values or vector. In an array
     context returns the value and the index in the array where it occurs.

min(@vector), min(\@vector)
     return the minimum value of given values or vector, In an array
     context returns the value and the index in the array where it occurs.

maxabs(@vector), maxabs(\@vector)
     return the maximum value of absolute of the given values or vector. In
     an array context returns the value and the index in the array where it
     occurs.

minabs(@vector), minabs(\@vector)
     return the minimum value of the absolute of the given values or
     vector. In an array context returns the value and the index in the
     array where it occurs.

sum($v1,$v2,...), sum(@vector), sum(\@vector)
     return the sum of the given values or vector

average($v1,$v2,..), average(@vector), average(\@vector)
     return the average of the given values or vector

vecprod($a,$v1,$v2,..), vecprod($a,@vector), vecprod( $a, \@vector )
     return a vector built by multiplying the scalar $a by each element of
     the  @vector.

ordered($v1,$v2,..), ordered(@vector), ordered(\@vector)
     return nonzero iff the vector is nondecreasing with respect to its
     index.  To be used like

          if( ordered( $lowBound, $value, $highBound ) ){

     instead of the (slightly) more clumsy

          if( ($lowBound <= $value) && ($value <= $highBound) ) {

sumbyelement( \@array1, \@array2 ), diffbyelement(\@array1,\@array2)
     return the element-by-element sum or difference of two
     identically-sized vectors. Given

          $s = sumbyelement( [10,20,30], [1,2,3] );
          $d = diffbyelement( [10,20,30], [1,2,3] );

     $s will be `[11,22,33]', $d will be `[9,18,27]'.

allequal( \@array1, \@array2 )
     returns true if and only if the two arrays are numerically identical.

convolute( \@array1, \@array2 )
     return a reference to an array containing the element-by-element
     product of the two input arrays. I.e.,

          $r = convolute( [1,2,3], [-1,2,1] );

     returns a reference to

          [-1,4,3]

HISTORY
=======

     $Log: VecStat.pm,v $
     Revision 1.7  2000/10/24 15:28:00  spinellia@acm.org
     Added functions allequal diffbyelement
     Created a reasonable test suite.

     Revision 1.6  2000/06/29 16:06:37  spinellia@acm.org
     Added functions vecprod, convolute, sumbyelement

     Revision 1.5  1997/02/26 17:20:37  willijar
     Added line before pod header so pod2man installs man page correctly

     Revision 1.4  1996/02/20 07:53:10  willijar
     Added ability to return index in array contex to max and min
     functions. Added minabs and maxabs functions.
     Thanks to Mark Borges <mdb@cdc.noaa.gov> for these suggestions.

     Revision 1.3  1996/01/06 11:03:30  willijar
     Fixed stupid bug that crept into looping in min and max functions

     Revision 1.2  1995/12/26 09:56:38  willijar
     Oops - removed xy data functions.

     Revision 1.1  1995/12/26 09:39:07  willijar
     Initial revision

BUGS
====

   Let me know. I welcome any appropriate additions for this package.

AUTHORS
=======

   John A.R. Williams <J.A.R.Williams@aston.ac.uk> Andrea Spinelli
<spinellia@acm.org>


File: pm.info,  Node: Mcrypt,  Next: MegaHAL,  Prev: Math/VecStat,  Up: Module List

Perl extension for the Mcrypt cryptography library
**************************************************

NAME
====

   Mcrypt - Perl extension for the Mcrypt cryptography library

SYNOPSIS
========

     use Mcrypt;

     # Procedural routines

     $td = Mcrypt::mcrypt_load($algorithm, $algorithm_dir,
     			    $mode, $mode_dir);

     Mcrypt::mcrypt_get_key_size($td);   # in bytes
     Mcrypt::mcrypt_get_iv_size($td);    # in bytes
     Mcrypt::mcrypt_get_block_size($td); # in bytes

     Mcrypt::mcrypt_init($td, $key, $iv);

     $encryptedstr = Mcrypt::mcrypt_encrypt($td, $decryptedstr);
     $decryptedstr = Mcrypt::mcrypt_decrypt($td, $encryptedstr);

     Mcrypt::mcrypt_end($td);

     # Object-oriented methods

     $td = Mcrypt->new( algorithm => $algorithm,
     		     mode => $mode );

     $keysize = $td->{KEY_SIZE};
     $ivsize  = $td->{IV_SIZE};
     $blksize = $td->{BLOCK_SIZE};

     $td->init($key, $iv);

     $encryptedstr = $td->encrypt($decryptedstr);
     $decryptedstr = $td->decrypt($encryptedstr);

     # If the $td goes out of context,
     # the destructor will do this for you
     $td->end();

DESCRIPTION
===========

   This module wraps the libmcrypt encryption library for easy and
convenient use from within perl.  Encryption and decryption using a
variety of algorithms is as easy as a few simple lines of perl.

Exported constants
==================

   The predefined groups of exports in the use statements are as follows:

   use Mcrypt qw(:ALGORITHMS);

   Exports the BLOWFISH DES 3DES 3WAY GOST SAFER_SK64 SAFER_SK128 CAST_128
XTEA RC2 TWOFISH CAST_256 SAFERPLUS LOKI97 SERPENT RIJNDAEL_128
RIJNDAEL_192 RIJNDAEL_256 ENIGMA ARCFOUR WAKE libmcrypt algorithms.  See
the mcrypt(3) man page for more details.

   use Mcrypt qw(:MODES);

   Exports the CBC ECB CFB OFB bOFB STREAM modes of encryption.  See the
mcrypt(3) man page for more details.

   use Mcrypt qw(:FUNCS);

   Exports the following functions: mcrypt_load, mcrypt_unload,
mcrypt_init, mcrypt_end, mcrypt_encrypt, mcrypt_decrypt,
mcrypt_get_block_size, mcrypt_get_iv_size, mcrypt_get_key_size.

EXAMPLES
========

     # Procedural approach:
     # create an ecryption descriptor:
     #   ALGORITHM: blowfish (256 bit key + 16 byte IV)
     #   MODE:      cfb
     # The user application has set:
     #   $method to either "encrypt" or "decrypt"
     #   $infile to the input filename
     #   $outfile to the output filename
     my($td) = Mcrypt::mcrypt_load( Mcrypt::BLOWFISH, '',
     				 Mcrypt::CFB, '' );
     my($key) = "32 bytes of your apps secret key";  # secret key
     my($iv) = "16 bytes of rand"; # shared initialization vector
     Mcrypt::mcrypt_init($td, $key, $iv) || die "Could not initialize td";
     print Mcrypt::mcrypt_encrypt($td, $_) while(<>);
     Mcrypt::mcrypt_end($td);

     # OO approach of the above except decrypting
     my($td) = Mcrypt->new( algorithm => Mcrypt::BLOWFISH,
                            mode => Mcrypt::CFB,
                            verbose => 0 );
     my($key) = "k" x $td->{KEY_SIZE};
     my($iv) = "i" x $td->{IV_SIZE};
     $td->init($key, $iv);
     print $td->decrypt($_) while (<>);
     $td->end();

AUTHOR
======

   Theo Schlossnagle <jesus@omniti.com>

SEE ALSO
========

   The libmcrypt man page: mcrypt(3).  Other libmcrypt information is
available at http://mcrypt.hellug.gr/.


File: pm.info,  Node: MegaHAL,  Next: MemHandle,  Prev: Mcrypt,  Up: Module List

Perl interface to the MegaHAL natural language             conversation simulator.
**********************************************************************************

NAME
====

     MegaHAL - Perl interface to the MegaHAL natural language
               conversation simulator.

SYNOPSIS
========

     use MegaHAL;

     $megahal = new MegaHAL('Path'     => './',
                            'Banner'   => 0,
                            'Prompt'   => 0,
                            'Wrap'     => 0,
                            'AutoSave' => 0);

     $text = $megahal->initial_greeting();
     $text = $megahal->do_reply($message);

DESCRIPTION
===========

     Conversation simulators are computer programs which give
     the appearance of conversing with a user in natural
     language.  Such programs are effective because they
     exploit the fact that human beings tend to read much more
     meaning into what is said than is actually there; we are
     fooled into reading structure into chaos, and we
     interpret non-sequitur as valid conversation.

     This package provides a Perl interface to the MegaHAL
     conversation simulator written by Jason Hutchens.

USAGE
=====

     $megahal = new MegaHAL('Path'     => './',
                            'Banner'   => 0,
                            'Prompt'   => 0,
                            'Wrap'     => 0,
                            'AutoSave' => 0);

     Creates a new MegaHAL object.  The object constructor can
     optionaly receive the following named parameters:

     'Path'   - The path to MegaHALs brain or training file
                (megahal.brn and megahal.trn respectively).
                If 'Path' is not specified the current working
                directory is assumed.

     'Banner' - A flag which enables/disables the banner
                which is displayed when MegaHAL starts up.
                The default is to disable the banner.

     'Prompt' - A flag which enables/disables the prompt. This
                flag is only useful when MegaHAL is run
                interactively and is disabled by default.

     'Wrap'   - A flag which enables/disables word wrapping of
                MegaHALs responses when the lines exceed 80
                characters in length.  The default is to
                disable word wrapping.

     $text = $megahal->initial_greeting();

     Returns a string containing the initial greeting which is
     created by MegaHAL at startup.

     $text = $megahal->do_reply($message);

     Generates reply $text to a given message $message.

BUGS
====

     None known at this time.

AUTHORS
=======

     The Perl MegaHAL interface was written by Cory Spencer
     <cspencer@interchange.ubc.ca>

     MegaHAL was originally written by and is copyright
     Jason Hutchens <hutch@ciips.ee.uwa.edu.au>


File: pm.info,  Node: MemHandle,  Next: MemHandle/Tie,  Prev: MegaHAL,  Up: Module List

supply memory-based FILEHANDLE methods
**************************************

NAME
====

   MemHandle - supply memory-based FILEHANDLE methods

SYNOPSIS
========

     use MemHandle;
     use IO::Seekable;

     my $mh = new MemHandle;
     print $mh "foo\n";
     $mh->print( "bar\n" );
     printf $mh "This is a number: %d\n", 10;
     $mh->printf( "a string: \"%s\"\n", "all strings come to those who wait" );

     my $len = $mh->tell();  # Use $mh->tell();
                             # tell( $mh ) will NOT work!
     $mh->seek(0, SEEK_SET); # Use $mh->seek($where, $whence)
                             # seek($mh, $where, $whence)
                             # will NOT work!

     my $memory = $mh->mem();

     Here's the real meat:

     my $mh = new MemHandle;
     my $old = select( $mh );
     .
     .
     .
     print "foo bar\n";
     print "baz\n";
     &MyPrintSub();
     select( $old );

     print "here it all is: ", $mh->mem(), "\n";

DESCRIPTION
===========

   Generates inherits from IO::Handle and IO::Seekable. It provides an
interface to the file routines which uses memory instead.  See perldoc
IO::Handle, and perldoc IO::Seekable as well as *Note Perlfunc:
(perl.info)perlfunc, for more detailed descriptions of the provided
built-in functions:

     print
     printf
     readline
     sysread
     syswrite
     getc
     gets

   The following functions are provided, but tie doesn't allow them to be
tied to the built in functions.  They should be used by calling the
appropriate method on the MemHandle object.

     seek
     tell

   call them like this:

     my $mh = new MemHandle();
     .
     .
     .
     my $pos = $mh->tell();
     $mh->seek( 0, SEEK_SET );

CONSTRUCTOR
===========

new( [mem] )
     Creates a `MemHandle', which is a reference to a newly created symbol
     (see the Symbol package).  It then ties the FILEHANDLE to
     `MemHandle::Tie' (see `"Tying FileHandles"', *Note Perltie:
     (perl.info)perltie,).  Tied methods in `MemHandle::Tie' translate
     file operations into reads/writes into a string, which can be
     accessed by calling `MemHandle::mem'.

METHODS
=======

seek( POS, WHENCE )
     Sets the read/write position to WHENCE + POS.  WHENCE is one of the
     constants which are available from IO::Seekable or POSIX:

          SEEK_SET # absolute position from the beginning.
          SEEK_CUR # offset from the current location.
          SEEK_END # from the end (POS can be negative).

tell()
     Returns the current position of the mem-file, similiar to the way tell
     would.  (See *Note Perlfunc: (perl.info)perlfunc,).

mem( [mem] )
     gets or sets the memory.  If called with a parameter, it copies it to
     the memory and sets the position to be immediately after (so if you
     write more to it, you append the string).  Returns the current value
     of memory.

AUTHOR
======

   "Sheridan C. Rawlins" <scr14@cornell.edu>

SEE ALSO
========

   *Note Perl: (perl.info)perl,.  *Note Perlfunc: (perl.info)perlfunc,.
`"Tying FileHandles"', *Note Perltie: (perl.info)perltie,.  perldoc
IO::Handle.  perldoc IO::Seekable.  perldoc Symbol.


File: pm.info,  Node: MemHandle/Tie,  Next: Memoize,  Prev: MemHandle,  Up: Module List

The package which ties the MemHandle to memory.
***********************************************

NAME
====

   MemHandle::Tie - The package which ties the MemHandle to memory.

SYNOPSIS
========

DESCRIPTION
===========

   This should not be used except by MemHandle.  It provides functions for
tie-ing a FILEHANDLE.  See `"Tying FileHandles"', *Note Perltie:
(perl.info)perltie, for more detail.

AUTHOR
======

   "Sheridan C. Rawlins" <scr14@cornell.edu>

SEE ALSO
========

   *Note Perl: (perl.info)perl,.  *Note Perlfunc: (perl.info)perlfunc,.
`"Tying FileHandles"', *Note Perltie: (perl.info)perltie,.  perldoc
MemHandle.


File: pm.info,  Node: Memoize,  Next: Memoize/Expire,  Prev: MemHandle/Tie,  Up: Module List

Make your functions faster by trading space for time
****************************************************

NAME
====

   Memoize - Make your functions faster by trading space for time

SYNOPSIS
========

     use Memoize;
     memoize('slow_function');
     slow_function(arguments);    # Is faster than it was before

   This is normally all you need to know.  However, many options are
available:

     memoize(function, options...);

   Options include:

     NORMALIZER => function
     INSTALL => new_name

     SCALAR_CACHE => 'MEMORY'
     SCALAR_CACHE => ['TIE', Module, arguments...]
             SCALAR_CACHE => ['HASH', \%cache_hash ]
     SCALAR_CACHE => 'FAULT'
     SCALAR_CACHE => 'MERGE'

     LIST_CACHE => 'MEMORY'
     LIST_CACHE => ['TIE', Module, arguments...]
             LIST_CACHE => ['HASH', \%cache_hash ]
     LIST_CACHE => 'FAULT'
     LIST_CACHE => 'MERGE'

DESCRIPTION
===========

   `Memoizing' a function makes it faster by trading space for time.  It
does this by caching the return values of the function in a table.  If you
call the function again with the same arguments, `memoize' jmups in and
gives you the value out of the table, instead of letting the function
compute the value all over again.

   Here is an extreme example.  Consider the Fibonacci sequence, defined
by the following function:

     # Compute Fibonacci numbers
     sub fib {
       my $n = shift;
       return $n if $n < 2;
       fib($n-1) + fib($n-2);
     }

   This function is very slow.  Why?  To compute fib(14), it first wants
to compute fib(13) and fib(12), and add the results.  But to compute
fib(13), it first has to compute fib(12) and fib(11), and then it comes
back and computes fib(12) all over again even though the answer is the
same.  And both of the times that it wants to compute fib(12), it has to
compute fib(11) from scratch, and then it has to do it again each time it
wants to compute fib(13).  This function does so much recomputing of old
results that it takes a really long time to run--fib(14) makes 1,200 extra
recursive calls to itself, to compute and recompute things that it already
computed.

   This function is a good candidate for memoization.  If you memoize the
`fib' function above, it will compute fib(14) exactly once, the first time
it needs to, and then save the result in a table.  Then if you ask for
fib(14) again, it gives you the result out of the table.  While computing
fib(14), instead of computing fib(12) twice, it does it once; the second
time it needs the value it gets it from the table.  It doesn't compute
fib(11) four times; it computes it once, getting it from the table the
next three times.  Instead of making 1,200 recursive calls to `fib', it
makes 15.  This makes the function about 150 times faster.

   You could do the memoization yourself, by rewriting the function, like
this:

     # Compute Fibonacci numbers, memoized version
     { my @fib;
       	  sub fib {
         my $n = shift;
         return $fib[$n] if defined $fib[$n];
         return $fib[$n] = $n if $n < 2;
         $fib[$n] = fib($n-1) + fib($n-2);
       }
             }

   Or you could use this module, like this:

     use Memoize;
     memoize('fib');

     # Rest of the fib function just like the original version.

   This makes it easy to turn memoizing on and off.

   Here's an even simpler example: I wrote a simple ray tracer; the
program would look in a certain direction, figure out what it was looking
at, and then convert the `color' value (typically a string like `red') of
that object to a red, green, and blue pixel value, like this:

     for ($direction = 0; $direction < 300; $direction++) {
       # Figure out which object is in direction $direction
       $color = $object->{color};
       ($r, $g, $b) = @{&ColorToRGB($color)};
       ...
     }

   Since there are relatively few objects in a picture, there are only a
few colors, which get looked up over and over again.  Memoizing
`ColorToRGB' speeded up the program by several percent.

DETAILS
=======

   This module exports exactly one function, `memoize'.  The rest of the
functions in this package are None of Your Business.

   You should say

     memoize(function)

   where function is the name of the function you want to memoize, or a
reference to it.  `memoize' returns a reference to the new, memoized
version of the function, or undef on a non-fatal error.  At present, there
are no non-fatal errors, but there might be some in the future.

   If function was the name of a function, then `memoize' hides the old
version and installs the new memoized version under the old name, so that
`&function(...)' actually invokes the memoized version.

OPTIONS
=======

   There are some optional options you can pass to `memoize' to change the
way it behaves a little.  To supply options, invoke `memoize' like this:

     memoize(function, NORMALIZER => function,
     		  INSTALL => newname,
                               SCALAR_CACHE => option,
                       LIST_CACHE => option
     		 );

   Each of these options is optional; you can include some, all, or none
of them.

INSTALL
-------

   If you supply a function name with INSTALL, memoize will install the
new, memoized version of the function under the name you give.  For
example,

     memoize('fib', INSTALL => 'fastfib')

   installs the memoized version of `fib' as `fastfib'; without the
INSTALL option it would have replaced the old `fib' with the memoized
version.

   To prevent `memoize' from installing the memoized version anywhere, use
`INSTALL => undef'.

NORMALIZER
----------

   Suppose your function looks like this:

     # Typical call: f('aha!', A => 11, B => 12);
     sub f {
       my $a = shift;
       my %hash = @_;
       $hash{B} ||= 2;  # B defaults to 2
       $hash{C} ||= 7;  # C defaults to 7

     # Do something with $a, %hash
     	}

   Now, the following calls to your function are all completely equivalent:

     f(OUCH);
     f(OUCH, B => 2);
     f(OUCH, C => 7);
     f(OUCH, B => 2, C => 7);
     f(OUCH, C => 7, B => 2);
     (etc.)

   However, unless you tell `Memoize' that these calls are equivalent, it
will not know that, and it will compute the values for these invocations
of your function separately, and store them separately.

   To prevent this, supply a NORMALIZER function that turns the program
arguments into a string in a way that equivalent arguments turn into the
same string.  A NORMALIZER function for f above might look like this:

     sub normalize_f {
       my $a = shift;
       my %hash = @_;
       $hash{B} ||= 2;
       $hash{C} ||= 7;

     join($;, $a, map ($_ => $hash{$_}) sort keys %hash);
     	}

   Each of the argument lists above comes out of the `normalize_f'
function looking exactly the same, like this:

     OUCH^\B^\2^\C^\7

   You would tell `Memoize' to use this normalizer this way:

     memoize('f', NORMALIZER => 'normalize_f');

   `memoize' knows that if the normalized version of the arguments is the
same for two argument lists, then it can safely look up the value that it
computed for one argument list and return it as the result of calling the
function with the other argument list, even if the argument lists look
different.

   The default normalizer just concatenates the arguments with $; in
between.  This always works correctly for functions with only one
argument, and also when the arguments never contain $; (which is normally
character #28, control-\.  )  However, it can confuse certain argument
lists:

     normalizer("a\034", "b")
     normalizer("a", "\034b")
     normalizer("a\034\034b")

   for example.

   The default normalizer also won't work when the function's arguments
are references.  For exampple, consider a function g which gets two
arguments: A number, and a reference to an array of numbers:

     g(13, [1,2,3,4,5,6,7]);

   The default normalizer will turn this into something like
`"13\024ARRAY(0x436c1f)"'.  That would be all right, except that a
subsequent array of numbers might be stored at a different location even
though it contains the same data.  If this happens, `Memoize' will think
that the arguments are different, even though they are equivalent.  In
this case, a normalizer like this is appropriate:

     sub normalize { join ' ', $_[0], @{$_[1]} }

   For the example above, this produces the key "13 1 2 3 4 5 6 7".

   Another use for normalizers is when the function depends on data other
than those in its arguments.  Suppose you have a function which returns a
value which depends on the current hour of the day:

     sub on_duty {
               my ($problem_type) = @_;
       my $hour = (localtime)[2];
               open my $fh, "$DIR/$problem_type" or die...;
               my $line;
               while ($hour-- > 0)
                 $line = <$fh>;
               }
       return $line;
     }

   At 10:23, this function generates the tenth line of a data file; at
3:45 PM it generates the 15th line instead.  By default, `Memoize' will
only see the $problem_type argument.  To fix this, include the current
hour in the normalizer:

     sub normalize { join ' ', (localtime)[2], @_ }

   The calling context of the function (scalar or list context) is
propagated to the normalizer.  This means that if the memoized function
will treat its arguments differently in list context than it would in
scalar context, you can have the normalizer function select its behavior
based on the results of wantarray.  Even if called in a list context, a
normalizer should still return a single string.

`SCALAR_CACHE', `LIST_CACHE'
----------------------------

   Normally, `Memoize' caches your function's return values into an
ordinary Perl hash variable.  However, you might like to have the values
cached on the disk, so that they persist from one run of your program to
the next, or you might like to associate some other interesting semantics
with the cached values.

   There's a slight complication under the hood of `Memoize': There are
actually *two* caches, one for scalar values and one for list values.
When your function is called in scalar context, its return value is cached
in one hash, and when your function is called in list context, its value
is cached in the other hash.  You can control the caching behavior of both
contexts independently with these options.

   The argument to `LIST_CACHE' or `SCALAR_CACHE' must either be one of
the following five strings:

     MEMORY
     TIE
     FAULT
     MERGE
             HASH

   or else it must be a reference to a list whose first element is one of
these four strings, such as `[TIE, arguments...]'.

MEMORY
     MEMORY means that return values from the function will be cached in
     an ordinary Perl hash variable.  The hash variable will not persist
     after the program exits.  This is the default.

TIE
     TIE means that the function's return values will be cached in a tied
     hash.  A tied hash can have any semantics at all.  It is typically
     tied to an on-disk database, so that cached values are stored in the
     database and retrieved from it again when needed, and the disk file
     typically persists after your pogram has exited.

     If TIE is specified as the first element of a list, the remaining
     list elements are taken as arguments to the tie call that sets up the
     tied hash.  For example,

          SCALAR_CACHE => [TIE, DB_File, $filename, O_RDWR | O_CREAT, 0666]

     says to tie the hash into the DB_File package, and to pass the
     $filename, `O_RDWR | O_CREAT', and `0666' arguments to the tie call.
     This has the effect of storing the cache in a DB_File database whose
     name is in $filename.

     Other typical uses of TIE:

          LIST_CACHE => [TIE, GDBM_File, $filename, O_RDWR | O_CREAT, 0666]
          SCALAR_CACHE => [TIE, MLDBM, DB_File, $filename, O_RDWR|O_CREAT, 0666]
          LIST_CACHE => [TIE, My_Package, $tablename, $key_field, $val_field]

     This last might tie the cache hash to a package that you wrote
     yourself that stores the cache in a SQL-accessible database.  A
     useful use of this feature: You can construct a batch program that
     runs in the background and populates the memo table, and then when you
     come to run your real program the memoized function will be
     screamingly fast because all its results have been precomputed.

HASH
     HASH allows you to specify that a particular hash that you supply
     will be used as the cache.  You can tie this hash beforehand to give
     it any behavior you want.

`FAULT'
     `FAULT' means that you never expect to call the function in scalar
     (or list) context, and that if `Memoize' detects such a call, it
     should abort the program.  The error message is one of

          `foo' function called in forbidden list context at line ...
          `foo' function called in forbidden scalar context at line ...

`MERGE'
     `MERGE' normally means the function does not distinguish between list
     and sclar context, and that return values in both contexts should be
     stored together.  `LIST_CACHE => MERGE' means that list context
     return values should be stored in the same hash that is used for
     scalar context returns, and `SCALAR_CACHE => MERGE' means the same,
     mutatis mutandis.  It is an error to specify `MERGE' for both, but it
     probably does something useful.

     Consider this function:

          sub pi { 3; }

     Normally, the following code will result in two calls to pi:

          $x = pi();
          ($y) = pi();
          $z = pi();

     The first call caches the value 3 in the scalar cache; the second
     caches the list (3) in the list cache.  The third call doesn't call
     the real pi function; it gets the value from the scalar cache.

     Obviously, the second call to pi is a waste of time, and storing its
     return value is a waste of space.  Specifying `LIST_CACHE => MERGE'
     will make `memoize' use the same cache for scalar and list context
     return values, so that the second call uses the scalar cache that was
     populated by the first call.  pi ends up being cvalled only once, and
     both subsequent calls return 3 from the cache, regardless of the
     calling context.

     Another use for `MERGE' is when you want both kinds of return values
     stored in the same disk file; this saves you from having to deal with
     two disk files instead of one.  You can use a normalizer function to
     keep the two sets of return values separate.  For example:

          memoize 'myfunc',
            NORMALIZER => 'n',
            SCALAR_CACHE => [TIE, MLDBM, DB_File, $filename, ...],
            LIST_CACHE => MERGE,
          ;

          sub n {
            my $context = wantarray() ? 'L' : 'S';
            # ... now compute the hash key from the arguments ...
            $hashkey = "$context:$hashkey";
          }

     This normalizer function will store scalar context return values in
     the disk file under keys that begin with `S:', and list context
     return values under keys that begin with `L:'.

OTHER FACILITIES
================

`unmemoize'
-----------

   There's an `unmemoize' function that you can import if you want to.
Why would you want to?  Here's an example: Suppose you have your cache
tied to a DBM file, and you want to make sure that the cache is written
out to disk if someone interrupts the program.  If the program exits
normally, this will happen anyway, but if someone types control-C or
something then the program will terminate immediately without
synchronizing the database.  So what you can do instead is

     $SIG{INT} = sub { unmemoize 'function' };

   Thanks to Jonathan Roy for discovering a use for `unmemoize'.

   `unmemoize' accepts a reference to, or the name of a previously
memoized function, and undoes whatever it did to provide the memoized
version in the first place, including making the name refer to the
unmemoized version if appropriate.  It returns a reference to the
unmemoized version of the function.

   If you ask it to unmemoize a function that was never memoized, it
croaks.

flush_cache
-----------

   `flush_cache(function)' will flush out the caches, discarding all the
cached data.  The argument may be a funciton name or a reference to a
function.  For finer control over when data is discarded or expired, see
the documentation for `Memoize::Expire', included in this package.

   Note that if the cache is a tied hash, flush_cache will attempt to
invoke the CLEAR method on the hash.  If there is no CLEAR method, this
will cause a run-time error.

   An alternative approach to cache flushing is to use the HASH option
(see above) to request that `Memoize' use a particular hash variable as
its cache.  Then you can examine or modify the hash at any time in any way
you desire.

CAVEATS
=======

   Memoization is not a cure-all:

   * Do not memoize a function whose behavior depends on program state
     other than its own arguments, such as global variables, the time of
     day, or file input.  These functions will not produce correct results
     when memoized.  For a particularly easy example:

          sub f {
            time;
          }

     This function takes no arguments, and as far as `Memoize' is
     concerned, it always returns the same result.  `Memoize' is wrong, of
     course, and the memoized version of this function will call time once
     to get the current time, and it will return that same time every time
     you call it after that.

   * Do not memoize a function with side effects.

          sub f {
            my ($a, $b) = @_;
                    my $s = $a + $b;
            print "$a + $b = $s.\n";
          }

     This function accepts two arguments, adds them, and prints their sum.
     Its return value is the numuber of characters it printed, but you
     probably didn't care about that.  But `Memoize' doesn't understand
     that.  If you memoize this function, you will get the result you
     expect the first time you ask it to print the sum of 2 and 3, but
     subsequent calls will return 1 (the return value of print) without
     actually printing anything.

   * Do not memoize a function that returns a data structure that is
     modified by its caller.

     Consider these functions:  `getusers' returns a list of users somehow,
     and then main throws away the first user on the list and prints the
     rest:

          sub main {
            my $userlist = getusers();
            shift @$userlist;
            foreach $u (@$userlist) {
              print "User $u\n";
            }
          }

          sub getusers {
            my @users;
            # Do something to get a list of users;
            \@users;  # Return reference to list.
          }

     If you memoize `getusers' here, it will work right exactly once.  The
     reference to the users list will be stored in the memo table.  main
     will discard the first element from the referenced list.  The next
     time you invoke main, `Memoize' will not call `getusers'; it will
     just return the same reference to the same list it got last time.  But
     this time the list has already had its head removed; main will
     erroneously remove another element from it.  The list will get shorter
     and shorter every time you call main.

     Similarly, this:

          $u1 = getusers();
          $u2 = getusers();
          pop @$u1;

     will modify $u2 as well as $u1, because both variables are references
     to the same array.  Had `getusers' not been memoized, $u1 and $u2
     would have referred to different arrays.

PERSISTENT CACHE SUPPORT
========================

   You can tie the cache tables to any sort of tied hash that you want to,
as long as it supports TIEHASH, FETCH, STORE, and EXISTS.  For example,

     memoize 'function', SCALAR_CACHE =>
                                 [TIE, GDBM_File, $filename, O_RDWR|O_CREAT, 0666];

   works just fine.  For some storage methods, you need a little glue.

   SDBM_File doesn't supply an EXISTS method, so included in this package
is a glue module called `Memoize::SDBM_File' which does provide one.  Use
this instead of plain SDBM_File to store your cache table on disk in an
SDBM_File database:

     memoize 'function',
                     SCALAR_CACHE =>
                     [TIE, Memoize::SDBM_File, $filename, O_RDWR|O_CREAT, 0666];

   `NDBM_File' has the same problem and the same solution.

   Storable isn't a tied hash class at all.  You can use it to store a
hash to disk and retrieve it again, but you can't modify the hash while
it's on the disk.  So if you want to store your cache table in a Storable
database, use `Memoize::Storable', which puts a hashlike front-end onto
Storable.  The hash table is actually kept in memory, and is loaded from
your Storable file at the time you memoize the function, and stored back
at the time you unmemoize the function (or when your program exits):

     memoize 'function',
                     SCALAR_CACHE => [TIE, Memoize::Storable, $filename];

     memoize 'function',
                     SCALAR_CACHE => [TIE, Memoize::Storable, $filename, 'nstore'];

   Include the `nstore' option to have the Storable database written in
`network order'.  (See *Note Storable: Storable, for more details about
this.)

EXPIRATION SUPPORT
==================

   See Memoize::Expire, which is a plug-in module that adds expiration
functionality to Memoize.  If you don't like the kinds of policies that
Memoize::Expire implements, it is easy to write your own plug-in module to
implement whatever policy you desire.

BUGS
====

   The test suite is much better, but always needs improvement.

   There used to be some problem with the way `goto &f' works under
threaded Perl, because of the lexical scoping of `@_'.  This is a bug in
Perl, and until it is resolved, Memoize won't work with these Perls.  This
is probably still the case, although I have not been able to try it out.
If you encounter this problem, you can fix it by chopping the source code
a little.  Find the comment in the source code that says `--- THREADED
PERL COMMENT---' and comment out the active line and uncomment the
commented one.  Then try it again.

   Here's a bug that isn't my fault: Some versions of DB_File won't let
you store data under a key of length 0.  That means that if you have a
function f which you memoized and the cache is in a DB_File database, then
the value of `f()' (f called with no arguments) will not be memoized.  Let
us all breathe deeply and repeat this mantra: "Gosh, Keith, that sure was
a stupid thing to do."

MAILING LIST
============

   To join a very low-traffic mailing list for announcements about
`Memoize', send an empty note to `mjd-perl-memoize-request@plover.com'.

AUTHOR
======

   Mark-Jason Dominus (`mjd-perl-memoize+@plover.com'), Plover Systems co.

   See the `Memoize.pm' Page at http://www.plover.com/~mjd/perl/Memoize/
for news and upgrades.  Near this page, at
http://www.plover.com/~mjd/perl/MiniMemoize/ there is an article about
memoization and about the internals of Memoize that appeared in The Perl
Journal, issue #13.  (This article is also included in the Memoize
distribution as `article.html'.)

   To join a mailing list for announcements about `Memoize', send an empty
message to `mjd-perl-memoize-request@plover.com'.  This mailing list is
for announcements only and has extremely low traffic--about four messages
per year.

THANK YOU
=========

   Many thanks to Jonathan Roy for bug reports and suggestions, to Michael
Schwern for other bug reports and patches, to Mike Cariaso for helping me
to figure out the Right Thing to Do About Expiration, to Joshua Gerth,
Joshua Chamas, Jonathan Roy, Mark D. Anderson, and Andrew Johnson for more
suggestions about expiration, to Ariel Scolnikov for delightful messages
about the Fibonacci function, to Dion Almaer for thought-provoking
suggestions about the default normalizer, to Walt Mankowski and Kurt
Starsinic for much help investigating problems under threaded Perl, to
Alex Dudkevich for reporting the bug in prototyped functions and for
checking my patch, to Tony Bass for many helpful suggestions, to Philippe
Verdret for enlightening discussion of Hook::PrePostCall, to Nat
Torkington for advice I ignored, to Chris Nandor for portability advice,
to Randal Schwartz for suggesting the 'flush_cache function, and to Jenda
Krynicky for being a light in the world.


