This is gsl-ref.info, produced by Makeinfo version 3.12h from
gsl-ref.texi.

INFO-DIR-SECTION Scientific software
START-INFO-DIR-ENTRY
* gsl-ref: (gsl-ref).                   GNU Scientific Library - Reference
END-INFO-DIR-ENTRY

   This file documents the GNU Scientific Library.

   Copyright (C) 1996, 1997, 1998, 1999 The GSL Project.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be stated in a
translation approved by the Foundation.


File: gsl-ref.info,  Node: The histogram probability distribution struct,  Next: Example programs for histograms,  Prev: Resampling from histograms,  Up: Histograms

The histogram probability distribution struct
=============================================

   The probability distribution function for a histogram consists of a
set of "bins" which measure the probability of an event falling into a
given range of a continuous variable x. A probability distribution
function is defined by the following struct, which actually stores the
cumulative probability distribution function.  This is the natural
quantity for generating samples via the inverse transform method,
because there is a one-to-one mapping between the cumulative
probability distribution and the range [0,1].  It can be shown that by
taking a uniform random number in this range and finding its
corresponding coordinate in the cumulative probability distribution we
obtain samples with the desired probability distribution.

 - Data Type: gsl_histogram_pdf
    `size_t n'
          This is the number of bins used to approximate the probability
          distribution function.

    `double * range'
          The ranges of the bins are stored in an array of N+1 elements
          pointed to by RANGE.

    `double * sum'
          The cumulative probability for the bins is stored in an array
          of N elements pointed to by SUM.

The following functions allow you to create a `gsl_histogram_pdf'
struct which represents this probability distribution and generate
random samples from it.

 - Function: gsl_histogram_pdf * gsl_histogram_pdf_alloc (const
          gsl_histogram * H)
     This function allocates memory for a probability distribution
     calculated from the histogram H and returns a pointer to a newly
     initialized `gsl_histogram_pdf' struct.  If any of the bins of H
     are negative then a null pointer is returned and the error handler
     is invoked with an error code of `GSL_EDOM' because a probability
     distribution cannot contain negative values.

     If insufficient memory is available a null pointer is returned and
     the error handler is invoked with an error code of `GSL_ENOMEM'.

 - Function: void gsl_histogram_pdf_free (gsl_histogram_pdf * P)
     This function frees the probability distribution function P and
     all of the memory associated with it.

 - Function: double gsl_histogram_pdf_sample (const gsl_histogram_pdf *
          P, double R)
     This function uses R, a uniform random number between zero and
     one, to compute a single random sample from the probability
     distribution P.  The algorithm used to compute the sample s is
     given by the following formula,

          s = range[i] + delta * (range[i+1] - range[i])

     where i is the index which satisfies sum[i] <=  r < sum[i+1] and
     delta is (r - sum[i])/(sum[i+1] - sum[i]).


File: gsl-ref.info,  Node: Example programs for histograms,  Next: Two dimensional histograms,  Prev: The histogram probability distribution struct,  Up: Histograms

Example programs for histograms
===============================

   The following program shows how to make a simple histogram of a
column of numerical data supplied on `stdin'.  The program takes three
arguments, specifying the upper and lower bounds of the histogram and
the number of bins.  It then reads numbers from `stdin', one line at a
time, and adds them to the histogram.  When there is no more data to
read it prints out the accumulated histogram using
`gsl_histogram_fprintf'.

     #include <stdio.h>
     #include <stdlib.h>
     #include <gsl/gsl_histogram.h>
     
     int
     main (int argc, char **argv)
     {
       double a, b ;
       size_t n;
     
       if (argc != 4)
         {
           printf ("Usage: gsl-histogram xmin xmax n\n"
                   "Computes a histogram of the data on stdin"
                   "using n bins from xmin to xmax\n");
           exit (0);
         }
     
       a = atof (argv[1]);
       b = atof (argv[2]);
       n = atoi (argv[3]);
     
       {
         gsl_histogram * h = gsl_histogram_calloc_uniform (n, a, b) ;
         int status ;
         double x;
     
         while (fscanf(stdin, "%lg", &x) == 1)
           {
     	gsl_histogram_increment(h, x);
           }
     
         gsl_histogram_fprintf (stdout, h, "%g", "%g") ;
       }
     
       exit (0) ;
     }

Here is an example of the program in use.  We generate 10000 random
samples from a lorentz distribution with a width of 30 and histogram
them over the range -100 to 100, using 200 bins.

     gsl-lorentz 30 10000 | gsl-histogram -100 100 200 > histogram.dat

A plot of the resulting histogram shows the familiar shape of the
lorentz distribution and the fluctuations caused by the finite sample
size.

     gnuplot> plot 'histogram.dat' using 1:3 with step


File: gsl-ref.info,  Node: Two dimensional histograms,  Next: The 2D histogram struct,  Prev: Example programs for histograms,  Up: Histograms

Two dimensional histograms
==========================

   A two dimensional histogram consists of a set of "bins" which count
the number of events falling in a given area of the (x,y) plane.  The
simplest way to use a two dimensional histogram is to record
two-dimensional position information, n(x,y).  Another possibility is
to form a "joint distribution" by recording related variables.  For
example a detector might record both the position of an event (x) and
the amount of energy it deposited E.  These could be histogrammed as
the joint distribution n(x,E).


File: gsl-ref.info,  Node: The 2D histogram struct,  Next: 2D Histogram allocation,  Prev: Two dimensional histograms,  Up: Histograms

The 2D histogram struct
=======================

   Two dimensional histograms are defined by the following struct,

 - Data Type: gsl_histogram2d
    `size_t nx, ny'
          This is the number of histogram bins in the x and y
          directions.

    `double * xrange'
          The ranges of the bins in the x-direction are stored in an
          array of NX + 1 elements pointed to by XRANGE.

    `double * yrange'
          The ranges of the bins in the y-direction are stored in an
          array of NY + 1 pointed to by YRANGE.

    `double * bin'
          The counts for each bin are stored in an array pointed to by
          BIN.  The bins are floating-point numbers, so you can
          increment them by non-integer values if necessary.  The array
          BIN stores the two dimensional array of bins in a single
          block of memory according to the mapping `bin(i,j)' = `bin[i
          * ny + j]'.

The range for `bin(i,j)' is given by `xrange[i]' to `xrange[i+1]' in
the x-direction and `yrange[j]' to `yrange[j+1]' in the y-direction.
Each bin is inclusive at the lower end and exclusive at the upper end.
Mathematically this means that the bins are defined by the following
inequality,

     bin(i,j) corresponds to xrange[i] <= x < xrange[i+1]
                         and yrange[j] <= y < yrange[j+1]

   Note that any samples which fall on the upper sides of the histogram
are excluded.  If you want to include these values for the side bins
you will need to add an extra row or column to your histogram.

   The `gsl_histogram2d' struct and its associated functions are
defined in the header file `gsl_histogram2d.h'.


File: gsl-ref.info,  Node: 2D Histogram allocation,  Next: Copying 2D Histograms,  Prev: The 2D histogram struct,  Up: Histograms

2D Histogram allocation
=======================

   The functions for allocating memory to a 2D histogram follow the
style of `malloc' and `free'.  In addition they also perform their own
error checking.  If there is insufficient memory available to allocate
a histogram then the functions call the GSL error handler (with an
error number of `GSL_ENOMEM') in addition to returning a null pointer.
Thus if you use the library error handler to abort your program then it
isn't necessary to check every 2D histogram `alloc'.

 - Function: gsl_histogram2d * gsl_histogram2d_calloc (size_t NX,
          size_t NY)
     This function allocates memory for a two-dimensional histogram with
     NX bins in the x direction and NY bins in the y direction.  The
     function returns a pointer to a newly initialized
     `gsl_histogram2d' struct.  The bins are uniformly spaced with a
     total range of 0 <= x < nx in the x-direction and 0 <=  y < ny in
     the y-direction, as shown in the table below.

     The bins are initialized to zero so the histogram is ready for use.

     If insufficient memory is available a null pointer is returned and
     the error handler is invoked with an error code of `GSL_ENOMEM'.

 - Function: gsl_histogram2d * gsl_histogram2d_calloc_uniform (size_t
          NX, size_t NY, double XMIN, double XMAX, double YMIN, double
          YMAX)

 - Function: gsl_histogram2d * gsl_histogram2d_calloc_range (size_t NX,
          size_t NY, double * XRANGE, double * YRANGE)
     This function allocates a histogram of size NX-by-NY using the
     nx+1 and ny+1 bin ranges specified by the arrays XRANGE and
     XYRANGE.

 - Function: void gsl_histogram2d_free (gsl_histogram2d * H)
     This function frees the 2D histogram H and all of the memory
     associated with it.


File: gsl-ref.info,  Node: Copying 2D Histograms,  Next: Updating and accessing 2D histogram elements,  Prev: 2D Histogram allocation,  Up: Histograms

Copying 2D Histograms
=====================

 - Function: int gsl_histogram2d_memcpy (gsl_histogram2d * DEST, const
          gsl_histogram2d * SRC)
     This function copies the histogram SRC into the pre-existing
     histogram DEST, making DEST into an exact copy of SRC.  The two
     histograms must be of the same size.

 - Function: gsl_histogram2d * gsl_histogram2d_clone (const
          gsl_histogram2d * SRC)
     This function returns a pointer to a newly created histogram which
     is an exact copy of the histogram SRC.


File: gsl-ref.info,  Node: Updating and accessing 2D histogram elements,  Next: Searching 2D histogram ranges,  Prev: Copying 2D Histograms,  Up: Histograms

Updating and accessing 2D histogram elements
============================================

   You can access the bins of a two-dimensional histogram either by
specifying a pair of (x,y) coordinates or by using the bin indices
(i,j) directly.  The functions for accessing the histogram through
(x,y) coordinates use binary searches in the x and y directions to
identify the bin which covers the appropriate range.

 - Function: int gsl_histogram2d_increment (gsl_histogram2d * H, double
          X, double Y)
     This function updates the histogram H by adding one (1.0) to the
     bin whose x and y ranges contain the coordinates (X,Y).

     If the point (x,y) lies inside the valid ranges of the histogram
     then the function returns zero to indicate success.  If (x,y) lies
     outside the limits of the histogram then the function returns
     `GSL_EDOM', and none of bins are modified.  The error handler is
     not called, since it is often necessary to compute histogram for a
     small range of a larger dataset, ignoring any coordinates outside
     the range of interest.

 - Function: int gsl_histogram2d_accumulate (gsl_histogram2d * H,
          double X, double Y, double WEIGHT)
     This function is similar to `gsl_histogram2d_increment' but
     increases the value of the appropriate bin in the histogram H by
     the floating-point number WEIGHT.

 - Function: double gsl_histogram2d_get (const gsl_histogram2d * H,
          size_t I, size_t J)
     This function returns the contents of the (I,J)th bin of the
     histogram H.  If (I,J) lies outside the valid range of indices for
     the histogram then the error handler is called with an error code
     of `GSL_EDOM' and the function returns 0.

 - Function: int gsl_histogram2d_get_xrange (const gsl_histogram2d * H,
          size_t I, double * XLOWER, double * XUPPER)
 - Function: int gsl_histogram2d_get_yrange (const gsl_histogram2d * H,
          size_t J, double * YLOWER, double * YUPPER)
     These functions find the upper and lower range limits of the Ith
     and Jth bins in the x and y directions of the histogram H.  The
     range limits are stored in XLOWER and XUPPER or YLOWER and YUPPER.
     The lower limits are inclusive (i.e. events with these
     coordinates are included in the bin) and the upper limits are
     exclusive (i.e. events with the value of the upper limit are not
     included and fall in the neighboring higher bin, if it exists).
     The functions return 0 to indicate success.  If I or J lies
     outside the valid range of indices for the histogram then the
     error handler is called with an error code of `GSL_EDOM'.

 - Function: double gsl_histogram2d_xmax (const gsl_histogram2d * H)
 - Function: double gsl_histogram2d_xmin (const gsl_histogram2d * H)
 - Function: size_t gsl_histogram2d_nx (const gsl_histogram2d * H)
 - Function: double gsl_histogram2d_ymax (const gsl_histogram2d * H)
 - Function: double gsl_histogram2d_ymin (const gsl_histogram2d * H)
 - Function: size_t gsl_histogram2d_ny (const gsl_histogram2d * H)
     These functions return the maximum upper and minimum lower range
     limits and the number of bins for the x and y directions of the
     histogram H.  They provide a way of determining these values
     without accessing the `gsl_histogram2d' struct directly.

 - Function: void gsl_histogram2d_reset (gsl_histogram2d * H)
     This function resets all the bins of the histogram H to zero.


File: gsl-ref.info,  Node: Searching 2D histogram ranges,  Next: 2D Histogram Statistics,  Prev: Updating and accessing 2D histogram elements,  Up: Histograms

Searching 2D histogram ranges
=============================

   The following functions are used by the access and update routines to
locate the bin which corresponds to a given (x\,y) coordinate.

 - Function: int gsl_histogram2d_find_impl (const gsl_histogram2d * H,
          double X, double Y, size_t * I, size_t * J)
     This function finds and sets the indices I and J to the offsets in
     the arrays XRANGE and YRANGE which bound the value of (x,y), such
     that xrange[i] <= x < xrange[i+1] and yrange[j] <= y <
     yrange[j+1].  The binary search function `bsearch' from the system
     C-library is used to locate the appropriate ranges.  If suitable
     values of I and J are found then the function returns 0 to
     indicate success.  If X is less than the lower limit the function
     returns -1, and if X is greater than or equal to the upper limit
     it returns +1.  If X is valid then the same checks are applied to
     Y, with return values of -1 or +1 indicating and error.  The error
     handler is not called.

 - Function: int gsl_histogram2d_find (const gsl_histogram2d * H,
          double X, double Y, size_t * I, size_t * J)
     This function uses `gsl_histogram2d_find_impl' to set the indices
     I and J to the bin which covers the coordinates (x,y) in the
     histogram H.  If (x,y) is found then the function sets the indices
     (I,J) and returns zero to indicate success.  If (x,y) lies outside
     the valid range of the histogram then the function returns
     `GSL_EDOM' and the error handler is invoked.


File: gsl-ref.info,  Node: 2D Histogram Statistics,  Next: 2D Histogram Operations,  Prev: Searching 2D histogram ranges,  Up: Histograms

2D Histogram Statistics
=======================

 - Function: double gsl_histogram2d_max_val (const gsl_histogram2d * H)
     This function returns the maximum value contained in the histogram
     bins.

 - Function: void gsl_histogram2d_max_bin (const gsl_histogram2d * H,
          size_t * I, size_t * J)
     This function returns the indices (I,J) of the bin containing the
     maximum value in the histogram H. In the case where several bins
     contain the same maximum value the first bin found is returned.

 - Function: double gsl_histogram2d_min_val (const gsl_histogram2d * H)
     This function returns the minimum value contained in the histogram
     bins.

 - Function: void gsl_histogram2d_min_bin (const gsl_histogram2d * H,
          size_t * I, size_t * J)
     This function returns the indices (I,J) of the bin containing the
     minimum value in the histogram H. In the case where several bins
     contain the same maximum value the first bin found is returned.


File: gsl-ref.info,  Node: 2D Histogram Operations,  Next: Reading and writing 2D histograms,  Prev: 2D Histogram Statistics,  Up: Histograms

2D Histogram Operations
=======================

 - Function: int gsl_histogram2d_equal_bins_p (const gsl_histogram2d
          *H1, const gsl_histogram2d *H2)
     This function returns 1 if the all of the individual bin ranges of
     the two histograms are identical, and 0 otherwise.

 - Function: int gsl_histogram2d_add (gsl_histogram2d *H1, const
          gsl_histogram2d *H2)
     This function adds the contents of the bins in histogram H2 to the
     corresponding bins of histogram H1.  i.e. h'_1(i,j) = h_1(i,j) +
     h_2(i,j).

 - Function: int gsl_histogram2d_sub (gsl_histogram2d *H1, const
          gsl_histogram2d *H2)
     This function subtracts the contents of the bins in histogram H2
     from the corresponding bins of histogram H1.  i.e. h'_1(i,j) =
     h_1(i,j) - h_2(i,j).

 - Function: int gsl_histogram2d_mul (gsl_histogram2d *H1, const
          gsl_histogram2d *H2)
     This function multiplies the contents of the bins of histogram H1
     by the contents of the corresponding bins in histogram H2.  i.e.
     h'_1(i,j) = h_1(i,j) * h_2(i,j).

 - Function: int gsl_histogram2d_div (gsl_histogram2d *H1, const
          gsl_histogram2d *H2)
     This function divides the contents of the bins of histogram H1 by
     the contents of the corresponding bins in histogram H2.  i.e.
     h'_1(i,j) = h_1(i,j) / h_2(i,j).

 - Function: int gsl_histogram2d_scale (gsl_histogram2d *H, double
          SCALE)
     This function multiplies the contents of the bins of histogram H
     by the constant SCALE.  i.e. h'_1(i,j) = h_1(i,j) scale.

 - Function: int gsl_histogram2d_shift (gsl_histogram2d *H, double
          OFFSET)
     This function shifts the contents of the bins of histogram H by
     the constant OFFSET.  i.e. h'_1(i,j) = h_1(i,j) + offset.


File: gsl-ref.info,  Node: Reading and writing 2D histograms,  Next: Resampling from 2D histograms,  Prev: 2D Histogram Operations,  Up: Histograms

Reading and writing 2D histograms
=================================

   The library provides functions for reading and writing two
dimensional histograms to a file as binary data or formatted text.

 - Function: int gsl_histogram2d_fwrite (FILE * STREAM, const
          gsl_histogram2d * H)
     This function writes the ranges and bins of the histogram H to the
     stream STREAM in binary format.  The return value is 0 for success
     and `GSL_EFAILED' if there was a problem writing to the file.
     Since the data is written in the native binary format it may not
     be portable between different architectures.

 - Function: int gsl_histogram2d_fread (FILE * STREAM, gsl_histogram2d
          * H)
     This function reads into the histogram H from the stream STREAM in
     binary format.  The histogram H must be preallocated with the
     correct size since the function uses the number of x and y bins in
     H to determine how many bytes to read.  The return value is 0 for
     success and `GSL_EFAILED' if there was a problem reading from the
     file.  The data is assumed to have been written in the native
     binary format on the same architecture.

 - Function: int gsl_histogram2d_fprintf (FILE * STREAM, const
          gsl_histogram2d * H, const char * RANGE_FORMAT, const char *
          BIN_FORMAT)
     This function writes the ranges and bins of the histogram H
     line-by-line to the stream STREAM using the format specifiers
     RANGE_FORMAT and BIN_FORMAT.  These should be one of the `%g',
     `%e' or `%f' formats for floating point numbers.  The function
     returns 0 for success and `GSL_EFAILED' if there was a problem
     writing to the file.  The histogram output is formatted in five
     columns, and the columns are separated by spaces, like this,

          xrange[0] xrange[1] yrange[0] yrange[1] bin(0,0)
          xrange[0] xrange[1] yrange[1] yrange[2] bin(0,1)
          xrange[0] xrange[1] yrange[2] yrange[3] bin(0,2)
          ....
          xrange[0] xrange[1] yrange[ny-1] yrange[ny] bin(0,ny-1)
          
          xrange[1] xrange[2] yrange[0] yrange[1] bin(1,0)
          xrange[1] xrange[2] yrange[1] yrange[2] bin(1,1)
          xrange[1] xrange[2] yrange[1] yrange[2] bin(1,2)
          ....
          xrange[1] xrange[2] yrange[ny-1] yrange[ny] bin(1,ny-1)
          
          ....
          
          xrange[nx-1] xrange[nx] yrange[0] yrange[1] bin(nx-1,0)
          xrange[nx-1] xrange[nx] yrange[1] yrange[2] bin(nx-1,1)
          xrange[nx-1] xrange[nx] yrange[1] yrange[2] bin(nx-1,2)
          ....
          xrange[nx-1] xrange[nx] yrange[ny-1] yrange[ny] bin(nx-1,ny-1)

     Each line contains the lower and upper limits of the bin and the
     contents of the bin.  Since the upper limits of the each bin are
     the lower limits of the neighbouring bins there is duplication of
     these values but this allows the histogram to be manipulated with
     line-oriented tools.

 - Function: int gsl_histogram2d_fscanf (FILE * STREAM, gsl_histogram2d
          * H)
     This function reads formatted data from the stream STREAM into the
     histogram H.  The data is assumed to be in the five-column format
     used by `gsl_histogram_fprintf'.  The histogram H must be
     preallocated with the correct lengths since the function uses the
     sizes of H to determine how many numbers to read.  The function
     returns 0 for success and `GSL_EFAILED' if there was a problem
     reading from the file.


File: gsl-ref.info,  Node: Resampling from 2D histograms,  Next: Example programs for 2D histograms,  Prev: Reading and writing 2D histograms,  Up: Histograms

Resampling from 2D histograms
=============================

   As in the one-dimensional case, a two-dimensional histogram made by
counting events can be regarded as a measurement of a probability
distribution.  Allowing for statistical error, the height of each bin
represents the probability of an event where (x,y) falls in the range
of that bin.  For a two-dimensional histogram the probability
distribution takes the form p(x,y) dx dy where,

     p(x,y) = n_{ij}/ (N A_{ij})

In this equation n_{ij} is the number of events in the bin which
contains (x,y), A_{ij} is the area of the bin and N is the total number
of events.  The distribution of events within each bin is assumed to be
uniform.

 - Data Type: gsl_histogram2d_pdf
    `size_t nx, ny'
          This is the number of histogram bins used to approximate the
          probability distribution function in the x and y directions.

    `double * xrange'
          The ranges of the bins in the x-direction are stored in an
          array of NX + 1 elements pointed to by XRANGE.

    `double * yrange'
          The ranges of the bins in the y-direction are stored in an
          array of NY + 1 pointed to by YRANGE.

    `double * sum'
          The cumulative probability for the bins is stored in an array
          of NX*NY elements pointed to by SUM.

The following functions allow you to create a `gsl_histogram2d_pdf'
struct which represents a two dimensional probability distribution and
generate random samples from it.

 - Function: gsl_histogram2d_pdf * gsl_histogram2d_pdf_alloc (const
          gsl_histogram2d * H)
     This function allocates memory for a two-dimensional probability
     distribution calculated from the histogram H and returns a pointer
     to a newly initialized `gsl_histogram2d_pdf' struct.  If any of the
     bins of H are negative then a null pointer is returned and the
     error handler is invoked with an error code of `GSL_EDOM' because a
     probability distribution cannot contain negative values.

     If insufficient memory is available a null pointer is returned and
     the error handler is invoked with an error code of `GSL_ENOMEM'.

 - Function: void gsl_histogram2d_pdf_free (gsl_histogram2d_pdf * P)
     This function frees the two-dimensional probability distribution
     function P and all of the memory associated with it.

 - Function: int gsl_histogram2d_pdf_sample (const gsl_histogram2d_pdf
          * P, double R1, double R2, double * X, double * Y)
     This function uses two uniform random numbers between zero and one,
     R1 and R2, to compute a single random sample from the
     two-dimensional probability distribution P.


File: gsl-ref.info,  Node: Example programs for 2D histograms,  Prev: Resampling from 2D histograms,  Up: Histograms

Example programs for 2D histograms
==================================

   This program demonstrates two features of two-dimensional histograms.
First a 10 by 10 2d-histogram is created with x and y running from 0 to
1.  Then a few sample points are added to the histogram, at (0.3,0.3)
with a height of 1, at (0.8,0.1) with a height of 5 and at (0.7,0.9)
with a height of 0.5.  This histogram with three events is used to
generate a random sample of 1000 simulated events, which are printed
out.

     #include <stdio.h>
     #include <gsl/gsl_histogram2d.h>
     
     int
     main ()
     {
       gsl_histogram2d * h = gsl_histogram2d_calloc_uniform (10, 10,
                                                             0, 1, 0, 1) ;
     
       gsl_histogram2d_accumulate (h, 0.3, 0.3, 1) ;
       gsl_histogram2d_accumulate (h, 0.8, 0.1, 5) ;
       gsl_histogram2d_accumulate (h, 0.7, 0.9, 0.5) ;
     
       {
         int i ;
         gsl_histogram2d_pdf * p = gsl_histogram2d_pdf_alloc (h) ;
     
         for (i = 0 ; i < 1000 ; i++) {
           double x, y ;
           double u = ((double) rand ()) / RAND_MAX;
           double v = ((double) rand ()) / RAND_MAX;
     
           int status = gsl_histogram2d_pdf_sample (p, u, v, &x, &y) ;
     
           printf("%g %g\n", x, y) ;
         }
       }
     
      return 0 ;
     }

   The following plot shows the distribution of the simulated events.
Using a higher resolution grid we can see the original underlying
histogram and also the statistical fluctuations caused by the events
being uniformly distributed over the the area of these original bins.


File: gsl-ref.info,  Node: One dimensional Root-Finding,  Next: Multidimensional Root-Finding,  Prev: Histograms,  Up: Top

One dimensional Root-Finding
****************************

   This chapter describes functions for finding roots of arbitrary
one-dimensional functions.  The library provides low level components
for a variety of iterative solvers and convergence tests.  These can be
combined by the user to achieve the desired solution, with full access
to the intermediate steps of the iteration.  Each class of methods uses
the same framework, so that you can switch between solvers at runtime
without needing to recompile your program.  Each instance of a solver
keeps track of its own state, allowing the solvers to be used in
multi-threaded programs.

   The header file `gsl_roots.h' contains prototypes for the root
finding functions and related declarations.

* Menu:

* Root Finding Overview::
* Root Finding Caveats::
* Initializing the Solver::
* Providing the function to solve::
* Search Bounds and Guesses::
* Root Finding Iteration::
* Search Stopping Parameters::
* Root Bracketing Algorithms::
* Root Finding Algorithms using Derivatives::
* Root Finding Examples::
* Root Finding References and Further Reading::


File: gsl-ref.info,  Node: Root Finding Overview,  Next: Root Finding Caveats,  Up: One dimensional Root-Finding

Overview
========

   One-dimensional root finding algorithms can be divided into two
classes, "root bracketing" and "root polishing".  Algorithms which
proceed by bracketing a root are guaranteed to converge.  Bracketing
algorithms begin with a bounded region known to contain a root.  The
size of this bounded region is reduced, iteratively, until it encloses
the root to a desired tolerance.  This provides a rigorous error
estimate for the location of the root.

   The technique of "root polishing" attempts to improve an initial
guess to the root.  These algorithms converge only if started "close
enough" to a root, and sacrifice a rigorous error bound for speed.  By
approximating the behavior of a function in the vicinity of a root they
attempt to find a higher order improvement of an initial guess.  When
the behavior of the function is compatible with the algorithm and a good
initial guess is available a polishing algorithm can provide rapid
convergence.

   In GSL both types of algorithm are available in a similar framework.
The user provides a high-level driver for the algorithms, and the
library provides the individual functions necessary for each of the
steps.  There are three main phases of the iteration.  The steps are,

   * initialize solver state, S, for algorithm T

   * update S using the iteration T

   * test S for convergence, and repeat iteration if necessary

The state for bracketing solvers is held in a `gsl_root_fsolver'
struct.  The updating procedure uses only function evaluations (not
derivatives).  The state for root polishing solvers is held in a
`gsl_root_fdfsolver' struct.  The updates require both the function and
its derivative (hence the name `fdf') to be supplied by the user.


File: gsl-ref.info,  Node: Root Finding Caveats,  Next: Initializing the Solver,  Prev: Root Finding Overview,  Up: One dimensional Root-Finding

Caveats
=======

   Note that root finding functions can only search for one root at a
time.  When there are several roots in the search area, the first root
to be found will be returned; however it is difficult to predict which
of the roots this will be. _In most cases, no error will be reported if
you try to find a root in an area where there is more than one._

   Care must be taken when a function may have a multiple root (such as
f(x) = (x-x_0)^2 or f(x) = (x-x_0)^3).  It is not possible to use
root-bracketing algorithms on even-multiplicity roots.  For these
algorithms the initial interval must contain a zero-crossing, where the
function is negative at one end of the interval and positive at the
other end.  Roots with even-multiplicity do not cross zero, but only
touch it instantaneously.  Algorithms based on root bracketing will
still work for odd-multiplicity roots (e.g. cubic, quintic, ...).  Root
polishing algorithms generally work with higher multiplicity roots, but
at reduced rate of convergence.  In these cases the "Steffenson
algorithm" can be used to accelerate the convergence of multiple roots.

   While it is not absolutely required that f have a root within the
search region, numerical root finding functions should not be used
haphazardly to check for the _existence_ of roots.  There are better
ways to do this.  Because it is easy to create situations where
numerical root finders go awry, it is a bad idea to throw a root finder
at a function you do not know much about.  In general it is best to
examine the function visually by plotting before searching for a root.


File: gsl-ref.info,  Node: Initializing the Solver,  Next: Providing the function to solve,  Prev: Root Finding Caveats,  Up: One dimensional Root-Finding

Initializing the Solver
=======================

 - Function: gsl_root_fsolver * gsl_root_fsolver_alloc (const
          gsl_root_fsolver_type * T, gsl_function * F, gsl_interval X)
     This function returns a pointer to a a newly allocated instance of
     a solver of type T for the function F, with an initial bracket on
     the root of X.  For example, the following code creates an
     instance of a bisection solver,

          gsl_root_fsolver * s =
              gsl_root_fsolver_alloc (gsl_root_fsolver_bisection, f, x);

     If there is insufficient memory to create the solver then the
     function returns a null pointer and the error handler is invoked
     with an error code of `GSL_ENOMEM'.

 - Function: gsl_root_fdfsolver * gsl_root_fdfsolver_alloc (const
          gsl_root_fdfsolver_type * T, gsl_function_fdf * FDF, double
          ROOT)
     This function returns a pointer to a a newly allocated instance of
     a solver of type T for the function F, with an initial guess for
     the root of ROOT.  For example, the following code creates an
     instance of a Newton-Raphson solver,

          gsl_root_fdfsolver * s =
              gsl_root_fdfsolver_alloc (gsl_root_fdfsolver_newton, fdf, r);

     If there is insufficient memory to create the solver then the
     function returns a null pointer and the error handler is invoked
     with an error code of `GSL_ENOMEM'.

 - Function: int gsl_root_fsolver_set (gsl_root_fsolver * S,
          gsl_function * F, gsl_interval X)
     This function reinitializes an existing solver S to use the
     function F and the initial search interval X.

 - Function: int gsl_root_fdfsolver_set (gsl_root_fdfsolver * S,
          gsl_function_fdf * FDF, double ROOT)
     This function reinitializes an existing solver S to use the
     function and derivative FDF and the initial guess ROOT.

 - Function: void gsl_root_fsolver_free (gsl_root_fsolver * S)
 - Function: void gsl_root_fdfsolver_free (gsl_root_fdfsolver * S)
     These functions free all the memory associated with the solver S.

 - Function: const char * gsl_root_fsolver_name (const gsl_root_fsolver
          * S)
 - Function: const char * gsl_root_fdfsolver_name (const
          gsl_root_fdfsolver * S)
     These functions return a pointer to the name of the solver.  For
     example,

          printf("s is a '%s' solver\n", gsl_root_fsolver_name (s)) ;

     would print something like `s is a 'bisection' solver'


File: gsl-ref.info,  Node: Providing the function to solve,  Next: Search Bounds and Guesses,  Prev: Initializing the Solver,  Up: One dimensional Root-Finding

Providing the function to solve
===============================

   You must provide a continuous function of one variable for the root
finders to operate on, and, sometimes, its first derivative.  In order
to allow for general parameters the functions are defined by the
following data types:

 - Data Type: gsl_function
     This data type defines a general function with parameters.

    `double (* FUNCTION) (double X, void * PARAMS)'
          this function should return the value f(x,params) for
          argument X and parameters PARAMS

    `void * PARAMS'
          a pointer to the parameters of the function

   Here is an example for the general quadratic function,

     f(x) = a x^2 + b x + c

with a = 3, b = 2, c = 1.  The following code defines a `gsl_function'
`F' which you could pass to a root finder:

     struct my_f_params { double a ; double b ; double c ; } ;
     
     double
     my_f (double x, void * p) {
        struct my_f_params * params = (struct my_f_params *)p ;
        double a = (params->a) ;
        double b = (params->b) ;
        double c = (params->c) ;
     
        return  (a * x + b) * x + c ;
     }
     
     gsl_function F ;
     struct my_f_params params = { 3.0, 2.0, 1.0 };
     
     F.function = &my_f ;
     F.params = &params ;

   The function f(x) can be evaluated using the following macro,

     #define GSL_FN_EVAL(F,x) (*((F)->function))(x,(F)->params)

 - Data Type: gsl_function_fdf
     This data type defines a general function with parameters and its
     first derivative.

    `double (* F) (double X, void * PARAMS)'
          this function should return the value of f(x,params) for
          argument X and parameters PARAMS

    `double (* DF) (double X, void * PARAMS)'
          this function should return the value of the derivative of F
          with respect to X, f'(x,params), for argument X and
          parameters PARAMS

    `void (* FDF) (double X, void * PARAMS, double * F, double * Df)'
          this function should set the values of the function F to
          f(x,params) and its derivative DF to f'(x,params) for
          argument X and parameters PARAMS.  This function provides an
          optimization of the separate functions for f(x) and f'(x) -
          it is always faster to compute the function and its
          derivative at the same time.

    `void * PARAMS'
          a pointer to the parameters of the function

   Here is an example where f(x) = 2\exp(2x):

     double
     my_f (double x, void * params)
     {
        return exp (2 * x);
     }
     
     double
     my_df (double x, void * params)
     {
        return 2 * exp (2 * x);
     }
     
     void
     my_fdf (double x, void * params, double * f, double * df)
     {
        double t = exp (2 * x) ;
     
        *f = t;
        *df = 2 * t;   /* computing using existing values */
     }
     
     gsl_function_fdf FDF ;
     
     FDF.f = &my_f ;
     FDF.df = &my_df ;
     FDF.fdf = &my_fdf ;
     FDF.params = 0 ;

   The function f(x) can be evaluated using the following macro,

     #define GSL_FN_FDF_EVAL_F(FDF,x)
          (*((FDF)->f))(x,(FDF)->params)

The derivative f'(x) can be evaluated using the following macro,

     #define GSL_FN_FDF_EVAL_DF(FDF,x)
          (*((FDF)->df))(x,(FDF)->params)

and both the function y = f(x) and its derivative dy = f'(x) can be
evaluated at the same time using the following macro,

     #define GSL_FN_FDF_EVAL_F_DF(FDF,x,y,dy)
          (*((FDF)->fdf))(x,(FDF)->params,(y),(dy))

   The macro stores f(x) in its Y argument and f'(x) in its DY argument
- both of these should be pointers to `double'.


File: gsl-ref.info,  Node: Search Bounds and Guesses,  Next: Root Finding Iteration,  Prev: Providing the function to solve,  Up: One dimensional Root-Finding

Search Bounds and Guesses
=========================

   You provide either search bounds or an initial guess; this section
explains how search bounds and guesses work and how function arguments
control them.

   A guess is simply an x value which is iterated until it is within
the desired precision of a root.  It takes the form of a `double'.

   Search bounds are the endpoints of a interval which is iterated until
the length of the interval is smaller than the requested precision.  The
interval is defined by the following struct,

 - Data Type: gsl_interval
     This is a structure that holds an interval [LOWER, UPPER] on the
     real line.

    `double lower'
          the lower limit of the interval

    `double upper'
          the upper limit of the interval

     Whether the endpoints are intended to be included in the interval
     or not depends on the context in which the interval is used.


File: gsl-ref.info,  Node: Root Finding Iteration,  Next: Search Stopping Parameters,  Prev: Search Bounds and Guesses,  Up: One dimensional Root-Finding

Iteration
=========

   The following functions drive the iteration of each algorithm.  Each
function performs one iteration to update the state of any solver of the
corresponding type.  The same functions work for all solvers so that
different methods can be substituted at runtime without modifications to
the code.

 - Function: int gsl_root_fsolver_iterate (gsl_root_fsolver * S)
 - Function: int gsl_root_fdfsolver_iterate (gsl_root_fdfsolver * S)
     These functions perform a single iteration of the solver S.  If the
     iteration encounters an unexpected problem then an error code will
     be returned,

    `GSL_EBADFUNC'
          the iteration encountered a singular point where the function
          or its derivative evaluated to `Inf' or `NaN'.

    `GSL_EZERODIV'
          the derivative of the function vanished at the iteration
          point, preventing the algorithm from continuing without a
          division by zero.

   The solver maintains a current best estimate of the root at all
times.  The bracketing solvers also keep track of the current best
interval bounding the root.  This information can be accessed with the
following auxiliary functions,

 - Function: double gsl_root_fsolver_root (const gsl_root_fsolver * S)
 - Function: double gsl_root_fdfsolver_root (const gsl_root_fdfsolver *
          S)
     These functions return the current estimate of the root for the
     solver S.

 - Function: gsl_interval gsl_root_fsolver_interval (const
          gsl_root_fsolver * S)
     This function returns the current bracketing interval for the
     solver S.


File: gsl-ref.info,  Node: Search Stopping Parameters,  Next: Root Bracketing Algorithms,  Prev: Root Finding Iteration,  Up: One dimensional Root-Finding

Search Stopping Parameters
==========================

   A root finding procedure should stop when one of the following
conditions is true:

   * A root has been found to within the user-specified precision.

   * A user-specified maximum number of iterations has executed.

   * An error has occurred.

In the root finding framework of GSL the handling of these conditions is
under user control.  The functions below allow the user to test the
precision of the current result in several standard ways.

 - Function: int gsl_root_test_interval (gsl_interval X, double EPSREL,
          double EPSABS)
     This function tests for the convergence of the interval X with
     absolute error EPSABS and relative error EPSREL.  The test returns
     `GSL_SUCCESS' if the following condition is achieved,

          |a - b| < epsabs + epsrel min(|a|,|b|)

     when the interval x = [a,b] does not include the origin.  If the
     interval includes the origin then \min(|a|,|b|) is replaced by
     zero (which is the minimum value of |x| over the interval).  This
     ensures that the relative error is accurately estimated for roots
     close to the origin.

     This condition on the interval also implies that any estimate of
     the root r in the interval satisfies the same condition with
     respect to the true root r^*,

          |r - r^*| < epsabs + epsrel r^*

     assuming that the true root r^* is contained within the interval.

 - Function: int gsl_root_test_delta (double X1, double X0, double
          EPSREL, double EPSABS)
     This function tests for the convergence of the sequence ..., X0,
     X1 with absolute error EPSABS and relative error EPSREL.  The test
     returns `GSL_SUCCESS' if the following condition is achieved,

          |x_1 - x_0| < epsabs + epsrel |x_1|

     and returns `GSL_CONTINUE' otherwise.

 - Function: int gsl_root_test_residual (double F, double EPSABS)
     This function tests the residual value F against the absolute
     error bound EPSABS.  The test returns `GSL_SUCCESS' if the
     following condition is achieved,

          |f| < epsabs

     and returns `GSL_CONTINUE' otherwise.  This criterion is suitable
     for situations where the the precise location of the root, x, is
     unimportant provided a value can be found where the residual,
     |f(x)|, is small enough.


File: gsl-ref.info,  Node: Root Bracketing Algorithms,  Next: Root Finding Algorithms using Derivatives,  Prev: Search Stopping Parameters,  Up: One dimensional Root-Finding

Root Bracketing Algorithms
==========================

   The root bracketing algorithms described in this section require an
initial interval which is guaranteed to contain a root - if a and b are
the endpoints of the interval then f(a) must differ in sign from f(b).
This ensures that the function crosses zero at least once in the
interval.  If a valid initial interval is used then these algorithm
cannot fail, provided the function is well-behaved.

   Note that a bracketing algorithm cannot find roots of even degree,
since these do not cross the x-axis.

 - Solver: gsl_root_fsolver_bisection
     The "bisection algorithm" is the simplest method of bracketing the
     roots of a function.   It is the slowest algorithm provided by the
     library, with linear convergence.

     On each iteration, the interval is bisected and the value of the
     function at the midpoint is calculated.  The sign of this value is
     used to determine which half of the interval does not contain a
     root.  That half is discarded to give a new, smaller interval
     containing the root.  This procedure can be continued indefinitely
     until the interval is sufficiently small.

     At any time the current estimate of the root is taken as the
     midpoint of the interval.


 - Solver: gsl_root_fsolver_falsepos
     The "false position algorithm" is a method of finding roots based
     on linear interpolation.  Its convergence is linear, but it is
     usually faster than bisection.

     On each iteration a line is drawn between the endpoints (a,f(a))
     and (b,f(b)) and the point where this line crosses the x-axis
     taken as a "midpoint".  The value of the function at this point is
     calculated and its sign is used to determine which side of the
     interval does not contain a root.  That side is discarded to give a
     new, smaller interval containing the root.  This procedure can be
     continued indefinitely until the interval is sufficiently small.

     The best estimate of the root is taken from the linear
     interpolation of the interval on the current iteration.


 - Solver: gsl_root_fsolver_brent
     The "Brent-Dekker method" (referred to here as "Brent's method")
     combines an interpolation strategy with the bisection algorithm.
     This produces a fast algorithm which is still robust.

     On each iteration Brent's method approximates the function using an
     interpolating curve.  On the first iteration this is a linear
     interpolation of the two endpoints.  For subsequent iterations the
     algorithm uses an inverse quadratic fit to the last three points,
     for higher accuracy.  The intercept of the interpolating curve
     with the x-axis is taken as a guess for the root.  If it lies
     within the bounds of the current interval then the interpolating
     point is accepted, and used to generate a smaller interval.  If
     the interpolating point is not accepted then the algorithm falls
     back to an ordinary bisection step.

     The best estimate of the root is taken from the most recent
     interpolation or bisection.


File: gsl-ref.info,  Node: Root Finding Algorithms using Derivatives,  Next: Root Finding Examples,  Prev: Root Bracketing Algorithms,  Up: One dimensional Root-Finding

Root Finding Algorithms using Derivatives
=========================================

   The root polishing algorithms described in this section require an
initial guess for the location of the root.  There is no absolute
guarantee of convergence - the function must be suitable for this
technique and the initial guess must be sufficiently close to the root
for it to work.  When the conditions are satisfied then convergence is
quadratic.

   These algorithms make use of both the function and its derivative.

 - Derivative Solver: gsl_root_fdfsolver_newton
     Newton's Method is the standard root-polishing algorithm.  The
     algorithm begins with an initial guess for the location of the
     root.  On each iteration, a line tangent to the function f is
     drawn at that position.  The point where this line crosses the
     x-axis becomes the new guess.  The iteration is defined by the
     following sequence,

          x_{i+1} = x_i - f(x_i)/f'(x_i)

     Newton's method converges quadratically for single roots, and
     linearly for multiple roots.


 - Derivative Solver: gsl_root_fdfsolver_secant
     The "secant method" is a simplified version of Newton's method
     which can be useful when computation of the derivative is costly.

     On its first iteration the algorithm begins with Newton's method,
     using the derivative to compute a first step,

          x_1 = x_0 - f(x_0)/f'(x_0)

     Subsequent iterations avoid the evaluation of the derivative by
     replacing it with a numerical estimate, the slope through the
     previous two points,

          x_{i+1} = x_i f(x_i) / f'_{est} where
           f'_{est} = (f(x_i) - f(x_{i-1})/(x_i - x_{i-1})

     When the derivative does not change significantly in the vicinity
     of the root the secant method gives a useful saving.  As with all
     methods of computing a numerical derivative the estimate can
     suffer from cancellation errors if the separation of the points
     becomes too small.

     On single roots, the method has a convergence of order (1 + \sqrt
     5)/2 (approximately 1.62).  It converges linearly for multiple
     roots.


 - Derivative Solver: gsl_root_fdfsolver_steffenson
     The "Steffenson Method" provides the fastest convergence of all the
     routines.  It combines the basic Newton algorithm with an Aitken
     "delta-squared" acceleration.  If the Newton iterates are x_i then
     the acceleration procedure generates a new sequence R_i,

          R_i = x_i - (x_{i+1} - x_i)^2 / (x_{i+2} - 2 x_{i+1} + x_{i})

     which converges faster than the original sequence under reasonable
     conditions.  The new sequence requires three terms before it can
     produce its first value so the method returns accelerated values
     on the second and subsequent iterations.  On the first iteration
     it returns the ordinary Newton estimate.  The Newton iterate is
     also returned if the denominator of the acceleration term ever
     becomes zero.

     As with all acceleration procedures this method can become
     unstable if the function is not well-behaved.

