Commit c4ce788c authored by liam's avatar liam

Added histogram.


git-svn-id: svn+ssh://pop/opt/space/mathematics/gsl/trunk@3165 a3d8a0fb-c1db-0310-ace7-a616afeb9e30
parent d2de9d52
......@@ -24,7 +24,6 @@ is that the GSL library must be loaded and accessible.
such functions may be combined into a single regular or generic
function.
======================
Needs work:
See Thu Apr 20 2006
......@@ -61,3 +60,7 @@ because they need a vector_int.
It would be nice to use e.g. vector-sap for direct vectors in
e.g. SBCL.
- reading and writing functions will require handling of C streams,
not provided.
......@@ -3,7 +3,7 @@
; description: Definition of GSLL system
; date:
; author: Liam Healy
; modified: Mon Jan 1 2007 - 12:10
; modified: Mon Jan 1 2007 - 22:08
;********************************************************
;;; $Id: $
......@@ -140,4 +140,13 @@
(:file "autocorrelation")
(:file "covariance")
;; minimum and maximum values provided in vector.lisp
(:file "median-percentile")))))
(:file "median-percentile")))
(:module histogram
:depends-on (init)
:components
((:file "histogram")
(:file "updating-accessing" :depends-on (histogram))
(:file "statistics" :depends-on (histogram))
(:file "operations" :depends-on (histogram))
(:file "read-write" :depends-on (histogram))
(:file "probability-distribution" :depends-on (histogram))))))
;********************************************************
; file: structure.lisp
; description: The histogram structure.
; date: Mon Jan 1 2007 - 11:32
; author: Liam M. Healy
; modified: Mon Jan 1 2007 - 20:44
;********************************************************
;;; $Id: $
(in-package :gsl)
;;; Define, make, copy histograms in one or two dimensions.
;;; Should this have a with-histogram macro, or be integrated into
;;; the data superclass (and so use with-data)?
(defclass histogram ()
((pointer
:initarg :pointer :accessor pointer
:documentation "A C pointer to the GSL representation of the histogram.")
(number-of-bins :initarg :number-of-bins :accessor number-of-bins))
(:documentation
"A histogram, including bin boundaries and bin contents."))
(defun-gsl alloc-histo-1 (object)
"gsl_histogram_alloc"
(((number-of-bins object) :size))
:export nil
:index alloc
:c-return (cr :pointer)
:return ((assign-pointer object cr)))
(defun-gsl alloc-histo-2 (object)
"gsl_histogram2d_alloc"
(((first (number-of-bins object)) :size)
((second (number-of-bins object)) :size))
:export nil
:index alloc
:c-return (cr :pointer)
:return ((assign-pointer object cr)))
(defmacro histo-1d2d
(object base-function-name &optional args1 args2)
`(if (listp (number-of-bins ,object))
(,(intern
(concatenate 'string (string base-function-name) "-2"))
,object ,@(or args2 args1))
(,(intern
(concatenate 'string (string base-function-name) "-1"))
,object ,@args1)))
(defmethod alloc ((object histogram))
(histo-1d2d object alloc-histo))
(defun-gsl free-histo-1 (object)
"gsl_histogram_free"
(((pointer object) :pointer))
:c-return (cr :pointer)
:return ((assign-pointer object cr)))
(defun-gsl free-histo-2 (object)
"gsl_histogram2d_free"
(((pointer object) :pointer))
:c-return (cr :pointer)
:return ((assign-pointer object cr)))
(defmethod free ((object histogram))
(histo-1d2d object free-histo))
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl set-ranges-1 (histogram ranges)
"gsl_histogram_set_ranges"
(((pointer histogram) :pointer)
((gsl-array ranges) :pointer) ((dim0 ranges) :size))
:export nil
:index set-ranges
:documentation
"Set the ranges of the existing histogram using
the gsl-vector of ranges. The values of the histogram
bins are reset to zero. The @code{ranges} array should contain the
desired bin limits. The ranges can be arbitrary, subject to the
restriction that they are monotonically increasing.")
(defun-gsl set-ranges-2 (histogram x-ranges y-ranges)
"gsl_histogram2d_set_ranges"
(((pointer histogram) :pointer)
((gsl-array x-ranges) :pointer) ((dim0 x-ranges) :size)
((gsl-array y-ranges) :pointer) ((dim0 y-ranges) :size))
:export nil
:index set-ranges)
(export 'set-ranges)
(defun set-ranges (histogram &rest ranges)
"Set the ranges of the existing histogram using
the gsl-vector(s) of ranges. The values of the histogram
bins are reset to zero. The ranges array(s) should contain the
desired bin limits. The ranges can be arbitrary, subject to the
restriction that they are monotonically increasing.
For a 2d histogram, supply two gsl-vectors."
(histo-1d2d histogram set-ranges
((first ranges))
((first ranges) (second ranges))))
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl set-ranges-uniform-1 (histogram minimum maximum)
"gsl_histogram_set_ranges_uniform"
(((pointer histogram) :pointer) (minimum :double) (maximum :double))
:export nil
:index set-ranges-uniform
:documentation
"Set the ranges of the existing histogram @var{h} to cover
the range @var{xmin} to @var{xmax} uniformly. The values of the
histogram bins are reset to zero. The bin ranges are shown in the table
below,
bin[0] corresponds to xmin <= x < xmin + d
bin[1] corresponds to xmin + d <= x < xmin + 2 d
......
bin[n-1] corresponds to xmin + (n-1)d <= x < xmax
where @math{d} is the bin spacing, @math{d = (xmax-xmin)/n}.")
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl set-ranges-uniform-2
(histogram x-minimum x-maximum y-minimum y-maximum)
"gsl_histogram2d_set_ranges_uniform"
(((pointer histogram) :pointer)
(x-minimum :double) (x-maximum :double)
(y-minimum :double) (y-maximum :double))
:export nil
:index set-ranges-uniform)
(export 'set-ranges-uniform)
(defun set-ranges-uniform (histogram &rest limits)
"Set the ranges of the existing histogram @var{h} to cover
the range @var{xmin} to @var{xmax} uniformly. The values of the
histogram bins are reset to zero. The bin ranges are shown in the table
below,
bin[0] corresponds to xmin <= x < xmin + d
bin[1] corresponds to xmin + d <= x < xmin + 2 d
......
bin[n-1] corresponds to xmin + (n-1)d <= x < xmax
where @math{d} is the bin spacing, @math{d = (xmax-xmin)/n}."
(histo-1d2d histogram set-ranges-uniform
((first limits) (second limits))
((first limits) (second limits)
(third limits) (fourth limits))))
(defun-gsl copy-1 (destination source)
"gsl_histogram_memcpy"
(((pointer destination) :pointer) ((pointer source) :pointer))
:export nil
:index copy
:documentation
"Copy the histogram source into the pre-existing
histogram destination, making the latter into
an exact copy of the former.
The two histograms must be of the same size.")
(defun-gsl copy-2 (destination source)
"gsl_histogram2d_memcpy"
(((pointer destination) :pointer) ((pointer source) :pointer))
:export nil
:index copy)
(defmethod copy ((destination histogram) (source histogram))
(histo-1d2d destination copy (source)))
(defun-gsl clone-1 (source)
"gsl_histogram_memcpy"
(((pointer source) :pointer))
:export nil
:index clone
:documentation
"Create a new histogram which is an
exact copy of the histogram source, and return the pointer.")
(defun-gsl clone-2 (source)
"gsl_histogram2d_memcpy"
(((pointer source) :pointer))
:export nil
:index clone
:documentation
"Create a new histogram which is an
exact copy of the histogram source, and return the pointer.")
(export 'clone)
(defun clone (source)
(histo-1d2d source clone))
(defun make-histogram (size &optional from)
"Make a histogram, optionally filling it with
data from an existing histogram."
(make-instance 'histogram :number-of-bins size
:pointer (when from (clone from))))
;********************************************************
; file: operations.lisp
; description: Histogram operations
; date: Mon Jan 1 2007 - 16:47
; author: Liam M. Healy
; modified: Mon Jan 1 2007 - 21:50
;********************************************************
;;; $Id: $
(in-package :gsl)
(defun-gsl equal-bins-p-1 (histogram1 histogram2)
"gsl_histogram_equal_bins_p"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:c-return :true-false
:export nil
:index equal-bins-p
:documentation
"Are all of the individual bin
ranges of the two histograms are identical?")
(defun-gsl equal-bins-p-2 (histogram1 histogram2)
"gsl_histogram2d_equal_bins_p"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:c-return :true-false
:export nil
:index equal-bins-p
:documentation
"Are all of the individual bin
ranges of the two histograms are identical?")
(export 'equal-bins-p)
(defun equal-bins-p (histogram1 histogram2)
"Are all of the individual bin
ranges of the two histograms are identical?"
(histo-1d2d histogram1 equal-bins-p (histogram2)))
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl gsl+-1 (histogram1 histogram2)
"gsl_histogram_add"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:export nil
:index gsl+
:documentation
"Add the contents of the bins in histogram2 to the
corresponding bins of histogram1 i.e. @math{h'_1(i) =
h_1(i) + h_2(i)}. The two histograms must have identical bin
ranges.")
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl gsl+-2 (histogram1 histogram2)
"gsl_histogram2d_add"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:export nil
:index gsl+
:documentation
"Add the contents of the bins in histogram2 to the
corresponding bins of histogram1 i.e. @math{h'_1(i) =
h_1(i) + h_2(i)}. The two histograms must have identical bin
ranges.")
(defmethod gsl+ ((histogram1 histogram) (histogram2 histogram))
"Add the contents of the bins in histogram2 to the
corresponding bins of histogram1 i.e. @math{h'_1(i) =
h_1(i) + h_2(i)}. The two histograms must have identical bin
ranges."
(histo-1d2d histogram1 gsl+ (histogram2)))
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl gsl--1 (histogram1 histogram2)
"gsl_histogram_sub"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:export nil
:index gsl-
:documentation
"Subtract the contents of the bins in histogram2 from the
corresponding bins of histogram1 i.e. @math{h'_1(i) = h_1(i) -
h_2(i)}. The two histograms must have identical bin ranges.")
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl gsl--2 (histogram1 histogram2)
"gsl_histogram2d_sub"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:export nil
:index gsl-
:documentation
"Subtract the contents of the bins in histogram2 from the
corresponding bins of histogram1 i.e. @math{h'_1(i) = h_1(i) -
h_2(i)}. The two histograms must have identical bin ranges.")
(defmethod gsl- ((histogram1 histogram) (histogram2 histogram))
"Subtract the contents of the bins in histogram2 from the
corresponding bins of histogram1 i.e. @math{h'_1(i) = h_1(i) -
h_2(i)}. The two histograms must have identical bin ranges."
(histo-1d2d histogram1 gsl- (histogram2)))
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl gsl*-1 (histogram1 histogram2)
"gsl_histogram_mul"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:export nil
:index gsl*
:documentation
"Multiply the contents of the bins of histogram1 by the
contents of the corresponding bins in histogram2
i.e. @math{h'_1(i) = h_1(i) * h_2(i)}. The two histograms
must have identical bin ranges.")
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl gsl*-2 (histogram1 histogram2)
"gsl_histogram2d_mul"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:export nil
:index gsl*
:documentation
"Multiply the contents of the bins of histogram1 by the
contents of the corresponding bins in histogram2
i.e. @math{h'_1(i) = h_1(i) * h_2(i)}. The two histograms
must have identical bin ranges.")
(defmethod gsl* ((histogram1 histogram) (histogram2 histogram))
"Multiply the contents of the bins of histogram1 by the
contents of the corresponding bins in histogram2
i.e. @math{h'_1(i) = h_1(i) * h_2(i)}. The two histograms
must have identical bin ranges."
(histo-1d2d histogram1 gsl* (histogram2)))
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl gsl/-1 (histogram1 histogram2)
"gsl_histogram_div"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:export nil
:index gsl/
:documentation
"Divide the contents of the bins of histogram1 by the
contents of the corresponding bins in histogram2
i.e. @math{h'_1(i) = h_1(i) / h_2(i)}. The two histograms
must have identical bin ranges.")
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl gsl/-2 (histogram1 histogram2)
"gsl_histogram2d_div"
(((pointer histogram1) :pointer) ((pointer histogram2) :pointer))
:export nil
:index gsl/
:documentation
"Divide the contents of the bins of histogram1 by the
contents of the corresponding bins in histogram2
i.e. @math{h'_1(i) = h_1(i) / h_2(i)}. The two histograms
must have identical bin ranges.")
(defmethod gsl/ ((histogram1 histogram) (histogram2 histogram))
"Divide the contents of the bins of histogram1 by the
contents of the corresponding bins in histogram2
i.e. @math{h'_1(i) = h_1(i) / h_2(i)}. The two histograms
must have identical bin ranges."
(histo-1d2d histogram1 gsl/ (histogram2)))
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl scale-1 (histogram scale)
"gsl_histogram_scale"
(((pointer histogram) :pointer) (scale :double))
:export nil
:index scale
:documentation
"Multiply the contents of the bins of histogram by the
constant scale, i.e. h'_1(i) = h_1(i) * scale.")
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl scale-2 (histogram scale)
"gsl_histogram2d_scale"
(((pointer histogram) :pointer) (scale :double))
:export nil
:index scale
:documentation
"Multiply the contents of the bins of histogram by the
constant scale, i.e. h'_1(i) = h_1(i) * scale.")
(export 'scale)
(defun scale (histogram scale)
"Multiply the contents of the bins of histogram by the
constant scale, i.e. h'_1(i) = h_1(i) * scale."
(histo-1d2d histogram scale (scale)))
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl shift-1 (histogram offset)
"gsl_histogram_shift"
(((pointer histogram) :pointer) (offset :double))
:export nil
:index shift
:documentation
"Shift the contents of the bins of histogram @var{h} by the
constant offset, i.e. h'_1(i) = h_1(i) + offset.")
;;; GSL documentation does not state what the return value for the
;;; C function means; assumed to be error code.
(defun-gsl shift-2 (histogram offset)
"gsl_histogram2d_shift"
(((pointer histogram) :pointer) (offset :double))
:export nil
:index shift
:documentation
"Shift the contents of the bins of histogram @var{h} by the
constant offset, i.e. h'_1(i) = h_1(i) + offset.")
(export 'shift)
(defun shift (histogram offset)
(histo-1d2d histogram shift (offset)))
;********************************************************
; file: probability-distribution.lisp
; description: Histogram probability distribution.
; date: Mon Jan 1 2007 - 17:51
; author: Liam M. Healy
; modified: Mon Jan 1 2007 - 22:22
;********************************************************
;;; $Id: $
(in-package :gsl)
(defclass histogram-pdf ()
((pointer
:initarg :pointer :accessor pointer
:documentation
"A C pointer to the GSL representation of the histogram.")
(number-of-bins :initarg :number-of-bins :accessor number-of-bins))
(:documentation
"A histogram, including bin boundaries and bin contents."))
(defun-gsl alloc-1 (object)
"gsl_histogram_pdf_alloc"
(((number-of-bins object) :size))
:export nil
:index alloc
:c-return (cr :pointer)
:return ((assign-pointer object cr)))
(defun-gsl alloc-2 (object)
"gsl_histogram2d_pdf_alloc"
(((number-of-bins object) :size))
:export nil
:index alloc
:c-return (cr :pointer)
:return ((assign-pointer object cr)))
(defmethod alloc ((object histogram-pdf))
(histo-1d2d object alloc))
(defun-gsl free-1 (object)
"gsl_histogram_pdf_free"
(((pointer object) :pointer))
:export nil
:index free
:c-return :void)
(defun-gsl free-2 (object)
"gsl_histogram2d_pdf_free"
(((pointer object) :pointer))
:export nil
:index free
:c-return :void)
(defmethod free ((object histogram-pdf))
(histo-1d2d object free))
(defun-gsl pdf-init-1 (pdf histogram)
"gsl_histogram_pdf_init"
(((pointer pdf) :pointer) ((pointer histogram) :pointer))
:return ()
:export nil
:index pdf-init
:documentation
"Initialize the probability distribution pdf with the contents
of the histogram. If any of the bins are negative then an
EDOM error is signalled because a probability distribution
cannot contain negative values.")
(defun-gsl pdf-init-2 (pdf histogram)
"gsl_histogram2d_pdf_init"
(((pointer pdf) :pointer) ((pointer histogram) :pointer))
:return ()
:export nil
:index pdf-init
:documentation
"Initialize the probability distribution pdf with the contents
of the histogram. If any of the bins are negative then an
EDOM error is signalled because a probability distribution
cannot contain negative values.")
(export 'pdf-init)
(defun pdf-init (pdf histogram)
"Initialize the probability distribution pdf with the contents
of the histogram. If any of the bins are negative then an
EDOM error is signalled because a probability distribution
cannot contain negative values."
(histo-1d2d pdf pdf-init (histogram)))
(defun-gsl sample-1 (pdf value)
"gsl_histogram_pdf_sample"
(((pointer pdf) :pointer) (value :double))
:c-return :double
:export nil
:index sample
:documentation
"Given a uniform random number between zero and one,
compute a single random sample from the probability distribution
'pdf. The algorithm used to compute the sample @math{s} is given by
s = range[i] + delta * (range[i+1] - range[i])
where @math{i} is the index which satisfies
@math{sum[i] <= r < sum[i+1]} and @math{delta} is
@math{(r - sum[i])/(sum[i+1] - sum[i])}.")
(defun-gsl sample-2 (pdf value)
"gsl_histogram2d_pdf_sample"
(((pointer pdf) :pointer) (value :double))
:c-return :double
:export nil
:index sample
:documentation
"Given a uniform random number between zero and one,
compute a single random sample from the probability distribution
'pdf. The algorithm used to compute the sample @math{s} is given by
s = range[i] + delta * (range[i+1] - range[i])
where @math{i} is the index which satisfies
@math{sum[i] <= r < sum[i+1]} and @math{delta} is
@math{(r - sum[i])/(sum[i+1] - sum[i])}.")
(export 'sample)
(defun sample (pdf value)
(histo-1d2d pdf sample (value)))
;********************************************************
; file: read-write.lisp
; description: Reading and writing histograms.
; date: Mon Jan 1 2007 - 17:13
; author: Liam M. Healy
; modified: Mon Jan 1 2007 - 22:06
;********************************************************
;;; $Id: $
(in-package :gsl)
(defun-gsl write-binary-1 (object stream)
"gsl_histogram_fwrite"
((stream :pointer) ((pointer object) :pointer))
:export nil
:index write-binary)
(defun-gsl write-binary-2 (object stream)
"gsl_histogram2d_fwrite"
((stream :pointer) ((pointer object) :pointer))
:export nil
:index write-binary)
(defmethod write-binary ((object histogram) stream)
(histo-1d2d object write-binary (stream)))
(defun-gsl read-binary-1 (object stream)
"gsl_histogram_fread"
((stream :pointer) ((pointer object) :pointer))
:export nil
:index read-binary)
(defun-gsl read-binary-2 (object stream)
"gsl_histogram2d_fread"
((stream :pointer) ((pointer object) :pointer))
:export nil
:index read-binary)
(defmethod read-binary ((object histogram) stream)
(histo-1d2d object read-binary (stream)))
(defun-gsl write-formatted-1 (object stream format)
"gsl_histogram_fprintf"
((stream :pointer) ((pointer object) :pointer)
((first format) :string) ((second format) :string))
:export nil
:index write-formatted)
(defun-gsl write-formatted-2 (object stream format)
"gsl_histogram2d_fprintf"
((stream :pointer) ((pointer object) :pointer)
((first format) :string) ((second format) :string))
:export nil
:index write-formatted)
(defmethod write-formatted ((object histogram) stream format)
"This function writes the ranges and bins of the histogram
line-by-line to the stream @var{stream} using the
format specifiers
(first format) for range format and (second format) for bin format.
These should be one of the
@code{%g}, @code{%e} or @code{%f} formats for floating point
numbers. The histogram output is
formatted in three columns, and the columns are separated by spaces,
like this,
range[0] range[1] bin[0]
range[1] range[2] bin[1]
range[2] range[3] bin[2]
....
range[n-1] range[n] bin[n-1]
The values of the ranges are formatted using @var{range_format} and the
value of the bins are formatted using @var{bin_format}. Each line
contains the lower and upper limit of the range of the bins and the
value of the bin itself. Since the upper limit of one bin is the lower
limit of the next there is duplication of these values between lines but
this allows the histogram to be manipulated with line-oriented tools."
(histo-1d2d object write-formatted (stream format)))
(defun-gsl read-formatted-1 (object stream format)
"gsl_histogram_fscanf"
((stream :pointer) ((pointer object) :pointer))
:export nil
:index read-formatted)
(defun-gsl read-formatted-2 (object stream format)
"gsl_histogram2d_fscanf"
((stream :pointer) ((pointer object) :pointer))
:export nil
:index read-formatted)
(defmethod read-formatted ((object histogram) stream format)
"Read formatted data from the stream into the histogram. The
data is assumed to be in the three-column format used by
#'write-formatted. The histogram must be preallocated with
the correct length since the function uses the size of the
histogram to determine how many numbers to read. The
argument 'format is ignored."
(histo-1d2d object read-formatted (stream format)))
;********************************************************
; file: statistics.lisp
; description: Statistics of histograms.
; date: Mon Jan 1 2007 - 16:13
; author: Liam M. Healy
; modified: Mon Jan 1 2007 - 22:39
;********************************************************
;;; $Id: $
(in-package :gsl)
(defun-gsl gsl-max-1 (histogram)
"gsl_histogram_max_val"
(((pointer histogram) :pointer))
:c-return :double
:export nil
:index gsl-max
:documentation
"The maximum value contained in the histogram bins.")
(defun-gsl gsl-max-2 (histogram)
"gsl_histogram2d_max_val"
(((pointer histogram) :pointer))
:c-return :double
:export nil
:index gsl-max
:documentation
"The maximum value contained in the histogram bins.")
(defmethod gsl-max ((histogram histogram))
"The maximum value contained in the histogram bins."
(histo-1d2d histogram gsl-max))
(defun-gsl gsl-min-1 (histogram)
"gsl_histogram_min_val"
(((pointer histogram) :pointer))
:c-return :double
:export nil
:index gsl-min
:documentation
"The minimum value contained in the histogram bins.")
(defun-gsl gsl-min-2 (histogram)
"gsl_histogram2d_min_val"
(((pointer histogram) :pointer))
:c-return :double
:export nil
:index gsl-min
:documentation
"The minimum value contained in the histogram bins.")
(defmethod gsl-min ((histogram histogram))
"The minimum value contained in the histogram bins."
(histo-1d2d histogram gsl-min))
(defun-gsl gsl-max-index-1 (histogram)
"gsl_histogram_max_bin"
(((pointer histogram) :pointer))
:c-return :size
:export nil
:index gsl-max-index
:documentation
"The index of the bin containing the maximum value. In the case
where several bins contain the same maximum value the smallest
index is returned.")